From 6e8edefc999c75927541e3a034c832617ef978a5 Mon Sep 17 00:00:00 2001 From: Matthew Parkinson Date: Tue, 28 Jan 2020 14:17:20 +0000 Subject: [PATCH] Make all large allocations naturally aligned This makes any large allocation naturally aligned to its size. This means all alignment requests can be handled without checks. --- README.md | 2 +- src/mem/largealloc.h | 55 ++-------------------------------- src/mem/sizeclass.h | 2 -- src/override/malloc.cc | 3 +- src/test/func/malloc/malloc.cc | 2 +- 5 files changed, 6 insertions(+), 58 deletions(-) diff --git a/README.md b/README.md index a3d6395..5566ab7 100644 --- a/README.md +++ b/README.md @@ -168,7 +168,7 @@ template void* reserve(const size_t* size) noexcept; ``` Only one of these needs to be implemented, depending on whether the underlying -system can provide strongly (e.g. 16MiB) aligned memory regions. +system can provide strongly aligned memory regions. If the system guarantees only page alignment, implement the second and snmalloc will over-allocate and then trim the requested region. If the system provides strong alignment, implement the first to return memory diff --git a/src/mem/largealloc.h b/src/mem/largealloc.h index 93c5cff..a5274fb 100644 --- a/src/mem/largealloc.h +++ b/src/mem/largealloc.h @@ -281,9 +281,6 @@ namespace snmalloc template class LargeAlloc { - void* reserved_start = nullptr; - void* reserved_end = nullptr; - public: // This will be a zero-size structure if stats are not enabled. Stats stats; @@ -292,38 +289,6 @@ namespace snmalloc LargeAlloc(MemoryProvider& mp) : memory_provider(mp) {} - template - bool reserve_memory(size_t need, size_t add) - { - assert(reserved_start <= reserved_end); - - /* - * Spell this comparison in terms of pointer subtraction like this, - * rather than "reserved_start + need < reserved_end" because the - * sum might not be representable on CHERI. - */ - if (pointer_diff(reserved_start, reserved_end) < need) - { - if constexpr (allow_reserve == YesReserve) - { - stats.segment_create(); - reserved_start = - memory_provider.template reserve(&add, SUPERSLAB_SIZE); - reserved_end = pointer_offset(reserved_start, add); - reserved_start = pointer_align_up(reserved_start); - - if (add < need) - return false; - } - else - { - return false; - } - } - - return true; - } - template void* alloc(size_t large_class, size_t size) { @@ -337,23 +302,9 @@ namespace snmalloc if (p == nullptr) { - assert(reserved_start <= reserved_end); - size_t add; - - if ((rsize + SUPERSLAB_SIZE) < RESERVE_SIZE) - add = RESERVE_SIZE; - else - add = rsize + SUPERSLAB_SIZE; - - if (!reserve_memory(rsize, add)) - return nullptr; - - p = reserved_start; - reserved_start = pointer_offset(p, rsize); - - stats.superslab_fresh(); - // All memory is zeroed since it comes from reserved space. - memory_provider.template notify_using(p, size); + size_t add = rsize; + p = memory_provider.template reserve(&add, rsize); + memory_provider.template notify_using(p, size); } else { diff --git a/src/mem/sizeclass.h b/src/mem/sizeclass.h index 825ebe0..a8b821b 100644 --- a/src/mem/sizeclass.h +++ b/src/mem/sizeclass.h @@ -179,8 +179,6 @@ namespace snmalloc { // Client responsible for checking alignment is not zero assert(alignment != 0); - // Client responsible for checking alignment is not above SUPERSLAB_SIZE - assert(alignment <= SUPERSLAB_SIZE); // Client responsible for checking alignment is a power of two assert(bits::next_pow2(alignment) == alignment); diff --git a/src/override/malloc.cc b/src/override/malloc.cc index 2248cbc..caa7706 100644 --- a/src/override/malloc.cc +++ b/src/override/malloc.cc @@ -108,8 +108,7 @@ extern "C" SNMALLOC_NAME_MANGLE(memalign)(size_t alignment, size_t size) { if ( - (alignment == 0) || (alignment == size_t(-1)) || - (alignment > SUPERSLAB_SIZE)) + (alignment == 0) || (alignment == size_t(-1))) { errno = EINVAL; return nullptr; diff --git a/src/test/func/malloc/malloc.cc b/src/test/func/malloc/malloc.cc index 446edf3..b0b5846 100644 --- a/src/test/func/malloc/malloc.cc +++ b/src/test/func/malloc/malloc.cc @@ -108,7 +108,7 @@ int main(int argc, char** argv) test_posix_memalign((size_t)-1, 0, EINVAL, true); test_posix_memalign(OS_PAGE_SIZE, sizeof(uintptr_t) / 2, EINVAL, true); - for (size_t align = sizeof(uintptr_t); align <= SUPERSLAB_SIZE; align <<= 1) + for (size_t align = sizeof(uintptr_t); align <= SUPERSLAB_SIZE * 8; align <<= 1) { for (snmalloc::sizeclass_t sc = 0; sc < NUM_SIZECLASSES; sc++) {