Remove allocated field from Metaslab

The metaslab contains a field specifying how many elements have been
allocated.  As the code has evolved this field has now always become
the maximum capacity of the slab for the sizeclass.

This commit looks up this value based on the sizeclass, and removes the
field from the slab's metadata.
This commit is contained in:
Matthew Parkinson
2021-03-22 10:52:33 +00:00
committed by Matthew Parkinson
parent d56a99a747
commit 04a185e634
5 changed files with 29 additions and 17 deletions

View File

@@ -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

View File

@@ -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);

View File

@@ -29,6 +29,8 @@ namespace snmalloc
ModArray<NUM_SIZECLASSES, size_t> inverse_cache_friendly_mask;
ModArray<NUM_SMALL_CLASSES, uint16_t> initial_offset_ptr;
ModArray<NUM_SMALL_CLASSES, uint16_t> short_initial_offset_ptr;
ModArray<NUM_SMALL_CLASSES, uint16_t> capacity;
ModArray<NUM_SMALL_CLASSES, uint16_t> short_capacity;
ModArray<NUM_MEDIUM_CLASSES, uint16_t> medium_slab_slots;
// Table of constants for reciprocal division for each sizeclass.
ModArray<NUM_SIZECLASSES, size_t> 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<uint16_t>(correction);
short_initial_offset_ptr[i] =
static_cast<uint16_t>(header_size + short_correction);
capacity[i] = static_cast<uint16_t>(
(SLAB_SIZE - initial_offset_ptr[i]) / (size[i]));
short_capacity[i] = static_cast<uint16_t>(
(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];

View File

@@ -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);

View File

@@ -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<uint16_t>(
(SLAB_SIZE - get_initial_offset(sizeclass, true)) /
sizeclass_to_size(sizeclass));
meta[0].set_full();
meta[0].sizeclass = static_cast<uint8_t>(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<uint16_t>(
(SLAB_SIZE - get_initial_offset(sizeclass, false)) /
sizeclass_to_size(sizeclass));
meta[h].set_full();
meta[h].sizeclass = static_cast<uint8_t>(sizeclass);