Hi, I would like to share a concept that I implemented and works, maybe could work in swift since it is about ref-counting objects.
The idea is every ref object pointer carries a one‑bit tag in its lowest bit:
-
Own_Ref(bit = 1) – owns the object; responsible for decrementing the reference count onrelease. -
Borrow_Ref(bit = 0) – a non‑owning view;releaseis a no‑op, meaning after checking the bit.
The api is
| Operation | Meaning | Input → Output | RC Change |
|---|---|---|---|
borrow(x) |
Create a borrowed view. | Any → Borrow_Ref |
None |
transfer(x) |
Move a reference unchanged. | Own → Own, Borrow → Borrow | None |
own(x) |
Promote to Own_Ref if needed, ex. when the pointer is returned. |
Borrow → Own (RC++) Own → Own (no‑op) |
Only if Borrowed |
share(x) |
Create an independent owner. | Any → Own_Ref |
Always RC++ |
release(x) |
Drop this reference. | Own → RC-- (free if 0) Borrow → nothing |
Only if Owned |
Here using liveness for insertion on a single thread
Function call
x liveness |
Operation | Release x? |
|---|---|---|
| Live after call | callee(borrow(x)) |
- |
| Dead after call | callee(transfer(x)) |
No, responsibility moved |
v = get(obj, f) operartion
v liveness |
Operation |
|---|---|
| Live after | v = share(raw_get(obj, f)) |
| Dead after | v = borrow(raw_get(obj, f)) |
set(obj, f, val) operation
release(transfer(raw_get(obj, f)))– always release the old field value.- Then:
val liveness |
Operation | Release val ? |
|---|---|---|
| Dead after | raw_set(obj, f, own(val)) |
No,responsability moved |
| Live after | raw_set(obj, f, share(val)) |
- |
Example of optimization:
share->borrowwhen the pointer is does not escapeown->transferwhen the previous pointer is dead.
More optimization could be done, whenever it is safe to do.
This is not a complete description, it is about summarizing the idea.