void FStatsMallocProfilerProxy::TrackAlloc( void* Ptr, int64 Size, int32 SequenceTag ) { if( bEnabled ) { FThreadStats* ThreadStats = FThreadStats::GetThreadStats(); #ifdef DEBUG_MALLOC_PROXY if (GThreadStatsToDumpMemory == ThreadStats && ThreadStats->MemoryMessageScope == 0) { ThreadStats->MemoryMessageScope++; UE_LOG( LogStats, Warning, TEXT( "TrackAlloc, %llu, %lli, %i, %i" ), (uint64)(UPTRINT)Ptr, Size, SequenceTag, ThreadStats->MemoryMessageScope ); ThreadStats->MemoryMessageScope--; } #endif // DEBUG_MALLOC_PROXY if (ThreadStats->MemoryMessageScope == 0) { #if UE_BUILD_DEBUG if (ThreadStats->Packet.StatMessages.Num() > 0 && ThreadStats->Packet.StatMessages.Num() % 32767 == 0) { ThreadStats->MemoryMessageScope++; const double InvMB = 1.0f / 1024.0f / 1024.0f; UE_LOG( LogStats, Verbose, TEXT( "ThreadID: %i, Current: %.1f" ), FPlatformTLS::GetCurrentThreadId(), InvMB*(int64)ThreadStats->Packet.StatMessages.Num()*sizeof( FStatMessage ) ); ThreadStats->MemoryMessageScope--; } #endif // UE_BUILD_DEBUG // 48 bytes per allocation. ThreadStats->AddMemoryMessage( GET_STATFNAME( STAT_Memory_AllocPtr ), (uint64)(UPTRINT)Ptr | (uint64)EMemoryOperation::Alloc ); ThreadStats->AddMemoryMessage( GET_STATFNAME( STAT_Memory_AllocSize ), Size ); ThreadStats->AddMemoryMessage( GET_STATFNAME( STAT_Memory_OperationSequenceTag ), (int64)SequenceTag ); AllocPtrCalls.Increment(); } } }
void FStatsMallocProfilerProxy::TrackFree( void* Ptr, int32 SequenceTag ) { if( bEnabled ) { if( Ptr != nullptr ) { FThreadStats* ThreadStats = FThreadStats::GetThreadStats(); #ifdef DEBUG_MALLOC_PROXY if( GThreadStatsToDumpMemory == ThreadStats && ThreadStats->MemoryMessageScope == 0 ) { ThreadStats->MemoryMessageScope++; UE_LOG(LogStats, Warning, TEXT("TrackFree, %llu, 0, %i, %i"), (uint64)(UPTRINT)Ptr, SequenceTag, ThreadStats->MemoryMessageScope); ThreadStats->MemoryMessageScope--; } #endif // DEBUG_MALLOC_PROXY if( ThreadStats->MemoryMessageScope == 0 ) { // 32 bytes per free. ThreadStats->AddMemoryMessage( GET_STATFNAME(STAT_Memory_FreePtr), (uint64)(UPTRINT)Ptr | (uint64)EMemoryOperation::Free ); // 16 bytes total ThreadStats->AddMemoryMessage( GET_STATFNAME(STAT_Memory_OperationSequenceTag), (int64)SequenceTag ); FreePtrCalls.Increment(); } } } }
void FStatsMallocProfilerProxy::TrackRealloc( void* OldPtr, void* NewPtr, int64 NewSize, int32 SequenceTag ) { if (bEnabled) { if (OldPtr != nullptr && NewSize > 0) { FThreadStats* ThreadStats = FThreadStats::GetThreadStats(); if (ThreadStats->MemoryMessageScope == 0) { // 64 bytes per reallocation. 80 for Free/Alloc ThreadStats->AddMemoryMessage( GET_STATFNAME( STAT_Memory_FreePtr ), (uint64)(UPTRINT)OldPtr | (uint64)EMemoryOperation::Realloc ); ThreadStats->AddMemoryMessage( GET_STATFNAME( STAT_Memory_AllocPtr ), (uint64)(UPTRINT)NewPtr | (uint64)EMemoryOperation::Realloc ); ThreadStats->AddMemoryMessage( GET_STATFNAME( STAT_Memory_AllocSize ), NewSize ); ThreadStats->AddMemoryMessage( GET_STATFNAME( STAT_Memory_OperationSequenceTag ), (int64)SequenceTag ); ReallocPtrCalls.Increment(); } } else if (OldPtr == nullptr) { #if !PLATFORM_XBOXONE TrackAlloc( NewPtr, NewSize, SequenceTag ); #endif } else { TrackFree( OldPtr, SequenceTag ); } } }
void FMalloc::InitializeStatsMetadata() { // Initialize stats metadata here instead of UpdateStats. // Mostly to avoid dead-lock when stats malloc profiler is enabled. GET_STATFNAME(STAT_MallocCalls); GET_STATFNAME(STAT_ReallocCalls); GET_STATFNAME(STAT_FreeCalls); GET_STATFNAME(STAT_TotalAllocatorCalls); }
void FStatsMallocProfilerProxy::InitializeStatsMetadata() { UsedMalloc->InitializeStatsMetadata(); // Initialize the memory messages metadata. // Malloc profiler proxy needs to be disabled otherwise it will hit infinite recursion in DoSetup. // Needs to be changed if we want to support boot time memory profiling. const FName NameAllocPtr = GET_STATFNAME(STAT_Memory_AllocPtr); const FName NameReallocPtr = GET_STATFNAME(STAT_Memory_ReallocPtr); const FName NameFreePtr = GET_STATFNAME(STAT_Memory_FreePtr); const FName NameAllocSize = GET_STATFNAME(STAT_Memory_AllocSize); const FName NameOperationSequenceTag = GET_STATFNAME(STAT_Memory_OperationSequenceTag); GET_STATFNAME(STAT_Memory_AllocPtr_Calls); GET_STATFNAME(STAT_Memory_ReallocPtr_Calls); GET_STATFNAME(STAT_Memory_FreePtr_Calls); GET_STATFNAME(STAT_Memory_AllocPtr_Mem); GET_STATFNAME(STAT_Memory_FreePtr_Mem); }