summaryrefslogtreecommitdiffstats
path: root/chromium/third_party/glslang/src/glslang/MachineIndependent/PoolAlloc.cpp
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@qt.io>2019-01-25 16:25:39 +0100
committerAllan Sandfeld Jensen <allan.jensen@qt.io>2019-01-29 15:43:13 +0000
commit2b94bfe47ccb6c08047959d1c26e392919550e86 (patch)
tree4a9cb6fb333ac7e0e5bfbdd3a8faa219880e193d /chromium/third_party/glslang/src/glslang/MachineIndependent/PoolAlloc.cpp
parent51f6c2793adab2d864b3d2b360000ef8db1d3e92 (diff)
BASELINE: Update Chromium to 71.0.3578.140
Change-Id: Ia85516cc06e245e449ca8a6652242b8a1bcace74 Reviewed-by: Michal Klocek <michal.klocek@qt.io>
Diffstat (limited to 'chromium/third_party/glslang/src/glslang/MachineIndependent/PoolAlloc.cpp')
-rw-r--r--chromium/third_party/glslang/src/glslang/MachineIndependent/PoolAlloc.cpp347
1 files changed, 347 insertions, 0 deletions
diff --git a/chromium/third_party/glslang/src/glslang/MachineIndependent/PoolAlloc.cpp b/chromium/third_party/glslang/src/glslang/MachineIndependent/PoolAlloc.cpp
new file mode 100644
index 00000000000..d56979b492b
--- /dev/null
+++ b/chromium/third_party/glslang/src/glslang/MachineIndependent/PoolAlloc.cpp
@@ -0,0 +1,347 @@
+//
+//Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
+//All rights reserved.
+//
+//Redistribution and use in source and binary forms, with or without
+//modification, are permitted provided that the following conditions
+//are met:
+//
+// Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+//
+// Neither the name of 3Dlabs Inc. Ltd. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+//"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+//LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+//FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+//COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+//INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+//BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+//LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+//CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+//LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+//ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+//POSSIBILITY OF SUCH DAMAGE.
+//
+
+#include "../Include/Common.h"
+#include "../Include/PoolAlloc.h"
+
+#include "../Include/InitializeGlobals.h"
+#include "../OSDependent/osinclude.h"
+
+namespace glslang {
+
+OS_TLSIndex PoolIndex;
+
+void InitializeMemoryPools()
+{
+ TThreadMemoryPools* pools = static_cast<TThreadMemoryPools*>(OS_GetTLSValue(PoolIndex));
+ if (pools)
+ return;
+
+ TPoolAllocator *threadPoolAllocator = new TPoolAllocator();
+
+ TThreadMemoryPools* threadData = new TThreadMemoryPools();
+
+ threadData->threadPoolAllocator = threadPoolAllocator;
+
+ OS_SetTLSValue(PoolIndex, threadData);
+}
+
+void FreeGlobalPools()
+{
+ // Release the allocated memory for this thread.
+ TThreadMemoryPools* globalPools = static_cast<TThreadMemoryPools*>(OS_GetTLSValue(PoolIndex));
+ if (! globalPools)
+ return;
+
+ GetThreadPoolAllocator().popAll();
+ delete &GetThreadPoolAllocator();
+ delete globalPools;
+}
+
+bool InitializePoolIndex()
+{
+ // Allocate a TLS index.
+ if ((PoolIndex = OS_AllocTLSIndex()) == OS_INVALID_TLS_INDEX)
+ return false;
+
+ return true;
+}
+
+void FreePoolIndex()
+{
+ // Release the TLS index.
+ OS_FreeTLSIndex(PoolIndex);
+}
+
+TPoolAllocator& GetThreadPoolAllocator()
+{
+ TThreadMemoryPools* threadData = static_cast<TThreadMemoryPools*>(OS_GetTLSValue(PoolIndex));
+
+ return *threadData->threadPoolAllocator;
+}
+
+void SetThreadPoolAllocator(TPoolAllocator& poolAllocator)
+{
+ TThreadMemoryPools* threadData = static_cast<TThreadMemoryPools*>(OS_GetTLSValue(PoolIndex));
+
+ threadData->threadPoolAllocator = &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)
+{
+ //
+ // 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*);
+ alignment &= ~(minAlign - 1);
+ if (alignment < minAlign)
+ alignment = minAlign;
+ size_t a = 1;
+ while (a < alignment)
+ a <<= 1;
+ alignment = a;
+ alignmentMask = a - 1;
+
+ //
+ // Align header skip
+ //
+ headerSkip = minAlign;
+ if (headerSkip < sizeof(tHeader)) {
+ headerSkip = (sizeof(tHeader) + alignmentMask) & ~alignmentMask;
+ }
+
+ push();
+}
+
+TPoolAllocator::~TPoolAllocator()
+{
+ while (inUseList) {
+ tHeader* next = inUseList->nextPage;
+ inUseList->~tHeader();
+ delete [] reinterpret_cast<char*>(inUseList);
+ inUseList = next;
+ }
+
+ //
+ // Always delete the free list memory - it can't be being
+ // (correctly) referenced, whether the pool allocator was
+ // global or not. We should not check the guard blocks
+ // 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);
+ freeList = next;
+ }
+}
+
+const unsigned char TAllocation::guardBlockBeginVal = 0xfb;
+const unsigned char TAllocation::guardBlockEndVal = 0xfe;
+const unsigned char TAllocation::userDataFill = 0xcd;
+
+# ifdef GUARD_BLOCKS
+ const size_t TAllocation::guardBlockSize = 16;
+# else
+ const size_t TAllocation::guardBlockSize = 0;
+# endif
+
+//
+// Check a single guard block for damage
+//
+#ifdef GUARD_BLOCKS
+void TAllocation::checkGuardBlock(unsigned char* blockMem, unsigned char val, const char* locText) const
+#else
+void TAllocation::checkGuardBlock(unsigned char*, unsigned char, const char*) const
+#endif
+{
+#ifdef GUARD_BLOCKS
+ for (size_t x = 0; x < guardBlockSize; x++) {
+ if (blockMem[x] != val) {
+ const int maxSize = 80;
+ char assertMsg[maxSize];
+
+ // We don't print the assert message. It's here just to be helpful.
+ snprintf(assertMsg, maxSize, "PoolAlloc: Damage %s %zu byte allocation at 0x%p\n",
+ locText, size, data());
+ assert(0 && "PoolAlloc: Damage in guard block");
+ }
+ }
+#else
+ assert(guardBlockSize == 0);
+#endif
+}
+
+
+void TPoolAllocator::push()
+{
+ tAllocState state = { currentPageOffset, inUseList };
+
+ stack.push_back(state);
+
+ //
+ // Indicate there is no current page to allocate from.
+ //
+ currentPageOffset = pageSize;
+}
+
+//
+// Do a mass-deallocation of all the individual allocations
+// that have occurred since the last push(), or since the
+// last pop(), or since the object's creation.
+//
+// The deallocated pages are saved for future allocations.
+//
+void TPoolAllocator::pop()
+{
+ if (stack.size() < 1)
+ return;
+
+ tHeader* page = stack.back().page;
+ currentPageOffset = stack.back().offset;
+
+ while (inUseList != page) {
+ // invoke destructor to free allocation list
+ inUseList->~tHeader();
+
+ tHeader* nextInUse = inUseList->nextPage;
+ if (inUseList->pageCount > 1)
+ delete [] reinterpret_cast<char*>(inUseList);
+ else {
+ inUseList->nextPage = freeList;
+ freeList = inUseList;
+ }
+ inUseList = nextInUse;
+ }
+
+ stack.pop_back();
+}
+
+//
+// Do a mass-deallocation of all the individual allocations
+// that have occurred.
+//
+void TPoolAllocator::popAll()
+{
+ while (stack.size() > 0)
+ pop();
+}
+
+void* TPoolAllocator::allocate(size_t numBytes)
+{
+ // If we are using guard blocks, all allocations are bracketed by
+ // them: [guardblock][allocation][guardblock]. numBytes is how
+ // much memory the caller asked for. allocationSize is the total
+ // size including guard blocks. In release build,
+ // guardBlockSize=0 and this all gets optimized away.
+ size_t allocationSize = TAllocation::allocationSize(numBytes);
+
+ //
+ // Just keep some interesting statistics.
+ //
+ ++numCalls;
+ totalBytes += numBytes;
+
+ //
+ // Do the allocation, most likely case first, for efficiency.
+ // This step could be moved to be inline sometime.
+ //
+ if (currentPageOffset + allocationSize <= pageSize) {
+ //
+ // Safe to allocate from currentPageOffset.
+ //
+ unsigned char* memory = reinterpret_cast<unsigned char*>(inUseList) + currentPageOffset;
+ currentPageOffset += allocationSize;
+ currentPageOffset = (currentPageOffset + alignmentMask) & ~alignmentMask;
+
+ return initializeAllocation(inUseList, memory, numBytes);
+ }
+
+ if (allocationSize + headerSkip > pageSize) {
+ //
+ // Do a multi-page allocation. Don't mix these with the others.
+ // The OS is efficient and allocating and free-ing multiple pages.
+ //
+ size_t numBytesToAlloc = allocationSize + headerSkip;
+ 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);
+ 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<UINT_PTR>(memory) + headerSkip);
+ }
+
+ //
+ // Need a simple page to allocate from.
+ //
+ tHeader* memory;
+ if (freeList) {
+ memory = freeList;
+ freeList = freeList->nextPage;
+ } else {
+ memory = reinterpret_cast<tHeader*>(::new char[pageSize]);
+ if (memory == 0)
+ return 0;
+ }
+
+ // Use placement-new to initialize header
+ new(memory) tHeader(inUseList, 1);
+ inUseList = memory;
+
+ unsigned char* ret = reinterpret_cast<unsigned char*>(inUseList) + headerSkip;
+ currentPageOffset = (headerSkip + allocationSize + alignmentMask) & ~alignmentMask;
+
+ return initializeAllocation(inUseList, ret, numBytes);
+}
+
+
+//
+// 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)
+ alloc->check();
+}
+
+} // end namespace glslang