Removes recording of memory records through the MemoryDriller
Signed-off-by: Esteban Papp <81431996+amznestebanpapp@users.noreply.github.com>
This commit is contained in:
@@ -26,30 +26,25 @@ using namespace AZ::Debug;
|
||||
// AllocationRecords
|
||||
// [9/16/2009]
|
||||
//=========================================================================
|
||||
AllocationRecords::AllocationRecords(unsigned char stackRecordLevels, bool isMemoryGuard, bool isMarkUnallocatedMemory, const char* allocatorName)
|
||||
AllocationRecords::AllocationRecords(unsigned char stackRecordLevels, [[maybe_unused]] bool isMemoryGuard, bool isMarkUnallocatedMemory, const char* allocatorName)
|
||||
: m_mode(AllocatorManager::Instance().m_defaultTrackingRecordMode)
|
||||
, m_isAutoIntegrityCheck(false)
|
||||
, m_isMarkUnallocatedMemory(isMarkUnallocatedMemory)
|
||||
, m_saveNames(false)
|
||||
, m_decodeImmediately(false)
|
||||
, m_numStackLevels(stackRecordLevels)
|
||||
#if defined(ENABLE_MEMORY_GUARD)
|
||||
, m_memoryGuardSize(isMemoryGuard ? sizeof(Debug::GuardValue) : 0)
|
||||
#else
|
||||
, m_memoryGuardSize(0)
|
||||
#endif
|
||||
, m_requestedAllocs(0)
|
||||
, m_requestedBytes(0)
|
||||
, m_requestedBytesPeak(0)
|
||||
, m_allocatorName(allocatorName)
|
||||
{
|
||||
#if defined(ENABLE_MEMORY_GUARD)
|
||||
m_memoryGuardSize = isMemoryGuard ? sizeof(Debug::GuardValue) : 0;
|
||||
#else
|
||||
(void)isMemoryGuard;
|
||||
m_memoryGuardSize = 0;
|
||||
#endif
|
||||
#if AZ_TRAIT_OS_HAS_CRITICAL_SECTION_SPIN_COUNT
|
||||
SetCriticalSectionSpinCount(DrillerEBusMutex::GetMutex().native_handle(), 4000);
|
||||
#endif
|
||||
// preallocate some buckets
|
||||
//m_records.rehash(20000);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
//=========================================================================
|
||||
// ~AllocationRecords
|
||||
@@ -73,7 +68,7 @@ AllocationRecords::~AllocationRecords()
|
||||
void
|
||||
AllocationRecords::lock()
|
||||
{
|
||||
DrillerEBusMutex::GetMutex().lock();
|
||||
m_recordsMutex.lock();
|
||||
}
|
||||
|
||||
//=========================================================================
|
||||
@@ -82,7 +77,7 @@ AllocationRecords::lock()
|
||||
//=========================================================================
|
||||
bool AllocationRecords::try_lock()
|
||||
{
|
||||
return DrillerEBusMutex::GetMutex().try_lock();
|
||||
return m_recordsMutex.try_lock();
|
||||
}
|
||||
|
||||
//=========================================================================
|
||||
@@ -92,7 +87,7 @@ bool AllocationRecords::try_lock()
|
||||
void
|
||||
AllocationRecords::unlock()
|
||||
{
|
||||
DrillerEBusMutex::GetMutex().unlock();
|
||||
m_recordsMutex.unlock();
|
||||
}
|
||||
|
||||
//=========================================================================
|
||||
@@ -117,7 +112,7 @@ AllocationRecords::RegisterAllocation(void* address, size_t byteSize, size_t ali
|
||||
{
|
||||
if (m_isAutoIntegrityCheck)
|
||||
{
|
||||
IntegrityCheckNoLock();
|
||||
IntegrityCheck();
|
||||
}
|
||||
|
||||
AZ_Assert(byteSize>sizeof(Debug::GuardValue), "Did you forget to add the extra MemoryGuardSize() bytes?");
|
||||
@@ -125,7 +120,11 @@ AllocationRecords::RegisterAllocation(void* address, size_t byteSize, size_t ali
|
||||
new(reinterpret_cast<char*>(address)+byteSize) Debug::GuardValue();
|
||||
}
|
||||
|
||||
Debug::AllocationRecordsType::pair_iter_bool iterBool = m_records.insert_key(address);
|
||||
Debug::AllocationRecordsType::pair_iter_bool iterBool;
|
||||
{
|
||||
AZStd::scoped_lock lock(m_recordsMutex);
|
||||
iterBool = m_records.insert_key(address);
|
||||
}
|
||||
|
||||
if (!iterBool.second)
|
||||
{
|
||||
@@ -210,7 +209,15 @@ AllocationRecords::RegisterAllocation(void* address, size_t byteSize, size_t ali
|
||||
|
||||
// statistics
|
||||
m_requestedBytes += byteSize;
|
||||
m_requestedBytesPeak = AZStd::GetMax(m_requestedBytesPeak, m_requestedBytes);
|
||||
|
||||
size_t currentRequestedBytePeak;
|
||||
size_t newRequestedBytePeak;
|
||||
do
|
||||
{
|
||||
currentRequestedBytePeak = m_requestedBytesPeak.load(std::memory_order::memory_order_relaxed);
|
||||
newRequestedBytePeak = AZStd::GetMax(currentRequestedBytePeak, m_requestedBytes.load(std::memory_order::memory_order_relaxed));
|
||||
} while (!m_requestedBytesPeak.compare_exchange_weak(currentRequestedBytePeak, newRequestedBytePeak));
|
||||
|
||||
++m_requestedAllocs;
|
||||
|
||||
return &ai;
|
||||
@@ -220,8 +227,7 @@ AllocationRecords::RegisterAllocation(void* address, size_t byteSize, size_t ali
|
||||
// UnregisterAllocation
|
||||
// [9/11/2009]
|
||||
//=========================================================================
|
||||
void
|
||||
AllocationRecords::UnregisterAllocation(void* address, size_t byteSize, size_t alignment, AllocationInfo* info)
|
||||
void AllocationRecords::UnregisterAllocation(void* address, size_t byteSize, size_t alignment, AllocationInfo* info)
|
||||
{
|
||||
if (m_mode == RECORD_NO_RECORDS)
|
||||
{
|
||||
@@ -232,24 +238,39 @@ AllocationRecords::UnregisterAllocation(void* address, size_t byteSize, size_t a
|
||||
return;
|
||||
}
|
||||
|
||||
Debug::AllocationRecordsType::iterator iter = m_records.find(address);
|
||||
|
||||
// We cannot assert if an allocation does not exist because our allocators start up way before the driller is started and the Allocator Records would be created.
|
||||
// It is currently impossible to actually track all allocations that happen before a certain point
|
||||
//AZ_Assert(iter!=m_records.end(), "Could not find address 0x%p in the allocator!", address);
|
||||
if (iter == m_records.end())
|
||||
AllocationInfo allocationInfo;
|
||||
{
|
||||
return;
|
||||
AZStd::scoped_lock lock(m_recordsMutex);
|
||||
Debug::AllocationRecordsType::iterator iter = m_records.find(address);
|
||||
// We cannot assert if an allocation does not exist because our allocators start up way before the driller is started and the
|
||||
// Allocator Records would be created. It is currently impossible to actually track all allocations that happen before a certain
|
||||
// point
|
||||
// AZ_Assert(iter!=m_records.end(), "Could not find address 0x%p in the allocator!", address);
|
||||
if (iter == m_records.end())
|
||||
{
|
||||
return;
|
||||
}
|
||||
allocationInfo = iter->second;
|
||||
m_records.erase(iter);
|
||||
|
||||
// try to be more aggressive and keep the memory footprint low.
|
||||
// \todo store the load factor at the last rehash to avoid unnecessary rehash
|
||||
if (m_records.load_factor() < 0.9f)
|
||||
{
|
||||
m_records.rehash(0);
|
||||
}
|
||||
}
|
||||
AllocatorManager::Instance().DebugBreak(address, iter->second);
|
||||
|
||||
|
||||
AllocatorManager::Instance().DebugBreak(address, allocationInfo);
|
||||
|
||||
(void)byteSize;
|
||||
(void)alignment;
|
||||
AZ_Assert(byteSize==0||byteSize==iter->second.m_byteSize, "Mismatched byteSize at deallocation! You supplied an invalid value!");
|
||||
AZ_Assert(alignment==0||alignment==iter->second.m_alignment, "Mismatched alignment at deallocation! You supplied an invalid value!");
|
||||
AZ_Assert(byteSize==0||byteSize==allocationInfo.m_byteSize, "Mismatched byteSize at deallocation! You supplied an invalid value!");
|
||||
AZ_Assert(alignment==0||alignment==allocationInfo.m_alignment, "Mismatched alignment at deallocation! You supplied an invalid value!");
|
||||
|
||||
// statistics
|
||||
m_requestedBytes -= iter->second.m_byteSize;
|
||||
m_requestedBytes -= allocationInfo.m_byteSize;
|
||||
|
||||
#if defined(ENABLE_MEMORY_GUARD)
|
||||
// memory guard
|
||||
@@ -258,18 +279,18 @@ AllocationRecords::UnregisterAllocation(void* address, size_t byteSize, size_t a
|
||||
if (m_isAutoIntegrityCheck)
|
||||
{
|
||||
// full integrity check
|
||||
IntegrityCheckNoLock();
|
||||
IntegrityCheck();
|
||||
}
|
||||
else
|
||||
{
|
||||
// check current allocation
|
||||
char* guardAddress = reinterpret_cast<char*>(address)+iter->second.m_byteSize;
|
||||
char* guardAddress = reinterpret_cast<char*>(address)+allocationInfo.m_byteSize;
|
||||
Debug::GuardValue* guard = reinterpret_cast<Debug::GuardValue*>(guardAddress);
|
||||
if (!guard->Validate())
|
||||
{
|
||||
AZ_Printf("Memory", "Memory stomp located at address %p, part of allocation:", guardAddress);
|
||||
PrintAllocationsCB printAlloc(true);
|
||||
printAlloc(address, iter->second, m_numStackLevels);
|
||||
printAlloc(address, allocationInfo, m_numStackLevels);
|
||||
AZ_Assert(false, "MEMORY STOMP DETECTED!!!");
|
||||
}
|
||||
guard->~GuardValue();
|
||||
@@ -278,33 +299,26 @@ AllocationRecords::UnregisterAllocation(void* address, size_t byteSize, size_t a
|
||||
#endif
|
||||
|
||||
// delete allocation record
|
||||
if (iter->second.m_namesBlock)
|
||||
if (allocationInfo.m_namesBlock)
|
||||
{
|
||||
m_records.get_allocator().deallocate(iter->second.m_namesBlock, iter->second.m_namesBlockSize, 1);
|
||||
iter->second.m_namesBlock = nullptr;
|
||||
iter->second.m_namesBlockSize = 0;
|
||||
iter->second.m_name = nullptr;
|
||||
iter->second.m_fileName = nullptr;
|
||||
m_records.get_allocator().deallocate(allocationInfo.m_namesBlock, allocationInfo.m_namesBlockSize, 1);
|
||||
allocationInfo.m_namesBlock = nullptr;
|
||||
allocationInfo.m_namesBlockSize = 0;
|
||||
allocationInfo.m_name = nullptr;
|
||||
allocationInfo.m_fileName = nullptr;
|
||||
}
|
||||
if (iter->second.m_stackFrames)
|
||||
if (allocationInfo.m_stackFrames)
|
||||
{
|
||||
m_records.get_allocator().deallocate(iter->second.m_stackFrames, sizeof(AZ::Debug::StackFrame)*m_numStackLevels, 1);
|
||||
iter->second.m_stackFrames = nullptr;
|
||||
m_records.get_allocator().deallocate(allocationInfo.m_stackFrames, sizeof(AZ::Debug::StackFrame)*m_numStackLevels, 1);
|
||||
allocationInfo.m_stackFrames = nullptr;
|
||||
}
|
||||
|
||||
if (info)
|
||||
{
|
||||
*info = iter->second;
|
||||
*info = allocationInfo;
|
||||
}
|
||||
|
||||
m_records.erase(iter);
|
||||
|
||||
// try to be more aggressive and keep the memory footprint low.
|
||||
// \todo store the load factor at the last rehash to avoid unnecessary rehash
|
||||
if (m_records.load_factor()<0.9f)
|
||||
{
|
||||
m_records.rehash(0);
|
||||
}
|
||||
|
||||
// if requested set memory to a specific value.
|
||||
if (m_isMarkUnallocatedMemory)
|
||||
@@ -325,9 +339,14 @@ AllocationRecords::ResizeAllocation(void* address, size_t newSize)
|
||||
return;
|
||||
}
|
||||
|
||||
Debug::AllocationRecordsType::iterator iter = m_records.find(address);
|
||||
AZ_Assert(iter!=m_records.end(), "Could not find address 0x%p in the allocator!", address);
|
||||
AllocatorManager::Instance().DebugBreak(address, iter->second);
|
||||
AllocationInfo* allocationInfo;
|
||||
{
|
||||
AZStd::scoped_lock lock(m_recordsMutex);
|
||||
Debug::AllocationRecordsType::iterator iter = m_records.find(address);
|
||||
AZ_Assert(iter != m_records.end(), "Could not find address 0x%p in the allocator!", address);
|
||||
allocationInfo = &iter->second;
|
||||
}
|
||||
AllocatorManager::Instance().DebugBreak(address, *allocationInfo);
|
||||
|
||||
#if defined(ENABLE_MEMORY_GUARD)
|
||||
if (m_memoryGuardSize == sizeof(Debug::GuardValue))
|
||||
@@ -335,12 +354,12 @@ AllocationRecords::ResizeAllocation(void* address, size_t newSize)
|
||||
if (m_isAutoIntegrityCheck)
|
||||
{
|
||||
// full integrity check
|
||||
IntegrityCheckNoLock();
|
||||
IntegrityCheck();
|
||||
}
|
||||
else
|
||||
{
|
||||
// check memory guard
|
||||
char* guardAddress = reinterpret_cast<char*>(address)+iter->second.m_byteSize;
|
||||
char* guardAddress = reinterpret_cast<char*>(address) + allocationInfo->m_byteSize;
|
||||
Debug::GuardValue* guard = reinterpret_cast<Debug::GuardValue*>(guardAddress);
|
||||
if (!guard->Validate())
|
||||
{
|
||||
@@ -358,13 +377,19 @@ AllocationRecords::ResizeAllocation(void* address, size_t newSize)
|
||||
#endif
|
||||
|
||||
// statistics
|
||||
m_requestedBytes -= iter->second.m_byteSize;
|
||||
m_requestedBytes -= allocationInfo->m_byteSize;
|
||||
m_requestedBytes += newSize;
|
||||
m_requestedBytesPeak = AZStd::GetMax(m_requestedBytesPeak, m_requestedBytes);
|
||||
size_t currentRequestedBytePeak;
|
||||
size_t newRequestedBytePeak;
|
||||
do
|
||||
{
|
||||
currentRequestedBytePeak = m_requestedBytesPeak.load(std::memory_order::memory_order_relaxed);
|
||||
newRequestedBytePeak = AZStd::GetMax(currentRequestedBytePeak, m_requestedBytes.load(std::memory_order::memory_order_relaxed));
|
||||
} while (!m_requestedBytesPeak.compare_exchange_weak(currentRequestedBytePeak, newRequestedBytePeak));
|
||||
++m_requestedAllocs;
|
||||
|
||||
// update allocation size
|
||||
iter->second.m_byteSize = newSize;
|
||||
allocationInfo->m_byteSize = newSize;
|
||||
}
|
||||
|
||||
//=========================================================================
|
||||
@@ -374,21 +399,20 @@ AllocationRecords::ResizeAllocation(void* address, size_t newSize)
|
||||
void
|
||||
AllocationRecords::SetMode(Mode mode)
|
||||
{
|
||||
DrillerEBusMutex::GetMutex().lock();
|
||||
|
||||
if (mode==RECORD_NO_RECORDS)
|
||||
if (mode == RECORD_NO_RECORDS)
|
||||
{
|
||||
m_records.clear();
|
||||
{
|
||||
AZStd::scoped_lock lock(m_recordsMutex);
|
||||
m_records.clear();
|
||||
}
|
||||
m_requestedBytes = 0;
|
||||
m_requestedBytesPeak = 0;
|
||||
m_requestedAllocs = 0;
|
||||
}
|
||||
|
||||
AZ_Warning("Memory", m_mode!=RECORD_NO_RECORDS||mode==RECORD_NO_RECORDS, "Records recording was disabled and now it's enabled! You might get assert when you free memory, if a you have allocations which were not recorded!");
|
||||
AZ_Warning("Memory", m_mode != RECORD_NO_RECORDS || mode == RECORD_NO_RECORDS, "Records recording was disabled and now it's enabled! You might get assert when you free memory, if a you have allocations which were not recorded!");
|
||||
|
||||
m_mode = mode;
|
||||
|
||||
DrillerEBusMutex::GetMutex().unlock();
|
||||
}
|
||||
|
||||
//=========================================================================
|
||||
@@ -398,11 +422,14 @@ AllocationRecords::SetMode(Mode mode)
|
||||
void
|
||||
AllocationRecords::EnumerateAllocations(AllocationInfoCBType cb)
|
||||
{
|
||||
DrillerEBusMutex::GetMutex().lock();
|
||||
// enumerate all allocations and stop if requested.
|
||||
// Since allocations can change during the iteration (code that prints out the records could allocate, which will
|
||||
// mutate m_records), we are going to make a copy and iterate the copy.
|
||||
const Debug::AllocationRecordsType recordsCopy = m_records;
|
||||
Debug::AllocationRecordsType recordsCopy;
|
||||
{
|
||||
AZStd::scoped_lock lock(m_recordsMutex);
|
||||
recordsCopy = m_records;
|
||||
}
|
||||
for (Debug::AllocationRecordsType::const_iterator iter = recordsCopy.begin(); iter != recordsCopy.end(); ++iter)
|
||||
{
|
||||
if (!cb(iter->first, iter->second, m_numStackLevels))
|
||||
@@ -410,7 +437,6 @@ AllocationRecords::EnumerateAllocations(AllocationInfoCBType cb)
|
||||
break;
|
||||
}
|
||||
}
|
||||
DrillerEBusMutex::GetMutex().unlock();
|
||||
}
|
||||
|
||||
//=========================================================================
|
||||
@@ -420,38 +446,29 @@ AllocationRecords::EnumerateAllocations(AllocationInfoCBType cb)
|
||||
void
|
||||
AllocationRecords::IntegrityCheck() const
|
||||
{
|
||||
#if defined(ENABLE_MEMORY_GUARD)
|
||||
if (m_memoryGuardSize == sizeof(Debug::GuardValue))
|
||||
{
|
||||
DrillerEBusMutex::GetMutex().lock();
|
||||
|
||||
IntegrityCheckNoLock();
|
||||
|
||||
DrillerEBusMutex::GetMutex().unlock();
|
||||
}
|
||||
}
|
||||
|
||||
//=========================================================================
|
||||
// IntegrityCheckNoLock
|
||||
// [9/13/2011]
|
||||
//=========================================================================
|
||||
void
|
||||
AllocationRecords::IntegrityCheckNoLock() const
|
||||
{
|
||||
#if defined(ENABLE_MEMORY_GUARD)
|
||||
for (Debug::AllocationRecordsType::const_iterator iter = m_records.begin(); iter != m_records.end(); ++iter)
|
||||
{
|
||||
// check memory guard
|
||||
const char* guardAddress = reinterpret_cast<const char*>(iter->first)+ iter->second.m_byteSize;
|
||||
if (!reinterpret_cast<const Debug::GuardValue*>(guardAddress)->Validate())
|
||||
Debug::AllocationRecordsType recordsCopy;
|
||||
{
|
||||
// We have to turn off the integrity check at this point if we want to succesfully report the memory
|
||||
// stomp we just found. If we don't turn this off, the printf just winds off the stack as each memory
|
||||
// allocation done therein recurses this same code.
|
||||
*const_cast<bool*>(&m_isAutoIntegrityCheck) = false;
|
||||
AZ_Printf("Memory", "Memory stomp located at address %p, part of allocation:", guardAddress);
|
||||
PrintAllocationsCB printAlloc(true);
|
||||
printAlloc(iter->first, iter->second, m_numStackLevels);
|
||||
AZ_Error("Memory", false, "MEMORY STOMP DETECTED!!!");
|
||||
AZStd::scoped_lock lock(m_recordsMutex);
|
||||
recordsCopy = m_records;
|
||||
}
|
||||
for (Debug::AllocationRecordsType::const_iterator iter = recordsCopy.begin(); iter != recordsCopy.end(); ++iter)
|
||||
{
|
||||
// check memory guard
|
||||
const char* guardAddress = reinterpret_cast<const char*>(iter->first)+ iter->second.m_byteSize;
|
||||
if (!reinterpret_cast<const Debug::GuardValue*>(guardAddress)->Validate())
|
||||
{
|
||||
// We have to turn off the integrity check at this point if we want to succesfully report the memory
|
||||
// stomp we just found. If we don't turn this off, the printf just winds off the stack as each memory
|
||||
// allocation done therein recurses this same code.
|
||||
*const_cast<bool*>(&m_isAutoIntegrityCheck) = false;
|
||||
AZ_Printf("Memory", "Memory stomp located at address %p, part of allocation:", guardAddress);
|
||||
PrintAllocationsCB printAlloc(true);
|
||||
printAlloc(iter->first, iter->second, m_numStackLevels);
|
||||
AZ_Error("Memory", false, "MEMORY STOMP DETECTED!!!");
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -120,10 +120,9 @@ namespace AZ
|
||||
*/
|
||||
class AllocationRecords
|
||||
{
|
||||
friend class MemoryDriller;
|
||||
public:
|
||||
AZ_CLASS_ALLOCATOR(AllocationRecords, OSAllocator, 0);
|
||||
|
||||
public:
|
||||
enum Mode : int
|
||||
{
|
||||
RECORD_NO_RECORDS, ///< Never record any information.
|
||||
@@ -178,7 +177,7 @@ namespace AZ
|
||||
/// Returns peak of requested memory. IMPORTANT: This is user requested memory! Any allocator overhead is NOT included.
|
||||
size_t RequestedBytesPeak() const { return m_requestedBytesPeak; }
|
||||
/// Reset the peak allocation to the current requested memory.
|
||||
void ResetPeakBytes() { m_requestedBytesPeak = m_requestedBytes; }
|
||||
void ResetPeakBytes() { m_requestedBytesPeak.store(m_requestedBytes); }
|
||||
/// Return requested user bytes. IMPORTANT: This is user requested memory! Any allocator overhead is NOT included.
|
||||
size_t RequestedBytes() const { return m_requestedBytes; }
|
||||
/// Returns total number of requested allocations.
|
||||
@@ -186,8 +185,6 @@ namespace AZ
|
||||
|
||||
const char* GetAllocatorName() const { return m_allocatorName; }
|
||||
|
||||
protected:
|
||||
|
||||
// @{ Allocation tracking management - we assume this functions are called with the lock locked.
|
||||
const AllocationInfo* RegisterAllocation(void* address, size_t byteSize, size_t alignment, const char* name, const char* fileName, int lineNum, unsigned int stackSuppressCount);
|
||||
void UnregisterAllocation(void* address, size_t byteSize, size_t alignment, AllocationInfo* info);
|
||||
@@ -195,9 +192,9 @@ namespace AZ
|
||||
void ResizeAllocation(void* address, size_t newSize);
|
||||
// @}
|
||||
|
||||
void IntegrityCheckNoLock() const;
|
||||
|
||||
protected:
|
||||
Debug::AllocationRecordsType m_records;
|
||||
AZStd::spin_mutex m_recordsMutex;
|
||||
Mode m_mode;
|
||||
bool m_isAutoIntegrityCheck;
|
||||
bool m_isMarkUnallocatedMemory; ///< True if we want to set value 0xcd in unallocated memory.
|
||||
@@ -205,9 +202,9 @@ namespace AZ
|
||||
bool m_decodeImmediately;
|
||||
unsigned char m_numStackLevels;
|
||||
unsigned int m_memoryGuardSize;
|
||||
size_t m_requestedAllocs;
|
||||
size_t m_requestedBytes;
|
||||
size_t m_requestedBytesPeak;
|
||||
AZStd::atomic<size_t> m_requestedAllocs;
|
||||
AZStd::atomic<size_t> m_requestedBytes;
|
||||
AZStd::atomic<size_t> m_requestedBytesPeak;
|
||||
|
||||
const char* m_allocatorName;
|
||||
};
|
||||
|
||||
@@ -8,7 +8,6 @@
|
||||
|
||||
#include <AzCore/Memory/Memory.h>
|
||||
#include <AzCore/Memory/AllocatorManager.h>
|
||||
#include <AzCore/Memory/MemoryDrillerBus.h>
|
||||
|
||||
using namespace AZ;
|
||||
|
||||
@@ -77,6 +76,12 @@ void AllocatorBase::PostCreate()
|
||||
#if PLATFORM_MEMORY_INSTRUMENTATION_ENABLED
|
||||
m_platformMemoryInstrumentationGroupId = AZ::PlatformMemoryInstrumentation::GetNextGroupId();
|
||||
AZ::PlatformMemoryInstrumentation::RegisterGroup(m_platformMemoryInstrumentationGroupId, GetDescription(), AZ::PlatformMemoryInstrumentation::m_groupRoot);
|
||||
#else
|
||||
const auto debugConfig = GetDebugConfig();
|
||||
if (!debugConfig.m_excludeFromDebugging)
|
||||
{
|
||||
SetRecords(aznew Debug::AllocationRecords((unsigned char)debugConfig.m_stackRecordLevels, debugConfig.m_usesMemoryGuards, debugConfig.m_marksUnallocatedMemory, GetName()));
|
||||
}
|
||||
#endif
|
||||
|
||||
m_isReady = true;
|
||||
@@ -84,6 +89,15 @@ void AllocatorBase::PostCreate()
|
||||
|
||||
void AllocatorBase::PreDestroy()
|
||||
{
|
||||
#if !PLATFORM_MEMORY_INSTRUMENTATION_ENABLED
|
||||
Debug::AllocationRecords* allocatorRecords = GetRecords();
|
||||
if(allocatorRecords)
|
||||
{
|
||||
delete allocatorRecords;
|
||||
SetRecords(nullptr);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (m_registrationEnabled && AZ::AllocatorManager::IsReady())
|
||||
{
|
||||
AllocatorManager::Instance().UnRegisterAllocator(this);
|
||||
@@ -133,7 +147,11 @@ void AllocatorBase::ProfileAllocation(void* ptr, size_t byteSize, size_t alignme
|
||||
#if PLATFORM_MEMORY_INSTRUMENTATION_ENABLED
|
||||
AZ::PlatformMemoryInstrumentation::Alloc(ptr, byteSize, 0, m_platformMemoryInstrumentationGroupId);
|
||||
#else
|
||||
EBUS_EVENT(AZ::Debug::MemoryDrillerBus, RegisterAllocation, this, ptr, byteSize, alignment, name, fileName, lineNum, suppressStackRecord);
|
||||
auto records = GetRecords();
|
||||
if (records)
|
||||
{
|
||||
records->RegisterAllocation(ptr, byteSize, alignment, name, fileName, lineNum, suppressStackRecord + 1);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@@ -145,21 +163,21 @@ void AllocatorBase::ProfileDeallocation(void* ptr, size_t byteSize, size_t align
|
||||
#if PLATFORM_MEMORY_INSTRUMENTATION_ENABLED
|
||||
AZ::PlatformMemoryInstrumentation::Free(ptr);
|
||||
#else
|
||||
EBUS_EVENT(AZ::Debug::MemoryDrillerBus, UnregisterAllocation, this, ptr, byteSize, alignment, info);
|
||||
auto records = GetRecords();
|
||||
if (records)
|
||||
{
|
||||
records->UnregisterAllocation(ptr, byteSize, alignment, info);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void AllocatorBase::ProfileReallocationBegin(void* ptr, size_t newSize)
|
||||
void AllocatorBase::ProfileReallocationBegin([[maybe_unused]] void* ptr, [[maybe_unused]] size_t newSize)
|
||||
{
|
||||
if (m_isProfilingActive)
|
||||
{
|
||||
#if PLATFORM_MEMORY_INSTRUMENTATION_ENABLED
|
||||
AZ::PlatformMemoryInstrumentation::ReallocBegin(ptr, newSize, m_platformMemoryInstrumentationGroupId);
|
||||
#else
|
||||
// Driller API intensionally not called, only End is required.
|
||||
AZ_UNUSED(ptr);
|
||||
AZ_UNUSED(newSize);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@@ -171,7 +189,9 @@ void AllocatorBase::ProfileReallocationEnd(void* ptr, void* newPtr, size_t newSi
|
||||
#if PLATFORM_MEMORY_INSTRUMENTATION_ENABLED
|
||||
AZ::PlatformMemoryInstrumentation::ReallocEnd(newPtr, newSize, 0);
|
||||
#else
|
||||
EBUS_EVENT(AZ::Debug::MemoryDrillerBus, ReallocateAllocation, this, ptr, newPtr, newSize, newAlignment);
|
||||
Debug::AllocationInfo info;
|
||||
ProfileDeallocation(ptr, 0, 0, &info);
|
||||
ProfileAllocation(newPtr, newSize, newAlignment, info.m_name, info.m_fileName, info.m_lineNum, 0);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@@ -185,7 +205,13 @@ void AllocatorBase::ProfileResize(void* ptr, size_t newSize)
|
||||
{
|
||||
if (newSize && m_isProfilingActive)
|
||||
{
|
||||
EBUS_EVENT(AZ::Debug::MemoryDrillerBus, ResizeAllocation, this, ptr, newSize);
|
||||
#if !PLATFORM_MEMORY_INSTRUMENTATION_ENABLED
|
||||
auto records = GetRecords();
|
||||
if (records)
|
||||
{
|
||||
records->ResizeAllocation(ptr, newSize);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -14,7 +14,6 @@
|
||||
#include <AzCore/Memory/AllocationRecords.h>
|
||||
#include <AzCore/Memory/AllocatorOverrideShim.h>
|
||||
#include <AzCore/Memory/MallocSchema.h>
|
||||
#include <AzCore/Memory/MemoryDrillerBus.h>
|
||||
|
||||
#include <AzCore/std/parallel/lock.h>
|
||||
#include <AzCore/std/smart_ptr/make_shared.h>
|
||||
@@ -215,8 +214,6 @@ AllocatorManager::RegisterAllocator(class IAllocator* alloc)
|
||||
#ifdef AZCORE_MEMORY_ENABLE_OVERRIDES
|
||||
ConfigureAllocatorOverrides(alloc);
|
||||
#endif
|
||||
|
||||
EBUS_EVENT(Debug::MemoryDrillerBus, RegisterAllocator, alloc);
|
||||
}
|
||||
|
||||
//=========================================================================
|
||||
@@ -319,11 +316,6 @@ AllocatorManager::UnRegisterAllocator(class IAllocator* alloc)
|
||||
{
|
||||
AZStd::lock_guard<AZStd::mutex> lock(m_allocatorListMutex);
|
||||
|
||||
if (alloc->GetRecords())
|
||||
{
|
||||
EBUS_EVENT(Debug::MemoryDrillerBus, UnregisterAllocator, alloc);
|
||||
}
|
||||
|
||||
for (int i = 0; i < m_numAllocators; ++i)
|
||||
{
|
||||
if (m_allocators[i] == alloc)
|
||||
|
||||
@@ -402,16 +402,18 @@ namespace UnitTest
|
||||
AllocatorsFixture::SetUp();
|
||||
AZ::ComponentApplication::Descriptor desc;
|
||||
desc.m_useExistingAllocator = true;
|
||||
m_app.Create(desc);
|
||||
m_app.reset(aznew AZ::ComponentApplication);
|
||||
m_app->Create(desc);
|
||||
}
|
||||
|
||||
void TearDown() override
|
||||
{
|
||||
m_app.Destroy();
|
||||
m_app->Destroy();
|
||||
m_app.reset();
|
||||
AllocatorsFixture::TearDown();
|
||||
}
|
||||
|
||||
AZ::ComponentApplication m_app;
|
||||
AZStd::unique_ptr<AZ::ComponentApplication> m_app;
|
||||
};
|
||||
|
||||
TEST_F(MATH_TransformApplicationFixture, DeserializingOldFormat)
|
||||
|
||||
Reference in New Issue
Block a user