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;
}
Example #3
0
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;
	}
}