diff --git a/src/ds/defines.h b/src/ds/defines.h index 69b9106..10bba45 100644 --- a/src/ds/defines.h +++ b/src/ds/defines.h @@ -3,6 +3,7 @@ #if defined(_MSC_VER) && !defined(__clang__) // 28 is FAST_FAIL_INVALID_BUFFER_ACCESS. Not using the symbolic constant to // avoid depending on winnt.h +# include // for __fastfail # define SNMALLOC_FAST_FAIL() __fastfail(28) # define ALWAYSINLINE __forceinline # define NOINLINE __declspec(noinline) @@ -141,32 +142,42 @@ namespace snmalloc # endif #endif -inline SNMALLOC_FAST_PATH void check_client_error(const char* const str) -{ - //[[clang::musttail]] - return snmalloc::error(str); -} - -inline SNMALLOC_FAST_PATH void -check_client_impl(bool test, const char* const str) -{ - if (SNMALLOC_UNLIKELY(!test)) - check_client_error(str); -} -#ifdef SNMALLOC_CHECK_CLIENT -# define check_client(test, str) check_client_impl(test, str) -#else -# define check_client(test, str) -#endif - namespace snmalloc { + template + SNMALLOC_FAST_PATH_INLINE void UNUSED(Args&&...) + {} + + inline SNMALLOC_FAST_PATH void check_client_error(const char* const str) + { + //[[clang::musttail]] + return snmalloc::error(str); + } + + inline SNMALLOC_FAST_PATH void + check_client_impl(bool test, const char* const str) + { + if (SNMALLOC_UNLIKELY(!test)) + { +#ifdef NDEBUG + UNUSED(str); + SNMALLOC_FAST_FAIL(); +#else + check_client_error(str); +#endif + } + } + #ifdef SNMALLOC_CHECK_CLIENT static constexpr bool CHECK_CLIENT = true; #else static constexpr bool CHECK_CLIENT = false; #endif - template - SNMALLOC_FAST_PATH_INLINE void UNUSED(Args&&...) - {} } // namespace snmalloc + +#ifdef SNMALLOC_CHECK_CLIENT +# define snmalloc_check_client(test, str) \ + snmalloc::check_client_impl(test, str) +#else +# define snmalloc_check_client(test, str) +#endif diff --git a/src/mem/corealloc.h b/src/mem/corealloc.h index ca9937e..89adfc8 100644 --- a/src/mem/corealloc.h +++ b/src/mem/corealloc.h @@ -379,7 +379,7 @@ namespace snmalloc alloc_classes[sizeclass].unused--; // TODO delay the clear to the next user of the slab, or teardown so - // don't touch the cache lines at this point in check_client. + // don't touch the cache lines at this point in snmalloc_check_client. auto chunk_record = clear_slab(meta, sizeclass); ChunkAllocator::dealloc( get_backend_local_state(), @@ -664,7 +664,7 @@ namespace snmalloc SNMALLOC_ASSERT(!meta->is_unused()); - check_client( + snmalloc_check_client( Metaslab::is_start_of_object( entry.get_sizeclass().as_small(), address_cast(p)), "Not deallocating start of an object"); diff --git a/src/mem/freelist.h b/src/mem/freelist.h index 4640534..d2e5a18 100644 --- a/src/mem/freelist.h +++ b/src/mem/freelist.h @@ -181,7 +181,7 @@ namespace snmalloc void check_prev(address_t signed_prev) { UNUSED(signed_prev); - check_client( + snmalloc_check_client( signed_prev == this->prev_encoded, "Heap corruption - free list corrupted!"); } diff --git a/src/mem/localalloc.h b/src/mem/localalloc.h index 4568f28..b243290 100644 --- a/src/mem/localalloc.h +++ b/src/mem/localalloc.h @@ -523,7 +523,7 @@ namespace snmalloc metaentry_chunk_sizeclass_to_slab_sizeclass(entry_sizeclass); // Check for start of allocation. - check_client( + snmalloc_check_client( pointer_align_down(p_tame, size) == p_tame, "Not start of an allocation."); @@ -560,7 +560,7 @@ namespace snmalloc // If p_tame is not null, then dealloc has been call on something // it shouldn't be called on. // TODO: Should this be tested even in the !CHECK_CLIENT case? - check_client(p_tame == nullptr, "Not allocated by snmalloc."); + snmalloc_check_client(p_tame == nullptr, "Not allocated by snmalloc."); # ifdef SNMALLOC_TRACING std::cout << "nullptr deallocation" << std::endl;