<!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>[165300] 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/165300">165300</a></dd>
<dt>Author</dt> <dd>benjamin@webkit.org</dd>
<dt>Date</dt> <dd>2014-03-07 16:40:11 -0800 (Fri, 07 Mar 2014)</dd>
</dl>

<h3>Log Message</h3>
<pre>Traversal failure in a direct adjacent chain with tail backtracking lacks the path to clear the tail
https://bugs.webkit.org/show_bug.cgi?id=129863

Reviewed by Gavin Barraclough.

Source/WebCore: 

Direct adjacent backtracking use the stack to push the backtracking entry point and recover from there.
In case of traversal failure, their is no point in recovering from the indirect adjancent entry point and
we should clear entry point from the stack (which is the purpose of the tail).

The adjancent tail was missing the part for clearing the stack in one case.

The case with adjancent backtracking inside descendant backtracing was doing everything right. This patch
generalize this code and the correct tail is fully generated by generateAdjacentBacktrackingTail().

JumpToClearAdjacentDescendantTail becomes JumpToClearAdjacentTail, and this new backtracking state is added
to the missing traversal action.

Test: fast/selectors/long-adjacent-backtracking.html

* cssjit/SelectorCompiler.cpp:
(WebCore::SelectorCompiler::solveBacktrackingAction):
(WebCore::SelectorCompiler::SelectorCodeGenerator::generateSelectorChecker):
(WebCore::SelectorCompiler::SelectorCodeGenerator::linkFailures):
(WebCore::SelectorCompiler::SelectorCodeGenerator::generateAdjacentBacktrackingTail):
(WebCore::SelectorCompiler::SelectorCodeGenerator::generateBacktrackingTailsIfNeeded):

LayoutTests: 

Test the faulty case.

* fast/selectors/long-adjacent-backtracking-expected.txt: Added.
* fast/selectors/long-adjacent-backtracking.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="#trunkLayoutTestsfastselectorslongadjacentbacktrackingexpectedtxt">trunk/LayoutTests/fast/selectors/long-adjacent-backtracking-expected.txt</a></li>
<li><a href="#trunkLayoutTestsfastselectorslongadjacentbacktrackinghtml">trunk/LayoutTests/fast/selectors/long-adjacent-backtracking.html</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkLayoutTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/ChangeLog (165299 => 165300)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/ChangeLog        2014-03-08 00:33:55 UTC (rev 165299)
+++ trunk/LayoutTests/ChangeLog        2014-03-08 00:40:11 UTC (rev 165300)
</span><span class="lines">@@ -1,3 +1,15 @@
</span><ins>+2014-03-07  Benjamin Poulain  &lt;benjamin@webkit.org&gt;
+
+        Traversal failure in a direct adjacent chain with tail backtracking lacks the path to clear the tail
+        https://bugs.webkit.org/show_bug.cgi?id=129863
+
+        Reviewed by Gavin Barraclough.
+
+        Test the faulty case.
+
+        * fast/selectors/long-adjacent-backtracking-expected.txt: Added.
+        * fast/selectors/long-adjacent-backtracking.html: Added.
+
</ins><span class="cx"> 2014-03-07  Bear Travis  &lt;betravis@adobe.com&gt;
</span><span class="cx"> 
</span><span class="cx">         [CSS Shapes] Correctly serialize ellipse positions
</span></span></pre></div>
<a id="trunkLayoutTestsfastselectorslongadjacentbacktrackingexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/fast/selectors/long-adjacent-backtracking-expected.txt (0 => 165300)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/selectors/long-adjacent-backtracking-expected.txt                                (rev 0)
+++ trunk/LayoutTests/fast/selectors/long-adjacent-backtracking-expected.txt        2014-03-08 00:40:11 UTC (rev 165300)
</span><span class="lines">@@ -0,0 +1,12 @@
</span><ins>+Test very long backtracking of a direct adjacent chain.
+
+On success, you will see a series of &quot;PASS&quot; messages, followed by &quot;TEST COMPLETE&quot;.
+
+
+PASS document.querySelectorAll(&quot;li.first+li+li+li+li+li+li+li+li+li+li+li+li+li+li+li+li+li+li+li+li~li&quot;).length is 20
+PASS allItems.length is 41
+PASS coloredCount is 20
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
</ins></span></pre></div>
<a id="trunkLayoutTestsfastselectorslongadjacentbacktrackinghtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/fast/selectors/long-adjacent-backtracking.html (0 => 165300)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/selectors/long-adjacent-backtracking.html                                (rev 0)
+++ trunk/LayoutTests/fast/selectors/long-adjacent-backtracking.html        2014-03-08 00:40:11 UTC (rev 165300)
</span><span class="lines">@@ -0,0 +1,75 @@
</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;
+li.first+li+li+li+li+li+li+li+li+li+li+li+li+li+li+li+li+li+li+li+li~li {
+    background-color: rgb(1, 2, 3);
+}
+&lt;/style&gt;
+&lt;/head&gt;
+&lt;body&gt;
+&lt;div style=&quot;display:none&quot;&gt;
+    &lt;ul id=targetTree&gt;
+        &lt;li class=first&gt;&lt;/li&gt;
+        &lt;li&gt;&lt;/li&gt;
+        &lt;li&gt;&lt;/li&gt;
+        &lt;li&gt;&lt;/li&gt;
+        &lt;li&gt;&lt;/li&gt;
+        &lt;li&gt;&lt;/li&gt;
+        &lt;li&gt;&lt;/li&gt;
+        &lt;li&gt;&lt;/li&gt;
+        &lt;li&gt;&lt;/li&gt;
+        &lt;li&gt;&lt;/li&gt;
+        &lt;li&gt;&lt;/li&gt;
+        &lt;li&gt;&lt;/li&gt;
+        &lt;li&gt;&lt;/li&gt;
+        &lt;li&gt;&lt;/li&gt;
+        &lt;li&gt;&lt;/li&gt;
+        &lt;li&gt;&lt;/li&gt;
+        &lt;li&gt;&lt;/li&gt;
+        &lt;li&gt;&lt;/li&gt;
+        &lt;li&gt;&lt;/li&gt;
+        &lt;li&gt;&lt;/li&gt;
+        &lt;li&gt;&lt;/li&gt;
+        &lt;li class=target&gt;&lt;/li&gt;
+        &lt;li class=target&gt;&lt;/li&gt;
+        &lt;li class=target&gt;&lt;/li&gt;
+        &lt;li class=target&gt;&lt;/li&gt;
+        &lt;li class=target&gt;&lt;/li&gt;
+        &lt;li class=target&gt;&lt;/li&gt;
+        &lt;li class=target&gt;&lt;/li&gt;
+        &lt;li class=target&gt;&lt;/li&gt;
+        &lt;li class=target&gt;&lt;/li&gt;
+        &lt;li class=target&gt;&lt;/li&gt;
+        &lt;li class=target&gt;&lt;/li&gt;
+        &lt;li class=target&gt;&lt;/li&gt;
+        &lt;li class=target&gt;&lt;/li&gt;
+        &lt;li class=target&gt;&lt;/li&gt;
+        &lt;li class=target&gt;&lt;/li&gt;
+        &lt;li class=target&gt;&lt;/li&gt;
+        &lt;li class=target&gt;&lt;/li&gt;
+        &lt;li class=target&gt;&lt;/li&gt;
+        &lt;li class=target&gt;&lt;/li&gt;
+        &lt;li class=target&gt;&lt;/li&gt;
+    &lt;/ul&gt;
+&lt;/div&gt;
+&lt;/body&gt;
+&lt;script&gt;
+description('Test very long backtracking of a direct adjacent chain.');
+
+shouldBe('document.querySelectorAll(&quot;li.first+li+li+li+li+li+li+li+li+li+li+li+li+li+li+li+li+li+li+li+li~li&quot;).length', '20');
+
+var allItems = document.getElementById('targetTree').querySelectorAll('li');
+var coloredCount = 0;
+for (var i = 0; i &lt; allItems.length; ++i) {
+    if (getComputedStyle(allItems[i]).backgroundColor === 'rgb(1, 2, 3)')
+        coloredCount++;
+}
+
+shouldBe('allItems.length', '41');
+shouldBe('coloredCount', '20');
+
+&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 (165299 => 165300)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2014-03-08 00:33:55 UTC (rev 165299)
+++ trunk/Source/WebCore/ChangeLog        2014-03-08 00:40:11 UTC (rev 165300)
</span><span class="lines">@@ -1,3 +1,31 @@
</span><ins>+2014-03-07  Benjamin Poulain  &lt;benjamin@webkit.org&gt;
+
+        Traversal failure in a direct adjacent chain with tail backtracking lacks the path to clear the tail
+        https://bugs.webkit.org/show_bug.cgi?id=129863
+
+        Reviewed by Gavin Barraclough.
+
+        Direct adjacent backtracking use the stack to push the backtracking entry point and recover from there.
+        In case of traversal failure, their is no point in recovering from the indirect adjancent entry point and
+        we should clear entry point from the stack (which is the purpose of the tail).
+
+        The adjancent tail was missing the part for clearing the stack in one case.
+
+        The case with adjancent backtracking inside descendant backtracing was doing everything right. This patch
+        generalize this code and the correct tail is fully generated by generateAdjacentBacktrackingTail().
+
+        JumpToClearAdjacentDescendantTail becomes JumpToClearAdjacentTail, and this new backtracking state is added
+        to the missing traversal action.
+
+        Test: fast/selectors/long-adjacent-backtracking.html
+
+        * cssjit/SelectorCompiler.cpp:
+        (WebCore::SelectorCompiler::solveBacktrackingAction):
+        (WebCore::SelectorCompiler::SelectorCodeGenerator::generateSelectorChecker):
+        (WebCore::SelectorCompiler::SelectorCodeGenerator::linkFailures):
+        (WebCore::SelectorCompiler::SelectorCodeGenerator::generateAdjacentBacktrackingTail):
+        (WebCore::SelectorCompiler::SelectorCodeGenerator::generateBacktrackingTailsIfNeeded):
+
</ins><span class="cx"> 2014-03-07  Andreas Kling  &lt;akling@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         [Mac] Notify system malloc of fake memory pressure.
</span></span></pre></div>
<a id="trunkSourceWebCorecssjitSelectorCompilercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/cssjit/SelectorCompiler.cpp (165299 => 165300)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/cssjit/SelectorCompiler.cpp        2014-03-08 00:33:55 UTC (rev 165299)
+++ trunk/Source/WebCore/cssjit/SelectorCompiler.cpp        2014-03-08 00:40:11 UTC (rev 165300)
</span><span class="lines">@@ -61,8 +61,8 @@
</span><span class="cx">     JumpToIndirectAdjacentEntryPoint,
</span><span class="cx">     JumpToDescendantTreeWalkerEntryPoint,
</span><span class="cx">     JumpToDescendantTail,
</span><del>-    JumpToClearAdjacentDescendantTail,
-    JumpToDirectAdjacentTail
</del><ins>+    JumpToDirectAdjacentTail,
+    JumpToClearAdjacentTail
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> struct BacktrackingFlag {
</span><span class="lines">@@ -161,9 +161,9 @@
</span><span class="cx">     void markParentElementIfResolvingStyle(JSC::FunctionPtr);
</span><span class="cx"> 
</span><span class="cx">     void linkFailures(Assembler::JumpList&amp; globalFailureCases, BacktrackingAction, Assembler::JumpList&amp; localFailureCases);
</span><del>-    void generateAdjacentBacktrackingTail(StackAllocator&amp; adjacentTailStack);
</del><ins>+    void generateAdjacentBacktrackingTail(Assembler::JumpList&amp; failureCases);
</ins><span class="cx">     void generateDescendantBacktrackingTail();
</span><del>-    void generateBacktrackingTailsIfNeeded(const SelectorFragment&amp;);
</del><ins>+    void generateBacktrackingTailsIfNeeded(Assembler::JumpList&amp; failureCases, const SelectorFragment&amp;);
</ins><span class="cx"> 
</span><span class="cx">     // Element properties matchers.
</span><span class="cx">     void generateElementMatching(Assembler::JumpList&amp; failureCases, const SelectorFragment&amp;);
</span><span class="lines">@@ -199,7 +199,7 @@
</span><span class="cx">     Assembler::JumpList m_descendantBacktrackingFailureCases;
</span><span class="cx">     StackAllocator::StackReference m_adjacentBacktrackingStart;
</span><span class="cx">     Assembler::JumpList m_adjacentBacktrackingFailureCases;
</span><del>-    Assembler::JumpList m_clearAdjacentEntryPointDescendantFailureCases;
</del><ins>+    Assembler::JumpList m_clearAdjacentBacktrackingFailureCases;
</ins><span class="cx"> 
</span><span class="cx"> #if CSS_SELECTOR_JIT_DEBUGGING
</span><span class="cx">     const CSSSelector* m_originalSelector;
</span><span class="lines">@@ -545,8 +545,12 @@
</span><span class="cx">                 if (!hasIndirectAdjacentRelationOnTheRightOfDirectAdjacentChain || isFirstAdjacent(adjacentPositionSinceIndirectAdjacentTreeWalk))
</span><span class="cx">                     fragment.traversalBacktrackingAction = BacktrackingAction::JumpToDescendantTail;
</span><span class="cx">                 else
</span><del>-                    fragment.traversalBacktrackingAction = BacktrackingAction::JumpToClearAdjacentDescendantTail;
</del><ins>+                    fragment.traversalBacktrackingAction = BacktrackingAction::JumpToClearAdjacentTail;
</ins><span class="cx">             }
</span><ins>+        } else {
+            // If we are in a direct adjacent chain with backtracking, we need to clear the backtracking register on the stack.
+            if (hasIndirectAdjacentRelationOnTheRightOfDirectAdjacentChain &amp;&amp; !isFirstAdjacent(adjacentPositionSinceIndirectAdjacentTreeWalk))
+                fragment.traversalBacktrackingAction = BacktrackingAction::JumpToClearAdjacentTail;
</ins><span class="cx">         }
</span><span class="cx"> 
</span><span class="cx">         // If the rightmost relation is a indirect adjacent, matching sould resume from there.
</span><span class="lines">@@ -559,7 +563,7 @@
</span><span class="cx">         } else if (hasDescendantRelationOnTheRight) {
</span><span class="cx">             if (isAfterChildRelation(ancestorPositionSinceDescendantRelation))
</span><span class="cx">                 fragment.matchingBacktrackingAction = BacktrackingAction::JumpToDescendantTail;
</span><del>-            else if (hasDescendantRelationOnTheRight)
</del><ins>+            else
</ins><span class="cx">                 fragment.matchingBacktrackingAction = BacktrackingAction::JumpToDescendantTreeWalkerEntryPoint;
</span><span class="cx">         }
</span><span class="cx">         break;
</span><span class="lines">@@ -667,7 +671,7 @@
</span><span class="cx">             generateIndirectAdjacentTreeWalker(failureCases, fragment);
</span><span class="cx">             break;
</span><span class="cx">         }
</span><del>-        generateBacktrackingTailsIfNeeded(fragment);
</del><ins>+        generateBacktrackingTailsIfNeeded(failureCases, fragment);
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     m_registerAllocator.deallocateRegister(elementAddressRegister);
</span><span class="lines">@@ -706,7 +710,7 @@
</span><span class="cx">         StackAllocator failureStack = m_stackAllocator;
</span><span class="cx"> 
</span><span class="cx">         LocalRegister checkingContextRegister(m_registerAllocator);
</span><del>-        successStack.pop(m_checkingContextStackReference, checkingContextRegister);
</del><ins>+        successStack.popAndDiscardUpTo(m_checkingContextStackReference);
</ins><span class="cx"> 
</span><span class="cx">         // Failure.
</span><span class="cx">         if (!failureCases.empty()) {
</span><span class="lines">@@ -900,18 +904,32 @@
</span><span class="cx">     case BacktrackingAction::JumpToDirectAdjacentTail:
</span><span class="cx">         m_adjacentBacktrackingFailureCases.append(localFailureCases);
</span><span class="cx">         break;
</span><del>-    case BacktrackingAction::JumpToClearAdjacentDescendantTail:
-        m_clearAdjacentEntryPointDescendantFailureCases.append(localFailureCases);
</del><ins>+    case BacktrackingAction::JumpToClearAdjacentTail:
+        m_clearAdjacentBacktrackingFailureCases.append(localFailureCases);
</ins><span class="cx">         break;
</span><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void SelectorCodeGenerator::generateAdjacentBacktrackingTail(StackAllocator&amp; adjacentTailStack)
</del><ins>+void SelectorCodeGenerator::generateAdjacentBacktrackingTail(Assembler::JumpList&amp; successCases)
</ins><span class="cx"> {
</span><ins>+    StackAllocator successStack = m_stackAllocator;
+    StackAllocator recoveryStack = m_stackAllocator;
+    StackAllocator failureStack = m_stackAllocator;
+
+    successStack.popAndDiscard(m_adjacentBacktrackingStart);
+    successCases.append(m_assembler.jump());
+
+    // Recovering tail.
</ins><span class="cx">     m_adjacentBacktrackingFailureCases.link(&amp;m_assembler);
</span><span class="cx">     m_adjacentBacktrackingFailureCases.clear();
</span><del>-    adjacentTailStack.pop(m_adjacentBacktrackingStart, elementAddressRegister);
</del><ins>+    recoveryStack.pop(m_adjacentBacktrackingStart, elementAddressRegister);
</ins><span class="cx">     m_assembler.jump(m_indirectAdjacentEntryPoint);
</span><ins>+
+    // Total failure tail.
+    m_clearAdjacentBacktrackingFailureCases.link(&amp;m_assembler);
+    failureStack.popAndDiscard(m_adjacentBacktrackingStart);
+
+    m_stackAllocator.merge(std::move(successStack), std::move(recoveryStack), std::move(failureStack));
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void SelectorCodeGenerator::generateDescendantBacktrackingTail()
</span><span class="lines">@@ -923,39 +941,18 @@
</span><span class="cx">     m_assembler.jump(m_descendantEntryPoint);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void SelectorCodeGenerator::generateBacktrackingTailsIfNeeded(const SelectorFragment&amp; fragment)
</del><ins>+void SelectorCodeGenerator::generateBacktrackingTailsIfNeeded(Assembler::JumpList&amp; failureCases, const SelectorFragment&amp; fragment)
</ins><span class="cx"> {
</span><span class="cx">     if (fragment.backtrackingFlags &amp; BacktrackingFlag::DirectAdjacentTail &amp;&amp; fragment.backtrackingFlags &amp; BacktrackingFlag::DescendantTail) {
</span><del>-        StackAllocator successStack = m_stackAllocator;
-        StackAllocator adjacentTailStack = m_stackAllocator;
-        StackAllocator descendantTailStack = m_stackAllocator;
-
-        successStack.popAndDiscard(m_adjacentBacktrackingStart);
-
-        Assembler::Jump normalCase = m_assembler.jump();
-
-        generateAdjacentBacktrackingTail(adjacentTailStack);
-
-        m_clearAdjacentEntryPointDescendantFailureCases.link(&amp;m_assembler);
-        m_clearAdjacentEntryPointDescendantFailureCases.clear();
-        descendantTailStack.popAndDiscard(m_adjacentBacktrackingStart);
-
</del><ins>+        Assembler::JumpList successCases;
+        generateAdjacentBacktrackingTail(successCases);
</ins><span class="cx">         generateDescendantBacktrackingTail();
</span><del>-
-        normalCase.link(&amp;m_assembler);
-
-        m_stackAllocator.merge(std::move(successStack), std::move(adjacentTailStack), std::move(descendantTailStack));
</del><ins>+        successCases.link(&amp;m_assembler);
</ins><span class="cx">     } else if (fragment.backtrackingFlags &amp; BacktrackingFlag::DirectAdjacentTail) {
</span><del>-        StackAllocator successStack = m_stackAllocator;
-        StackAllocator adjacentTailStack = m_stackAllocator;
-
-        successStack.popAndDiscard(m_adjacentBacktrackingStart);
-
-        Assembler::Jump normalCase = m_assembler.jump();
-        generateAdjacentBacktrackingTail(adjacentTailStack);
-        normalCase.link(&amp;m_assembler);
-
-        m_stackAllocator.merge(std::move(successStack), std::move(adjacentTailStack));
</del><ins>+        Assembler::JumpList successCases;
+        generateAdjacentBacktrackingTail(successCases);
+        failureCases.append(m_assembler.jump());
+        successCases.link(&amp;m_assembler);
</ins><span class="cx">     } else if (fragment.backtrackingFlags &amp; BacktrackingFlag::DescendantTail) {
</span><span class="cx">         Assembler::Jump normalCase = m_assembler.jump();
</span><span class="cx">         generateDescendantBacktrackingTail();
</span></span></pre>
</div>
</div>

</body>
</html>