Plumb LocalState ptrs through to Pagemap accessors
David points out that we might not have a static way to get at the pagemap, so it is potentially useful to pass pointers to state objects down from the Allocators.
This commit is contained in:
committed by
Nathaniel Wesley Filardo
parent
3710e351fe
commit
3af9d35099
@@ -114,6 +114,21 @@ namespace snmalloc
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a pointer to the backend state.
|
||||
*/
|
||||
LocalState* backend_state_ptr()
|
||||
{
|
||||
if constexpr (SharedStateHandle::Options.CoreAllocOwnsLocalState)
|
||||
{
|
||||
return &backend_state;
|
||||
}
|
||||
else
|
||||
{
|
||||
return backend_state;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return this allocator's "truncated" ID, an integer useful as a hash
|
||||
* value of this allocator.
|
||||
@@ -376,8 +391,8 @@ namespace snmalloc
|
||||
for (size_t i = 0; i < REMOTE_BATCH; i++)
|
||||
{
|
||||
auto p = message_queue().peek();
|
||||
auto& entry =
|
||||
SharedStateHandle::Pagemap::get_metaentry(snmalloc::address_cast(p));
|
||||
auto& entry = SharedStateHandle::Pagemap::get_metaentry(
|
||||
backend_state_ptr(), snmalloc::address_cast(p));
|
||||
|
||||
auto r = message_queue().dequeue(key_global);
|
||||
|
||||
@@ -516,9 +531,10 @@ namespace snmalloc
|
||||
SNMALLOC_FAST_PATH bool post()
|
||||
{
|
||||
// stats().remote_post(); // TODO queue not in line!
|
||||
bool sent_something = attached_cache->remote_dealloc_cache
|
||||
.post<sizeof(CoreAllocator), SharedStateHandle>(
|
||||
public_state()->trunc_id(), key_global);
|
||||
bool sent_something =
|
||||
attached_cache->remote_dealloc_cache
|
||||
.post<sizeof(CoreAllocator), SharedStateHandle>(
|
||||
backend_state_ptr(), public_state()->trunc_id(), key_global);
|
||||
|
||||
return sent_something;
|
||||
}
|
||||
@@ -538,8 +554,8 @@ namespace snmalloc
|
||||
|
||||
SNMALLOC_FAST_PATH void dealloc_local_object(void* p)
|
||||
{
|
||||
auto entry =
|
||||
SharedStateHandle::Pagemap::get_metaentry(snmalloc::address_cast(p));
|
||||
auto entry = SharedStateHandle::Pagemap::get_metaentry(
|
||||
backend_state_ptr(), snmalloc::address_cast(p));
|
||||
if (likely(dealloc_local_object_fast(entry, p, entropy)))
|
||||
return;
|
||||
|
||||
@@ -666,7 +682,7 @@ namespace snmalloc
|
||||
bool need_post = true; // Always going to post, so ignore.
|
||||
auto n = p->atomic_read_next(key_global);
|
||||
auto& entry = SharedStateHandle::Pagemap::get_metaentry(
|
||||
snmalloc::address_cast(p));
|
||||
backend_state_ptr(), snmalloc::address_cast(p));
|
||||
handle_dealloc_remote(entry, p, need_post);
|
||||
p = n;
|
||||
}
|
||||
@@ -681,7 +697,7 @@ namespace snmalloc
|
||||
|
||||
auto posted =
|
||||
attached_cache->flush<sizeof(CoreAllocator), SharedStateHandle>(
|
||||
[&](auto p) { dealloc_local_object(p); });
|
||||
backend_state_ptr(), [&](auto p) { dealloc_local_object(p); });
|
||||
|
||||
// We may now have unused slabs, return to the global allocator.
|
||||
for (sizeclass_t sizeclass = 0; sizeclass < NUM_SIZECLASSES; sizeclass++)
|
||||
|
||||
@@ -260,8 +260,8 @@ namespace snmalloc
|
||||
std::cout << "Remote dealloc post" << p << " size " << alloc_size(p)
|
||||
<< std::endl;
|
||||
#endif
|
||||
MetaEntry entry =
|
||||
SharedStateHandle::Pagemap::get_metaentry(address_cast(p));
|
||||
MetaEntry entry = SharedStateHandle::Pagemap::get_metaentry(
|
||||
core_alloc->backend_state_ptr(), address_cast(p));
|
||||
local_cache.remote_dealloc_cache.template dealloc<sizeof(CoreAlloc)>(
|
||||
entry.get_remote()->trunc_id(), CapPtr<void, CBAlloc>(p), key_global);
|
||||
post_remote_cache();
|
||||
@@ -472,8 +472,8 @@ namespace snmalloc
|
||||
// before init, that maps null to a remote_deallocator that will never be
|
||||
// in thread local state.
|
||||
|
||||
const MetaEntry& entry =
|
||||
SharedStateHandle::Pagemap::get_metaentry(address_cast(p));
|
||||
const MetaEntry& entry = SharedStateHandle::Pagemap::get_metaentry(
|
||||
core_alloc->backend_state_ptr(), address_cast(p));
|
||||
if (likely(local_cache.remote_allocator == entry.get_remote()))
|
||||
{
|
||||
if (likely(CoreAlloc::dealloc_local_object_fast(
|
||||
@@ -583,8 +583,8 @@ namespace snmalloc
|
||||
// To handle this case we require the uninitialised pagemap contain an
|
||||
// entry for the first chunk of memory, that states it represents a large
|
||||
// object, so we can pull the check for null off the fast path.
|
||||
MetaEntry entry =
|
||||
SharedStateHandle::Pagemap::get_metaentry(address_cast(p_raw));
|
||||
MetaEntry entry = SharedStateHandle::Pagemap::get_metaentry(
|
||||
core_alloc->backend_state_ptr(), address_cast(p_raw));
|
||||
|
||||
if (likely(entry.get_remote() != SharedStateHandle::fake_large_remote))
|
||||
return sizeclass_to_size(entry.get_sizeclass());
|
||||
@@ -611,7 +611,7 @@ namespace snmalloc
|
||||
// TODO bring back the CHERI bits. Wes to review if required.
|
||||
MetaEntry entry =
|
||||
SharedStateHandle::Pagemap::template get_metaentry<true>(
|
||||
address_cast(p_raw));
|
||||
core_alloc->backend_state_ptr(), address_cast(p_raw));
|
||||
auto sizeclass = entry.get_sizeclass();
|
||||
if (likely(entry.get_remote() != SharedStateHandle::fake_large_remote))
|
||||
{
|
||||
|
||||
@@ -74,7 +74,8 @@ namespace snmalloc
|
||||
size_t allocator_size,
|
||||
typename SharedStateHandle,
|
||||
typename DeallocFun>
|
||||
bool flush(DeallocFun dealloc)
|
||||
bool flush(
|
||||
typename SharedStateHandle::LocalState* local_state, DeallocFun dealloc)
|
||||
{
|
||||
auto& key = entropy.get_free_list_key();
|
||||
|
||||
@@ -92,7 +93,7 @@ namespace snmalloc
|
||||
}
|
||||
|
||||
return remote_dealloc_cache.post<allocator_size, SharedStateHandle>(
|
||||
remote_allocator->trunc_id(), key_global);
|
||||
local_state, remote_allocator->trunc_id(), key_global);
|
||||
}
|
||||
|
||||
template<ZeroMem zero_mem, typename SharedStateHandle, typename Slowpath>
|
||||
|
||||
@@ -76,7 +76,10 @@ namespace snmalloc
|
||||
}
|
||||
|
||||
template<size_t allocator_size, typename SharedStateHandle>
|
||||
bool post(RemoteAllocator::alloc_id_t id, const FreeListKey& key)
|
||||
bool post(
|
||||
typename SharedStateHandle::LocalState* local_state,
|
||||
RemoteAllocator::alloc_id_t id,
|
||||
const FreeListKey& key)
|
||||
{
|
||||
SNMALLOC_ASSERT(initialised);
|
||||
size_t post_round = 0;
|
||||
@@ -94,8 +97,8 @@ namespace snmalloc
|
||||
if (!list[i].empty())
|
||||
{
|
||||
auto [first, last] = list[i].extract_segment(key);
|
||||
MetaEntry entry =
|
||||
SharedStateHandle::Pagemap::get_metaentry(address_cast(first));
|
||||
MetaEntry entry = SharedStateHandle::Pagemap::get_metaentry(
|
||||
local_state, address_cast(first));
|
||||
entry.get_remote()->enqueue(first, last, key);
|
||||
sent_something = true;
|
||||
}
|
||||
@@ -117,8 +120,8 @@ namespace snmalloc
|
||||
// Use the next N bits to spread out remote deallocs in our own
|
||||
// slot.
|
||||
auto r = resend.take(key);
|
||||
MetaEntry entry =
|
||||
SharedStateHandle::Pagemap::get_metaentry(address_cast(r));
|
||||
MetaEntry entry = SharedStateHandle::Pagemap::get_metaentry(
|
||||
local_state, address_cast(r));
|
||||
auto i = entry.get_remote()->trunc_id();
|
||||
size_t slot = get_slot<allocator_size>(i, post_round);
|
||||
list[slot].add(r, key);
|
||||
|
||||
@@ -108,7 +108,7 @@ namespace snmalloc
|
||||
#endif
|
||||
MetaEntry entry{meta, remote, sizeclass};
|
||||
SharedStateHandle::Pagemap::set_metaentry(
|
||||
address_cast(slab), slab_size, entry);
|
||||
&local_state, address_cast(slab), slab_size, entry);
|
||||
return {slab, meta};
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user