[libc-commits] [libc] [libc][malloc] Reuse the prev_ field for allocated blocks (PR #101265)
Daniel Thornburgh via libc-commits
libc-commits at lists.llvm.org
Wed Jul 31 12:06:57 PDT 2024
================
@@ -182,40 +209,39 @@ class Block {
/// is the last block.
Block *next() const;
- /// @returns The block immediately before this one, or a null pointer if this
- /// is the first block.
- Block *prev() const;
+ /// @returns The free block immediately before this one, otherwise nullptr.
+ Block *prev_free() const;
- /// Indicates whether the block is in use.
- ///
- /// @returns `true` if the block is in use or `false` if not.
- bool used() const { return next_ & USED_MASK; }
+ /// @returns Whether the block is unavailable for allocation.
+ bool used() const { return !next() || !next()->prev_free(); }
/// Marks this block as in use.
- void mark_used() { next_ |= USED_MASK; }
+ void mark_used() {
+ LIBC_ASSERT(next() && "last block is always considered used");
+ next()->next_ &= ~PREV_FREE_MASK;
+ }
/// Marks this block as free.
- void mark_free() { next_ &= ~USED_MASK; }
+ void mark_free() {
+ LIBC_ASSERT(next() && "last block is always considered used");
+ next()->next_ |= PREV_FREE_MASK;
+ // The next block's prev_ field becomes alive, as it is no longer part of
+ // this block's used space.
+ *new (&next()->prev_) offset_type = outer_size();
----------------
mysterymath wrote:
The semantics of `inner_size()` were subtly recast to be the size available for allocation; the `prev_` field of the next block is always available, so it's always included in the inner size, regardless of whether or not the block is free. This allows checks against `inner_size()` to mostly persist unaltered, but it does complicate using it for block arithmetic.
https://github.com/llvm/llvm-project/pull/101265
More information about the libc-commits
mailing list