summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorericwilligers <ericwilligers@chromium.org>2015-11-07 23:48:21 -0800
committerCommit bot <commit-bot@chromium.org>2015-11-08 07:49:19 +0000
commit341e2d4c6c1373a87a897091e93246c8e941b160 (patch)
treee4b1f3de3b27f938228d30d702674755300a9d66
parent549425200e38dad0ddd8bd826a032f7a6062e47a (diff)
downloadchromium_src-341e2d4c6c1373a87a897091e93246c8e941b160.zip
chromium_src-341e2d4c6c1373a87a897091e93246c8e941b160.tar.gz
chromium_src-341e2d4c6c1373a87a897091e93246c8e941b160.tar.bz2
Manage inlining during StyleInvalidation tree traversal
The Sibling invalidation set CL https://codereview.chromium.org/1317533002 added lots of code (after inlining) to StyleInvalidator::checkInvalidationSetsAgainstElement For the common case where there are no relevant sibling selector rules, we can avoid executing the new code, and so it does not need to be inlined. We aim to recover most of the recent 10% regression in the ClassDescendantSelector performance benchmark. TBR=esprehn,rune BUG=549246,378135 Review URL: https://codereview.chromium.org/1419373003 Cr-Commit-Position: refs/heads/master@{#358547}
-rw-r--r--third_party/WebKit/Source/core/css/invalidation/StyleInvalidator.cpp65
-rw-r--r--third_party/WebKit/Source/core/css/invalidation/StyleInvalidator.h7
2 files changed, 46 insertions, 26 deletions
diff --git a/third_party/WebKit/Source/core/css/invalidation/StyleInvalidator.cpp b/third_party/WebKit/Source/core/css/invalidation/StyleInvalidator.cpp
index 3cff622..db5fa17 100644
--- a/third_party/WebKit/Source/core/css/invalidation/StyleInvalidator.cpp
+++ b/third_party/WebKit/Source/core/css/invalidation/StyleInvalidator.cpp
@@ -147,7 +147,7 @@ void StyleInvalidator::SiblingData::pushInvalidationSet(const SiblingInvalidatio
m_invalidationEntries.append(Entry(&invalidationSet, invalidationLimit));
}
-ALWAYS_INLINE bool StyleInvalidator::SiblingData::matchCurrentInvalidationSets(Element& element, RecursionData& recursionData)
+bool StyleInvalidator::SiblingData::matchCurrentInvalidationSets(Element& element, RecursionData& recursionData) const
{
bool thisElementNeedsStyleRecalc = false;
ASSERT(!recursionData.wholeSubtreeInvalid());
@@ -155,6 +155,7 @@ ALWAYS_INLINE bool StyleInvalidator::SiblingData::matchCurrentInvalidationSets(E
unsigned index = 0;
while (index < m_invalidationEntries.size()) {
if (m_elementIndex > m_invalidationEntries[index].m_invalidationLimit) {
+ // m_invalidationEntries[index] only applies to earlier siblings. Remove it.
m_invalidationEntries[index] = m_invalidationEntries.last();
m_invalidationEntries.removeLast();
continue;
@@ -186,6 +187,26 @@ ALWAYS_INLINE bool StyleInvalidator::SiblingData::matchCurrentInvalidationSets(E
return thisElementNeedsStyleRecalc;
}
+void StyleInvalidator::pushInvalidationSetsForElement(Element& element, RecursionData& recursionData, SiblingData& siblingData)
+{
+ PendingInvalidations* pendingInvalidations = m_pendingInvalidationMap.get(&element);
+ ASSERT(pendingInvalidations);
+
+ for (const auto& invalidationSet : pendingInvalidations->siblings())
+ siblingData.pushInvalidationSet(toSiblingInvalidationSet(*invalidationSet));
+
+ if (!pendingInvalidations->descendants().isEmpty()) {
+ for (const auto& invalidationSet : pendingInvalidations->descendants())
+ recursionData.pushInvalidationSet(toDescendantInvalidationSet(*invalidationSet));
+ if (UNLIKELY(*s_tracingEnabled)) {
+ TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline.invalidationTracking"),
+ "StyleInvalidatorInvalidationTracking",
+ TRACE_EVENT_SCOPE_THREAD,
+ "data", InspectorStyleInvalidatorInvalidateEvent::invalidationList(element, pendingInvalidations->descendants()));
+ }
+ }
+}
+
ALWAYS_INLINE bool StyleInvalidator::checkInvalidationSetsAgainstElement(Element& element, RecursionData& recursionData, SiblingData& siblingData)
{
if (element.styleChangeType() >= SubtreeStyleChange || recursionData.wholeSubtreeInvalid()) {
@@ -194,36 +215,21 @@ ALWAYS_INLINE bool StyleInvalidator::checkInvalidationSetsAgainstElement(Element
}
bool thisElementNeedsStyleRecalc = recursionData.matchesCurrentInvalidationSets(element);
- thisElementNeedsStyleRecalc |= siblingData.matchCurrentInvalidationSets(element, recursionData);
-
- if (UNLIKELY(element.needsStyleInvalidation())) {
- PendingInvalidations* pendingInvalidations = m_pendingInvalidationMap.get(&element);
- ASSERT(pendingInvalidations);
-
- for (const auto& invalidationSet : pendingInvalidations->siblings())
- siblingData.pushInvalidationSet(toSiblingInvalidationSet(*invalidationSet));
-
- if (!pendingInvalidations->descendants().isEmpty()) {
- for (const auto& invalidationSet : pendingInvalidations->descendants())
- recursionData.pushInvalidationSet(toDescendantInvalidationSet(*invalidationSet));
- if (UNLIKELY(*s_tracingEnabled)) {
- TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline.invalidationTracking"),
- "StyleInvalidatorInvalidationTracking",
- TRACE_EVENT_SCOPE_THREAD,
- "data", InspectorStyleInvalidatorInvalidateEvent::invalidationList(element, pendingInvalidations->descendants()));
- }
- }
- }
+ if (UNLIKELY(!siblingData.isEmpty()))
+ thisElementNeedsStyleRecalc |= siblingData.matchCurrentInvalidationSets(element, recursionData);
+
+ if (UNLIKELY(element.needsStyleInvalidation()))
+ pushInvalidationSetsForElement(element, recursionData, siblingData);
return thisElementNeedsStyleRecalc;
}
-bool StyleInvalidator::invalidateChildren(Element& element, RecursionData& recursionData)
+bool StyleInvalidator::invalidateShadowRootChildren(Element& element, RecursionData& recursionData)
{
- SiblingData siblingData;
bool someChildrenNeedStyleRecalc = false;
for (ShadowRoot* root = element.youngestShadowRoot(); root; root = root->olderShadowRoot()) {
if (!recursionData.treeBoundaryCrossing() && !root->childNeedsStyleInvalidation() && !root->needsStyleInvalidation())
continue;
+ SiblingData siblingData;
for (Element* child = ElementTraversal::firstChild(*root); child; child = ElementTraversal::nextSibling(*child)) {
bool childRecalced = invalidate(*child, recursionData, siblingData);
someChildrenNeedStyleRecalc = someChildrenNeedStyleRecalc || childRecalced;
@@ -231,6 +237,17 @@ bool StyleInvalidator::invalidateChildren(Element& element, RecursionData& recur
root->clearChildNeedsStyleInvalidation();
root->clearNeedsStyleInvalidation();
}
+ return someChildrenNeedStyleRecalc;
+}
+
+bool StyleInvalidator::invalidateChildren(Element& element, RecursionData& recursionData)
+{
+ SiblingData siblingData;
+ bool someChildrenNeedStyleRecalc = false;
+ if (UNLIKELY(!!element.youngestShadowRoot())) {
+ someChildrenNeedStyleRecalc = invalidateShadowRootChildren(element, recursionData);
+ }
+
for (Element* child = ElementTraversal::firstChild(element); child; child = ElementTraversal::nextSibling(*child)) {
bool childRecalced = invalidate(*child, recursionData, siblingData);
someChildrenNeedStyleRecalc = someChildrenNeedStyleRecalc || childRecalced;
@@ -240,8 +257,8 @@ bool StyleInvalidator::invalidateChildren(Element& element, RecursionData& recur
bool StyleInvalidator::invalidate(Element& element, RecursionData& recursionData, SiblingData& siblingData)
{
- RecursionCheckpoint checkpoint(&recursionData);
siblingData.advance();
+ RecursionCheckpoint checkpoint(&recursionData);
bool thisElementNeedsStyleRecalc = checkInvalidationSetsAgainstElement(element, recursionData, siblingData);
diff --git a/third_party/WebKit/Source/core/css/invalidation/StyleInvalidator.h b/third_party/WebKit/Source/core/css/invalidation/StyleInvalidator.h
index f99f005..dabe953 100644
--- a/third_party/WebKit/Source/core/css/invalidation/StyleInvalidator.h
+++ b/third_party/WebKit/Source/core/css/invalidation/StyleInvalidator.h
@@ -63,8 +63,9 @@ private:
{ }
void pushInvalidationSet(const SiblingInvalidationSet&);
- bool matchCurrentInvalidationSets(Element&, RecursionData&);
+ bool matchCurrentInvalidationSets(Element&, RecursionData&) const;
+ bool isEmpty() const { return m_invalidationEntries.isEmpty(); }
void advance() { m_elementIndex++; }
private:
@@ -79,13 +80,15 @@ private:
unsigned m_invalidationLimit;
};
- Vector<Entry, 16> m_invalidationEntries;
+ mutable Vector<Entry, 16> m_invalidationEntries;
unsigned m_elementIndex;
};
bool invalidate(Element&, RecursionData&, SiblingData&);
+ bool invalidateShadowRootChildren(Element&, RecursionData&);
bool invalidateChildren(Element&, RecursionData&);
bool checkInvalidationSetsAgainstElement(Element&, RecursionData&, SiblingData&);
+ void pushInvalidationSetsForElement(Element&, RecursionData&, SiblingData&);
class RecursionCheckpoint {
public: