From cd92aedf1bb67f643fb9656ab8d28fc5eab05083 Mon Sep 17 00:00:00 2001 From: Daniel Thornburgh Date: Thu, 16 Jan 2025 14:21:56 -0800 Subject: [PATCH] [NFC][libc] Remove Block::ALIGNMENT and Block::BLOCK_OVERHEAD --- libc/src/__support/block.h | 22 ++++++++++------------ libc/src/__support/freestore.h | 10 +++++----- libc/test/src/__support/block_test.cpp | 7 +++---- 3 files changed, 18 insertions(+), 21 deletions(-) diff --git a/libc/src/__support/block.h b/libc/src/__support/block.h index 1ec5fde77de0..ffb8ed5e91b6 100644 --- a/libc/src/__support/block.h +++ b/libc/src/__support/block.h @@ -109,9 +109,6 @@ class Block { static constexpr size_t SIZE_MASK = ~(PREV_FREE_MASK | LAST_MASK); public: - static constexpr size_t ALIGNMENT = cpp::max(alignof(max_align_t), size_t{4}); - static const size_t BLOCK_OVERHEAD; - // No copy or move. Block(const Block &other) = delete; Block &operator=(const Block &other) = delete; @@ -130,11 +127,11 @@ public: /// pointer will return a non-null pointer. LIBC_INLINE static Block *from_usable_space(void *usable_space) { auto *bytes = reinterpret_cast(usable_space); - return reinterpret_cast(bytes - BLOCK_OVERHEAD); + return reinterpret_cast(bytes - sizeof(Block)); } LIBC_INLINE static const Block *from_usable_space(const void *usable_space) { const auto *bytes = reinterpret_cast(usable_space); - return reinterpret_cast(bytes - BLOCK_OVERHEAD); + return reinterpret_cast(bytes - sizeof(Block)); } /// @returns The total size of the block in bytes, including the header. @@ -142,7 +139,7 @@ public: LIBC_INLINE static size_t outer_size(size_t inner_size) { // The usable region includes the prev_ field of the next block. - return inner_size - sizeof(prev_) + BLOCK_OVERHEAD; + return inner_size - sizeof(prev_) + sizeof(Block); } /// @returns The number of usable bytes inside the block were it to be @@ -170,20 +167,20 @@ public: /// @returns The number of usable bytes inside a block with the given outer /// size if it remains free. LIBC_INLINE static size_t inner_size_free(size_t outer_size) { - return outer_size - BLOCK_OVERHEAD; + return outer_size - sizeof(Block); } /// @returns A pointer to the usable space inside this block. /// /// Aligned to some multiple of max_align_t. LIBC_INLINE cpp::byte *usable_space() { - auto *s = reinterpret_cast(this) + BLOCK_OVERHEAD; + auto *s = reinterpret_cast(this) + sizeof(Block); LIBC_ASSERT(reinterpret_cast(s) % alignof(max_align_t) == 0 && "usable space must be aligned to a multiple of max_align_t"); return s; } LIBC_INLINE const cpp::byte *usable_space() const { - const auto *s = reinterpret_cast(this) + BLOCK_OVERHEAD; + const auto *s = reinterpret_cast(this) + sizeof(Block); LIBC_ASSERT(reinterpret_cast(s) % alignof(max_align_t) == 0 && "usable space must be aligned to a multiple of max_align_t"); return s; @@ -246,7 +243,8 @@ public: LIBC_INLINE void mark_last() { next_ |= LAST_MASK; } LIBC_INLINE Block(size_t outer_size) : next_(outer_size) { - LIBC_ASSERT(outer_size % ALIGNMENT == 0 && "block sizes must be aligned"); + LIBC_ASSERT(outer_size % alignof(max_align_t) == 0 && + "block sizes must be aligned"); LIBC_ASSERT(is_usable_space_aligned(alignof(max_align_t)) && "usable space must be aligned to a multiple of max_align_t"); } @@ -362,8 +360,8 @@ private: /// summarily considered used and has no next block. }; -inline constexpr size_t Block::BLOCK_OVERHEAD = - align_up(sizeof(Block), ALIGNMENT); +static_assert(alignof(max_align_t) >= 4, + "at least 2 bits must be available in block sizes for flags"); LIBC_INLINE optional Block::init(ByteSpan region) { diff --git a/libc/src/__support/freestore.h b/libc/src/__support/freestore.h index 97197dda4b54..09f2479debb3 100644 --- a/libc/src/__support/freestore.h +++ b/libc/src/__support/freestore.h @@ -40,13 +40,12 @@ public: Block *remove_best_fit(size_t size); private: - static constexpr size_t ALIGNMENT = alignof(max_align_t); static constexpr size_t MIN_OUTER_SIZE = - align_up(Block::BLOCK_OVERHEAD + sizeof(FreeList::Node), ALIGNMENT); + align_up(sizeof(Block) + sizeof(FreeList::Node), alignof(max_align_t)); static constexpr size_t MIN_LARGE_OUTER_SIZE = - align_up(Block::BLOCK_OVERHEAD + sizeof(FreeTrie::Node), ALIGNMENT); + align_up(sizeof(Block) + sizeof(FreeTrie::Node), alignof(max_align_t)); static constexpr size_t NUM_SMALL_SIZES = - (MIN_LARGE_OUTER_SIZE - MIN_OUTER_SIZE) / ALIGNMENT; + (MIN_LARGE_OUTER_SIZE - MIN_OUTER_SIZE) / alignof(max_align_t); LIBC_INLINE static bool too_small(Block *block) { return block->outer_size() < MIN_OUTER_SIZE; @@ -99,7 +98,8 @@ LIBC_INLINE Block *FreeStore::remove_best_fit(size_t size) { LIBC_INLINE FreeList &FreeStore::small_list(Block *block) { LIBC_ASSERT(is_small(block) && "only legal for small blocks"); - return small_lists[(block->outer_size() - MIN_OUTER_SIZE) / ALIGNMENT]; + return small_lists[(block->outer_size() - MIN_OUTER_SIZE) / + alignof(max_align_t)]; } LIBC_INLINE FreeList *FreeStore::find_best_small_fit(size_t size) { diff --git a/libc/test/src/__support/block_test.cpp b/libc/test/src/__support/block_test.cpp index 1da811544a94..a1e88a44ad34 100644 --- a/libc/test/src/__support/block_test.cpp +++ b/libc/test/src/__support/block_test.cpp @@ -22,7 +22,7 @@ using LIBC_NAMESPACE::cpp::span; TEST(LlvmLibcBlockTest, CanCreateSingleAlignedBlock) { constexpr size_t kN = 1024; - alignas(Block::ALIGNMENT) array bytes; + alignas(max_align_t) array bytes; auto result = Block::init(bytes); ASSERT_TRUE(result.has_value()); @@ -52,7 +52,7 @@ TEST(LlvmLibcBlockTest, CanCreateUnalignedSingleBlock) { constexpr size_t kN = 1024; // Force alignment, so we can un-force it below - alignas(Block::ALIGNMENT) array bytes; + alignas(max_align_t) array bytes; span aligned(bytes); auto result = Block::init(aligned.subspan(1)); @@ -90,8 +90,7 @@ TEST(LlvmLibcBlockTest, CanSplitBlock) { auto *block2 = *result; EXPECT_EQ(block1->inner_size(), kSplitN); - EXPECT_EQ(block1->outer_size(), - kSplitN - prev_field_size + Block::BLOCK_OVERHEAD); + EXPECT_EQ(block1->outer_size(), kSplitN - prev_field_size + sizeof(Block)); EXPECT_EQ(block2->outer_size(), orig_size - block1->outer_size()); EXPECT_FALSE(block2->used());