<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[194762] trunk/Source/WebCore</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/194762">194762</a></dd>
<dt>Author</dt> <dd>antti@apple.com</dd>
<dt>Date</dt> <dd>2016-01-08 01:06:10 -0800 (Fri, 08 Jan 2016)</dd>
</dl>

<h3>Log Message</h3>
<pre>Enable selector filtering for shadow trees
https://bugs.webkit.org/show_bug.cgi?id=152831

Reviewed by Simon Fraser.

Selector filtering doesn't currently work in shadow trees making style resolve for them slow.
This is because SelectorFilter is not in &quot;consistent&quot; state.

This patch moves SelectorFilter ownership from StyleResolver to TreeResolver and guarantees
it is always upadated consistently. It eliminates a bunch of now unnecessary consistency checks
and special cases.

* css/ElementRuleCollector.cpp:
(WebCore::ElementRuleCollector::ElementRuleCollector):

    Assert for consistency instead of testing for it.

(WebCore::ElementRuleCollector::matchedResult):
(WebCore::ElementRuleCollector::collectMatchingRulesForList):

    Selector filter can now be used if it exists.

* css/ElementRuleCollector.h:
(WebCore::ElementRuleCollector::ElementRuleCollector): Deleted.
* css/RuleSet.cpp:
(WebCore::RuleSet::addRule):

    Disable selector filtering for custom shadow pseudo rules. They are resolved by shadow DOM resolver
    but may contain components matching the normal DOM.

* css/RuleSet.h:
(WebCore::RuleData::descendantSelectorIdentifierHashes):
(WebCore::RuleData::disableSelectorFiltering):
(WebCore::RuleData::compilationStatus):
(WebCore::RuleData::compiledSelectorCodeRef):
* css/SelectorFilter.cpp:
(WebCore::collectElementIdentifierHashes):
(WebCore::SelectorFilter::parentStackIsConsistent):

    New consistency conditions. This is now used for asserts only.

(WebCore::SelectorFilter::pushParentStackFrame):
(WebCore::SelectorFilter::popParentStackFrame):

    Selector filter only filters the current tree context, replace parentOrShadowHostElement with parentElement.

(WebCore::SelectorFilter::setupParentStack): Deleted.

    No longer needed.

(WebCore::SelectorFilter::pushParent):

    Remove consistency check. These cases no longer happen.

* css/SelectorFilter.h:
(WebCore::SelectorFilter::popParent):
(WebCore::SelectorFilter::parentStackIsEmpty):
(WebCore::SelectorFilter::fastRejectSelector):
(WebCore::SelectorFilter::parentStackIsConsistent): Deleted.
* css/StyleInvalidationAnalysis.cpp:
(WebCore::StyleInvalidationAnalysis::invalidateIfNeeded):
(WebCore::StyleInvalidationAnalysis::invalidateStyle):
* css/StyleResolver.cpp:
(WebCore::StyleResolver::appendAuthorStyleSheets):
(WebCore::StyleResolver::addKeyframeStyle):
(WebCore::StyleResolver::initElement):
(WebCore::StyleResolver::State::initForStyleResolve):

    We no longer owner the selector filter. Move it to State.

(WebCore::StyleResolver::styleSharingCandidateMatchesRuleSet):
(WebCore::isAtShadowBoundary):
(WebCore::StyleResolver::styleForElement):
(WebCore::StyleResolver::pseudoStyleForElement):
(WebCore::StyleResolver::pseudoStyleRulesForElement):
(WebCore::StyleResolver::pushParentElement): Deleted.
(WebCore::StyleResolver::popParentElement): Deleted.

    No need for this logic.

* css/StyleResolver.h:
(WebCore::StyleResolver::ruleSets):
(WebCore::StyleResolver::mediaQueryEvaluator):
(WebCore::StyleResolver::State::document):
(WebCore::StyleResolver::State::setAuthorRollback):
(WebCore::StyleResolver::State::setUserRollback):
(WebCore::StyleResolver::State::selectorFilter):
(WebCore::StyleResolver::state):
(WebCore::checkRegionSelector):
(WebCore::StyleResolver::selectorFilter): Deleted.
(WebCore::StyleResolverParentPusher::StyleResolverParentPusher): Deleted.
(WebCore::StyleResolverParentPusher::push): Deleted.
(WebCore::StyleResolverParentPusher::~StyleResolverParentPusher): Deleted.
* style/StyleTreeResolver.cpp:

    This now owns the selector filter for a tree context.

(WebCore::Style::SelectorFilterPusher::SelectorFilterPusher):
(WebCore::Style::SelectorFilterPusher::push):
(WebCore::Style::SelectorFilterPusher::~SelectorFilterPusher):
(WebCore::Style::TreeResolver::TreeResolver):
(WebCore::Style::TreeResolver::styleForElement):
(WebCore::Style::TreeResolver::createRenderTreeForSlotAssignees):
(WebCore::Style::TreeResolver::createRenderTreeRecursively):
(WebCore::Style::TreeResolver::resolveChildren):
(WebCore::Style::TreeResolver::resolveRecursively):

    Push the filter in a few more places to keep it consistent in shadow trees.

* style/StyleTreeResolver.h:</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCorecssElementRuleCollectorcpp">trunk/Source/WebCore/css/ElementRuleCollector.cpp</a></li>
<li><a href="#trunkSourceWebCorecssElementRuleCollectorh">trunk/Source/WebCore/css/ElementRuleCollector.h</a></li>
<li><a href="#trunkSourceWebCorecssRuleSetcpp">trunk/Source/WebCore/css/RuleSet.cpp</a></li>
<li><a href="#trunkSourceWebCorecssRuleSeth">trunk/Source/WebCore/css/RuleSet.h</a></li>
<li><a href="#trunkSourceWebCorecssSelectorFiltercpp">trunk/Source/WebCore/css/SelectorFilter.cpp</a></li>
<li><a href="#trunkSourceWebCorecssSelectorFilterh">trunk/Source/WebCore/css/SelectorFilter.h</a></li>
<li><a href="#trunkSourceWebCorecssStyleInvalidationAnalysiscpp">trunk/Source/WebCore/css/StyleInvalidationAnalysis.cpp</a></li>
<li><a href="#trunkSourceWebCorecssStyleResolvercpp">trunk/Source/WebCore/css/StyleResolver.cpp</a></li>
<li><a href="#trunkSourceWebCorecssStyleResolverh">trunk/Source/WebCore/css/StyleResolver.h</a></li>
<li><a href="#trunkSourceWebCorestyleStyleTreeResolvercpp">trunk/Source/WebCore/style/StyleTreeResolver.cpp</a></li>
<li><a href="#trunkSourceWebCorestyleStyleTreeResolverh">trunk/Source/WebCore/style/StyleTreeResolver.h</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (194761 => 194762)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2016-01-08 08:36:47 UTC (rev 194761)
+++ trunk/Source/WebCore/ChangeLog        2016-01-08 09:06:10 UTC (rev 194762)
</span><span class="lines">@@ -1,3 +1,116 @@
</span><ins>+2016-01-07  Antti Koivisto  &lt;antti@apple.com&gt;
+
+        Enable selector filtering for shadow trees
+        https://bugs.webkit.org/show_bug.cgi?id=152831
+
+        Reviewed by Simon Fraser.
+
+        Selector filtering doesn't currently work in shadow trees making style resolve for them slow.
+        This is because SelectorFilter is not in &quot;consistent&quot; state.
+
+        This patch moves SelectorFilter ownership from StyleResolver to TreeResolver and guarantees
+        it is always upadated consistently. It eliminates a bunch of now unnecessary consistency checks
+        and special cases.
+
+        * css/ElementRuleCollector.cpp:
+        (WebCore::ElementRuleCollector::ElementRuleCollector):
+
+            Assert for consistency instead of testing for it.
+
+        (WebCore::ElementRuleCollector::matchedResult):
+        (WebCore::ElementRuleCollector::collectMatchingRulesForList):
+
+            Selector filter can now be used if it exists.
+
+        * css/ElementRuleCollector.h:
+        (WebCore::ElementRuleCollector::ElementRuleCollector): Deleted.
+        * css/RuleSet.cpp:
+        (WebCore::RuleSet::addRule):
+
+            Disable selector filtering for custom shadow pseudo rules. They are resolved by shadow DOM resolver
+            but may contain components matching the normal DOM.
+
+        * css/RuleSet.h:
+        (WebCore::RuleData::descendantSelectorIdentifierHashes):
+        (WebCore::RuleData::disableSelectorFiltering):
+        (WebCore::RuleData::compilationStatus):
+        (WebCore::RuleData::compiledSelectorCodeRef):
+        * css/SelectorFilter.cpp:
+        (WebCore::collectElementIdentifierHashes):
+        (WebCore::SelectorFilter::parentStackIsConsistent):
+
+            New consistency conditions. This is now used for asserts only.
+
+        (WebCore::SelectorFilter::pushParentStackFrame):
+        (WebCore::SelectorFilter::popParentStackFrame):
+
+            Selector filter only filters the current tree context, replace parentOrShadowHostElement with parentElement.
+
+        (WebCore::SelectorFilter::setupParentStack): Deleted.
+
+            No longer needed.
+
+        (WebCore::SelectorFilter::pushParent):
+
+            Remove consistency check. These cases no longer happen.
+
+        * css/SelectorFilter.h:
+        (WebCore::SelectorFilter::popParent):
+        (WebCore::SelectorFilter::parentStackIsEmpty):
+        (WebCore::SelectorFilter::fastRejectSelector):
+        (WebCore::SelectorFilter::parentStackIsConsistent): Deleted.
+        * css/StyleInvalidationAnalysis.cpp:
+        (WebCore::StyleInvalidationAnalysis::invalidateIfNeeded):
+        (WebCore::StyleInvalidationAnalysis::invalidateStyle):
+        * css/StyleResolver.cpp:
+        (WebCore::StyleResolver::appendAuthorStyleSheets):
+        (WebCore::StyleResolver::addKeyframeStyle):
+        (WebCore::StyleResolver::initElement):
+        (WebCore::StyleResolver::State::initForStyleResolve):
+
+            We no longer owner the selector filter. Move it to State.
+
+        (WebCore::StyleResolver::styleSharingCandidateMatchesRuleSet):
+        (WebCore::isAtShadowBoundary):
+        (WebCore::StyleResolver::styleForElement):
+        (WebCore::StyleResolver::pseudoStyleForElement):
+        (WebCore::StyleResolver::pseudoStyleRulesForElement):
+        (WebCore::StyleResolver::pushParentElement): Deleted.
+        (WebCore::StyleResolver::popParentElement): Deleted.
+
+            No need for this logic.
+
+        * css/StyleResolver.h:
+        (WebCore::StyleResolver::ruleSets):
+        (WebCore::StyleResolver::mediaQueryEvaluator):
+        (WebCore::StyleResolver::State::document):
+        (WebCore::StyleResolver::State::setAuthorRollback):
+        (WebCore::StyleResolver::State::setUserRollback):
+        (WebCore::StyleResolver::State::selectorFilter):
+        (WebCore::StyleResolver::state):
+        (WebCore::checkRegionSelector):
+        (WebCore::StyleResolver::selectorFilter): Deleted.
+        (WebCore::StyleResolverParentPusher::StyleResolverParentPusher): Deleted.
+        (WebCore::StyleResolverParentPusher::push): Deleted.
+        (WebCore::StyleResolverParentPusher::~StyleResolverParentPusher): Deleted.
+        * style/StyleTreeResolver.cpp:
+
+            This now owns the selector filter for a tree context.
+
+        (WebCore::Style::SelectorFilterPusher::SelectorFilterPusher):
+        (WebCore::Style::SelectorFilterPusher::push):
+        (WebCore::Style::SelectorFilterPusher::~SelectorFilterPusher):
+        (WebCore::Style::TreeResolver::TreeResolver):
+        (WebCore::Style::TreeResolver::styleForElement):
+        (WebCore::Style::TreeResolver::createRenderTreeForSlotAssignees):
+        (WebCore::Style::TreeResolver::createRenderTreeRecursively):
+        (WebCore::Style::TreeResolver::resolveChildren):
+        (WebCore::Style::TreeResolver::resolveRecursively):
+
+            Push the filter in a few more places to keep it consistent in shadow trees.
+
+        * style/StyleTreeResolver.h:
+
</ins><span class="cx"> 2016-01-07  Zalan Bujtas  &lt;zalan@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Move computeLineBoundsForText from GraphicsContext* to GraphicsContext.
</span></span></pre></div>
<a id="trunkSourceWebCorecssElementRuleCollectorcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/css/ElementRuleCollector.cpp (194761 => 194762)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/css/ElementRuleCollector.cpp        2016-01-08 08:36:47 UTC (rev 194761)
+++ trunk/Source/WebCore/css/ElementRuleCollector.cpp        2016-01-08 09:06:10 UTC (rev 194762)
</span><span class="lines">@@ -40,6 +40,7 @@
</span><span class="cx"> #include &quot;RenderRegion.h&quot;
</span><span class="cx"> #include &quot;SVGElement.h&quot;
</span><span class="cx"> #include &quot;SelectorCompiler.h&quot;
</span><ins>+#include &quot;SelectorFilter.h&quot;
</ins><span class="cx"> #include &quot;ShadowRoot.h&quot;
</span><span class="cx"> #include &quot;StyleProperties.h&quot;
</span><span class="cx"> #include &quot;StyledElement.h&quot;
</span><span class="lines">@@ -75,6 +76,15 @@
</span><span class="cx">     const bool includeEmptyRules;
</span><span class="cx"> };
</span><span class="cx"> 
</span><ins>+ElementRuleCollector::ElementRuleCollector(Element&amp; element, RenderStyle* style, const DocumentRuleSets&amp; ruleSets, const SelectorFilter* selectorFilter)
+    : m_element(element)
+    , m_style(style)
+    , m_ruleSets(ruleSets)
+    , m_selectorFilter(selectorFilter)
+{
+    ASSERT(!m_selectorFilter || m_selectorFilter-&gt;parentStackIsConsistent(element.parentNode()));
+}
+
</ins><span class="cx"> StyleResolver::MatchResult&amp; ElementRuleCollector::matchedResult()
</span><span class="cx"> {
</span><span class="cx">     ASSERT(m_mode == SelectorChecker::Mode::ResolvingStyle);
</span><span class="lines">@@ -352,7 +362,7 @@
</span><span class="cx">         if (!ruleData.canMatchPseudoElement() &amp;&amp; m_pseudoStyleRequest.pseudoId != NOPSEUDO)
</span><span class="cx">             continue;
</span><span class="cx"> 
</span><del>-        if (m_canUseFastReject &amp;&amp; m_selectorFilter.fastRejectSelector&lt;RuleData::maximumIdentifierCount&gt;(ruleData.descendantSelectorIdentifierHashes()))
</del><ins>+        if (m_selectorFilter &amp;&amp; m_selectorFilter-&gt;fastRejectSelector&lt;RuleData::maximumIdentifierCount&gt;(ruleData.descendantSelectorIdentifierHashes()))
</ins><span class="cx">             continue;
</span><span class="cx"> 
</span><span class="cx">         StyleRule* rule = ruleData.rule();
</span></span></pre></div>
<a id="trunkSourceWebCorecssElementRuleCollectorh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/css/ElementRuleCollector.h (194761 => 194762)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/css/ElementRuleCollector.h        2016-01-08 08:36:47 UTC (rev 194761)
+++ trunk/Source/WebCore/css/ElementRuleCollector.h        2016-01-08 09:06:10 UTC (rev 194762)
</span><span class="lines">@@ -45,14 +45,7 @@
</span><span class="cx"> 
</span><span class="cx"> class ElementRuleCollector {
</span><span class="cx"> public:
</span><del>-    ElementRuleCollector(Element&amp; element, RenderStyle* style, const DocumentRuleSets&amp; ruleSets, const SelectorFilter&amp; selectorFilter)
-        : m_element(element)
-        , m_style(style)
-        , m_ruleSets(ruleSets)
-        , m_selectorFilter(selectorFilter)
-        , m_canUseFastReject(m_selectorFilter.parentStackIsConsistent(element.parentNode()))
-    {
-    }
</del><ins>+    ElementRuleCollector(Element&amp;, RenderStyle*, const DocumentRuleSets&amp;, const SelectorFilter*);
</ins><span class="cx"> 
</span><span class="cx">     void matchAllRules(bool matchAuthorAndUserStyles, bool includeSMILProperties);
</span><span class="cx">     void matchUARules();
</span><span class="lines">@@ -94,14 +87,13 @@
</span><span class="cx">     Element&amp; m_element;
</span><span class="cx">     RenderStyle* m_style;
</span><span class="cx">     const DocumentRuleSets&amp; m_ruleSets;
</span><del>-    const SelectorFilter&amp; m_selectorFilter;
</del><ins>+    const SelectorFilter* m_selectorFilter;
</ins><span class="cx"> 
</span><span class="cx">     bool m_isPrintStyle { false };
</span><span class="cx">     const RenderRegion* m_regionForStyling { nullptr };
</span><span class="cx">     PseudoStyleRequest m_pseudoStyleRequest { NOPSEUDO };
</span><span class="cx">     bool m_sameOriginOnly { false };
</span><span class="cx">     SelectorChecker::Mode m_mode { SelectorChecker::Mode::ResolvingStyle };
</span><del>-    bool m_canUseFastReject;
</del><span class="cx"> 
</span><span class="cx">     Vector&lt;MatchedRule, 64&gt; m_matchedRules;
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCorecssRuleSetcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/css/RuleSet.cpp (194761 => 194762)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/css/RuleSet.cpp        2016-01-08 08:36:47 UTC (rev 194761)
+++ trunk/Source/WebCore/css/RuleSet.cpp        2016-01-08 09:06:10 UTC (rev 194762)
</span><span class="lines">@@ -225,6 +225,8 @@
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><span class="cx">         if (selector-&gt;isCustomPseudoElement()) {
</span><ins>+            // FIXME: Custom pseudo elements are handled by the shadow tree's selector filter. It doesn't know about the main DOM.
+            ruleData.disableSelectorFiltering();
</ins><span class="cx">             addToRuleSet(selector-&gt;value().impl(), m_shadowPseudoElementRules, ruleData);
</span><span class="cx">             return;
</span><span class="cx">         }
</span></span></pre></div>
<a id="trunkSourceWebCorecssRuleSeth"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/css/RuleSet.h (194761 => 194762)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/css/RuleSet.h        2016-01-08 08:36:47 UTC (rev 194761)
+++ trunk/Source/WebCore/css/RuleSet.h        2016-01-08 09:06:10 UTC (rev 194762)
</span><span class="lines">@@ -84,6 +84,8 @@
</span><span class="cx">     static const unsigned maximumIdentifierCount = 4;
</span><span class="cx">     const unsigned* descendantSelectorIdentifierHashes() const { return m_descendantSelectorIdentifierHashes; }
</span><span class="cx"> 
</span><ins>+    void disableSelectorFiltering() { m_descendantSelectorIdentifierHashes[0] = 0; }
+
</ins><span class="cx"> #if ENABLE(CSS_SELECTOR_JIT)
</span><span class="cx">     SelectorCompilationStatus compilationStatus() const { return m_compilationStatus; }
</span><span class="cx">     JSC::MacroAssemblerCodeRef compiledSelectorCodeRef() const { return m_compiledSelectorCodeRef; }
</span></span></pre></div>
<a id="trunkSourceWebCorecssSelectorFiltercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/css/SelectorFilter.cpp (194761 => 194762)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/css/SelectorFilter.cpp        2016-01-08 08:36:47 UTC (rev 194761)
+++ trunk/Source/WebCore/css/SelectorFilter.cpp        2016-01-08 09:06:10 UTC (rev 194762)
</span><span class="lines">@@ -30,6 +30,7 @@
</span><span class="cx"> #include &quot;SelectorFilter.h&quot;
</span><span class="cx"> 
</span><span class="cx"> #include &quot;CSSSelector.h&quot;
</span><ins>+#include &quot;ShadowRoot.h&quot;
</ins><span class="cx"> #include &quot;StyledElement.h&quot;
</span><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span><span class="lines">@@ -53,11 +54,18 @@
</span><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+bool SelectorFilter::parentStackIsConsistent(const ContainerNode* parentNode) const
+{
+    if (!parentNode || is&lt;Document&gt;(parentNode) || is&lt;ShadowRoot&gt;(parentNode))
+        return m_parentStack.isEmpty();
+
+    return !m_parentStack.isEmpty() &amp;&amp; m_parentStack.last().element == parentNode;
+}
+
</ins><span class="cx"> void SelectorFilter::pushParentStackFrame(Element* parent)
</span><span class="cx"> {
</span><del>-    ASSERT(m_ancestorIdentifierFilter);
-    ASSERT(m_parentStack.isEmpty() || m_parentStack.last().element == parent-&gt;parentOrShadowHostElement());
-    ASSERT(!m_parentStack.isEmpty() || !parent-&gt;parentOrShadowHostElement());
</del><ins>+    ASSERT(m_parentStack.isEmpty() || m_parentStack.last().element == parent-&gt;parentElement());
+    ASSERT(!m_parentStack.isEmpty() || !parent-&gt;parentElement());
</ins><span class="cx">     m_parentStack.append(ParentStackFrame(parent));
</span><span class="cx">     ParentStackFrame&amp; parentFrame = m_parentStack.last();
</span><span class="cx">     // Mix tags, class names and ids into some sort of weird bouillabaisse.
</span><span class="lines">@@ -65,50 +73,25 @@
</span><span class="cx">     collectElementIdentifierHashes(parent, parentFrame.identifierHashes);
</span><span class="cx">     size_t count = parentFrame.identifierHashes.size();
</span><span class="cx">     for (size_t i = 0; i &lt; count; ++i)
</span><del>-        m_ancestorIdentifierFilter-&gt;add(parentFrame.identifierHashes[i]);
</del><ins>+        m_ancestorIdentifierFilter.add(parentFrame.identifierHashes[i]);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void SelectorFilter::popParentStackFrame()
</span><span class="cx"> {
</span><span class="cx">     ASSERT(!m_parentStack.isEmpty());
</span><del>-    ASSERT(m_ancestorIdentifierFilter);
</del><span class="cx">     const ParentStackFrame&amp; parentFrame = m_parentStack.last();
</span><span class="cx">     size_t count = parentFrame.identifierHashes.size();
</span><span class="cx">     for (size_t i = 0; i &lt; count; ++i)
</span><del>-        m_ancestorIdentifierFilter-&gt;remove(parentFrame.identifierHashes[i]);
</del><ins>+        m_ancestorIdentifierFilter.remove(parentFrame.identifierHashes[i]);
</ins><span class="cx">     m_parentStack.removeLast();
</span><span class="cx">     if (m_parentStack.isEmpty()) {
</span><del>-        ASSERT(m_ancestorIdentifierFilter-&gt;likelyEmpty());
-        m_ancestorIdentifierFilter = nullptr;
</del><ins>+        ASSERT(m_ancestorIdentifierFilter.likelyEmpty());
+        m_ancestorIdentifierFilter.clear();
</ins><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void SelectorFilter::setupParentStack(Element* parent)
-{
-    ASSERT(m_parentStack.isEmpty() == !m_ancestorIdentifierFilter);
-    // Kill whatever we stored before.
-    m_parentStack.shrink(0);
-    m_ancestorIdentifierFilter = std::make_unique&lt;CountingBloomFilter&lt;bloomFilterKeyBits&gt;&gt;();
-    // Fast version if parent is a root element:
-    if (!parent-&gt;parentNode() &amp;&amp; !parent-&gt;isShadowRoot()) {
-        pushParentStackFrame(parent);
-        return;
-    }
-    // Otherwise climb up the tree.
-    Vector&lt;Element*, 30&gt; ancestors;
-    for (Element* ancestor = parent; ancestor; ancestor = ancestor-&gt;parentOrShadowHostElement())
-        ancestors.append(ancestor);
-    for (size_t n = ancestors.size(); n; --n)
-        pushParentStackFrame(ancestors[n - 1]);
-}
-
</del><span class="cx"> void SelectorFilter::pushParent(Element* parent)
</span><span class="cx"> {
</span><del>-    ASSERT(m_ancestorIdentifierFilter);
-    // We may get invoked for some random elements in some wacky cases during style resolve.
-    // Pause maintaining the stack in this case.
-    if (m_parentStack.last().element != parent-&gt;parentOrShadowHostElement())
-        return;
</del><span class="cx">     pushParentStackFrame(parent);
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCorecssSelectorFilterh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/css/SelectorFilter.h (194761 => 194762)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/css/SelectorFilter.h        2016-01-08 08:36:47 UTC (rev 194761)
+++ trunk/Source/WebCore/css/SelectorFilter.h        2016-01-08 09:06:10 UTC (rev 194762)
</span><span class="lines">@@ -43,11 +43,10 @@
</span><span class="cx">     void pushParentStackFrame(Element* parent);
</span><span class="cx">     void popParentStackFrame();
</span><span class="cx"> 
</span><del>-    void setupParentStack(Element* parent);
</del><span class="cx">     void pushParent(Element* parent);
</span><span class="cx">     void popParent() { popParentStackFrame(); }
</span><span class="cx">     bool parentStackIsEmpty() const { return m_parentStack.isEmpty(); }
</span><del>-    bool parentStackIsConsistent(const ContainerNode* parentNode) const { return !m_parentStack.isEmpty() &amp;&amp; m_parentStack.last().element == parentNode; }
</del><ins>+    bool parentStackIsConsistent(const ContainerNode* parentNode) const;
</ins><span class="cx"> 
</span><span class="cx">     template &lt;unsigned maximumIdentifierCount&gt;
</span><span class="cx">     inline bool fastRejectSelector(const unsigned* identifierHashes) const;
</span><span class="lines">@@ -64,15 +63,14 @@
</span><span class="cx"> 
</span><span class="cx">     // With 100 unique strings in the filter, 2^12 slot table has false positive rate of ~0.2%.
</span><span class="cx">     static const unsigned bloomFilterKeyBits = 12;
</span><del>-    std::unique_ptr&lt;CountingBloomFilter&lt;bloomFilterKeyBits&gt;&gt; m_ancestorIdentifierFilter;
</del><ins>+    CountingBloomFilter&lt;bloomFilterKeyBits&gt; m_ancestorIdentifierFilter;
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> template &lt;unsigned maximumIdentifierCount&gt;
</span><span class="cx"> inline bool SelectorFilter::fastRejectSelector(const unsigned* identifierHashes) const
</span><span class="cx"> {
</span><del>-    ASSERT(m_ancestorIdentifierFilter);
</del><span class="cx">     for (unsigned n = 0; n &lt; maximumIdentifierCount &amp;&amp; identifierHashes[n]; ++n) {
</span><del>-        if (!m_ancestorIdentifierFilter-&gt;mayContain(identifierHashes[n]))
</del><ins>+        if (!m_ancestorIdentifierFilter.mayContain(identifierHashes[n]))
</ins><span class="cx">             return true;
</span><span class="cx">     }
</span><span class="cx">     return false;
</span></span></pre></div>
<a id="trunkSourceWebCorecssStyleInvalidationAnalysiscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/css/StyleInvalidationAnalysis.cpp (194761 => 194762)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/css/StyleInvalidationAnalysis.cpp        2016-01-08 08:36:47 UTC (rev 194761)
+++ trunk/Source/WebCore/css/StyleInvalidationAnalysis.cpp        2016-01-08 09:06:10 UTC (rev 194762)
</span><span class="lines">@@ -97,7 +97,7 @@
</span><span class="cx"> 
</span><span class="cx">     switch (element.styleChangeType()) {
</span><span class="cx">     case NoStyleChange: {
</span><del>-        ElementRuleCollector ruleCollector(element, nullptr, m_ruleSets, filter);
</del><ins>+        ElementRuleCollector ruleCollector(element, nullptr, m_ruleSets, &amp;filter);
</ins><span class="cx">         ruleCollector.setMode(SelectorChecker::Mode::CollectingRulesIgnoringVirtualPseudoElements);
</span><span class="cx">         ruleCollector.matchAuthorRules(false);
</span><span class="cx"> 
</span><span class="lines">@@ -145,11 +145,6 @@
</span><span class="cx">         else
</span><span class="cx">             it.traverseNextSkippingChildren();
</span><span class="cx">     }
</span><del>-
-    while (!parentStack.isEmpty()) {
-        parentStack.removeLast();
-        filter.popParent();
-    }
</del><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void StyleInvalidationAnalysis::invalidateStyle(Document&amp; document)
</span><span class="lines">@@ -163,7 +158,6 @@
</span><span class="cx">         return;
</span><span class="cx"> 
</span><span class="cx">     SelectorFilter filter;
</span><del>-    filter.setupParentStack(documentElement);
</del><span class="cx">     invalidateStyleForTree(*documentElement, filter);
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCorecssStyleResolvercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/css/StyleResolver.cpp (194761 => 194762)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/css/StyleResolver.cpp        2016-01-08 08:36:47 UTC (rev 194761)
+++ trunk/Source/WebCore/css/StyleResolver.cpp        2016-01-08 09:06:10 UTC (rev 194762)
</span><span class="lines">@@ -293,28 +293,6 @@
</span><span class="cx"> #endif
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void StyleResolver::pushParentElement(Element* parent)
-{
-    const ContainerNode* parentsParent = parent-&gt;parentOrShadowHostElement();
-
-    // We are not always invoked consistently. For example, script execution can cause us to enter
-    // style recalc in the middle of tree building. We may also be invoked from somewhere within the tree.
-    // Reset the stack in this case, or if we see a new root element.
-    // Otherwise just push the new parent.
-    if (!parentsParent || m_selectorFilter.parentStackIsEmpty())
-        m_selectorFilter.setupParentStack(parent);
-    else
-        m_selectorFilter.pushParent(parent);
-}
-
-void StyleResolver::popParentElement(Element* parent)
-{
-    // Note that we may get invoked for some random elements in some wacky cases during style resolve.
-    // Pause maintaining the stack in this case.
-    if (m_selectorFilter.parentStackIsConsistent(parent))
-        m_selectorFilter.popParent();
-}
-
</del><span class="cx"> // This is a simplified style setting function for keyframe styles
</span><span class="cx"> void StyleResolver::addKeyframeStyle(PassRefPtr&lt;StyleRuleKeyframes&gt; rule)
</span><span class="cx"> {
</span><span class="lines">@@ -387,7 +365,7 @@
</span><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-inline void StyleResolver::State::initForStyleResolve(Document&amp; document, Element* e, RenderStyle* parentStyle, const RenderRegion* regionForStyling)
</del><ins>+inline void StyleResolver::State::initForStyleResolve(Document&amp; document, Element* e, RenderStyle* parentStyle, const RenderRegion* regionForStyling, const SelectorFilter* selectorFilter)
</ins><span class="cx"> {
</span><span class="cx">     m_regionForStyling = regionForStyling;
</span><span class="cx"> 
</span><span class="lines">@@ -408,6 +386,8 @@
</span><span class="cx">     m_authorRollback = nullptr;
</span><span class="cx">     m_userRollback = nullptr;
</span><span class="cx"> 
</span><ins>+    m_selectorFilter = selectorFilter;
+
</ins><span class="cx">     updateConversionData();
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -475,7 +455,7 @@
</span><span class="cx">     if (!ruleSet)
</span><span class="cx">         return false;
</span><span class="cx"> 
</span><del>-    ElementRuleCollector collector(*m_state.element(), m_state.style(), m_ruleSets, m_selectorFilter);
</del><ins>+    ElementRuleCollector collector(*m_state.element(), m_state.style(), m_ruleSets, m_state.selectorFilter());
</ins><span class="cx">     return collector.hasAnyMatchingRules(ruleSet);
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -723,7 +703,7 @@
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> Ref&lt;RenderStyle&gt; StyleResolver::styleForElement(Element* element, RenderStyle* defaultParent,
</span><del>-    StyleSharingBehavior sharingBehavior, RuleMatchingBehavior matchingBehavior, const RenderRegion* regionForStyling)
</del><ins>+    StyleSharingBehavior sharingBehavior, RuleMatchingBehavior matchingBehavior, const RenderRegion* regionForStyling, const SelectorFilter* selectorFilter)
</ins><span class="cx"> {
</span><span class="cx">     RELEASE_ASSERT(!m_inLoadPendingImages);
</span><span class="cx"> 
</span><span class="lines">@@ -741,7 +721,8 @@
</span><span class="cx"> 
</span><span class="cx">     State&amp; state = m_state;
</span><span class="cx">     initElement(element);
</span><del>-    state.initForStyleResolve(document(), element, defaultParent, regionForStyling);
</del><ins>+    state.initForStyleResolve(document(), element, defaultParent, regionForStyling, selectorFilter);
+
</ins><span class="cx">     if (sharingBehavior == AllowStyleSharing) {
</span><span class="cx">         if (RenderStyle* sharedStyle = locateSharedStyle()) {
</span><span class="cx">             state.clear();
</span><span class="lines">@@ -773,7 +754,7 @@
</span><span class="cx">     if (needsCollection)
</span><span class="cx">         m_ruleSets.collectFeatures();
</span><span class="cx"> 
</span><del>-    ElementRuleCollector collector(*element, state.style(), m_ruleSets, m_selectorFilter);
</del><ins>+    ElementRuleCollector collector(*element, state.style(), m_ruleSets, m_state.selectorFilter());
</ins><span class="cx">     collector.setRegionForStyling(regionForStyling);
</span><span class="cx">     collector.setMedium(m_medium.get());
</span><span class="cx"> 
</span><span class="lines">@@ -939,7 +920,7 @@
</span><span class="cx">     // those rules.
</span><span class="cx"> 
</span><span class="cx">     // Check UA, user and author rules.
</span><del>-    ElementRuleCollector collector(*element, m_state.style(), m_ruleSets, m_selectorFilter);
</del><ins>+    ElementRuleCollector collector(*element, m_state.style(), m_ruleSets, m_state.selectorFilter());
</ins><span class="cx">     collector.setPseudoStyleRequest(pseudoStyleRequest);
</span><span class="cx">     collector.setMedium(m_medium.get());
</span><span class="cx">     collector.matchUARules();
</span><span class="lines">@@ -1418,7 +1399,7 @@
</span><span class="cx">     initElement(element);
</span><span class="cx">     m_state.initForStyleResolve(document(), element, nullptr);
</span><span class="cx"> 
</span><del>-    ElementRuleCollector collector(*element, m_state.style(), m_ruleSets, m_selectorFilter);
</del><ins>+    ElementRuleCollector collector(*element, m_state.style(), m_ruleSets, m_state.selectorFilter());
</ins><span class="cx">     collector.setMode(SelectorChecker::Mode::CollectingRules);
</span><span class="cx">     collector.setPseudoStyleRequest(PseudoStyleRequest(pseudoId));
</span><span class="cx">     collector.setMedium(m_medium.get());
</span></span></pre></div>
<a id="trunkSourceWebCorecssStyleResolverh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/css/StyleResolver.h (194761 => 194762)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/css/StyleResolver.h        2016-01-08 08:36:47 UTC (rev 194761)
+++ trunk/Source/WebCore/css/StyleResolver.h        2016-01-08 09:06:10 UTC (rev 194762)
</span><span class="lines">@@ -35,7 +35,6 @@
</span><span class="cx"> #include &quot;RuntimeEnabledFeatures.h&quot;
</span><span class="cx"> #include &quot;ScrollTypes.h&quot;
</span><span class="cx"> #include &quot;SelectorChecker.h&quot;
</span><del>-#include &quot;SelectorFilter.h&quot;
</del><span class="cx"> #include &quot;StyleInheritedData.h&quot;
</span><span class="cx"> #include &quot;ViewportStyleResolver.h&quot;
</span><span class="cx"> #include &lt;bitset&gt;
</span><span class="lines">@@ -76,6 +75,7 @@
</span><span class="cx"> class RenderScrollbar;
</span><span class="cx"> class RuleData;
</span><span class="cx"> class RuleSet;
</span><ins>+class SelectorFilter;
</ins><span class="cx"> class Settings;
</span><span class="cx"> class StyleImage;
</span><span class="cx"> class StyleKeyframe;
</span><span class="lines">@@ -135,12 +135,8 @@
</span><span class="cx">     StyleResolver(Document&amp;);
</span><span class="cx">     ~StyleResolver();
</span><span class="cx"> 
</span><del>-    // Using these during tree walk will allow style selector to optimize child and descendant selector lookups.
-    void pushParentElement(Element*);
-    void popParentElement(Element*);
-
</del><span class="cx">     Ref&lt;RenderStyle&gt; styleForElement(Element*, RenderStyle* parentStyle, StyleSharingBehavior = AllowStyleSharing,
</span><del>-        RuleMatchingBehavior = MatchAllRules, const RenderRegion* regionForStyling = nullptr);
</del><ins>+        RuleMatchingBehavior = MatchAllRules, const RenderRegion* regionForStyling = nullptr, const SelectorFilter* = nullptr);
</ins><span class="cx"> 
</span><span class="cx">     void keyframeStylesForAnimation(Element*, const RenderStyle*, KeyframeList&amp;);
</span><span class="cx"> 
</span><span class="lines">@@ -160,7 +156,6 @@
</span><span class="cx"> 
</span><span class="cx">     DocumentRuleSets&amp; ruleSets() { return m_ruleSets; }
</span><span class="cx">     const DocumentRuleSets&amp; ruleSets() const { return m_ruleSets; }
</span><del>-    SelectorFilter&amp; selectorFilter() { return m_selectorFilter; }
</del><span class="cx"> 
</span><span class="cx">     const MediaQueryEvaluator&amp; mediaQueryEvaluator() const { return *m_medium; }
</span><span class="cx"> 
</span><span class="lines">@@ -385,7 +380,7 @@
</span><span class="cx"> 
</span><span class="cx">     public:
</span><span class="cx">         void initElement(Element*);
</span><del>-        void initForStyleResolve(Document&amp;, Element*, RenderStyle* parentStyle, const RenderRegion* regionForStyling = nullptr);
</del><ins>+        void initForStyleResolve(Document&amp;, Element*, RenderStyle* parentStyle, const RenderRegion* regionForStyling = nullptr, const SelectorFilter* = nullptr);
</ins><span class="cx">         void clear();
</span><span class="cx"> 
</span><span class="cx">         Document&amp; document() const { return m_element-&gt;document(); }
</span><span class="lines">@@ -443,6 +438,8 @@
</span><span class="cx">         
</span><span class="cx">         void setAuthorRollback(std::unique_ptr&lt;CascadedProperties&gt;&amp; rollback) { m_authorRollback = WTFMove(rollback); }
</span><span class="cx">         void setUserRollback(std::unique_ptr&lt;CascadedProperties&gt;&amp; rollback) { m_userRollback = WTFMove(rollback); }
</span><ins>+
+        const SelectorFilter* selectorFilter() const { return m_selectorFilter; }
</ins><span class="cx">         
</span><span class="cx">     private:
</span><span class="cx">         void updateConversionData();
</span><span class="lines">@@ -480,6 +477,8 @@
</span><span class="cx">         CascadeLevel m_cascadeLevel { UserAgentLevel };
</span><span class="cx">         std::unique_ptr&lt;CascadedProperties&gt; m_authorRollback;
</span><span class="cx">         std::unique_ptr&lt;CascadedProperties&gt; m_userRollback;
</span><ins>+
+        const SelectorFilter* m_selectorFilter { nullptr };
</ins><span class="cx">     };
</span><span class="cx"> 
</span><span class="cx">     State&amp; state() { return m_state; }
</span><span class="lines">@@ -559,7 +558,6 @@
</span><span class="cx">     RefPtr&lt;RenderStyle&gt; m_rootDefaultStyle;
</span><span class="cx"> 
</span><span class="cx">     Document&amp; m_document;
</span><del>-    SelectorFilter m_selectorFilter;
</del><span class="cx"> 
</span><span class="cx">     bool m_matchAuthorAndUserStyles;
</span><span class="cx"> 
</span><span class="lines">@@ -618,34 +616,6 @@
</span><span class="cx">     return false;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-class StyleResolverParentPusher {
-public:
-    StyleResolverParentPusher(Element* parent)
-        : m_parent(parent)
-        , m_pushedStyleResolver(nullptr)
-    { }
-    void push()
-    {
-        if (m_pushedStyleResolver)
-            return;
-        m_pushedStyleResolver = &amp;m_parent-&gt;styleResolver();
-        m_pushedStyleResolver-&gt;pushParentElement(m_parent);
-    }
-    ~StyleResolverParentPusher()
-    {
-        if (!m_pushedStyleResolver)
-            return;
-        // This tells us that our pushed style selector is in a bad state,
-        // so we should just bail out in that scenario.
-        ASSERT(m_pushedStyleResolver == &amp;m_parent-&gt;styleResolver());
-        m_pushedStyleResolver-&gt;popParentElement(m_parent);
-    }
-    
-private:
-    Element* m_parent;
-    StyleResolver* m_pushedStyleResolver;
-};
-
</del><span class="cx"> } // namespace WebCore
</span><span class="cx"> 
</span><span class="cx"> #endif // StyleResolver_h
</span></span></pre></div>
<a id="trunkSourceWebCorestyleStyleTreeResolvercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/style/StyleTreeResolver.cpp (194761 => 194762)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/style/StyleTreeResolver.cpp        2016-01-08 08:36:47 UTC (rev 194761)
+++ trunk/Source/WebCore/style/StyleTreeResolver.cpp        2016-01-08 09:06:10 UTC (rev 194762)
</span><span class="lines">@@ -66,6 +66,36 @@
</span><span class="cx"> static void detachRenderTree(Element&amp;, DetachType);
</span><span class="cx"> static void resolveTextNode(Text&amp;, RenderTreePosition&amp;);
</span><span class="cx"> 
</span><ins>+class SelectorFilterPusher {
+public:
+    enum PushMode { Push, NoPush };
+    SelectorFilterPusher(SelectorFilter&amp; selectorFilter, Element&amp; parent, PushMode pushMode = Push)
+        : m_selectorFilter(selectorFilter)
+        , m_parent(parent)
+    {
+        if (pushMode == Push)
+            push();
+    }
+    void push()
+    {
+        if (m_didPush)
+            return;
+        m_didPush = true;
+        m_selectorFilter.pushParent(&amp;m_parent);
+    }
+    ~SelectorFilterPusher()
+    {
+        if (!m_didPush)
+            return;
+        m_selectorFilter.popParent();
+    }
+    
+private:
+    SelectorFilter&amp; m_selectorFilter;
+    Element&amp; m_parent;
+    bool m_didPush { false };
+};
+
</ins><span class="cx"> TreeResolver::TreeResolver(Document&amp; document)
</span><span class="cx">     : m_document(document)
</span><span class="cx">     , m_styleResolver(document.ensureStyleResolver())
</span><span class="lines">@@ -97,7 +127,7 @@
</span><span class="cx">         if (RefPtr&lt;RenderStyle&gt; style = element.customStyleForRenderer(inheritedStyle))
</span><span class="cx">             return style.releaseNonNull();
</span><span class="cx">     }
</span><del>-    return m_styleResolver.styleForElement(&amp;element, &amp;inheritedStyle);
</del><ins>+    return m_styleResolver.styleForElement(&amp;element, &amp;inheritedStyle, AllowStyleSharing, MatchAllRules, nullptr, &amp;m_selectorFilter);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> #if ENABLE(CSS_REGIONS)
</span><span class="lines">@@ -410,8 +440,10 @@
</span><span class="cx">             else if (is&lt;Element&gt;(*child))
</span><span class="cx">                 m_shadowHostTreeResolver-&gt;createRenderTreeRecursively(downcast&lt;Element&gt;(*child), inheritedStyle, renderTreePosition, nullptr);
</span><span class="cx">         }
</span><del>-    } else
</del><ins>+    } else {
+        SelectorFilterPusher selectorFilterPusher(m_selectorFilter, slot);
</ins><span class="cx">         createRenderTreeForChildren(slot, inheritedStyle, renderTreePosition);
</span><ins>+    }
</ins><span class="cx"> 
</span><span class="cx">     slot.clearNeedsStyleRecalc();
</span><span class="cx">     slot.clearChildNeedsStyleRecalc();
</span><span class="lines">@@ -436,16 +468,17 @@
</span><span class="cx">     createRenderer(current, inheritedStyle, renderTreePosition, WTFMove(resolvedStyle));
</span><span class="cx"> 
</span><span class="cx">     if (auto* renderer = current.renderer()) {
</span><del>-        StyleResolverParentPusher parentPusher(&amp;current);
</del><ins>+        SelectorFilterPusher selectorFilterPusher(m_selectorFilter, current, SelectorFilterPusher::NoPush);
</ins><span class="cx"> 
</span><span class="cx">         RenderTreePosition childRenderTreePosition(*renderer);
</span><span class="cx">         createRenderTreeForBeforeOrAfterPseudoElement(current, BEFORE, childRenderTreePosition);
</span><span class="cx"> 
</span><span class="cx">         auto* shadowRoot = current.shadowRoot();
</span><del>-        if (shadowRoot)
</del><ins>+        if (shadowRoot) {
+            selectorFilterPusher.push();
</ins><span class="cx">             createRenderTreeForShadowRoot(*shadowRoot);
</span><del>-        else if (current.firstChild())
-            parentPusher.push();
</del><ins>+        } else if (current.firstChild())
+            selectorFilterPusher.push();
</ins><span class="cx"> 
</span><span class="cx">         bool skipChildren = shadowRoot;
</span><span class="cx">         if (!skipChildren)
</span><span class="lines">@@ -730,7 +763,7 @@
</span><span class="cx"> 
</span><span class="cx"> void TreeResolver::resolveChildren(Element&amp; current, RenderStyle&amp; inheritedStyle, Change change, RenderTreePosition&amp; childRenderTreePosition)
</span><span class="cx"> {
</span><del>-    StyleResolverParentPusher parentPusher(&amp;current);
</del><ins>+    SelectorFilterPusher selectorFilterPusher(m_selectorFilter, current, SelectorFilterPusher::NoPush);
</ins><span class="cx"> 
</span><span class="cx">     bool elementNeedingStyleRecalcAffectsNextSiblingElementStyle = false;
</span><span class="cx">     for (Node* child = current.firstChild(); child; child = child-&gt;nextSibling()) {
</span><span class="lines">@@ -751,7 +784,7 @@
</span><span class="cx">         } else if (childElement.needsStyleRecalc())
</span><span class="cx">             elementNeedingStyleRecalcAffectsNextSiblingElementStyle = childElement.affectsNextSiblingElementStyle();
</span><span class="cx">         if (change &gt;= Inherit || childElement.childNeedsStyleRecalc() || childElement.needsStyleRecalc()) {
</span><del>-            parentPusher.push();
</del><ins>+            selectorFilterPusher.push();
</ins><span class="cx">             resolveRecursively(childElement, inheritedStyle, childRenderTreePosition, change);
</span><span class="cx">         }
</span><span class="cx">     }
</span><span class="lines">@@ -803,6 +836,8 @@
</span><span class="cx">     if (change != Detach &amp;&amp; renderer) {
</span><span class="cx">         auto* shadowRoot = current.shadowRoot();
</span><span class="cx">         if (shadowRoot &amp;&amp; (change &gt;= Inherit || shadowRoot-&gt;childNeedsStyleRecalc() || shadowRoot-&gt;needsStyleRecalc())) {
</span><ins>+            SelectorFilterPusher selectorFilterPusher(m_selectorFilter, current);
+
</ins><span class="cx">             TreeResolver shadowTreeResolver(*shadowRoot, *this);
</span><span class="cx">             shadowTreeResolver.resolveShadowTree(change, renderer-&gt;style());
</span><span class="cx">         }
</span></span></pre></div>
<a id="trunkSourceWebCorestyleStyleTreeResolverh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/style/StyleTreeResolver.h (194761 => 194762)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/style/StyleTreeResolver.h        2016-01-08 08:36:47 UTC (rev 194761)
+++ trunk/Source/WebCore/style/StyleTreeResolver.h        2016-01-08 09:06:10 UTC (rev 194762)
</span><span class="lines">@@ -27,6 +27,7 @@
</span><span class="cx"> #define StyleTreeResolver_h
</span><span class="cx"> 
</span><span class="cx"> #include &quot;RenderStyleConstants.h&quot;
</span><ins>+#include &quot;SelectorFilter.h&quot;
</ins><span class="cx"> #include &quot;StyleChange.h&quot;
</span><span class="cx"> #include &lt;functional&gt;
</span><span class="cx"> #include &lt;wtf/RefPtr.h&gt;
</span><span class="lines">@@ -82,6 +83,8 @@
</span><span class="cx"> 
</span><span class="cx">     ShadowRoot* m_shadowRoot { nullptr };
</span><span class="cx">     TreeResolver* m_shadowHostTreeResolver { nullptr };
</span><ins>+
+    SelectorFilter m_selectorFilter;
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> void detachRenderTree(Element&amp;);
</span></span></pre>
</div>
</div>

</body>
</html>