gwnavruntime/kernel/SF_Memory.h Source File

SF_Memory.h
Go to the documentation of this file.
1 /*
2 * Copyright 2016 Autodesk, Inc. All rights reserved.
3 * Use of this software is subject to the terms of the Autodesk license agreement and any attachments or Appendices thereto provided at the time of installation or download,
4 * or which otherwise accompanies this software in either electronic or hard copy form, or which is signed by you and accepted by Autodesk.
5 */
6 
7 #pragma once
8 
11 #include <new>
12 
13 // Unified SysAlloc. New malloc-friendly allocator
16 
17 // This file requires operator 'new' to NOT be defined; its definition
18 // is restored in the bottom of the header based on KY_DEFINE_NEW.
19 #undef new
20 
21 // ***** Memory Allocation Macros
22 
23 // These macros are used for allocation to ensure that the allocation location
24 // filename and line numbers are recorded in debug builds. The heap-based
25 // operator new versions are declared in a separate header file "HeapNew.h".
26 
27 #if !defined(KY_MEMORY_ENABLE_DEBUG_INFO)
28  // Allocate from global heap.
29  #define KY_ALLOC(s,id) Kaim::Memory::Alloc((s))
30  #define KY_MEMALIGN(s,a,id) Kaim::Memory::Alloc((s),(a))
31  #define KY_REALLOC(p,s,id) Kaim::Memory::Realloc((p),(s))
32  #define KY_FREE(p) Kaim::Memory::Free((p))
33  #define KY_FREE_ALIGN(s) Kaim::Memory::Free((s))
34  // Heap versions.
35  #define KY_HEAP_ALLOC(heap,s,id) Kaim::Memory::AllocInHeap((heap),(s))
36  #define KY_HEAP_MEMALIGN(heap,s,a,id) Kaim::Memory::AllocInHeap((heap),(s),(a))
37  #define KY_HEAP_REALLOC(heap,p,s,id) Kaim::Memory::ReallocInHeap((heap),(p),(s))
38  #define KY_HEAP_AUTO_ALLOC(addr,s) Kaim::Memory::AllocAutoHeap((addr),(s))
39  #define KY_HEAP_AUTO_ALLOC_ID(addr,s,id) Kaim::Memory::AllocAutoHeap((addr),(s))
40  #define KY_HEAP_FREE(heap, p) Kaim::Memory::Free((p))
41 
42 #else // KY_MEMORY_ENABLE_DEBUG_INFO
43  #define KY_ALLOC(s,id) Kaim::Memory::Alloc((s), Kaim::AllocInfo((id),__FILE__,__LINE__))
44  #define KY_MEMALIGN(s,a,id) Kaim::Memory::Alloc((s),(a), Kaim::AllocInfo((id),__FILE__,__LINE__))
45  #define KY_REALLOC(p,s,id) Kaim::Memory::Realloc((p),(s),Kaim::AllocInfo((id),__FILE__,__LINE__))
46  #define KY_FREE(p) Kaim::Memory::Free((p))
47  #define KY_FREE_ALIGN(s) Kaim::Memory::Free((s))
48  // Heap versions.
49  #define KY_HEAP_ALLOC(heap,s,id) Kaim::Memory::AllocInHeap((heap),(s), Kaim::AllocInfo((id),__FILE__,__LINE__))
50  #define KY_HEAP_MEMALIGN(heap,s,a,id) Kaim::Memory::AllocInHeap((heap),(s),(a), Kaim::AllocInfo((id),__FILE__,__LINE__))
51  #define KY_HEAP_REALLOC(heap,p,s,id) Kaim::Memory::ReallocInHeap((heap),(p),(s))
52  #define KY_HEAP_AUTO_ALLOC(addr,s) Kaim::Memory::AllocAutoHeap((addr),(s), Kaim::AllocInfo(Kaim::Stat_Default_Mem,__FILE__,__LINE__))
53  #define KY_HEAP_AUTO_ALLOC_ID(addr,s,id) Kaim::Memory::AllocAutoHeap((addr),(s), Kaim::AllocInfo((id),__FILE__,__LINE__))
54  #define KY_HEAP_FREE(heap, p) Kaim::Memory::Free((p))
55 
56 #endif // !defined(KY_MEMORY_ENABLE_DEBUG_INFO)
57 
58 // note that even if KY_ENABLE_STACK_REGISTRY is defined, a call to StackRegistry::Initialize() is necessary to enable the StackRegistry
59 #if defined(KY_ENABLE_STACK_REGISTRY)
60 KY_INLINE void* RegisterStack(void* p, Kaim::UPInt size) { Kaim::StackRegistry::MapCurrentStackToUid(Kaim::UPInt(p), size); return p; }
61 #define KY_REGISTER_STACK(p, s) RegisterStack(p, s);
62 #define KY_UNREGISTER_STACK(p) Kaim::StackRegistry::UnMapStackFromUid((Kaim::UPInt)p)
63 #else
64 #define KY_REGISTER_STACK(p, s) p
65 #define KY_UNREGISTER_STACK(p)
66 #endif
67 
68 namespace Kaim {
69 
70 // ***** Memory Class
71 
72 // Maintains current heap and the global allocator, wrapping heap access functions.
73 // The main purpose of wrapping is to allow AllocDebugInfo temporary to be converted
74 // from a constant reference to an optional pointer argument for the allocation
75 // functions in MemoryHeap.
76 class Memory
77 {
78 public:
79  static MemoryHeap *pGlobalHeap;
80 
81  // May need to export this later and check allocation status.
82  static void SetGlobalHeap(MemoryHeap *heap) { pGlobalHeap = heap; }
83  static MemoryHeap* GetGlobalHeap() { return pGlobalHeap; }
84 
85  // *** Operations with memory arenas
86  //--------------------------------------------------------------------
87  static void DestroyArena(UPInt arena) { pGlobalHeap->DestroyArena(arena); }
88  static bool ArenaIsEmpty(UPInt arena) { return pGlobalHeap->ArenaIsEmpty(arena); }
89 
90  // *** Memory Allocation
91  // Memory::Alloc of size==0 will allocate a tiny block & return a valid pointer;
92  // this makes it suitable for new operator.
93  static void* Alloc(UPInt size) { return KY_REGISTER_STACK(pGlobalHeap->Alloc(size), size); }
94  static void* Alloc(UPInt size, UPInt align) { return KY_REGISTER_STACK(pGlobalHeap->Alloc(size, align), size); }
95  static void* Alloc(UPInt size, const AllocInfo& info) { return KY_REGISTER_STACK(pGlobalHeap->Alloc(size, &info), size); }
96  static void* Alloc(UPInt size, UPInt align, const AllocInfo& info) { return KY_REGISTER_STACK(pGlobalHeap->Alloc(size, align, &info), size); }
97 
98  // Allocate while automatically identifying heap and allocation id based on the specified address.
99  static void* AllocAutoHeap(const void *p, UPInt size) { return KY_REGISTER_STACK(pGlobalHeap->AllocAutoHeap(p, size), size); }
100  static void* AllocAutoHeap(const void *p, UPInt size, UPInt align) { return KY_REGISTER_STACK(pGlobalHeap->AllocAutoHeap(p, size, align), size); }
101  static void* AllocAutoHeap(const void *p, UPInt size, const AllocInfo& info) { return KY_REGISTER_STACK(pGlobalHeap->AllocAutoHeap(p, size, &info), size); }
102  static void* AllocAutoHeap(const void *p, UPInt size, UPInt align, const AllocInfo& info) { return KY_REGISTER_STACK(pGlobalHeap->AllocAutoHeap(p, size, align, &info), size); }
103 
104  // Allocate in a specified heap. The later functions are provided to ensure that
105  // AllocInfo can be passed by reference with extended lifetime.
106  static void* AllocInHeap(MemoryHeap* heap, UPInt size) { return KY_REGISTER_STACK(heap->Alloc(size), size); }
107  static void* AllocInHeap(MemoryHeap* heap, UPInt size, UPInt align) { return KY_REGISTER_STACK(heap->Alloc(size, align), size); }
108  static void* AllocInHeap(MemoryHeap* heap, UPInt size, const AllocInfo& info) { return KY_REGISTER_STACK(heap->Alloc(size, &info), size); }
109  static void* AllocInHeap(MemoryHeap* heap, UPInt size, UPInt align, const AllocInfo& info) { return KY_REGISTER_STACK(heap->Alloc(size, align, &info), size); }
110 
111  // Reallocate to a new size, 0 return == can't reallocate, previous memory is still valid
112  //
113  // Realloc to decrease size will never fail
114  // Realloc of pointer == 0 is equivalent to Memory::Alloc
115  // Realloc of size == 0, shrinks to the minimal size, pointer remains valid and requires Free().
116  // NOTE: Realloc guarantees the alignment specified in Alloc()
117  static void* Realloc(void *p, UPInt newSize) { KY_UNREGISTER_STACK(p); return KY_REGISTER_STACK(pGlobalHeap->Realloc(p, newSize), newSize); }
118  static void* ReallocAutoHeap(void *p, UPInt newSize) { KY_UNREGISTER_STACK(p); return KY_REGISTER_STACK(pGlobalHeap->ReallocAutoHeap(p, newSize), newSize); }
119  static void* ReallocInHeap(MemoryHeap* heap, void *p, UPInt newSize) { KY_UNREGISTER_STACK(p); return KY_REGISTER_STACK(heap->Realloc(p, newSize), newSize); }
120 
121  // Free allocated/reallocated block
122  static void Free(void *p) { KY_UNREGISTER_STACK(p); pGlobalHeap->Free(p); }
123 
124  static MemoryHeap* GetHeapByAddress(const void* p) { return pGlobalHeap->GetAllocHeap(p); }
125  static bool DetectMemoryLeaks() { return pGlobalHeap->DumpMemoryLeaks(); }
126 };
127 
128 // ***** Macros to redefine class new/delete operators
129 
130 // Types specifically declared to allow disambiguation of address in
131 // class member operator new. Used in HeapNew.h.
132 
133 struct MemAddressStub { };
134 typedef MemAddressStub* MemAddressPtr;
135 
136 #define KY_MEMORY_REDEFINE_NEW_IMPL(class_name, check_delete, StatType) \
137  void* operator new(Kaim::UPInt sz) \
138  { void *p = KY_ALLOC(sz, StatType); return p; } \
139  void* operator new(Kaim::UPInt sz, Kaim::MemoryHeap* heap) \
140  { void *p = KY_HEAP_ALLOC(heap, sz, StatType); return p; } \
141  void* operator new(Kaim::UPInt sz, Kaim::MemoryHeap* heap, int blocktype) \
142  { KY_UNUSED(blocktype); void *p = KY_HEAP_ALLOC(heap, sz, blocktype); return p; } \
143  void* operator new(Kaim::UPInt sz, Kaim::MemAddressPtr adr) \
144  { void *p = Kaim::Memory::AllocAutoHeap(adr, sz, Kaim::AllocInfo(StatType,__FILE__,__LINE__)); return p; } \
145  void* operator new(Kaim::UPInt sz, const char* pfilename, int line) \
146  { void* p = Kaim::Memory::Alloc(sz, Kaim::AllocInfo(StatType, pfilename, line)); return p; } \
147  void* operator new(Kaim::UPInt sz, Kaim::MemoryHeap* heap, const char* pfilename, int line) \
148  { void* p = Kaim::Memory::AllocInHeap(heap, sz, Kaim::AllocInfo(StatType, pfilename, line)); return p; } \
149  void* operator new(Kaim::UPInt sz, Kaim::MemAddressPtr adr, const char* pfilename, int line) \
150  { void* p = Kaim::Memory::AllocAutoHeap(adr, sz, Kaim::AllocInfo(StatType, pfilename, line)); return p; } \
151  void* operator new(Kaim::UPInt sz, int blocktype, const char* pfilename, int line) \
152  { void* p = Kaim::Memory::Alloc(sz, Kaim::AllocInfo(blocktype, pfilename, line)); return p; } \
153  void* operator new(Kaim::UPInt sz, Kaim::MemoryHeap* heap, int blocktype, const char* pfilename, int line) \
154  { void* p = Kaim::Memory::AllocInHeap(heap, sz, Kaim::AllocInfo(blocktype, pfilename, line)); return p; } \
155  void* operator new(Kaim::UPInt sz, Kaim::MemAddressPtr adr, int blocktype, const char* pfilename, int line) \
156  { void* p = Kaim::Memory::AllocAutoHeap(adr, sz, Kaim::AllocInfo(blocktype, pfilename, line)); return p; } \
157  void operator delete(void *p) \
158  { check_delete(class_name, p); KY_FREE(p); } \
159  void operator delete(void *p, const char*, int) \
160  { check_delete(class_name, p); KY_FREE(p); } \
161  void operator delete(void *p, int, const char*, int) \
162  { check_delete(class_name, p); KY_FREE(p); } \
163  void operator delete(void *p, Kaim::MemoryHeap*) \
164  { check_delete(class_name, p); KY_FREE(p); } \
165  void operator delete(void *p, Kaim::MemoryHeap*, int) \
166  { check_delete(class_name, p); KY_FREE(p); } \
167  void operator delete(void *p, Kaim::MemoryHeap*, const char*, int) \
168  { check_delete(class_name, p); KY_FREE(p); } \
169  void operator delete(void *p, Kaim::MemoryHeap*, int,const char*,int) \
170  { check_delete(class_name, p); KY_FREE(p); } \
171  void operator delete(void *p, Kaim::MemAddressPtr) \
172  { check_delete(class_name, p); KY_FREE(p); } \
173  void operator delete(void *p, Kaim::MemAddressPtr, int) \
174  { check_delete(class_name, p); KY_FREE(p); } \
175  void operator delete(void *p, Kaim::MemAddressPtr, const char*, int) \
176  { check_delete(class_name, p); KY_FREE(p); } \
177  void operator delete(void *p, Kaim::MemAddressPtr,int,const char*,int) \
178  { check_delete(class_name, p); KY_FREE(p); }
179 
180 #define KY_MEMORY_DEFINE_PLACEMENT_NEW \
181  void* operator new (Kaim::UPInt n, void *ptr) { KY_UNUSED(n); return ptr; } \
182  void operator delete (void *ptr, void *ptr2) { KY_UNUSED2(ptr,ptr2); }
183 
184 
185 #define KY_MEMORY_CHECK_DELETE_NONE(class_name, p)
186 
187 // Redefined all delete/new operators in a class without custom memory initialization
188 #define KY_MEMORY_REDEFINE_NEW(class_name, StatType) KY_MEMORY_REDEFINE_NEW_IMPL(class_name, KY_MEMORY_CHECK_DELETE_NONE, StatType)
189 
190 // Base class that overrides the new and delete operators.
191 // Deriving from this class, even as a multiple base, incurs no space overhead.
192 template<int Stat>
193 class NewOverrideBase
194 {
195 public:
196  enum { StatType = Stat };
197 
198  // Redefine all new & delete operators.
199  KY_MEMORY_REDEFINE_NEW(NewOverrideBase, Stat)
200 };
201 
202 
203 } // Scaleform
204 
205 
206 
207 // *** Restore operator 'new' Definition
208 
209 // If users specified KY__BUILD_DEFINE_NEW in preprocessor settings, use that definition.
210 #if defined(KY_BUILD_DEFINE_NEW) && !defined(KY_DEFINE_NEW)
211 #define KY_DEFINE_NEW new(__FILE__,__LINE__)
212 #endif
213 // Redefine operator 'new' if necessary.
214 #if defined(KY_DEFINE_NEW)
215 #define new KY_DEFINE_NEW
216 #endif
217 
The Autodesk Navigation namespace.
Definition: gamekitcrowddispersion.cpp:17