I'm writing an allocator, and I have a type whose layout is logically:
struct Slab<T> {
hdr: SlabHeader<T>,
objects: [SlabObject<T>],
}
However, for performance, I'm not actually using [SlabObject<T>]
, and instead modifying memory directly and just "knowing" how long the array of objects is (how I know isn't relevant here). I'm not storing the length in the Slab<T>
itself, so objects
is an array of SlabObject<T>
in the C sense.
Currently, in order to do this, I do some somewhat-expensive computation in order to figure out what the padding after the hdr
field needs to be in order for objects
to be aligned to mem::align_of::<SlabObject<T>>()
. I then save the result of that computation and use it later.
However, I'd like to avoid having to pass around that computed data and instead just have the compiler bake this in. Is there a way for me to do that? For example, one (incorrect) attempt might be to make a struct like this:
struct VirtualSlab<T> {
hdr: SlabHeader<T>,
first_object: SlabObject<T>,
}
and then figure out the offset of the first_object
field from the beginning of the struct using, for example, the method described here. Unfortunately, the compiler might re-order the fields, and so there's no guarantee that I'll get the answer that I want.
Is there some other way I can do this? To clarify, here are my constraints:
- I know that the entire
Slab<T>
will be aligned to an alignment greater than the alignment ofSlabHeader<T>
. I don't know what that alignment is at compile time, but I don't think that matters. - I need the offset into
Slab<T>
ofobjects
such that bothhdr
andobjects
are aligned as required by the typesSlabHeader<T>
andSlabObject<T>
respectively.