<!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>[164932] trunk</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/164932">164932</a></dd>
<dt>Author</dt> <dd>benjamin@webkit.org</dd>
<dt>Date</dt> <dd>2014-03-01 15:50:17 -0800 (Sat, 01 Mar 2014)</dd>
</dl>

<h3>Log Message</h3>
<pre>Tighten minimumRegisterRequirements()
https://bugs.webkit.org/show_bug.cgi?id=129538

Reviewed by Andreas Kling.

Source/WebCore: 

Fix small things that made minimumRegisterRequirements() a little optimistic
when dealing with attributes.

Test: fast/selectors/adjacent-descendant-tail-register-requirement.html

* cssjit/SelectorCompiler.cpp:
(WebCore::SelectorCompiler::SelectorCodeGenerator::SelectorCodeGenerator):
Attribute Set does not do value matching, the case sensitive value matching is irrelevant
The problem is that flag is also used by minimumRegisterRequirements()
to find if one more register is needed.

Set the flag to case sensitive to avoid reserving one extra register.

(WebCore::SelectorCompiler::minimumRegisterRequirements):
Use a new backtrackingFlag to know if there is a descendant tail, thus a backtracking register
reserved.
This is better than using the backtracking action because the backtracking chain could be
an adjacent chain inside a descendant chain.

The flags are designed for that, just set one for minimumRegisterRequirements().

The 2 extra registers for the attribute count and address become limited to all attributes
except the last one. We don't keep a copy for the last matching, those registers were not needed.

(WebCore::SelectorCompiler::SelectorCodeGenerator::computeBacktrackingInformation):

LayoutTests: 

* fast/selectors/adjacent-descendant-tail-register-requirement-expected.txt: Added.
* fast/selectors/adjacent-descendant-tail-register-requirement.html: Added.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsChangeLog">trunk/LayoutTests/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCorecssjitSelectorCompilercpp">trunk/Source/WebCore/cssjit/SelectorCompiler.cpp</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsfastselectorsadjacentdescendanttailregisterrequirementexpectedtxt">trunk/LayoutTests/fast/selectors/adjacent-descendant-tail-register-requirement-expected.txt</a></li>
<li><a href="#trunkLayoutTestsfastselectorsadjacentdescendanttailregisterrequirementhtml">trunk/LayoutTests/fast/selectors/adjacent-descendant-tail-register-requirement.html</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkLayoutTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/ChangeLog (164931 => 164932)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/ChangeLog        2014-03-01 23:31:03 UTC (rev 164931)
+++ trunk/LayoutTests/ChangeLog        2014-03-01 23:50:17 UTC (rev 164932)
</span><span class="lines">@@ -1,3 +1,13 @@
</span><ins>+2014-03-01  Benjamin Poulain  &lt;benjamin@webkit.org&gt;
+
+        Tighten minimumRegisterRequirements()
+        https://bugs.webkit.org/show_bug.cgi?id=129538
+
+        Reviewed by Andreas Kling.
+
+        * fast/selectors/adjacent-descendant-tail-register-requirement-expected.txt: Added.
+        * fast/selectors/adjacent-descendant-tail-register-requirement.html: Added.
+
</ins><span class="cx"> 2014-03-01  Yoav Weiss  &lt;yoav@yoav.ws&gt;
</span><span class="cx"> 
</span><span class="cx">         Fix srcset related bugs
</span></span></pre></div>
<a id="trunkLayoutTestsfastselectorsadjacentdescendanttailregisterrequirementexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/fast/selectors/adjacent-descendant-tail-register-requirement-expected.txt (0 => 164932)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/selectors/adjacent-descendant-tail-register-requirement-expected.txt                                (rev 0)
+++ trunk/LayoutTests/fast/selectors/adjacent-descendant-tail-register-requirement-expected.txt        2014-03-01 23:50:17 UTC (rev 164932)
</span><span class="lines">@@ -0,0 +1,11 @@
</span><ins>+The backtracking register was not taken into account when in an adjacent chain inside a backtracking descendant chain.
+
+On success, you will see a series of &quot;PASS&quot; messages, followed by &quot;TEST COMPLETE&quot;.
+
+
+Adjacent relations (tree modifiers), no descendant backtracking, multi-attribute match.
+PASS getComputedStyle(document.getElementById(&quot;target1&quot;)).backgroundColor is &quot;rgb(1, 2, 3)&quot;
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
</ins></span></pre></div>
<a id="trunkLayoutTestsfastselectorsadjacentdescendanttailregisterrequirementhtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/fast/selectors/adjacent-descendant-tail-register-requirement.html (0 => 164932)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/selectors/adjacent-descendant-tail-register-requirement.html                                (rev 0)
+++ trunk/LayoutTests/fast/selectors/adjacent-descendant-tail-register-requirement.html        2014-03-01 23:50:17 UTC (rev 164932)
</span><span class="lines">@@ -0,0 +1,60 @@
</span><ins>+&lt;!doctype html&gt;
+&lt;html&gt;
+&lt;head&gt;
+&lt;script src=&quot;../../resources/js-test-pre.js&quot;&gt;&lt;/script&gt;
+&lt;style&gt;
+[a][b]+c+d~e&gt;ul&gt;li span {
+    background-color:rgb(1,2,3);
+}
+&lt;/style&gt;
+&lt;/head&gt;
+&lt;body&gt;
+&lt;div style=&quot;display:none&quot;&gt;
+    &lt;!-- case [a][b]+c+d~e&gt;ul&gt;li span --&gt;
+    &lt;div a b&gt;&lt;/div&gt;
+    &lt;c&gt;&lt;/c&gt;
+    &lt;d&gt;&lt;/d&gt;
+    &lt;div&gt;&lt;/div&gt;
+
+    &lt;div a&gt;&lt;/div&gt;
+    &lt;c&gt;&lt;/c&gt;
+    &lt;d&gt;&lt;/d&gt;
+    &lt;div&gt;&lt;/div&gt;
+
+    &lt;c&gt;&lt;/c&gt;
+    &lt;d&gt;&lt;/d&gt;
+    &lt;div&gt;&lt;/div&gt;
+    &lt;e&gt;
+        &lt;ul&gt;
+            &lt;li&gt;
+
+                &lt;!-- Subtree that fails, and should backtrack to the tree above. --&gt;
+                &lt;div a&gt;&lt;/div&gt;
+                &lt;c&gt;&lt;/c&gt;
+                &lt;d&gt;&lt;/d&gt;
+                &lt;div&gt;&lt;/div&gt;
+                &lt;c&gt;&lt;/c&gt;
+                &lt;d&gt;&lt;/d&gt;
+                &lt;div&gt;&lt;/div&gt;
+                &lt;e&gt;
+                    &lt;ul&gt;
+                        &lt;li&gt;
+                            &lt;span id=&quot;target1&quot;&gt;&lt;/span&gt;
+                        &lt;/li&gt;
+                    &lt;/ul&gt;
+                &lt;/e&gt;
+
+            &lt;/li&gt;
+        &lt;/ul&gt;
+    &lt;/e&gt;
+&lt;/div&gt;
+&lt;/body&gt;
+&lt;script&gt;
+description('The backtracking register was not taken into account when in an adjacent chain inside a backtracking descendant chain.');
+
+debug(&quot;Adjacent relations (tree modifiers), no descendant backtracking, multi-attribute match.&quot;);
+shouldBeEqualToString('getComputedStyle(document.getElementById(&quot;target1&quot;)).backgroundColor', 'rgb(1, 2, 3)');
+
+&lt;/script&gt;
+&lt;script src=&quot;../../resources/js-test-post.js&quot;&gt;&lt;/script&gt;
+&lt;/html&gt;
</ins></span></pre></div>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (164931 => 164932)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2014-03-01 23:31:03 UTC (rev 164931)
+++ trunk/Source/WebCore/ChangeLog        2014-03-01 23:50:17 UTC (rev 164932)
</span><span class="lines">@@ -1,3 +1,36 @@
</span><ins>+2014-03-01  Benjamin Poulain  &lt;benjamin@webkit.org&gt;
+
+        Tighten minimumRegisterRequirements()
+        https://bugs.webkit.org/show_bug.cgi?id=129538
+
+        Reviewed by Andreas Kling.
+
+        Fix small things that made minimumRegisterRequirements() a little optimistic
+        when dealing with attributes.
+
+        Test: fast/selectors/adjacent-descendant-tail-register-requirement.html
+
+        * cssjit/SelectorCompiler.cpp:
+        (WebCore::SelectorCompiler::SelectorCodeGenerator::SelectorCodeGenerator):
+        Attribute Set does not do value matching, the case sensitive value matching is irrelevant
+        The problem is that flag is also used by minimumRegisterRequirements()
+        to find if one more register is needed.
+
+        Set the flag to case sensitive to avoid reserving one extra register.
+
+        (WebCore::SelectorCompiler::minimumRegisterRequirements):
+        Use a new backtrackingFlag to know if there is a descendant tail, thus a backtracking register
+        reserved.
+        This is better than using the backtracking action because the backtracking chain could be
+        an adjacent chain inside a descendant chain.
+
+        The flags are designed for that, just set one for minimumRegisterRequirements().
+
+        The 2 extra registers for the attribute count and address become limited to all attributes
+        except the last one. We don't keep a copy for the last matching, those registers were not needed.
+
+        (WebCore::SelectorCompiler::SelectorCodeGenerator::computeBacktrackingInformation):
+
</ins><span class="cx"> 2014-03-01  Pratik Solanki  &lt;psolanki@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         [iOS] selectionImageForcingBlackText should return autoreleased object
</span></span></pre></div>
<a id="trunkSourceWebCorecssjitSelectorCompilercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/cssjit/SelectorCompiler.cpp (164931 => 164932)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/cssjit/SelectorCompiler.cpp        2014-03-01 23:31:03 UTC (rev 164931)
+++ trunk/Source/WebCore/cssjit/SelectorCompiler.cpp        2014-03-01 23:50:17 UTC (rev 164932)
</span><span class="lines">@@ -73,6 +73,7 @@
</span><span class="cx">         SaveAdjacentBacktrackingStart = 1 &lt;&lt; 3,
</span><span class="cx">         DirectAdjacentTail = 1 &lt;&lt; 4,
</span><span class="cx">         DescendantTail = 1 &lt;&lt; 5,
</span><ins>+        InChainWithDescendantTail = 1 &lt;&lt; 6
</ins><span class="cx">     };
</span><span class="cx"> };
</span><span class="cx"> 
</span><span class="lines">@@ -351,7 +352,7 @@
</span><span class="cx">             fragment.attributes.append(AttributeMatchingInfo(selector, HTMLDocument::isCaseSensitiveAttribute(selector-&gt;attribute())));
</span><span class="cx">             break;
</span><span class="cx">         case CSSSelector::Set:
</span><del>-            fragment.attributes.append(AttributeMatchingInfo(selector, false));
</del><ins>+            fragment.attributes.append(AttributeMatchingInfo(selector, true));
</ins><span class="cx">             break;
</span><span class="cx">         case CSSSelector::Unknown:
</span><span class="cx">         case CSSSelector::List:
</span><span class="lines">@@ -414,14 +415,14 @@
</span><span class="cx">         const SelectorFragment&amp; selectorFragment = selectorFragments[selectorFragmentIndex];
</span><span class="cx">         const Vector&lt;AttributeMatchingInfo&gt;&amp; attributes = selectorFragment.attributes;
</span><span class="cx"> 
</span><del>-        for (unsigned attributeIndex = 0; attributeIndex &lt; attributes.size(); ++attributeIndex) {
</del><ins>+        unsigned attributeCount = attributes.size();
+        for (unsigned attributeIndex = 0; attributeIndex &lt; attributeCount; ++attributeIndex) {
</ins><span class="cx">             // Element + ElementData + scratchRegister + attributeArrayPointer + expectedLocalName + (qualifiedNameImpl &amp;&amp; expectedValue).
</span><span class="cx">             unsigned attributeMinimum = 6;
</span><del>-            if (selectorFragment.traversalBacktrackingAction == BacktrackingAction::JumpToDescendantTail
-                || selectorFragment.matchingBacktrackingAction == BacktrackingAction::JumpToDescendantTail)
</del><ins>+            if (selectorFragment.backtrackingFlags &amp; BacktrackingFlag::InChainWithDescendantTail)
</ins><span class="cx">                 attributeMinimum += 1; // If there is a DescendantTail, there is a backtracking register.
</span><span class="cx"> 
</span><del>-            if (attributes.size() != 1)
</del><ins>+            if (attributeIndex + 1 &lt; attributeCount)
</ins><span class="cx">                 attributeMinimum += 2; // For the local copy of the counter and attributeArrayPointer.
</span><span class="cx"> 
</span><span class="cx">             const AttributeMatchingInfo&amp; attributeInfo = attributes[attributeIndex];
</span><span class="lines">@@ -595,6 +596,9 @@
</span><span class="cx">         needsAdjacentTail |= requiresAdjacentTail(fragment);
</span><span class="cx">         needsDescendantTail |= requiresDescendantTail(fragment);
</span><span class="cx"> 
</span><ins>+        if (needsDescendantTail)
+            fragment.backtrackingFlags |= BacktrackingFlag::InChainWithDescendantTail;
+
</ins><span class="cx">         // Add code generation flags.
</span><span class="cx">         if (fragment.relationToLeftFragment != FragmentRelation::Descendant &amp;&amp; fragment.relationToRightFragment == FragmentRelation::Descendant)
</span><span class="cx">             fragment.backtrackingFlags |= BacktrackingFlag::DescendantEntryPoint;
</span></span></pre>
</div>
</div>

</body>
</html>