Hey everyone,
I needed tagged pointers recently for a Swift project, so I decided to make my solution into a general Swift Package! Come take a look GitHub - joehinkle11/SwiftTaggedPointer: Tagged pointers in Swift
This particular implementation gives you 20 extra bits!
Here's some sample code of how to use it:
let x = 5
withUnsafePointer(to: x) { p in
var tp = TaggedPointer(p)
tp.bitTag0 = true
tp.bitTag1 = true
tp.bitTag2 = true
tp.dataInt17 = 23
assert(tp.getPointer() == p)
}
And here's a visual of the memory laid out.
Raw storage: |-----------------------------64 bits----------------------------|
Pointer anatomy: |--16 bits--|------1 bit-----|---- 44 bits ---|------3 bits------|
|unused bits|is kernel space?|the pointer guts|alignment artifact|
| all 0s | 0 | ??? | all 0s |
Raw storage: |-----------------------------64 bits----------------------------|
Simplified Pointer anatomy: |-----17 bits-----|--------------44 bits--------------|--3 bits--|
| all 0s | significant bits of pointer | all 0s |
|----------------------------------------------------------------|
Raw storage: |-----------------------------64 bits----------------------------|
TaggedPointer anatomy: |-------17 bits-------|------44 bits-------|--------3 bits-------|
| custom 17 bit data | pointer data | custom 3 bit tag |
| | `getPointer` | |
| | `setPointer` | |
|----------------------------------------------------------------|
|-----------------------------64 bits----------------------------|
|--------61 bits-------|-----------------3 bits------------------|
| | `tagUInt3` |
| |----1 bit----|----1 bit----|----1 bit----|
| | `bitTag2` | `bitTag1` | `bitTag0` |
|----------------------------------------------------------------|
|-----------------------------64 bits----------------------------|
|------------17 bits----------|--------------47 bits-------------|
| `dataInt17` | |
|-----16 bits-----|---1 bit---| |
| magnitude | `signBit` | |
|----------------------------------------------------------------|
|-----------------------------64 bits----------------------------|
|-----16 bits-----|---------------------48 bits------------------|
| `dataUInt16` | |
| `dataInt16` | |
|----------------------------------------------------------------|