@@ -60,6 +60,9 @@ class StackAllocator {
60
60
// / True if the first slab is pre-allocated.
61
61
bool firstSlabIsPreallocated;
62
62
63
+ // / The minimal alignment of allocated memory.
64
+ static constexpr size_t alignment = alignof (std::max_align_t );
65
+
63
66
// / If set to true, memory allocations are checked for buffer overflows and
64
67
// / use-after-free, similar to guard-malloc.
65
68
static constexpr bool guardAllocations =
@@ -90,11 +93,21 @@ class StackAllocator {
90
93
assert ((size_t )capacity == newCapacity && " capacity overflow" );
91
94
}
92
95
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
+
93
106
// / Return the payload buffer address at \p atOffset.
94
107
// /
95
108
// / Note: it's valid to call this function on a not-yet-constructed slab.
96
109
char *getAddr (size_t atOffset) {
97
- return (char *)( this + 1 ) + atOffset;
110
+ return (char *)this + headerSize ( ) + atOffset;
98
111
}
99
112
100
113
// / Return true if this slab can fit an allocation of \p size.
@@ -162,23 +175,20 @@ class StackAllocator {
162
175
previous (previous), slab(slab) {}
163
176
164
177
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));
166
184
}
167
185
168
186
// / Return \p size with the added overhead of the allocation header.
169
187
static size_t includingHeader (size_t size) {
170
- return size + sizeof (Allocation) ;
188
+ return headerSize () + size ;
171
189
}
172
190
};
173
191
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
-
182
192
// Return a slab which is suitable to allocate \p size memory.
183
193
Slab *getSlabForAllocation (size_t size) {
184
194
Slab *slab = (lastAllocation ? lastAllocation->slab : firstSlab);
@@ -204,7 +214,7 @@ class StackAllocator {
204
214
}
205
215
size_t capacity = std::max (SlabCapacity,
206
216
Allocation::includingHeader (size));
207
- void *slabBuffer = malloc (sizeof ( Slab) + capacity);
217
+ void *slabBuffer = malloc (Slab::includingHeader ( capacity) );
208
218
Slab *newSlab = new (slabBuffer) Slab (capacity);
209
219
if (slab)
210
220
slab->next = newSlab;
@@ -235,10 +245,12 @@ class StackAllocator {
235
245
236
246
// / Construct a StackAllocator with a pre-allocated first slab.
237
247
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));
239
250
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 ());
242
254
firstSlabIsPreallocated = true ;
243
255
}
244
256
0 commit comments