diff options
Diffstat (limited to 'src/3rdparty/angle/src/compiler/translator/PoolAlloc.cpp')
-rw-r--r-- | src/3rdparty/angle/src/compiler/translator/PoolAlloc.cpp | 227 |
1 files changed, 146 insertions, 81 deletions
diff --git a/src/3rdparty/angle/src/compiler/translator/PoolAlloc.cpp b/src/3rdparty/angle/src/compiler/translator/PoolAlloc.cpp index 887cb66504..0f1cd8b5c9 100644 --- a/src/3rdparty/angle/src/compiler/translator/PoolAlloc.cpp +++ b/src/3rdparty/angle/src/compiler/translator/PoolAlloc.cpp @@ -6,16 +6,16 @@ #include "compiler/translator/PoolAlloc.h" -#include "compiler/translator/InitializeGlobals.h" - -#include "common/platform.h" -#include "common/angleutils.h" -#include "common/tls.h" - #include <stdint.h> #include <stdio.h> #include <assert.h> +#include "common/angleutils.h" +#include "common/debug.h" +#include "common/platform.h" +#include "common/tls.h" +#include "compiler/translator/InitializeGlobals.h" + TLSIndex PoolIndex = TLS_INVALID_INDEX; bool InitializePoolIndex() @@ -34,13 +34,13 @@ void FreePoolIndex() PoolIndex = TLS_INVALID_INDEX; } -TPoolAllocator* GetGlobalPoolAllocator() +TPoolAllocator *GetGlobalPoolAllocator() { assert(PoolIndex != TLS_INVALID_INDEX); - return static_cast<TPoolAllocator*>(GetTLSValue(PoolIndex)); + return static_cast<TPoolAllocator *>(GetTLSValue(PoolIndex)); } -void SetGlobalPoolAllocator(TPoolAllocator* poolAllocator) +void SetGlobalPoolAllocator(TPoolAllocator *poolAllocator) { assert(PoolIndex != TLS_INVALID_INDEX); SetTLSValue(PoolIndex, poolAllocator); @@ -50,56 +50,66 @@ void SetGlobalPoolAllocator(TPoolAllocator* poolAllocator) // Implement the functionality of the TPoolAllocator class, which // is documented in PoolAlloc.h. // -TPoolAllocator::TPoolAllocator(int growthIncrement, int allocationAlignment) : - pageSize(growthIncrement), - alignment(allocationAlignment), - freeList(0), - inUseList(0), - numCalls(0), - totalBytes(0) +TPoolAllocator::TPoolAllocator(int growthIncrement, int allocationAlignment) + : alignment(allocationAlignment), +#if !defined(ANGLE_TRANSLATOR_DISABLE_POOL_ALLOC) + pageSize(growthIncrement), + freeList(0), + inUseList(0), + numCalls(0), + totalBytes(0), +#endif + mLocked(false) { // - // Don't allow page sizes we know are smaller than all common - // OS page sizes. - // - if (pageSize < 4*1024) - pageSize = 4*1024; - - // - // A large currentPageOffset indicates a new page needs to - // be obtained to allocate memory. - // - currentPageOffset = pageSize; - - // // Adjust alignment to be at least pointer aligned and // power of 2. // - size_t minAlign = sizeof(void*); + size_t minAlign = sizeof(void *); alignment &= ~(minAlign - 1); if (alignment < minAlign) alignment = minAlign; - size_t a = 1; + size_t a = 1; while (a < alignment) a <<= 1; - alignment = a; + alignment = a; alignmentMask = a - 1; +#if !defined(ANGLE_TRANSLATOR_DISABLE_POOL_ALLOC) + // + // Don't allow page sizes we know are smaller than all common + // OS page sizes. + // + if (pageSize < 4 * 1024) + pageSize = 4 * 1024; + + // + // A large currentPageOffset indicates a new page needs to + // be obtained to allocate memory. + // + currentPageOffset = pageSize; + // // Align header skip // headerSkip = minAlign; - if (headerSkip < sizeof(tHeader)) { + if (headerSkip < sizeof(tHeader)) + { headerSkip = (sizeof(tHeader) + alignmentMask) & ~alignmentMask; } +#else // !defined(ANGLE_TRANSLATOR_DISABLE_POOL_ALLOC) + mStack.push_back({}); +#endif } TPoolAllocator::~TPoolAllocator() { - while (inUseList) { - tHeader* next = inUseList->nextPage; +#if !defined(ANGLE_TRANSLATOR_DISABLE_POOL_ALLOC) + while (inUseList) + { + tHeader *next = inUseList->nextPage; inUseList->~tHeader(); - delete [] reinterpret_cast<char*>(inUseList); + delete[] reinterpret_cast<char *>(inUseList); inUseList = next; } @@ -107,11 +117,22 @@ TPoolAllocator::~TPoolAllocator() // here, because we did it already when the block was // placed into the free list. // - while (freeList) { - tHeader* next = freeList->nextPage; - delete [] reinterpret_cast<char*>(freeList); + while (freeList) + { + tHeader *next = freeList->nextPage; + delete[] reinterpret_cast<char *>(freeList); freeList = next; } +#else // !defined(ANGLE_TRANSLATOR_DISABLE_POOL_ALLOC) + for (auto &allocs : mStack) + { + for (auto alloc : allocs) + { + free(alloc); + } + } + mStack.clear(); +#endif } // Support MSVC++ 6.0 @@ -120,28 +141,32 @@ const unsigned char TAllocation::guardBlockEndVal = 0xfe; const unsigned char TAllocation::userDataFill = 0xcd; #ifdef GUARD_BLOCKS - const size_t TAllocation::guardBlockSize = 16; +const size_t TAllocation::guardBlockSize = 16; #else - const size_t TAllocation::guardBlockSize = 0; +const size_t TAllocation::guardBlockSize = 0; #endif // // Check a single guard block for damage // -void TAllocation::checkGuardBlock(unsigned char* blockMem, unsigned char val, const char* locText) const +void TAllocation::checkGuardBlock(unsigned char *blockMem, + unsigned char val, + const char *locText) const { #ifdef GUARD_BLOCKS - for (size_t x = 0; x < guardBlockSize; x++) { - if (blockMem[x] != val) { + for (size_t x = 0; x < guardBlockSize; x++) + { + if (blockMem[x] != val) + { char assertMsg[80]; - // We don't print the assert message. It's here just to be helpful. +// We don't print the assert message. It's here just to be helpful. #if defined(_MSC_VER) - snprintf(assertMsg, sizeof(assertMsg), "PoolAlloc: Damage %s %Iu byte allocation at 0x%p\n", - locText, size, data()); + snprintf(assertMsg, sizeof(assertMsg), + "PoolAlloc: Damage %s %Iu byte allocation at 0x%p\n", locText, size, data()); #else - snprintf(assertMsg, sizeof(assertMsg), "PoolAlloc: Damage %s %zu byte allocation at 0x%p\n", - locText, size, data()); + snprintf(assertMsg, sizeof(assertMsg), + "PoolAlloc: Damage %s %zu byte allocation at 0x%p\n", locText, size, data()); #endif assert(0 && "PoolAlloc: Damage in guard block"); } @@ -149,17 +174,20 @@ void TAllocation::checkGuardBlock(unsigned char* blockMem, unsigned char val, co #endif } - void TPoolAllocator::push() { - tAllocState state = { currentPageOffset, inUseList }; +#if !defined(ANGLE_TRANSLATOR_DISABLE_POOL_ALLOC) + tAllocState state = {currentPageOffset, inUseList}; + + mStack.push_back(state); - stack.push_back(state); - // // Indicate there is no current page to allocate from. // currentPageOffset = pageSize; +#else // !defined(ANGLE_TRANSLATOR_DISABLE_POOL_ALLOC) + mStack.push_back({}); +#endif } // @@ -171,27 +199,37 @@ void TPoolAllocator::push() // void TPoolAllocator::pop() { - if (stack.size() < 1) + if (mStack.size() < 1) return; - tHeader* page = stack.back().page; - currentPageOffset = stack.back().offset; +#if !defined(ANGLE_TRANSLATOR_DISABLE_POOL_ALLOC) + tHeader *page = mStack.back().page; + currentPageOffset = mStack.back().offset; - while (inUseList != page) { + while (inUseList != page) + { // invoke destructor to free allocation list inUseList->~tHeader(); - - tHeader* nextInUse = inUseList->nextPage; + + tHeader *nextInUse = inUseList->nextPage; if (inUseList->pageCount > 1) - delete [] reinterpret_cast<char*>(inUseList); - else { + delete[] reinterpret_cast<char *>(inUseList); + else + { inUseList->nextPage = freeList; - freeList = inUseList; + freeList = inUseList; } inUseList = nextInUse; } - stack.pop_back(); + mStack.pop_back(); +#else // !defined(ANGLE_TRANSLATOR_DISABLE_POOL_ALLOC) + for (auto &alloc : mStack.back()) + { + free(alloc); + } + mStack.pop_back(); +#endif } // @@ -200,12 +238,15 @@ void TPoolAllocator::pop() // void TPoolAllocator::popAll() { - while (stack.size() > 0) + while (mStack.size() > 0) pop(); } -void* TPoolAllocator::allocate(size_t numBytes) +void *TPoolAllocator::allocate(size_t numBytes) { + ASSERT(!mLocked); + +#if !defined(ANGLE_TRANSLATOR_DISABLE_POOL_ALLOC) // // Just keep some interesting statistics. // @@ -226,18 +267,20 @@ void* TPoolAllocator::allocate(size_t numBytes) // Do the allocation, most likely case first, for efficiency. // This step could be moved to be inline sometime. // - if (allocationSize <= pageSize - currentPageOffset) { + if (allocationSize <= pageSize - currentPageOffset) + { // // Safe to allocate from currentPageOffset. // - unsigned char* memory = reinterpret_cast<unsigned char *>(inUseList) + currentPageOffset; + unsigned char *memory = reinterpret_cast<unsigned char *>(inUseList) + currentPageOffset; currentPageOffset += allocationSize; currentPageOffset = (currentPageOffset + alignmentMask) & ~alignmentMask; return initializeAllocation(inUseList, memory, numBytes); } - if (allocationSize > pageSize - headerSkip) { + if (allocationSize > pageSize - headerSkip) + { // // Do a multi-page allocation. Don't mix these with the others. // The OS is efficient and allocating and free-ing multiple pages. @@ -247,49 +290,71 @@ void* TPoolAllocator::allocate(size_t numBytes) if (numBytesToAlloc < allocationSize) return 0; - tHeader* memory = reinterpret_cast<tHeader*>(::new char[numBytesToAlloc]); + tHeader *memory = reinterpret_cast<tHeader *>(::new char[numBytesToAlloc]); if (memory == 0) return 0; // Use placement-new to initialize header - new(memory) tHeader(inUseList, (numBytesToAlloc + pageSize - 1) / pageSize); + new (memory) tHeader(inUseList, (numBytesToAlloc + pageSize - 1) / pageSize); inUseList = memory; currentPageOffset = pageSize; // make next allocation come from a new page // No guard blocks for multi-page allocations (yet) - return reinterpret_cast<void*>(reinterpret_cast<uintptr_t>(memory) + headerSkip); + return reinterpret_cast<void *>(reinterpret_cast<uintptr_t>(memory) + headerSkip); } // // Need a simple page to allocate from. // - tHeader* memory; - if (freeList) { - memory = freeList; + tHeader *memory; + if (freeList) + { + memory = freeList; freeList = freeList->nextPage; - } else { - memory = reinterpret_cast<tHeader*>(::new char[pageSize]); + } + else + { + memory = reinterpret_cast<tHeader *>(::new char[pageSize]); if (memory == 0) return 0; } // Use placement-new to initialize header - new(memory) tHeader(inUseList, 1); + new (memory) tHeader(inUseList, 1); inUseList = memory; - - unsigned char* ret = reinterpret_cast<unsigned char *>(inUseList) + headerSkip; - currentPageOffset = (headerSkip + allocationSize + alignmentMask) & ~alignmentMask; + + unsigned char *ret = reinterpret_cast<unsigned char *>(inUseList) + headerSkip; + currentPageOffset = (headerSkip + allocationSize + alignmentMask) & ~alignmentMask; return initializeAllocation(inUseList, ret, numBytes); +#else // !defined(ANGLE_TRANSLATOR_DISABLE_POOL_ALLOC) + void *alloc = malloc(numBytes + alignmentMask); + mStack.back().push_back(alloc); + + intptr_t intAlloc = reinterpret_cast<intptr_t>(alloc); + intAlloc = (intAlloc + alignmentMask) & ~alignmentMask; + return reinterpret_cast<void *>(intAlloc); +#endif +} + +void TPoolAllocator::lock() +{ + ASSERT(!mLocked); + mLocked = true; } +void TPoolAllocator::unlock() +{ + ASSERT(mLocked); + mLocked = false; +} // // Check all allocations in a list for damage by calling check on each. // void TAllocation::checkAllocList() const { - for (const TAllocation* alloc = this; alloc != 0; alloc = alloc->prevAlloc) + for (const TAllocation *alloc = this; alloc != 0; alloc = alloc->prevAlloc) alloc->check(); } |