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

Reply via email to