diff options
author | ericwilligers <ericwilligers@chromium.org> | 2015-11-07 23:48:21 -0800 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-11-08 07:49:19 +0000 |
commit | 341e2d4c6c1373a87a897091e93246c8e941b160 (patch) | |
tree | e4b1f3de3b27f938228d30d702674755300a9d66 | |
parent | 549425200e38dad0ddd8bd826a032f7a6062e47a (diff) | |
download | chromium_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.cpp | 65 | ||||
-rw-r--r-- | third_party/WebKit/Source/core/css/invalidation/StyleInvalidator.h | 7 |
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: |