Files
CosmicEngine/lib/All/JoltPhysics/TestFramework/Utils/CustomMemoryHook.cpp

140 lines
3.1 KiB
C++

// Jolt Physics Library (https://github.com/jrouwe/JoltPhysics)
// SPDX-FileCopyrightText: 2021 Jorrit Rouwe
// SPDX-License-Identifier: MIT
#include <TestFramework.h>
#include <Utils/CustomMemoryHook.h>
#ifdef JPH_CUSTOM_MEMORY_HOOK_ENABLED
// Global to turn checking on/off
static bool sEnableCustomMemoryHook = false;
// Local to temporarily disable checking
static thread_local int sDisableCustomMemoryHook = 1;
// Local to keep track if we're coming through the custom allocator
static thread_local bool sInCustomAllocator = false;
// Struct to put on the stack to flag that we're in the custom memory allocator
struct InCustomAllocator
{
InCustomAllocator()
{
JPH_ASSERT(!sInCustomAllocator);
sInCustomAllocator = true;
}
~InCustomAllocator()
{
JPH_ASSERT(sInCustomAllocator);
sInCustomAllocator = false;
}
};
// Add a tag to an allocation to track if it is aligned / unaligned
static void *TagAllocation(void *inPointer, size_t inAlignment, char inMode)
{
if (inPointer == nullptr)
return nullptr;
uint8 *p = reinterpret_cast<uint8 *>(inPointer);
*p = inMode;
return p + inAlignment;
}
// Remove tag from allocation
static void *UntagAllocation(void *inPointer, size_t inAlignment, char inMode)
{
if (inPointer == nullptr)
return nullptr;
uint8 *p = reinterpret_cast<uint8 *>(inPointer) - inAlignment;
JPH_ASSERT(*p == inMode);
*p = 0;
return p;
}
static void *AllocateHook(size_t inSize)
{
JPH_ASSERT(inSize > 0);
InCustomAllocator ica;
return TagAllocation(malloc(inSize + 16), 16, 'U');
}
static void *ReallocateHook(void *inBlock, size_t inOldSize, size_t inNewSize)
{
JPH_ASSERT(inNewSize > 0);
InCustomAllocator ica;
return TagAllocation(realloc(UntagAllocation(inBlock, 16, 'U'), inNewSize + 16), 16, 'U');
}
static void FreeHook(void *inBlock)
{
InCustomAllocator ica;
free(UntagAllocation(inBlock, 16, 'U'));
}
static void *AlignedAllocateHook(size_t inSize, size_t inAlignment)
{
JPH_ASSERT(inSize > 0 && inAlignment > 0 && inAlignment <= 64);
InCustomAllocator ica;
return TagAllocation(_aligned_malloc(inSize + 64, inAlignment), 64, 'A');
}
static void AlignedFreeHook(void *inBlock)
{
InCustomAllocator ica;
_aligned_free(UntagAllocation(inBlock, 64, 'A'));
}
static int MyAllocHook(int nAllocType, void *pvData, size_t nSize, int nBlockUse, long lRequest, const unsigned char * szFileName, int nLine) noexcept
{
JPH_ASSERT(!sEnableCustomMemoryHook || sDisableCustomMemoryHook <= 0 || sInCustomAllocator);
return true;
}
void RegisterCustomMemoryHook()
{
Allocate = AllocateHook;
Reallocate = ReallocateHook;
Free = FreeHook;
AlignedAllocate = AlignedAllocateHook;
AlignedFree = AlignedFreeHook;
_CrtSetAllocHook(MyAllocHook);
}
void EnableCustomMemoryHook(bool inEnable)
{
sEnableCustomMemoryHook = inEnable;
}
bool IsCustomMemoryHookEnabled()
{
return sEnableCustomMemoryHook;
}
DisableCustomMemoryHook::DisableCustomMemoryHook()
{
sDisableCustomMemoryHook--;
}
DisableCustomMemoryHook::~DisableCustomMemoryHook()
{
sDisableCustomMemoryHook++;
}
#else
DisableCustomMemoryHook::DisableCustomMemoryHook()
{
}
DisableCustomMemoryHook::~DisableCustomMemoryHook()
{
}
#endif // JPH_CUSTOM_MEMORY_HOOK_ENABLED