Simplify remote allocator.
Don't store the sizeclass, as we can find it easily, and already are going to touch though cache lines in the common case.
This commit is contained in:
@@ -536,8 +536,7 @@ namespace snmalloc
|
||||
this->size += sizeclass_to_size(sizeclass);
|
||||
|
||||
Remote* r = (Remote*)p;
|
||||
r->set_sizeclass_and_target_id(target_id, sizeclass);
|
||||
assert(r->sizeclass() == sizeclass);
|
||||
r->set_target_id(target_id);
|
||||
assert(r->target_id() == target_id);
|
||||
|
||||
RemoteList* l = &list[get_slot(target_id, 0)];
|
||||
@@ -702,21 +701,34 @@ namespace snmalloc
|
||||
{
|
||||
if (p != &stub)
|
||||
{
|
||||
uint8_t sizeclass = p->sizeclass();
|
||||
Superslab* super = Superslab::get(p);
|
||||
|
||||
if (p->target_id() == id())
|
||||
if (super->get_kind() == Super)
|
||||
{
|
||||
stats().remote_receive(sizeclass);
|
||||
|
||||
if (sizeclass < NUM_SMALL_CLASSES)
|
||||
small_dealloc(Superslab::get(p), p, sizeclass);
|
||||
Slab* slab = Slab::get(p);
|
||||
Metaslab& meta = super->get_meta(slab);
|
||||
if (p->target_id() == id())
|
||||
{
|
||||
small_dealloc(super, p, meta.sizeclass);
|
||||
}
|
||||
else
|
||||
medium_dealloc(Mediumslab::get(p), p, sizeclass);
|
||||
{
|
||||
// Queue for remote dealloc elsewhere.
|
||||
remote.dealloc(p->target_id(), p, meta.sizeclass);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Queue for remote dealloc elsewhere.
|
||||
remote.dealloc(p->target_id(), p, sizeclass);
|
||||
Mediumslab* slab = Mediumslab::get(p);
|
||||
if (p->target_id() == id())
|
||||
{
|
||||
medium_dealloc(slab, p, slab->get_sizeclass());
|
||||
}
|
||||
else
|
||||
{
|
||||
// Queue for remote dealloc elsewhere.
|
||||
remote.dealloc(p->target_id(), p, slab->get_sizeclass());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,13 +10,6 @@ namespace snmalloc
|
||||
{
|
||||
struct Remote
|
||||
{
|
||||
static const size_t PTR_BITS = sizeof(void*) * 8;
|
||||
static const size_t SIZECLASS_BITS =
|
||||
bits::next_pow2_bits_const(NUM_SIZECLASSES);
|
||||
static const bool USE_TOP_BITS =
|
||||
SIZECLASS_BITS + bits::ADDRESS_BITS < PTR_BITS;
|
||||
static const uintptr_t SIZECLASS_MASK = ((1ULL << SIZECLASS_BITS) - 1);
|
||||
|
||||
using alloc_id_t = size_t;
|
||||
union
|
||||
{
|
||||
@@ -24,66 +17,19 @@ namespace snmalloc
|
||||
Remote* non_atomic_next;
|
||||
};
|
||||
|
||||
// Uses an intptr_t so that when we use the TOP_BITS to encode the
|
||||
// sizeclass, then we can use signed shift to correctly handle kernel versus
|
||||
// user mode.
|
||||
intptr_t value;
|
||||
alloc_id_t allocator_id;
|
||||
|
||||
// This will not exist for the minimum object size. This is only used if
|
||||
// USE_TOP_BITS is false, and the bottom bit of value is set.
|
||||
uint8_t possible_sizeclass;
|
||||
|
||||
void set_sizeclass_and_target_id(alloc_id_t id, uint8_t sizeclass)
|
||||
void set_target_id(alloc_id_t id)
|
||||
{
|
||||
if constexpr (USE_TOP_BITS)
|
||||
{
|
||||
value = (intptr_t)(
|
||||
(id << SIZECLASS_BITS) | ((static_cast<uintptr_t>(sizeclass))));
|
||||
}
|
||||
else
|
||||
{
|
||||
assert((id & 1) == 0);
|
||||
if (sizeclass == 0)
|
||||
{
|
||||
value = (intptr_t)(id | 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
value = (intptr_t)id;
|
||||
possible_sizeclass = sizeclass;
|
||||
}
|
||||
}
|
||||
allocator_id = id;
|
||||
}
|
||||
|
||||
alloc_id_t target_id()
|
||||
{
|
||||
if constexpr (USE_TOP_BITS)
|
||||
{
|
||||
return (alloc_id_t)(value >> SIZECLASS_BITS);
|
||||
}
|
||||
else
|
||||
{
|
||||
return (alloc_id_t)(value & ~1);
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t sizeclass()
|
||||
{
|
||||
if constexpr (USE_TOP_BITS)
|
||||
{
|
||||
return (static_cast<uint8_t>((uintptr_t)value & SIZECLASS_MASK));
|
||||
}
|
||||
else
|
||||
{
|
||||
return ((value & 1) == 1) ? 0 : possible_sizeclass;
|
||||
}
|
||||
return allocator_id;
|
||||
}
|
||||
};
|
||||
|
||||
static_assert(
|
||||
(offsetof(Remote, possible_sizeclass)) <= MIN_ALLOC_SIZE,
|
||||
"Need to be able to cast any small alloc to Remote");
|
||||
|
||||
struct RemoteAllocator
|
||||
{
|
||||
using alloc_id_t = Remote::alloc_id_t;
|
||||
|
||||
Reference in New Issue
Block a user