6#include "HAL/CriticalSection.h"
7#include "HAL/ThreadSafeCounter.h"
8#include "HAL/PlatformProcess.h"
9#include "Misc/ScopeLock.h"
10#include "Templates/AlignmentTemplates.h"
56 check(Pages && MaximumAlignment % FPlatformMemory::FPlatformVirtualMemoryBlock::GetVirtualSizeAlignment() == 0);
75 check(!Link->Ptr && Ptr);
87 check(IsAligned(Result, MaximumAlignment) && IsAligned(AlignedSize, MaximumAlignment));
95 FVirtualAllocator(
void *InLowAdress,
void* InHighAddress, size_t InPageSize, size_t InMaximumAlignment,
bool bInBacksMalloc)
107 check(LowAddress && HighAddress && LowAddress < HighAddress && IsAligned(LowAddress, MaximumAlignment));
114 check(Alignment <= MaximumAlignment && Alignment > 0);
115 size_t SizeAndAlignment = FMath::Max(Align(Size, Alignment), PageSize);
119 size_t Pages = SizeAndAlignment /
PageSize;
120 check(Pages == uint32(Pages));
121 return uint32(Pages);
123 size_t BlockIndex = FMath::CeilLogTwo64(FMath::Max(SizeAndAlignment, PageSize));
124 size_t AlignedSize = size_t(1) << BlockIndex;
125 check(AlignedSize % PageSize == 0);
126 size_t Pages = AlignedSize /
PageSize;
127 check(Pages == uint32(Pages));
128 return uint32(Pages);
133 check(AlignmentForCheck <= MaximumAlignment && AlignmentForCheck > 0 && NumPages);
136 size_t BlockIndex =
FMath::CeilLogTwo64(NumPages *
PageSize);
137 size_t AlignedSize = size_t(1) << BlockIndex;
138 bool bHackForHugeBlock =
false;
142 AlignedSize = size_t(NumPages) *
PageSize;
143 bHackForHugeBlock =
true;
153 check(!bHackForHugeBlock);
161 check(!Block.FirstFree || Block.FirstFree->Ptr);
164 check(IsAligned(Result, FMath::Min(AlignedSize, MaximumAlignment)));
169 size_t AllocSize = FMath::Max(AlignedSize, MaximumAlignment);
171 check(IsAligned(LocalNextAlloc, MaximumAlignment));
173 uint8* NewNextAlloc = LocalNextAlloc + AllocSize;
181 Result = LocalNextAlloc;
183 LocalNextAlloc += AlignedSize;
184 while (LocalNextAlloc < NewNextAlloc && !bHackForHugeBlock)
187 LocalNextAlloc += AlignedSize;
190 check(IsAligned(Result, AlignmentForCheck));
199 check(!
"Huge vm blocks may not be freed.");
202 size_t BlockIndex =
FMath::CeilLogTwo64(NumPages *
PageSize);
203 size_t AlignedSize = size_t(1) << BlockIndex;
237 for (int32 Index = 0; Index < 64; Index++)
FWindowsCriticalSection FCriticalSection
UE_NODISCARD_CTOR FScopeLock(FCriticalSection *InSynchObject)
virtual ~FVirtualAllocator()=default
void * AllocateVirtualPages(uint32 NumPages, size_t AlignmentForCheck=1)
uint32 GetPagesForSizeAndAlignment(size_t Size, size_t Alignment=1) const
void GetStats(FVirtualAllocatorStats &OutStats)
void FreeVirtual(void *Ptr, uint32 NumPages)
virtual uint8 * AllocNewVM(size_t AlignedSize)
FVirtualAllocator(void *InLowAdress, void *InHighAddress, size_t InPageSize, size_t InMaximumAlignment, bool bInBacksMalloc)
void FreeVirtualByBlock(void *Ptr, FPerBlockSize &Block, size_t AlignedSize)
FFreeLink * RecycledLinks
FCriticalSection CriticalSection
static void * Malloc(SIZE_T Count, uint32 Alignment=DEFAULT_ALIGNMENT)
size_t VMSpaceConsumedPeak
FVirtualAllocatorStatsPerBlockSize BlockStats[64]