diff options
author | chai <chaifix@163.com> | 2019-08-14 22:50:43 +0800 |
---|---|---|
committer | chai <chaifix@163.com> | 2019-08-14 22:50:43 +0800 |
commit | 15740faf9fe9fe4be08965098bbf2947e096aeeb (patch) | |
tree | a730ec236656cc8cab5b13f088adfaed6bb218fb /Runtime/Allocator/AllocationHeader.h |
Diffstat (limited to 'Runtime/Allocator/AllocationHeader.h')
-rw-r--r-- | Runtime/Allocator/AllocationHeader.h | 159 |
1 files changed, 159 insertions, 0 deletions
diff --git a/Runtime/Allocator/AllocationHeader.h b/Runtime/Allocator/AllocationHeader.h new file mode 100644 index 0000000..8d66159 --- /dev/null +++ b/Runtime/Allocator/AllocationHeader.h @@ -0,0 +1,159 @@ +#ifndef ALLOCATION_HEADER_H_ +#define ALLOCATION_HEADER_H_ + +#if ENABLE_MEMORY_MANAGER + +#include "Runtime/Profiler/MemoryProfiler.h" + +#define USE_MEMORY_DEBUGGING (!UNITY_RELEASE && !(UNITY_LINUX && UNITY_64)) +#if UNITY_LINUX +#pragma warning "FIXME LINUX: 64bit memory debugging" +#endif + +/* +Allocation Header: +(12345hhhhhhhhmmmm____________) (1-n:paddingcount, h: header, m:memoryprofiler) +hasPadding: 1 bit +size: 31 bit +*********USE_MEMORY_DEBUGGING********* + allocator: 16 bit + magicValue: 12 bit +*********USE_MEMORY_DEBUGGING********* +--------------- +Followed by x bytes requested by MemoryProfiler +---------------------------------------- +Actual Allocated Data +---------------------------------------- +*********USE_MEMORY_DEBUGGING********* +Followed by a footer if memory guarding is enabled +*********USE_MEMORY_DEBUGGING********* +*/ + +struct AllocationHeader +{ +public: + static void Set(void* ptr, int id, int size, int padCount, int align); + static AllocationHeader* GetHeader(const void* ptr); + static ProfilerAllocationHeader* GetProfilerHeader(const void* ptr); + + UInt32 GetPadding () const { return m_HasPadding ? *(((UInt32*)(this))-1) : 0; } + size_t GetRequestedSize () const { return m_AllocationSize; } + + static size_t CalculateNeededAllocationSize( size_t size, int align ); + static void ValidateIntegrity(void* ptr, int id, int align = -1); + static void* GetRealPointer( void* ptr ); + static int GetRequiredPadding(void* realptr, int align); + static int GetHeaderSize(); + static AllocationHeader* GetHeaderFromRealPointer( const void* realptr ); + + int GetOverheadSize(); + +private: + + // prev byte is padding count, if there is padding + UInt32 m_HasPadding : 1; + UInt32 m_AllocationSize : 31; + +#if USE_MEMORY_DEBUGGING + // DEBUG: + SInt16 m_AllocatorIdentifier; + UInt16 m_Magic : 12; + static const UInt32 kMagicValue = 0xDFA; + static const UInt32 kFooterSize = 4; +#else + static const UInt32 kFooterSize = 0; +#endif + + // followed by x bytes used for memory profiling header (0 if no memory profiling) +}; + +inline void AllocationHeader::Set(void* ptr, int id, int size, int padCount, int align) +{ + AllocationHeader* header = GetHeader(ptr); + header->m_AllocationSize = size; + header->m_HasPadding = padCount != 0; + if(header->m_HasPadding) + *(((UInt32*)(header))-1) = padCount; +#if USE_MEMORY_DEBUGGING + // set header + if(header->m_HasPadding) // set leading bytes + memset(((char*)header)-padCount,0xAA,padCount-4); + + header->m_AllocatorIdentifier = id; + header->m_Magic = kMagicValue; + // set footer + memset(((char*)ptr)+size,0xFD,kFooterSize); +#endif +} + +inline ProfilerAllocationHeader* AllocationHeader::GetProfilerHeader( const void* ptr ) +{ + return (ProfilerAllocationHeader*)( (const char*)ptr - MemoryProfiler::GetHeaderSize() ); +} + +inline AllocationHeader* AllocationHeader::GetHeader( const void* ptr ) +{ + return (AllocationHeader*)( (const char*)ptr - GetHeaderSize() ); +} + +inline int AllocationHeader::GetHeaderSize() +{ + return sizeof(AllocationHeader) + MemoryProfiler::GetHeaderSize(); +} + +inline int AllocationHeader::GetRequiredPadding( void* realptr, int align ) +{ + return align - ((((int)realptr + GetHeaderSize() - 1)&(align - 1)) + 1); +} + +inline size_t AllocationHeader::CalculateNeededAllocationSize( size_t size, int align ) +{ + int alignMask = align-1; + return size + GetHeaderSize() + kFooterSize + alignMask; +} + +inline void* AllocationHeader::GetRealPointer( void* ptr ) +{ + AllocationHeader* header = GetHeader(ptr); + int padCount = header->GetPadding(); + return ((char*)header) - padCount; +} + +inline int AllocationHeader::GetOverheadSize() +{ + int alignMask = kDefaultMemoryAlignment-1; // estimate + return GetHeaderSize() + kFooterSize + alignMask; +} + +inline AllocationHeader* AllocationHeader::GetHeaderFromRealPointer( const void* realptr ) +{ +#if USE_MEMORY_DEBUGGING + unsigned char* ptr = (unsigned char*)realptr; + while(*ptr == 0xAA) + ptr++; + AllocationHeader* header = (AllocationHeader*)ptr; + if(header->m_Magic != kMagicValue) + header = (AllocationHeader*)(ptr+4); + return header; +#else + return NULL; +#endif +} + +inline void AllocationHeader::ValidateIntegrity( void* ptr, int id, int /*align*/ ) +{ +#if USE_MEMORY_DEBUGGING + AllocationHeader* header = GetHeader(ptr); + Assert(header->m_Magic == AllocationHeader::kMagicValue); + Assert(id == -1 || id == header->m_AllocatorIdentifier); + + int size = header->m_AllocationSize; + unsigned char* footer = ((unsigned char*)ptr)+size; + for(int i = 0; i < kFooterSize; i++, footer++) + Assert(*footer == 0xFD); +#endif +} + +#endif + +#endif |