29#if !defined(UE_MBC_MAX_LISTED_SMALL_POOL_SIZE)
30# define UE_MBC_MAX_LISTED_SMALL_POOL_SIZE 28672
33#if !defined(UE_MBC_NUM_LISTED_SMALL_POOLS)
34# define UE_MBC_NUM_LISTED_SMALL_POOLS 52
37#if !defined(BINNEDCOMMON_USE_SEPARATE_VM_PER_POOL)
39# define BINNEDCOMMON_USE_SEPARATE_VM_PER_POOL 1
41# define BINNEDCOMMON_USE_SEPARATE_VM_PER_POOL 0
45#define UE_MBC_MIN_SMALL_POOL_ALIGNMENT 8
46#define UE_MBC_MAX_SMALL_POOL_ALIGNMENT 256
47#define UE_MBC_STANDARD_ALIGNMENT 16
48#define UE_MBC_MIN_BIN_SIZE 8
49#define UE_MBC_BIN_SIZE_SHIFT 3
51#if !defined(AGGRESSIVE_MEMORY_SAVING)
52# error "AGGRESSIVE_MEMORY_SAVING must be defined"
55#if AGGRESSIVE_MEMORY_SAVING
56# define UE_DEFAULT_GMallocBinnedBundleSize 8192
58# define UE_DEFAULT_GMallocBinnedBundleSize 65536
61#if !defined(UE_DEFAULT_GMallocBinnedPerThreadCaches)
62# define UE_DEFAULT_GMallocBinnedPerThreadCaches 1
64#define UE_DEFAULT_GMallocBinnedBundleCount 64
65#define UE_DEFAULT_GMallocBinnedAllocExtra 32
66#define UE_DEFAULT_GMallocBinnedMaxBundlesBeforeRecycle 8
68#ifndef UE_MBC_ALLOW_RUNTIME_TWEAKING
69# define UE_MBC_ALLOW_RUNTIME_TWEAKING 0
72#if UE_MBC_ALLOW_RUNTIME_TWEAKING
79# define GMallocBinnedPerThreadCaches UE_DEFAULT_GMallocBinnedPerThreadCaches
80# define GMallocBinnedBundleSize UE_DEFAULT_GMallocBinnedBundleSize
81# define GMallocBinnedBundleCount UE_DEFAULT_GMallocBinnedBundleCount
82# define GMallocBinnedAllocExtra UE_DEFAULT_GMallocBinnedAllocExtra
83# define GMallocBinnedMaxBundlesBeforeRecycle UE_DEFAULT_GMallocBinnedMaxBundlesBeforeRecycle
86#ifndef UE_MBC_ALLOCATOR_STATS
87# define UE_MBC_ALLOCATOR_STATS (!UE_BUILD_SHIPPING || WITH_EDITOR)
90#if UE_MBC_ALLOCATOR_STATS
91# define UE_MBC_UPDATE_STATS(x) x
94# define UE_MBC_UPDATE_STATS(x)
97#ifndef UE_MBC_LOG_LARGE_ALLOCATION
98# define UE_MBC_LOG_LARGE_ALLOCATION 0
101#ifndef UE_MBC_LIGHTWEIGHT_BIN_CALLSTACK_TRACKER
102# define UE_MBC_LIGHTWEIGHT_BIN_CALLSTACK_TRACKER 0
105#if UE_MBC_LIGHTWEIGHT_BIN_CALLSTACK_TRACKER && !UE_MBC_ALLOCATOR_STATS
106# error "MB lightweight bin callstack tracker needs UE_MBC_ALLOCATOR_STATS to be enabled."
109#define UE_MBC_MAX_SUPPORTED_PLATFORM_PAGE_SIZE 16 * 1024
136 uint32 AllocationSize = 8;
139 uint32 OffsetOfLastRow = 0;
141 while (Capacity < NumPages)
145 OffsetOfLastRow = AllocationSize / 8;
152 return AllocationSize;
210 : PtrToPoolPageBitShift(0)
214 , AddressSpaceBase(0)
227 PtrToPoolPageBitShift = FPlatformMath::CeilLogTwo(
InPageSize);
230 MaxHashBuckets = FMath::RoundUpToPowerOfTwo64(AddressLimit -
AddressBase) >> HashKeyShift;
245 return MaxHashBuckets;
250 uint64 PtrToPoolPageBitShift;
279 inline void PushHead(FBundleNode* Node)
281 Node->SetNextNodeInCurrentBundle(Head);
286 inline FBundleNode* PopHead()
288 FBundleNode*
Result = Head;
291 Head = Head->GetNextNodeInCurrentBundle();
313 FullBundle = PartialBundle;
314 PartialBundle.Reset();
327 if ((!PartialBundle.Head) & (!!FullBundle.Head))
329 PartialBundle = FullBundle;
332 return PartialBundle.Head ? PartialBundle.PopHead() :
nullptr;
342 FullBundle.Head->Count = FullBundle.Count;
345 Result = FullBundle.Head;
355 if (!PartialBundle.Head)
357 PartialBundle.Count = 0;
359 if (PartialBundle.Head)
361 PartialBundle.Count = PartialBundle.Head->Count;
374 PartialBundle.Reset();
391 Next =
Next->GetNextNodeInCurrentBundle();
393 Prev->SetNextNodeInCurrentBundle(
Full);
404 FBundle PartialBundle;
417#if UE_MBC_ALLOCATOR_STATS
439#if UE_MBC_LOG_LARGE_ALLOCATION
445#if UE_MBC_LIGHTWEIGHT_BIN_CALLSTACK_TRACKER
450template <
class AllocType,
int NumSmallPools,
int MaxSmallPoolSize>
459 struct FPoolHashBucket
462 typename AllocType::FPoolInfo* FirstPool;
463 FPoolHashBucket* Prev;
464 FPoolHashBucket*
Next;
494#if UE_MBC_ALLOCATOR_STATS
640#if UE_MBC_ALLOCATOR_STATS
646 uint64 MemoryTrimEpoch = 0;
648 bool bLockedByOwnerThread =
false;
692 Collision->FirstPool[PoolIndex].SetCanary(Kind,
false,
true);
698 Collision->FirstPool[PoolIndex].SetCanary(Kind,
false,
false);
708 Allocator.HashBucketFreeList = (FPoolHashBucket*)
Allocator.AllocateMetaDataMemory(AllocType::OsAllocationGranularity);
711 for (
UPTRINT i = 0, n = AllocType::OsAllocationGranularity /
sizeof(FPoolHashBucket); i < n; ++i)
713 Allocator.HashBucketFreeList->Link(
new (
Allocator.HashBucketFreeList + i) FPoolHashBucket());
717 FPoolHashBucket* NextFree =
Allocator.HashBucketFreeList->Next;
731 NewBucket->FirstPool[PoolIndex].SetCanary(Kind,
false,
true);
735 NewBucket->FirstPool[PoolIndex].SetCanary(Kind,
false,
false);
805 ((
AllocType*)
this)->FlushCurrentThreadCacheInternal();
853 const uint32 BinSize = Alloc.PoolIndexToBinSize(PoolIndex);
862 }
while (PoolIndex < NUM_SMALL_POOLS);
865 Alignment = FPlatformMath::Max<uint32>(Alignment, Alloc.OsAllocationGranularity);
876 checkSlow(PoolIndex >= 0 && PoolIndex < NUM_SMALL_POOLS);
893 const uint32 BlockSize = Alloc.PoolIndexToBinSize(PoolIndex);
903 }
while (PoolIndex < NUM_SMALL_POOLS);
920 typename AllocType::FPoolInfo* Pool;
938#if UE_MBC_ALLOCATOR_STATS
958#if UE_MBC_ALLOCATOR_STATS && CSV_PROFILER_STATS
975 const int BinSize = Alloc.PoolIndexToBinSize(i);
993 const float Fragmentation = 1.0f - (
float)Alloc.SmallPoolTables[i].TotalUsedBins / (
float)Alloc.SmallPoolTables[i].TotalAllocatedBins;
996 const float TotalMem = (
float)Alloc.SmallPoolTables[i].TotalAllocatedMem / 1024.0f / 1024.0f;
1013 HashBuckets = (FPoolHashBucket*)AllocType::AllocateMetaDataMemory(
HashAllocSize);
1021 FPoolHashBucket* HashBuckets =
nullptr;
1022 FPoolHashBucket* HashBucketFreeList =
nullptr;
1024 static void RegisterThreadFreeBlockLists(FPerThreadFreeBlockLists*
FreeBlockLists)
1031 static void UnregisterThreadFreeBlockLists(FPerThreadFreeBlockLists*
FreeBlockLists)
1040#if UE_ENABLE_INCLUDE_ORDER_DEPRECATED_IN_5_7
constexpr T Align(T Val, uint64 Alignment)
Definition AlignmentTemplates.h:18
constexpr bool IsAligned(T Val, uint64 Alignment)
Definition AlignmentTemplates.h:50
#define checkSlow(expr)
Definition AssertionMacros.h:332
#define check(expr)
Definition AssertionMacros.h:314
#define checkf(expr, format,...)
Definition AssertionMacros.h:315
#define verify(expr)
Definition AssertionMacros.h:319
#define TSAN_SAFE
Definition CoreMiscDefines.h:144
UE_FORCEINLINE_HINT TSharedRef< CastToType, Mode > StaticCastSharedRef(TSharedRef< CastFromType, Mode > const &InSharedRef)
Definition SharedPointer.h:127
#define CSV_CATEGORY_INDEX(CategoryName)
Definition CsvProfiler.h:75
#define CSV_DECLARE_CATEGORY_EXTERN(CategoryName)
Definition CsvProfiler.h:79
#define CSV_CUSTOM_STAT(Category, StatName, Value, Op)
Definition CsvProfiler.h:160
void Init()
Definition LockFreeList.h:4
#define UE_MBC_BIN_SIZE_SHIFT
Definition MallocBinnedCommon.h:49
CORE_API int32 GMallocBinnedFlushRegisteredThreadCachesOnOneThread
Definition MallocBinnedCommon.cpp:547
#define GMallocBinnedAllocExtra
Definition MallocBinnedCommon.h:82
#define UE_MBC_MAX_SMALL_POOL_ALIGNMENT
Definition MallocBinnedCommon.h:46
#define UE_MBC_UPDATE_STATS(x)
Definition MallocBinnedCommon.h:91
#define GMallocBinnedBundleCount
Definition MallocBinnedCommon.h:81
#define GMallocBinnedPerThreadCaches
Definition MallocBinnedCommon.h:79
#define GMallocBinnedBundleSize
Definition MallocBinnedCommon.h:80
#define UE_MBC_ALLOW_RUNTIME_TWEAKING
Definition MallocBinnedCommon.h:69
CORE_API float GMallocBinnedFlushThreadCacheMaxWaitTime
Definition MallocBinnedCommon.cpp:539
#define UE_MBC_MIN_SMALL_POOL_ALIGNMENT
Definition MallocBinnedCommon.h:45
CORE_API int32 GMallocBinnedEnableCSVStats
#define GMallocBinnedMaxBundlesBeforeRecycle
Definition MallocBinnedCommon.h:83
#define UE_MBC_STANDARD_ALIGNMENT
Definition MallocBinnedCommon.h:47
USkinnedMeshComponent float
Definition SkinnedMeshComponent.h:60
FRWLock Lock
Definition UnversionedPropertySerialization.cpp:921
uint32 Size
Definition VulkanMemory.cpp:4034
Definition MallocBinnedCommon.h:120
FBitTree()
Definition MallocBinnedCommon.h:129
uint32 CountOnes(uint32 UpTo) const
Definition MallocBinnedCommon.cpp:445
uint32 Slow_NextAllocBits(uint32 NumBits, uint64 StartIndex)
Definition MallocBinnedCommon.cpp:472
static constexpr uint32 GetMemoryRequirements(uint32 NumPages)
Definition MallocBinnedCommon.h:134
void FBitTreeInit(uint32 InDesiredCapacity, void *Memory, uint32 MemorySize, bool InitialValue)
Definition MallocBinnedCommon.cpp:168
uint32 AllocBit()
Definition MallocBinnedCommon.cpp:229
uint32 NextAllocBit() const
Definition MallocBinnedCommon.cpp:319
void FreeBit(uint32 Index)
Definition MallocBinnedCommon.cpp:415
bool IsAllocated(uint32 Index) const
Definition MallocBinnedCommon.cpp:278
Definition MallocBinnedCommon.h:184
static std::atomic< int64 > AllocatedOSSmallPoolMemory
Definition MallocBinnedCommon.h:421
void UnrecognizedPointerFatalError(void *Ptr)
Definition MallocBinnedCommon.cpp:633
static std::atomic< int64 > ConsolidatedMemory
Definition MallocBinnedCommon.h:419
static void OutOfMemory(uint64 Size, uint32 Alignment=0)
Definition MallocBinnedCommon.h:431
static uint32 OsAllocationGranularity
Definition MallocBinnedCommon.h:410
static int64 PoolInfoMemory
Definition MallocBinnedCommon.h:425
std::atomic< uint64 > MemoryTrimEpoch
Definition MallocBinnedCommon.h:415
static CORE_API uint32 BinnedTlsSlot
Definition MallocBinnedCommon.h:413
static std::atomic< int64 > TLSMemory
Definition MallocBinnedCommon.h:418
static std::atomic< int64 > AllocatedLargePoolMemory
Definition MallocBinnedCommon.h:422
static int64 HashMemory
Definition MallocBinnedCommon.h:426
void GetAllocatorStatsInternal(FGenericMemoryStats &OutStats, int64 TotalAllocatedSmallPoolMemory)
virtual CORE_API void OnMallocInitialized() override
Definition MallocBinnedCommon.cpp:814
FPtrToPoolMapping PtrToPoolMapping
Definition MallocBinnedCommon.h:408
UE::FPlatformRecursiveMutex ExternalAllocMutex
Definition MallocBinnedCommon.h:411
void LogLargeAllocation(SIZE_T Size) const
Definition MallocBinnedCommon.h:442
static std::atomic< int64 > AllocatedSmallPoolMemory
Definition MallocBinnedCommon.h:420
static std::atomic< int64 > AllocatedLargePoolMemoryWAlignment
Definition MallocBinnedCommon.h:423
uint64 NumPoolsPerPage
Definition MallocBinnedCommon.h:409
Definition MallocBinnedCommonUtils.h:98
Definition MemoryBase.h:99
Definition NameTypes.h:617
Definition MallocBinnedCommon.h:452
static TArray< FPerThreadFreeBlockLists * > & GetRegisteredFreeBlockLists()
Definition MallocBinnedCommon.h:774
virtual void SetupTLSCachesOnCurrentThread() override
Definition MallocBinnedCommon.h:780
void AllocateHashBuckets()
Definition MallocBinnedCommon.h:1009
uint32 BoundSizeToPoolIndex(SIZE_T Size, const uint8(&MemSizeToPoolIndex)[SIZE_TO_POOL_INDEX_NUM]) const
Definition MallocBinnedCommon.h:871
SIZE_T QuantizeSizeCommon(SIZE_T Count, uint32 Alignment, const AllocType &Alloc) const
Definition MallocBinnedCommon.h:836
static UE::FPlatformRecursiveMutex & GetFreeBlockListsRegistrationMutex()
Definition MallocBinnedCommon.h:768
void UpdateStatsCommon(const AllocType &Alloc)
Definition MallocBinnedCommon.h:956
static constexpr int SIZE_TO_POOL_INDEX_NUM
Definition MallocBinnedCommon.h:500
virtual void MarkTLSCachesAsUnusedOnCurrentThread() override
Definition MallocBinnedCommon.h:821
int64 GetTotalAllocatedSmallPoolMemory() const
Definition MallocBinnedCommon.h:939
bool GetAllocationSizeExternal(void *Ptr, SIZE_T &SizeOut)
Definition MallocBinnedCommon.h:909
virtual void GetAllocatorStats(FGenericMemoryStats &OutStats) override
Definition MallocBinnedCommon.h:492
FORCENOINLINE bool PromoteToLargerBin(SIZE_T &Size, uint32 &Alignment, const AllocType &Alloc) const
Definition MallocBinnedCommon.h:881
virtual void ClearAndDisableTLSCachesOnCurrentThread() override
Definition MallocBinnedCommon.h:796
virtual void MarkTLSCachesAsUsedOnCurrentThread() override
Definition MallocBinnedCommon.h:809
Definition WordMutex.h:21
bool TryLock()
Definition WordMutex.h:28
void Unlock()
Definition WordMutex.h:45
void Lock()
Definition WordMutex.h:34
Definition UniqueLock.h:20
@ Count
Definition AudioMixerDevice.h:90
UE_STRING_CLASS Result(Forward< LhsType >(Lhs), RhsLen)
Definition String.cpp.inl:732
FPThreadsRecursiveMutex FPlatformRecursiveMutex
Definition AndroidPlatformMutex.h:12
U16 Index
Definition radfft.cpp:71
static uint32 AllocTlsSlot(void)
Definition AndroidPlatformTLS.h:30
static UE_FORCEINLINE_HINT void * GetTlsValue(uint32 SlotIndex)
Definition AndroidPlatformTLS.h:57
static UE_FORCEINLINE_HINT void SetTlsValue(uint32 SlotIndex, void *Value)
Definition AndroidPlatformTLS.h:47
Definition MemoryMisc.h:21
Definition MallocBinnedCommon.h:188
void SetNextNodeInCurrentBundle(FBundleNode *Next)
Definition MallocBinnedCommon.h:193
uint64 NextNodeInCurrentBundle
Definition MallocBinnedCommon.h:189
FBundleNode * GetNextNodeInCurrentBundle()
Definition MallocBinnedCommon.h:198
uint64 Reserved
Definition MallocBinnedCommon.h:191
uint64 Count
Definition MallocBinnedCommon.h:190
Definition MallocBinnedCommon.h:301
FBundleNode * RecyleFull(uint32 InPoolIndex, T &InGlobalRecycler)
Definition MallocBinnedCommon.h:337
UE_FORCEINLINE_HINT bool CanPushToFront(uint32 InPoolIndex, uint32 InBinSize) const
Definition MallocBinnedCommon.h:320
bool ObtainPartial(uint32 InPoolIndex, T &InGlobalRecycler)
Definition MallocBinnedCommon.h:353
bool PushToFront(void *InPtr, uint32 InPoolIndex, uint32 InBinSize)
Definition MallocBinnedCommon.h:303
void * PopFromFront(uint32 InPoolIndex)
Definition MallocBinnedCommon.h:325
FBundleNode * PopBundles(uint32 InPoolIndex)
Definition MallocBinnedCommon.h:369
Definition MallocBinnedCommon.h:208
UE_FORCEINLINE_HINT uint64 GetMaxHashBuckets() const
Definition MallocBinnedCommon.h:243
FPtrToPoolMapping(uint32 InPageSize, uint64 InNumPoolsPerPage, uint64 AddressBase, uint64 AddressLimit)
Definition MallocBinnedCommon.h:218
void GetHashBucketAndPoolIndices(const void *InPtr, uint32 &OutBucketIndex, UPTRINT &OutBucketCollision, uint32 &OutPoolIndex) const
Definition MallocBinnedCommon.h:234
FPtrToPoolMapping()
Definition MallocBinnedCommon.h:209
void Init(uint32 InPageSize, uint64 InNumPoolsPerPage, uint64 AddressBase, uint64 AddressLimit)
Definition MallocBinnedCommon.h:223
static constexpr UE_FORCEINLINE_HINT bool IsPowerOfTwo(T Value)
Definition UnrealMathUtility.h:519
Definition MallocBinnedCommon.h:168
FSizeTableEntry()=default
static uint8 FillSizeTable(uint64 PlatformPageSize, FSizeTableEntry *SizeTable, uint32 BasePageSize, uint32 MaxSize, uint32 SizeIncrement)
Definition MallocBinnedCommon.cpp:142
uint32 BinSize
Definition MallocBinnedCommon.h:169
bool operator<(const FSizeTableEntry &Other) const
Definition MallocBinnedCommon.h:175
uint32 NumMemoryPagesPerBlock
Definition MallocBinnedCommon.h:170
static int32 Sprintf(CharType *Dest, const FmtType &Fmt, Types... Args)
Definition CString.h:569
Definition MallocBinnedCommon.h:503
static void ClearTLS()
Definition MallocBinnedCommon.h:558
FBundleNode * RecycleFullBundle(uint32 InPoolIndex, T &InGlobalRecycler)
Definition MallocBinnedCommon.h:596
UE_FORCEINLINE_HINT bool Free(void *InPtr, uint32 InPoolIndex, uint32 InBinSize)
Definition MallocBinnedCommon.h:583
static FPerThreadFreeBlockLists * Get() TSAN_SAFE
Definition MallocBinnedCommon.h:504
bool ObtainRecycledPartial(uint32 InPoolIndex, T &InGlobalRecycler)
Definition MallocBinnedCommon.h:603
UE_FORCEINLINE_HINT void * Malloc(uint32 InPoolIndex)
Definition MallocBinnedCommon.h:577
UE_FORCEINLINE_HINT bool CanFree(uint32 InPoolIndex, uint32 InBinSize) const
Definition MallocBinnedCommon.h:589
bool UpdateEpoch(uint64 NewEpoch)
Definition MallocBinnedCommon.h:629
static void LockTLS()
Definition MallocBinnedCommon.h:548
FBundleNode * PopBundles(uint32 InPoolIndex)
Definition MallocBinnedCommon.h:608
void Lock()
Definition MallocBinnedCommon.h:613
static void UnlockTLS()
Definition MallocBinnedCommon.h:538
static void SetTLS()
Definition MallocBinnedCommon.h:520
bool TryLock()
Definition MallocBinnedCommon.h:618
void Unlock()
Definition MallocBinnedCommon.h:623
int64 AllocatedMemory
Definition MallocBinnedCommon.h:642
static PoolInfo * GetOrCreatePoolInfo(AllocType &Allocator, void *InPtr, typename PoolInfo::ECanary Kind)
Definition MallocBinnedCommon.h:657
typename AllocType::FPoolInfo PoolInfo
Definition MallocBinnedCommon.h:653
static PoolInfo * FindPoolInfo(AllocType &Allocator, void *InPtr)
Definition MallocBinnedCommon.h:745