void FMacMallocCrashHandler::Free( void* Ptr ) { if ( IsOnCrashedThread() && Ptr && MemoryZone->size( MemoryZone, Ptr ) > 0 ) { FMacMallocZone::Free( Ptr ); } }
void FGenericPlatformMallocCrash::Free( void* Ptr ) { if( IsOnCrashedThread() ) { if( IsPtrInSmallPool(Ptr) ) { FMallocCrashPool* Pool = FindPoolFromSize( GetAllocationSize(Ptr) ); if( Pool ) { Pool->TryFreeFromPool( (uint8*)Ptr ); } else { FPlatformMisc::DebugBreak(); } } else if( IsPtrInLargePool(Ptr) ) { // Not implemented yet. } else { // From the previous allocator. } } }
void* FGenericPlatformMallocCrash::Realloc( void* Ptr, SIZE_T NewSize, uint32 Alignment ) { if( IsOnCrashedThread() ) { void* Result = nullptr; if( Ptr && NewSize ) { SIZE_T PtrSize = 0; const bool bPreviousMalloc = NewSize > 0 && Ptr && !(IsPtrInLargePool(Ptr)||IsPtrInSmallPool(Ptr)); if( bPreviousMalloc ) { // At this moment, we can safely get allocation size only from the binned malloc, this may change in future. if( FCStringWide::Strcmp( PreviousMalloc->GetDescriptiveName(), TEXT("binned") ) == 0 ) { // Realloc from the previous allocator. PreviousMalloc->GetAllocationSize(Ptr,PtrSize); if( PtrSize == 0 ) { PtrSize = 0; } } // There is nothing we can do about it. else { FPlatformMisc::LowLevelOutputDebugString( TEXT( "Realloc from previous malloc, exiting...\n" ) ); FPlatformMisc::RequestExit( true ); } } else { PtrSize = GetAllocationSize(Ptr); } Result = Malloc( NewSize, REQUIRED_ALIGNMENT ); FMemory::Memcpy( Result, Ptr, FMath::Min(NewSize,PtrSize) ); if( PtrSize > 32768 ) { FPlatformMisc::LowLevelOutputDebugStringf( TEXT( "Realloc PtrSize=%u NewSize=%u PooledPtr=0x%016llx\n" ), (uint32)PtrSize, (uint32)NewSize, (uint64)Ptr ); } Free( Ptr ); } else if( Ptr == nullptr ) { Result = Malloc( NewSize, REQUIRED_ALIGNMENT ); } else { Free( Ptr ); Result = nullptr; } return Result; } return nullptr; }
bool FMacMallocCrashHandler::GetAllocationSize( void *Original, SIZE_T &SizeOut ) { SizeOut = 0; if ( IsOnCrashedThread() && Original ) { SizeOut = MemoryZone->size( MemoryZone, Original ); } return SizeOut > 0; }
void* FMacMallocCrashHandler::Malloc( SIZE_T Size, uint32 Alignment ) { void* Result = nullptr; if ( IsOnCrashedThread() ) { Result = FMacMallocZone::Malloc( Size, Alignment ); if( !Result ) { check(CrashContext); CrashContext->GenerateCrashInfoAndLaunchReporter(); } } return Result; }
void* FGenericPlatformMallocCrash::Malloc( SIZE_T Size, uint32 Alignment ) { const uint32 Size32 = (uint32)Size; if( Alignment > 16 ) { FPlatformMisc::DebugBreak(); FPlatformMisc::LowLevelOutputDebugString( TEXT( "Alignment > 16 is not supported\n" ) ); } if( IsOnCrashedThread() ) { FMallocCrashPool* Pool = FindPoolFromSize( Size32 ); if( Pool ) { const uint8* PooledPtr = Pool->AllocateFromPool( Size32 ); return (void*)PooledPtr; } else { const uint32 SizeWithOverhead = Size32 + PER_ALLOC_OVERHEAD; LargeMemoryPoolOffset = Align( LargeMemoryPoolOffset, REQUIRED_ALIGNMENT ); if( LargeMemoryPoolOffset + SizeWithOverhead <= LARGE_MEMORYPOOL_SIZE ) { const uint32 ReturnMemoryPoolOffset = LargeMemoryPoolOffset; LargeMemoryPoolOffset += SizeWithOverhead; FPtrInfo* PtrInfo = (FPtrInfo*)(LargeMemoryPool+ReturnMemoryPoolOffset); PtrInfo->Size = Size32; PtrInfo->Ptr = LargeMemoryPool+ReturnMemoryPoolOffset+PER_ALLOC_OVERHEAD; FPlatformMisc::LowLevelOutputDebugStringf( TEXT( "Malloc Size=%u LargeMemoryPoolOffset=%u \n" ), Size32, LargeMemoryPoolOffset ); return (void*)PtrInfo->Ptr; } else { FPlatformMisc::DebugBreak(); FPlatformMisc::LowLevelOutputDebugStringf( TEXT( "MallocCrash run out of memory allocating %u bytes, free %u bytes\n" ), Size32, LARGE_MEMORYPOOL_SIZE-LargeMemoryPoolOffset ); FPlatformMisc::LowLevelOutputDebugString( TEXT( "Please increase LARGE_MEMORYPOOL_SIZE, exiting...\n" ) ); FPlatformMisc::RequestExit( true ); } } } return nullptr; }
void* FMacMallocCrashHandler::Realloc( void* Ptr, SIZE_T NewSize, uint32 Alignment ) { void* Result = nullptr; if ( IsOnCrashedThread() ) { if ( Ptr == nullptr || MemoryZone->size( MemoryZone, Ptr ) > 0 ) { Result = FMacMallocZone::Realloc( Ptr, NewSize, Alignment ); if( NewSize && !Result ) { check(CrashContext); CrashContext->GenerateCrashInfoAndLaunchReporter(); } } else if ( NewSize ) { if ( FCStringWide::Strcmp( OriginalHeap->GetDescriptiveName(), TEXT("ANSI") ) != 0 ) { SIZE_T OldSize = 0; if ( OriginalHeap->GetAllocationSize( Ptr, OldSize ) ) { Result = Malloc( NewSize, Alignment ); if ( Result ) { FMemory::Memcpy( Result, Ptr, FMath::Min( NewSize, OldSize ) ); } else { check(CrashContext); CrashContext->GenerateCrashInfoAndLaunchReporter(); } } } else // Can't safely handle this, so just report & exit { check(CrashContext); CrashContext->GenerateCrashInfoAndLaunchReporter(); } } } return Result; }