зеркало из https://github.com/microsoft/snmalloc.git
PagemapRegisterRange: don't presume Pagemap entry type
To date, we've had exactly one kind of Pagemap and it held exactly one type of thing, a descendant of class MetaEntryBase. PagemapRegisterRange tacitly assumed that the Pagemap (adapter) it interacted would therefore store entries that could have .set_boundary() called on them. But in general there's no requirement that this be true; Pagemaps are generic data structures. To enable reuse of the PagemapRegisterRange machinery more generally, change the type of Pagemap::register_range() to take a pointer (rather than an address) and move the MetaEntryBase-specific functionality to the backend_helpers/pagemap adapter.
This commit is contained in:
Родитель
06873ac366
Коммит
7f3b59eaf9
|
@ -74,7 +74,9 @@ namespace snmalloc
|
|||
auto [heap_base, heap_length] =
|
||||
Pagemap::concretePagemap.init(base, length);
|
||||
|
||||
Pagemap::register_range(address_cast(heap_base), heap_length);
|
||||
auto heap_arena = capptr::Arena<void>::unsafe_from(heap_base);
|
||||
|
||||
Pagemap::register_range(heap_arena, heap_length);
|
||||
|
||||
// Push memory into the global range.
|
||||
range_to_pow_2_blocks<MIN_CHUNK_BITS>(
|
||||
|
|
|
@ -62,15 +62,9 @@ namespace snmalloc
|
|||
* mmap/virtual alloc calls can be consolidated.
|
||||
* @{
|
||||
*/
|
||||
# if defined(_WIN32) || defined(__CHERI_PURE_CAPABILITY__)
|
||||
static constexpr bool CONSOLIDATE_PAL_ALLOCS = false;
|
||||
# else
|
||||
static constexpr bool CONSOLIDATE_PAL_ALLOCS = true;
|
||||
# endif
|
||||
|
||||
using Base = Pipe<
|
||||
PalRange<Pal>,
|
||||
PagemapRegisterRange<Pagemap, CONSOLIDATE_PAL_ALLOCS>>;
|
||||
using Base = Pipe<PalRange<Pal>, PagemapRegisterRange<Pagemap>>;
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
|
|
@ -32,6 +32,21 @@ namespace snmalloc
|
|||
std::is_same_v<PagemapEntry, typename ConcreteMap::EntryType>,
|
||||
"BasicPagemap's PagemapEntry and ConcreteMap disagree!");
|
||||
|
||||
static_assert(
|
||||
std::is_base_of_v<MetaEntryBase, PagemapEntry>,
|
||||
"BasicPagemap's PagemapEntry type is not a MetaEntryBase");
|
||||
|
||||
/**
|
||||
* Prevent snmalloc's backend ranges from consolidating across adjacent OS
|
||||
* allocations on platforms (e.g., Windows or StrictProvenance) where
|
||||
* that's required.
|
||||
*/
|
||||
#if defined(_WIN32) || defined(__CHERI_PURE_CAPABILITY__)
|
||||
static constexpr bool CONSOLIDATE_PAL_ALLOCS = false;
|
||||
#else
|
||||
static constexpr bool CONSOLIDATE_PAL_ALLOCS = true;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Instance of the concrete pagemap, accessible to the backend so that
|
||||
* it can call the init method whose type dependent on fixed_range.
|
||||
|
@ -78,10 +93,19 @@ namespace snmalloc
|
|||
/**
|
||||
* Register a range in the pagemap as in-use, requiring it to allow writing
|
||||
* to the underlying memory.
|
||||
*
|
||||
* Mark the MetaEntry at the bottom of the range as a boundary, preventing
|
||||
* consolidation with a lower range, unless CONSOLIDATE_PAL_ALLOCS.
|
||||
*/
|
||||
static void register_range(address_t p, size_t sz)
|
||||
static void register_range(capptr::Arena<void> p, size_t sz)
|
||||
{
|
||||
concretePagemap.register_range(p, sz);
|
||||
concretePagemap.register_range(address_cast(p), sz);
|
||||
if constexpr (!CONSOLIDATE_PAL_ALLOCS)
|
||||
{
|
||||
// Mark start of allocation in pagemap.
|
||||
auto& entry = get_metaentry_mut(address_cast(p));
|
||||
entry.set_boundary();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -1,14 +1,13 @@
|
|||
#pragma once
|
||||
|
||||
#include "../mem/metadata.h"
|
||||
#include "../pal/pal.h"
|
||||
#include "empty_range.h"
|
||||
#include "range_helpers.h"
|
||||
|
||||
namespace snmalloc
|
||||
{
|
||||
template<
|
||||
SNMALLOC_CONCEPT(IsWritablePagemapWithRegister) Pagemap,
|
||||
bool CanConsolidate = true>
|
||||
template<SNMALLOC_CONCEPT(IsPagemapWithRegister) Pagemap>
|
||||
struct PagemapRegisterRange
|
||||
{
|
||||
template<typename ParentRange = EmptyRange<>>
|
||||
|
@ -30,13 +29,8 @@ namespace snmalloc
|
|||
auto base = parent.alloc_range(size);
|
||||
|
||||
if (base != nullptr)
|
||||
Pagemap::register_range(address_cast(base), size);
|
||||
|
||||
if (!CanConsolidate)
|
||||
{
|
||||
// Mark start of allocation in pagemap.
|
||||
auto& entry = Pagemap::get_metaentry_mut(address_cast(base));
|
||||
entry.set_boundary();
|
||||
Pagemap::register_range(base, size);
|
||||
}
|
||||
|
||||
return base;
|
||||
|
|
|
@ -63,10 +63,10 @@ namespace snmalloc
|
|||
* which combines this and the core concept, above.
|
||||
*/
|
||||
template<typename Pagemap>
|
||||
concept IsPagemapWithRegister = requires(address_t addr, size_t sz)
|
||||
concept IsPagemapWithRegister = requires(capptr::Arena<void> p, size_t sz)
|
||||
{
|
||||
{
|
||||
Pagemap::register_range(addr, sz)
|
||||
Pagemap::register_range(p, sz)
|
||||
}
|
||||
->ConceptSame<void>;
|
||||
};
|
||||
|
|
|
@ -36,7 +36,7 @@ namespace snmalloc
|
|||
using LocalState = StandardLocalState<
|
||||
Pal,
|
||||
Pagemap,
|
||||
Pipe<PalRange<Pal>, PagemapRegisterRange<Pagemap, false>>>;
|
||||
Pipe<PalRange<Pal>, PagemapRegisterRange<Pagemap>>>;
|
||||
|
||||
using GlobalPoolState = PoolState<CoreAllocator<CustomConfig>>;
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче