зеркало из https://github.com/microsoft/snmalloc.git
Add some type safety to other pagemap accesses.
Introduce a descriptor for the pagemap config and check that the source descriptor is compatible with the destination type.
This commit is contained in:
Родитель
51fbdf3a44
Коммит
a93f43fd2f
|
@ -10,6 +10,36 @@ namespace snmalloc
|
|||
static constexpr size_t PAGEMAP_NODE_BITS = 16;
|
||||
static constexpr size_t PAGEMAP_NODE_SIZE = 1ULL << PAGEMAP_NODE_BITS;
|
||||
|
||||
/**
|
||||
* Structure describing the configuration of a pagemap. When querying a
|
||||
* pagemap from a different instantiation of snmalloc, the pagemap is exposed
|
||||
* as a `void*`. This structure allows the caller to check whether the
|
||||
* pagemap is of the format that they expect.
|
||||
*/
|
||||
struct PagemapConfig
|
||||
{
|
||||
/**
|
||||
* The version of the pagemap structure. This is always 1 in existing
|
||||
* versions of snmalloc. This will be incremented every time the format
|
||||
* changes in an incompatible way. Changes to the format may add fields to
|
||||
* the end of this structure.
|
||||
*/
|
||||
uint32_t version;
|
||||
/**
|
||||
* Is this a flat pagemap? If this field is false, the pagemap is the
|
||||
* hierarchical structure.
|
||||
*/
|
||||
bool is_flat_pagemap;
|
||||
/**
|
||||
* The number of bits of the address used to index into the pagemap.
|
||||
*/
|
||||
uint64_t pagemap_bits;
|
||||
/**
|
||||
* The size (in bytes) of a pagemap entry.
|
||||
*/
|
||||
size_t size_of_entry;
|
||||
};
|
||||
|
||||
template<size_t GRANULARITY_BITS, typename T, T default_content>
|
||||
class Pagemap
|
||||
{
|
||||
|
@ -168,6 +198,19 @@ namespace snmalloc
|
|||
}
|
||||
|
||||
public:
|
||||
static constexpr PagemapConfig config = {
|
||||
1, false, GRANULARITY_BITS, sizeof(T)};
|
||||
static Pagemap* cast_to_pagemap(void* pm, const PagemapConfig* c)
|
||||
{
|
||||
if (
|
||||
(c->version != 1) || (c->is_flat_pagemap) ||
|
||||
(c->pagemap_bits != GRANULARITY_BITS) ||
|
||||
(c->size_of_entry != sizeof(T)) || (!std::is_integral_v<T>))
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
return static_cast<Pagemap*>(pm);
|
||||
}
|
||||
/**
|
||||
* Returns the index of a pagemap entry within a given page. This is used
|
||||
* in code that propagates changes to the pagemap elsewhere.
|
||||
|
@ -247,6 +290,20 @@ namespace snmalloc
|
|||
std::atomic<T> top[ENTRIES];
|
||||
|
||||
public:
|
||||
static constexpr PagemapConfig config = {
|
||||
1, true, GRANULARITY_BITS, sizeof(T)};
|
||||
|
||||
static FlatPagemap* cast_to_pagemap(void* pm, PagemapConfig* c)
|
||||
{
|
||||
if (
|
||||
(c->version != 1) || (!c->is_flat_pagemap) ||
|
||||
(c->pagemap_bits != GRANULARITY_BITS) ||
|
||||
(c->size_of_entry != sizeof(T)) || (!std::is_integral_v<T>))
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
return static_cast<FlatPagemap*>(pm);
|
||||
}
|
||||
T get(void* p)
|
||||
{
|
||||
return top[(size_t)p >> SHIFT].load(std::memory_order_relaxed);
|
||||
|
@ -268,4 +325,5 @@ namespace snmalloc
|
|||
} while (length > 0);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -206,8 +206,16 @@ extern "C"
|
|||
}
|
||||
|
||||
#ifdef SNMALLOC_EXPOSE_PAGEMAP
|
||||
SNMALLOC_EXPORT void* SNMALLOC_NAME_MANGLE(snmalloc_get_global_pagemap)(void)
|
||||
SNMALLOC_EXPORT void* SNMALLOC_NAME_MANGLE(snmalloc_get_global_pagemap)(
|
||||
PagemapConfig const** config)
|
||||
{
|
||||
if (config)
|
||||
{
|
||||
*config = &decltype(snmalloc::global_pagemap)::config;
|
||||
assert(
|
||||
decltype(snmalloc::global_pagemap)::cast_to_pagemap(
|
||||
&snmalloc::global_pagemap, *config) == &snmalloc::global_pagemap);
|
||||
}
|
||||
return &snmalloc::global_pagemap;
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#define USE_RESERVE_MULTIPLE 1
|
||||
#define NO_BOOTSTRAP_ALLOCATOR
|
||||
#define IS_ADDRESS_SPACE_CONSTRAINED
|
||||
#define SNMALLOC_EXPOSE_PAGEMAP
|
||||
#define SNMALLOC_NAME_MANGLE(a) enclave_##a
|
||||
// Redefine the namespace, so we can have two versions.
|
||||
#define snmalloc snmalloc_enclave
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#undef IS_ADDRESS_SPACE_CONSTRAINED
|
||||
#define SNMALLOC_NAME_MANGLE(a) host_##a
|
||||
#define NO_BOOTSTRAP_ALLOCATOR
|
||||
#define SNMALLOC_EXPOSE_PAGEMAP
|
||||
// Redefine the namespace, so we can have two versions.
|
||||
#define snmalloc snmalloc_host
|
||||
#include "../../../override/malloc.cc"
|
||||
#include "../../../override/malloc.cc"
|
||||
|
|
|
@ -32,6 +32,11 @@ extern "C" void host_free(void*);
|
|||
extern "C" void* enclave_malloc(size_t);
|
||||
extern "C" void enclave_free(void*);
|
||||
|
||||
extern "C" void*
|
||||
enclave_snmalloc_get_global_pagemap(snmalloc::PagemapConfig const**);
|
||||
extern "C" void*
|
||||
host_snmalloc_get_global_pagemap(snmalloc::PagemapConfig const**);
|
||||
|
||||
using namespace snmalloc;
|
||||
int main()
|
||||
{
|
||||
|
@ -42,6 +47,10 @@ int main()
|
|||
oe_end = (uint8_t*)oe_base + size;
|
||||
std::cout << "Allocated region " << oe_base << " - " << oe_end << std::endl;
|
||||
|
||||
// Call these functions to trigger asserts if the cast-to-self doesn't work.
|
||||
enclave_snmalloc_get_global_pagemap(nullptr);
|
||||
host_snmalloc_get_global_pagemap(nullptr);
|
||||
|
||||
auto a = host_malloc(128);
|
||||
auto b = enclave_malloc(128);
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче