[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]


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 

- 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).


reply via email to

[Prev in Thread] Current Thread [Next in Thread]