Lines Matching full:block

1 //===-- Unittests for a block of memory -------------------------*- C++ -*-===//
13 #include "src/__support/block.h"
17 using LIBC_NAMESPACE::Block;
27 auto result = Block::init(bytes);
29 Block *block = *result;
31 EXPECT_EQ(reinterpret_cast<uintptr_t>(block) % alignof(Block), size_t{0});
32 EXPECT_TRUE(block->is_usable_space_aligned(alignof(max_align_t)));
34 Block *last = block->next();
35 ASSERT_NE(last, static_cast<Block *>(nullptr));
36 EXPECT_EQ(reinterpret_cast<uintptr_t>(last) % alignof(Block), size_t{0});
38 EXPECT_EQ(last->outer_size(), sizeof(Block));
39 EXPECT_EQ(last->prev_free(), block);
43 reinterpret_cast<uintptr_t>(last) - reinterpret_cast<uintptr_t>(block);
44 EXPECT_EQ(block->outer_size(), block_outer_size);
45 EXPECT_EQ(block->inner_size(),
46 block_outer_size - sizeof(Block) + Block::PREV_FIELD_SIZE);
47 EXPECT_EQ(block->prev_free(), static_cast<Block *>(nullptr));
48 EXPECT_FALSE(block->used());
58 auto result = Block::init(aligned.subspan(1));
61 Block *block = *result;
62 EXPECT_EQ(reinterpret_cast<uintptr_t>(block) % alignof(Block), size_t{0});
63 EXPECT_TRUE(block->is_usable_space_aligned(alignof(max_align_t)));
65 Block *last = block->next();
66 ASSERT_NE(last, static_cast<Block *>(nullptr));
67 EXPECT_EQ(reinterpret_cast<uintptr_t>(last) % alignof(Block), size_t{0});
72 auto result = Block::init(bytes);
79 // Choose a split position such that the next block's usable space is 512
82 const size_t kSplitN = Block::inner_size(512);
85 auto result = Block::init(bytes);
96 kSplitN - Block::PREV_FIELD_SIZE + sizeof(Block));
100 EXPECT_EQ(reinterpret_cast<uintptr_t>(block2) % alignof(Block), size_t{0});
111 auto result = Block::init(bytes);
113 Block *block1 = *result;
120 Block *block2 = *result;
126 EXPECT_EQ(reinterpret_cast<uintptr_t>(block2) % alignof(Block), size_t{0});
134 // split once, then split the original block again to ensure that the
137 // [[ BLOCK 1 ]]
148 auto result = Block::init(bytes);
150 Block *block1 = *result;
154 Block *block2 = *result;
158 Block *block3 = *result;
170 auto result = Block::init(bytes);
172 Block *block = *result;
174 result = block->split(block->inner_size() + 1);
182 auto result = Block::init(bytes);
184 Block *block = *result;
186 result = block->split(block->inner_size() - sizeof(Block) + 1);
191 // Ensure that we can't ask for more space than the block actually has...
195 auto result = Block::init(bytes);
197 Block *block = *result;
199 result = block->split(block->inner_size() + 1);
204 // This block does support splitting with minimal payload size.
208 auto result = Block::init(bytes);
210 Block *block = *result;
212 result = block->split(0);
214 EXPECT_LE(block->outer_size(), sizeof(Block) + alignof(max_align_t));
218 // Likewise, the split block can be minimal-width.
222 auto result = Block::init(bytes);
224 Block *block1 = *result;
226 result = block1->split(Block::prev_possible_block_start(
229 Block::PREV_FIELD_SIZE);
231 EXPECT_LE((*result)->outer_size(), sizeof(Block) + alignof(max_align_t));
238 auto result = Block::init(bytes);
240 Block *block = *result;
241 size_t orig_size = block->outer_size();
243 block->mark_used();
244 EXPECT_TRUE(block->used());
245 EXPECT_EQ(block->outer_size(), orig_size);
247 block->mark_free();
248 EXPECT_FALSE(block->used());
256 auto result = Block::init(bytes);
258 Block *block = *result;
260 block->mark_used();
261 result = block->split(kSplitN);
267 // merge block 3 and 2
272 auto result = Block::init(bytes);
274 Block *block1 = *result;
283 Block *block3 = *result;
298 auto result = Block::init(bytes);
300 Block *block1 = *result;
305 Block *block2 = *result;
315 auto result = Block::init(bytes);
317 Block *block = *result;
320 result = block->split(kSplitN);
323 block->mark_used();
324 EXPECT_FALSE(block->merge_next());
329 auto result = Block::init(bytes);
331 Block *block1 = *result;
334 Block *block2 = Block::from_usable_space(ptr);
342 auto result = Block::init(bytes);
344 const Block *block1 = *result;
347 const Block *block2 = Block::from_usable_space(ptr);
354 // Ensure we can allocate everything up to the block size within this block.
357 auto result = Block::init(bytes);
359 Block *block = *result;
361 if (i > block->inner_size())
364 auto info = Block::allocate(block, alignof(max_align_t), i);
365 EXPECT_NE(info.block, static_cast<Block *>(nullptr));
371 auto result = Block::init(bytes);
373 Block *block = *result;
376 if (Block::min_size_for_allocation(alignment, 1) > block->inner_size())
379 auto info = Block::allocate(block, alignment, 1);
380 EXPECT_NE(info.block, static_cast<Block *>(nullptr));
388 auto result = Block::init(bytes);
390 Block *block = *result;
391 uintptr_t orig_end = reinterpret_cast<uintptr_t>(block) + block->outer_size();
393 constexpr size_t SIZE = Block::PREV_FIELD_SIZE + 1;
396 Block::allocate(block, alignof(max_align_t), SIZE);
398 // Since this is already aligned, there should be no previous block.
399 EXPECT_EQ(prev, static_cast<Block *>(nullptr));
401 // Ensure we the block is aligned and large enough.
402 EXPECT_NE(aligned_block, static_cast<Block *>(nullptr));
406 // Check the next block.
407 EXPECT_NE(next, static_cast<Block *>(nullptr));
416 auto result = Block::init(bytes);
418 Block *block = *result;
420 uintptr_t orig_end = reinterpret_cast<uintptr_t>(block) + block->outer_size();
423 // it. We want to explicitly test that the block will split into one before
426 while (block->is_usable_space_aligned(alignment))
429 auto [aligned_block, prev, next] = Block::allocate(block, alignment, 10);
431 // Check the previous block was created appropriately. Since this block is the
432 // first block, a new one should be made before this.
433 EXPECT_NE(prev, static_cast<Block *>(nullptr));
439 // Ensure we the block is aligned and the size we expect.
440 EXPECT_NE(next, static_cast<Block *>(nullptr));
443 // Check the next block.
444 EXPECT_NE(next, static_cast<Block *>(nullptr));
453 auto result = Block::init(bytes);
455 Block *block = *result;
457 // Split the block roughly halfway and work on the second half.
458 auto result2 = block->split(kN / 2);
460 Block *newblock = *result2;
461 ASSERT_EQ(newblock->prev_free(), block);
462 size_t old_prev_size = block->outer_size();
465 // it. We want to explicitly test that the block will split into one before
471 // Ensure we can allocate in the new block.
472 auto [aligned_block, prev, next] = Block::allocate(newblock, alignment, 1);
474 // Now there should be no new previous block. Instead, the padding we did
475 // create should be merged into the original previous block.
476 EXPECT_EQ(prev, static_cast<Block *>(nullptr));
477 EXPECT_EQ(aligned_block->prev_free(), block);
478 EXPECT_EQ(block->next(), aligned_block);
479 EXPECT_GT(block->outer_size(), old_prev_size);
484 // should be able to reconstruct the original block from the blocklets.
490 auto result = Block::init(bytes);
492 Block *block = *result;
494 Block *orig_block = block;
497 Block *last = block->next();
499 ASSERT_EQ(block->prev_free(), static_cast<Block *>(nullptr));
502 // it. We want to explicitly test that the block will split into one before
505 while (block->is_usable_space_aligned(alignment))
508 auto [aligned_block, prev, next] = Block::allocate(block, alignment, 1);
511 ASSERT_NE(prev, static_cast<Block *>(nullptr));
513 EXPECT_NE(next, static_cast<Block *>(nullptr));