1 /* 2 * Copyright 2012 Google Inc. 3 * 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file. 6 */ 7 8 #ifndef GrMemoryPool_DEFINED 9 #define GrMemoryPool_DEFINED 10 11 #include "GrTypes.h" 12 13 /** 14 * Allocates memory in blocks and parcels out space in the blocks for allocation 15 * requests. It is optimized for allocate / release speed over memory 16 * effeciency. The interface is designed to be used to implement operator new 17 * and delete overrides. All allocations are expected to be released before the 18 * pool's destructor is called. Allocations will be 8-byte aligned. 19 */ 20 class GrMemoryPool { 21 public: 22 /** 23 * Prealloc size is the amount of space to make available at pool creation 24 * time and keep around until pool destruction. The min alloc size is the 25 * smallest allowed size of additional allocations. 26 */ 27 GrMemoryPool(size_t preallocSize, size_t minAllocSize); 28 29 ~GrMemoryPool(); 30 31 /** 32 * Allocates memory. The memory must be freed with release(). 33 */ 34 void* allocate(size_t size); 35 36 /** 37 * p must have been returned by allocate() 38 */ 39 void release(void* p); 40 41 /** 42 * Returns true if there are no unreleased allocations. 43 */ isEmpty()44 bool isEmpty() const { return fTail == fHead && !fHead->fLiveCount; } 45 46 /** 47 * Returns the total allocated size of the GrMemoryPool minus any preallocated amount 48 */ size()49 size_t size() const { return fSize; } 50 51 private: 52 struct BlockHeader; 53 54 static BlockHeader* CreateBlock(size_t size); 55 56 static void DeleteBlock(BlockHeader* block); 57 58 void validate(); 59 60 struct BlockHeader { 61 #ifdef SK_DEBUG 62 uint32_t fBlockSentinal; ///< known value to check for bad back pointers to blocks 63 #endif 64 BlockHeader* fNext; ///< doubly-linked list of blocks. 65 BlockHeader* fPrev; 66 int fLiveCount; ///< number of outstanding allocations in the 67 ///< block. 68 intptr_t fCurrPtr; ///< ptr to the start of blocks free space. 69 intptr_t fPrevPtr; ///< ptr to the last allocation made 70 size_t fFreeSize; ///< amount of free space left in the block. 71 size_t fSize; ///< total allocated size of the block 72 }; 73 74 static const uint32_t kAssignedMarker = 0xCDCDCDCD; 75 static const uint32_t kFreedMarker = 0xEFEFEFEF; 76 77 struct AllocHeader { 78 #ifdef SK_DEBUG 79 uint32_t fSentinal; ///< known value to check for memory stomping (e.g., (CD)*) 80 #endif 81 BlockHeader* fHeader; ///< pointer back to the block header in which an alloc resides 82 }; 83 84 enum { 85 // We assume this alignment is good enough for everybody. 86 kAlignment = 8, 87 kHeaderSize = GR_CT_ALIGN_UP(sizeof(BlockHeader), kAlignment), 88 kPerAllocPad = GR_CT_ALIGN_UP(sizeof(AllocHeader), kAlignment), 89 }; 90 size_t fSize; 91 size_t fPreallocSize; 92 size_t fMinAllocSize; 93 BlockHeader* fHead; 94 BlockHeader* fTail; 95 #ifdef SK_DEBUG 96 int fAllocationCnt; 97 int fAllocBlockCnt; 98 #endif 99 }; 100 101 #endif 102