[fpc-devel] Suggestion: reference counted objects
Sven Barth
pascaldragon at googlemail.com
Sun Sep 21 14:25:30 CEST 2014
On 21.09.2014 13:20, Marco van de Voort wrote:
> In our previous episode, Sven Barth said:
>
> (as sb purely interested from an academic viewpoint, I have no real need for
> this)
Understood.
>> - a reference counted class (and its child classes) would include a
>> reference count field that the compiler knows how to access (for
>> automatic reference counting) and which can be accessed through RTTI
>> (for manual reference counting); it is *not* exposed as a regular field
>> as this might lead to identifier conflicts
>
> Does this mean multiple roots? That would make creating helpers for the
> refcounting different (since the field would be at a different offset
> everwhere)
No, not multiple roots. If a class is declared as refcounted (and it's
parent class is not) then a hidden field is inserted into its list of
fields, just as a normal one would, only that it isn't accesible using
the "."-operator (because it won't have a valid Pascal identifier). The
compiler of course knows the offset at compile time and at runtime the
field can be accessed using the class' RTTI which would have a
"RefCountOffset" field added (if that offset is < 0 then the object does
not support reference counting).
>> - only *variables* (or parameters) that have a reference counted class
>> as its type will be subject to ARC; in extension this means that
>> assignments from/to a variable of a not reference counted base class
>> (e.g. TObject) will *not* change the reference count. Take this code for
>> example:
>
> One of the performance sinks with refcounting is passing parameters through
> a call chain. (e.g. a class calling an inner class in a field to do the
> actual work, inherited() etc).
>
> How do you think to tackle that? With const?
>
> Maybe that can
In the same way it's a problem with strings, interfaces and arrays. They
all react accordingly to var/const/constref by not changing the
reference count. Reference counted classes would follow the same rules
(consistency here). And of course as a user of reference counted classes
one needs to be aware of the potential performance impact.
Did anyone till now really complain about the performance impact of
reference counting on interfaces? Especially since they are used *so*
much in today's OOP designs?
>> This will most likely result in "CreateObject" returning an instance to
>> class that is already freed (because the only reference inside
>> "CreateObject" is a (hypothetical) temporary of type "TARCObject" which
>> goes out of scope once "CreateObject" returns)
>
> It seems to me that implementation details of the return value handling
> (hidden/pseudo temp var etc) now trickle into the ARC design.
>
> Wouldn't it be more logical to make the result temp var a bit special so
> that it is not released when returned (requiring a
>
> func(); // ignores return value
>
> to pop the result and decrease the refcount?
The function result is just a special case. This can also be achived
with normal variables or parameters so it is important to have a
consistent handling here. The only way to consistently handle this
without making *all* object variables subject to reference counting
again is to not have assignments of reference counted object instances
from/to non-reference counted variables influence the reference count in
any way.
Also this is compatible to how interfaces work, though the analogous
interface example is highly constructed:
=== code begin ===
program tintfrefcount;
{$mode objfpc}
type
TTestClass = class(TInterfacedObject, IInterface)
destructor Destroy; override;
end;
destructor TTestClass.Destroy;
begin
Writeln('Destroy');
inherited;
end;
function Test: TObject;
begin
Result := (TTestClass.Create as IInterface) as TTestClass;
end;
var
o: TObject;
begin
o := Test;
Writeln('After Test');
o.Free;
end.
=== code end ===
Will result in:
=== output begin ===
Destroy
After Test
=== output end ===
Regards,
Sven
More information about the fpc-devel
mailing list