[Dlang-study] [lifetime] Initial thoughts on lifetime management

Timon Gehr timon.gehr at gmx.ch
Wed Oct 28 15:39:56 PDT 2015


On 10/28/2015 08:20 PM, Andrei Alexandrescu wrote:
> On 10/28/2015 02:00 PM, Timon Gehr wrote:
>>> void bar() {
>>>      C c = new C();
>>>      [[auto __t = c; __t.refs += 2;]]
>>>      foo(c, c);
>>>      [[__t.refs -= 2;]]
>>> }
>>
>> +=2 seems arbitrary. Only one new reference is generated.
>
> I was thinking conservatively - add 1 for anything passed in, whether by
> value or reference.
> ...

By reference does not actually pass in the reference, but a reference to 
the reference. Ultimately there is no difference. RC does not care about 
how many times the same reference is counted, as long as it is counted 
with the same (positive) multiplicity when it is generated as when it is 
destroyed.

> Generally I'm very optimistic about conservative analyses - analyses
> that look at a function statically and conclude that the reference count
> can't go beyond e.g. 12 or whatever. Then upon object creation there's
> __t.refs+=12 and upon exit there's a __t-=12 and inside the function
> proper there's no other refcount bump.
>
> Basic idea being +=1 or +=100 have the same cost, and refcount doesn't
> need to precisely reflect the number of references, only >=. We can
> exploit these facts.
> ...

Actually, we do not need #references <= count.
It's just (#references > 0) -> (count > 0).
(The converse should also hold, but then #references has to include 
cyclic references.)

> (There are other analyses that compute conservative bounds, such as our
> well-known VRP or computing the stack frame size for a function.)
> ...

The analysis does not need to determine the maximal number of increments 
in the scope. They can in principle all be fused into one inc upon 
object creation and one dec upon exit (both multiplicity 1), with the 
obvious caveat that the reference may now live longer than before the 
transformation. Increments are then only necessary within the method 
body if there is a chance that the copied reference escapes.

>> Anyway, the solution is indeed to make it the responsibility of the
>> caller to keep the borrowed object alive. I.e. when passing a non-scope
>> reference to a scope argument, the reference count must be increased for
>> the duration of the call. The benefit is that scope references can be
>> duplicated arbitrarily without updating the reference count.
>> This applies to globals just as well as to other cases.
>
> Sounds interesting. So it looks like one additional hidden variable per
> reference created in a scope may be necessary in order to avoid
> complicated inc/dec for references.
> ...

IMHO it's not all that complicated even without the lowering.



More information about the Dlang-study mailing list