[swift-dev] [Discussion] New refcount representation
brent at architechies.com
Wed Mar 16 15:42:39 CDT 2016
This is damned clever.
> * Allows inexpensive per-object storage for future features like associated references or class extensions with instance variables.
It sounds like you wouldn't be able to resize an out-of-band refcount allocation once it's been created, though, right? There are pointers to it all over memory; you can't track them all unless you save back references to all of them. So if you added, say, a refcount allocation-based feature for extension ivars, every refcount allocation would need to have the extra pointers to accommodate them in case you dynamically loaded code later that added an ivar in an extension. You couldn't go "whoops, need space for ivars, let's replace this recount allocation with one that has room for another pointer".
> The MSB bit also becomes set if you increment or decrement a retain count too far. That means we can implement the RR fast path with a single conditional branch after the increment or decrement:
You don't talk much about it, but I think you're suggesting that the strong and unowned refcounts would still be packed into the same fields. It's worth noting that your clever high-bit-indicates-slow-path trick would *not* work on the unowned refcount, though that matters less since it doesn't get checked as often.
> // out-of-object refcount (MSB bits 0b10x)
> // or refcount has overflowed (MSB bits 0b111)
> // or refcount is constant (MSB bits 0b110)
Is this going to work on 32-bit? Even if we assume that valid pointers don't start with 0b1, can we assume that they don't start with 1b01?
> The side allocation would store a pointer to the object and a strong refcount and a weak refcount. (This weak refcount would be distinct from the unowned refcount.) The weak refcount would be incremented once for every weak variable holding this object.
> The advantage of using a side allocation for weak references is that the storage for a weakly-referenced object could be freed synchronously when deinit completes. Only the small side allocation would remain, backing the weak variables until they are cleared on their next access. This is a memory improvement over today's scheme, which keeps the object's entire storage alive for a potentially long time.
> The hierarchy:
> Strong refcount goes to zero: deinit
> Unowned refcount goes to zero: free the object
> Weak refcount goes to zero: free the side allocation
I take it the refcount field's pointer is itself considered a weak reference, so the weak refcount starts +1 like the unowned refcount does?
More information about the swift-dev