[libc-commits] [libc] [NFC][libc][malloc] Refactor Block (PR #100445)
via libc-commits
libc-commits at lists.llvm.org
Wed Jul 24 12:21:31 PDT 2024
================
@@ -459,84 +421,78 @@ Block<OffsetType, kAlign>::allocate(Block *block, size_t alignment,
}
// Now get a block for the requested size.
- if (optional<Block *> next = Block::split(info.block, size))
+ if (optional<Block *> next = info.block->split(size))
info.next = *next;
return info;
}
template <typename OffsetType, size_t kAlign>
optional<Block<OffsetType, kAlign> *>
-Block<OffsetType, kAlign>::split(Block *&block, size_t new_inner_size) {
- if (block == nullptr)
+Block<OffsetType, kAlign>::split(size_t new_inner_size) {
+ if (used())
return {};
- if (block->used())
- return {};
-
- size_t old_inner_size = block->inner_size();
+ size_t old_inner_size = inner_size();
new_inner_size = align_up(new_inner_size, ALIGNMENT);
if (old_inner_size < new_inner_size)
return {};
if (old_inner_size - new_inner_size < BLOCK_OVERHEAD)
return {};
- return split_impl(block, new_inner_size);
+ return split_impl(new_inner_size);
}
template <typename OffsetType, size_t kAlign>
Block<OffsetType, kAlign> *
-Block<OffsetType, kAlign>::split_impl(Block *&block, size_t new_inner_size) {
- size_t prev_outer_size = block->prev_;
+Block<OffsetType, kAlign>::split_impl(size_t new_inner_size) {
size_t outer_size1 = new_inner_size + BLOCK_OVERHEAD;
- bool is_last = block->last();
- ByteSpan bytes = as_bytes(cpp::move(block));
- Block *block1 = as_block(prev_outer_size, bytes.subspan(0, outer_size1));
- Block *block2 = as_block(outer_size1, bytes.subspan(outer_size1));
-
- if (is_last)
- block2->mark_last();
- else
- block2->next()->prev_ = block2->next_;
-
- block = cpp::move(block1);
- return block2;
+ bool is_last = last();
+ ByteSpan new_region = region().subspan(outer_size1);
+ LIBC_ASSERT(!used() && "used blocks cannot be split");
+ // The low order bits of outer_size1 should both be zero, and is the correct
+ // value for the flags is false.
+ next_ = outer_size1;
+ LIBC_ASSERT(!used() && !last() && "incorrect first split flags");
+ Block *new_block = as_block(outer_size1, new_region);
+
+ if (is_last) {
+ new_block->mark_last();
+ } else {
+ // The two flags are both false, so next_ is a plain size.
+ LIBC_ASSERT(!new_block->used() && !new_block->last() &&
+ "flags disrupt use of size");
+ new_block->next()->prev_ = new_block->next_;
+ }
+ return new_block;
}
template <typename OffsetType, size_t kAlign>
-bool Block<OffsetType, kAlign>::merge_next(Block *&block) {
- if (block == nullptr)
+bool Block<OffsetType, kAlign>::merge_next() {
+ if (last())
return false;
- if (block->last())
+ if (used() || next()->used())
return false;
- Block *next = block->next();
- if (block->used() || next->used())
- return false;
+ // Extend the size and copy the last() flag from the next block to this one.
+ next_ &= SIZE_MASK;
+ next_ += next()->next_;
- size_t prev_outer_size = block->prev_;
- bool is_last = next->last();
- ByteSpan prev_bytes = as_bytes(cpp::move(block));
- ByteSpan next_bytes = as_bytes(cpp::move(next));
- size_t outer_size = prev_bytes.size() + next_bytes.size();
- cpp::byte *merged = ::new (prev_bytes.data()) cpp::byte[outer_size];
- block = as_block(prev_outer_size, ByteSpan(merged, outer_size));
-
- if (is_last)
- block->mark_last();
- else
- block->next()->prev_ = block->next_;
+ if (!last()) {
+ // The two flags are both false, so next_ is a plain size.
+ LIBC_ASSERT(!used() && !last() && "flags disrupt use of size");
+ next()->prev_ = next_;
+ }
return true;
}
template <typename OffsetType, size_t kAlign>
Block<OffsetType, kAlign> *Block<OffsetType, kAlign>::next() const {
- uintptr_t addr =
- last() ? 0 : reinterpret_cast<uintptr_t>(this) + outer_size();
- return reinterpret_cast<Block *>(addr);
+ return reinterpret_cast<Block *>(reinterpret_cast<uintptr_t>(this) +
+ outer_size());
----------------
PiJoules wrote:
should this still check `last()`?
https://github.com/llvm/llvm-project/pull/100445
More information about the libc-commits
mailing list