@@ -227,15 +227,17 @@ class Block {
227
227
*new (&next ()->prev_ ) size_t = outer_size ();
228
228
}
229
229
230
- // / Marks this block as the last one in the chain. Makes next() return
231
- // / nullptr.
232
- LIBC_INLINE void mark_last () { next_ |= LAST_MASK; }
233
-
234
- LIBC_INLINE Block ( size_t outer_size) : next_(outer_size) {
235
- LIBC_ASSERT ( outer_size % alignof (max_align_t ) == 0 &&
236
- " block sizes must be aligned" );
230
+ LIBC_INLINE Block ( size_t outer_size, bool is_last) : next_(outer_size) {
231
+ // Last blocks are not usable, so they need not have sizes aligned to
232
+ // max_align_t. Their lower bits must still be free, so they must be aligned
233
+ // to Block.
234
+ LIBC_ASSERT (
235
+ outer_size % (is_last ? alignof (Block) : alignof ( max_align_t ) ) == 0 &&
236
+ " block sizes must be aligned" );
237
237
LIBC_ASSERT (is_usable_space_aligned (alignof (max_align_t )) &&
238
238
" usable space must be aligned to a multiple of max_align_t" );
239
+ if (is_last)
240
+ next_ |= LAST_MASK;
239
241
}
240
242
241
243
LIBC_INLINE bool is_usable_space_aligned (size_t alignment) const {
@@ -325,7 +327,13 @@ class Block {
325
327
LIBC_ASSERT (reinterpret_cast <uintptr_t >(bytes.data ()) % alignof (Block) ==
326
328
0 &&
327
329
" block start must be suitably aligned" );
328
- return ::new (bytes.data ()) Block (bytes.size ());
330
+ return ::new (bytes.data ()) Block (bytes.size (), /* is_last=*/ false );
331
+ }
332
+
333
+ LIBC_INLINE static void make_last_block (cpp::byte *start) {
334
+ LIBC_ASSERT (reinterpret_cast <uintptr_t >(start) % alignof (Block) == 0 &&
335
+ " block start must be suitably aligned" );
336
+ ::new (start) Block (sizeof (Block), /* is_last=*/ true );
329
337
}
330
338
331
339
// / Offset from this block to the previous block. 0 if this is the first
@@ -353,7 +361,7 @@ class Block {
353
361
static constexpr size_t PREV_FIELD_SIZE = sizeof (prev_);
354
362
};
355
363
356
- static_assert (alignof (max_align_t ) >= 4 ,
364
+ static_assert (alignof (Block ) >= 4 ,
357
365
" at least 2 bits must be available in block sizes for flags" );
358
366
359
367
LIBC_INLINE
@@ -380,9 +388,8 @@ optional<Block *> Block::init(ByteSpan region) {
380
388
auto *last_start_ptr = reinterpret_cast <cpp::byte *>(last_start);
381
389
Block *block =
382
390
as_block ({reinterpret_cast <cpp::byte *>(block_start), last_start_ptr});
383
- Block *last = as_block ({ last_start_ptr, sizeof (Block)} );
391
+ make_last_block ( last_start_ptr);
384
392
block->mark_free ();
385
- last->mark_last ();
386
393
return block;
387
394
}
388
395
0 commit comments