Saxum/extern/bullet/Extras/CDTestFramework/Opcode/Ice/IceMemoryMacros.h
Fabian Klemp aeb6218d2d Renaming.
2014-10-24 11:49:46 +02:00

181 lines
6.6 KiB
C

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/**
* Contains all memory macros.
* \file IceMemoryMacros.h
* \author Pierre Terdiman
* \date April, 4, 2000
*/
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Include Guard
#ifndef ICEMEMORYMACROS_H
#define ICEMEMORYMACROS_H
#undef ZeroMemory
#undef CopyMemory
#undef MoveMemory
#undef FillMemory
//! Clears a buffer.
//! \param addr [in] buffer address
//! \param size [in] buffer length
//! \see FillMemory
//! \see StoreDwords
//! \see CopyMemory
//! \see MoveMemory
inline_ void ZeroMemory(void* addr, regsize size) { memset(addr, 0, size); }
//! Fills a buffer with a given byte.
//! \param addr [in] buffer address
//! \param size [in] buffer length
//! \param val [in] the byte value
//! \see StoreDwords
//! \see ZeroMemory
//! \see CopyMemory
//! \see MoveMemory
inline_ void FillMemory(void* dest, regsize size, ubyte val) { memset(dest, val, size); }
//! Fills a buffer with a given dword.
//! \param addr [in] buffer address
//! \param nb [in] number of dwords to write
//! \param value [in] the dword value
//! \see FillMemory
//! \see ZeroMemory
//! \see CopyMemory
//! \see MoveMemory
//! \warning writes nb*4 bytes !
inline_ void StoreDwords(udword* dest, udword nb, udword value)
{
// The asm code below **SHOULD** be equivalent to one of those C versions
// or the other if your compiled is good: (checked on VC++ 6.0)
//
// 1) while(nb--) *dest++ = value;
//
// 2) for(udword i=0;i<nb;i++) dest[i] = value;
//
_asm push eax
_asm push ecx
_asm push edi
_asm mov edi, dest
_asm mov ecx, nb
_asm mov eax, value
_asm rep stosd
_asm pop edi
_asm pop ecx
_asm pop eax
}
//! Copies a buffer.
//! \param addr [in] destination buffer address
//! \param addr [in] source buffer address
//! \param size [in] buffer length
//! \see ZeroMemory
//! \see FillMemory
//! \see StoreDwords
//! \see MoveMemory
inline_ void CopyMemory(void* dest, const void* src, regsize size) { memcpy(dest, src, size); }
//! Moves a buffer.
//! \param addr [in] destination buffer address
//! \param addr [in] source buffer address
//! \param size [in] buffer length
//! \see ZeroMemory
//! \see FillMemory
//! \see StoreDwords
//! \see CopyMemory
inline_ void MoveMemory(void* dest, const void* src, regsize size) { memmove(dest, src, size); }
//! Flexible buffer copy
//! \param src [in] source buffer address
//! \param dst [in] destination buffer address
//! \param nb_elem [in] number of elements to copy
//! \param elem_size [in] size of an element
//! \param stride [in] stride in bytes, including size of element
inline_ void FlexiCopy(const void* src, void* dst, udword nb_elem, regsize elem_size, udword stride)
{
ubyte* d = (ubyte*)dst;
const ubyte* s = (const ubyte*)src;
const ubyte* Last = s + stride*nb_elem;
while(s!=Last)
{
CopyMemory(d, s, elem_size);
d += elem_size;
s += stride;
}
}
//! Gives the size of current object. This avoids some mistakes (e.g. "sizeof(this)").
#define SIZEOFOBJECT sizeof(*this)
//! Clears current object. Laziness is my business! HANDLE WITH CARE. ### Removed, too dangerous, cleared too many v-tables
//#define CLEAROBJECT { memset(this, 0, SIZEOFOBJECT); }
// The two macros below are here for several reasons:
// - sometimes we write "delete x" instead of "delete []x" just because we don't pay attention. Using the macro forces you
// to think about what you're deleting, just because you have to write the macro's name (SINGLE or ARRAY).
// - always clearing the pointer afterwards prevents some double-deletion in various situations.
// - deleting null is a valid operation according to the standard, yet some lame memory managers don't like it. In sake of
// robustness, we avoid trying.
//! Deletes an instance of a class.
#define DELETESINGLE(x) if (x) { delete x; x = null; }
//! Deletes an array.
#define DELETEARRAY(x) if (x) { delete []x; x = null; }
//! Safe D3D-style release
#define SAFE_RELEASE(x) if (x) { (x)->Release(); (x) = null; }
//! Safe ICE-style release
#define SAFE_DESTRUCT(x) if (x) { (x)->SelfDestruct(); (x) = null; }
#ifdef ICEERROR_H
//! Standard alloc checking. HANDLE WITH CARE. Relies on strict coding rules. Probably shouldn't be used outside of ICE.
#define CHECKALLOC(x) if(!x) return SetIceError("Out of memory.", EC_OUT_OF_MEMORY);
#else
#define CHECKALLOC(x) if(!x) return false;
#endif
//! Standard allocation cycle
#define SAFE_ALLOC(ptr, type, count) DELETEARRAY(ptr); ptr = new type[count]; CHECKALLOC(ptr);
#define SAFE_ICE_ALLOC(ptr, type, count) DELETEARRAY(ptr); ptr = ICE_NEW(type)[count]; CHECKALLOC(ptr);
//! Don't use inline for alloca !!!
#ifdef WIN32
#define StackAlloc(x) _alloca(x)
#elif LINUX
#define StackAlloc(x) alloca(x)
#elif defined(__APPLE__)
#define StackAlloc(x) alloca(x)
#elif defined(_XBOX)
#define StackAlloc(x) _alloca(x)
#endif
#ifdef _DEBUG
// #define ICE_ALLOC_TMP(x) GetAllocator()->mallocDebug(x, __FILE__, __LINE__, #x, MEMORY_TEMP)
// #define ICE_ALLOC(x) GetAllocator()->mallocDebug(x, __FILE__, __LINE__, #x, MEMORY_PERSISTENT)
#define ICE_ALLOC_TMP(x) GetAllocator()->mallocDebug(x, __FILE__, __LINE__, "(undefined)", MEMORY_TEMP)
#define ICE_ALLOC(x) GetAllocator()->mallocDebug(x, __FILE__, __LINE__, "(undefined)", MEMORY_PERSISTENT)
#define ICE_ALLOC_TMP2(x, y) GetAllocator()->mallocDebug(x, __FILE__, __LINE__, #y, MEMORY_TEMP)
#define ICE_ALLOC2(x, y) GetAllocator()->mallocDebug(x, __FILE__, __LINE__, #y, MEMORY_PERSISTENT)
#else
#define ICE_ALLOC_TMP(x) GetAllocator()->malloc(x, MEMORY_TEMP)
#define ICE_ALLOC(x) GetAllocator()->malloc(x, MEMORY_PERSISTENT)
#endif
#define ICE_FREE(x) if(x) { GetAllocator()->free(x); x = null; }
#ifdef DONT_TRACK_MEMORY_LEAKS
#ifdef _DEBUG
#define ICE_NEW_TMP(x) new(__FILE__, __LINE__, #x, MEMORY_TEMP) x
#define ICE_NEW(x) new(__FILE__, __LINE__, #x, MEMORY_PERSISTENT) x
#else
#define ICE_NEW_TMP(x) new(MEMORY_TEMP) x
#define ICE_NEW(x) new(MEMORY_PERSISTENT) x
#endif
#else
#define ICE_NEW_TMP(x) new x
#define ICE_NEW(x) new x
#endif
#endif // ICEMEMORYMACROS_H