diff options
author | bsalomon <bsalomon@google.com> | 2016-07-11 08:31:27 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2016-07-11 08:31:27 -0700 |
commit | 810efb57b77d4ee6bf9eb3a09110567f439f21bd (patch) | |
tree | 65bb672e7faea473744373974a8c0f61f54de2c3 | |
parent | d0d652e0e0cb4bcecb7ccac9f4f4831fcaccdc45 (diff) |
Delay initialization of free list in SkTLList until first use of list
GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=2138043002
Review-Url: https://codereview.chromium.org/2138043002
-rw-r--r-- | src/core/SkTLList.h | 47 |
1 files changed, 32 insertions, 15 deletions
diff --git a/src/core/SkTLList.h b/src/core/SkTLList.h index 48e81bdac1..58fa3f4aac 100644 --- a/src/core/SkTLList.h +++ b/src/core/SkTLList.h @@ -38,14 +38,10 @@ private: 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(); - } + // Having fCount initialized to -1 indicates that the first time we attempt to grab a free node + // all the nodes in the pre-allocated first block need to be inserted into the free list. This + // allows us to skip that loop in instances when the list is never populated. + SkTLList() : fCount(-1) {} ~SkTLList() { this->validate(); @@ -148,18 +144,19 @@ public: this->remove(iter.get()); iter = next; } - SkASSERT(0 == fCount); + SkASSERT(0 == fCount || -1 == fCount); this->validate(); } - int count() const { return fCount; } - bool isEmpty() const { this->validate(); return 0 == fCount; } + int count() const { return SkTMax(fCount ,0); } + bool isEmpty() const { this->validate(); return 0 == fCount || -1 == fCount; } bool operator== (const SkTLList& list) const { if (this == &list) { return true; } - if (fCount != list.fCount) { + // Call count() rather than use fCount because an empty list may have fCount = 0 or -1. + if (this->count() != list.count()) { return false; } for (Iter a(*this, Iter::kHead_IterStart), b(list, Iter::kHead_IterStart); @@ -223,7 +220,21 @@ private: Node fNodes[N]; }; + void delayedInit() { + SkASSERT(-1 == fCount); + fFirstBlock.fNodesInUse = 0; + for (unsigned int i = 0; i < N; ++i) { + fFreeList.addToHead(fFirstBlock.fNodes + i); + fFirstBlock.fNodes[i].fBlock = &fFirstBlock; + } + fCount = 0; + this->validate(); + } + Node* createNode() { + if (-1 == fCount) { + this->delayedInit(); + } Node* node = fFreeList.head(); if (node) { fFreeList.remove(node); @@ -270,11 +281,17 @@ private: void validate() const { #ifdef SK_DEBUG - SkASSERT((0 == fCount) == fList.isEmpty()); - if (0 == fCount) { + bool isEmpty = false; + if (-1 == fCount) { + // We should not yet have initialized the free list. + SkASSERT(fFreeList.isEmpty()); + isEmpty = true; + } else if (0 == fCount) { // Should only have the nodes from the first block in the free list. SkASSERT(fFreeList.countEntries() == N); + isEmpty = true; } + SkASSERT(isEmpty == fList.isEmpty()); fList.validate(); fFreeList.validate(); typename NodeList::Iter iter; @@ -318,7 +335,7 @@ private: SkASSERT(activeCnt == block->fNodesInUse); activeNode = iter.next(); } - SkASSERT(count == fCount); + SkASSERT(count == fCount || (0 == count && -1 == fCount)); #endif } |