OROCHI
 
Loading...
Searching...
No Matches
GxAllocatorHeap.h
Go to the documentation of this file.
1//===========================================================================
10//===========================================================================
11#pragma once
12
13GX_CORE_NAMESPACE_BEGIN()
14class GxList;
15//===========================================================================
17//===========================================================================
19{
20 //-----------------------------------------------------------
22 //-----------------------------------------------------------
24public:
25 // RTTI定義
26 GX_RTTI_CLASS(GxAllocatorHeap, GxAllocator)
27 // ClassBase継承クラス用禁止宣言
29
30private:
31 static constexpr u32 HEAP_SHIFT = 4;
32 static constexpr u32 BLOCK_SIZE = (1 << HEAP_SHIFT);
33 static constexpr u32 HASH_TABLE_THRESHOLD= 16;
34 static constexpr u32 HASH_TABLE_NUM = 40;
35 static constexpr u32 HEAP_MAGIC_NUMBER = GX_FOURCC('h','e','a','p');
36
37public:
39 enum class ALLOCATE_TYPE
40 {
41 FAST = 0,
42 HEAD,
43 TAIL,
44
45 MAX
46 };
47
49 //
50 // ポインタ ヘッダサイズ ビルド
51 // 32bit 48byte Develop
52 // 32bit 48byte Master
53 // 64bit 80byte Develop
54 // 64bit 64byte Master
56 {
57 //-----------------------------------------------------------
59 //-----------------------------------------------------------
61 public:
63 void initialize(GxAllocatorHeap* pAllocator, u32 usedSize, u32 freeSize, u32 alignmentSize, u32 alignment)
64 {
65 GX_MEMSET(this, 0, sizeof(GxHeapInformation));
66 _magic = HEAP_MAGIC_NUMBER;
67 _pAllocator = pAllocator;
68 _alignment = static_cast<GxMemory::ALIGNMENT>(alignment);
69 _usedBlock = GxAllocatorHeap::getBlockFromSize(usedSize);
70 _freeBlock = GxAllocatorHeap::getBlockFromSize(freeSize);
71 _alignmentBlock = static_cast<u16>(GxAllocatorHeap::getBlockFromSize(alignmentSize));
72 }
73
75 //-----------------------------------------------------------
77 //-----------------------------------------------------------
79
81 b32 isHead(void) const { return !_pPrevious; }
83 b32 isTail(void) const { return !_pNext; }
84
85#if GX_DEVELOP
87 void setAnnotation(GX_CSTR name);
89 GX_CSTR getAnnotation(void) const;
91 u32 getAnnotationLength(void) const;
94 GX_CSTR getFilename(GX_STR buffer, u32 bufferSize) const;
97 GX_CSTR getName(GX_STR buffer, u32 bufferSize) const;
98#endif // GX_DEVELOP
99
101 //-----------------------------------------------------------
103 //-----------------------------------------------------------
105
106 u32 _magic;
112#if GX_DEVELOP
113 // デバッグ用データ
114 u16 _line;
115 void** _ppDebugData;
116 u32 _serialNumber;
117#if defined(_WINDOWS) || defined(_PS4) || defined(_PS5) || defined(_XBOX_XS)
118 // 64bit OS (_pad を入れなくてもBLOCK_SIZEにアラインされている)
119 u16 _callStackMax;
120#endif //_WINDOWS || _PS4 || _PS5 || _XBOX_XS
121#else // GX_DEVELOP
122#if defined(_NX64)
123 // 32bit OS
124 u16 _pad[5];
125#endif //_NX64
126#endif // !GX_DEVELOP
131
133 };
134
136 //-----------------------------------------------------------
138 //-----------------------------------------------------------
140protected:
142 GxAllocatorHeap(void) : _pHeapTop(nullptr), _pHeapLast(nullptr){ GX_MEMSET(_freeTop, 0, sizeof(GxHeapInformation) * (HASH_TABLE_NUM + 1)); }
144 GxAllocatorHeap(GX_CSTR name);
145
146public:
148 GxAllocatorHeap(GX_CSTR name, GxMemory::TYPE type, u32 size);
150 GxAllocatorHeap(GX_CSTR name, void* pAddress, u32 size);
152 ~GxAllocatorHeap(void);
153
155 static GxAllocatorHeap* create(GX_CSTR name, void* pAddress, u32 size);
157 static void destroy(GxAllocatorHeap*& pAllocator);
158
159protected:
161 void initialize(void* pAddress, u32 size);
162
164 //-----------------------------------------------------------
166 //-----------------------------------------------------------
168public:
169#if GX_DEBUG_NEW
171 void* allocateMemory(u32 type, u32 size, GX_CSTR filename, u32 line, GxMemory::ALIGNMENT alignment = GxMemory::ALIGNMENT::_16) override;
173 void freeMemory(void* pAddress, GX_CSTR filename, u32 line) override;
175 void* reallocMemory(void* pAddress, u32 size, GX_CSTR filename, u32 line) override;
177 void allocateDummyMemory(void);
179 void freeDummyMemory(void);
180#else // GX_DEBUG_NEW
182 void* allocateMemory(u32 type, u32 size, GxMemory::ALIGNMENT alignment = GxMemory::ALIGNMENT::_16) override;
184 void freeMemory(void* pAddress) override;
186 void* reallocMemory(void* pAddress, u32 size) override;
187#endif // !GX_DEBUG_NEW
188
189public:
190#if GX_DEVELOP
192 void printInformation(void) override;
194 constexpr void setDebugAllocator(GxAllocatorHeap* pAllocator) { _pDebugAllocator = pAllocator; }
196 static void traceCallStackAddToString(const GxHeapInformation* pHeapInformation, GxString& message);
198 static void traceCallStack(const GxHeapInformation* pHeapInformation);
201 void dumpToCsv(void);
202#endif // GX_DEVELOP
204 b32 isValid(void);
206 b32 isValid(const GxHeapInformation* pHeapInformation) const;
207
208protected:
209#if GX_DEVELOP
211 void traceAllocateInformation(const void* pAddress, u32 size, GX_CSTR filename = nullptr, u32 line = 0) const override;
213 void traceFreeInformation(const void* pAddress, GX_CSTR filename = nullptr, u32 line = 0) const override;
214#endif // GX_DEVELOP
215
216#if GX_DEBUG_NEW
218 void* allocateMemoryFastDebug(u32 size, GX_CSTR filename, u32 line, GxMemory::ALIGNMENT alignment);
220 void* allocateMemoryForwardDebug(u32 size, GX_CSTR filename, u32 line, GxMemory::ALIGNMENT alignment);
222 void* allocateMemoryBackDebug(u32 size, GX_CSTR filename, u32 line, GxMemory::ALIGNMENT alignment);
223#endif // GX_DEBUG_NEW
225 void* allocateMemoryFast(u32 size, GxMemory::ALIGNMENT alignment);
227 void* allocateMemoryForward(u32 size, GxMemory::ALIGNMENT alignment);
229 void* allocateMemoryBack(u32 size, GxMemory::ALIGNMENT alignment);
230
232 void insertHeap(GxHeapInformation* pBaseHeap, GxHeapInformation* pInsertHeap);
234 void linkFreeHeapList(GxHeapInformation* pFreeHeap);
236 u32 getHashValue(u32 value) const;
239
240#if GX_DEVELOP
242 void allocateDebugData(GxHeapInformation* pHeapInformation);
244 void freeDebugData(GxHeapInformation* pHeapInformation);
246 void addHeapDebugInformation(GxHeapInformation* pAddress, u32 serialNumber, GX_CSTR filename = nullptr, u32 line = 0);
248 void checkMemoryLeak(void);
249#endif // GX_DEVELOP
250
252 //-----------------------------------------------------------
254 //-----------------------------------------------------------
256public:
258 constexpr u32 getUsedSize(void) const { return _usedSize; }
260 u32 getFreeMax(void) const;
262 u32 getMaxAvailableSize(GxMemory::ALIGNMENT alignment = GxMemory::ALIGNMENT::_16) const;
264 constexpr GxHeapInformation* getHeapTop(void) const { return _pHeapTop; }
265
266#if GX_DEVELOP
268 constexpr u32 getUsedSizeMax(void) const { return _usedSizeMax; }
270 constexpr void clearUsedSizeMax(void) { _usedSizeMax = _usedSize; }
272 constexpr void setCallStackMax(u32 count) { _callStackMax = count; }
274 constexpr u32 getCallStackMax(void) const { return _callStackMax; }
276 GX_FORCE_INLINE void updateMaxAvailableSize(void) { _maxFreeSize = getMaxAvailableSize(); }
278 constexpr u32 getWalkFreeMax(void) const { return _walkFreeMax; }
280 constexpr void setUsedSizeDiff(void) { _usedSizeSave = _usedSize; }
282 constexpr s32 getUsedSizeDiff(void) const { return static_cast<s32>(static_cast<s64>(_usedSize) - static_cast<s64>(_usedSizeSave)); }
284 constexpr u32 getSerialNumber(void) const { return _serialNumber; }
285#endif // GX_DEVELOP
286
288 static void* getMemoryPointer(const GxAllocatorHeap::GxHeapInformation* pHeapInformation);
290 static GxHeapInformation* getHeaderPointer(void* pAddress);
292 static u32 getBlockFromSize(u32 size);
294 static u32 getSizeFromBlock(u32 block);
296 static u32 getHeaderSize(void);
297
298public:
299#if GX_DEVELOP
301 void getPropertyUsedSizeDiff(void* const pValue) const { *static_cast<s32*>(pValue) = getUsedSizeDiff(); }
302#endif // GX_DEVELOP
303
305 //-----------------------------------------------------------
307 //-----------------------------------------------------------
309private:
310 GxHeapInformation* _pHeapTop;
311 GxHeapInformation* _pHeapLast;
312 GxHeapInformation _freeTop[HASH_TABLE_NUM + 1];
313 u32 _usedSize;
314 b32 _isBufferAllocated;
315#if GX_DEVELOP
316 u32 _usedSizeMax;
317 u32 _maxFreeSize;
318 u32 _serialNumber;
319 u32 _assertSerialNumber;
320 u32 _callStackMax;
321 u32 _allocateDummyMemorySize;
322 GxList _dummyHeapList;
323 GxAllocatorHeap* _pDebugAllocator;
324 u32 _walkFreeMax;
325 u32 _usedSizeSave;
326#endif // GX_DEVELOP
327
329};
330
331#if GX_DEVELOP
332//---------------------------------------------------------------------------
333// 確保メモリ情報出力
338//---------------------------------------------------------------------------
339GX_FORCE_INLINE void GxAllocatorHeap::traceAllocateInformation(const void* pAddress, u32 size, GX_CSTR filename, u32 line) const
340{
342 {
343 // 確保メモリ情報出力
344 const auto* pHeader = getHeaderPointer(const_cast<void*>(pAddress));
345 GX_TRACE(GX_TRACE_CATEGORY_CORE, "[heapAllocate] <%s> addr(0x%p) size(%d) : HeapAddr(0x%p) usedSize(%d) freeSize(%d) Prev(0x%p) Next(0x%p) PrevFree(0x%p) NextFree(0x%p)", getAllocatorName(), pAddress, size, pHeader, getSizeFromBlock(pHeader->_usedBlock), getSizeFromBlock(pHeader->_freeBlock), pHeader->_pPrevious, pHeader->_pNext, pHeader->_pPreviousFree, pHeader->_pNextFree);
346
347 // 確保呼び出し情報出力
348 if( filename )
349 {
350 GX_TRACE(GX_TRACE_CATEGORY_CORE, " %s (%d)", filename, line);
351 GX_TRACE(GX_TRACE_CATEGORY_CORE, " serial[%d]", pHeader->_serialNumber);
352 }
353 }
354}
355
356//---------------------------------------------------------------------------
357// 解放メモリ情報出力
361//---------------------------------------------------------------------------
362GX_FORCE_INLINE void GxAllocatorHeap::traceFreeInformation(const void* pAddress, GX_CSTR filename, u32 line) const
363{
365 {
366 // 解放メモリ情報出力
367 const auto* pHeader = getHeaderPointer(const_cast<void*>(pAddress));
368 GX_TRACE(GX_TRACE_CATEGORY_CORE, "[heapFree] <%s> addr(0x%p) : HeapAddr(0x%p) usedSize(%d) freeSize(%d) Prev(0x%p) Next(0x%p) PrevFree(0x%p) NextFree(0x%p)",
369 getAllocatorName(), pAddress, pHeader, getSizeFromBlock(pHeader->_usedBlock), getSizeFromBlock(pHeader->_freeBlock), pHeader->_pPrevious, pHeader->_pNext, pHeader->_pPreviousFree, pHeader->_pNextFree);
370
371 // 解放呼び出し情報出力
372 if( filename )
373 {
374 GX_TRACE(GX_TRACE_CATEGORY_CORE, " %s (%d)", filename, line);
375 GX_TRACE(GX_TRACE_CATEGORY_CORE, " serial[%d]", pHeader->_serialNumber);
376 GX_TRACE(GX_TRACE_CATEGORY_CORE, " %s (%d)", pHeader->getAnnotation(), pHeader->_line);
377 }
378 }
379}
380#endif // GX_DEVELOP
381
382//---------------------------------------------------------------------------
383// ヘッダーポインタから確保メモリを取得
386//---------------------------------------------------------------------------
387GX_FORCE_INLINE void* GxAllocatorHeap::getMemoryPointer(const GxAllocatorHeap::GxHeapInformation* pHeapInformation)
388{
389 return reinterpret_cast<void*>(reinterpret_cast<size_t>(pHeapInformation) + getHeaderSize());
390}
391
392//---------------------------------------------------------------------------
393// 確保メモリからヘッダーポインタ取得
396//---------------------------------------------------------------------------
398{
399 return reinterpret_cast<GxHeapInformation*>(reinterpret_cast<size_t>(pAddress) - getHeaderSize());
400}
401
402//---------------------------------------------------------------------------
403// サイズ → ブロック数取得
406//---------------------------------------------------------------------------
407GX_FORCE_INLINE u32 GxAllocatorHeap::getBlockFromSize(u32 size)
408{
409 GX_ASSERT(GxMath::isAlignmentFast(size, BLOCK_SIZE), "argument error!! size(%d) is not alignment BLOCK_SIZE(%d)", size, BLOCK_SIZE);
410 return ((size + BLOCK_SIZE - 1) >> HEAP_SHIFT);
411}
412
413//---------------------------------------------------------------------------
414// ブロック数 → サイズ取得
417//---------------------------------------------------------------------------
418GX_FORCE_INLINE u32 GxAllocatorHeap::getSizeFromBlock(u32 block)
419{
420 return (block << HEAP_SHIFT);
421}
422
423//---------------------------------------------------------------------------
424// ヘッダーサイズ取得 (※BLOCK_SIZEでのアライメント考慮)
426//---------------------------------------------------------------------------
427GX_FORCE_INLINE u32 GxAllocatorHeap::getHeaderSize(void)
428{
429 return GxMath::getRoundUpFast(static_cast<u32>(sizeof(GxHeapInformation)), BLOCK_SIZE);
430}
431
432GX_CORE_NAMESPACE_END()
#define GX_PROHIBIT_CLASS_BASE(__CLASS__)
GxClassBase継承の禁止宣言
Definition GxBase.h:240
@ MAX
定義数
ヒープメモリアロケータ
Definition GxAllocatorHeap.h:19
static GxHeapInformation * getHeaderPointer(void *pAddress)
確保メモリからヘッダーポインタ取得
Definition GxAllocatorHeap.h:397
static u32 getHeaderSize(void)
ヘッダーサイズ取得 (※BLOCK_SIZEでのアライメント考慮)
Definition GxAllocatorHeap.h:427
static u32 getBlockFromSize(u32 size)
サイズ → ブロック数取得
Definition GxAllocatorHeap.h:407
GxAllocatorHeap(void)
デフォルトコンストラクタ (使用禁止)
Definition GxAllocatorHeap.h:142
void calculateMaxAvailableSize(void)
最大確保可能サイズの計算
static u32 getSizeFromBlock(u32 block)
ブロック数 → サイズ取得
Definition GxAllocatorHeap.h:418
ALLOCATE_TYPE
メモリ確保手法
Definition GxAllocatorHeap.h:40
constexpr u32 getUsedSize(void) const
使用サイズの取得
Definition GxAllocatorHeap.h:258
static void * getMemoryPointer(const GxAllocatorHeap::GxHeapInformation *pHeapInformation)
ヘッダーポインタから確保メモリを取得
Definition GxAllocatorHeap.h:387
constexpr GxHeapInformation * getHeapTop(void) const
ヒープ先頭アドレスの取得
Definition GxAllocatorHeap.h:264
メモリアロケータ基底クラス
Definition GxAllocator.h:82
@ ATTRIBUTE_TRACE
メモリ確保・解放時にログを出力
Definition GxAllocator.h:99
u32 _attribute
属性
Definition GxAllocator.h:220
連結リストクラス
Definition GxList.h:18
static GX_FORCE_INLINE T getRoundUpFast(T value, size_t alignment)
数値切り上げ(高速版 ※2のべき乗指定)
Definition GxMath.h:537
static GX_FORCE_INLINE b32 isAlignmentFast(T value, u32 alignment)
アライメント判定(高速版 ※2のべき乗指定)
Definition GxMath.h:500
ALIGNMENT
メモリアライメント定義
Definition GxMemory.h:51
@ _16
16byteアライメント
Definition GxMemory.h:54
TYPE
割り当てメモリ種別
Definition GxMemory.h:30
ヒープ情報ヘッダー (BLOCK_SIZEアライメント)
Definition GxAllocatorHeap.h:56
u32 _freeBlock
空きブロック数
Definition GxAllocatorHeap.h:110
GxMemory::ALIGNMENT _alignment
確保アライメント
Definition GxAllocatorHeap.h:108
GxHeapInformation * _pNext
1つ後のヒープ情報
Definition GxAllocatorHeap.h:128
void initialize(GxAllocatorHeap *pAllocator, u32 usedSize, u32 freeSize, u32 alignmentSize, u32 alignment)
初期情報設定
Definition GxAllocatorHeap.h:63
GxHeapInformation * _pPrevious
1つ前のヒープ情報
Definition GxAllocatorHeap.h:127
b32 isHead(void) const
先頭ヒープ情報判定
Definition GxAllocatorHeap.h:81
GxAllocatorHeap * _pAllocator
確保アロケータポインタ
Definition GxAllocatorHeap.h:107
b32 isTail(void) const
終端ヒープ情報判定
Definition GxAllocatorHeap.h:83
GxHeapInformation * _pNextFree
1つ後の空き領域保持ヒープ情報
Definition GxAllocatorHeap.h:130
u16 _alignmentBlock
アライメント補正されたブロック数
Definition GxAllocatorHeap.h:111
u32 _magic
マジックナンバー
Definition GxAllocatorHeap.h:106
GxHeapInformation * _pPreviousFree
1つ前の空き領域保持ヒープ情報
Definition GxAllocatorHeap.h:129
u32 _usedBlock
使用メモリブロック数
Definition GxAllocatorHeap.h:109
文字列型クラス
Definition GxString.h:18
32bitブーリアン
Definition GxDefine.h:173