backend ranges: use Arena bounds throughout
Update the backend concept so that metadata allocations are Arena-bounded.
This commit is contained in:
committed by
Nathaniel Filardo
parent
a78a16e637
commit
86124ba26c
@@ -35,10 +35,10 @@ namespace snmalloc
|
||||
* does not avail itself of this degree of freedom.
|
||||
*/
|
||||
template<typename T>
|
||||
static capptr::Chunk<void>
|
||||
static capptr::Arena<void>
|
||||
alloc_meta_data(LocalState* local_state, size_t size)
|
||||
{
|
||||
capptr::Chunk<void> p;
|
||||
capptr::Arena<void> p;
|
||||
if (local_state != nullptr)
|
||||
{
|
||||
p = local_state->get_meta_range().alloc_range_with_leftover(size);
|
||||
@@ -84,7 +84,7 @@ namespace snmalloc
|
||||
return {nullptr, nullptr};
|
||||
}
|
||||
|
||||
auto p = local_state.get_object_range()->alloc_range(size);
|
||||
capptr::Arena<void> p = local_state.get_object_range()->alloc_range(size);
|
||||
|
||||
#ifdef SNMALLOC_TRACING
|
||||
message<1024>("Alloc chunk: {} ({})", p.unsafe_ptr(), size);
|
||||
@@ -140,13 +140,13 @@ namespace snmalloc
|
||||
Pagemap::set_metaentry(address_cast(alloc), size, t);
|
||||
|
||||
local_state.get_meta_range().dealloc_range(
|
||||
capptr::Chunk<void>::unsafe_from(&slab_metadata), sizeof(SlabMetadata));
|
||||
capptr::Arena<void>::unsafe_from(&slab_metadata), sizeof(SlabMetadata));
|
||||
|
||||
// On non-CHERI platforms, we don't need to re-derive to get a pointer to
|
||||
// the chunk. On CHERI platforms this will need to be stored in the
|
||||
// SlabMetadata or similar.
|
||||
auto chunk = capptr::Chunk<void>::unsafe_from(alloc.unsafe_ptr());
|
||||
local_state.get_object_range()->dealloc_range(chunk, size);
|
||||
auto arena = capptr::Arena<void>::unsafe_from(alloc.unsafe_ptr());
|
||||
local_state.get_object_range()->dealloc_range(arena, size);
|
||||
}
|
||||
|
||||
template<bool potentially_out_of_range = false>
|
||||
|
||||
@@ -78,9 +78,9 @@ namespace snmalloc
|
||||
|
||||
// Push memory into the global range.
|
||||
range_to_pow_2_blocks<MIN_CHUNK_BITS>(
|
||||
capptr::Chunk<void>::unsafe_from(heap_base),
|
||||
capptr::Arena<void>::unsafe_from(heap_base),
|
||||
heap_length,
|
||||
[&](capptr::Chunk<void> p, size_t sz, bool) {
|
||||
[&](capptr::Arena<void> p, size_t sz, bool) {
|
||||
typename LocalState::GlobalR g;
|
||||
g.dealloc_range(p, sz);
|
||||
});
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
namespace snmalloc
|
||||
{
|
||||
template<SNMALLOC_CONCEPT(capptr::ConceptBound) B = capptr::bounds::Chunk>
|
||||
template<SNMALLOC_CONCEPT(capptr::ConceptBound) B = capptr::bounds::Arena>
|
||||
class EmptyRange
|
||||
{
|
||||
public:
|
||||
|
||||
@@ -231,14 +231,14 @@ namespace snmalloc
|
||||
*/
|
||||
template<bool exists = MAX_SIZE_BITS != (bits::BITS - 1)>
|
||||
std::enable_if_t<exists>
|
||||
parent_dealloc_range(capptr::Chunk<void> base, size_t size)
|
||||
parent_dealloc_range(capptr::Arena<void> base, size_t size)
|
||||
{
|
||||
static_assert(
|
||||
MAX_SIZE_BITS != (bits::BITS - 1), "Don't set SFINAE parameter");
|
||||
parent.dealloc_range(base, size);
|
||||
}
|
||||
|
||||
void dealloc_overflow(capptr::Chunk<void> overflow)
|
||||
void dealloc_overflow(capptr::Arena<void> overflow)
|
||||
{
|
||||
if constexpr (MAX_SIZE_BITS != (bits::BITS - 1))
|
||||
{
|
||||
@@ -258,19 +258,19 @@ namespace snmalloc
|
||||
* Add a range of memory to the address space.
|
||||
* Divides blocks into power of two sizes with natural alignment
|
||||
*/
|
||||
void add_range(capptr::Chunk<void> base, size_t length)
|
||||
void add_range(capptr::Arena<void> base, size_t length)
|
||||
{
|
||||
range_to_pow_2_blocks<MIN_CHUNK_BITS>(
|
||||
base, length, [this](capptr::Chunk<void> base, size_t align, bool) {
|
||||
base, length, [this](capptr::Arena<void> base, size_t align, bool) {
|
||||
auto overflow =
|
||||
capptr::Chunk<void>::unsafe_from(reinterpret_cast<void*>(
|
||||
capptr::Arena<void>::unsafe_from(reinterpret_cast<void*>(
|
||||
buddy_large.add_block(base.unsafe_uintptr(), align)));
|
||||
|
||||
dealloc_overflow(overflow);
|
||||
});
|
||||
}
|
||||
|
||||
capptr::Chunk<void> refill(size_t size)
|
||||
capptr::Arena<void> refill(size_t size)
|
||||
{
|
||||
if (ParentRange::Aligned)
|
||||
{
|
||||
@@ -342,11 +342,14 @@ namespace snmalloc
|
||||
|
||||
static constexpr bool ConcurrencySafe = false;
|
||||
|
||||
using ChunkBounds = capptr::bounds::Chunk;
|
||||
/* The large buddy allocator always deals in Arena-bounded pointers. */
|
||||
using ChunkBounds = capptr::bounds::Arena;
|
||||
static_assert(
|
||||
std::is_same_v<typename ParentRange::ChunkBounds, ChunkBounds>);
|
||||
|
||||
constexpr Type() = default;
|
||||
|
||||
capptr::Chunk<void> alloc_range(size_t size)
|
||||
capptr::Arena<void> alloc_range(size_t size)
|
||||
{
|
||||
SNMALLOC_ASSERT(size >= MIN_CHUNK_SIZE);
|
||||
SNMALLOC_ASSERT(bits::is_pow2(size));
|
||||
@@ -359,7 +362,7 @@ namespace snmalloc
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto result = capptr::Chunk<void>::unsafe_from(
|
||||
auto result = capptr::Arena<void>::unsafe_from(
|
||||
reinterpret_cast<void*>(buddy_large.remove_block(size)));
|
||||
|
||||
if (result != nullptr)
|
||||
@@ -368,7 +371,7 @@ namespace snmalloc
|
||||
return refill(size);
|
||||
}
|
||||
|
||||
void dealloc_range(capptr::Chunk<void> base, size_t size)
|
||||
void dealloc_range(capptr::Arena<void> base, size_t size)
|
||||
{
|
||||
SNMALLOC_ASSERT(size >= MIN_CHUNK_SIZE);
|
||||
SNMALLOC_ASSERT(bits::is_pow2(size));
|
||||
@@ -383,7 +386,7 @@ namespace snmalloc
|
||||
}
|
||||
|
||||
auto overflow =
|
||||
capptr::Chunk<void>::unsafe_from(reinterpret_cast<void*>(
|
||||
capptr::Arena<void>::unsafe_from(reinterpret_cast<void*>(
|
||||
buddy_large.add_block(base.unsafe_uintptr(), size)));
|
||||
dealloc_overflow(overflow);
|
||||
}
|
||||
|
||||
@@ -14,11 +14,11 @@ namespace snmalloc
|
||||
// need to be changed.
|
||||
static constexpr bool ConcurrencySafe = true;
|
||||
|
||||
using ChunkBounds = capptr::bounds::Chunk;
|
||||
using ChunkBounds = capptr::bounds::Arena;
|
||||
|
||||
constexpr PalRange() = default;
|
||||
|
||||
capptr::Chunk<void> alloc_range(size_t size)
|
||||
capptr::Arena<void> alloc_range(size_t size)
|
||||
{
|
||||
if (bits::next_pow2_bits(size) >= bits::BITS - 1)
|
||||
{
|
||||
@@ -28,7 +28,7 @@ namespace snmalloc
|
||||
if constexpr (pal_supports<AlignedAllocation, PAL>)
|
||||
{
|
||||
SNMALLOC_ASSERT(size >= PAL::minimum_alloc_size);
|
||||
auto result = capptr::Chunk<void>::unsafe_from(
|
||||
auto result = capptr::Arena<void>::unsafe_from(
|
||||
PAL::template reserve_aligned<false>(size));
|
||||
|
||||
#ifdef SNMALLOC_TRACING
|
||||
@@ -38,7 +38,7 @@ namespace snmalloc
|
||||
}
|
||||
else
|
||||
{
|
||||
auto result = capptr::Chunk<void>::unsafe_from(PAL::reserve(size));
|
||||
auto result = capptr::Arena<void>::unsafe_from(PAL::reserve(size));
|
||||
|
||||
#ifdef SNMALLOC_TRACING
|
||||
message<1024>("Pal range alloc: {} ({})", result.unsafe_ptr(), size);
|
||||
|
||||
@@ -122,7 +122,7 @@ namespace snmalloc
|
||||
{
|
||||
Backend::template alloc_meta_data<void*>(local_state, size)
|
||||
}
|
||||
->ConceptSame<capptr::Chunk<void>>;
|
||||
->ConceptSame<capptr::Arena<void>>;
|
||||
}
|
||||
&&requires(
|
||||
LocalState& local_state,
|
||||
|
||||
Reference in New Issue
Block a user