@@ -60,6 +60,9 @@ class StackAllocator {
6060 // / True if the first slab is pre-allocated.
6161 bool firstSlabIsPreallocated;
6262
63+ // / The minimal alignment of allocated memory.
64+ static constexpr size_t alignment = alignof (std::max_align_t );
65+
6366 // / If set to true, memory allocations are checked for buffer overflows and
6467 // / use-after-free, similar to guard-malloc.
6568 static constexpr bool guardAllocations =
@@ -90,11 +93,21 @@ class StackAllocator {
9093 assert ((size_t )capacity == newCapacity && " capacity overflow" );
9194 }
9295
96+ // / The size of the slab header.
97+ static size_t headerSize () {
98+ return llvm::alignTo (sizeof (Slab), llvm::Align (alignment));
99+ }
100+
101+ // / Return \p size with the added overhead of the slab header.
102+ static size_t includingHeader (size_t size) {
103+ return headerSize () + size;
104+ }
105+
93106 // / Return the payload buffer address at \p atOffset.
94107 // /
95108 // / Note: it's valid to call this function on a not-yet-constructed slab.
96109 char *getAddr (size_t atOffset) {
97- return (char *)( this + 1 ) + atOffset;
110+ return (char *)this + headerSize ( ) + atOffset;
98111 }
99112
100113 // / Return true if this slab can fit an allocation of \p size.
@@ -162,23 +175,20 @@ class StackAllocator {
162175 previous (previous), slab(slab) {}
163176
164177 void *getAllocatedMemory () {
165- return (void *)(this + 1 );
178+ return (char *)this + headerSize ();
179+ }
180+
181+ // / The size of the allocation header.
182+ static size_t headerSize () {
183+ return llvm::alignTo (sizeof (Allocation), llvm::Align (alignment));
166184 }
167185
168186 // / Return \p size with the added overhead of the allocation header.
169187 static size_t includingHeader (size_t size) {
170- return size + sizeof (Allocation) ;
188+ return headerSize () + size ;
171189 }
172190 };
173191
174- static constexpr size_t alignment = alignof (std::max_align_t );
175-
176- static_assert (sizeof (Slab) % StackAllocator::alignment == 0 ,
177- " Slab size must be a multiple of the max allocation alignment" );
178-
179- static_assert (sizeof (Allocation) % StackAllocator::alignment == 0 ,
180- " Allocation size must be a multiple of the max allocation alignment" );
181-
182192 // Return a slab which is suitable to allocate \p size memory.
183193 Slab *getSlabForAllocation (size_t size) {
184194 Slab *slab = (lastAllocation ? lastAllocation->slab : firstSlab);
@@ -204,7 +214,7 @@ class StackAllocator {
204214 }
205215 size_t capacity = std::max (SlabCapacity,
206216 Allocation::includingHeader (size));
207- void *slabBuffer = malloc (sizeof ( Slab) + capacity);
217+ void *slabBuffer = malloc (Slab::includingHeader ( capacity) );
208218 Slab *newSlab = new (slabBuffer) Slab (capacity);
209219 if (slab)
210220 slab->next = newSlab;
@@ -235,10 +245,12 @@ class StackAllocator {
235245
236246 // / Construct a StackAllocator with a pre-allocated first slab.
237247 StackAllocator (void *firstSlabBuffer, size_t bufferCapacity) {
238- char *start = (char *)llvm::alignAddr (firstSlabBuffer, llvm::Align (alignment));
248+ char *start = (char *)llvm::alignAddr (firstSlabBuffer,
249+ llvm::Align (alignment));
239250 char *end = (char *)firstSlabBuffer + bufferCapacity;
240- assert (start + sizeof (Slab) <= end && " buffer for first slab too small" );
241- firstSlab = new (start) Slab (end - start - sizeof (Slab));
251+ assert (start + Slab::headerSize () <= end &&
252+ " buffer for first slab too small" );
253+ firstSlab = new (start) Slab (end - start - Slab::headerSize ());
242254 firstSlabIsPreallocated = true ;
243255 }
244256
0 commit comments