[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
NSDecrementExtraRefCountWasZero
From: |
David Chisnall |
Subject: |
NSDecrementExtraRefCountWasZero |
Date: |
Wed, 29 Nov 2017 12:43:45 +0000 |
Hello the list,
In trying to reduce lock contention for deallocation, I took a bit from the
reference count to indicate that weak references exist to an object (and
therefore avoid any serialisation on deallocation). Unfortunately, when
Andreas tried testing it, he discovered that this broke
NSDecrementExtraRefCountWasZero (and, in theory, NSIncrementExtraRefCount,
though not in a way that’s likely to be observable).
On OS X, this function is unavailable in ARC mode and comes with a warning that
if any code uses ARC then it may give surprising results.
Looking in GNUstep, it appears that this is called in only a small number of
places:
- NSObject is using it, but probably should just be calling objc_retain() /
objc_release() / objc_autorelease() (the runtime will call these directly
instead of retain / release anyway). NSProxy, similarly, should simply be
calling the relevant functions.
- A few classes are calling it to avoid deallocation of objects that are in a
table for reuse.It’s also not clear whether this is still a win: we’ll get more
cache contention from refcount manipulations if the objects are small, such as
NSIndexPath (though it is required for correctness in a few cases, such as
NSConnection). In these cases, if the runtime supports ARC then we can simply
use a strong-to-weak NSHashTable and get rid of most of this logic.
I’d like to start making these changes, and expose some new libobjc2 functions
that can provide the functionality of NSDecrementExtraRefCountWasZero
(NSIncrementExtraRefCount can be a trivial wrapper around objc_retain().
Currently, the only way I can see of implementing
NSDecrementExtraRefCountWasZero on top of the ARC APIs that I can see is to
take a weak reference to the object, release it, and then see if the reference
is 0.
It’s also worth noting that both NSDecrementExtraRefCountWasZero and
NSIncrementExtraRefCount are currently broken (and will cause memory
corruption) if called on blocks (or classes, constant strings, and so on).
David
- NSDecrementExtraRefCountWasZero,
David Chisnall <=