aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar bsalomon <bsalomon@google.com>2016-07-11 08:31:27 -0700
committerGravatar Commit bot <commit-bot@chromium.org>2016-07-11 08:31:27 -0700
commit810efb57b77d4ee6bf9eb3a09110567f439f21bd (patch)
tree65bb672e7faea473744373974a8c0f61f54de2c3
parentd0d652e0e0cb4bcecb7ccac9f4f4831fcaccdc45 (diff)
Delay initialization of free list in SkTLList until first use of list
-rw-r--r--src/core/SkTLList.h47
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
}