4#include "Containers/List.h"
6#include "HAL/Allocators/CachedOSPageAllocator.h"
7#include "HAL/CriticalSection.h"
8#include "HAL/PlatformMemory.h"
9#include "HAL/UnrealMemory.h"
12#ifndef UE_USE_VERYLARGEPAGEALLOCATOR_FALLBACKPATH
19#define CACHEDOSVERYLARGEPAGEALLOCATOR_BYTE_LIMIT (128
*1024
*1024
)
21#define CACHEDOSVERYLARGEPAGEALLOCATOR_BYTE_LIMIT (16
*1024
*1024
)
24#define CACHEDOSVERYLARGEPAGEALLOCATOR_MAX_CACHED_OS_FREES (256
)
27#ifndef UE_VERYLARGEPAGEALLOCATOR_TAKEONALL64KBALLOCATIONS
28#define UE_VERYLARGEPAGEALLOCATOR_TAKEONALL64KBALLOCATIONS 1
31#ifndef UE_VERYLARGEPAGEALLOCATOR_RESERVED_SIZE_IN_GB
32#define UE_VERYLARGEPAGEALLOCATOR_RESERVED_SIZE_IN_GB 2
36#ifndef UE_VERYLARGEPAGEALLOCATOR_PAGESIZE_KB
37#define UE_VERYLARGEPAGEALLOCATOR_PAGESIZE_KB 2048
39class FCachedOSVeryLargePageAllocator
42#if UE_VERYLARGEPAGEALLOCATOR_TAKEONALL64KBALLOCATIONS
43 static constexpr uint64 AddressSpaceToReserve = ((1024LL * 1024LL * 1024LL) * UE_VERYLARGEPAGEALLOCATOR_RESERVED_SIZE_IN_GB * 2LL);
44 static constexpr uint64 AddressSpaceToReserveForSmallPool = AddressSpaceToReserve / 2;
46 static constexpr uint64 AddressSpaceToReserve = ((1024 * 1024 * 1024LL) * UE_VERYLARGEPAGEALLOCATOR_RESERVED_SIZE_IN_GB);
47 static constexpr uint64 AddressSpaceToReserveForSmallPool = AddressSpaceToReserve;
49 static constexpr uint64 SizeOfLargePage = (UE_VERYLARGEPAGEALLOCATOR_PAGESIZE_KB * 1024);
50 static constexpr uint64 SizeOfSubPage = (1024 * 64);
51 static constexpr uint64 NumberOfLargePages = (AddressSpaceToReserve / SizeOfLargePage);
52 static constexpr uint64 NumberOfSubPagesPerLargePage = (SizeOfLargePage / SizeOfSubPage);
55 FCachedOSVeryLargePageAllocator()
62 ~FCachedOSVeryLargePageAllocator()
67 void* Allocate(SIZE_T Size, uint32 AllocationHint = 0, FCriticalSection* Mutex =
nullptr);
69 void Free(
void* Ptr, SIZE_T Size, FCriticalSection* Mutex =
nullptr,
bool ThreadIsTimeCritical =
false);
71 void FreeAll(FCriticalSection* Mutex =
nullptr);
78 uint64 GetCachedFreeTotal()
80 return CachedFree + CachedOSPageAllocator.GetCachedFreeTotal();
83 FORCEINLINE
bool IsPartOf(
const void* Ptr)
85 if (((uintptr_t)Ptr - AddressSpaceReserved) < AddressSpaceToReserveForSmallPool)
95 void ShrinkEmptyBackStore(int32 NewEmptyBackStoreSize, FMemory::AllocationHints AllocationHint);
98 uintptr_t AddressSpaceReserved;
99 uintptr_t AddressSpaceReservedEndSmallPool;
100 uintptr_t AddressSpaceReservedEnd;
102 int32 EmptyBackStoreCount[FMemory::AllocationHints::Max];
103 int32 CommitedLargePagesCount[FMemory::AllocationHints::Max];
105 FPlatformMemory::FPlatformVirtualMemoryBlock Block;
107 struct FLargePage :
public TIntrusiveLinkedList<FLargePage>
109 uintptr_t FreeSubPages[NumberOfSubPagesPerLargePage];
110 int32 NumberOfFreeSubPages;
111 uint32 AllocationHint;
113 uintptr_t BaseAddress;
115 void Init(
void* InBaseAddress)
117 BaseAddress = (uintptr_t)InBaseAddress;
118 NumberOfFreeSubPages = NumberOfSubPagesPerLargePage;
119 uintptr_t Ptr = BaseAddress;
120 for (
int i = 0; i < NumberOfFreeSubPages; i++)
122 FreeSubPages[i] = Ptr;
123 Ptr += SizeOfSubPage;
129 FreeSubPages[NumberOfFreeSubPages++] = (uintptr_t)Ptr;
135 if (NumberOfFreeSubPages)
137 ret = (
void*)FreeSubPages[--NumberOfFreeSubPages];
143 FLargePage* FreeLargePagesHead[FMemory::AllocationHints::Max];
145 FLargePage* UsedLargePagesHead[FMemory::AllocationHints::Max];
147 FLargePage* UsedLargePagesWithSpaceHead[FMemory::AllocationHints::Max];
149 FLargePage* EmptyButAvailableLargePagesHead[FMemory::AllocationHints::Max];
151 FLargePage LargePagesArray[NumberOfLargePages];
153 TCachedOSPageAllocator<CACHEDOSVERYLARGEPAGEALLOCATOR_MAX_CACHED_OS_FREES, CACHEDOSVERYLARGEPAGEALLOCATOR_BYTE_LIMIT> CachedOSPageAllocator;
156CORE_API
extern bool GEnableVeryLargePageAllocator;
#define UE_USE_VERYLARGEPAGEALLOCATOR