Improve codegen for checks.
Use fail fast in release to avoid stack frame for error reporting. Scope check_client macro.
This commit is contained in:
committed by
Matthew Parkinson
parent
a8ef963ed7
commit
c299826f58
@@ -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 <intrin.h> // 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<typename... Args>
|
||||
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<typename... Args>
|
||||
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
|
||||
|
||||
@@ -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<SharedStateHandle>(
|
||||
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");
|
||||
|
||||
@@ -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!");
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user