diff options
author | bsalomon <bsalomon@google.com> | 2015-11-18 19:48:50 -0800 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-11-18 19:48:50 -0800 |
commit | a7c41c5217da2f091ae78d002c9b92c20360ab87 (patch) | |
tree | fc60973e8dcfa251d16889249da9358724bdba80 /src/core/SkTLList.h | |
parent | f045d600fc5c17f8a3537401baf45043e7617368 (diff) |
Make SkTLList prealloc its first block of nodes
Review URL: https://codereview.chromium.org/1458703005
Diffstat (limited to 'src/core/SkTLList.h')
-rw-r--r-- | src/core/SkTLList.h | 29 |
1 files changed, 22 insertions, 7 deletions
diff --git a/src/core/SkTLList.h b/src/core/SkTLList.h index 1a8c54cb7c..48e81bdac1 100644 --- a/src/core/SkTLList.h +++ b/src/core/SkTLList.h @@ -39,6 +39,11 @@ public: class Iter; SkTLList() : fCount(0) { + fFirstBlock.fNodesInUse = 0; + for (unsigned int i = 0; i < N; ++i) { + fFreeList.addToHead(fFirstBlock.fNodes + i); + fFirstBlock.fNodes[i].fBlock = &fFirstBlock; + } this->validate(); } @@ -54,7 +59,9 @@ public: for (unsigned int i = 0; i < N; ++i) { block->fNodes[i].~Node(); } - sk_free(block); + if (block != &fFirstBlock) { + sk_free(block); + } } } } @@ -222,6 +229,9 @@ private: fFreeList.remove(node); ++node->fBlock->fNodesInUse; } else { + // Should not get here when count == 0 because we always have the preallocated first + // block. + SkASSERT(fCount > 0); Block* block = reinterpret_cast<Block*>(sk_malloc_throw(sizeof(Block))); node = &block->fNodes[0]; new (node) Node; @@ -241,8 +251,9 @@ private: SkASSERT(node); fList.remove(node); SkTCast<T*>(node->fObj)->~T(); - if (0 == --node->fBlock->fNodesInUse) { - Block* block = node->fBlock; + Block* block = node->fBlock; + // Don't ever elease the first block, just add its nodes to the free list + if (0 == --block->fNodesInUse && block != &fFirstBlock) { for (unsigned int i = 0; i < N; ++i) { if (block->fNodes + i != node) { fFreeList.remove(block->fNodes + i); @@ -260,8 +271,10 @@ private: void validate() const { #ifdef SK_DEBUG SkASSERT((0 == fCount) == fList.isEmpty()); - SkASSERT((0 != fCount) || fFreeList.isEmpty()); - + if (0 == fCount) { + // Should only have the nodes from the first block in the free list. + SkASSERT(fFreeList.countEntries() == N); + } fList.validate(); fFreeList.validate(); typename NodeList::Iter iter; @@ -269,8 +282,9 @@ private: while (freeNode) { SkASSERT(fFreeList.isInList(freeNode)); Block* block = freeNode->fBlock; - SkASSERT(block->fNodesInUse > 0 && (unsigned)block->fNodesInUse < N); - + // Only the first block is allowed to have all its nodes in the free list. + SkASSERT(block->fNodesInUse > 0 || block == &fFirstBlock); + SkASSERT((unsigned)block->fNodesInUse < N); int activeCnt = 0; int freeCnt = 0; for (unsigned int i = 0; i < N; ++i) { @@ -310,6 +324,7 @@ private: NodeList fList; NodeList fFreeList; + Block fFirstBlock; int fCount; }; |