From 8390a70a48a63481259543311c59459fce7f526d Mon Sep 17 00:00:00 2001 From: Nathaniel Filardo Date: Mon, 19 Apr 2021 21:01:26 +0100 Subject: [PATCH] Fix static-sized alloc paths, add compilation test The CapPtr refactoring was largely compiler guided; unfortunately, it turns out that the static-sized alloc function is not well exercised. As such, some type errors and unnecessary unsafety lurked behind missing template instantiation. Correct those and add calls to the test harness to make sure we always generate at least one instance of each small/medium/large case. While here, it doesn't hurt to make sure that we call all three possible dealloc() flavors as well. This will, if nothing else, force instantiation of the static-sized dealloc template as well. --- src/mem/alloc.h | 6 ++--- src/test/func/memory/memory.cc | 40 ++++++++++++++++++++++++++++++++++ 2 files changed, 43 insertions(+), 3 deletions(-) diff --git a/src/mem/alloc.h b/src/mem/alloc.h index 77dbe5d..ee6ff63 100644 --- a/src/mem/alloc.h +++ b/src/mem/alloc.h @@ -139,18 +139,18 @@ namespace snmalloc if constexpr (sizeclass < NUM_SMALL_CLASSES) { - return small_alloc(size); + return capptr_reveal(small_alloc(size)); } else if constexpr (sizeclass < NUM_SIZECLASSES) { handle_message_queue(); constexpr size_t rsize = sizeclass_to_size(sizeclass); - return medium_alloc(sizeclass, rsize, size); + return capptr_reveal(medium_alloc(sizeclass, rsize, size)); } else { handle_message_queue(); - return large_alloc(size).unsafe_capptr; + return capptr_reveal(large_alloc(size)); } #endif } diff --git a/src/test/func/memory/memory.cc b/src/test/func/memory/memory.cc index 1f5cb92..cb8e0e7 100644 --- a/src/test/func/memory/memory.cc +++ b/src/test/func/memory/memory.cc @@ -381,6 +381,45 @@ void test_calloc_large_bug() alloc->dealloc(p1); } +template +void test_static_sized_alloc() +{ + auto alloc = ThreadAlloc::get(); + auto p = alloc->alloc(); + + static_assert((dealloc >= 0) && (dealloc <= 2), "bad dealloc flavor"); + switch (dealloc) + { + case 0: + alloc->dealloc(p); + break; + case 1: + alloc->dealloc(p, asz); + break; + case 2: + alloc->dealloc(p); + break; + } +} + +void test_static_sized_allocs() +{ + // For each small, medium, and large class, do each kind dealloc. This is + // mostly to ensure that all of these forms compile. + + test_static_sized_alloc(); + test_static_sized_alloc(); + test_static_sized_alloc(); + + test_static_sized_alloc(); + test_static_sized_alloc(); + test_static_sized_alloc(); + + test_static_sized_alloc(); + test_static_sized_alloc(); + test_static_sized_alloc(); +} + int main(int argc, char** argv) { setup(); @@ -412,6 +451,7 @@ int main(int argc, char** argv) test_calloc(); test_double_alloc(); #ifndef SNMALLOC_PASS_THROUGH // Depends on snmalloc specific features + test_static_sized_allocs(); test_calloc_large_bug(); test_external_pointer_dealloc_bug(); test_external_pointer_large();