diff options
Diffstat (limited to 'src/3rdparty/angle/src/compiler/translator/PoolAlloc.h')
-rw-r--r-- | src/3rdparty/angle/src/compiler/translator/PoolAlloc.h | 220 |
1 files changed, 124 insertions, 96 deletions
diff --git a/src/3rdparty/angle/src/compiler/translator/PoolAlloc.h b/src/3rdparty/angle/src/compiler/translator/PoolAlloc.h index dab2926c90..ad63bc4cd6 100644 --- a/src/3rdparty/angle/src/compiler/translator/PoolAlloc.h +++ b/src/3rdparty/angle/src/compiler/translator/PoolAlloc.h @@ -13,8 +13,8 @@ // // This header defines an allocator that can be used to efficiently -// allocate a large number of small requests for heap memory, with the -// intention that they are not individually deallocated, but rather +// allocate a large number of small requests for heap memory, with the +// intention that they are not individually deallocated, but rather // collectively deallocated at one time. // // This simultaneously @@ -38,53 +38,58 @@ // If we are using guard blocks, we must track each indivual // allocation. If we aren't using guard blocks, these // never get instantiated, so won't have any impact. -// - -class TAllocation { -public: - TAllocation(size_t size, unsigned char* mem, TAllocation* prev = 0) : - size(size), mem(mem), prevAlloc(prev) { - // Allocations are bracketed: - // [allocationHeader][initialGuardBlock][userData][finalGuardBlock] - // This would be cleaner with if (guardBlockSize)..., but that - // makes the compiler print warnings about 0 length memsets, - // even with the if() protecting them. +// + +class TAllocation +{ + public: + TAllocation(size_t size, unsigned char *mem, TAllocation *prev = 0) + : size(size), mem(mem), prevAlloc(prev) + { +// Allocations are bracketed: +// [allocationHeader][initialGuardBlock][userData][finalGuardBlock] +// This would be cleaner with if (guardBlockSize)..., but that +// makes the compiler print warnings about 0 length memsets, +// even with the if() protecting them. #ifdef GUARD_BLOCKS memset(preGuard(), guardBlockBeginVal, guardBlockSize); - memset(data(), userDataFill, size); - memset(postGuard(), guardBlockEndVal, guardBlockSize); + memset(data(), userDataFill, size); + memset(postGuard(), guardBlockEndVal, guardBlockSize); #endif } - void check() const { - checkGuardBlock(preGuard(), guardBlockBeginVal, "before"); - checkGuardBlock(postGuard(), guardBlockEndVal, "after"); + void check() const + { + checkGuardBlock(preGuard(), guardBlockBeginVal, "before"); + checkGuardBlock(postGuard(), guardBlockEndVal, "after"); } void checkAllocList() const; // Return total size needed to accomodate user buffer of 'size', // plus our tracking data. - inline static size_t allocationSize(size_t size) { + inline static size_t allocationSize(size_t size) + { return size + 2 * guardBlockSize + headerSize(); } // Offset from surrounding buffer to get to user data buffer. - inline static unsigned char* offsetAllocation(unsigned char* m) { + inline static unsigned char *offsetAllocation(unsigned char *m) + { return m + guardBlockSize + headerSize(); } -private: - void checkGuardBlock(unsigned char* blockMem, unsigned char val, const char* locText) const; + private: + void checkGuardBlock(unsigned char *blockMem, unsigned char val, const char *locText) const; // Find offsets to pre and post guard blocks, and user data buffer - unsigned char* preGuard() const { return mem + headerSize(); } - unsigned char* data() const { return preGuard() + guardBlockSize; } - unsigned char* postGuard() const { return data() + size; } + unsigned char *preGuard() const { return mem + headerSize(); } + unsigned char *data() const { return preGuard() + guardBlockSize; } + unsigned char *postGuard() const { return data() + size; } - size_t size; // size of the user data area - unsigned char* mem; // beginning of our allocation (pts to header) - TAllocation* prevAlloc; // prior allocation in the chain + size_t size; // size of the user data area + unsigned char *mem; // beginning of our allocation (pts to header) + TAllocation *prevAlloc; // prior allocation in the chain // Support MSVC++ 6.0 const static unsigned char guardBlockBeginVal; @@ -101,7 +106,7 @@ private: // // There are several stacks. One is to track the pushing and popping -// of the user, and not yet implemented. The others are simply a +// of the user, and not yet implemented. The others are simply a // repositories of free pages or used pages. // // Page stacks are linked together with a simple header at the beginning @@ -110,12 +115,13 @@ private: // re-use. // // The "page size" used is not, nor must it match, the underlying OS -// page size. But, having it be about that size or equal to a set of +// page size. But, having it be about that size or equal to a set of // pages is likely most optimal. // -class TPoolAllocator { -public: - TPoolAllocator(int growthIncrement = 8*1024, int allocationAlignment = 16); +class TPoolAllocator +{ + public: + TPoolAllocator(int growthIncrement = 8 * 1024, int allocationAlignment = 16); // // Don't call the destructor just to free up the memory, call pop() @@ -143,7 +149,7 @@ public: // Call allocate() to actually acquire memory. Returns 0 if no memory // available, otherwise a properly aligned pointer to 'numBytes' of memory. // - void* allocate(size_t numBytes); + void *allocate(size_t numBytes); // // There is no deallocate. The point of this class is that @@ -152,75 +158,92 @@ public: // by calling pop(), and to not have to solve memory leak problems. // -protected: + // Catch unwanted allocations. + // TODO(jmadill): Remove this when we remove the global allocator. + void lock(); + void unlock(); + + private: + size_t alignment; // all returned allocations will be aligned at + // this granularity, which will be a power of 2 + size_t alignmentMask; + +#if !defined(ANGLE_TRANSLATOR_DISABLE_POOL_ALLOC) friend struct tHeader; - - struct tHeader { - tHeader(tHeader* nextPage, size_t pageCount) : - nextPage(nextPage), - pageCount(pageCount) + + struct tHeader + { + tHeader(tHeader *nextPage, size_t pageCount) + : nextPage(nextPage), + pageCount(pageCount) #ifdef GUARD_BLOCKS - , lastAllocation(0) + , + lastAllocation(0) #endif - { } + { + } - ~tHeader() { + ~tHeader() + { #ifdef GUARD_BLOCKS if (lastAllocation) lastAllocation->checkAllocList(); #endif } - tHeader* nextPage; + tHeader *nextPage; size_t pageCount; #ifdef GUARD_BLOCKS - TAllocation* lastAllocation; + TAllocation *lastAllocation; #endif }; - struct tAllocState { + struct tAllocState + { size_t offset; - tHeader* page; + tHeader *page; }; typedef std::vector<tAllocState> tAllocStack; // Track allocations if and only if we're using guard blocks - void* initializeAllocation(tHeader* block, unsigned char* memory, size_t numBytes) { + void *initializeAllocation(tHeader *block, unsigned char *memory, size_t numBytes) + { #ifdef GUARD_BLOCKS - new(memory) TAllocation(numBytes, memory, block->lastAllocation); - block->lastAllocation = reinterpret_cast<TAllocation*>(memory); + new (memory) TAllocation(numBytes, memory, block->lastAllocation); + block->lastAllocation = reinterpret_cast<TAllocation *>(memory); #endif // This is optimized entirely away if GUARD_BLOCKS is not defined. return TAllocation::offsetAllocation(memory); } - size_t pageSize; // granularity of allocation from the OS - size_t alignment; // all returned allocations will be aligned at - // this granularity, which will be a power of 2 - size_t alignmentMask; - size_t headerSkip; // amount of memory to skip to make room for the - // header (basically, size of header, rounded - // up to make it aligned + size_t pageSize; // granularity of allocation from the OS + size_t headerSkip; // amount of memory to skip to make room for the + // header (basically, size of header, rounded + // up to make it aligned size_t currentPageOffset; // next offset in top of inUseList to allocate from - tHeader* freeList; // list of popped memory - tHeader* inUseList; // list of all memory currently being used - tAllocStack stack; // stack of where to allocate from, to partition pool - - int numCalls; // just an interesting statistic - size_t totalBytes; // just an interesting statistic -private: - TPoolAllocator& operator=(const TPoolAllocator&); // dont allow assignment operator - TPoolAllocator(const TPoolAllocator&); // dont allow default copy constructor -}; + tHeader *freeList; // list of popped memory + tHeader *inUseList; // list of all memory currently being used + tAllocStack mStack; // stack of where to allocate from, to partition pool + int numCalls; // just an interesting statistic + size_t totalBytes; // just an interesting statistic + +#else // !defined(ANGLE_TRANSLATOR_DISABLE_POOL_ALLOC) + std::vector<std::vector<void *>> mStack; +#endif + + TPoolAllocator &operator=(const TPoolAllocator &); // dont allow assignment operator + TPoolAllocator(const TPoolAllocator &); // dont allow default copy constructor + bool mLocked; +}; // // There could potentially be many pools with pops happening at // different times. But a simple use is to have a global pop // with everyone using the same global allocator. // -extern TPoolAllocator* GetGlobalPoolAllocator(); -extern void SetGlobalPoolAllocator(TPoolAllocator* poolAllocator); +extern TPoolAllocator *GetGlobalPoolAllocator(); +extern void SetGlobalPoolAllocator(TPoolAllocator *poolAllocator); // // This STL compatible allocator is intended to be used as the allocator @@ -229,63 +252,68 @@ extern void SetGlobalPoolAllocator(TPoolAllocator* poolAllocator); // It will use the pools for allocation, and not // do any deallocation, but will still do destruction. // -template<class T> -class pool_allocator { -public: +template <class T> +class pool_allocator +{ + public: typedef size_t size_type; typedef ptrdiff_t difference_type; - typedef T* pointer; - typedef const T* const_pointer; - typedef T& reference; - typedef const T& const_reference; + typedef T *pointer; + typedef const T *const_pointer; + typedef T &reference; + typedef const T &const_reference; typedef T value_type; - template<class Other> - struct rebind { + template <class Other> + struct rebind + { typedef pool_allocator<Other> other; }; pointer address(reference x) const { return &x; } const_pointer address(const_reference x) const { return &x; } - pool_allocator() { } + pool_allocator() {} - template<class Other> - pool_allocator(const pool_allocator<Other>& p) { } + template <class Other> + pool_allocator(const pool_allocator<Other> &p) + { + } template <class Other> - pool_allocator<T>& operator=(const pool_allocator<Other>& p) { return *this; } + pool_allocator<T> &operator=(const pool_allocator<Other> &p) + { + return *this; + } #if defined(__SUNPRO_CC) && !defined(_RWSTD_ALLOCATOR) // libCStd on some platforms have a different allocate/deallocate interface. // Caller pre-bakes sizeof(T) into 'n' which is the number of bytes to be // allocated, not the number of elements. - void* allocate(size_type n) { - return getAllocator().allocate(n); - } - void* allocate(size_type n, const void*) { - return getAllocator().allocate(n); - } - void deallocate(void*, size_type) {} + void *allocate(size_type n) { return getAllocator().allocate(n); } + void *allocate(size_type n, const void *) { return getAllocator().allocate(n); } + void deallocate(void *, size_type) {} #else - pointer allocate(size_type n) { + pointer allocate(size_type n) + { return reinterpret_cast<pointer>(getAllocator().allocate(n * sizeof(T))); } - pointer allocate(size_type n, const void*) { + pointer allocate(size_type n, const void *) + { return reinterpret_cast<pointer>(getAllocator().allocate(n * sizeof(T))); } void deallocate(pointer, size_type) {} #endif // _RWSTD_ALLOCATOR - void construct(pointer p, const T& val) { new ((void *)p) T(val); } + void construct(pointer p, const T &val) { new ((void *)p) T(val); } void destroy(pointer p) { p->T::~T(); } - bool operator==(const pool_allocator& rhs) const { return true; } - bool operator!=(const pool_allocator& rhs) const { return false; } + bool operator==(const pool_allocator &rhs) const { return true; } + bool operator!=(const pool_allocator &rhs) const { return false; } size_type max_size() const { return static_cast<size_type>(-1) / sizeof(T); } size_type max_size(int size) const { return static_cast<size_type>(-1) / size; } - TPoolAllocator& getAllocator() const { return *GetGlobalPoolAllocator(); } + TPoolAllocator &getAllocator() const { return *GetGlobalPoolAllocator(); } }; -#endif // COMPILER_TRANSLATOR_POOLALLOC_H_ +#endif // COMPILER_TRANSLATOR_POOLALLOC_H_ |