My understanding is that since the slice only needs 36 bytes (9 × 4), the allocator pads it with 28 bytes to fill out the 64-byte alignment boundary.
If I then realloc the slice to a larger capacity:
allocator.realloc(self.data, 16);
The new capacity (64 bytes) fits within the original allocation including the padding. In this case, does realloc guarantee an in-place expansion when the new size fits within the old buffer plus its alignment padding?
That’s not a guarantee that the Allocator interface makes. It seems like resize might be more in line with what you’re looking for (but you’d also need to handle the possibility of false being returned).
My understanding is that […] the allocator pads it
That’d be up to the particular Allocatorimplementation, which is free to handle it however it wants. The behavior that’s consistent between Allocator implementations is what’s documented in the Allocator interface.
Alignment has no effect on the size of what it point to nor implies padding, it only means that the address of it is aligned.
So, there is no guarantee the realloc succeeds or is in-place. If you need to guarantee a size change to be in-place, then you should use Allocator.resize. Even then, there is no guarantee that a shrink will succeed (consider the implementation of std.heap.SmpAllocator where allocations have different size classes and shrinking an allocation could change its class).
I understand it now. The only guarantee alignedAlloc provides is that the data starts at an address that is multiple of the alignment value. Aligned memory address are useful in the case of SIMD instructions, where CPU can load register worth data in one instruction.