diff --git a/src/mem/metaslab.h b/src/mem/metaslab.h index 7121105..b39d552 100644 --- a/src/mem/metaslab.h +++ b/src/mem/metaslab.h @@ -30,7 +30,7 @@ namespace snmalloc /** * Pointer to first free entry in this slab * - * The list will be (allocated - needed) long. + * The list will be (slab_capacity - needed) long. */ FreeListBuilder free_queue; @@ -44,11 +44,6 @@ namespace snmalloc */ uint16_t needed = 0; - /** - * How many entries have been allocated from this slab. - */ - uint16_t allocated = 0; - uint8_t sizeclass; // Initially zero to encode the superslabs relative list of slabs. uint8_t next = 0; @@ -136,7 +131,8 @@ namespace snmalloc void* n = fast_free_list.take(); // Treat stealing the free list as allocating it all. - self->needed = self->allocated; + self->needed = + get_slab_capacity(self->sizeclass, Metaslab::is_short(slab)); self->remove(); self->set_full(); @@ -195,8 +191,8 @@ namespace snmalloc SNMALLOC_ASSERT(SLAB_SIZE >= accounted_for); } - auto bumpptr = (allocated * size) + offset; - // Check we haven't allocaated more than gits in a slab + auto bumpptr = (get_slab_capacity(sizeclass, is_short) * size) + offset; + // Check we haven't allocated more than fits in a slab SNMALLOC_ASSERT(bumpptr <= SLAB_SIZE); // Account for to be bump allocated space diff --git a/src/mem/sizeclass.h b/src/mem/sizeclass.h index 35e3d74..24080e7 100644 --- a/src/mem/sizeclass.h +++ b/src/mem/sizeclass.h @@ -14,6 +14,8 @@ namespace snmalloc constexpr static uintptr_t SIZECLASS_MASK = 0xFF; constexpr static uint16_t get_initial_offset(sizeclass_t sc, bool is_short); + constexpr static uint16_t get_slab_capacity(sizeclass_t sc, bool is_short); + constexpr static size_t sizeclass_to_size(sizeclass_t sizeclass); constexpr static size_t sizeclass_to_cache_friendly_mask(sizeclass_t sizeclass); diff --git a/src/mem/sizeclasstable.h b/src/mem/sizeclasstable.h index 6db06aa..390bce7 100644 --- a/src/mem/sizeclasstable.h +++ b/src/mem/sizeclasstable.h @@ -29,6 +29,8 @@ namespace snmalloc ModArray inverse_cache_friendly_mask; ModArray initial_offset_ptr; ModArray short_initial_offset_ptr; + ModArray capacity; + ModArray short_capacity; ModArray medium_slab_slots; // Table of constants for reciprocal division for each sizeclass. ModArray div_mult; @@ -41,6 +43,8 @@ namespace snmalloc inverse_cache_friendly_mask(), initial_offset_ptr(), short_initial_offset_ptr(), + capacity(), + short_capacity(), medium_slab_slots(), div_mult(), mod_mult() @@ -90,6 +94,11 @@ namespace snmalloc initial_offset_ptr[i] = static_cast(correction); short_initial_offset_ptr[i] = static_cast(header_size + short_correction); + + capacity[i] = static_cast( + (SLAB_SIZE - initial_offset_ptr[i]) / (size[i])); + short_capacity[i] = static_cast( + (SLAB_SIZE - short_initial_offset_ptr[i]) / (size[i])); } for (sizeclass_t i = NUM_SMALL_CLASSES; i < NUM_SIZECLASSES; i++) @@ -111,6 +120,15 @@ namespace snmalloc return sizeclass_metadata.initial_offset_ptr[sc]; } + static inline constexpr uint16_t + get_slab_capacity(sizeclass_t sc, bool is_short) + { + if (is_short) + return sizeclass_metadata.short_capacity[sc]; + + return sizeclass_metadata.capacity[sc]; + } + constexpr static inline size_t sizeclass_to_size(sizeclass_t sizeclass) { return sizeclass_metadata.size[sizeclass]; diff --git a/src/mem/slab.h b/src/mem/slab.h index 295bba8..860bb6f 100644 --- a/src/mem/slab.h +++ b/src/mem/slab.h @@ -109,8 +109,10 @@ namespace snmalloc if (meta.is_full()) { + auto allocated = get_slab_capacity( + meta.sizeclass, Metaslab::is_short(Metaslab::get_slab(p))); // We are not on the sizeclass list. - if (meta.allocated == 1) + if (allocated == 1) { // Dealloc on the superslab. if (Metaslab::is_short(self)) @@ -120,7 +122,7 @@ namespace snmalloc } SNMALLOC_ASSERT(meta.free_queue.empty()); meta.free_queue.open(p); - meta.needed = meta.allocated - 1; + meta.needed = allocated - 1; // Push on the list of slabs for this sizeclass. sl->insert_prev(&meta); diff --git a/src/mem/superslab.h b/src/mem/superslab.h index 4398fa4..d689d09 100644 --- a/src/mem/superslab.h +++ b/src/mem/superslab.h @@ -170,9 +170,6 @@ namespace snmalloc // returned all the elements, but this is a slab that is still being bump // allocated from. Hence, the bump allocator slab will never be returned // for use in another size class. - meta[0].allocated = static_cast( - (SLAB_SIZE - get_initial_offset(sizeclass, true)) / - sizeclass_to_size(sizeclass)); meta[0].set_full(); meta[0].sizeclass = static_cast(sizeclass); @@ -194,9 +191,6 @@ namespace snmalloc // returned all the elements, but this is a slab that is still being bump // allocated from. Hence, the bump allocator slab will never be returned // for use in another size class. - meta[h].allocated = static_cast( - (SLAB_SIZE - get_initial_offset(sizeclass, false)) / - sizeclass_to_size(sizeclass)); meta[h].set_full(); meta[h].sizeclass = static_cast(sizeclass);