[Dlang-study] [lifetime] Initial thoughts on lifetime management
Andrei Alexandrescu
andrei at erdani.com
Wed Oct 28 12:20:51 PDT 2015
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.
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.
(There are other analyses that compute conservative bounds, such as our
well-known VRP or computing the stack frame size for a function.)
> 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.
> (I haven't read DIP74 though, so I might be misinterpreting your
> intentions.)
I'm glad you didn't because (a) it's better to have a fresh mind, (b)
DIP74 has progressively integrated cases we hadn't thought of, and
became a mess.
Andrei
More information about the Dlang-study
mailing list