summaryrefslogtreecommitdiffstats
path: root/src/3rdparty/angle/src/compiler/translator/PoolAlloc.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/3rdparty/angle/src/compiler/translator/PoolAlloc.cpp')
-rw-r--r--src/3rdparty/angle/src/compiler/translator/PoolAlloc.cpp227
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();
}