DIP60: @nogc attribute
Steven Schveighoffer via Digitalmars-d
digitalmars-d at puremagic.com
Fri Apr 18 05:55:59 PDT 2014
On Fri, 18 Apr 2014 01:53:00 -0400, Walter Bright
<newshound2 at digitalmars.com> wrote:
> On 4/17/2014 6:58 PM, Michel Fortin wrote:
>> Auto-nulling weak references are perfectly memory-safe. In Objective-C
>> you use
>> the __weak pointer modifier for that. If you don't want it to be
>> auto-nulling,
>> use __unsafe_unretained instead to get a raw pointer. In general, seeing
>> __unsafe_unretained in the code is a red flag however. You'd better
>> know what
>> you're doing.
>>
>> If you could transpose the concept to D, __weak would be allowed in
>> @safe
>> functions while __unsafe_unretained would not. And thus memory-safety
>> is preserved.
>
> I recall our email discussion about implementing ARC in D that we
> couldn't even avoid an inc/dec for the 'this' when calling member
> functions. So I don't see how inc/dec can be elided in sufficient
> numbers to make ARC performant and unbloated.
The important thing to recognize is that it's the *caller* that
increments/decrements. This means you can elide calls to an object where
you already have a guarantee of its reference count being high enough.
I looked up the example you referred to, it was this:
> class R : RefCounted
> {
> int _x;
> int readx() { return _x; }
> }
> int main()
> {
> R r = new R;
> return r.readx();
> }
>According to 12. there is no refcounting going on when calling or
> executing readx. Ok, now what happens here:
>class R : RefCounted
> {
> int _x;
> int readx(C c)
> {
> c.r = null; // "standard" rc deletes r here
> return _x; // reads garbage
> }
> }
> class C
> {
> R r;
> }
> int main()
> {
> C c = new C;
> c.r = new R;
> return c.r.readx(c);
> }
>This reads garbage or crashes if there is no reference counting going on
> when calling readx.
So essentially, main needs to increment c.r's ref count. But not c's,
because it already knows that it owns one of c's reference counts. R.readx
does NOT need to increment its own reference count.
I think the distinction is important.
Also, consider if R is a final class, it can inline readx and can possibly
defer incrementing the ref count for later, or cache _x before setting c.r
to null (probably the better option).
Opportunities for elision are not as hopeless as you make it sound. The
compiler has a lot of information.
The rules should be:
1. when compiling a function, you can assume parameters have at least one
reference count increment that will not go away.
2. When passing an object into a function, ensure #1 is true for that
function.
Given D's type system of knowing when variables are shared (and if we
implement thread-local destruction of unshared data), we have a lot more
power even than Objective-C to make better decisions on ref counting.
> Of course, you can always *manually* elide these things, but then if you
> make a mistake, then you've got a leak and memory corruption.
Manual eliding should be reserved for extreme optimization cases. It's
similar to cast. Apple considers it dangerous enough to statically
disallow it for ARC code.
-Steve
More information about the Digitalmars-d
mailing list