gfx/angle/src/compiler/PoolAlloc.cpp

Sat, 03 Jan 2015 20:18:00 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Sat, 03 Jan 2015 20:18:00 +0100
branch
TOR_BUG_3246
changeset 7
129ffea94266
permissions
-rw-r--r--

Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.

     1 //
     2 // Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
     3 // Use of this source code is governed by a BSD-style license that can be
     4 // found in the LICENSE file.
     5 //
     7 #include "compiler/PoolAlloc.h"
     9 #ifndef _MSC_VER
    10 #include <stdint.h>
    11 #endif
    12 #include <stdio.h>
    14 #include "common/angleutils.h"
    15 #include "compiler/InitializeGlobals.h"
    16 #include "compiler/osinclude.h"
    18 OS_TLSIndex PoolIndex = OS_INVALID_TLS_INDEX;
    20 bool InitializePoolIndex()
    21 {
    22     assert(PoolIndex == OS_INVALID_TLS_INDEX);
    24     PoolIndex = OS_AllocTLSIndex();
    25     return PoolIndex != OS_INVALID_TLS_INDEX;
    26 }
    28 void FreePoolIndex()
    29 {
    30     assert(PoolIndex != OS_INVALID_TLS_INDEX);
    32     OS_FreeTLSIndex(PoolIndex);
    33     PoolIndex = OS_INVALID_TLS_INDEX;
    34 }
    36 TPoolAllocator* GetGlobalPoolAllocator()
    37 {
    38     assert(PoolIndex != OS_INVALID_TLS_INDEX);
    39     return static_cast<TPoolAllocator*>(OS_GetTLSValue(PoolIndex));
    40 }
    42 void SetGlobalPoolAllocator(TPoolAllocator* poolAllocator)
    43 {
    44     assert(PoolIndex != OS_INVALID_TLS_INDEX);
    45     OS_SetTLSValue(PoolIndex, poolAllocator);
    46 }
    48 //
    49 // Implement the functionality of the TPoolAllocator class, which
    50 // is documented in PoolAlloc.h.
    51 //
    52 TPoolAllocator::TPoolAllocator(int growthIncrement, int allocationAlignment) : 
    53     pageSize(growthIncrement),
    54     alignment(allocationAlignment),
    55     freeList(0),
    56     inUseList(0),
    57     numCalls(0),
    58     totalBytes(0)
    59 {
    60     //
    61     // Don't allow page sizes we know are smaller than all common
    62     // OS page sizes.
    63     //
    64     if (pageSize < 4*1024)
    65         pageSize = 4*1024;
    67     //
    68     // A large currentPageOffset indicates a new page needs to
    69     // be obtained to allocate memory.
    70     //
    71     currentPageOffset = pageSize;
    73     //
    74     // Adjust alignment to be at least pointer aligned and
    75     // power of 2.
    76     //
    77     size_t minAlign = sizeof(void*);
    78     alignment &= ~(minAlign - 1);
    79     if (alignment < minAlign)
    80         alignment = minAlign;
    81     size_t a = 1;
    82     while (a < alignment)
    83         a <<= 1;
    84     alignment = a;
    85     alignmentMask = a - 1;
    87     //
    88     // Align header skip
    89     //
    90     headerSkip = minAlign;
    91     if (headerSkip < sizeof(tHeader)) {
    92         headerSkip = (sizeof(tHeader) + alignmentMask) & ~alignmentMask;
    93     }
    94 }
    96 TPoolAllocator::~TPoolAllocator()
    97 {
    98     while (inUseList) {
    99         tHeader* next = inUseList->nextPage;
   100         inUseList->~tHeader();
   101         delete [] reinterpret_cast<char*>(inUseList);
   102         inUseList = next;
   103     }
   105     // We should not check the guard blocks
   106     // here, because we did it already when the block was
   107     // placed into the free list.
   108     //
   109     while (freeList) {
   110         tHeader* next = freeList->nextPage;
   111         delete [] reinterpret_cast<char*>(freeList);
   112         freeList = next;
   113     }
   114 }
   116 // Support MSVC++ 6.0
   117 const unsigned char TAllocation::guardBlockBeginVal = 0xfb;
   118 const unsigned char TAllocation::guardBlockEndVal   = 0xfe;
   119 const unsigned char TAllocation::userDataFill       = 0xcd;
   121 #ifdef GUARD_BLOCKS
   122     const size_t TAllocation::guardBlockSize = 16;
   123 #else
   124     const size_t TAllocation::guardBlockSize = 0;
   125 #endif
   127 //
   128 // Check a single guard block for damage
   129 //
   130 void TAllocation::checkGuardBlock(unsigned char* blockMem, unsigned char val, const char* locText) const
   131 {
   132 #ifdef GUARD_BLOCKS
   133     for (size_t x = 0; x < guardBlockSize; x++) {
   134         if (blockMem[x] != val) {
   135             char assertMsg[80];
   137             // We don't print the assert message.  It's here just to be helpful.
   138 #if defined(_MSC_VER)
   139             snprintf(assertMsg, sizeof(assertMsg), "PoolAlloc: Damage %s %Iu byte allocation at 0x%p\n",
   140                     locText, size, data());
   141 #else
   142             snprintf(assertMsg, sizeof(assertMsg), "PoolAlloc: Damage %s %zu byte allocation at 0x%p\n",
   143                     locText, size, data());
   144 #endif
   145             assert(0 && "PoolAlloc: Damage in guard block");
   146         }
   147     }
   148 #endif
   149 }
   152 void TPoolAllocator::push()
   153 {
   154     tAllocState state = { currentPageOffset, inUseList };
   156     stack.push_back(state);
   158     //
   159     // Indicate there is no current page to allocate from.
   160     //
   161     currentPageOffset = pageSize;
   162 }
   164 //
   165 // Do a mass-deallocation of all the individual allocations
   166 // that have occurred since the last push(), or since the
   167 // last pop(), or since the object's creation.
   168 //
   169 // The deallocated pages are saved for future allocations.
   170 //
   171 void TPoolAllocator::pop()
   172 {
   173     if (stack.size() < 1)
   174         return;
   176     tHeader* page = stack.back().page;
   177     currentPageOffset = stack.back().offset;
   179     while (inUseList != page) {
   180         // invoke destructor to free allocation list
   181         inUseList->~tHeader();
   183         tHeader* nextInUse = inUseList->nextPage;
   184         if (inUseList->pageCount > 1)
   185             delete [] reinterpret_cast<char*>(inUseList);
   186         else {
   187             inUseList->nextPage = freeList;
   188             freeList = inUseList;
   189         }
   190         inUseList = nextInUse;
   191     }
   193     stack.pop_back();
   194 }
   196 //
   197 // Do a mass-deallocation of all the individual allocations
   198 // that have occurred.
   199 //
   200 void TPoolAllocator::popAll()
   201 {
   202     while (stack.size() > 0)
   203         pop();
   204 }
   206 void* TPoolAllocator::allocate(size_t numBytes)
   207 {
   208     //
   209     // Just keep some interesting statistics.
   210     //
   211     ++numCalls;
   212     totalBytes += numBytes;
   214     // If we are using guard blocks, all allocations are bracketed by
   215     // them: [guardblock][allocation][guardblock].  numBytes is how
   216     // much memory the caller asked for.  allocationSize is the total
   217     // size including guard blocks.  In release build,
   218     // guardBlockSize=0 and this all gets optimized away.
   219     size_t allocationSize = TAllocation::allocationSize(numBytes);
   220     // Detect integer overflow.
   221     if (allocationSize < numBytes)
   222         return 0;
   224     //
   225     // Do the allocation, most likely case first, for efficiency.
   226     // This step could be moved to be inline sometime.
   227     //
   228     if (allocationSize <= pageSize - currentPageOffset) {
   229         //
   230         // Safe to allocate from currentPageOffset.
   231         //
   232         unsigned char* memory = reinterpret_cast<unsigned char *>(inUseList) + currentPageOffset;
   233         currentPageOffset += allocationSize;
   234         currentPageOffset = (currentPageOffset + alignmentMask) & ~alignmentMask;
   236         return initializeAllocation(inUseList, memory, numBytes);
   237     }
   239     if (allocationSize > pageSize - headerSkip) {
   240         //
   241         // Do a multi-page allocation.  Don't mix these with the others.
   242         // The OS is efficient and allocating and free-ing multiple pages.
   243         //
   244         size_t numBytesToAlloc = allocationSize + headerSkip;
   245         // Detect integer overflow.
   246         if (numBytesToAlloc < allocationSize)
   247             return 0;
   249         tHeader* memory = reinterpret_cast<tHeader*>(::new char[numBytesToAlloc]);
   250         if (memory == 0)
   251             return 0;
   253         // Use placement-new to initialize header
   254         new(memory) tHeader(inUseList, (numBytesToAlloc + pageSize - 1) / pageSize);
   255         inUseList = memory;
   257         currentPageOffset = pageSize;  // make next allocation come from a new page
   259         // No guard blocks for multi-page allocations (yet)
   260         return reinterpret_cast<void*>(reinterpret_cast<uintptr_t>(memory) + headerSkip);
   261     }
   263     //
   264     // Need a simple page to allocate from.
   265     //
   266     tHeader* memory;
   267     if (freeList) {
   268         memory = freeList;
   269         freeList = freeList->nextPage;
   270     } else {
   271         memory = reinterpret_cast<tHeader*>(::new char[pageSize]);
   272         if (memory == 0)
   273             return 0;
   274     }
   276     // Use placement-new to initialize header
   277     new(memory) tHeader(inUseList, 1);
   278     inUseList = memory;
   280     unsigned char* ret = reinterpret_cast<unsigned char *>(inUseList) + headerSkip;
   281     currentPageOffset = (headerSkip + allocationSize + alignmentMask) & ~alignmentMask;
   283     return initializeAllocation(inUseList, ret, numBytes);
   284 }
   287 //
   288 // Check all allocations in a list for damage by calling check on each.
   289 //
   290 void TAllocation::checkAllocList() const
   291 {
   292     for (const TAllocation* alloc = this; alloc != 0; alloc = alloc->prevAlloc)
   293         alloc->check();
   294 }

mercurial