draft proposal for ref counting in D

Walter Bright newshound2 at digitalmars.com
Wed Oct 9 17:03:37 PDT 2013


Steven Schveighoffer wrote:


On Jun 25, 2013, at 4:44 PM, Walter Bright wrote:

 >
 > On 6/25/2013 1:19 PM, Steven Schveighoffer wrote:
 >>
 >> Would this be a mechanism that's worth putting in? I think it goes really 
well with something like TempAlloc.  I don't think we should use convention, 
though...
 >
 > I agree with not relying on convention. But also reserving the new*, init*, 
alloc* and copy* namespaces seems excessive for D.
 >
 > As for autoreleasepool, it is relying on a convention that its fields are not 
leaking. I don't see how we can enforce this.

I don't think the autoreleasepool is relying on convention, it's simply giving 
the compiler a way to elide careful tracking of temporaries' reference counts.

It was definitely of more use when manual reference counting was done, because 
one only had to worry about retaining non-temporary data in that case.

But the compiler can make the same optimizations (and does in the ARC version of 
Objective-C).

Consider the following code:

NSString *str = [NSString stringWithFormat:@"%d", 5];

// translating to D, that would be something like:
NSString str = NSString.stringWithFormat("%d", 5);

stringWithFormat is a class method that gives you back a temporary string.  You 
are not asserting ownership, you are just assigning to a variable.

Now, if you wanted to do some fancy stuff with str, we could do:

{
NSString str2;

{
    NSString str = NSString.stringWithFormat("%d", 5);
    if(condition)
        str2 = str;
    if(otherCondition)
    {
        NSString str3 = str;
        str = NSString.stringWithFormat("%d", 6);
    }
}

str2 = str;
}

Now, in all this mess, how is the compiler to sort out the AddRefs and Releases? 
  Most likely, it will end up adding more than it needs to.

But with autorelease pool, it's like you did this:

AutoReleasePool arp;
{
NSString str2;

{
    NSString str = NSString.stringWithFormat("%d", 5);
    arp.add(str);
    if(condition)
        str2 = str;
    if(otherCondition)
    {
        NSString str3 = str;
        str = NSString.stringWithFormat("%d", 6);
        arp.add(str);
    }
}

str2 = str;
}
arp.drain(); // releases both strings used, don't care what now-out-of-scope 
variables

Essentially, they are only retained when created, and because they go out of 
scope, they are no longer needed.

The compiler can surmise that because the fields aren't leaving the scope, it 
doesn't have to retain them.  If it does see that, it adds a retain.

Then, it can release them all at once.

In fact, this could be done automatically, but you have to allocate a place to 
put these 'scheduled for release' things. In Cocoa, the main event loop has an 
auto release pool, and you can add them manually wherever you wish for more 
fine-grained memory management (that is, if you wanted to free objects before 
you left the event loop).

Note that in Objective-C, they use those naming conventions to determine whether 
an object is auto-released or not.  But we could make sure it's *always* 
auto-released, as we don't have the historical requirements that Objective-C 
has.  The question is, does it make sense to use this technique to "lump 
together" deallocations instead of conservatively calling retain/release 
wherever you assign variables (like C++ shared_ptr)?  And a further question is 
whether the compiler should pick those points, or whether they should be picked 
manually.

-Steve



More information about the Digitalmars-d mailing list