I'm currently using "fat" reference types to isolate state across threads. The maximum size of said state is capped to some known-at-compile-time-but-ideally-easy-to-change size. For the most part, I'm using that memory either as raw bytes, or bound to an array of small, fixed-size structs.
My assertions / assumptions are:
- the number of objects is dynamic but their individual sizes are fixed
- the number of objects will steadily grow until some arbitrary cpu limit kicks in, then mostly remain constant
- memory management is fast, but there are probably some locks involved somewhere
For these reasons, I would like to (eventually) use an arena allocator but, while my objects are fixed in size, they are composed out of smaller structs (nominally non-copyable, but I had to relax that a bit and add a reset()
method due to known bugs / limitations in the language). Unfortunately, all of them are currently using Buffer.allocate(static_size)
which results in another reference. I could use Array
but, that too is a reference pretending to be a value under the hood.
Ideally this would work for both structs and references, but since I plan on using pools anyway, I could live with a reference-only solution (I'd just allocate everything once and pool the top-level objects). On references, I could use the undocumented _getUnsafePointerToStoredProperties
method, wrap all other state in a local struct and add MemoryLayout<local_state>
to get the address of the "trailer" but I still have no way of telling the compiler to reserve some bytes for storage:
class Something {
struct Header {
var size = 0
var isItMonday = true
}
private var header = Header()
private var storage: UnsafeMutableRawPointer { _getUnsafePointerToStoredProperties(self) + MemoryLayout<Header>.stride }
private var trailer: ???
}
I'd prefer something other than mental bit masking:
struct B16 { var a = Int64(0), b = Int64(0) }
struct B32 { var a = B16(), b = B16() }
struct B64 { var a = B32(), b = B32() }
// ...
struct Trailer { var a = B64(), b = B32(), c = B16(), d = Int8(0) } // 113 (120) bytes