Introduce a class that we can use to more completely separate the frontend encoding details from the backend.
120 lines
3.8 KiB
C++
120 lines
3.8 KiB
C++
#pragma once
|
|
|
|
#ifdef __cpp_concepts
|
|
# include <cstddef>
|
|
# include "../ds/concept.h"
|
|
# include "../pal/pal_concept.h"
|
|
# include "../ds/address.h"
|
|
namespace snmalloc
|
|
{
|
|
class MetaEntry;
|
|
|
|
/**
|
|
* The core of the static pagemap accessor interface: {get,set}_metadata.
|
|
*
|
|
* get_metadata takes a bool-ean template parameter indicating whether it may
|
|
* be accessing memory that is not known to be committed.
|
|
*/
|
|
template<typename Meta>
|
|
concept ConceptBackendMeta =
|
|
requires(
|
|
address_t addr,
|
|
size_t sz,
|
|
const MetaEntry& t)
|
|
{
|
|
{ Meta::set_metaentry(addr, sz, t) } -> ConceptSame<void>;
|
|
|
|
{ Meta::template get_metaentry<MetaEntry, true>(addr) }
|
|
-> ConceptSame<const MetaEntry&>;
|
|
|
|
{ Meta::template get_metaentry<MetaEntry, false>(addr) }
|
|
-> ConceptSame<const MetaEntry&>;
|
|
};
|
|
|
|
/**
|
|
* The pagemap can also be told to commit backing storage for a range of
|
|
* addresses. This is broken out to a separate concept so that we can
|
|
* annotate which functions expect to do this vs. which merely use the core
|
|
* interface above. In practice, use ConceptBackendMetaRange (without the
|
|
* underscore) below, which combines this and the core concept, above.
|
|
*/
|
|
template<typename Meta>
|
|
concept ConceptBackendMeta_Range =
|
|
requires(address_t addr, size_t sz)
|
|
{
|
|
{ Meta::register_range(addr, sz) } -> ConceptSame<void>;
|
|
};
|
|
|
|
/**
|
|
* The full pagemap accessor interface, with all of {get,set}_metadata and
|
|
* register_range. Use this to annotate callers that need the full interface
|
|
* and use ConceptBackendMeta for callers that merely need {get,set}_metadata,
|
|
* but note that the difference is just for humans and not compilers (since
|
|
* concept checking is lower bounding and does not constrain the templatized
|
|
* code to use only those affordances given by the concept).
|
|
*/
|
|
template<typename Meta>
|
|
concept ConceptBackendMetaRange =
|
|
ConceptBackendMeta<Meta> && ConceptBackendMeta_Range<Meta>;
|
|
|
|
/**
|
|
* The backend also defines domestication (that is, the difference between
|
|
* Tame and Wild CapPtr bounds). It exports the intended affordance for
|
|
* testing a Wild pointer and either returning nullptr or the original
|
|
* pointer, now Tame.
|
|
*/
|
|
template<typename Globals>
|
|
concept ConceptBackendDomestication =
|
|
requires(
|
|
typename Globals::LocalState* ls,
|
|
capptr::AllocWild<void> ptr)
|
|
{
|
|
{ Globals::capptr_domesticate(ls, ptr) }
|
|
-> ConceptSame<capptr::Alloc<void>>;
|
|
|
|
{ Globals::capptr_domesticate(ls, ptr.template as_static<char>()) }
|
|
-> ConceptSame<capptr::Alloc<char>>;
|
|
};
|
|
|
|
class CommonConfig;
|
|
struct Flags;
|
|
|
|
/**
|
|
* Backend global objects of type T must obey a number of constraints. They
|
|
* must...
|
|
*
|
|
* * inherit from CommonConfig (see commonconfig.h)
|
|
* * specify which PAL is in use via T::Pal
|
|
* * have static pagemap accessors via T::Pagemap
|
|
* * define a T::LocalState type (and alias it as T::Pagemap::LocalState)
|
|
* * define T::Options of type snmalloc::Flags
|
|
* * expose the global allocator pool via T::pool()
|
|
*
|
|
*/
|
|
template<typename Globals>
|
|
concept ConceptBackendGlobals =
|
|
std::is_base_of<CommonConfig, Globals>::value &&
|
|
ConceptPAL<typename Globals::Pal> &&
|
|
ConceptBackendMetaRange<typename Globals::Pagemap> &&
|
|
requires()
|
|
{
|
|
typename Globals::LocalState;
|
|
|
|
{ Globals::Options } -> ConceptSameModRef<const Flags>;
|
|
|
|
typename Globals::GlobalPoolState;
|
|
{ Globals::pool() } -> ConceptSame<typename Globals::GlobalPoolState &>;
|
|
|
|
};
|
|
|
|
/**
|
|
* The lazy version of the above; please see ds/concept.h and use sparingly.
|
|
*/
|
|
template<typename Globals>
|
|
concept ConceptBackendGlobalsLazy =
|
|
!is_type_complete_v<Globals> || ConceptBackendGlobals<Globals>;
|
|
|
|
} // namespace snmalloc
|
|
|
|
#endif
|