Ark Server API (ASA) - Wiki
Loading...
Searching...
No Matches
MallocCallstackHandler.h
Go to the documentation of this file.
1// Copyright Epic Games, Inc. All Rights Reserved.
2
3#pragma once
4
5#include "Containers/Array.h"
6#include "Containers/Map.h"
7#include "CoreTypes.h"
8#include "HAL/CriticalSection.h"
9#include "HAL/MemoryBase.h"
10#include "HAL/PlatformTLS.h"
11#include "Misc/Crc.h"
12
14
16{
17public:
19
20 /**
21 * Malloc
22 */
23 virtual void* Malloc(SIZE_T Count, uint32 Alignment = DEFAULT_ALIGNMENT) override;
24
25 /**
26 * Realloc
27 */
28 virtual void* Realloc(void* Original, SIZE_T Count, uint32 Alignment = DEFAULT_ALIGNMENT) override;
29
30 /**
31 * Free
32 */
33 virtual void Free(void* Original) override;
34
35 /**
36 * For some allocators this will return the actual size that should be requested to eliminate
37 * internal fragmentation. The return value will always be >= Count. This can be used to grow
38 * and shrink containers to optimal sizes.
39 * This call is always fast and thread safe with no locking.
40 */
41 virtual SIZE_T QuantizeSize(SIZE_T Count, uint32 Alignment) override
42 {
43 return UsedMalloc->QuantizeSize(Count, Alignment);
44 }
45
46 /**
47 * If possible determine the size of the memory allocated at the given address
48 *
49 * @param Original - Pointer to memory we are checking the size of
50 * @param SizeOut - If possible, this value is set to the size of the passed in pointer
51 * @return true if succeeded
52 */
53 virtual bool GetAllocationSize(void *Original, SIZE_T &SizeOut) override
54 {
55 return UsedMalloc->GetAllocationSize(Original, SizeOut);
56 }
57
58 /**
59 * Releases as much memory as possible. Must be called from the main thread.
60 */
61 virtual void Trim(bool bTrimThreadCaches) override
62 {
63 UsedMalloc->Trim(bTrimThreadCaches);
64 }
65
66 /**
67 * Set up TLS caches on the current thread. These are the threads that we can trim.
68 */
69 virtual void SetupTLSCachesOnCurrentThread() override
70 {
72 }
73
74 /**
75 * Clears the TLS caches on the current thread and disables any future caching.
76 */
78 {
80 }
81
82 /**
83 * Initializes stats metadata. We need to do this as soon as possible, but cannot be done in the constructor
84 * due to the FName::StaticInit
85 */
86 virtual void InitializeStatsMetadata() override
87 {
89 }
90
91 /** Called once per frame, gathers and sets all memory allocator statistics into the corresponding stats. MUST BE THREAD SAFE. */
92 virtual void UpdateStats() override
93 {
95 }
96
97 /** Writes allocator stats from the last update into the specified destination. */
98 virtual void GetAllocatorStats(FGenericMemoryStats& out_Stats) override
99 {
101 }
102
103 /** Dumps current allocator stats to the log. */
104 virtual void DumpAllocatorStats(class FOutputDevice& Ar) override
105 {
107 }
108
109 /**
110 * Returns if the allocator is guaranteed to be thread-safe and therefore
111 * doesn't need a unnecessary thread-safety wrapper around it.
112 */
113 virtual bool IsInternallyThreadSafe() const override
114 {
115 return true;
116 }
117
118 /**
119 * Validates the allocator's heap
120 */
121 virtual bool ValidateHeap() override
122 {
124 }
125
126 /**
127 * Gets descriptive name for logging purposes.
128 *
129 * @return pointer to human-readable malloc name
130 */
131 virtual const TCHAR* GetDescriptiveName() override
132 {
134 }
135
136 virtual void OnMallocInitialized() override
137 {
139 }
140
141 virtual void OnPreFork() override
142 {
144 }
145
146 virtual void OnPostFork() override
147 {
149 }
150
151 static constexpr SIZE_T MaxCallStackDepth = 64;
152 static constexpr SIZE_T CallStackEntriesToSkipCount = 2;
153
155 {
156 uint32 Count;
158 };
159
160 /** Used as a key in our current allocations/freed allocations maps*/
162 {
163 uint32 CRC;
164 uint64* CallStack;
165
166 FCallStackMapKey(uint64* InCallStack)
167 : CallStack(InCallStack)
168 {
169 CRC = FCrc::MemCrc32(InCallStack, MaxCallStackDepth * sizeof(uint64));
170 }
171
172 friend bool operator==(const FCallStackMapKey& A, const FCallStackMapKey& B)
173 {
174 if (A.CRC != B.CRC)
175 {
176 return false;
177 }
178 for (int i = 0; i < MaxCallStackDepth; ++i)
179 {
180 uint64 APtr = A.CallStack[i];
181 uint64 BPtr = B.CallStack[i];
182 if (APtr != BPtr)
183 {
184 return false;
185 }
186 if (APtr == 0)
187 break;
188 }
189 return true;
190 }
191
192 friend inline uint32 GetTypeHash(const FCallStackMapKey& InKey)
193 {
194 return InKey.CRC;
195 }
196 };
197
198 virtual void Init();
199 void DumpStackTraceToLog(int32 StackIndex);
200
202
203protected:
204 /** Malloc we're based on, aka using under the hood */
209
211 {
212 uint64_t DisabledCount = (uint64_t)FPlatformTLS::GetTlsValue(DisabledTLS);
213 ++DisabledCount;
214 FPlatformTLS::SetTlsValue(DisabledTLS, (void*)DisabledCount);
215 }
216
218 {
219 uint64_t DisabledCount = (uint64_t)FPlatformTLS::GetTlsValue(DisabledTLS);
220 --DisabledCount;
221 FPlatformTLS::SetTlsValue(DisabledTLS, (void*)DisabledCount);
222 }
223 virtual bool IsDisabled()
224 {
226 }
227
228 virtual void TrackRealloc(void* OldPtr, void* NewPtr, uint32 NewSize, uint32 OldSize, int32 CallStackIndex);
229 virtual void TrackMalloc(void* Ptr, uint32 Size, int32 CallStackIndex) = 0;
230 virtual void TrackFree(void* Ptr, uint32 OldSize, int32 CallStackIndex) = 0;
231
233
236
237 virtual int32 GetCallStackIndex();
238};
239
241
242/**
243 * Disables the callstack handler for the current thread
244 * Need to do this as we might allocate memory for the allocators tracking data, that can't be tracked!
245 */
246
248{
249public:
250
252 {
254 }
255
257 {
259 }
260};
FMallocCallstackHandler * GMallocCallstackHandler
@ DEFAULT_ALIGNMENT
Definition MemoryBase.h:24
#define FORCEINLINE
Definition Platform.h:644
FWindowsCriticalSection FCriticalSection
FWindowsRWLock FRWLock
FWindowsPlatformTLS FPlatformTLS
virtual void * Realloc(void *Original, SIZE_T Count, uint32 Alignment=DEFAULT_ALIGNMENT) override
virtual void Free(void *Original) override
static constexpr SIZE_T MaxCallStackDepth
virtual void InitializeStatsMetadata() override
FMallocCallstackHandler(FMalloc *InMalloc)
virtual void * Malloc(SIZE_T Count, uint32 Alignment=DEFAULT_ALIGNMENT) override
virtual bool ValidateHeap() override
virtual bool GetAllocationSize(void *Original, SIZE_T &SizeOut) override
virtual void TrackRealloc(void *OldPtr, void *NewPtr, uint32 NewSize, uint32 OldSize, int32 CallStackIndex)
virtual void TrackFree(void *Ptr, uint32 OldSize, int32 CallStackIndex)=0
virtual void SetupTLSCachesOnCurrentThread() override
virtual void OnMallocInitialized() override
virtual void UpdateStats() override
virtual void GetAllocatorStats(FGenericMemoryStats &out_Stats) override
virtual int32 GetCallStackIndex()
void DumpStackTraceToLog(int32 StackIndex)
virtual void ClearAndDisableTLSCachesOnCurrentThread() override
virtual void OnPostFork() override
virtual void Trim(bool bTrimThreadCaches) override
virtual void DumpAllocatorStats(class FOutputDevice &Ar) override
TMap< FCallStackMapKey, int32 > CallStackMapKeyToCallStackIndexMap
static constexpr SIZE_T CallStackEntriesToSkipCount
virtual bool IsInternallyThreadSafe() const override
virtual void OnPreFork() override
virtual void TrackMalloc(void *Ptr, uint32 Size, int32 CallStackIndex)=0
virtual SIZE_T QuantizeSize(SIZE_T Count, uint32 Alignment) override
virtual const TCHAR * GetDescriptiveName() override
TArray< FCallStackInfo > CallStackInfoArray
virtual const TCHAR * GetDescriptiveName()
Definition MemoryBase.h:208
virtual void UpdateStats()
virtual void OnMallocInitialized()
Definition MemoryBase.h:216
virtual void OnPreFork()
Definition MemoryBase.h:221
virtual bool GetAllocationSize(void *Original, SIZE_T &SizeOut)
Definition MemoryBase.h:133
virtual bool ValidateHeap()
Definition MemoryBase.h:198
virtual void SetupTLSCachesOnCurrentThread()
Definition MemoryBase.h:148
virtual void GetAllocatorStats(FGenericMemoryStats &out_Stats)
virtual void DumpAllocatorStats(class FOutputDevice &Ar)
Definition MemoryBase.h:181
virtual void Trim(bool bTrimThreadCaches)
Definition MemoryBase.h:141
virtual void OnPostFork()
Definition MemoryBase.h:226
virtual void InitializeStatsMetadata()
virtual void ClearAndDisableTLSCachesOnCurrentThread()
Definition MemoryBase.h:155
virtual SIZE_T QuantizeSize(SIZE_T Count, uint32 Alignment)
Definition MemoryBase.h:121
friend bool operator==(const FCallStackMapKey &A, const FCallStackMapKey &B)
friend uint32 GetTypeHash(const FCallStackMapKey &InKey)
static FORCEINLINE void * GetTlsValue(uint32 SlotIndex)
static FORCEINLINE void SetTlsValue(uint32 SlotIndex, void *Value)