[libc-commits] [libc] [libc] Use best-fit binary trie to make malloc logarithmic (PR #106259)

Daniel Thornburgh via libc-commits libc-commits at lists.llvm.org
Thu Oct 10 16:03:41 PDT 2024


================
@@ -54,89 +47,76 @@ template <size_t NUM_BUCKETS = DEFAULT_BUCKETS.size()> class FreeListHeap {
   void *realloc(void *ptr, size_t size);
   void *calloc(size_t num, size_t size);
 
-  cpp::span<cpp::byte> region() const { return {begin_, end_}; }
+  cpp::span<cpp::byte> region() const { return {begin, end}; }
 
 private:
   void init();
 
   void *allocate_impl(size_t alignment, size_t size);
 
-  span<cpp::byte> block_to_span(BlockType *block) {
+  span<cpp::byte> block_to_span(Block<> *block) {
     return span<cpp::byte>(block->usable_space(), block->inner_size());
   }
 
-  bool is_valid_ptr(void *ptr) { return ptr >= begin_ && ptr < end_; }
+  bool is_valid_ptr(void *ptr) { return ptr >= begin && ptr < end; }
 
-  bool is_initialized_ = false;
-  cpp::byte *begin_;
-  cpp::byte *end_;
-  FreeListType freelist_{DEFAULT_BUCKETS};
+  cpp::byte *begin;
+  cpp::byte *end;
+  bool is_initialized = false;
+  FreeStore free_store;
 };
 
-template <size_t BUFF_SIZE, size_t NUM_BUCKETS = DEFAULT_BUCKETS.size()>
-class FreeListHeapBuffer : public FreeListHeap<NUM_BUCKETS> {
-  using parent = FreeListHeap<NUM_BUCKETS>;
-  using FreeListNode = typename parent::FreeListType::FreeListNode;
-
+template <size_t BUFF_SIZE> class FreeListHeapBuffer : public FreeListHeap {
 public:
-  constexpr FreeListHeapBuffer()
-      : FreeListHeap<NUM_BUCKETS>{buffer}, buffer{} {}
+  constexpr FreeListHeapBuffer() : FreeListHeap{buffer}, buffer{} {}
 
 private:
   cpp::byte buffer[BUFF_SIZE];
 };
 
-template <size_t NUM_BUCKETS> void FreeListHeap<NUM_BUCKETS>::init() {
-  LIBC_ASSERT(!is_initialized_ && "duplicate initialization");
-  auto result = BlockType::init(region());
-  BlockType *block = *result;
-  freelist_.add_chunk(block_to_span(block));
-  is_initialized_ = true;
+LIBC_INLINE void FreeListHeap::init() {
+  LIBC_ASSERT(!is_initialized && "duplicate initialization");
+  auto result = Block<>::init(region());
+  Block<> *block = *result;
+  free_store.set_range({0, cpp::bit_ceil(block->inner_size())});
+  free_store.insert(block);
+  is_initialized = true;
 }
 
-template <size_t NUM_BUCKETS>
-void *FreeListHeap<NUM_BUCKETS>::allocate_impl(size_t alignment, size_t size) {
+LIBC_INLINE void *FreeListHeap::allocate_impl(size_t alignment, size_t size) {
   if (size == 0)
     return nullptr;
 
-  if (!is_initialized_)
+  if (!is_initialized)
     init();
 
-  // Find a chunk in the freelist. Split it if needed, then return.
-  auto chunk =
-      freelist_.find_chunk_if([alignment, size](span<cpp::byte> chunk) {
-        BlockType *block = BlockType::from_usable_space(chunk.data());
-        return block->can_allocate(alignment, size);
-      });
+  size_t request_size =
+      alignment <= alignof(max_align_t) ? size : size + alignment - 1;
----------------
mysterymath wrote:

Done.

https://github.com/llvm/llvm-project/pull/106259


More information about the libc-commits mailing list