Pagemap requires registration of used space
This PR exposes a pagemap interface to specify ranges that are being used. The overall invariant is that any memory in the address space manager has the pagemap committed. This means that individual operations do not need to commit entries. This is important for Windows that does not support lazy commit. It is also important if we want to PROT_NONE most of the pagemap to reduce the risk of memory safety issues getting access to the pagemap. There are minor changes to test to pull memory directly from the Pal. There are also bug fixes in the pagemap tests.
This commit is contained in:
committed by
Matthew Parkinson
parent
da01d5b4ca
commit
02d2ab8f7e
@@ -18,18 +18,14 @@ int main()
|
||||
{
|
||||
#ifndef SNMALLOC_PASS_THROUGH // Depends on snmalloc specific features
|
||||
|
||||
// Create a standard address space to get initial allocation
|
||||
// this just bypasses having to understand the test platform.
|
||||
AddressSpaceManager<DefaultPal> address_space;
|
||||
|
||||
// 28 is large enough to produce a nested allocator.
|
||||
// It is also large enough for the example to run in.
|
||||
// For 1MiB superslabs, SUPERSLAB_BITS + 4 is not big enough for the example.
|
||||
size_t size = bits::one_at_bit(28);
|
||||
auto oe_base = address_space.reserve<true>(size);
|
||||
auto oe_end = pointer_offset(oe_base, size).unsafe_ptr();
|
||||
std::cout << "Allocated region " << oe_base.unsafe_ptr() << " - "
|
||||
<< pointer_offset(oe_base, size).unsafe_ptr() << std::endl;
|
||||
auto [oe_base, size] = Pal::reserve_at_least(bits::one_at_bit(28));
|
||||
Pal::notify_using<NoZero>(oe_base, size);
|
||||
auto oe_end = pointer_offset(oe_base, size);
|
||||
std::cout << "Allocated region " << oe_base << " - "
|
||||
<< pointer_offset(oe_base, size) << std::endl;
|
||||
|
||||
CustomGlobals fixed_handle;
|
||||
CustomGlobals::init(oe_base, size);
|
||||
@@ -47,7 +43,7 @@ int main()
|
||||
if (r1 == nullptr)
|
||||
break;
|
||||
|
||||
if (oe_base.unsafe_ptr() > r1)
|
||||
if (oe_base > r1)
|
||||
{
|
||||
std::cout << "Allocated: " << r1 << std::endl;
|
||||
abort();
|
||||
|
||||
@@ -47,14 +47,6 @@ void check_get(
|
||||
}
|
||||
}
|
||||
|
||||
void add(bool bounded, address_t address, T new_value)
|
||||
{
|
||||
if (bounded)
|
||||
pagemap_test_bound.add(address, new_value);
|
||||
else
|
||||
pagemap_test_unbound.add(address, new_value);
|
||||
}
|
||||
|
||||
void set(bool bounded, address_t address, T new_value)
|
||||
{
|
||||
if (bounded)
|
||||
@@ -71,38 +63,36 @@ void test_pagemap(bool bounded)
|
||||
address_t high = bits::one_at_bit(30);
|
||||
|
||||
// Nullptr needs to work before initialisation
|
||||
CHECK_GET(true, 0, T());
|
||||
CHECK_GET(bounded, 0, T());
|
||||
|
||||
// Initialise the pagemap
|
||||
if (bounded)
|
||||
{
|
||||
auto size = bits::one_at_bit(30);
|
||||
auto base = address_space.reserve<true>(size);
|
||||
std::cout << "Fixed base: " << base.unsafe_ptr() << " (" << size << ") "
|
||||
<< " end: " << pointer_offset(base, size).unsafe_ptr()
|
||||
<< std::endl;
|
||||
auto [base, size] = Pal::reserve_at_least(bits::one_at_bit(30));
|
||||
Pal::notify_using<NoZero>(base, size);
|
||||
std::cout << "Fixed base: " << base << " (" << size << ") "
|
||||
<< " end: " << pointer_offset(base, size) << std::endl;
|
||||
auto [heap_base, heap_size] = pagemap_test_bound.init(base, size);
|
||||
std::cout << "Heap base: " << heap_base.unsafe_ptr() << " (" << heap_size
|
||||
<< ") "
|
||||
<< " end: " << pointer_offset(heap_base, heap_size).unsafe_ptr()
|
||||
<< std::endl;
|
||||
std::cout << "Heap base: " << heap_base << " (" << heap_size << ") "
|
||||
<< " end: " << pointer_offset(heap_base, heap_size) << std::endl;
|
||||
low = address_cast(heap_base);
|
||||
high = low + heap_size;
|
||||
}
|
||||
else
|
||||
{
|
||||
pagemap_test_unbound.init();
|
||||
pagemap_test_unbound.register_range(low, high - low);
|
||||
}
|
||||
|
||||
// Nullptr should still work after init.
|
||||
CHECK_GET(true, 0, T());
|
||||
CHECK_GET(bounded, 0, T());
|
||||
|
||||
// Store a pattern into page map
|
||||
T value = 1;
|
||||
for (uintptr_t ptr = low; ptr < high;
|
||||
ptr += bits::one_at_bit(GRANULARITY_BITS + 3))
|
||||
{
|
||||
add(false, ptr, value);
|
||||
set(bounded, ptr, value);
|
||||
value.v++;
|
||||
if (value.v == T().v)
|
||||
value = 0;
|
||||
@@ -116,7 +106,7 @@ void test_pagemap(bool bounded)
|
||||
for (uintptr_t ptr = low; ptr < high;
|
||||
ptr += bits::one_at_bit(GRANULARITY_BITS + 3))
|
||||
{
|
||||
CHECK_GET(false, ptr, value);
|
||||
CHECK_GET(bounded, ptr, value);
|
||||
value.v++;
|
||||
if (value.v == T().v)
|
||||
value = 0;
|
||||
|
||||
@@ -20,6 +20,5 @@ namespace snmalloc
|
||||
extern "C" void oe_allocator_init(void* base, void* end)
|
||||
{
|
||||
snmalloc::CustomGlobals fixed_handle;
|
||||
fixed_handle.init(
|
||||
CapPtr<void, CBChunk>(base), address_cast(end) - address_cast(base));
|
||||
fixed_handle.init(base, address_cast(end) - address_cast(base));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user