[swift-dev] [Discussion] New refcount representation
brent at architechies.com
Wed Mar 16 16:35:12 CDT 2016
>> 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.
> My understanding is that there would not be an unowned refcount here (inline in the object). The first time you make a weak reference to the object it gets converted to have the out-of-band refcount structure, and the strong and unowned refcounts both get stored there (in an undefined-by-this-proposal way).
Note this line in the proposal:
>>> (This weak refcount would be distinct from the unowned refcount.)
My understanding is that there are three refcounts:
* The (new) weak refcount represents claims on the refcount allocation. It (perhaps) starts +1 because the object's refcount field is a claim on the refcount allocation. When it goes to 0, the refcount allocation is freed.
* The unowned refcount represents claims on the object's allocation. It starts +1 because the strong refcount is a claim on the object's allocation. When it goes to 0, the refcount allocation's backreference is nulled (if there is one), the weak refcount is decremented (if it exists), and the object is freed.
* The strong refcount represents ownership of the object. It starts +1 because the initializer owns the object. When it goes to 0, the object is marked as deinitializing, `deinit`s are run, and the unowned refcount is decremented.
(The backreference might be cut when the strong refcount goes to zero; it doesn't make much difference either way.)
It sounds to me like this proposal is saying:
* There is a pointer-sized refcount field in each object.
* If the high bit is clear, ~half of its bytes are used for the strong refcount and the rest are used for the unowned refcount, with a few bits somewhere used for various flags.
* If the high bit is set, the remaining bits are a pointer to an allocation containing strong, unowned, and weak refcounts, plus any other stuff we might add later.
* We switch from inline refcount to pointer to refcount when one of the refcounts overflow, a weak reference is formed, or one of the future features we might add later are used. We switch from pointer to refcount to inline refcount never.
More information about the swift-dev