diff --git a/src/mem/largealloc.h b/src/mem/largealloc.h index 14cbd53..cb347c0 100644 --- a/src/mem/largealloc.h +++ b/src/mem/largealloc.h @@ -366,8 +366,7 @@ namespace snmalloc p = memory_provider.template reserve(large_class); if (p == nullptr) return nullptr; - memory_provider.template notify_using( - p, bits::align_up(size, OS_PAGE_SIZE)); + memory_provider.template notify_using(p, rsize); } else { @@ -390,8 +389,7 @@ namespace snmalloc // Passing zero_mem ensures the PAL provides zeroed pages if // required. memory_provider.template notify_using( - pointer_offset(p, OS_PAGE_SIZE), - bits::align_up(size, OS_PAGE_SIZE) - OS_PAGE_SIZE); + pointer_offset(p, OS_PAGE_SIZE), rsize - OS_PAGE_SIZE); } else { @@ -399,6 +397,8 @@ namespace snmalloc if constexpr (zero_mem == YesZero) memory_provider.template zero( p, bits::align_up(size, OS_PAGE_SIZE)); + else + UNUSED(size); } } diff --git a/src/mem/sizeclass.h b/src/mem/sizeclass.h index 76e774e..5b200d1 100644 --- a/src/mem/sizeclass.h +++ b/src/mem/sizeclass.h @@ -185,4 +185,13 @@ namespace snmalloc return ((alignment - 1) | (size - 1)) + 1; } + + SNMALLOC_FAST_PATH static size_t round_size(size_t size) + { + if (size > size_to_sizeclass(NUM_SIZECLASSES - 1)) + { + return bits::next_pow2(size); + } + return sizeclass_to_size(size_to_sizeclass(size)); + } } // namespace snmalloc diff --git a/src/override/malloc.cc b/src/override/malloc.cc index 61aaf5e..cb1a2f6 100644 --- a/src/override/malloc.cc +++ b/src/override/malloc.cc @@ -86,7 +86,7 @@ extern "C" #endif size_t sz = Alloc::alloc_size(ptr); // Keep the current allocation if the given size is in the same sizeclass. - if (sz == sizeclass_to_size(size_to_sizeclass(size))) + if (sz == round_size(size)) return ptr; void* p = SNMALLOC_NAME_MANGLE(malloc)(size); diff --git a/src/test/func/malloc/malloc.cc b/src/test/func/malloc/malloc.cc index 3ed01ed..d648d95 100644 --- a/src/test/func/malloc/malloc.cc +++ b/src/test/func/malloc/malloc.cc @@ -18,8 +18,13 @@ void check_result(size_t size, size_t align, void* p, int err, bool null) } else { - if (our_malloc_usable_size(p) < size) + auto asize = our_malloc_usable_size(p); + if (asize < size) + { + printf( + "Usable size is %zu, but required to be at least %zu.\n", asize, size); abort(); + } if (static_cast(reinterpret_cast(p) % align) != 0) abort(); @@ -30,7 +35,7 @@ void check_result(size_t size, size_t align, void* p, int err, bool null) void test_calloc(size_t nmemb, size_t size, int err, bool null) { - fprintf(stderr, "calloc(%d, %d)\n", (int)nmemb, (int)size); + fprintf(stderr, "calloc(%zu, %zu)\n", nmemb, size); errno = 0; void* p = our_calloc(nmemb, size); @@ -47,7 +52,11 @@ void test_calloc(size_t nmemb, size_t size, int err, bool null) void test_realloc(void* p, size_t size, int err, bool null) { - fprintf(stderr, "realloc(%p(%d), %d)\n", p, int(size), (int)size); + size_t old_size = 0; + if (p != nullptr) + old_size = our_malloc_usable_size(p); + + fprintf(stderr, "realloc(%p(%zu), %zu)\n", p, old_size, size); errno = 0; auto new_p = our_realloc(p, size); // Realloc failure case, deallocate original block @@ -58,7 +67,7 @@ void test_realloc(void* p, size_t size, int err, bool null) void test_posix_memalign(size_t size, size_t align, int err, bool null) { - fprintf(stderr, "posix_memalign(&p, %d, %d)\n", (int)align, (int)size); + fprintf(stderr, "posix_memalign(&p, %zu, %zu)\n", align, size); void* p = nullptr; errno = our_posix_memalign(&p, align, size); check_result(size, align, p, err, null); @@ -66,7 +75,7 @@ void test_posix_memalign(size_t size, size_t align, int err, bool null) void test_memalign(size_t size, size_t align, int err, bool null) { - fprintf(stderr, "memalign(%d, %d)\n", (int)align, (int)size); + fprintf(stderr, "memalign(%zu, %zu)\n", align, size); errno = 0; void* p = our_memalign(align, size); check_result(size, align, p, err, null); @@ -81,6 +90,16 @@ int main(int argc, char** argv) constexpr int SUCCESS = 0; + test_realloc(our_malloc(64), 4194304, SUCCESS, false); + + for (snmalloc::sizeclass_t sc = 0; sc < (SUPERSLAB_BITS + 4); sc++) + { + const size_t size = 1ULL << sc; + printf("malloc: %zu\n", size); + check_result(size, 1, our_malloc(size), SUCCESS, false); + check_result(size + 1, 1, our_malloc(size + 1), SUCCESS, false); + } + test_calloc(0, 0, SUCCESS, false); for (snmalloc::sizeclass_t sc = 0; sc < NUM_SIZECLASSES; sc++) @@ -97,11 +116,37 @@ int main(int argc, char** argv) test_calloc(n, 0, SUCCESS, false); } test_calloc(0, size, SUCCESS, false); + } + for (snmalloc::sizeclass_t sc = 0; sc < NUM_SIZECLASSES; sc++) + { + const size_t size = sizeclass_to_size(sc); test_realloc(our_malloc(size), size, SUCCESS, false); test_realloc(our_malloc(size), 0, SUCCESS, true); test_realloc(nullptr, size, SUCCESS, false); test_realloc(our_malloc(size), (size_t)-1, ENOMEM, true); + for (snmalloc::sizeclass_t sc2 = 0; sc2 < NUM_SIZECLASSES; sc2++) + { + const size_t size2 = sizeclass_to_size(sc2); + test_realloc(our_malloc(size), size2, SUCCESS, false); + test_realloc(our_malloc(size + 1), size2, SUCCESS, false); + } + } + + for (snmalloc::sizeclass_t sc = 0; sc < (SUPERSLAB_BITS + 4); sc++) + { + const size_t size = 1ULL << sc; + test_realloc(our_malloc(size), size, SUCCESS, false); + test_realloc(our_malloc(size), 0, SUCCESS, true); + test_realloc(nullptr, size, SUCCESS, false); + test_realloc(our_malloc(size), (size_t)-1, ENOMEM, true); + for (snmalloc::sizeclass_t sc2 = 0; sc2 < (SUPERSLAB_BITS + 4); sc2++) + { + const size_t size2 = 1ULL << sc2; + printf("size1: %zu, size2:%zu\n", size, size2); + test_realloc(our_malloc(size), size2, SUCCESS, false); + test_realloc(our_malloc(size + 1), size2, SUCCESS, false); + } } test_posix_memalign(0, 0, EINVAL, true); diff --git a/src/test/func/memory/memory.cc b/src/test/func/memory/memory.cc index 8a0d122..cecb5fe 100644 --- a/src/test/func/memory/memory.cc +++ b/src/test/func/memory/memory.cc @@ -221,7 +221,7 @@ void test_external_pointer_large() for (size_t i = 0; i < count; i++) { - size_t b = snmalloc::bits::is64() ? 28 : 26; + size_t b = SUPERSLAB_BITS + 3; size_t rand = r.next() & ((1 << b) - 1); size_t size = (1 << 24) + rand; total_size += size; diff --git a/src/test/func/sizeclass/sizeclass.cc b/src/test/func/sizeclass/sizeclass.cc index 757d3a6..7d6eaf8 100644 --- a/src/test/func/sizeclass/sizeclass.cc +++ b/src/test/func/sizeclass/sizeclass.cc @@ -18,7 +18,7 @@ void test_align_size() size < snmalloc::sizeclass_to_size(snmalloc::NUM_SIZECLASSES - 1); size++) { - size_t rsize = snmalloc::sizeclass_to_size(size_to_sizeclass(size)); + size_t rsize = snmalloc::round_size(size); if (rsize < size) {