UDocumentation UE5.7 10.02.2026 (Source)
API documentation for Unreal Engine 5.7
LowLevelMemTracker.h
Go to the documentation of this file.
1// Copyright Epic Games, Inc. All Rights Reserved.
2
3#pragma once
4
5#include "CoreTypes.h"
6#include "HAL/PlatformMutex.h"
7#include "LowLevelMemTrackerDefines.h" // LLM_ENABLED_IN_CONFIG
9#include "AutoRTFM.h"
10
11#ifndef PLATFORM_SUPPORTS_LLM
12 #define PLATFORM_SUPPORTS_LLM 1
13#endif
14
15#define LLM_ENABLED_ON_PLATFORM UE_DEPRECATED_MACRO(5.7, "Use PLATFORM_SUPPORTS_LLM instead") (PLATFORM_SUPPORTS_LLM)
16
17#ifdef ENABLE_LOW_LEVEL_MEM_TRACKER
18 #error ENABLE_LOW_LEVEL_MEM_TRACKER is now a derived define that should not be defined separately. Define LLM_ENABLED_IN_CONFIG (build environment only) or PLATFORM_SUPPORTS_LLM (build environment or c++ header) instead.
19#endif
20#define ENABLE_LOW_LEVEL_MEM_TRACKER (LLM_ENABLED_IN_CONFIG && PLATFORM_SUPPORTS_LLM)
21
22#if ENABLE_LOW_LEVEL_MEM_TRACKER
23
24// Public defines configuring LLM; see also private defines in LowLevelMemTracker.cpp
25
26// LLM_ALLOW_ASSETS_TAGS: Set to 1 to enable run-time toggling of AssetTags reporting, 0 to disable.
27// Enabling the define causes extra cputime costs to track costs even when AssetTags are toggled off.
28// When defined on, the feature can be toggled on at runtime with commandline -llmtagsets=assets.
29// Toggling the feature on causes a huge number of stat ids to be created and has a high cputime cost.
30// When defined on and runtime-toggled on, AssetTags report the asset that is in scope for each allocation
31// LLM Assets can be viewed in game using 'Stat LLMAssets'.
32#ifndef LLM_ALLOW_ASSETS_TAGS
33 #define LLM_ALLOW_ASSETS_TAGS 0
34#endif
35
36// LLM_ALLOW_UOBJECTCLASSES_TAGS will be enabled when LLM_ALLOW_ASSETS_TAGS is not
37// The intent is to avoid the amount of memory overhead by having 3 active TagSet at once.
38#ifndef LLM_ALLOW_UOBJECTCLASSES_TAGS
39 #define LLM_ALLOW_UOBJECTCLASSES_TAGS !LLM_ALLOW_ASSETS_TAGS
40#endif
41
42// LLM_ALLOW_STATS: Set to 1 to allow stats to be used as tags, 0 to disable.
43// When enabled LLM_SCOPED_TAG_WITH_STAT macros are enabled and create an LLM tag per stat at the cost of more LLM
44// memory usage per allocation. Turning this on uses the same amount of memory per allocation as LLM_ALLOW_NAMES_TAGS.
45// Turning both of them on has no extra cost.
46#ifndef LLM_ALLOW_STATS
47 #define LLM_ALLOW_STATS 0
48#endif
49
50// Enable stat tags if: (1) Stats or (2) Asset tags are allowed (asset tags use the stat macros to record asset scopes)
51#define LLM_ENABLED_STAT_TAGS (LLM_ALLOW_STATS || LLM_ALLOW_ASSETS_TAGS)
52
53#include "Containers/Array.h"
56#include "HAL/CriticalSection.h"
57#include "HAL/PlatformCrt.h"
58#include "HAL/PlatformMisc.h"
61#include "UObject/NameTypes.h"
62#include "UObject/UnrealNames.h"
63
64#include <atomic>
65
66class FTagTrace;
67
68#if DO_CHECK
69
70namespace UE::LLMPrivate
71{
72
73bool HandleAssert(bool bLog, const TCHAR* Format, ...);
74
75// LLMEnsure's use of this generates a bool per callsite by passing a lambda which uniquely instantiates the template.
76template <typename Type>
77bool TrueOnFirstCallOnly(const Type&)
78{
79 static bool bValue = true;
80 bool Result = bValue;
81 bValue = false;
82 return Result;
83}
84
85} // UE::LLMPrivate
86
87#if !USING_CODE_ANALYSIS
88 #define LLMTrueOnFirstCallOnly UE::LLMPrivate::TrueOnFirstCallOnly([]{})
89#else
90 #define LLMTrueOnFirstCallOnly false
91#endif
92
93#define LLMCheckMessage(expr) TEXT("LLM check failed: %s [File:%s] [Line: %d]\r\n"), TEXT(#expr), TEXT(__FILE__), __LINE__
94#define LLMCheckfMessage(expr, format) TEXT("LLM check failed: %s [File:%s] [Line: %d]\r\n") format TEXT("\r\n"), TEXT(#expr), TEXT(__FILE__), __LINE__
95#define LLMEnsureMessage(expr) TEXT("LLM ensure failed: %s [File:%s] [Line: %d]\r\n"), TEXT(#expr), TEXT(__FILE__), __LINE__
96
97#define LLMCheck(expr) do { if (UNLIKELY(!(expr))) { UE::LLMPrivate::HandleAssert(true, LLMCheckMessage(expr)); FPlatformMisc::RaiseException(1); } } while(false)
98#define LLMCheckf(expr,format,...) do { if (UNLIKELY(!(expr))) { UE::LLMPrivate::HandleAssert(true, LLMCheckfMessage(expr, format), ##__VA_ARGS__); FPlatformMisc::RaiseException(1); } } while(false)
99#define LLMEnsure(expr) (LIKELY(!!(expr)) || UE::LLMPrivate::HandleAssert(LLMTrueOnFirstCallOnly, LLMEnsureMessage(expr)))
100
101#else
102
103#define LLMCheck(expr)
104#define LLMCheckf(expr,...)
105#define LLMEnsure(expr) (!!(expr))
106
107#endif
108
109#define LLM_TAG_TYPE uint8
110
111// estimate the maximum amount of memory LLM will need to run on a game with around 4 million allocations.
112// Make sure that you have debug memory enabled on consoles (on screen warning will show if you don't)
113// (currently only used on PS4 to stop it reserving a large chunk up front. This will go away with the new memory system)
114#define LLM_MEMORY_OVERHEAD (600LL*1024*1024)
115
116/*
117 * LLM Trackers
118 */
119enum class ELLMTracker : uint8
120{
121 Platform,
122 Default,
123
124 Max,
125};
126
127/*
128 * optional tags that need to be enabled with -llmtagsets=x,y,z on the commandline
129 */
130enum class ELLMTagSet : uint8
131{
132 None,
133 Assets,
136
137 Max, // note: see FLowLevelMemTracker::ShouldReduceThreads and IsAssetTagForAssets if you add any asset-style tagsets
138};
139
140/*
141 * Size parameter flags used when requesting the size of the tracked tag data.
142 */
143namespace UE::LLM
144{
145
146enum class ESizeParams : uint8
147{
148 Default = 0,
149 ReportCurrent = 0,
150 ReportPeak = 1,
152};
153
155
156} // UE::LLM
157
158// Do not add to these macros. Please use the LLM_DECLARE_TAG family of macros below to create new tags.
159#define LLM_ENUM_GENERIC_TAGS(macro) \
160 macro(Untagged, "Untagged", NAME_None, NAME_None, -1)\
161 macro(Paused, "Paused", NAME_None, NAME_None, -1)\
162 macro(Total, "Total", GET_STATFNAME(STAT_TotalLLM), GET_STATFNAME(STAT_TrackedTotalSummaryLLM), -1)\
163 macro(Untracked, "Untracked", GET_STATFNAME(STAT_UntrackedLLM), GET_STATFNAME(STAT_TrackedTotalSummaryLLM), -1)\
164 macro(PlatformTotal, "Total", GET_STATFNAME(STAT_PlatformTotalLLM), NAME_None, -1)\
165 macro(TrackedTotal, "TrackedTotal", GET_STATFNAME(STAT_TrackedTotalLLM), GET_STATFNAME(STAT_TrackedTotalSummaryLLM), -1)\
166 macro(UntaggedTotal, "Untagged", GET_STATFNAME(STAT_UntaggedTotalLLM), NAME_None, -1)\
167 macro(WorkingSetSize, "WorkingSetSize", GET_STATFNAME(STAT_WorkingSetSizeLLM), GET_STATFNAME(STAT_TrackedTotalSummaryLLM), -1)\
168 macro(PagefileUsed, "PagefileUsed", GET_STATFNAME(STAT_PagefileUsedLLM), GET_STATFNAME(STAT_TrackedTotalSummaryLLM), -1)\
169 macro(PlatformTrackedTotal, "TrackedTotal", GET_STATFNAME(STAT_PlatformTrackedTotalLLM), NAME_None, -1)\
170 macro(PlatformUntaggedTotal, "Untagged", GET_STATFNAME(STAT_PlatformUntaggedTotalLLM), NAME_None, -1)\
171 macro(PlatformUntracked, "Untracked", GET_STATFNAME(STAT_PlatformUntrackedLLM), NAME_None, -1)\
172 macro(PlatformOverhead, "LLMOverhead", GET_STATFNAME(STAT_PlatformOverheadLLM), NAME_None, -1)\
173 macro(PlatformOSAvailable, "OSAvailable", GET_STATFNAME(STAT_PlatformOSAvailableLLM), NAME_None, -1)\
174 /*FMalloc is a special tag that is reserved for the Platform Tracker only. It's used with ELLMAllocType::FMalloc to calculate ELLMTag::FMallocUnused. */ \
175 macro(FMalloc, "FMalloc", GET_STATFNAME(STAT_FMallocLLM), NAME_None, -1)\
176 macro(FMallocUnused, "FMallocUnused", GET_STATFNAME(STAT_FMallocUnusedLLM), GET_STATFNAME(STAT_EngineSummaryLLM), -1)\
177 macro(RHIUnused, "RHIUnused", GET_STATFNAME(STAT_RHIUnusedLLM), GET_STATFNAME(STAT_EngineSummaryLLM), -1)\
178 macro(ThreadStack, "ThreadStack", GET_STATFNAME(STAT_ThreadStackLLM), GET_STATFNAME(STAT_EngineSummaryLLM), -1)\
179 macro(ThreadStackPlatform, "ThreadStack", GET_STATFNAME(STAT_ThreadStackPlatformLLM), NAME_None, -1)\
180 macro(ProgramSizePlatform, "ProgramSize", GET_STATFNAME(STAT_ProgramSizePlatformLLM), NAME_None, -1)\
181 macro(ProgramSize, "ProgramSize", GET_STATFNAME(STAT_ProgramSizeLLM), GET_STATFNAME(STAT_EngineSummaryLLM), -1)\
182 macro(BackupOOMMemoryPoolPlatform, "OOMBackupPool", GET_STATFNAME(STAT_OOMBackupPoolPlatformLLM), NAME_None, -1)\
183 macro(BackupOOMMemoryPool, "OOMBackupPool", GET_STATFNAME(STAT_OOMBackupPoolLLM), GET_STATFNAME(STAT_EngineSummaryLLM), -1)\
184 macro(GenericPlatformMallocCrash, "GenericPlatformMallocCrash", GET_STATFNAME(STAT_GenericPlatformMallocCrashLLM), GET_STATFNAME(STAT_EngineSummaryLLM), -1)\
185 macro(GenericPlatformMallocCrashPlatform, "GenericPlatformMallocCrash", GET_STATFNAME(STAT_GenericPlatformMallocCrashPlatformLLM), GET_STATFNAME(STAT_EngineSummaryLLM), -1)\
186 /* Any low-level memory that is not tracked in any other category. */ \
187 macro(EngineMisc, "EngineMisc", GET_STATFNAME(STAT_EngineMiscLLM), GET_STATFNAME(STAT_EngineSummaryLLM), -1)\
188 /* Any task kicked off from the task graph that doesn't have its own category. Should be fairly low. */ \
189 macro(TaskGraphTasksMisc, "TaskGraphMiscTasks", GET_STATFNAME(STAT_TaskGraphTasksMiscLLM), GET_STATFNAME(STAT_EngineSummaryLLM), -1)\
190 macro(LinearAllocator, "LinearAllocator", GET_STATFNAME(STAT_LinearAllocatorLLM), NAME_None, -1)\
191 macro(Audio, "Audio", GET_STATFNAME(STAT_AudioLLM), GET_STATFNAME(STAT_AudioSummaryLLM), -1)\
192 macro(AudioMisc, "AudioMisc", GET_STATFNAME(STAT_AudioMiscLLM), GET_STATFNAME(STAT_AudioSummaryLLM), ELLMTag::Audio)\
193 macro(AudioSoundWaves, "AudioSoundWaves", GET_STATFNAME(STAT_AudioSoundWavesLLM), GET_STATFNAME(STAT_AudioSummaryLLM), ELLMTag::Audio)\
194 macro(AudioSoundWaveProxies, "AudioSoundWaveProxies", GET_STATFNAME(STAT_AudioSoundWaveProxiesLLM), GET_STATFNAME(STAT_AudioSummaryLLM), ELLMTag::Audio)\
195 macro(AudioMixer, "AudioMixer", GET_STATFNAME(STAT_AudioMixerLLM), GET_STATFNAME(STAT_AudioSummaryLLM), ELLMTag::Audio)\
196 macro(AudioMixerPlugins, "AudioMixerPlugins", GET_STATFNAME(STAT_AudioMixerPluginsLLM), GET_STATFNAME(STAT_AudioSummaryLLM), ELLMTag::Audio)\
197 macro(AudioPrecache, "AudioPrecache", GET_STATFNAME(STAT_AudioPrecacheLLM), GET_STATFNAME(STAT_AudioSummaryLLM), ELLMTag::Audio)\
198 macro(AudioDecompress, "AudioDecompress", GET_STATFNAME(STAT_AudioDecompressLLM), GET_STATFNAME(STAT_AudioSummaryLLM), ELLMTag::Audio)\
199 macro(AudioRealtimePrecache, "AudioRealtimePrecache", GET_STATFNAME(STAT_AudioRealtimePrecacheLLM), GET_STATFNAME(STAT_AudioSummaryLLM), ELLMTag::Audio)\
200 macro(AudioFullDecompress, "AudioFullDecompress", GET_STATFNAME(STAT_AudioFullDecompressLLM), GET_STATFNAME(STAT_AudioSummaryLLM), ELLMTag::Audio)\
201 macro(AudioStreamCache, "AudioStreamCache", GET_STATFNAME(STAT_AudioStreamCacheLLM), GET_STATFNAME(STAT_AudioSummaryLLM), ELLMTag::Audio)\
202 macro(AudioStreamCacheCompressedData, "AudioStreamCacheCompressedData",GET_STATFNAME(STAT_AudioStreamCacheCompressedDataLLM), GET_STATFNAME(STAT_AudioSummaryLLM), ELLMTag::Audio)\
203 macro(AudioSynthesis, "AudioSynthesis", GET_STATFNAME(STAT_AudioSynthesisLLM), GET_STATFNAME(STAT_AudioSummaryLLM), ELLMTag::Audio)\
204 macro(RealTimeCommunications, "RealTimeCommunications", GET_STATFNAME(STAT_RealTimeCommunicationsLLM), NAME_None, -1)\
205 macro(FName, "FName", GET_STATFNAME(STAT_FNameLLM), GET_STATFNAME(STAT_EngineSummaryLLM), -1)\
206 macro(Networking, "Networking", GET_STATFNAME(STAT_NetworkingLLM), GET_STATFNAME(STAT_NetworkingSummaryLLM), -1)\
207 macro(Meshes, "Meshes", GET_STATFNAME(STAT_MeshesLLM), GET_STATFNAME(STAT_MeshesSummaryLLM), -1)\
208 macro(Stats, "Stats", GET_STATFNAME(STAT_StatsLLM), GET_STATFNAME(STAT_EngineSummaryLLM), -1)\
209 macro(Shaders, "Shaders", GET_STATFNAME(STAT_ShadersLLM), GET_STATFNAME(STAT_EngineSummaryLLM), -1)\
210 macro(PSO, "PSO", GET_STATFNAME(STAT_PSOLLM), GET_STATFNAME(STAT_EngineSummaryLLM), -1)\
211 macro(Textures, "Textures", GET_STATFNAME(STAT_TexturesLLM), GET_STATFNAME(STAT_TexturesSummaryLLM), -1)\
212 macro(TextureMetaData, "TextureMetaData", GET_STATFNAME(STAT_TextureMetaDataLLM), GET_STATFNAME(STAT_TexturesSummaryLLM), -1)\
213 macro(VirtualTextureSystem, "VirtualTextureSystem", GET_STATFNAME(STAT_VirtualTextureSystemLLM), GET_STATFNAME(STAT_TexturesSummaryLLM), -1)\
214 macro(RenderTargets, "RenderTargets", GET_STATFNAME(STAT_RenderTargetsLLM), GET_STATFNAME(STAT_EngineSummaryLLM), -1)\
215 macro(SceneRender, "SceneRender", GET_STATFNAME(STAT_SceneRenderLLM), GET_STATFNAME(STAT_EngineSummaryLLM), -1)\
216 macro(RHIMisc, "RHIMisc", GET_STATFNAME(STAT_RHIMiscLLM), GET_STATFNAME(STAT_EngineSummaryLLM), -1)\
217 macro(AsyncLoading, "AsyncLoading", GET_STATFNAME(STAT_AsyncLoadingLLM), GET_STATFNAME(STAT_EngineSummaryLLM), -1)\
218 /* UObject is a catch-all for all Engine and game memory that is not tracked in any other category. */ \
219 /* it includes any class inherited from UObject and anything that is serialized by that class including properties. */ \
220 /* Note that this stat doesn't include Mesh or Animation data which are tracked separately. */ \
221 /* It is correlated to the number of Objects placed in the Level. */ \
222 macro(UObject, "UObject", GET_STATFNAME(STAT_UObjectLLM), GET_STATFNAME(STAT_UObjectSummaryLLM), -1)\
223 macro(Animation, "Animation", GET_STATFNAME(STAT_AnimationLLM), GET_STATFNAME(STAT_AnimationSummaryLLM), -1)\
224 /* This is the UStaticMesh class and related properties, and does not include the actual mesh data. */ \
225 macro(StaticMesh, "StaticMesh", GET_STATFNAME(STAT_StaticMeshLLM), GET_STATFNAME(STAT_StaticMeshSummaryLLM), ELLMTag::Meshes)\
226 macro(Materials, "Materials", GET_STATFNAME(STAT_MaterialsLLM), GET_STATFNAME(STAT_MaterialsSummaryLLM), -1)\
227 macro(Particles, "Particles", GET_STATFNAME(STAT_ParticlesLLM), GET_STATFNAME(STAT_ParticlesSummaryLLM), -1)\
228 macro(Niagara, "Niagara", GET_STATFNAME(STAT_NiagaraLLM), GET_STATFNAME(STAT_NiagaraSummaryLLM), -1)\
229 macro(GPUSort, "GPUSort", GET_STATFNAME(STAT_GPUSortLLM), GET_STATFNAME(STAT_EngineSummaryLLM), -1)\
230 macro(GC, "GC", GET_STATFNAME(STAT_GCLLM), GET_STATFNAME(STAT_EngineSummaryLLM), -1)\
231 macro(UI, "UI", GET_STATFNAME(STAT_UILLM), GET_STATFNAME(STAT_UISummaryLLM), -1)\
232 macro(NavigationRecast, "NavigationRecast", GET_STATFNAME(STAT_NavigationRecastLLM), GET_STATFNAME(STAT_NavigationSummaryLLM), -1)\
233 macro(Physics, "Physics", GET_STATFNAME(STAT_PhysicsLLM), GET_STATFNAME(STAT_PhysicsSummaryLLM), -1)\
234 macro(PhysX, "PhysX", GET_STATFNAME(STAT_PhysXLLM), GET_STATFNAME(STAT_PhysXSummaryLLM), ELLMTag::Physics)\
235 macro(PhysXGeometry, "PhysXGeometry", GET_STATFNAME(STAT_PhysXGeometryLLM), GET_STATFNAME(STAT_PhysXSummaryLLM), ELLMTag::Physics)\
236 macro(PhysXTrimesh, "PhysXTrimesh", GET_STATFNAME(STAT_PhysXTrimeshLLM), GET_STATFNAME(STAT_PhysXSummaryLLM), ELLMTag::Physics)\
237 macro(PhysXConvex, "PhysXConvex", GET_STATFNAME(STAT_PhysXConvexLLM), GET_STATFNAME(STAT_PhysXSummaryLLM), ELLMTag::Physics)\
238 macro(PhysXAllocator, "PhysXAllocator", GET_STATFNAME(STAT_PhysXAllocatorLLM), GET_STATFNAME(STAT_PhysXSummaryLLM), ELLMTag::Physics)\
239 macro(PhysXLandscape, "PhysXLandscape", GET_STATFNAME(STAT_PhysXLandscapeLLM), GET_STATFNAME(STAT_PhysXSummaryLLM), ELLMTag::Physics)\
240 macro(Chaos, "Chaos", GET_STATFNAME(STAT_ChaosLLM), GET_STATFNAME(STAT_ChaosSummaryLLM), ELLMTag::Physics)\
241 macro(ChaosGeometry, "ChaosGeometry", GET_STATFNAME(STAT_ChaosGeometryLLM), GET_STATFNAME(STAT_ChaosSummaryLLM), ELLMTag::Physics)\
242 macro(ChaosAcceleration, "ChaosAcceleration", GET_STATFNAME(STAT_ChaosAccelerationLLM), GET_STATFNAME(STAT_ChaosSummaryLLM), ELLMTag::Physics)\
243 macro(ChaosParticles, "ChaosParticles", GET_STATFNAME(STAT_ChaosParticlesLLM), GET_STATFNAME(STAT_ChaosSummaryLLM), ELLMTag::Physics)\
244 macro(ChaosLandscape, "ChaosLandscape", GET_STATFNAME(STAT_ChaosLandscapeLLM), GET_STATFNAME(STAT_ChaosSummaryLLM), ELLMTag::Physics)\
245 macro(ChaosTrimesh, "ChaosTrimesh", GET_STATFNAME(STAT_ChaosTrimeshLLM), GET_STATFNAME(STAT_ChaosSummaryLLM), ELLMTag::Physics)\
246 macro(ChaosConvex, "ChaosConvex", GET_STATFNAME(STAT_ChaosConvexLLM), GET_STATFNAME(STAT_ChaosSummaryLLM), ELLMTag::Physics)\
247 macro(ChaosScene, "ChaosScene", GET_STATFNAME(STAT_ChaosSceneLLM), GET_STATFNAME(STAT_ChaosSummaryLLM), ELLMTag::Physics)\
248 macro(ChaosUpdate, "ChaosUpdate", GET_STATFNAME(STAT_ChaosUpdateLLM), GET_STATFNAME(STAT_ChaosSummaryLLM), ELLMTag::Physics)\
249 macro(ChaosActor, "ChaosActor", GET_STATFNAME(STAT_ChaosActorLLM), GET_STATFNAME(STAT_ChaosSummaryLLM), ELLMTag::Physics)\
250 macro(ChaosBody, "ChaosBody", GET_STATFNAME(STAT_ChaosBodyLLM), GET_STATFNAME(STAT_ChaosSummaryLLM), ELLMTag::Physics)\
251 macro(ChaosConstraint, "ChaosConstraint", GET_STATFNAME(STAT_ChaosConstraintLLM), GET_STATFNAME(STAT_ChaosSummaryLLM), ELLMTag::Physics)\
252 macro(ChaosMaterial, "ChaosMaterial", GET_STATFNAME(STAT_ChaosMaterialLLM), GET_STATFNAME(STAT_ChaosSummaryLLM), ELLMTag::Physics)\
253 macro(EnginePreInitMemory, "EnginePreInit", GET_STATFNAME(STAT_EnginePreInitLLM), GET_STATFNAME(STAT_EngineSummaryLLM), -1)\
254 macro(EngineInitMemory, "EngineInit", GET_STATFNAME(STAT_EngineInitLLM), GET_STATFNAME(STAT_EngineSummaryLLM), -1)\
255 macro(RenderingThreadMemory, "RenderingThread", GET_STATFNAME(STAT_RenderingThreadLLM), GET_STATFNAME(STAT_EngineSummaryLLM), -1)\
256 macro(LoadMapMisc, "LoadMapMisc", GET_STATFNAME(STAT_LoadMapMiscLLM), GET_STATFNAME(STAT_EngineSummaryLLM), -1)\
257 macro(StreamingManager, "StreamingManager", GET_STATFNAME(STAT_StreamingManagerLLM), GET_STATFNAME(STAT_EngineSummaryLLM), -1)\
258 macro(GraphicsPlatform, "Graphics", GET_STATFNAME(STAT_GraphicsPlatformLLM), NAME_None, -1)\
259 macro(FileSystem, "FileSystem", GET_STATFNAME(STAT_FileSystemLLM), GET_STATFNAME(STAT_EngineSummaryLLM), -1)\
260 macro(Localization, "Localization", GET_STATFNAME(STAT_LocalizationLLM), GET_STATFNAME(STAT_EngineSummaryLLM), -1)\
261 macro(AssetRegistry, "AssetRegistry", GET_STATFNAME(STAT_AssetRegistryLLM), GET_STATFNAME(STAT_EngineSummaryLLM), -1)\
262 macro(ConfigSystem, "ConfigSystem", GET_STATFNAME(STAT_ConfigSystemLLM), GET_STATFNAME(STAT_EngineSummaryLLM), -1)\
263 macro(InitUObject, "InitUObject", GET_STATFNAME(STAT_InitUObjectLLM), GET_STATFNAME(STAT_EngineSummaryLLM), -1)\
264 macro(VideoRecording, "VideoRecording", GET_STATFNAME(STAT_VideoRecordingLLM), GET_STATFNAME(STAT_EngineSummaryLLM), -1)\
265 macro(Replays, "Replays", GET_STATFNAME(STAT_ReplaysLLM), GET_STATFNAME(STAT_NetworkingSummaryLLM), ELLMTag::Networking)\
266 macro(MaterialInstance, "MaterialInstance", GET_STATFNAME(STAT_MaterialInstanceLLM), GET_STATFNAME(STAT_EngineSummaryLLM), -1)\
267 macro(SkeletalMesh, "SkeletalMesh", GET_STATFNAME(STAT_SkeletalMeshLLM), GET_STATFNAME(STAT_EngineSummaryLLM), ELLMTag::Meshes)\
268 macro(InstancedMesh, "InstancedMesh", GET_STATFNAME(STAT_InstancedMeshLLM), GET_STATFNAME(STAT_EngineSummaryLLM), ELLMTag::Meshes)\
269 macro(Landscape, "Landscape", GET_STATFNAME(STAT_LandscapeLLM), GET_STATFNAME(STAT_EngineSummaryLLM), ELLMTag::Meshes)\
270 macro(CsvProfiler, "CsvProfiler", GET_STATFNAME(STAT_CsvProfilerLLM), GET_STATFNAME(STAT_EngineSummaryLLM), -1)\
271 macro(MediaStreaming, "MediaStreaming", GET_STATFNAME(STAT_MediaStreamingLLM), GET_STATFNAME(STAT_MediaStreamingSummaryLLM), -1)\
272 macro(ElectraPlayer, "ElectraPlayer", GET_STATFNAME(STAT_ElectraPlayerLLM), GET_STATFNAME(STAT_MediaStreamingSummaryLLM), ELLMTag::MediaStreaming)\
273 macro(WMFPlayer, "WMFPlayer", GET_STATFNAME(STAT_WMFPlayerLLM), GET_STATFNAME(STAT_MediaStreamingSummaryLLM), ELLMTag::MediaStreaming)\
274 macro(PlatformMMIO, "MMIO", GET_STATFNAME(STAT_PlatformMMIOLLM), NAME_None, -1)\
275 macro(PlatformVM, "Virtual Memory", GET_STATFNAME(STAT_PlatformVMLLM), NAME_None, -1)\
276 macro(CustomName, "CustomName", GET_STATFNAME(STAT_CustomName), NAME_None, -1)\
277
278/*
279 * Enum values to be passed in to LLM_SCOPE() macro
280 */
281enum class ELLMTag : LLM_TAG_TYPE
282{
283#define LLM_ENUM(Enum,Str,Stat,Group,Parent) Enum,
285#undef LLM_ENUM
286
288
289 //------------------------------
290 // Platform tags
291 PlatformTagStart = 111,
292 PlatformTagEnd = 149,
293
294 //------------------------------
295 // Project tags
296 ProjectTagStart = 150,
297 ProjectTagEnd = 255,
298
299 // anything above this value is treated as an FName for a stat section
300};
301static_assert( ELLMTag::GenericTagCount <= ELLMTag::PlatformTagStart,
302 "too many LLM tags defined -- Instead of adding a new tag and updating the limits, please use the LLM_DECLARE_TAG macros below");
303
304constexpr inline uint32 LLM_TAG_COUNT = 256;
305constexpr inline uint32 LLM_CUSTOM_TAG_START = (int32)ELLMTag::PlatformTagStart;
306constexpr inline uint32 LLM_CUSTOM_TAG_END = (int32)ELLMTag::ProjectTagEnd;
308
313enum class ELLMAllocType
314{
315 None = 0,
316 FMalloc,
317 System,
318 RHI,
319 Count
320};
321
323extern const TCHAR* LLMGetTagName(ELLMTag Tag);
325/*
326 * LLM utility macros
327 */
328#define LLM(x) x
329#define LLM_IF_ENABLED(x) if (FLowLevelMemTracker::IsEnabled()) { x; }
330#define LLM_IS_ENABLED() FLowLevelMemTracker::IsEnabled()
331#define SCOPE_NAME PREPROCESSOR_JOIN(LLMScope,__LINE__)
332
334// These are the main macros to use externally when tracking memory
336
340#define LLM_SCOPE(Tag) FLLMScope SCOPE_NAME(Tag, false /* bIsStatTag */, ELLMTagSet::None, ELLMTracker::Default);\
341 UE_MEMSCOPE(Tag)
342#define LLM_SCOPE_DYNAMIC(UniqueName, Tracker, TagSet, Constructor) \
343 FLLMScopeDynamic SCOPE_NAME(Tracker, TagSet); \
344 UE_MEMSCOPE_UNINITIALIZED(__LINE__); \
345 do \
346 { \
347 if (SCOPE_NAME.IsEnabled()) \
348 { \
349 FName UniqueNameEvaluated(UniqueName); \
350 if (!UniqueNameEvaluated.IsNone()) \
351 { \
352 if (SCOPE_NAME.TryFindTag(UniqueNameEvaluated)) \
353 { \
354 SCOPE_NAME.Activate(); \
355 } \
356 else \
357 { \
358 SCOPE_NAME.TryAddTagAndActivate(UniqueNameEvaluated, Constructor); \
359 } \
360 constexpr int DefaultTracker = (int)ELLMTracker::Default; \
361 if (TagSet == ELLMTagSet::None && (int)Tracker == DefaultTracker) \
362 { \
363 UE_MEMSCOPE_ACTIVATE(__LINE__, UniqueNameEvaluated); \
364 } \
365 } \
366 } \
367 } while (false) /* do/while is added to require a semicolon */
368
369#define LLM_TAGSET_SCOPE(Tag, TagSet) FLLMScope SCOPE_NAME(Tag, false /* bIsStaTag */, TagSet, ELLMTracker::Default);
370#define LLM_SCOPE_BYNAME(Tag) static FName PREPROCESSOR_JOIN(LLMScope_Name,__LINE__)(Tag);\
371 FLLMScope SCOPE_NAME(PREPROCESSOR_JOIN(LLMScope_Name,__LINE__), false /* bIsStatTag */, ELLMTagSet::None, ELLMTracker::Default);\
372 UE_MEMSCOPE(PREPROCESSOR_JOIN(LLMScope_Name,__LINE__));
373#define LLM_SCOPE_BYTAG(TagDeclName) FLLMScope SCOPE_NAME(PREPROCESSOR_JOIN(LLMTagDeclaration_, TagDeclName).GetUniqueName(), false /* bIsStatTag */, ELLMTagSet::None, ELLMTracker::Default);\
374 UE_MEMSCOPE(PREPROCESSOR_JOIN(LLMTagDeclaration_,TagDeclName).GetUniqueName());
375#define LLM_SCOPE_RENDER_RESOURCE(Tag) static const FString PREPROCESSOR_JOIN(LLMScope_NamePrefix,__LINE__)(TEXT("RenderResources.")); \
376 FName PREPROCESSOR_JOIN(LLMScope_Name,__LINE__)(PREPROCESSOR_JOIN(LLMScope_NamePrefix, __LINE__) + (Tag ? Tag : TEXT("Unknown"))); \
377 FLLMScope SCOPE_NAME(PREPROCESSOR_JOIN(LLMScope_Name,__LINE__), false /* bIsStatTag */, ELLMTagSet::Assets, ELLMTracker::Default, false /* bOverride */);
378#define LLM_PLATFORM_SCOPE(Tag) FLLMScope SCOPE_NAME(Tag, false /* bIsStatTag */, ELLMTagSet::None, ELLMTracker::Platform);
379#define LLM_PLATFORM_SCOPE_BYNAME(Tag) static FName PREPROCESSOR_JOIN(LLMScope_Name,__LINE__)(Tag);\
380 FLLMScope SCOPE_NAME(PREPROCESSOR_JOIN(LLMScope_Name,__LINE__), false /* bIsStatTag */, ELLMTagSet::None, ELLMTracker::Platform);
381#define LLM_PLATFORM_SCOPE_BYTAG(TagDeclName) FLLMScope SCOPE_NAME(PREPROCESSOR_JOIN(LLMTagDeclaration_, TagDeclName).GetUniqueName(), false /* bIsStatTag */, ELLMTagSet::None, ELLMTracker::Platform);
382#define LLM_SCOPE_CLEAR() FLLMClearScope SCOPE_NAME(ELLMTagSet::None, ELLMTracker::Default);\
383 UE_MEMSCOPE(0)
384#define LLM_TAGSET_SCOPE_CLEAR(TagSet) FLLMClearScope SCOPE_NAME(TagSet, ELLMTracker::Default);
385
389#define LLM_SCOPED_PAUSE_TRACKING(AllocType) FLLMPauseScope SCOPE_NAME(ELLMTag::Untagged, false /* bIsStatTag */, 0, ELLMTracker::Max, AllocType);
390#define LLM_SCOPED_PAUSE_TRACKING_FOR_TRACKER(Tracker, AllocType) FLLMPauseScope SCOPE_NAME(ELLMTag::Untagged, false /* bIsStatTag */, 0, Tracker, AllocType);
391#define LLM_SCOPED_PAUSE_TRACKING_WITH_ENUM_AND_AMOUNT(Tag, Amount, Tracker, AllocType) FLLMPauseScope SCOPE_NAME(Tag, false /* bIsStatTag */, Amount, Tracker, AllocType);
392#define LLM_SCOPED_PAUSE_TRACKING_WITH_ENUM_AND_AMOUNT_BYTAG(TagDeclName, Amount, Tracker, AllocType) FLLMPauseScope SCOPE_NAME(PREPROCESSOR_JOIN(LLMTagDeclaration_, TagDeclName).GetUniqueName(), false /* bIsStatTag */, Amount, Tracker, AllocType);
393
397#define LLM_REALLOC_SCOPE(Ptr) FLLMScopeFromPtr SCOPE_NAME(Ptr, ELLMTracker::Default);
398#define LLM_REALLOC_PLATFORM_SCOPE(Ptr) FLLMScopeFromPtr SCOPE_NAME(Ptr, ELLMTracker::Platform);
399
403#define LLM_DUMP_TAG() FLowLevelMemTracker::Get().DumpTag(ELLMTracker::Default,__FILE__,__LINE__)
404#define LLM_DUMP_PLATFORM_TAG() FLowLevelMemTracker::Get().DumpTag(ELLMTracker::Platform,__FILE__,__LINE__)
405
419#define LLM_DEFINE_TAG(UniqueNameWithUnderscores, ...) FLLMTagDeclaration PREPROCESSOR_JOIN(LLMTagDeclaration_, UniqueNameWithUnderscores)(TEXT(#UniqueNameWithUnderscores), ##__VA_ARGS__)
420
434#define LLM_DEFINE_STATIC_TAG(UniqueNameWithUnderscores, ...) static FLLMTagDeclaration PREPROCESSOR_JOIN(LLMTagDeclaration_, UniqueNameWithUnderscores)(TEXT(#UniqueNameWithUnderscores), ##__VA_ARGS__)
435
444#define LLM_DECLARE_TAG(UniqueNameWithUnderscores) extern FLLMTagDeclaration PREPROCESSOR_JOIN(LLMTagDeclaration_, UniqueNameWithUnderscores)
445#define LLM_DECLARE_TAG_API(UniqueNameWithUnderscores, ModuleAPI) extern ModuleAPI FLLMTagDeclaration PREPROCESSOR_JOIN(LLMTagDeclaration_, UniqueNameWithUnderscores)
446
448#define LLM_TAG_NAME(UniqueNameWithUnderscores) (PREPROCESSOR_JOIN(LLMTagDeclaration_, UniqueNameWithUnderscores).GetUniqueName())
449
455#define LLM_DEFINE_BOOTSTRAP_TAG(UniqueNameWithUnderscores, ...) \
456 FLLMTagDeclaration& PREPROCESSOR_JOIN(GetLLMTagDeclaration_, UniqueNameWithUnderscores)() \
457 { \
458 static FLLMTagDeclaration PREPROCESSOR_JOIN(LLMTagDeclaration_, UniqueNameWithUnderscores)(TEXT(#UniqueNameWithUnderscores), ##__VA_ARGS__); \
459 return PREPROCESSOR_JOIN(LLMTagDeclaration_, UniqueNameWithUnderscores); \
460 }
461#define LLM_SCOPE_BY_BOOTSTRAP_TAG(TagDeclName) FLLMScope SCOPE_NAME(PREPROCESSOR_JOIN(GetLLMTagDeclaration_, TagDeclName)().GetUniqueName(), false /* bIsStatTag */, ELLMTagSet::None, ELLMTracker::Default);\
462 UE_MEMSCOPE(PREPROCESSOR_JOIN(GetLLMTagDeclaration_,TagDeclName)().GetUniqueName());
463#define LLM_DECLARE_BOOTSTRAP_TAG(UniqueNameWithUnderscores) extern FLLMTagDeclaration& PREPROCESSOR_JOIN(GetLLMTagDeclaration_, UniqueNameWithUnderscores)();
464#define LLM_DECLARE_BOOTSTRAP_TAG_API(UniqueNameWithUnderscores, ModuleAPI) extern ModuleAPI FLLMTagDeclaration& PREPROCESSOR_JOIN(GetLLMTagDeclaration_, UniqueNameWithUnderscores)();
465
466typedef void*(*LLMAllocFunction)(size_t);
467typedef void(*LLMFreeFunction)(void*, size_t);
468
470
472
473namespace UE::LLMPrivate
474{
475
477class FLLMCsvWriter;
478class FLLMThreadState;
479class FLLMTraceWriter;
480class FLLMTracker;
481class FTagData;
482class FTagDataArray;
483class FTagDataNameMap;
484
485namespace AllocatorPrivate
486{
487 struct FBin;
488 struct FPage;
489}
494class FLLMAllocator
495{
496public:
499
500 static FLLMAllocator*& Get();
501
503 void Clear();
504 void* Alloc(size_t Size);
505 void* Malloc(size_t Size);
506 void Free(void* Ptr, size_t Size);
507 void* Realloc(void* Ptr, size_t OldSize, size_t NewSize);
508 int64 GetTotal() const;
509
510 template <typename T, typename... ArgsType>
511 T* New(ArgsType&&... Args)
512 {
513 T* Ptr = reinterpret_cast<T*>(Alloc(sizeof(T)));
514 new (Ptr) T(Forward<ArgsType>(Args)...);
515 return Ptr;
516 }
517
518 template <typename T>
519 void Delete(T* Ptr)
520 {
521 if (Ptr)
522 {
523 Ptr->~T();
524 Free(Ptr, sizeof(T));
525 }
526 }
527
529 {
530 return PlatformAlloc;
531 }
533 {
534 return PlatformFree;
535 }
536
537private:
538 void* AllocPages(size_t Size);
539 void FreePages(void* Ptr, size_t Size);
540 int32 GetBinIndex(size_t Size) const;
541
545 AllocatorPrivate::FBin* Bins;
546 int64 Total;
547 int32 PageSize;
548 int32 NumBins;
549
550 friend struct UE::LLMPrivate::AllocatorPrivate::FPage;
551 friend struct UE::LLMPrivate::AllocatorPrivate::FBin;
552};
553
554enum class ETagReferenceSource
555{
556 Scope,
557 Declare,
558 EnumTag,
562};
563
565typedef void (*FTagCreationCallback)(const UE::LLMPrivate::FTagData* TagData, UPTRINT UserData);
566
572{
573private:
574 CORE_API static void AddInitialisedCallback(FLLMInitialisedCallback Callback, UPTRINT UserData);
575 // There is no RemoveInitialiseCallback because it is triggered and cleared before Main is called,
576 // there should be no need to remove a callback before then.
577 CORE_API static void AddTagCreationCallback(FTagCreationCallback Callback, UPTRINT UserData);
579
580 friend class ::FTagTrace;
581};
582
583} // UE::LLMPrivate
584
585struct UE_DEPRECATED(4.27, "FLLMCustomTag was an implementation detail that has been modified, switch to FLLMTagInfo or to your own local struct") FLLMCustomTag
586{
587 int32 Tag;
588 const TCHAR* Name;
589 FName StatName;
591};
592
594struct FLLMTagInfo
595{
596 const TCHAR* Name;
597 FName StatName; // shows in the LLMFULL stat group
598 FName SummaryStatName; // shows in the LLM summary stat group
599 int32 ParentTag = -1;
600};
601
604{
605public:
606
608 inline static FLowLevelMemTracker& Get()
609 {
610 if (TrackerInstance)
611 return *TrackerInstance;
612 else
613 return Construct();
614 }
615
617
622 inline static bool IsEnabled();
623
628 CORE_API void ProcessCommandLine(const TCHAR* CmdLine);
629
632
644 CORE_API void OnLowLevelAlloc(ELLMTracker Tracker, const void* Ptr, uint64 Size, ELLMTag DefaultTag = ELLMTag::Untagged,
645 ELLMAllocType AllocType = ELLMAllocType::None, bool bTrackInMemPro = true);
647 ELLMAllocType AllocType = ELLMAllocType::None, bool bTrackInMemPro = true);
648
658 CORE_API void OnLowLevelFree(ELLMTracker Tracker, const void* Ptr,
659 ELLMAllocType AllocType = ELLMAllocType::None, bool bTrackInMemPro = true);
660
672
674 CORE_API void OnLowLevelAllocMoved(ELLMTracker Tracker, const void* Dest, const void* Source,
675 ELLMAllocType AllocType = ELLMAllocType::None);
676
678 CORE_API void UpdateStatsPerFrame(const TCHAR* LogName=nullptr);
680 CORE_API void Tick();
681
683 CORE_API void SetProgramSize(uint64 InProgramSize);
684
686 CORE_API bool Exec(const TCHAR* Cmd, FOutputDevice& Ar);
687
690
693
695 CORE_API const UE::LLMPrivate::FTagData* GetActiveTagData(ELLMTracker Tracker, ELLMTagSet TagSet = ELLMTagSet::None);
696
698 CORE_API void RegisterPlatformTag(int32 Tag, const TCHAR* Name, FName StatName, FName SummaryStatName, int32 ParentTag = -1);
699 CORE_API void RegisterProjectTag(int32 Tag, const TCHAR* Name, FName StatName, FName SummaryStatName, int32 ParentTag = -1);
700
703
706
709
711 CORE_API bool FindTagByName(const TCHAR* Name, uint64& OutTag, ELLMTagSet InTagSet = ELLMTagSet::None) const;
712
713 UE_DEPRECATED(4.27, "Use FindTagDisplayName instead")
714 CORE_API const TCHAR* FindTagName(uint64 Tag) const;
715
718 CORE_API FName FindPtrDisplayName(void* Ptr) const;
719
721 CORE_API FName GetTagDisplayName(const UE::LLMPrivate::FTagData* TagData) const;
722
724 CORE_API FString GetTagDisplayPathName(const UE::LLMPrivate::FTagData* TagData) const;
725 CORE_API void GetTagDisplayPathName(const UE::LLMPrivate::FTagData* TagData,
727
729 CORE_API FName GetTagUniqueName(const UE::LLMPrivate::FTagData* TagData) const;
730
732 CORE_API const UE::LLMPrivate::FTagData* GetTagParent(const UE::LLMPrivate::FTagData* TagData) const;
733
735 CORE_API bool GetTagIsEnumTag(const UE::LLMPrivate::FTagData* TagData) const;
736
741 CORE_API ELLMTag GetTagClosestEnumTag(const UE::LLMPrivate::FTagData* TagData) const;
742
745
748
750
753
756
758 CORE_API uint64 DumpTag(ELLMTracker Tracker, const char* FileName, int LineNumber);
759
762
763 enum class EDumpFormat
764 {
765 PlainText,
766 CSV,
767 };
768 CORE_API void DumpToLog(EDumpFormat DumpFormat = EDumpFormat::PlainText, FOutputDevice* OutputDevice = nullptr, UE::LLM::ESizeParams SizeParams = UE::LLM::ESizeParams::Default, ELLMTagSet TagSet = ELLMTagSet::None);
769
770 CORE_API void OnPreFork();
771
773 {
774 return bFullyInitialised;
775 }
776
778 {
780 }
781
790
798
799private:
800 enum class EEnabled : uint8
801 {
802 NotYetKnown = 0,
803 Disabled,
804 Enabled,
805 };
807
808private:
810
812
813 bool IsBootstrapping() const { return bIsBootstrapping; }
814
816 void Clear();
818
819 class UE::LLMPrivate::FLLMTracker* GetTracker(ELLMTracker Tracker);
820 const class UE::LLMPrivate::FLLMTracker* GetTracker(ELLMTracker Tracker) const;
821
822 void TickInternal();
823 void UpdateTags();
824 void SortTags(UE::LLMPrivate::FTagDataArray*& OutOldTagDatas);
825 void PublishDataPerFrame(const TCHAR* LogName);
826
827 void RegisterCustomTagInternal(int32 Tag, ELLMTagSet TagSet, const TCHAR* Name, FName StatName, FName SummaryStatName, int32 ParentTag = -1);
832 void BootstrapTagDatas();
835 void InitialiseTagDatas();
836 void ClearTagDatas();
838 UE::LLMPrivate::FTagData& RegisterTagData(FName Name, FName DisplayName, FName ParentName, FName StatName, FName SummaryStatName, bool bHasEnumTag, ELLMTag EnumTag, bool bIsStatTag, UE::LLMPrivate::ETagReferenceSource ReferenceSource, ELLMTagSet TagSet = ELLMTagSet::None);
840 void FinishConstruct(UE::LLMPrivate::FTagData* TagData, UE::LLMPrivate::ETagReferenceSource ReferenceSource);
841 void ReportDuplicateTagName(UE::LLMPrivate::FTagData* TagData, UE::LLMPrivate::ETagReferenceSource ReferenceSource);
842
843 const UE::LLMPrivate::FTagData* FindOrAddTagData(ELLMTag EnumTag, UE::LLMPrivate::ETagReferenceSource ReferenceSource = UE::LLMPrivate::ETagReferenceSource::FunctionAPI);
844 const UE::LLMPrivate::FTagData* FindOrAddTagData(FName Name, ELLMTagSet TagSet, bool bIsStatData=false, UE::LLMPrivate::ETagReferenceSource ReferenceSource = UE::LLMPrivate::ETagReferenceSource::FunctionAPI);
845 const UE::LLMPrivate::FTagData* FindOrAddTagData(FName Name, ELLMTagSet TagSet, FName StatName, UE::LLMPrivate::ETagReferenceSource ReferenceSource = UE::LLMPrivate::ETagReferenceSource::FunctionAPI);
846 const UE::LLMPrivate::FTagData* FindTagData(ELLMTag EnumTag, UE::LLMPrivate::ETagReferenceSource ReferenceSource = UE::LLMPrivate::ETagReferenceSource::FunctionAPI);
847 const UE::LLMPrivate::FTagData* FindTagData(FName Name, ELLMTagSet TagSet, UE::LLMPrivate::ETagReferenceSource ReferenceSource = UE::LLMPrivate::ETagReferenceSource::FunctionAPI);
848
858
859 friend class FLLMPauseScope;
860 friend class FLLMScope;
861 friend class FLLMScopeDynamic;
862 friend class FLLMScopeFromPtr;
863 friend class UE::LLMPrivate::FLLMCsvWriter;
864 friend class UE::LLMPrivate::FLLMTracker;
865 friend class UE::LLMPrivate::FLLMThreadState;
866 friend class UE::LLMPrivate::FLLMTraceWriter;
867 friend class UE::LLMPrivate::FLLMCsvProfilerWriter;
869
870private:
871 UE::LLMPrivate::FLLMAllocator Allocator;
873 UE::LLMPrivate::FTagDataArray* TagDatas;
875 UE::LLMPrivate::FTagDataNameMap* TagDataNameMap;
877 UE::LLMPrivate::FTagData** TagDataEnumMap;
878
879 UE::LLMPrivate::FLLMTracker* Trackers[static_cast<int32>(ELLMTracker::Max)];
880
882 UE::FPlatformRecursiveMutex UpdateMutex;
884
885 uint64 ProgramSize;
888
889 bool ActiveSets[(int32)ELLMTagSet::Max];
890
892 bool bCanEnable;
896 bool bIsBootstrapping;
897 bool bBeganInitialisedTracking = false;
899 std::atomic<bool> bConfigurationComplete;
900 bool bTagAdded;
901 bool bAutoPublish;
904
906 static CORE_API EEnabled EnabledState;
907public:
908 UE_DEPRECATED(5.5, "Use IsEnabled instead.")
910};
911
913class FLLMScope
914{
915public:
916 CORE_API explicit FLLMScope(FName TagName, bool bIsStatTag, ELLMTagSet InTagSet, ELLMTracker InTracker, bool bOverride = true);
917 CORE_API explicit FLLMScope(ELLMTag TagEnum, bool bIsStatTag, ELLMTagSet InTagSet, ELLMTracker InTracker, bool bOverride = true);
918 CORE_API explicit FLLMScope(const UE::LLMPrivate::FTagData* TagData, bool bIsStatTag, ELLMTagSet InTagSet, ELLMTracker InTracker, bool bOverride = true);
920
921protected:
922 CORE_API void Destruct();
923
924 // All fields other than bEnabled are not initialized by constructor unless bEnabled is true
926 bool bEnabled = false; // Needs to be a uint8 rather than a bitfield to minimize ALU operations
927 ELLMTagSet TagSet;
928};
929
935{
936public:
937 virtual ~ILLMDynamicTagConstructor() = default;
938 virtual FString GetStatName() const
939 {
940 return FString();
941 }
942 virtual bool NeedsStatConstruction() const
943 {
944 return true;
945 }
946};
947
950{
951public:
953 virtual FString GetStatName() const override { return StatName; }
954 FString StatName;
955};
956
964{
965public:
967 {
968 if (FLowLevelMemTracker::IsEnabled())
969 {
971 }
972 }
973 bool IsEnabled() const { return bEnabled; }
974 CORE_API bool TryFindTag(FName UniqueName); // Set name separately so the calculation of name can be skipped if TagSet is disabled
976 CORE_API void Activate();
977
979 {
980 if (bEnabled)
981 {
982 Destruct();
983 }
984 }
985
986protected:
988 CORE_API void Destruct();
989
990 // All fields other than bEnabled are not initialized by constructor unless bEnabled is true
991 const UE::LLMPrivate::FTagData* TagData;
993 bool bEnabled = false; // Needs to be a uint8 rather than a bitfield to minimize ALU operations
994 ELLMTagSet TagSet;
995};
996
998class FLLMPauseScope
999{
1000public:
1004protected:
1005 CORE_API void Init(FName TagName, ELLMTag EnumTag, bool bIsEnumTag, bool bIsStatTag, uint64 Amount,
1009 bool bEnabled;
1010};
1011
1013class FLLMClearScope : public FLLMScope
1014{
1015public:
1017};
1018
1020class FLLMScopeFromPtr
1021{
1022public:
1025protected:
1027 bool bEnabled[static_cast<int32>(ELLMTagSet::Max)];
1028
1029private:
1030 inline void DisableAll()
1031 {
1032 FMemory::Memzero(bEnabled);
1033 }
1034};
1035
1038{
1039public:
1041 FName GetUniqueName() const { return UniqueName; }
1042
1044protected:
1045
1047 static CORE_API void ClearCreationCallbacks();
1050
1051 CORE_API void Register();
1052
1053protected:
1055
1056 const TCHAR* CPPName;
1057 FName UniqueName;
1060 FName StatName;
1062 ELLMTagSet TagSet;
1063 FLLMTagDeclaration* Next = nullptr;
1064
1065 friend class FLowLevelMemTracker;
1066};
1067
1070{
1072 FName Name;
1074 ELLMTagSet TagSet;
1075};
1076
1077inline bool FLowLevelMemTracker::IsEnabled()
1078{
1079 return EnabledState != EEnabled::Disabled;
1080}
1081
1082#else
1083
1084#ifndef LLM_ALLOW_ASSETS_TAGS
1085 #define LLM_ALLOW_ASSETS_TAGS 0
1086#endif
1087
1088#ifndef LLM_ALLOW_UOBJECTCLASSES_TAGS
1089 #define LLM_ALLOW_UOBJECTCLASSES_TAGS 0
1090#endif
1091
1092#define LLM(...)
1093#define LLM_IF_ENABLED(...)
1094#define LLM_IS_ENABLED() false
1095#define LLM_SCOPE(...)
1096#define LLM_SCOPE_DYNAMIC(...)
1097#define LLM_TAGSET_SCOPE(...)
1098#define LLM_SCOPE_BYNAME(...)
1099#define LLM_SCOPE_BYTAG(...)
1100#define LLM_SCOPE_RENDER_RESOURCE(...)
1101#define LLM_PLATFORM_SCOPE(...)
1102#define LLM_PLATFORM_SCOPE_BYNAME(...)
1103#define LLM_PLATFORM_SCOPE_BYTAG(...)
1104#define LLM_SCOPE_CLEAR()
1105#define LLM_TAGSET_SCOPE_CLEAR(...)
1106#define LLM_REALLOC_SCOPE(...)
1107#define LLM_REALLOC_PLATFORM_SCOPE(...)
1108#define LLM_SCOPED_PAUSE_TRACKING(...)
1109#define LLM_SCOPED_PAUSE_TRACKING_FOR_TRACKER(...)
1110#define LLM_SCOPED_PAUSE_TRACKING_WITH_ENUM_AND_AMOUNT(...)
1111#define LLM_SCOPED_PAUSE_TRACKING_WITH_ENUM_AND_AMOUNT_BYTAG(...)
1112#define LLM_DUMP_TAG()
1113#define LLM_DUMP_PLATFORM_TAG()
1114#define LLM_DEFINE_TAG(...)
1115#define LLM_DEFINE_STATIC_TAG(...)
1116#define LLM_DECLARE_TAG(...)
1117#define LLM_DECLARE_TAG_API(...)
1118#define LLM_DEFINE_BOOTSTRAP_TAG(...)
1119#define LLM_SCOPE_BY_BOOTSTRAP_TAG(...)
1120#define LLM_DECLARE_BOOTSTRAP_TAG(...)
1121#define LLM_DECLARE_BOOTSTRAP_TAG_API(...)
1122
1123#endif // #if ENABLE_LOW_LEVEL_MEM_TRACKER
OODEFFUNC typedef void(OODLE_CALLBACK t_fp_OodleCore_Plugin_Free)(void *ptr)
#define UE_DEPRECATED(Version, Message)
Definition CoreMiscDefines.h:302
FPlatformTypes::TCHAR TCHAR
Either ANSICHAR or WIDECHAR, depending on whether the platform supports wide characters or the requir...
Definition Platform.h:1135
FPlatformTypes::int64 int64
A 64-bit signed integer.
Definition Platform.h:1127
FPlatformTypes::int32 int32
A 32-bit signed integer.
Definition Platform.h:1125
FPlatformTypes::UPTRINT UPTRINT
An unsigned integer the same size as a pointer.
Definition Platform.h:1146
#define UE_FORCEINLINE_HINT
Definition Platform.h:723
FPlatformTypes::ANSICHAR ANSICHAR
An ANSI character. Normally a signed type.
Definition Platform.h:1131
FPlatformTypes::uint64 uint64
A 64-bit unsigned integer.
Definition Platform.h:1117
UE_FORCEINLINE_HINT TSharedRef< CastToType, Mode > StaticCastSharedRef(TSharedRef< CastFromType, Mode > const &InSharedRef)
Definition SharedPointer.h:127
#define ENUM_CLASS_FLAGS(Enum)
Definition EnumClassFlags.h:6
bool ProcessCommandLine()
Definition LaunchWindows.cpp:147
void Init()
Definition LockFreeList.h:4
#define LLM(...)
Definition LowLevelMemTracker.h:1092
T * New(FMemStackBase &Mem, int32 Count=1, int32 Align=DEFAULT_ALIGNMENT)
Definition MemStack.h:259
void Construct(const FArguments &InArgs)
UE_INTRINSIC_CAST UE_REWRITE constexpr std::remove_reference_t< T > && MoveTemp(T &&Obj) noexcept
Definition UnrealTemplate.h:520
uint32 Size
Definition VulkanMemory.cpp:4034
uint8_t uint8
Definition binka_ue_file_header.h:8
uint32_t uint32
Definition binka_ue_file_header.h:6
Definition MemoryBase.h:99
Definition NameTypes.h:617
Definition OutputDevice.h:133
Definition RHI.Build.cs:8
Definition ArrayView.h:139
Definition Array.h:670
Definition UnrealString.h.inl:34
bool IsEnabled()
Definition IAudioLinkFactory.cpp:13
const FStructTracker ** GetTracker(const uint32 SerializationHash)
Definition StructTypeBitSet.cpp:29
void * Alloc(int size)
void Initialise(bool wait_for_connect=false)
UE::FRecursiveMutex Mutex
Definition MeshPaintVirtualTexture.cpp:164
FORCEINLINE T * Get(const FObjectPtr &ObjectPtr)
Definition ObjectPtr.h:426
void Destruct(void *Dest)
Definition Class.h:1265
Definition ParallelFor.h:40
Definition AdvancedWidgetsModule.cpp:13
FPThreadsRecursiveMutex FPlatformRecursiveMutex
Definition AndroidPlatformMutex.h:12
FPThreadsSharedMutex FPlatformSharedMutex
Definition AndroidPlatformMutex.h:13
@ Exec
This function is executable from the command line.
Definition ObjectMacros.h:962
@ DisplayName
[ClassMetadata] [PropertyMetadata] [FunctionMetadata] The name to display for this class,...
Definition ObjectMacros.h:1240
static UE_FORCEINLINE_HINT void * Memzero(void *Dest, SIZE_T Count)
Definition UnrealMemory.h:131