[swift-dev] [Discussion] New refcount representation

John Calsbeek john.calsbeek+lists at gmail.com
Wed Mar 16 23:20:58 CDT 2016

> One scheme that I want to investigate for ObjC's use is to allocate a flat array of side allocations, and store an index into that array in the isa field's extra bits. Depending on architecture that allows between 256K and 64M objects with side allocations before falling back to a global table. If that works well enough then packing everything into a single pointer-size field becomes more plausible.
> Joe, did you measure the cost of a mask operation at every Swift virtual call? I can't remember.

This is a totally harebrained idea, but: if a mask at every call site is acceptable and you admit restrictions about where in the virtual address space vtables can be allocated, *and* you do the flat array of side allocations, you can get back a lot of bits.

Example (for 64-bit):

     1 bit   is deallocating
     1 bit   is pinned
    18 bits  side allocation index
    20 bits  vtable pointer high
     2 bits  00 (ordinary) or 11 (strong refcount is constant)
    10 bits  strong refcount
     4 bits  vtable pointer low
     8 bits  unowned refcount

Mask this with 0x00000fffff000f00 and you get a pointer with 256-byte alignment that can range over a 44-bit address space with a stride of 16 MB—hopefully enough flexibility to find some unused virtual address space. Unfortunately with this layout you can only fit 16 vtables in one 4k page, so it’s not particularly TLB-friendly.

I can think of several dozen ways this might fall over, plus it’s starting to be a pretty complicated layout to inline and make ABI-stable, but it’s an idea.

> My biggest concern is future Swift concurrency support. I suspect we will want storage for a thread ID or a lock. Maybe those would be uncommon enough that they can live in a side allocation. Will we want a thread ID in every thread-local object in production code so we can assert that it has not incorrectly escaped, or can we leave things like that for debug builds only?

I don’t know anything about the possible future concurrency use cases, but I certainly hope we won’t need a lock in every object in the fast path.

More information about the swift-dev mailing list