draft proposal for ref counting in D

Walter Bright newshound2 at digitalmars.com
Wed Oct 9 18:42:36 PDT 2013


On 6/26/2013 12:19 AM, Rainer Schuetze wrote:
 >
 > As Michel also said, the reference count does not have to be in inside the 
object itself, so we might want to allow reference counting on other types aswell.

That opens the question of what is the point of other RC types? For example, C++ 
can throw any type - but it turns out that throwing anything but class types is 
largely pointless.

My proposal does not specify where the count actually is - the two functions can 
be arbitrarily implemented.

 >
 >>
 >> 4. The compiler needs to know about ref counted types.
 >
 > I imagine a few (constrained) templated functions for the different 
operations defined in the library could also do the job, though it might drown 
compilation speed. Also getting help from the optimizer to remove redundant 
calls will need some back doors.

I don't see how this can be done without specific compiler knowledge in a memory 
safe way.

 >
 >>      T AddRef();
 >>      T Release();
 >
 > Is T typeof(this) here?

T is not relevant to the proposal - it's up to the specific implementation of 
those functions.

 >
 > I don't think we should force linking this functionality with COM, the 
programmer can do this with a simple wrapper.

Yeah, that's Michel's suggestion, and it's a good one.

 >
 >>
 >> An RC class is like a regular D class with these additional semantics:
 >>
 >> 1. In @safe code, casting (implicit or explicit) to a base class that
 >> does not
 >> have both AddRef() and Release() is an error.
 >>
 >> 2. Initialization of a class reference causes a call to AddRef().
 >>
 >> 3. Assignment to a class reference causes a call to AddRef() on the new
 >> value
 >> followed by a call to Release() on its original value.
 >
 > It might be common knowledge, but I want to point out that the usual COM 
implementation (atomic increment/decrement and free when refcount goes down to 
0) is not thread-safe for shared pointers. That means you either have to guard 
all reads and writes with a lock to make the full assignment atomic or have to 
implement reference counting very different (e.g. deferred reference counting).

Since the implementation of AddRef()/Release() is up to the user, whether it 
uses locks or not and whether it supports shared or not is up to the user.

 >> 12. AddRef() is not called when passed as the implicit 'this' reference.
 >>
 >
 > Isn't this unsafe if a member function is called through the last existing 
reference and this reference is then cleared during execution of this member 
function or from another thread?

No. The caller of the function still retains a reference in that thread.

 >
 >> 13. Taking the address of, or passing by reference, any fields of an RC
 >> object
 >> is not allowed in @safe code. Passing by reference an RC field is allowed.
 >
 > Please note that this includes slices to fixed size arrays.

As I suggested, arrays would not be supported with this proposal - but the user 
can create ref counted array-like objects.

 >>
 >> 16. RC objects cannot be const or immutable.
 >
 > This is a bit of a downer. If the reference count is not within the object, 
this can be implemented.

Also, an exception could be made for the AddRef()/Release() functions.

 >
 > I feel I'm hijacking this proposal, but the step to library defined 
read/write barriers seems pretty small. Make AddRef, Release and assignment free 
template functions, e.g.
 >
 > void ptrConstruct(T,bool stackOrHeap)(T*adr, T p);
 > void ptrAssign(T,bool stackOrHeap)(T*adr, T p);
 > void ptrRelease(T,bool stackOrHeap)(T*adr);
 >
 > and we are able to experiment with all kinds of sophisticated GC algorithms 
including RC. Eliding redundant addref/release pairs would need some extra 
support though, I read that LLVM does something like this, but I don't know how.
 >

It's pretty invasive into the code generation and performance, and could 
completely disrupt the C compatibility of D.


More information about the Digitalmars-d mailing list