00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #ifndef OVR_Allocator_h
00018 #define OVR_Allocator_h
00019
00020 #include "OVR_Types.h"
00021
00022
00023
00024
00025 #if defined(OVR_CC_MSVC)
00026
00027 #pragma warning(disable : 4503)
00028 #pragma warning(disable : 4786)
00029
00030 #pragma warning(disable : 4345)
00031 #endif
00032
00033
00034 #undef new
00035
00036
00037
00038
00039
00040
00041 #ifndef __PLACEMENT_NEW_INLINE
00042 #define __PLACEMENT_NEW_INLINE
00043
00044 # if defined(OVR_CC_MWERKS) || defined(OVR_CC_BORLAND) || defined(OVR_CC_GNU)
00045 # include <new>
00046 # else
00047
00048 OVR_FORCE_INLINE void* operator new (OVR::UPInt n, void *ptr) { OVR_UNUSED(n); return ptr; }
00049 OVR_FORCE_INLINE void operator delete (void *, void *) { }
00050 # endif
00051
00052 #endif // __PLACEMENT_NEW_INLINE
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062 #define OVR_MEMORY_REDEFINE_NEW_IMPL(class_name, check_delete) \
00063 void* operator new(UPInt sz) \
00064 { void *p = OVR_ALLOC_DEBUG(sz, __FILE__, __LINE__); return p; } \
00065 void* operator new(UPInt sz, const char* file, int line) \
00066 { void* p = OVR_ALLOC_DEBUG(sz, file, line); OVR_UNUSED2(file, line); return p; } \
00067 void operator delete(void *p) \
00068 { check_delete(class_name, p); OVR_FREE(p); } \
00069 void operator delete(void *p, const char*, int) \
00070 { check_delete(class_name, p); OVR_FREE(p); }
00071
00072 #define OVR_MEMORY_DEFINE_PLACEMENT_NEW \
00073 void* operator new (UPInt n, void *ptr) { OVR_UNUSED(n); return ptr; } \
00074 void operator delete (void *ptr, void *ptr2) { OVR_UNUSED2(ptr,ptr2); }
00075
00076
00077 #define OVR_MEMORY_CHECK_DELETE_NONE(class_name, p)
00078
00079
00080 #define OVR_MEMORY_REDEFINE_NEW(class_name) \
00081 OVR_MEMORY_REDEFINE_NEW_IMPL(class_name, OVR_MEMORY_CHECK_DELETE_NONE)
00082
00083
00084 namespace OVR {
00085
00086
00087
00088
00089
00090
00091
00092
00093 template <class T>
00094 OVR_FORCE_INLINE T* Construct(void *p)
00095 {
00096 return ::new(p) T;
00097 }
00098
00099 template <class T>
00100 OVR_FORCE_INLINE T* Construct(void *p, const T& source)
00101 {
00102 return ::new(p) T(source);
00103 }
00104
00105
00106 template <class T, class S>
00107 OVR_FORCE_INLINE T* ConstructAlt(void *p, const S& source)
00108 {
00109 return ::new(p) T(source);
00110 }
00111
00112 template <class T, class S1, class S2>
00113 OVR_FORCE_INLINE T* ConstructAlt(void *p, const S1& src1, const S2& src2)
00114 {
00115 return ::new(p) T(src1, src2);
00116 }
00117
00118 template <class T>
00119 OVR_FORCE_INLINE void ConstructArray(void *p, UPInt count)
00120 {
00121 UByte *pdata = (UByte*)p;
00122 for (UPInt i=0; i< count; ++i, pdata += sizeof(T))
00123 {
00124 Construct<T>(pdata);
00125 }
00126 }
00127
00128 template <class T>
00129 OVR_FORCE_INLINE void ConstructArray(void *p, UPInt count, const T& source)
00130 {
00131 UByte *pdata = (UByte*)p;
00132 for (UPInt i=0; i< count; ++i, pdata += sizeof(T))
00133 {
00134 Construct<T>(pdata, source);
00135 }
00136 }
00137
00138 template <class T>
00139 OVR_FORCE_INLINE void Destruct(T *pobj)
00140 {
00141 pobj->~T();
00142 OVR_UNUSED1(pobj);
00143 }
00144
00145 template <class T>
00146 OVR_FORCE_INLINE void DestructArray(T *pobj, UPInt count)
00147 {
00148 for (UPInt i=0; i<count; ++i, ++pobj)
00149 pobj->~T();
00150 }
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166 class Allocator
00167 {
00168 friend class System;
00169 public:
00170
00171
00172
00173
00174
00175
00176 virtual void* Alloc(UPInt size) = 0;
00177
00178 virtual void* AllocDebug(UPInt size, const char* file, unsigned line)
00179 { OVR_UNUSED2(file, line); return Alloc(size); }
00180
00181
00182
00183
00184
00185
00186
00187 virtual void* Realloc(void* p, UPInt newSize) = 0;
00188
00189
00190
00191 virtual void Free(void *p) = 0;
00192
00193
00194
00195
00196
00197
00198
00199 virtual void* AllocAligned(UPInt size, UPInt align);
00200
00201 virtual void FreeAligned(void* p);
00202
00203
00204
00205 static Allocator* GetInstance() { return pInstance; }
00206
00207
00208 protected:
00209
00210
00211 virtual void onSystemShutdown() { }
00212
00213 public:
00214 static void setInstance(Allocator* palloc)
00215 {
00216 OVR_ASSERT((pInstance == 0) || (palloc == 0));
00217 pInstance = palloc;
00218 }
00219
00220 private:
00221
00222 static Allocator* pInstance;
00223 };
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237 template<class D>
00238 class Allocator_SingletonSupport : public Allocator
00239 {
00240 struct AllocContainer
00241 {
00242 UPInt Data[(sizeof(D) + sizeof(UPInt)-1) / sizeof(UPInt)];
00243 bool Initialized;
00244 AllocContainer() : Initialized(0) { }
00245 };
00246
00247 AllocContainer* pContainer;
00248
00249 public:
00250 Allocator_SingletonSupport() : pContainer(0) { }
00251
00252
00253
00254 static D* InitSystemSingleton()
00255 {
00256 static AllocContainer Container;
00257 OVR_ASSERT(Container.Initialized == false);
00258
00259 Allocator_SingletonSupport<D> *presult = Construct<D>((void*)Container.Data);
00260 presult->pContainer = &Container;
00261 Container.Initialized = true;
00262 return (D*)presult;
00263 }
00264
00265 protected:
00266 virtual void onSystemShutdown()
00267 {
00268 Allocator::onSystemShutdown();
00269 if (pContainer)
00270 {
00271 pContainer->Initialized = false;
00272 Destruct((D*)this);
00273 pContainer = 0;
00274 }
00275 }
00276 };
00277
00278
00279
00280
00281
00282
00283
00284 class DefaultAllocator : public Allocator_SingletonSupport<DefaultAllocator>
00285 {
00286 public:
00287 virtual void* Alloc(UPInt size);
00288 virtual void* AllocDebug(UPInt size, const char* file, unsigned line);
00289 virtual void* Realloc(void* p, UPInt newSize);
00290 virtual void Free(void *p);
00291 };
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301 #define OVR_REALLOC(p,s) OVR::Allocator::GetInstance()->Realloc((p),(s))
00302 #define OVR_FREE(p) OVR::Allocator::GetInstance()->Free((p))
00303 #define OVR_ALLOC_ALIGNED(s,a) OVR::Allocator::GetInstance()->AllocAligned((s),(a))
00304 #define OVR_FREE_ALIGNED(p) OVR::Allocator::GetInstance()->FreeAligned((p))
00305
00306 #ifdef OVR_BUILD_DEBUG
00307 #define OVR_ALLOC(s) OVR::Allocator::GetInstance()->AllocDebug((s), __FILE__, __LINE__)
00308 #define OVR_ALLOC_DEBUG(s,f,l) OVR::Allocator::GetInstance()->AllocDebug((s), f, l)
00309 #else
00310 #define OVR_ALLOC(s) OVR::Allocator::GetInstance()->Alloc((s))
00311 #define OVR_ALLOC_DEBUG(s,f,l) OVR::Allocator::GetInstance()->Alloc((s))
00312 #endif
00313
00314
00315
00316
00317
00318 class NewOverrideBase
00319 {
00320 public:
00321
00322
00323 OVR_MEMORY_REDEFINE_NEW(NewOverrideBase)
00324 };
00325
00326
00327 }
00328
00329
00330
00331 #if defined(OVR_DEFINE_NEW)
00332 #define new OVR_DEFINE_NEW
00333 #endif
00334
00335
00336 #endif // OVR_Memory