From 0f70494d55af9af3cc44367a49d0d8e665bcd271 Mon Sep 17 00:00:00 2001 From: Matthew Parkinson Date: Thu, 26 Aug 2021 10:04:44 +0100 Subject: [PATCH] Enable passthrough to an underlying allocator This passes though to an underlying allocator rather than using snmalloc. This is required for using ASAN in Verona. Verona takes a close coupling with snmalloc, but to use with ASAN would require a more work, so we pass to the system allocator in this case. --- CMakeLists.txt | 2 +- src/mem/localalloc.h | 29 ++++++++++++++++++++++------- 2 files changed, 23 insertions(+), 8 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index ce9cbc7..c8b0d0d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -286,7 +286,7 @@ if(NOT DEFINED SNMALLOC_ONLY_HEADER_LIBRARY) # NetBSD, OpenBSD and DragonFlyBSD do not support malloc*size calls. set(FLAVOURS fast;check) else() - set(FLAVOURS fast;check) #malloc - TODO-need to add pass through back + set(FLAVOURS fast;check;malloc) endif() foreach(FLAVOUR ${FLAVOURS}) unset(SRC) diff --git a/src/mem/localalloc.h b/src/mem/localalloc.h index f4a576e..ae25905 100644 --- a/src/mem/localalloc.h +++ b/src/mem/localalloc.h @@ -14,6 +14,10 @@ #include "remotecache.h" #include "sizeclasstable.h" +#ifdef SNMALLOC_PASS_THROUGH +# include "external_alloc.h" +#endif + #ifdef SNMALLOC_TRACING # include #endif @@ -458,7 +462,9 @@ namespace snmalloc SNMALLOC_FAST_PATH void dealloc(void* p) { - // TODO Pass through code! +#ifdef SNMALLOC_PASS_THROUGH + external_alloc::free(p); +#else // TODO: // Care is needed so that dealloc(nullptr) works before init // The backend allocator must ensure that a minimal page map exists @@ -485,10 +491,10 @@ namespace snmalloc entry.get_remote()->trunc_id(), CapPtr(p), key_global); -#ifdef SNMALLOC_TRACING +# ifdef SNMALLOC_TRACING std::cout << "Remote dealloc fast" << p << " size " << alloc_size(p) << std::endl; -#endif +# endif return; } @@ -509,10 +515,10 @@ namespace snmalloc pointer_align_down(p, size) == p, "Not start of an allocation."); size_t slab_sizeclass = large_size_to_chunk_sizeclass(size); -#ifdef SNMALLOC_TRACING +# ifdef SNMALLOC_TRACING std::cout << "Large deallocation: " << size << " chunk sizeclass: " << slab_sizeclass << std::endl; -#endif +# endif ChunkRecord* slab_record = reinterpret_cast(entry.get_metaslab()); slab_record->chunk = CapPtr(p); @@ -524,10 +530,11 @@ namespace snmalloc return; } -#ifdef SNMALLOC_TRACING +# ifdef SNMALLOC_TRACING std::cout << "nullptr deallocation" << std::endl; -#endif +# endif return; +#endif } SNMALLOC_FAST_PATH void dealloc(void* p, size_t s) @@ -558,6 +565,9 @@ namespace snmalloc SNMALLOC_FAST_PATH size_t alloc_size(const void* p_raw) { +#ifdef SNMALLOC_PASS_THROUGH + return external_alloc::malloc_usable_size(const_cast(p_raw)); +#else // Note that this should return 0 for nullptr. // Other than nullptr, we know the system will be initialised as it must // be called with something we have already allocated. @@ -574,6 +584,7 @@ namespace snmalloc return bits::one_at_bit(entry.get_sizeclass()); return 0; +#endif } /** @@ -586,6 +597,7 @@ namespace snmalloc template void* external_pointer(void* p_raw) { +#ifndef SNMALLOC_PASS_THROUGH // TODO bring back the CHERI bits. Wes to review if required. if (likely(is_initialised())) { @@ -627,6 +639,9 @@ namespace snmalloc { // Allocator not initialised, so definitely not our allocation } +#else + UNUSED(p_raw); +#endif if constexpr ((location == End) || (location == OnePastEnd)) // We don't know the End, so return MAX_PTR