gwnavruntime/kernel/SF_Memory.h Source File

SF_Memory.h
Go to the documentation of this file.
1 /*
2 * Copyright 2015 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 /**************************************************************************
8 
9 PublicHeader: Kernel
10 Filename : KY_Memory.h
11 Content : General purpose memory allocation functions
12 Created : December 28, 1998 - 2009
13 Authors : Michael Antonov, Maxim Shemanarev
14 
15 **************************************************************************/
16 
17 #ifndef INC_KY_Kernel_Memory_H
18 #define INC_KY_Kernel_Memory_H
19 
22 
23 // Unified SysAlloc. New malloc-friendly allocator
26 #define KY_SYSALLOC_DEFAULT_CLASS Kaim::SysAllocMalloc
27 
28 /*
29 // Include the right allocation header for the platform involved.
30 // This is ok even if users use custom allocators, as having the headers
31 // included here does NOT force the code to be linked.
32 #if defined(KY_OS_WIN32) || defined(KY_OS_XBOX360) || defined(KY_OS_WINCE)
33  #include "gwnavruntime/kernel/HeapPT/HeapPT_SysAllocWinAPI.h"
34  #define KY_SYSALLOC_DEFAULT_CLASS SysAllocWinAPI
35  #include "gwnavruntime/kernel/HeapPT/HeapPT_SysAllocMalloc.h"
36  //#define KY_SYSALLOC_DEFAULT_CLASS SysAllocMalloc
37 #elif defined(KY_OS_PS3)
38  #include "gwnavruntime/kernel/HeapPT/HeapPT_SysAllocPS3.h"
39  #define KY_SYSALLOC_DEFAULT_CLASS SysAllocPS3
40 #elif defined(KY_OS_WII)
41  #include "gwnavruntime/kernel/HeapPT/HeapPT_SysAllocWii.h"
42  #define KY_SYSALLOC_DEFAULT_CLASS SysAllocWii
43 #elif defined(KY_OS_3DS)
44  #include "gwnavruntime/kernel/HeapPT/HeapPT_SysAlloc3DS.h"
45  #define KY_SYSALLOC_DEFAULT_CLASS SysAlloc3DS
46 #else
47  #include "gwnavruntime/kernel/HeapMH/HeapMH_SysAllocMalloc.h"
48  #define KY_SYSALLOC_DEFAULT_CLASS SysAllocPagedMalloc
49 #endif
50 */
51 
52 
53 // Define this macro to enable memory tracking; since tracking is not free
54 // this variable probably should not be defined for a release build.
55 //#define KY_MEMORY_TRACKSIZES
56 
57 // This file requires operator 'new' to NOT be defined; its definition
58 // is restored in the bottom of the header based on KY_DEFINE_NEW.
59 #undef new
60 
61 // ***** Memory Allocation Macros
62 
63 // These macros are used for allocation to ensure that the allocation location
64 // filename and line numbers are recorded in debug builds. The heap-based
65 // operator new versions are declared in a separate header file "HeapNew.h".
66 
67 #if !defined(KY_MEMORY_ENABLE_DEBUG_INFO)
68  // Allocate from global heap.
69  #define KY_ALLOC(s,id) Kaim::Memory::Alloc((s))
70  #define KY_MEMALIGN(s,a,id) Kaim::Memory::Alloc((s),(a))
71  #define KY_REALLOC(p,s,id) Kaim::Memory::Realloc((p),(s))
72  #define KY_FREE(p) Kaim::Memory::Free((p))
73  #define KY_FREE_ALIGN(s) Kaim::Memory::Free((s))
74  // Heap versions.
75  #define KY_HEAP_ALLOC(heap,s,id) Kaim::Memory::AllocInHeap((heap),(s))
76  #define KY_HEAP_MEMALIGN(heap,s,a,id) Kaim::Memory::AllocInHeap((heap),(s),(a))
77  #define KY_HEAP_REALLOC(heap,p,s,id) Kaim::Memory::ReallocInHeap((heap),(p),(s))
78  #define KY_HEAP_AUTO_ALLOC(addr,s) Kaim::Memory::AllocAutoHeap((addr),(s))
79  #define KY_HEAP_AUTO_ALLOC_ID(addr,s,id) Kaim::Memory::AllocAutoHeap((addr),(s))
80  #define KY_HEAP_FREE(heap, p) Kaim::Memory::Free((p))
81 
82 #else // KY_MEMORY_ENABLE_DEBUG_INFO
83  #define KY_ALLOC(s,id) Kaim::Memory::Alloc((s), Kaim::AllocInfo((id),__FILE__,__LINE__))
84  #define KY_MEMALIGN(s,a,id) Kaim::Memory::Alloc((s),(a), Kaim::AllocInfo((id),__FILE__,__LINE__))
85  #define KY_REALLOC(p,s,id) Kaim::Memory::Realloc((p),(s),Kaim::AllocInfo((id),__FILE__,__LINE__))
86  #define KY_FREE(p) Kaim::Memory::Free((p))
87  #define KY_FREE_ALIGN(s) Kaim::Memory::Free((s))
88  // Heap versions.
89  #define KY_HEAP_ALLOC(heap,s,id) Kaim::Memory::AllocInHeap((heap),(s), Kaim::AllocInfo((id),__FILE__,__LINE__))
90  #define KY_HEAP_MEMALIGN(heap,s,a,id) Kaim::Memory::AllocInHeap((heap),(s),(a), Kaim::AllocInfo((id),__FILE__,__LINE__))
91  #define KY_HEAP_REALLOC(heap,p,s,id) Kaim::Memory::ReallocInHeap((heap),(p),(s))
92  #define KY_HEAP_AUTO_ALLOC(addr,s) Kaim::Memory::AllocAutoHeap((addr),(s), Kaim::AllocInfo(Kaim::Stat_Default_Mem,__FILE__,__LINE__))
93  #define KY_HEAP_AUTO_ALLOC_ID(addr,s,id) Kaim::Memory::AllocAutoHeap((addr),(s), Kaim::AllocInfo((id),__FILE__,__LINE__))
94  #define KY_HEAP_FREE(heap, p) Kaim::Memory::Free((p))
95 
96 #endif // !defined(KY_MEMORY_ENABLE_DEBUG_INFO)
97 
98 #ifdef KY_ENABLE_STACK_REGISTRY
99 KY_INLINE void* RegisterStack(void* p, Kaim::UPInt size) { Kaim::StackRegistry::MapCurrentStackToUid(Kaim::UPInt(p), size); return p; }
100 #define KY_REGISTER_STACK(p, s) RegisterStack(p, s);
101 #define KY_UNREGISTER_STACK(p) Kaim::StackRegistry::UnMapStackFromUid((Kaim::UPInt)p)
102 #else
103 #define KY_REGISTER_STACK(p, s) p
104 #define KY_UNREGISTER_STACK(p)
105 #endif
106 
107 namespace Kaim {
108 
109 // ***** Memory Class
110 
111 // Maintains current heap and the global allocator, wrapping heap access functions.
112 // The main purpose of wrapping is to allow GAllocDebugInfo temporary to be converted
113 // from a constant reference to an optional pointer argument for the allocation
114 // functions in MemoryHeap.
115 
116 class Memory
117 {
118 public:
119  static MemoryHeap *pGlobalHeap;
120 
121 
122  // May need to export this later and check allocation status.
123  static void KY_STDCALL SetGlobalHeap(MemoryHeap *heap) { pGlobalHeap = heap; }
124  static MemoryHeap* KY_STDCALL GetGlobalHeap() { return pGlobalHeap; }
125 
126  // *** Operations with memory arenas
127  //--------------------------------------------------------------------
128  static void KY_STDCALL CreateArena(UPInt arena, SysAllocPaged* sysAlloc) { pGlobalHeap->CreateArena(arena, sysAlloc); }
129  static void KY_STDCALL DestroyArena(UPInt arena) { pGlobalHeap->DestroyArena(arena); }
130  static bool KY_STDCALL ArenaIsEmpty(UPInt arena) { return pGlobalHeap->ArenaIsEmpty(arena); }
131 
132  // *** Memory Allocation
133  // Memory::Alloc of size==0 will allocate a tiny block & return a valid pointer;
134  // this makes it suitable for new operator.
135  static void* KY_STDCALL Alloc(UPInt size) { return KY_REGISTER_STACK(pGlobalHeap->Alloc(size), size); }
136  static void* KY_STDCALL Alloc(UPInt size, UPInt align) { return KY_REGISTER_STACK(pGlobalHeap->Alloc(size, align), size); }
137  static void* KY_STDCALL Alloc(UPInt size, const AllocInfo& info) { return KY_REGISTER_STACK(pGlobalHeap->Alloc(size, &info), size); }
138  static void* KY_STDCALL Alloc(UPInt size, UPInt align, const AllocInfo& info) { return KY_REGISTER_STACK(pGlobalHeap->Alloc(size, align, &info), size); }
139 
140  // Allocate while automatically identifying heap and allocation id based on the specified address.
141  static void* KY_STDCALL AllocAutoHeap(const void *p, UPInt size) { return KY_REGISTER_STACK(pGlobalHeap->AllocAutoHeap(p, size), size); }
142  static void* KY_STDCALL AllocAutoHeap(const void *p, UPInt size, UPInt align) { return KY_REGISTER_STACK(pGlobalHeap->AllocAutoHeap(p, size, align), size); }
143  static void* KY_STDCALL AllocAutoHeap(const void *p, UPInt size, const AllocInfo& info) { return KY_REGISTER_STACK(pGlobalHeap->AllocAutoHeap(p, size, &info), size); }
144  static void* KY_STDCALL AllocAutoHeap(const void *p, UPInt size, UPInt align, const AllocInfo& info) { return KY_REGISTER_STACK(pGlobalHeap->AllocAutoHeap(p, size, align, &info), size); }
145 
146  // Allocate in a specified heap. The later functions are provided to ensure that
147  // AllocInfo can be passed by reference with extended lifetime.
148  static void* KY_STDCALL AllocInHeap(MemoryHeap* heap, UPInt size) { return KY_REGISTER_STACK(heap->Alloc(size), size); }
149  static void* KY_STDCALL AllocInHeap(MemoryHeap* heap, UPInt size, UPInt align) { return KY_REGISTER_STACK(heap->Alloc(size, align), size); }
150  static void* KY_STDCALL AllocInHeap(MemoryHeap* heap, UPInt size, const AllocInfo& info) { return KY_REGISTER_STACK(heap->Alloc(size, &info), size); }
151  static void* KY_STDCALL AllocInHeap(MemoryHeap* heap, UPInt size, UPInt align, const AllocInfo& info) { return KY_REGISTER_STACK(heap->Alloc(size, align, &info), size); }
152 
153  // Reallocate to a new size, 0 return == can't reallocate, previous memory is still valid
154  //
155  // Realloc to decrease size will never fail
156  // Realloc of pointer == 0 is equivalent to Memory::Alloc
157  // Realloc of size == 0, shrinks to the minimal size, pointer remains valid and requires Free().
158  // NOTE: Realloc guarantees the alignment specified in Alloc()
159  static void* KY_STDCALL Realloc(void *p, UPInt newSize) { KY_UNREGISTER_STACK(p); return KY_REGISTER_STACK(pGlobalHeap->Realloc(p, newSize), newSize); }
160  static void* KY_STDCALL ReallocAutoHeap(void *p, UPInt newSize) { KY_UNREGISTER_STACK(p); return KY_REGISTER_STACK(pGlobalHeap->ReallocAutoHeap(p, newSize), newSize); }
161  static void* KY_STDCALL ReallocInHeap(MemoryHeap* heap, void *p, UPInt newSize) { KY_UNREGISTER_STACK(p); return KY_REGISTER_STACK(heap->Realloc(p, newSize), newSize); }
162 
163  // Free allocated/reallocated block
164  static void KY_STDCALL Free(void *p) { KY_UNREGISTER_STACK(p); pGlobalHeap->Free(p); }
165 
166  static MemoryHeap* KY_STDCALL GetHeapByAddress(const void* p) { return pGlobalHeap->GetAllocHeap(p); }
167  static bool KY_STDCALL DetectMemoryLeaks() { return pGlobalHeap->DumpMemoryLeaks(); }
168 };
169 
170 // ***** Macros to redefine class new/delete operators
171 
172 // Types specifically declared to allow disambiguation of address in
173 // class member operator new. Used in HeapNew.h.
174 
175 struct MemAddressStub { };
176 typedef MemAddressStub* MemAddressPtr;
177 
178 #define KY_MEMORY_REDEFINE_NEW_IMPL(class_name, check_delete, StatType) \
179  void* operator new(Kaim::UPInt sz) \
180  { void *p = KY_ALLOC(sz, StatType); return p; } \
181  void* operator new(Kaim::UPInt sz, Kaim::MemoryHeap* heap) \
182  { void *p = KY_HEAP_ALLOC(heap, sz, StatType); return p; } \
183  void* operator new(Kaim::UPInt sz, Kaim::MemoryHeap* heap, int blocktype) \
184  { KY_UNUSED(blocktype); void *p = KY_HEAP_ALLOC(heap, sz, blocktype); return p; } \
185  void* operator new(Kaim::UPInt sz, Kaim::MemAddressPtr adr) \
186  { void *p = Kaim::Memory::AllocAutoHeap(adr, sz, Kaim::AllocInfo(StatType,__FILE__,__LINE__)); return p; } \
187  void* operator new(Kaim::UPInt sz, const char* pfilename, int line) \
188  { void* p = Kaim::Memory::Alloc(sz, Kaim::AllocInfo(StatType, pfilename, line)); return p; } \
189  void* operator new(Kaim::UPInt sz, Kaim::MemoryHeap* heap, const char* pfilename, int line) \
190  { void* p = Kaim::Memory::AllocInHeap(heap, sz, Kaim::AllocInfo(StatType, pfilename, line)); return p; } \
191  void* operator new(Kaim::UPInt sz, Kaim::MemAddressPtr adr, const char* pfilename, int line) \
192  { void* p = Kaim::Memory::AllocAutoHeap(adr, sz, Kaim::AllocInfo(StatType, pfilename, line)); return p; } \
193  void* operator new(Kaim::UPInt sz, int blocktype, const char* pfilename, int line) \
194  { void* p = Kaim::Memory::Alloc(sz, Kaim::AllocInfo(blocktype, pfilename, line)); return p; } \
195  void* operator new(Kaim::UPInt sz, Kaim::MemoryHeap* heap, int blocktype, const char* pfilename, int line) \
196  { void* p = Kaim::Memory::AllocInHeap(heap, sz, Kaim::AllocInfo(blocktype, pfilename, line)); return p; } \
197  void* operator new(Kaim::UPInt sz, Kaim::MemAddressPtr adr, int blocktype, const char* pfilename, int line) \
198  { void* p = Kaim::Memory::AllocAutoHeap(adr, sz, Kaim::AllocInfo(blocktype, pfilename, line)); return p; } \
199  void operator delete(void *p) \
200  { check_delete(class_name, p); KY_FREE(p); } \
201  void operator delete(void *p, const char*, int) \
202  { check_delete(class_name, p); KY_FREE(p); } \
203  void operator delete(void *p, int, const char*, int) \
204  { check_delete(class_name, p); KY_FREE(p); } \
205  void operator delete(void *p, Kaim::MemoryHeap*) \
206  { check_delete(class_name, p); KY_FREE(p); } \
207  void operator delete(void *p, Kaim::MemoryHeap*, int) \
208  { check_delete(class_name, p); KY_FREE(p); } \
209  void operator delete(void *p, Kaim::MemoryHeap*, const char*, int) \
210  { check_delete(class_name, p); KY_FREE(p); } \
211  void operator delete(void *p, Kaim::MemoryHeap*, int,const char*,int) \
212  { check_delete(class_name, p); KY_FREE(p); } \
213  void operator delete(void *p, Kaim::MemAddressPtr) \
214  { check_delete(class_name, p); KY_FREE(p); } \
215  void operator delete(void *p, Kaim::MemAddressPtr, int) \
216  { check_delete(class_name, p); KY_FREE(p); } \
217  void operator delete(void *p, Kaim::MemAddressPtr, const char*, int) \
218  { check_delete(class_name, p); KY_FREE(p); } \
219  void operator delete(void *p, Kaim::MemAddressPtr,int,const char*,int) \
220  { check_delete(class_name, p); KY_FREE(p); }
221 
222 #define KY_MEMORY_DEFINE_PLACEMENT_NEW \
223  void* operator new (Kaim::UPInt n, void *ptr) { KY_UNUSED(n); return ptr; } \
224  void operator delete (void *ptr, void *ptr2) { KY_UNUSED2(ptr,ptr2); }
225 
226 
227 #define KY_MEMORY_CHECK_DELETE_NONE(class_name, p)
228 
229 // Redefined all delete/new operators in a class without custom memory initialization
230 #define KY_MEMORY_REDEFINE_NEW(class_name, StatType) KY_MEMORY_REDEFINE_NEW_IMPL(class_name, KY_MEMORY_CHECK_DELETE_NONE, StatType)
231 
232 // Base class that overrides the new and delete operators.
233 // Deriving from this class, even as a multiple base, incurs no space overhead.
234 template<int Stat>
235 class NewOverrideBase
236 {
237 public:
238  enum { StatType = Stat };
239 
240  // Redefine all new & delete operators.
241  KY_MEMORY_REDEFINE_NEW(NewOverrideBase, Stat)
242 };
243 
244 
245 } // Scaleform
246 
247 
248 
249 // *** Restore operator 'new' Definition
250 
251 // If users specified KY__BUILD_DEFINE_NEW in preprocessor settings, use that definition.
252 #if defined(KY_BUILD_DEFINE_NEW) && !defined(KY_DEFINE_NEW)
253 #define KY_DEFINE_NEW new(__FILE__,__LINE__)
254 #endif
255 // Redefine operator 'new' if necessary.
256 #if defined(KY_DEFINE_NEW)
257 #define new KY_DEFINE_NEW
258 #endif
259 
260 
261 #endif // INC_GMEMORY_H
Definition: gamekitcrowddispersion.h:20