diff --git a/src/mem/alloc.h b/src/mem/alloc.h index 934f704..de64bbe 100644 --- a/src/mem/alloc.h +++ b/src/mem/alloc.h @@ -973,7 +973,7 @@ namespace snmalloc if (super != nullptr) { - Slab* slab = super->alloc_short_slab(sizeclass); + auto slab = Superslab::alloc_short_slab(super, sizeclass); SNMALLOC_ASSERT(super->is_full()); return slab; } @@ -983,7 +983,7 @@ namespace snmalloc if (super == nullptr) return nullptr; - Slab* slab = super->alloc_short_slab(sizeclass); + auto slab = Superslab::alloc_short_slab(super, sizeclass); reposition_superslab(super); return slab; } @@ -993,7 +993,7 @@ namespace snmalloc if (super == nullptr) return nullptr; - Slab* slab = super->alloc_slab(sizeclass); + auto slab = Superslab::alloc_slab(super, sizeclass); reposition_superslab(super); return slab; } diff --git a/src/mem/superslab.h b/src/mem/superslab.h index ea35a71..6519b26 100644 --- a/src/mem/superslab.h +++ b/src/mem/superslab.h @@ -186,43 +186,50 @@ namespace snmalloc return meta[slab_to_index(slab)]; } - Slab* alloc_short_slab(sizeclass_t sizeclass) + // This is pre-factored to take an explicit self parameter so that we can + // eventually annotate that pointer with additional information. + static Slab* alloc_short_slab(Superslab* self, sizeclass_t sizeclass) { - if ((used & 1) == 1) - return alloc_slab(sizeclass); + if ((self->used & 1) == 1) + return alloc_slab(self, sizeclass); - meta[0].free_queue.init(); + auto& metaz = self->meta[0]; + + metaz.free_queue.init(); // Set up meta data as if the entire slab has been turned into a free // list. This means we don't have to check for special cases where we have // 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].set_full(); - meta[0].sizeclass = static_cast(sizeclass); + metaz.set_full(); + metaz.sizeclass = static_cast(sizeclass); - used++; - return reinterpret_cast(this); + self->used++; + return reinterpret_cast(self); } - Slab* alloc_slab(sizeclass_t sizeclass) + // This is pre-factored to take an explicit self parameter so that we can + // eventually annotate that pointer with additional information. + static Slab* alloc_slab(Superslab* self, sizeclass_t sizeclass) { - uint8_t h = head; + uint8_t h = self->head; Slab* slab = reinterpret_cast( - pointer_offset(this, (static_cast(h) << SLAB_BITS))); + pointer_offset(self, (static_cast(h) << SLAB_BITS))); - uint8_t n = meta[h].next; + auto& metah = self->meta[h]; + uint8_t n = metah.next; - meta[h].free_queue.init(); + metah.free_queue.init(); // Set up meta data as if the entire slab has been turned into a free // list. This means we don't have to check for special cases where we have // 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].set_full(); - meta[h].sizeclass = static_cast(sizeclass); + metah.set_full(); + metah.sizeclass = static_cast(sizeclass); - head = h + n + 1; - used += 2; + self->head = h + n + 1; + self->used += 2; return slab; }