1 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3 * Contains all memory macros.
4 * \file IceMemoryMacros.h
5 * \author Pierre Terdiman
8 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
10 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
12 #ifndef ICEMEMORYMACROS_H
13 #define ICEMEMORYMACROS_H
21 //! \param addr [in] buffer address
22 //! \param size [in] buffer length
27 inline_ void ZeroMemory(void* addr, regsize size) { memset(addr, 0, size); }
29 //! Fills a buffer with a given byte.
30 //! \param addr [in] buffer address
31 //! \param size [in] buffer length
32 //! \param val [in] the byte value
37 inline_ void FillMemory(void* dest, regsize size, ubyte val) { memset(dest, val, size); }
39 //! Fills a buffer with a given dword.
40 //! \param addr [in] buffer address
41 //! \param nb [in] number of dwords to write
42 //! \param value [in] the dword value
47 //! \warning writes nb*4 bytes !
48 inline_ void StoreDwords(udword* dest, udword nb, udword value)
50 // The asm code below **SHOULD** be equivalent to one of those C versions
51 // or the other if your compiled is good: (checked on VC++ 6.0)
53 // 1) while(nb--) *dest++ = value;
55 // 2) for(udword i=0;i<nb;i++) dest[i] = value;
70 //! \param addr [in] destination buffer address
71 //! \param addr [in] source buffer address
72 //! \param size [in] buffer length
77 inline_ void CopyMemory(void* dest, const void* src, regsize size) { memcpy(dest, src, size); }
80 //! \param addr [in] destination buffer address
81 //! \param addr [in] source buffer address
82 //! \param size [in] buffer length
87 inline_ void MoveMemory(void* dest, const void* src, regsize size) { memmove(dest, src, size); }
89 //! Flexible buffer copy
90 //! \param src [in] source buffer address
91 //! \param dst [in] destination buffer address
92 //! \param nb_elem [in] number of elements to copy
93 //! \param elem_size [in] size of an element
94 //! \param stride [in] stride in bytes, including size of element
95 inline_ void FlexiCopy(const void* src, void* dst, udword nb_elem, regsize elem_size, udword stride)
97 ubyte* d = (ubyte*)dst;
98 const ubyte* s = (const ubyte*)src;
99 const ubyte* Last = s + stride*nb_elem;
102 CopyMemory(d, s, elem_size);
108 //! Gives the size of current object. This avoids some mistakes (e.g. "sizeof(this)").
109 #define SIZEOFOBJECT sizeof(*this)
111 //! Clears current object. Laziness is my business! HANDLE WITH CARE. ### Removed, too dangerous, cleared too many v-tables
112 //#define CLEAROBJECT { memset(this, 0, SIZEOFOBJECT); }
114 // The two macros below are here for several reasons:
115 // - sometimes we write "delete x" instead of "delete []x" just because we don't pay attention. Using the macro forces you
116 // to think about what you're deleting, just because you have to write the macro's name (SINGLE or ARRAY).
117 // - always clearing the pointer afterwards prevents some double-deletion in various situations.
118 // - deleting null is a valid operation according to the standard, yet some lame memory managers don't like it. In sake of
119 // robustness, we avoid trying.
121 //! Deletes an instance of a class.
122 #define DELETESINGLE(x) if (x) { delete x; x = null; }
123 //! Deletes an array.
124 #define DELETEARRAY(x) if (x) { delete []x; x = null; }
126 //! Safe D3D-style release
127 #define SAFE_RELEASE(x) if (x) { (x)->Release(); (x) = null; }
129 //! Safe ICE-style release
130 #define SAFE_DESTRUCT(x) if (x) { (x)->SelfDestruct(); (x) = null; }
133 //! Standard alloc checking. HANDLE WITH CARE. Relies on strict coding rules. Probably shouldn't be used outside of ICE.
134 #define CHECKALLOC(x) if(!x) return SetIceError("Out of memory.", EC_OUT_OF_MEMORY);
136 #define CHECKALLOC(x) if(!x) return false;
139 //! Standard allocation cycle
140 #define SAFE_ALLOC(ptr, type, count) DELETEARRAY(ptr); ptr = new type[count]; CHECKALLOC(ptr);
141 #define SAFE_ICE_ALLOC(ptr, type, count) DELETEARRAY(ptr); ptr = ICE_NEW(type)[count]; CHECKALLOC(ptr);
143 //! Don't use inline for alloca !!!
145 #define StackAlloc(x) _alloca(x)
147 #define StackAlloc(x) alloca(x)
148 #elif defined(__APPLE__)
149 #define StackAlloc(x) alloca(x)
151 #define StackAlloc(x) _alloca(x)
155 // #define ICE_ALLOC_TMP(x) GetAllocator()->mallocDebug(x, __FILE__, __LINE__, #x, MEMORY_TEMP)
156 // #define ICE_ALLOC(x) GetAllocator()->mallocDebug(x, __FILE__, __LINE__, #x, MEMORY_PERSISTENT)
157 #define ICE_ALLOC_TMP(x) GetAllocator()->mallocDebug(x, __FILE__, __LINE__, "(undefined)", MEMORY_TEMP)
158 #define ICE_ALLOC(x) GetAllocator()->mallocDebug(x, __FILE__, __LINE__, "(undefined)", MEMORY_PERSISTENT)
159 #define ICE_ALLOC_TMP2(x, y) GetAllocator()->mallocDebug(x, __FILE__, __LINE__, #y, MEMORY_TEMP)
160 #define ICE_ALLOC2(x, y) GetAllocator()->mallocDebug(x, __FILE__, __LINE__, #y, MEMORY_PERSISTENT)
162 #define ICE_ALLOC_TMP(x) GetAllocator()->malloc(x, MEMORY_TEMP)
163 #define ICE_ALLOC(x) GetAllocator()->malloc(x, MEMORY_PERSISTENT)
165 #define ICE_FREE(x) if(x) { GetAllocator()->free(x); x = null; }
167 #ifdef DONT_TRACK_MEMORY_LEAKS
169 #define ICE_NEW_TMP(x) new(__FILE__, __LINE__, #x, MEMORY_TEMP) x
170 #define ICE_NEW(x) new(__FILE__, __LINE__, #x, MEMORY_PERSISTENT) x
172 #define ICE_NEW_TMP(x) new(MEMORY_TEMP) x
173 #define ICE_NEW(x) new(MEMORY_PERSISTENT) x
176 #define ICE_NEW_TMP(x) new x
177 #define ICE_NEW(x) new x
180 #endif // ICEMEMORYMACROS_H