The atomic RCing can be done like so:
proc incRef(x: ptr ObjectHeader) =
let allocator = regionof(x)
if allocator.isShared: atomicInc(x.rc)
else: inc(x.rc)
Run
The allocator proposal assumes an efficient `regionof` operation, most likely
to be implemented via pointer masking with a compile-time constant (alignment
by 64K seems to be good value for modern machines). Every allocator then must
ensure that this pointer masking leads to an allocator control block:
type
AllocatorFlag* {.pure.} = enum ## flags describing the properties of the
allocator
ThreadLocal ## the allocator is thread local only.
ZerosMem ## the allocator always zeros the memory on an allocation
Allocator* = ptr AllocatorObj
AllocatorObj* {.inheritable.} = object
alloc*: proc (a: Allocator; size: int; alignment: int = 8): pointer
{.nimcall, raises: [], tags: [].}
dealloc*: proc (a: Allocator; p: pointer; size: int) {.nimcall, raises:
[], tags: [].}
realloc*: proc (a: Allocator; p: pointer; oldSize, newSize: int):
pointer {.nimcall, raises: [], tags: [].}
deallocAll*: proc (a: Allocator) {.nimcall, raises: [], tags: [].}
flags*: set[AllocatorFlag]
name*: cstring
allocCount: int
deallocCount: int
Run
The only downside is that most existing allocators do not adhere to this
design. :-)