From e51f1c3d5005315cc7663dabc19691c7b495b404 Mon Sep 17 00:00:00 2001 From: Matthew Parkinson Date: Wed, 23 Jan 2019 11:03:13 +0000 Subject: [PATCH 1/6] Namespace test globals for external_pointer Some times the global count was leading to a warning with a local count in the test. --- .../perf/external_pointer/externalpointer.cc | 106 +++++++++--------- 1 file changed, 55 insertions(+), 51 deletions(-) diff --git a/src/test/perf/external_pointer/externalpointer.cc b/src/test/perf/external_pointer/externalpointer.cc index 9ec8cceb..453ccf48 100644 --- a/src/test/perf/external_pointer/externalpointer.cc +++ b/src/test/perf/external_pointer/externalpointer.cc @@ -5,62 +5,66 @@ using namespace snmalloc; -constexpr size_t count_log = 20; -constexpr size_t count = 1 << count_log; -// Pre allocate all the objects -size_t* objects[count]; - -NOINLINE void setup(xoroshiro::p128r64& r, Alloc* alloc) +namespace test { - for (size_t i = 0; i < count; i++) + static constexpr size_t count_log = 20; + static constexpr size_t count = 1 << count_log; + // Pre allocate all the objects + size_t* objects[count]; + + + NOINLINE void setup(xoroshiro::p128r64& r, Alloc* alloc) { - size_t rand = (size_t)r.next(); - size_t offset = bits::clz(rand); - if (offset > 30) - offset = 30; - size_t size = (rand & 15) << offset; - if (size < 16) - size = 16; - // store object - objects[i] = (size_t*)alloc->alloc(size); - // Store allocators size for this object - *objects[i] = Alloc::alloc_size(objects[i]); - } -} - -NOINLINE void teardown(Alloc* alloc) -{ - // Deallocate everything - for (size_t i = 0; i < count; i++) - { - alloc->dealloc(objects[i]); - } - - current_alloc_pool()->debug_check_empty(); -} - -void test_external_pointer(xoroshiro::p128r64& r) -{ - auto* alloc = ThreadAlloc::get(); - - setup(r, alloc); - - DO_TIME("External pointer queries ", { - for (size_t i = 0; i < 10000000; i++) + for (size_t i = 0; i < count; i++) { size_t rand = (size_t)r.next(); - size_t oid = rand & (((size_t)1 << count_log) - 1); - size_t* external_ptr = objects[oid]; - size_t size = *external_ptr; - size_t offset = (size >> 4) * (rand & 15); - size_t interior_ptr = ((size_t)external_ptr) + offset; - void* calced_external = Alloc::external_pointer((void*)interior_ptr); - if (calced_external != external_ptr) - abort(); + size_t offset = bits::clz(rand); + if (offset > 30) + offset = 30; + size_t size = (rand & 15) << offset; + if (size < 16) + size = 16; + // store object + objects[i] = (size_t*)alloc->alloc(size); + // Store allocators size for this object + *objects[i] = Alloc::alloc_size(objects[i]); } - }); + } - teardown(alloc); + NOINLINE void teardown(Alloc* alloc) + { + // Deallocate everything + for (size_t i = 0; i < count; i++) + { + alloc->dealloc(objects[i]); + } + + current_alloc_pool()->debug_check_empty(); + } + + void test_external_pointer(xoroshiro::p128r64& r) + { + auto* alloc = ThreadAlloc::get(); + + setup(r, alloc); + + DO_TIME("External pointer queries ", { + for (size_t i = 0; i < 10000000; i++) + { + size_t rand = (size_t)r.next(); + size_t oid = rand & (((size_t)1 << count_log) - 1); + size_t* external_ptr = objects[oid]; + size_t size = *external_ptr; + size_t offset = (size >> 4) * (rand & 15); + size_t interior_ptr = ((size_t)external_ptr) + offset; + void* calced_external = Alloc::external_pointer((void*)interior_ptr); + if (calced_external != external_ptr) + abort(); + } + }); + + teardown(alloc); + } } int main(int, char**) @@ -73,6 +77,6 @@ int main(int, char**) #endif for (size_t n = 0; n < nn; n++) - test_external_pointer(r); + test::test_external_pointer(r); return 0; } From 8d074468ae6040a4f01d98b91276357a80d072ab Mon Sep 17 00:00:00 2001 From: Matthew Parkinson Date: Wed, 23 Jan 2019 11:03:43 +0000 Subject: [PATCH 2/6] Fix MSVC warning in malloc.cc --- src/override/malloc.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/override/malloc.cc b/src/override/malloc.cc index c879ab6e..0d9e9a1d 100644 --- a/src/override/malloc.cc +++ b/src/override/malloc.cc @@ -140,7 +140,7 @@ extern "C" for (; sc < NUM_SIZECLASSES; sc++) { size = sizeclass_to_size(sc); - if ((size & -size) >= alignment) + if ((size & (~size - 1)) >= alignment) { return SNMALLOC_NAME_MANGLE(aligned_alloc)(alignment, size); } From ef3a57850399eda588182a6ccc7b5595ca7e5b2d Mon Sep 17 00:00:00 2001 From: Matthew Parkinson Date: Wed, 23 Jan 2019 11:05:50 +0000 Subject: [PATCH 3/6] Allow __je_bootstrap methods to not be compiled The __je_bootstrap.. allocator methods can be specified that they shouldn't be compiled using NO_BOOTSTRAP_ALLOCATION. --- src/override/malloc.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/override/malloc.cc b/src/override/malloc.cc index 0d9e9a1d..09b04361 100644 --- a/src/override/malloc.cc +++ b/src/override/malloc.cc @@ -201,7 +201,7 @@ extern "C" return ENOENT; } -#ifndef __PIC__ +#if !defined(__PIC__) && !defined(NO_BOOTSTRAP_ALLOCATOR) // The following functions are required to work before TLS is set up, in // statically-linked programs. These temporarily grab an allocator from the // pool and return it. From 5240b3f8c626b4967e9030978da16a7a624fe244 Mon Sep 17 00:00:00 2001 From: Matthew Parkinson Date: Wed, 23 Jan 2019 11:06:07 +0000 Subject: [PATCH 4/6] Formatting --- src/override/malloc.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/override/malloc.cc b/src/override/malloc.cc index 09b04361..5814b04f 100644 --- a/src/override/malloc.cc +++ b/src/override/malloc.cc @@ -210,6 +210,7 @@ extern "C" { return get_slow_allocator()->alloc(size); } + void* __je_bootstrap_calloc(size_t nmemb, size_t size) { bool overflow = false; @@ -223,6 +224,7 @@ extern "C" sz = ((sz - 1) >> (bits::BITS - 1)) + sz; return get_slow_allocator()->alloc(sz); } + void __je_bootstrap_free(void* ptr) { get_slow_allocator()->dealloc(ptr); From 28a28bb1ed26c7f239a38643d6c73b63f2824216 Mon Sep 17 00:00:00 2001 From: Matthew Parkinson Date: Wed, 23 Jan 2019 11:08:21 +0000 Subject: [PATCH 5/6] Simple example of using two allocators in one application. Example to simulate using two allocators in one application. This will be useful for scenarios in openenclave. --- src/test/func/two_alloc_types/alloc1.cc | 10 +++++ src/test/func/two_alloc_types/alloc2.cc | 6 +++ src/test/func/two_alloc_types/main.cc | 53 +++++++++++++++++++++++++ 3 files changed, 69 insertions(+) create mode 100644 src/test/func/two_alloc_types/alloc1.cc create mode 100644 src/test/func/two_alloc_types/alloc2.cc create mode 100644 src/test/func/two_alloc_types/main.cc diff --git a/src/test/func/two_alloc_types/alloc1.cc b/src/test/func/two_alloc_types/alloc1.cc new file mode 100644 index 00000000..f7333e43 --- /dev/null +++ b/src/test/func/two_alloc_types/alloc1.cc @@ -0,0 +1,10 @@ +#undef IS_ADDRESS_SPACE_CONSTRAINED +#define OPEN_ENCLAVE +#define OPEN_ENCLAVE_SIMULATION +#define USE_RESERVE_MULTIPLE 1 +#define NO_BOOTSTRAP_ALLOCATOR +#define IS_ADDRESS_SPACE_CONSTRAINED +#define SNMALLOC_NAME_MANGLE(a) enclave_##a +// Redefine the namespace, so we can have two versions. +#define snmalloc snmalloc_enclave +#include "../../../override/malloc.cc" diff --git a/src/test/func/two_alloc_types/alloc2.cc b/src/test/func/two_alloc_types/alloc2.cc new file mode 100644 index 00000000..f3a151be --- /dev/null +++ b/src/test/func/two_alloc_types/alloc2.cc @@ -0,0 +1,6 @@ +#undef IS_ADDRESS_SPACE_CONSTRAINED +#define SNMALLOC_NAME_MANGLE(a) host_##a +#define NO_BOOTSTRAP_ALLOCATOR +// Redefine the namespace, so we can have two versions. +#define snmalloc snmalloc_host +#include "../../../override/malloc.cc" \ No newline at end of file diff --git a/src/test/func/two_alloc_types/main.cc b/src/test/func/two_alloc_types/main.cc new file mode 100644 index 00000000..f34ee6d6 --- /dev/null +++ b/src/test/func/two_alloc_types/main.cc @@ -0,0 +1,53 @@ +#include "../../../snmalloc.h" + +#include +#include +#include + +void* oe_base; +void* oe_end; +extern "C" const void* __oe_get_heap_base() +{ + return oe_base; +} + +extern "C" const void* __oe_get_heap_end() +{ + return oe_end; +} + +extern "C" void* oe_memset(void* p, int c, size_t size) +{ + return memset(p, c, size); +} + +extern "C" void oe_abort() +{ + abort(); +} + +extern "C" void* host_malloc(size_t); +extern "C" void host_free(void*); + +extern "C" void* enclave_malloc(size_t); +extern "C" void enclave_free(void*); + +using namespace snmalloc; +int main() +{ + DefaultPal pal; + + size_t size = 1ULL << 28; + oe_base = pal.reserve(&size, 0); + oe_end = (uint8_t*)oe_base + size; + std::cout << "Allocated region " << oe_base << " - " << oe_end << std::endl; + + auto a = host_malloc(128); + auto b = enclave_malloc(128); + + std::cout << "Host alloc " << a << std::endl; + std::cout << "Enclave alloc " << b << std::endl; + + host_free(a); + enclave_free(b); +} From 67fbcba65384e4ab3a78e3a50f6c5780fc154f04 Mon Sep 17 00:00:00 2001 From: Matthew Parkinson Date: Thu, 24 Jan 2019 11:22:44 +0000 Subject: [PATCH 6/6] Clang format --- src/override/malloc.cc | 4 ++-- src/test/perf/external_pointer/externalpointer.cc | 1 - 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/override/malloc.cc b/src/override/malloc.cc index 5814b04f..48afc9d8 100644 --- a/src/override/malloc.cc +++ b/src/override/malloc.cc @@ -201,7 +201,7 @@ extern "C" return ENOENT; } -#if !defined(__PIC__) && !defined(NO_BOOTSTRAP_ALLOCATOR) +#if !defined(__PIC__) && !defined(NO_BOOTSTRAP_ALLOCATOR) // The following functions are required to work before TLS is set up, in // statically-linked programs. These temporarily grab an allocator from the // pool and return it. @@ -224,7 +224,7 @@ extern "C" sz = ((sz - 1) >> (bits::BITS - 1)) + sz; return get_slow_allocator()->alloc(sz); } - + void __je_bootstrap_free(void* ptr) { get_slow_allocator()->dealloc(ptr); diff --git a/src/test/perf/external_pointer/externalpointer.cc b/src/test/perf/external_pointer/externalpointer.cc index 453ccf48..20c96768 100644 --- a/src/test/perf/external_pointer/externalpointer.cc +++ b/src/test/perf/external_pointer/externalpointer.cc @@ -12,7 +12,6 @@ namespace test // Pre allocate all the objects size_t* objects[count]; - NOINLINE void setup(xoroshiro::p128r64& r, Alloc* alloc) { for (size_t i = 0; i < count; i++)