From 15740faf9fe9fe4be08965098bbf2947e096aeeb Mon Sep 17 00:00:00 2001 From: chai Date: Wed, 14 Aug 2019 22:50:43 +0800 Subject: +Unity Runtime code --- Runtime/Allocator/UnityDefaultAllocator.cpp | 284 ++++++++++++++++++++++++++++ 1 file changed, 284 insertions(+) create mode 100644 Runtime/Allocator/UnityDefaultAllocator.cpp (limited to 'Runtime/Allocator/UnityDefaultAllocator.cpp') diff --git a/Runtime/Allocator/UnityDefaultAllocator.cpp b/Runtime/Allocator/UnityDefaultAllocator.cpp new file mode 100644 index 0000000..a2ec30c --- /dev/null +++ b/Runtime/Allocator/UnityDefaultAllocator.cpp @@ -0,0 +1,284 @@ +#include "UnityPrefix.h" +#include "UnityDefaultAllocator.h" + +#if ENABLE_MEMORY_MANAGER + +#include "Runtime/Allocator/AllocationHeader.h" +#include "Runtime/Profiler/MemoryProfiler.h" +#include "Runtime/Utilities/BitUtility.h" +#include "Runtime/Allocator/MemoryManager.h" + +template +UnityDefaultAllocator::UnityDefaultAllocator(const char* name) +: BaseAllocator(name) +{ + memset(m_PageAllocationList,0,sizeof(m_PageAllocationList)); +} + +template +void* UnityDefaultAllocator::Allocate (size_t size, int align) +{ + size_t realSize = AllocationHeader::CalculateNeededAllocationSize(size, align); + void* rawPtr = LLAlloctor::Malloc( realSize ); + if(rawPtr == NULL) + return NULL; + + void* realPtr = AddHeaderAndFooter(rawPtr, size, align); + RegisterAllocation(realPtr); + + return realPtr; +} + +template +void* UnityDefaultAllocator::Reallocate( void* p, size_t size, int align) +{ + if (p == NULL) + return Allocate(size, align); + + AllocationHeader::ValidateIntegrity(p, m_AllocatorIdentifier, align); + RegisterDeallocation(p); + + size_t oldSize = GetPtrSize(p); + size_t oldPadCount = AllocationHeader::GetHeader(p)->GetPadding(); + + void* realPtr = AllocationHeader::GetRealPointer(p); + size_t realSize = AllocationHeader::CalculateNeededAllocationSize(size, align); + char* rawPtr = (char*)LLAlloctor::Realloc(realPtr, realSize); + if(rawPtr == NULL) + return NULL; + + int newPadCount = AllocationHeader::GetRequiredPadding(rawPtr, align); + + if (newPadCount != oldPadCount){ + // new ptr needs different align padding. move memory and repad + char* srcptr = rawPtr + AllocationHeader::GetHeaderSize() + oldPadCount; + char* dstptr = rawPtr + AllocationHeader::GetHeaderSize() + newPadCount; + memmove(dstptr, srcptr, ( oldSize < size ? oldSize : size ) ); + } + + void* newptr = AddHeaderAndFooter(rawPtr, size, align); + RegisterAllocation(newptr); + + return newptr; +} + +template +void UnityDefaultAllocator::Deallocate (void* p) +{ + if (p == NULL) + return; + + AllocationHeader::ValidateIntegrity(p, m_AllocatorIdentifier); + RegisterDeallocation(p); + + void* realpointer = AllocationHeader::GetRealPointer(p); + + LLAlloctor::Free(realpointer); +} + +template +template +bool UnityDefaultAllocator::AllocationPage(const void* p){ + + // A memory and performance optimization could be to register lone pointers in the array instead of setting the bit. + // when multiple pointers arrive, pull the pointer out, register it, and register the next. Requires some bookkeeping. + // bottom 2 bits of the pointer can be used for flags. + int pageAllocationListIndex = 0; + UInt32 val = (UInt32)p; + + if(sizeof(void*) > sizeof(UInt32)) + { + Assert(sizeof(void*) == sizeof(UInt64)); + UInt32 highbits = (UInt32)((UInt64)(uintptr_t)(p) >> 32); + if(highbits != 0) + { + pageAllocationListIndex = -1; + for(int i = 0; i < kNumPageAllocationBlocks; i++) + if(m_PageAllocationList[i].m_HighBits == highbits) + pageAllocationListIndex = i; + + if(pageAllocationListIndex == -1) + { + // highbits not found in the list. find a free list element + for(int i = 0; i < kNumPageAllocationBlocks; i++) + { + if(m_PageAllocationList[i].m_PageAllocations == NULL) + { + m_PageAllocationList[i].m_HighBits = highbits; + pageAllocationListIndex = i; + break; + } + } + if(requestType == kTest) + { + return false; + } + else + { + if(pageAllocationListIndex == -1) + ErrorString("Using memoryadresses from more that 16GB of memory"); + } + } + } + } + + int ****& pageAllocations = m_PageAllocationList[pageAllocationListIndex].m_PageAllocations; + int page1 = (val >> (32-kPage1Bits)) & ((1<> (32-kPage1Bits-kPage2Bits)) & ((1<> (32-kPage1Bits-kPage2Bits-kPage3Bits)) & ((1<> (32-kPage1Bits-kPage2Bits-kPage3Bits-kPage4Bits)) & ((1<> kTargetBitsRepresentedPerBit) & 0x1F; + + if(requestType == kUnregister){ + Assert(pageAllocations != NULL); + Assert(pageAllocations[page1] != NULL); + Assert(pageAllocations[page1][page2] != NULL); + Assert(pageAllocations[page1][page2][page3] != NULL); + + pageAllocations[page1][page2][page3][page4] &= ~(1< +void* UnityDefaultAllocator::AddHeaderAndFooter( void* ptr, size_t size, int align ) const +{ + Assert(align >= kDefaultMemoryAlignment && align <= 16*1024 && IsPowerOfTwo(align)); + // calculate required padding for ptr to be aligned after header addition + // ppppppppHHHH*********** + int padCount = AllocationHeader::GetRequiredPadding(ptr, align); + void* realPtr = ((char*)ptr) + (padCount + AllocationHeader::GetHeaderSize()); + AllocationHeader::Set(realPtr, m_AllocatorIdentifier, size, padCount, align); + return realPtr; +} + +template +void UnityDefaultAllocator::RegisterAllocation( const void* p ) +{ + Mutex::AutoLock lock(m_AllocLock); + const size_t ptrSize = GetPtrSize(p); + const int overheadSize = AllocationHeader::GetHeader(p)->GetOverheadSize(); + RegisterAllocationData(ptrSize, overheadSize); + m_TotalReservedMemory += ptrSize + overheadSize; + AllocationPage(p); +} + +template +void UnityDefaultAllocator::RegisterDeallocation( const void* p ) +{ + Mutex::AutoLock lock(m_AllocLock); + const size_t ptrSize = GetPtrSize(p); + const int overheadSize = AllocationHeader::GetHeader(p)->GetOverheadSize(); + RegisterDeallocationData(ptrSize, overheadSize); + m_TotalReservedMemory -= ptrSize + overheadSize; + AllocationPage(p); +} + +template +bool UnityDefaultAllocator::Contains (const void* p) +{ + Mutex::AutoLock lock(m_AllocLock); + return AllocationPage(p); +} + +template +size_t UnityDefaultAllocator::GetPtrSize( const void* ptr ) const +{ + return AllocationHeader::GetHeader(ptr)->GetRequestedSize(); +} + +template +ProfilerAllocationHeader* UnityDefaultAllocator::GetProfilerHeader(const void* ptr) const +{ + // LocalHeader:ProfilerHeader:Data + return AllocationHeader::GetProfilerHeader(ptr); +} + +template +int UnityDefaultAllocator::GetOverheadSize(void* ptr) +{ + return AllocationHeader::GetHeader(ptr)->GetOverheadSize(); +} + +template class UnityDefaultAllocator; + +#endif -- cgit v1.1-26-g67d0