Make Secondary Allocator a template parameter (#774)

This refactors the use of the Secondary Allocator, so that out of tree implementations can be used.
This commit is contained in:
Matthew Parkinson
2025-06-30 21:23:07 +01:00
committed by GitHub
parent e600bf1b38
commit 9a3d12a724
9 changed files with 28 additions and 33 deletions

View File

@@ -1,6 +1,7 @@
#pragma once
#include "../backend_helpers/backend_helpers.h"
#include "../mem/secondary/default.h"
#include "snmalloc/stl/type_traits.h"
#include "standard_range.h"
@@ -13,12 +14,14 @@ namespace snmalloc
*/
template<
SNMALLOC_CONCEPT(IsPAL) PAL,
typename ClientMetaDataProvider = NoClientMetaDataProvider>
typename ClientMetaDataProvider = NoClientMetaDataProvider,
typename SecondaryAllocator_ = DefaultSecondaryAllocator>
class FixedRangeConfig final : public CommonConfig
{
public:
using PagemapEntry = DefaultPagemapEntry<ClientMetaDataProvider>;
using ClientMeta = ClientMetaDataProvider;
using SecondaryAllocator = SecondaryAllocator_;
private:
using ConcretePagemap =

View File

@@ -3,7 +3,7 @@
#include "../backend_helpers/backend_helpers.h"
#include "backend.h"
#include "meta_protected_range.h"
#include "snmalloc/mem/secondary.h"
#include "snmalloc/mem/secondary/default.h"
#include "standard_range.h"
namespace snmalloc
@@ -22,16 +22,19 @@ namespace snmalloc
* The Configuration sets up a Pagemap for the backend to use, and the state
* required to build new allocators (GlobalPoolState).
*/
template<typename ClientMetaDataProvider = NoClientMetaDataProvider>
template<
typename ClientMetaDataProvider = NoClientMetaDataProvider,
typename SecondaryAllocator_ = DefaultSecondaryAllocator>
class StandardConfigClientMeta final : public CommonConfig
{
using GlobalPoolState =
PoolState<Allocator<StandardConfigClientMeta<ClientMetaDataProvider>>>;
using GlobalPoolState = PoolState<Allocator<
StandardConfigClientMeta<ClientMetaDataProvider, SecondaryAllocator_>>>;
public:
using Pal = DefaultPal;
using PagemapEntry = DefaultPagemapEntry<ClientMetaDataProvider>;
using ClientMeta = ClientMetaDataProvider;
using SecondaryAllocator = SecondaryAllocator_;
private:
using ConcretePagemap =

View File

@@ -302,9 +302,9 @@ namespace snmalloc
const auto& entry = Config_::Backend::get_metaentry(address_cast(p_raw));
if (SNMALLOC_UNLIKELY(
!SecondaryAllocator::pass_through && !entry.is_owned() &&
!Config::SecondaryAllocator::pass_through && !entry.is_owned() &&
p_raw != nullptr))
return SecondaryAllocator::alloc_size(p_raw);
return Config::SecondaryAllocator::alloc_size(p_raw);
// TODO What's the domestication policy here? At the moment we just
// probe the pagemap with the raw address, without checks. There could
// be implicit domestication through the `Config::Pagemap` or

View File

@@ -6,7 +6,6 @@
#include "metadata.h"
#include "pool.h"
#include "remotecache.h"
#include "secondary.h"
#include "sizeclasstable.h"
#include "snmalloc/stl/new.h"
#include "ticker.h"
@@ -653,7 +652,7 @@ namespace snmalloc
}
// Check if secondary allocator wants to offer the memory
void* result = SecondaryAllocator::allocate(
void* result = Config::SecondaryAllocator::allocate(
[size]() -> stl::Pair<size_t, size_t> {
return {size, natural_alignment(size)};
});
@@ -710,7 +709,7 @@ namespace snmalloc
SNMALLOC_FAST_PATH capptr::Alloc<void>
small_refill(smallsizeclass_t sizeclass, freelist::Iter<>& fast_free_list)
{
void* result = SecondaryAllocator::allocate(
void* result = Config::SecondaryAllocator::allocate(
[sizeclass]() -> stl::Pair<size_t, size_t> {
auto size = sizeclass_to_size(sizeclass);
return {size, natural_alignment(size)};
@@ -1285,7 +1284,7 @@ namespace snmalloc
}
dealloc_cheri_checks(p_tame.unsafe_ptr());
SecondaryAllocator::deallocate(p_tame.unsafe_ptr());
Config::SecondaryAllocator::deallocate(p_tame.unsafe_ptr());
}
/**

View File

@@ -1,20 +0,0 @@
#pragma once
#include "snmalloc/ds_core/defines.h"
#include "snmalloc/ds_core/ptrwrap.h"
#ifdef SNMALLOC_ENABLE_GWP_ASAN_INTEGRATION
# include "snmalloc/mem/secondary/gwp_asan.h"
namespace snmalloc
{
using SecondaryAllocator = GwpAsanSecondaryAllocator;
} // namespace snmalloc
#else
# include "snmalloc/mem/secondary/default.h"
namespace snmalloc
{
using SecondaryAllocator = DefaultSecondaryAllocator;
} // namespace snmalloc
#endif

View File

@@ -6,13 +6,23 @@
// Provides the global configuration for the snmalloc implementation.
#include "backend/globalconfig.h"
#ifdef SNMALLOC_ENABLE_GWP_ASAN_INTEGRATION
# include "snmalloc/mem/secondary/gwp_asan.h"
#endif
namespace snmalloc
{
// If you define SNMALLOC_PROVIDE_OWN_CONFIG then you must provide your own
// definition of `snmalloc::Alloc` before including any files that include
// `snmalloc.h` or consume the global allocation APIs.
#ifndef SNMALLOC_PROVIDE_OWN_CONFIG
# ifdef SNMALLOC_ENABLE_GWP_ASAN_INTEGRATION
using Config = snmalloc::StandardConfigClientMeta<
NoClientMetaDataProvider,
GwpAsanSecondaryAllocator>;
# else
using Config = snmalloc::StandardConfigClientMeta<NoClientMetaDataProvider>;
# endif
#endif
/**
* Create allocator type for this configuration.

View File

@@ -5,6 +5,7 @@
#include <snmalloc/backend/backend.h>
#include <snmalloc/backend/standard_range.h>
#include <snmalloc/backend_helpers/backend_helpers.h>
#include <snmalloc/mem/secondary/default.h>
#include <snmalloc/snmalloc_core.h>
// Specify type of allocator
@@ -18,6 +19,7 @@ namespace snmalloc
using Pal = DefaultPal;
using PagemapEntry = DefaultPagemapEntry<NoClientMetaDataProvider>;
using ClientMeta = NoClientMetaDataProvider;
using SecondaryAllocator = DefaultSecondaryAllocator;
private:
using ConcretePagemap =

View File

@@ -1,4 +1,3 @@
#include "snmalloc/mem/secondary.h"
#include "test/setup.h"
#include <iostream>

View File

@@ -1,4 +1,3 @@
#include "snmalloc/mem/secondary.h"
#include "test/setup.h"
#include <iostream>