<!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>[189013] trunk/Source/JavaScriptCore</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/189013">189013</a></dd>
<dt>Author</dt> <dd>fpizlo@apple.com</dd>
<dt>Date</dt> <dd>2015-08-27 00:16:07 -0700 (Thu, 27 Aug 2015)</dd>
</dl>

<h3>Log Message</h3>
<pre>Node::origin should always be set, and the dead zone due to SSA Phis can just use exitOK=false
https://bugs.webkit.org/show_bug.cgi?id=148462

Reviewed by Saam Barati.

The need to label nodes that absolutely cannot exit was first observed when we introduced SSA form.
We indicated this by not setting the CodeOrigin.

But just recently (http://trac.webkit.org/changeset/188979), we added a more comprehensive &quot;exitOK&quot;
bit in NodeOrigin. After that change, there were two ways of indicating that you cannot exit:
!exitOK and an unset NodeOrigin. An unset NodeOrigin implied !exitOK.

Now, this change is about removing the old way so that we only use !exitOK. From now on, all nodes
must have their NodeOrigin set, and the IR validation will check this. This means that I could
remove various pieces of cruft for dealing with unset NodeOrigins, but I did have to add some new
cruft to ensure that all nodes we create have a NodeOrigin.

This change simplifies our IR by having a simpler rule about when NodeOrigin is set: it's always
set.

* dfg/DFGBasicBlock.cpp:
(JSC::DFG::BasicBlock::isInBlock):
(JSC::DFG::BasicBlock::removePredecessor):
(JSC::DFG::BasicBlock::firstOriginNode): Deleted.
(JSC::DFG::BasicBlock::firstOrigin): Deleted.
* dfg/DFGBasicBlock.h:
(JSC::DFG::BasicBlock::begin):
(JSC::DFG::BasicBlock::end):
(JSC::DFG::BasicBlock::numSuccessors):
(JSC::DFG::BasicBlock::successor):
* dfg/DFGCombinedLiveness.cpp:
(JSC::DFG::liveNodesAtHead):
* dfg/DFGConstantHoistingPhase.cpp:
* dfg/DFGCriticalEdgeBreakingPhase.cpp:
(JSC::DFG::CriticalEdgeBreakingPhase::breakCriticalEdge):
* dfg/DFGForAllKills.h:
(JSC::DFG::forAllKilledOperands):
* dfg/DFGIntegerRangeOptimizationPhase.cpp:
* dfg/DFGLoopPreHeaderCreationPhase.cpp:
(JSC::DFG::createPreHeader):
(JSC::DFG::LoopPreHeaderCreationPhase::run):
* dfg/DFGOSRAvailabilityAnalysisPhase.cpp:
(JSC::DFG::OSRAvailabilityAnalysisPhase::run):
* dfg/DFGObjectAllocationSinkingPhase.cpp:
* dfg/DFGPutStackSinkingPhase.cpp:
* dfg/DFGSSAConversionPhase.cpp:
(JSC::DFG::SSAConversionPhase::run):
* dfg/DFGValidate.cpp:
(JSC::DFG::Validate::validate):
(JSC::DFG::Validate::validateSSA):</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceJavaScriptCoreChangeLog">trunk/Source/JavaScriptCore/ChangeLog</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGBasicBlockcpp">trunk/Source/JavaScriptCore/dfg/DFGBasicBlock.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGBasicBlockh">trunk/Source/JavaScriptCore/dfg/DFGBasicBlock.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGCombinedLivenesscpp">trunk/Source/JavaScriptCore/dfg/DFGCombinedLiveness.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGConstantHoistingPhasecpp">trunk/Source/JavaScriptCore/dfg/DFGConstantHoistingPhase.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGCriticalEdgeBreakingPhasecpp">trunk/Source/JavaScriptCore/dfg/DFGCriticalEdgeBreakingPhase.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGForAllKillsh">trunk/Source/JavaScriptCore/dfg/DFGForAllKills.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGIntegerRangeOptimizationPhasecpp">trunk/Source/JavaScriptCore/dfg/DFGIntegerRangeOptimizationPhase.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGLoopPreHeaderCreationPhasecpp">trunk/Source/JavaScriptCore/dfg/DFGLoopPreHeaderCreationPhase.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGOSRAvailabilityAnalysisPhasecpp">trunk/Source/JavaScriptCore/dfg/DFGOSRAvailabilityAnalysisPhase.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGObjectAllocationSinkingPhasecpp">trunk/Source/JavaScriptCore/dfg/DFGObjectAllocationSinkingPhase.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGPutStackSinkingPhasecpp">trunk/Source/JavaScriptCore/dfg/DFGPutStackSinkingPhase.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGSSAConversionPhasecpp">trunk/Source/JavaScriptCore/dfg/DFGSSAConversionPhase.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGValidatecpp">trunk/Source/JavaScriptCore/dfg/DFGValidate.cpp</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ChangeLog (189012 => 189013)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ChangeLog        2015-08-27 05:54:21 UTC (rev 189012)
+++ trunk/Source/JavaScriptCore/ChangeLog        2015-08-27 07:16:07 UTC (rev 189013)
</span><span class="lines">@@ -1,3 +1,56 @@
</span><ins>+2015-08-26  Filip Pizlo  &lt;fpizlo@apple.com&gt;
+
+        Node::origin should always be set, and the dead zone due to SSA Phis can just use exitOK=false
+        https://bugs.webkit.org/show_bug.cgi?id=148462
+
+        Reviewed by Saam Barati.
+
+        The need to label nodes that absolutely cannot exit was first observed when we introduced SSA form.
+        We indicated this by not setting the CodeOrigin.
+
+        But just recently (http://trac.webkit.org/changeset/188979), we added a more comprehensive &quot;exitOK&quot;
+        bit in NodeOrigin. After that change, there were two ways of indicating that you cannot exit:
+        !exitOK and an unset NodeOrigin. An unset NodeOrigin implied !exitOK.
+
+        Now, this change is about removing the old way so that we only use !exitOK. From now on, all nodes
+        must have their NodeOrigin set, and the IR validation will check this. This means that I could
+        remove various pieces of cruft for dealing with unset NodeOrigins, but I did have to add some new
+        cruft to ensure that all nodes we create have a NodeOrigin.
+
+        This change simplifies our IR by having a simpler rule about when NodeOrigin is set: it's always
+        set.
+
+        * dfg/DFGBasicBlock.cpp:
+        (JSC::DFG::BasicBlock::isInBlock):
+        (JSC::DFG::BasicBlock::removePredecessor):
+        (JSC::DFG::BasicBlock::firstOriginNode): Deleted.
+        (JSC::DFG::BasicBlock::firstOrigin): Deleted.
+        * dfg/DFGBasicBlock.h:
+        (JSC::DFG::BasicBlock::begin):
+        (JSC::DFG::BasicBlock::end):
+        (JSC::DFG::BasicBlock::numSuccessors):
+        (JSC::DFG::BasicBlock::successor):
+        * dfg/DFGCombinedLiveness.cpp:
+        (JSC::DFG::liveNodesAtHead):
+        * dfg/DFGConstantHoistingPhase.cpp:
+        * dfg/DFGCriticalEdgeBreakingPhase.cpp:
+        (JSC::DFG::CriticalEdgeBreakingPhase::breakCriticalEdge):
+        * dfg/DFGForAllKills.h:
+        (JSC::DFG::forAllKilledOperands):
+        * dfg/DFGIntegerRangeOptimizationPhase.cpp:
+        * dfg/DFGLoopPreHeaderCreationPhase.cpp:
+        (JSC::DFG::createPreHeader):
+        (JSC::DFG::LoopPreHeaderCreationPhase::run):
+        * dfg/DFGOSRAvailabilityAnalysisPhase.cpp:
+        (JSC::DFG::OSRAvailabilityAnalysisPhase::run):
+        * dfg/DFGObjectAllocationSinkingPhase.cpp:
+        * dfg/DFGPutStackSinkingPhase.cpp:
+        * dfg/DFGSSAConversionPhase.cpp:
+        (JSC::DFG::SSAConversionPhase::run):
+        * dfg/DFGValidate.cpp:
+        (JSC::DFG::Validate::validate):
+        (JSC::DFG::Validate::validateSSA):
+
</ins><span class="cx"> 2015-08-26  Saam barati  &lt;sbarati@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         MarkedBlock::allocateBlock will have the wrong allocation size when (sizeof(MarkedBlock) + bytes) is divisible by WTF::pageSize()
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGBasicBlockcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGBasicBlock.cpp (189012 => 189013)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGBasicBlock.cpp        2015-08-27 05:54:21 UTC (rev 189012)
+++ trunk/Source/JavaScriptCore/dfg/DFGBasicBlock.cpp        2015-08-27 07:16:07 UTC (rev 189013)
</span><span class="lines">@@ -102,21 +102,6 @@
</span><span class="cx">     return false;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-Node* BasicBlock::firstOriginNode()
-{
-    for (Node* node : *this) {
-        if (node-&gt;origin.isSet())
-            return node;
-    }
-    RELEASE_ASSERT_NOT_REACHED();
-    return nullptr;
-}
-
-NodeOrigin BasicBlock::firstOrigin()
-{
-    return firstOriginNode()-&gt;origin;
-}
-
</del><span class="cx"> void BasicBlock::removePredecessor(BasicBlock* block)
</span><span class="cx"> {
</span><span class="cx">     for (unsigned i = 0; i &lt; predecessors.size(); ++i) {
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGBasicBlockh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGBasicBlock.h (189012 => 189013)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGBasicBlock.h        2015-08-27 05:54:21 UTC (rev 189012)
+++ trunk/Source/JavaScriptCore/dfg/DFGBasicBlock.h        2015-08-27 07:16:07 UTC (rev 189013)
</span><span class="lines">@@ -141,10 +141,7 @@
</span><span class="cx">     
</span><span class="cx">     BlockNodeList::iterator begin() { return m_nodes.begin(); }
</span><span class="cx">     BlockNodeList::iterator end() { return m_nodes.end(); }
</span><del>-    
-    Node* firstOriginNode();
-    NodeOrigin firstOrigin();
-    
</del><ins>+
</ins><span class="cx">     unsigned numSuccessors() { return terminal()-&gt;numSuccessors(); }
</span><span class="cx">     
</span><span class="cx">     BasicBlock*&amp; successor(unsigned index)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGCombinedLivenesscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGCombinedLiveness.cpp (189012 => 189013)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGCombinedLiveness.cpp        2015-08-27 05:54:21 UTC (rev 189012)
+++ trunk/Source/JavaScriptCore/dfg/DFGCombinedLiveness.cpp        2015-08-27 07:16:07 UTC (rev 189013)
</span><span class="lines">@@ -43,7 +43,7 @@
</span><span class="cx">     
</span><span class="cx">     AvailabilityMap&amp; availabilityMap = block-&gt;ssa-&gt;availabilityAtHead;
</span><span class="cx">     graph.forAllLocalsLiveInBytecode(
</span><del>-        block-&gt;firstOrigin().forExit,
</del><ins>+        block-&gt;at(0)-&gt;origin.forExit,
</ins><span class="cx">         [&amp;] (VirtualRegister reg) {
</span><span class="cx">             availabilityMap.closeStartingWithLocal(
</span><span class="cx">                 reg,
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGConstantHoistingPhasecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGConstantHoistingPhase.cpp (189012 => 189013)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGConstantHoistingPhase.cpp        2015-08-27 05:54:21 UTC (rev 189012)
+++ trunk/Source/JavaScriptCore/dfg/DFGConstantHoistingPhase.cpp        2015-08-27 07:16:07 UTC (rev 189013)
</span><span class="lines">@@ -94,7 +94,7 @@
</span><span class="cx">                     HashMap&lt;FrozenValue*, Node*&gt;&amp; values = valuesFor(node-&gt;op());
</span><span class="cx">                     auto result = values.add(node-&gt;constant(), node);
</span><span class="cx">                     if (result.isNewEntry)
</span><del>-                        node-&gt;origin = NodeOrigin();
</del><ins>+                        node-&gt;origin = m_graph.block(0)-&gt;at(0)-&gt;origin;
</ins><span class="cx">                     else {
</span><span class="cx">                         node-&gt;setReplacement(result.iterator-&gt;value);
</span><span class="cx">                         toFree.append(node);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGCriticalEdgeBreakingPhasecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGCriticalEdgeBreakingPhase.cpp (189012 => 189013)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGCriticalEdgeBreakingPhase.cpp        2015-08-27 05:54:21 UTC (rev 189012)
+++ trunk/Source/JavaScriptCore/dfg/DFGCriticalEdgeBreakingPhase.cpp        2015-08-27 07:16:07 UTC (rev 189013)
</span><span class="lines">@@ -77,7 +77,7 @@
</span><span class="cx">         // don't know its execution frequency.
</span><span class="cx">         BasicBlock* pad = m_insertionSet.insertBefore(*successor, PNaN);
</span><span class="cx">         pad-&gt;appendNode(
</span><del>-            m_graph, SpecNone, Jump, (*successor)-&gt;firstOrigin(), OpInfo(*successor));
</del><ins>+            m_graph, SpecNone, Jump, (*successor)-&gt;at(0)-&gt;origin, OpInfo(*successor));
</ins><span class="cx">         pad-&gt;predecessors.append(predecessor);
</span><span class="cx">         (*successor)-&gt;replacePredecessor(predecessor, pad);
</span><span class="cx">         
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGForAllKillsh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGForAllKills.h (189012 => 189013)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGForAllKills.h        2015-08-27 05:54:21 UTC (rev 189012)
+++ trunk/Source/JavaScriptCore/dfg/DFGForAllKills.h        2015-08-27 07:16:07 UTC (rev 189013)
</span><span class="lines">@@ -55,33 +55,18 @@
</span><span class="cx">     CodeOrigin after = nodeAfter-&gt;origin.forExit;
</span><span class="cx">     
</span><span class="cx">     VirtualRegister alreadyNoted;
</span><del>-    if (!!after) {
-        // If we MovHint something that is live at the time, then we kill the old value.
-        if (nodeAfter-&gt;containsMovHint()) {
-            VirtualRegister reg = nodeAfter-&gt;unlinkedLocal();
-            if (graph.isLiveInBytecode(reg, after)) {
-                functor(reg);
-                alreadyNoted = reg;
-            }
</del><ins>+    // If we MovHint something that is live at the time, then we kill the old value.
+    if (nodeAfter-&gt;containsMovHint()) {
+        VirtualRegister reg = nodeAfter-&gt;unlinkedLocal();
+        if (graph.isLiveInBytecode(reg, after)) {
+            functor(reg);
+            alreadyNoted = reg;
</ins><span class="cx">         }
</span><span class="cx">     }
</span><span class="cx">     
</span><del>-    if (!before) {
-        if (!after)
-            return;
-        // The true before-origin is the origin at predecessors that jump to us. But there can be
-        // many such predecessors and they will likely all have a different origin. So, it's better
-        // to do the conservative thing.
-        graph.forAllLocalsLiveInBytecode(after, functor);
-        return;
-    }
-    
</del><span class="cx">     if (before == after)
</span><span class="cx">         return;
</span><span class="cx">     
</span><del>-    // before could be unset even if after is, but the opposite cannot happen.
-    ASSERT(!!after);
-    
</del><span class="cx">     // It's easier to do this if the inline call frames are the same. This is way faster than the
</span><span class="cx">     // other loop, below.
</span><span class="cx">     if (before.inlineCallFrame == after.inlineCallFrame) {
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGIntegerRangeOptimizationPhasecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGIntegerRangeOptimizationPhase.cpp (189012 => 189013)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGIntegerRangeOptimizationPhase.cpp        2015-08-27 05:54:21 UTC (rev 189012)
+++ trunk/Source/JavaScriptCore/dfg/DFGIntegerRangeOptimizationPhase.cpp        2015-08-27 07:16:07 UTC (rev 189013)
</span><span class="lines">@@ -999,7 +999,7 @@
</span><span class="cx">             }
</span><span class="cx">         }
</span><span class="cx">         if (!m_zero) {
</span><del>-            m_zero = m_insertionSet.insertConstant(0, NodeOrigin(), jsNumber(0));
</del><ins>+            m_zero = m_insertionSet.insertConstant(0, m_graph.block(0)-&gt;at(0)-&gt;origin, jsNumber(0));
</ins><span class="cx">             m_insertionSet.execute(m_graph.block(0));
</span><span class="cx">         }
</span><span class="cx">         
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGLoopPreHeaderCreationPhasecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGLoopPreHeaderCreationPhase.cpp (189012 => 189013)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGLoopPreHeaderCreationPhase.cpp        2015-08-27 05:54:21 UTC (rev 189012)
+++ trunk/Source/JavaScriptCore/dfg/DFGLoopPreHeaderCreationPhase.cpp        2015-08-27 07:16:07 UTC (rev 189013)
</span><span class="lines">@@ -42,7 +42,7 @@
</span><span class="cx">     // Don't bother to preserve execution frequencies for now.
</span><span class="cx">     BasicBlock* preHeader = insertionSet.insertBefore(block, PNaN);
</span><span class="cx">     preHeader-&gt;appendNode(
</span><del>-        graph, SpecNone, Jump, block-&gt;firstOrigin(), OpInfo(block));
</del><ins>+        graph, SpecNone, Jump, block-&gt;at(0)-&gt;origin, OpInfo(block));
</ins><span class="cx">     
</span><span class="cx">     for (unsigned predecessorIndex = 0; predecessorIndex &lt; block-&gt;predecessors.size(); predecessorIndex++) {
</span><span class="cx">         BasicBlock* predecessor = block-&gt;predecessors[predecessorIndex];
</span><span class="lines">@@ -108,7 +108,7 @@
</span><span class="cx">             // A pre-header is most useful if it's possible to exit from its terminal. Hence
</span><span class="cx">             // if the terminal of the existing pre-header doesn't allow for exit, but the first
</span><span class="cx">             // origin of the loop header does, then we should create a new pre-header.
</span><del>-            if (!needsNewPreHeader &amp;&amp; loop.header()-&gt;firstOrigin().exitOK
</del><ins>+            if (!needsNewPreHeader &amp;&amp; loop.header()-&gt;at(0)-&gt;origin.exitOK
</ins><span class="cx">                 &amp;&amp; !existingPreHeader-&gt;terminal()-&gt;origin.exitOK)
</span><span class="cx">                 needsNewPreHeader = true;
</span><span class="cx">             
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGOSRAvailabilityAnalysisPhasecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGOSRAvailabilityAnalysisPhase.cpp (189012 => 189013)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGOSRAvailabilityAnalysisPhase.cpp        2015-08-27 05:54:21 UTC (rev 189012)
+++ trunk/Source/JavaScriptCore/dfg/DFGOSRAvailabilityAnalysisPhase.cpp        2015-08-27 07:16:07 UTC (rev 189013)
</span><span class="lines">@@ -91,7 +91,7 @@
</span><span class="cx">                     BasicBlock* successor = block-&gt;successor(successorIndex);
</span><span class="cx">                     successor-&gt;ssa-&gt;availabilityAtHead.merge(calculator.m_availability);
</span><span class="cx">                     successor-&gt;ssa-&gt;availabilityAtHead.pruneByLiveness(
</span><del>-                        m_graph, successor-&gt;firstOrigin().forExit);
</del><ins>+                        m_graph, successor-&gt;at(0)-&gt;origin.forExit);
</ins><span class="cx">                 }
</span><span class="cx">             }
</span><span class="cx">         } while (changed);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGObjectAllocationSinkingPhasecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGObjectAllocationSinkingPhase.cpp (189012 => 189013)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGObjectAllocationSinkingPhase.cpp        2015-08-27 05:54:21 UTC (rev 189012)
+++ trunk/Source/JavaScriptCore/dfg/DFGObjectAllocationSinkingPhase.cpp        2015-08-27 07:16:07 UTC (rev 189013)
</span><span class="lines">@@ -1548,7 +1548,7 @@
</span><span class="cx">         // with useless constants everywhere
</span><span class="cx">         HashMap&lt;FrozenValue*, Node*&gt; lazyMapping;
</span><span class="cx">         if (!m_bottom)
</span><del>-            m_bottom = m_insertionSet.insertConstant(0, NodeOrigin(), jsNumber(1927));
</del><ins>+            m_bottom = m_insertionSet.insertConstant(0, m_graph.block(0)-&gt;at(0)-&gt;origin, jsNumber(1927));
</ins><span class="cx">         for (BasicBlock* block : m_graph.blocksInNaturalOrder()) {
</span><span class="cx">             m_heap = m_heapAtHead[block];
</span><span class="cx"> 
</span><span class="lines">@@ -1621,7 +1621,7 @@
</span><span class="cx">                 if (m_heapAtHead[block].follow(location))
</span><span class="cx">                     return nullptr;
</span><span class="cx"> 
</span><del>-                Node* phiNode = m_graph.addNode(SpecHeapTop, Phi, NodeOrigin());
</del><ins>+                Node* phiNode = m_graph.addNode(SpecHeapTop, Phi, block-&gt;at(0)-&gt;origin.withInvalidExit());
</ins><span class="cx">                 phiNode-&gt;mergeFlags(NodeResultJS);
</span><span class="cx">                 return phiNode;
</span><span class="cx">             });
</span><span class="lines">@@ -1638,7 +1638,7 @@
</span><span class="cx">                 if (!m_heapAtHead[block].getAllocation(identifier).isEscapedAllocation())
</span><span class="cx">                     return nullptr;
</span><span class="cx"> 
</span><del>-                Node* phiNode = m_graph.addNode(SpecHeapTop, Phi, NodeOrigin());
</del><ins>+                Node* phiNode = m_graph.addNode(SpecHeapTop, Phi, block-&gt;at(0)-&gt;origin.withInvalidExit());
</ins><span class="cx">                 phiNode-&gt;mergeFlags(NodeResultJS);
</span><span class="cx">                 return phiNode;
</span><span class="cx">             });
</span><span class="lines">@@ -1669,7 +1669,9 @@
</span><span class="cx"> 
</span><span class="cx">                 if (m_sinkCandidates.contains(location.base())) {
</span><span class="cx">                     m_insertionSet.insert(
</span><del>-                        0, location.createHint(m_graph, NodeOrigin(), phiDef-&gt;value()));
</del><ins>+                        0,
+                        location.createHint(
+                            m_graph, block-&gt;at(0)-&gt;origin.withInvalidExit(), phiDef-&gt;value()));
</ins><span class="cx">                 }
</span><span class="cx">             }
</span><span class="cx"> 
</span><span class="lines">@@ -1680,7 +1682,9 @@
</span><span class="cx">                 Node* identifier = indexToNode[variable-&gt;index()];
</span><span class="cx">                 m_escapeeToMaterialization.add(identifier, phiDef-&gt;value());
</span><span class="cx">                 bool canExit = false;
</span><del>-                insertOSRHintsForUpdate(0, NodeOrigin(), canExit, availabilityCalculator.m_availability, identifier, phiDef-&gt;value());
</del><ins>+                insertOSRHintsForUpdate(
+                    0, block-&gt;at(0)-&gt;origin, canExit,
+                    availabilityCalculator.m_availability, identifier, phiDef-&gt;value());
</ins><span class="cx">             }
</span><span class="cx"> 
</span><span class="cx">             if (verbose) {
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGPutStackSinkingPhasecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGPutStackSinkingPhase.cpp (189012 => 189013)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGPutStackSinkingPhase.cpp        2015-08-27 05:54:21 UTC (rev 189012)
+++ trunk/Source/JavaScriptCore/dfg/DFGPutStackSinkingPhase.cpp        2015-08-27 07:16:07 UTC (rev 189013)
</span><span class="lines">@@ -358,7 +358,7 @@
</span><span class="cx">                 if (verbose)
</span><span class="cx">                     dataLog(&quot;Adding Phi for &quot;, operand, &quot; at &quot;, pointerDump(block), &quot;\n&quot;);
</span><span class="cx">                 
</span><del>-                Node* phiNode = m_graph.addNode(SpecHeapTop, Phi, NodeOrigin());
</del><ins>+                Node* phiNode = m_graph.addNode(SpecHeapTop, Phi, block-&gt;at(0)-&gt;origin.withInvalidExit());
</ins><span class="cx">                 phiNode-&gt;mergeFlags(resultFor(format));
</span><span class="cx">                 return phiNode;
</span><span class="cx">             });
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGSSAConversionPhasecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGSSAConversionPhase.cpp (189012 => 189013)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGSSAConversionPhase.cpp        2015-08-27 05:54:21 UTC (rev 189012)
+++ trunk/Source/JavaScriptCore/dfg/DFGSSAConversionPhase.cpp        2015-08-27 07:16:07 UTC (rev 189013)
</span><span class="lines">@@ -149,7 +149,7 @@
</span><span class="cx">                     return nullptr;
</span><span class="cx">                 
</span><span class="cx">                 Node* phiNode = m_graph.addNode(
</span><del>-                    variable-&gt;prediction(), Phi, NodeOrigin());
</del><ins>+                    variable-&gt;prediction(), Phi, block-&gt;at(0)-&gt;origin.withInvalidExit());
</ins><span class="cx">                 FlushFormat format = variable-&gt;flushFormat();
</span><span class="cx">                 NodeFlags result = resultFor(format);
</span><span class="cx">                 phiNode-&gt;mergeFlags(result);
</span><span class="lines">@@ -252,9 +252,12 @@
</span><span class="cx">                 valueForOperand.operand(variable-&gt;local()) = phiDef-&gt;value();
</span><span class="cx">                 
</span><span class="cx">                 m_insertionSet.insertNode(
</span><del>-                    phiInsertionPoint, SpecNone, MovHint, NodeOrigin(),
</del><ins>+                    phiInsertionPoint, SpecNone, MovHint, block-&gt;at(0)-&gt;origin.withInvalidExit(),
</ins><span class="cx">                     OpInfo(variable-&gt;local().offset()), phiDef-&gt;value()-&gt;defaultEdge());
</span><span class="cx">             }
</span><ins>+
+            if (block-&gt;at(0)-&gt;origin.exitOK)
+                m_insertionSet.insertNode(phiInsertionPoint, SpecNone, ExitOK, block-&gt;at(0)-&gt;origin);
</ins><span class="cx">             
</span><span class="cx">             for (unsigned nodeIndex = 0; nodeIndex &lt; block-&gt;size(); ++nodeIndex) {
</span><span class="cx">                 Node* node = block-&gt;at(nodeIndex);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGValidatecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGValidate.cpp (189012 => 189013)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGValidate.cpp        2015-08-27 05:54:21 UTC (rev 189012)
+++ trunk/Source/JavaScriptCore/dfg/DFGValidate.cpp        2015-08-27 07:16:07 UTC (rev 189013)
</span><span class="lines">@@ -187,6 +187,7 @@
</span><span class="cx">             for (size_t i = 0; i &lt; block-&gt;size(); ++i) {
</span><span class="cx">                 Node* node = block-&gt;at(i);
</span><span class="cx"> 
</span><ins>+                VALIDATE((node), node-&gt;origin.isSet());
</ins><span class="cx">                 VALIDATE((node), node-&gt;origin.semantic.isSet() == node-&gt;origin.forExit.isSet());
</span><span class="cx">                 VALIDATE((node), !(!node-&gt;origin.forExit.isSet() &amp;&amp; node-&gt;origin.exitOK));
</span><span class="cx">                 VALIDATE((node), !(mayExit(m_graph, node) == Exits &amp;&amp; !node-&gt;origin.exitOK));
</span><span class="lines">@@ -526,20 +527,21 @@
</span><span class="cx">                 continue;
</span><span class="cx">             
</span><span class="cx">             VALIDATE((block), block-&gt;phis.isEmpty());
</span><ins>+
+            bool didSeeExitOK = false;
</ins><span class="cx">             
</span><del>-            unsigned nodeIndex = 0;
-            for (; nodeIndex &lt; block-&gt;size() &amp;&amp; !block-&gt;at(nodeIndex)-&gt;origin.forExit.isSet(); nodeIndex++) { }
-            
-            VALIDATE((block), nodeIndex &lt; block-&gt;size());
-            
-            for (; nodeIndex &lt; block-&gt;size(); nodeIndex++)
-                VALIDATE((block-&gt;at(nodeIndex)), block-&gt;at(nodeIndex)-&gt;origin.forExit.isSet());
-            
</del><span class="cx">             for (unsigned nodeIndex = 0; nodeIndex &lt; block-&gt;size(); ++nodeIndex) {
</span><span class="cx">                 Node* node = block-&gt;at(nodeIndex);
</span><ins>+                didSeeExitOK |= node-&gt;origin.exitOK;
</ins><span class="cx">                 switch (node-&gt;op()) {
</span><span class="cx">                 case Phi:
</span><del>-                    VALIDATE((node), !node-&gt;origin.forExit.isSet());
</del><ins>+                    // Phi cannot exit, and it would be wrong to hoist anything to the Phi that could
+                    // exit.
+                    VALIDATE((node), !node-&gt;origin.exitOK);
+
+                    // It never makes sense to have exitOK anywhere in the block before a Phi. It's only
+                    // OK to exit after all Phis are done.
+                    VALIDATE((node), !didSeeExitOK);
</ins><span class="cx">                     break;
</span><span class="cx">                     
</span><span class="cx">                 case GetLocal:
</span></span></pre>
</div>
</div>

</body>
</html>