From f1be609cdbd564018d506a91f02ab26b3dd619af Mon Sep 17 00:00:00 2001 From: David Chisnall Date: Fri, 21 Jan 2022 14:19:26 +0000 Subject: [PATCH] Small fixes for snmalloc used in FreeBSD libc. (#454) - Mark the hook that we're exporting for the threading library to call to clean up per-thread malloc state as 'used'. It was changed to `inline` to allow duplicate copies of it to be merged but this also means that it isn't emitted at all in compilation units that don't use it (and it isn't used internally at all). - Fix the `__je_bootstrap_*` functions, which are used to bootstrap TLS allocation, for the changes to `ScopedAllocator`. The `__je_bootstrap*` functions weren't being built in CI. They now are for non-PIE targets with a smoke test. --- src/ds/defines.h | 2 ++ src/mem/threadalloc.h | 1 + src/override/malloc.cc | 6 +++--- src/test/func/malloc/malloc.cc | 9 +++++++++ 4 files changed, 15 insertions(+), 3 deletions(-) diff --git a/src/ds/defines.h b/src/ds/defines.h index 10bba45..b21b194 100644 --- a/src/ds/defines.h +++ b/src/ds/defines.h @@ -25,6 +25,7 @@ # define SNMALLOC_COLD # define SNMALLOC_REQUIRE_CONSTINIT # define SNMALLOC_UNUSED_FUNCTION +# define SNMALLOC_USED_FUNCTION #else # define SNMALLOC_FAST_FAIL() __builtin_trap() # define SNMALLOC_LIKELY(x) __builtin_expect(!!(x), 1) @@ -47,6 +48,7 @@ # define SNMALLOC_PURE __attribute__((const)) # define SNMALLOC_COLD __attribute__((cold)) # define SNMALLOC_UNUSED_FUNCTION __attribute((unused)) +# define SNMALLOC_USED_FUNCTION __attribute((used)) # ifdef __clang__ # define SNMALLOC_REQUIRE_CONSTINIT \ [[clang::require_constant_initialization]] diff --git a/src/mem/threadalloc.h b/src/mem/threadalloc.h index c7d23f1..1ab5892 100644 --- a/src/mem/threadalloc.h +++ b/src/mem/threadalloc.h @@ -169,6 +169,7 @@ namespace snmalloc * Entry point that allows libc to call into the allocator for per-thread * cleanup. */ +SNMALLOC_USED_FUNCTION inline void _malloc_thread_cleanup() { snmalloc::ThreadAlloc::get().teardown(); diff --git a/src/override/malloc.cc b/src/override/malloc.cc index f40b2d8..82b8eaf 100644 --- a/src/override/malloc.cc +++ b/src/override/malloc.cc @@ -238,7 +238,7 @@ extern "C" void* __je_bootstrap_malloc(size_t size) { - return get_scoped_allocator().alloc(size); + return get_scoped_allocator()->alloc(size); } void* __je_bootstrap_calloc(size_t nmemb, size_t size) @@ -252,12 +252,12 @@ extern "C" } // Include size 0 in the first sizeclass. sz = ((sz - 1) >> (bits::BITS - 1)) + sz; - return get_scoped_allocator().alloc(sz); + return get_scoped_allocator()->alloc(sz); } void __je_bootstrap_free(void* ptr) { - get_scoped_allocator().dealloc(ptr); + get_scoped_allocator()->dealloc(ptr); } #endif } diff --git a/src/test/func/malloc/malloc.cc b/src/test/func/malloc/malloc.cc index a672a25..6aa8ae9 100644 --- a/src/test/func/malloc/malloc.cc +++ b/src/test/func/malloc/malloc.cc @@ -4,6 +4,7 @@ #define SNMALLOC_NAME_MANGLE(a) our_##a #undef SNMALLOC_NO_REALLOCARRAY #undef SNMALLOC_NO_REALLOCARR +#define SNMALLOC_BOOTSTRAP_ALLOCATOR #include "../../../override/malloc.cc" using namespace snmalloc; @@ -338,6 +339,14 @@ int main(int argc, char** argv) abort(); } +#ifndef __PIC__ snmalloc::debug_check_empty(); + void* bootstrap = __je_bootstrap_malloc(42); + if (bootstrap == nullptr) + { + printf("Failed to allocate from bootstrap malloc\n"); + } + __je_bootstrap_free(bootstrap); +#endif return 0; }