| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright 2012 Google Inc. | 2 * Copyright 2012 Google Inc. |
| 3 * | 3 * |
| 4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
| 5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
| 6 */ | 6 */ |
| 7 | 7 |
| 8 #include "GrMemoryPool.h" | 8 #include "GrMemoryPool.h" |
| 9 | 9 |
| 10 #ifdef SK_DEBUG | 10 #ifdef SK_DEBUG |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 48 BlockHeader* block = CreateBlock(blockSize); | 48 BlockHeader* block = CreateBlock(blockSize); |
| 49 | 49 |
| 50 block->fPrev = fTail; | 50 block->fPrev = fTail; |
| 51 block->fNext = nullptr; | 51 block->fNext = nullptr; |
| 52 SkASSERT(nullptr == fTail->fNext); | 52 SkASSERT(nullptr == fTail->fNext); |
| 53 fTail->fNext = block; | 53 fTail->fNext = block; |
| 54 fTail = block; | 54 fTail = block; |
| 55 fSize += block->fSize; | 55 fSize += block->fSize; |
| 56 SkDEBUGCODE(++fAllocBlockCnt); | 56 SkDEBUGCODE(++fAllocBlockCnt); |
| 57 } | 57 } |
| 58 SkASSERT(kAssignedMarker == fTail->fBlockSentinal); |
| 58 SkASSERT(fTail->fFreeSize >= size); | 59 SkASSERT(fTail->fFreeSize >= size); |
| 59 intptr_t ptr = fTail->fCurrPtr; | 60 intptr_t ptr = fTail->fCurrPtr; |
| 60 // We stash a pointer to the block header, just before the allocated space, | 61 // We stash a pointer to the block header, just before the allocated space, |
| 61 // so that we can decrement the live count on delete in constant time. | 62 // so that we can decrement the live count on delete in constant time. |
| 62 AllocHeader* allocData = reinterpret_cast<AllocHeader*>(ptr); | 63 AllocHeader* allocData = reinterpret_cast<AllocHeader*>(ptr); |
| 63 SkDEBUGCODE(allocData->fSentinal = kAssignedMarker); | 64 SkDEBUGCODE(allocData->fSentinal = kAssignedMarker); |
| 64 allocData->fHeader = fTail; | 65 allocData->fHeader = fTail; |
| 65 ptr += kPerAllocPad; | 66 ptr += kPerAllocPad; |
| 66 fTail->fPrevPtr = fTail->fCurrPtr; | 67 fTail->fPrevPtr = fTail->fCurrPtr; |
| 67 fTail->fCurrPtr += size; | 68 fTail->fCurrPtr += size; |
| 68 fTail->fFreeSize -= size; | 69 fTail->fFreeSize -= size; |
| 69 fTail->fLiveCount += 1; | 70 fTail->fLiveCount += 1; |
| 70 | 71 |
| 71 SkDEBUGCODE(++fAllocationCnt); | 72 SkDEBUGCODE(++fAllocationCnt); |
| 72 VALIDATE; | 73 VALIDATE; |
| 73 return reinterpret_cast<void*>(ptr); | 74 return reinterpret_cast<void*>(ptr); |
| 74 } | 75 } |
| 75 | 76 |
| 76 void GrMemoryPool::release(void* p) { | 77 void GrMemoryPool::release(void* p) { |
| 77 VALIDATE; | 78 VALIDATE; |
| 78 intptr_t ptr = reinterpret_cast<intptr_t>(p) - kPerAllocPad; | 79 intptr_t ptr = reinterpret_cast<intptr_t>(p) - kPerAllocPad; |
| 79 AllocHeader* allocData = reinterpret_cast<AllocHeader*>(ptr); | 80 AllocHeader* allocData = reinterpret_cast<AllocHeader*>(ptr); |
| 80 SkASSERT(kAssignedMarker == allocData->fSentinal); | 81 SkASSERT(kAssignedMarker == allocData->fSentinal); |
| 81 SkDEBUGCODE(allocData->fSentinal = kFreedMarker); | 82 SkDEBUGCODE(allocData->fSentinal = kFreedMarker); |
| 82 BlockHeader* block = allocData->fHeader; | 83 BlockHeader* block = allocData->fHeader; |
| 84 SkASSERT(kAssignedMarker == block->fBlockSentinal); |
| 83 if (1 == block->fLiveCount) { | 85 if (1 == block->fLiveCount) { |
| 84 // the head block is special, it is reset rather than deleted | 86 // the head block is special, it is reset rather than deleted |
| 85 if (fHead == block) { | 87 if (fHead == block) { |
| 86 fHead->fCurrPtr = reinterpret_cast<intptr_t>(fHead) + kHeaderSize; | 88 fHead->fCurrPtr = reinterpret_cast<intptr_t>(fHead) + kHeaderSize; |
| 87 fHead->fLiveCount = 0; | 89 fHead->fLiveCount = 0; |
| 88 fHead->fFreeSize = fPreallocSize; | 90 fHead->fFreeSize = fPreallocSize; |
| 89 } else { | 91 } else { |
| 90 BlockHeader* prev = block->fPrev; | 92 BlockHeader* prev = block->fPrev; |
| 91 BlockHeader* next = block->fNext; | 93 BlockHeader* next = block->fNext; |
| 92 SkASSERT(prev); | 94 SkASSERT(prev); |
| (...skipping 19 matching lines...) Expand all Loading... |
| 112 SkDEBUGCODE(--fAllocationCnt); | 114 SkDEBUGCODE(--fAllocationCnt); |
| 113 VALIDATE; | 115 VALIDATE; |
| 114 } | 116 } |
| 115 | 117 |
| 116 GrMemoryPool::BlockHeader* GrMemoryPool::CreateBlock(size_t size) { | 118 GrMemoryPool::BlockHeader* GrMemoryPool::CreateBlock(size_t size) { |
| 117 size_t paddedSize = size + kHeaderSize; | 119 size_t paddedSize = size + kHeaderSize; |
| 118 BlockHeader* block = | 120 BlockHeader* block = |
| 119 reinterpret_cast<BlockHeader*>(sk_malloc_throw(paddedSize)); | 121 reinterpret_cast<BlockHeader*>(sk_malloc_throw(paddedSize)); |
| 120 // we assume malloc gives us aligned memory | 122 // we assume malloc gives us aligned memory |
| 121 SkASSERT(!(reinterpret_cast<intptr_t>(block) % kAlignment)); | 123 SkASSERT(!(reinterpret_cast<intptr_t>(block) % kAlignment)); |
| 124 SkDEBUGCODE(block->fBlockSentinal = kAssignedMarker); |
| 122 block->fLiveCount = 0; | 125 block->fLiveCount = 0; |
| 123 block->fFreeSize = size; | 126 block->fFreeSize = size; |
| 124 block->fCurrPtr = reinterpret_cast<intptr_t>(block) + kHeaderSize; | 127 block->fCurrPtr = reinterpret_cast<intptr_t>(block) + kHeaderSize; |
| 125 block->fPrevPtr = 0; // gcc warns on assigning nullptr to an intptr_t. | 128 block->fPrevPtr = 0; // gcc warns on assigning nullptr to an intptr_t. |
| 126 block->fSize = paddedSize; | 129 block->fSize = paddedSize; |
| 127 return block; | 130 return block; |
| 128 } | 131 } |
| 129 | 132 |
| 130 void GrMemoryPool::DeleteBlock(BlockHeader* block) { | 133 void GrMemoryPool::DeleteBlock(BlockHeader* block) { |
| 134 SkASSERT(kAssignedMarker == block->fBlockSentinal); |
| 135 SkDEBUGCODE(block->fBlockSentinal = kFreedMarker); // FWIW |
| 131 sk_free(block); | 136 sk_free(block); |
| 132 } | 137 } |
| 133 | 138 |
| 134 void GrMemoryPool::validate() { | 139 void GrMemoryPool::validate() { |
| 135 #ifdef SK_DEBUG | 140 #ifdef SK_DEBUG |
| 136 BlockHeader* block = fHead; | 141 BlockHeader* block = fHead; |
| 137 BlockHeader* prev = nullptr; | 142 BlockHeader* prev = nullptr; |
| 138 SkASSERT(block); | 143 SkASSERT(block); |
| 139 int allocCount = 0; | 144 int allocCount = 0; |
| 140 do { | 145 do { |
| 146 SkASSERT(kAssignedMarker == block->fBlockSentinal); |
| 141 allocCount += block->fLiveCount; | 147 allocCount += block->fLiveCount; |
| 142 SkASSERT(prev == block->fPrev); | 148 SkASSERT(prev == block->fPrev); |
| 143 if (prev) { | 149 if (prev) { |
| 144 SkASSERT(prev->fNext == block); | 150 SkASSERT(prev->fNext == block); |
| 145 } | 151 } |
| 146 | 152 |
| 147 intptr_t b = reinterpret_cast<intptr_t>(block); | 153 intptr_t b = reinterpret_cast<intptr_t>(block); |
| 148 size_t ptrOffset = block->fCurrPtr - b; | 154 size_t ptrOffset = block->fCurrPtr - b; |
| 149 size_t totalSize = ptrOffset + block->fFreeSize; | 155 size_t totalSize = ptrOffset + block->fFreeSize; |
| 150 size_t userSize = totalSize - kHeaderSize; | 156 size_t userSize = totalSize - kHeaderSize; |
| (...skipping 19 matching lines...) Expand all Loading... |
| 170 SkASSERT(block == allocData->fHeader); | 176 SkASSERT(block == allocData->fHeader); |
| 171 } | 177 } |
| 172 | 178 |
| 173 prev = block; | 179 prev = block; |
| 174 } while ((block = block->fNext)); | 180 } while ((block = block->fNext)); |
| 175 SkASSERT(allocCount == fAllocationCnt); | 181 SkASSERT(allocCount == fAllocationCnt); |
| 176 SkASSERT(prev == fTail); | 182 SkASSERT(prev == fTail); |
| 177 SkASSERT(fAllocBlockCnt != 0 || fSize == 0); | 183 SkASSERT(fAllocBlockCnt != 0 || fSize == 0); |
| 178 #endif | 184 #endif |
| 179 } | 185 } |
| OLD | NEW |