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
_______________________________________________
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel

Reply via email to