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 ff::BufferCache::BorrowAndMapBuffer(size_t nBytes, ID3D11Buffer **ppBuffer, void **ppMapped) { assertRetVal(ppBuffer, false); size_t nBuffer = GetBufferIndex(nBytes); size_t nLargestBuffer = _countof(_buffers) - 1; // Try to reuse a cached buffer for (ComPtr<ID3D11Buffer> *pCur = _buffers[nBuffer].GetFirst(); pCur; pCur = _buffers[nBuffer].GetNext(*pCur)) { size_t nCurSize = GetBufferSize(*pCur); if (nCurSize >= nBytes) { if (ppMapped) { // Try to lock the buffer D3D11_MAPPED_SUBRESOURCE map; assertRetVal(SUCCEEDED(_device->GetContext()->Map(*pCur, 0, D3D11_MAP_WRITE_DISCARD, 0, &map)), false); *ppMapped = map.pData; } *ppBuffer = pCur->AddRef(); _buffers[nBuffer].Delete(*pCur); return true; } } // See if one of the large buffers should be thrown away // (to make room for a larger one) if (nBuffer == nLargestBuffer && _allocated[nLargestBuffer] >= GetMaxBufferCount() && _buffers[nLargestBuffer].Size()) { // Throw away one of the "large" buffers, it isn't large enough for (ComPtr<ID3D11Buffer> *pCur = _buffers[nLargestBuffer].GetFirst(); pCur; pCur = _buffers[nLargestBuffer].GetNext(*pCur)) { size_t nCurSize = GetBufferSize(*pCur); if (nCurSize < nBytes) { _buffers[nLargestBuffer].Delete(*pCur); _allocated[nLargestBuffer]--; break; } } } // Add a few empty buffers for later if (nBuffer != nLargestBuffer && !_allocated[nBuffer]) { for (size_t i = 0; i < GetMaxBufferCount() - 1; i++) { ComPtr<ID3D11Buffer> pBuffer; assertRetVal(CreateBuffer(GetAllocationSize(nBytes), &pBuffer), false); _buffers[nBuffer].Insert(pBuffer); _allocated[nBuffer]++; } } // Can't reuse an existing buffer, so create a new one { ComPtr<ID3D11Buffer> pBuffer; assertRetVal(CreateBuffer(GetAllocationSize(nBytes), &pBuffer), false); if (ppMapped) { D3D11_MAPPED_SUBRESOURCE map; assertRetVal(SUCCEEDED(_device->GetContext()->Map(pBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &map)), false); *ppMapped = map.pData; } *ppBuffer = pBuffer.Detach(); _allocated[nBuffer]++; return true; } }