| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright 2006 The Android Open Source Project | 2 * Copyright 2006 The Android Open Source Project |
| 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 "SkChunkAlloc.h" | 8 #include "SkChunkAlloc.h" |
| 9 | 9 |
| 10 // Don't malloc any chunks smaller than this | 10 // Don't malloc any chunks smaller than this |
| 11 #define MIN_CHUNKALLOC_BLOCK_SIZE 1024 | 11 #define MIN_CHUNKALLOC_BLOCK_SIZE 1024 |
| 12 | 12 |
| 13 // Return the new min blocksize given the current value | 13 // Return the new min blocksize given the current value |
| 14 static size_t increase_next_size(size_t size) { | 14 static size_t increase_next_size(size_t size) { |
| 15 return size + (size >> 1); | 15 return size + (size >> 1); |
| 16 } | 16 } |
| 17 | 17 |
| 18 /////////////////////////////////////////////////////////////////////////////// | 18 /////////////////////////////////////////////////////////////////////////////// |
| 19 | 19 |
| 20 struct SkChunkAlloc::Block { | 20 struct SkChunkAlloc::Block { |
| 21 Block* fNext; | 21 Block* fNext; |
| 22 size_t fFreeSize; | 22 size_t fFreeSize; |
| 23 char* fFreePtr; | 23 char* fFreePtr; |
| 24 // data[] follows | 24 // data[] follows |
| 25 | 25 |
| 26 size_t blockSize() { | 26 size_t blockSize() const { |
| 27 char* start = this->startOfData(); | 27 char* start = this->startOfData(); |
| 28 size_t bytes = fFreePtr - start; | 28 size_t bytes = fFreePtr - start; |
| 29 return fFreeSize + bytes; | 29 return fFreeSize + bytes; |
| 30 } | 30 } |
| 31 | 31 |
| 32 void reset() { | 32 void reset() { |
| 33 fNext = nullptr; | 33 fNext = nullptr; |
| 34 fFreeSize = this->blockSize(); | 34 fFreeSize = this->blockSize(); |
| 35 fFreePtr = this->startOfData(); | 35 fFreePtr = this->startOfData(); |
| 36 } | 36 } |
| 37 | 37 |
| 38 char* startOfData() { | 38 char* startOfData() const { |
| 39 return reinterpret_cast<char*>(this + 1); | 39 return reinterpret_cast<char*>(SkAlign8(reinterpret_cast<size_t>(this +
1))); |
| 40 } | 40 } |
| 41 | 41 |
| 42 static void FreeChain(Block* block) { | 42 static void FreeChain(Block* block) { |
| 43 while (block) { | 43 while (block) { |
| 44 Block* next = block->fNext; | 44 Block* next = block->fNext; |
| 45 sk_free(block); | 45 sk_free(block); |
| 46 block = next; | 46 block = next; |
| 47 } | 47 } |
| 48 }; | 48 }; |
| 49 | 49 |
| 50 bool contains(const void* addr) const { | 50 bool contains(const void* addr) const { |
| 51 const char* ptr = reinterpret_cast<const char*>(addr); | 51 const char* ptr = reinterpret_cast<const char*>(addr); |
| 52 return ptr >= (const char*)(this + 1) && ptr < fFreePtr; | 52 return ptr >= this->startOfData() && ptr < fFreePtr; |
| 53 } | 53 } |
| 54 }; | 54 }; |
| 55 | 55 |
| 56 /////////////////////////////////////////////////////////////////////////////// | 56 /////////////////////////////////////////////////////////////////////////////// |
| 57 | 57 |
| 58 SkChunkAlloc::SkChunkAlloc(size_t minSize) { | 58 SkChunkAlloc::SkChunkAlloc(size_t minSize) { |
| 59 if (minSize < MIN_CHUNKALLOC_BLOCK_SIZE) { | 59 if (minSize < MIN_CHUNKALLOC_BLOCK_SIZE) { |
| 60 minSize = MIN_CHUNKALLOC_BLOCK_SIZE; | 60 minSize = MIN_CHUNKALLOC_BLOCK_SIZE; |
| 61 } | 61 } |
| 62 | 62 |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 114 SkDEBUGCODE(fTotalLost = 0;) | 114 SkDEBUGCODE(fTotalLost = 0;) |
| 115 SkDEBUGCODE(this->validate();) | 115 SkDEBUGCODE(this->validate();) |
| 116 } | 116 } |
| 117 | 117 |
| 118 SkChunkAlloc::Block* SkChunkAlloc::newBlock(size_t bytes, AllocFailType ftype) { | 118 SkChunkAlloc::Block* SkChunkAlloc::newBlock(size_t bytes, AllocFailType ftype) { |
| 119 size_t size = bytes; | 119 size_t size = bytes; |
| 120 if (size < fChunkSize) { | 120 if (size < fChunkSize) { |
| 121 size = fChunkSize; | 121 size = fChunkSize; |
| 122 } | 122 } |
| 123 | 123 |
| 124 Block* block = (Block*)sk_malloc_flags(sizeof(Block) + size, | 124 Block* block = (Block*)sk_malloc_flags(SkAlign8(sizeof(Block)) + size, |
| 125 ftype == kThrow_AllocFailType ? SK_MALLOC_THROW : 0); | 125 ftype == kThrow_AllocFailType ? SK_MALLOC_THROW : 0); |
| 126 | 126 |
| 127 if (block) { | 127 if (block) { |
| 128 block->fFreeSize = size; | 128 block->fFreeSize = size; |
| 129 block->fFreePtr = block->startOfData(); | 129 block->fFreePtr = block->startOfData(); |
| 130 | 130 |
| 131 fTotalCapacity += size; | 131 fTotalCapacity += size; |
| 132 SkDEBUGCODE(fBlockCount += 1;) | 132 SkDEBUGCODE(fBlockCount += 1;) |
| 133 | 133 |
| 134 fChunkSize = increase_next_size(fChunkSize); | 134 fChunkSize = increase_next_size(fChunkSize); |
| 135 } | 135 } |
| 136 return block; | 136 return block; |
| 137 } | 137 } |
| 138 | 138 |
| 139 SkChunkAlloc::Block* SkChunkAlloc::addBlockIfNecessary(size_t bytes, AllocFailTy
pe ftype) { | 139 SkChunkAlloc::Block* SkChunkAlloc::addBlockIfNecessary(size_t bytes, AllocFailTy
pe ftype) { |
| 140 SkASSERT(SkIsAlign4(bytes)); | 140 SkASSERT(SkIsAlign8(bytes)); |
| 141 | 141 |
| 142 if (!fBlock || bytes > fBlock->fFreeSize) { | 142 if (!fBlock || bytes > fBlock->fFreeSize) { |
| 143 Block* block = this->newBlock(bytes, ftype); | 143 Block* block = this->newBlock(bytes, ftype); |
| 144 if (!block) { | 144 if (!block) { |
| 145 return nullptr; | 145 return nullptr; |
| 146 } | 146 } |
| 147 #ifdef SK_DEBUG | 147 #ifdef SK_DEBUG |
| 148 if (fBlock) { | 148 if (fBlock) { |
| 149 fTotalLost += fBlock->fFreeSize; | 149 fTotalLost += fBlock->fFreeSize; |
| 150 } | 150 } |
| 151 #endif | 151 #endif |
| 152 block->fNext = fBlock; | 152 block->fNext = fBlock; |
| 153 fBlock = block; | 153 fBlock = block; |
| 154 } | 154 } |
| 155 | 155 |
| 156 SkASSERT(fBlock && bytes <= fBlock->fFreeSize); | 156 SkASSERT(fBlock && bytes <= fBlock->fFreeSize); |
| 157 return fBlock; | 157 return fBlock; |
| 158 } | 158 } |
| 159 | 159 |
| 160 void* SkChunkAlloc::alloc(size_t bytes, AllocFailType ftype) { | 160 void* SkChunkAlloc::alloc(size_t bytes, AllocFailType ftype) { |
| 161 SkDEBUGCODE(this->validate();) | 161 SkDEBUGCODE(this->validate();) |
| 162 | 162 |
| 163 bytes = SkAlign4(bytes); | 163 bytes = SkAlign8(bytes); |
| 164 | 164 |
| 165 Block* block = this->addBlockIfNecessary(bytes, ftype); | 165 Block* block = this->addBlockIfNecessary(bytes, ftype); |
| 166 if (!block) { | 166 if (!block) { |
| 167 return nullptr; | 167 return nullptr; |
| 168 } | 168 } |
| 169 | 169 |
| 170 char* ptr = block->fFreePtr; | 170 char* ptr = block->fFreePtr; |
| 171 | 171 |
| 172 fTotalUsed += bytes; | 172 fTotalUsed += bytes; |
| 173 block->fFreeSize -= bytes; | 173 block->fFreeSize -= bytes; |
| 174 block->fFreePtr = ptr + bytes; | 174 block->fFreePtr = ptr + bytes; |
| 175 SkDEBUGCODE(this->validate();) | 175 SkDEBUGCODE(this->validate();) |
| 176 SkASSERT(SkIsAlign8((size_t)ptr)); |
| 176 return ptr; | 177 return ptr; |
| 177 } | 178 } |
| 178 | 179 |
| 179 size_t SkChunkAlloc::unalloc(void* ptr) { | 180 size_t SkChunkAlloc::unalloc(void* ptr) { |
| 180 SkDEBUGCODE(this->validate();) | 181 SkDEBUGCODE(this->validate();) |
| 181 | 182 |
| 182 size_t bytes = 0; | 183 size_t bytes = 0; |
| 183 Block* block = fBlock; | 184 Block* block = fBlock; |
| 184 if (block) { | 185 if (block) { |
| 185 char* cPtr = reinterpret_cast<char*>(ptr); | 186 char* cPtr = reinterpret_cast<char*>(ptr); |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 225 } | 226 } |
| 226 } | 227 } |
| 227 | 228 |
| 228 SkASSERT(fBlockCount == numBlocks); | 229 SkASSERT(fBlockCount == numBlocks); |
| 229 SkASSERT(fTotalCapacity == totCapacity); | 230 SkASSERT(fTotalCapacity == totCapacity); |
| 230 SkASSERT(fTotalUsed == totUsed); | 231 SkASSERT(fTotalUsed == totUsed); |
| 231 SkASSERT(fTotalLost == totLost); | 232 SkASSERT(fTotalLost == totLost); |
| 232 SkASSERT(totCapacity == totUsed + totLost + totAvailable); | 233 SkASSERT(totCapacity == totUsed + totLost + totAvailable); |
| 233 } | 234 } |
| 234 #endif | 235 #endif |
| OLD | NEW |