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:
committed by
Matthew Parkinson
parent
d56a99a747
commit
04a185e634
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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];
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user