5#include "HAL/MemoryBase.h"
6#include "HAL/PlatformTLS.h"
8#ifndef WITH_MALLOC_STOMP2
9#define WITH_MALLOC_STOMP2 0
14
15
16
19 #include "Microsoft/WindowsHWrapper.h"
23
24
25
26
27
28class FMallocStomp2 final :
public FMalloc
31 FORCEINLINE SIZE_T GetAlignedSize(SIZE_T InSize, SIZE_T InAlignment)
33 return (((InSize)+(InAlignment - 1)) & ~(InAlignment - 1));
39 static constexpr SIZE_T SentinelExpectedValue = 0xdeadbeefdeadbeef;
42 static constexpr SIZE_T SentinelExpectedValue = 0xdeadbeef;
45 const SIZE_T PageSize;
47 struct FAllocationData
50 void *FullAllocationPointer;
60 struct FAddressSpaceStompDataBlockRangeEntry
70 struct FAddressSpaceStompDataBlock
72 static constexpr SIZE_T VirtualAddressSpaceToReserve = 1024LL * 1024LL * 1024LL * 64LL;
73 std::atomic<UPTRINT> CurrentAddress;
80 SIZE_T SizeToTryAndReserve = VirtualAddressSpaceToReserve;
82 while (SizeToTryAndReserve >= 1024LL * 1024LL * 1024LL)
84 StartAddress = (UPTRINT) ::VirtualAlloc(
nullptr, SizeToTryAndReserve, MEM_RESERVE, PAGE_READWRITE);
87 EndAddress = StartAddress + SizeToTryAndReserve;
88 Size = SizeToTryAndReserve;
89 CurrentAddress = StartAddress;
92 SizeToTryAndReserve /= 2;
97 void* Malloc(SIZE_T InSizeToAllocate, SIZE_T InPageSize,
bool InUnderrun =
false)
99 UPTRINT Ret = CurrentAddress.fetch_add(InSizeToAllocate);
100 if (Ret + InSizeToAllocate > EndAddress)
107 Ret = (UPTRINT) ::VirtualAlloc((
void*)Ret, InSizeToAllocate - InPageSize, MEM_COMMIT, PAGE_READWRITE);
112 Ret = (UPTRINT) ::VirtualAlloc((
void*)(Ret+InPageSize), InSizeToAllocate, MEM_COMMIT, PAGE_READWRITE);
117 void Free(
void* InPtr, SIZE_T InSize)
119#if PLATFORM_WINDOWS && USING_CODE_ANALYSIS
120 MSVC_PRAGMA(warning(push))
121 MSVC_PRAGMA(warning(disable : 6250))
124 ::VirtualFree(InPtr, InSize, MEM_DECOMMIT);
126#if PLATFORM_WINDOWS && USING_CODE_ANALYSIS
127 MSVC_PRAGMA(warning(pop))
134 static constexpr SIZE_T TargetAddressSpaceToReserve = 1024LL * 1024LL * 1024LL * 1024LL * 32LL;
137 static constexpr SIZE_T MaxAddressSpaceStompDataBlocks = 4096;
139 std::atomic<int64> CurrentAddressSpaceStompDataBlockIndex;
140 FAddressSpaceStompDataBlock AddressSpaceStompDataBlocks[MaxAddressSpaceStompDataBlocks];
142 int NumberOfRangeEntries;
143 FAddressSpaceStompDataBlockRangeEntry AddressSpaceStompDataBlocksRangeEntries[MaxAddressSpaceStompDataBlocks];
147 int IsPartOf(
void* InPtr);
148 int FindAddressSpaceStompDataBlockIndex(
void* InPtr,
int Index);
152 const bool bUseUnderrunMode;
157 FMallocStomp2(FMalloc* InMalloc,
const bool InUseUnderrunMode =
false);
160
161
162
163
164
165
166
167
168
169
170 virtual void* Malloc(SIZE_T Size, uint32 Alignment) override;
172 virtual void* TryMalloc(SIZE_T Size, uint32 Alignment) override;
175
176
177
178
179
180
181
182
183 virtual void* Realloc(
void* InPtr, SIZE_T NewSize, uint32 Alignment) override;
185 virtual void* TryRealloc(
void* InPtr, SIZE_T NewSize, uint32 Alignment) override;
188
189
190
191
192 virtual void Free(
void* InPtr) override;
195
196
197
198
199
200
201
202
203 virtual bool GetAllocationSize(
void *Original, SIZE_T &SizeOut) override;
206
207
208
209
210 virtual void DumpAllocatorStats( FOutputDevice& Ar ) override
216
217
218 virtual bool ValidateHeap() override
225 virtual const TCHAR* GetDescriptiveName() override
227 return TEXT(
"Stomp2" );
230 virtual bool IsInternallyThreadSafe()
const override
236 static FMalloc* OverrideIfEnabled(FMalloc* InUsedAlloc);
241 static uint32 DisableTlsSlot;
245 static SIZE_T MinSize;
247 static SIZE_T MaxSize;
252
253
254
255
256
257class FScopeDisableMallocStomp2
262
263
264 FScopeDisableMallocStomp2()
266 uint64 DisableCounter = (uint64)FPlatformTLS::GetTlsValue(FMallocStomp2::DisableTlsSlot);
268 FPlatformTLS::SetTlsValue(FMallocStomp2::DisableTlsSlot, (
void*)DisableCounter);
272 ~FScopeDisableMallocStomp2()
274 uint64 DisableCounter = (uint64)FPlatformTLS::GetTlsValue(FMallocStomp2::DisableTlsSlot);
276 FPlatformTLS::SetTlsValue(FMallocStomp2::DisableTlsSlot, (
void*)DisableCounter);
280extern FMallocStomp2* GMallocStomp2;
281extern bool GMallocStomp2Enabled;
#define WITH_MALLOC_STOMP2