<!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>[208560] 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/208560">208560</a></dd>
<dt>Author</dt> <dd>mark.lam@apple.com</dd>
<dt>Date</dt> <dd>2016-11-10 13:19:52 -0800 (Thu, 10 Nov 2016)</dd>
</dl>

<h3>Log Message</h3>
<pre>Graph::methodOfGettingAValueProfileFor() should be returning the profile for the operand node.
https://bugs.webkit.org/show_bug.cgi?id=164600
&lt;rdar://problem/28828676&gt;

Reviewed by Filip Pizlo.

JSTests:

* stress/osr-exit-on-op-negate-should-no-fail-assertions.js: Added.

Source/JavaScriptCore:

Currently, Graph::methodOfGettingAValueProfileFor() assumes that the operand DFG
node that it is provided with always has a different origin than the node that is
using that operand.  For example, in a DFG graph that looks like this:

    a: ...
    b: ArithAdd(@a, ...)

... when emitting speculation checks on @a for the ArithAdd node at @b,
Graph::methodOfGettingAValueProfileFor() is passed @a, and expects @a's to
originate from a different bytecode than @b.  The intent here is to get the
profile for @a so that the OSR exit ramp for @b can update @a's profile with the
observed result type from @a so that future type prediction on incoming args for
the ArithAdd node can take this into consideration.

However, op_negate can be compiled into the following series of nodes:

    a: ...
    b: BooleanToNumber(@a)
    c: DoubleRep(@b)
    d: ArithNegate(@c)

All 3 nodes @b, @c, and @d maps to the same op_negate bytecode i.e. they have the
same origin.  When the speculativeJIT emits a speculationCheck for DoubleRep, it
calls Graph::methodOfGettingAValueProfileFor() to get the ArithProfile for the
BooleanToNumber node.  But because all 3 nodes have the same origin,
Graph::methodOfGettingAValueProfileFor() erroneously returns the ArithProfile for
the op_negate.  Subsequently, the OSR exit ramp will modify the ArithProfile of
the op_negate and corrupt its profile.  Instead, what the OSR exit ramp should be
doing is update the ArithProfile of op_negate's operand i.e. BooleanToNumber's
operand @a in this case.

The fix is to always pass the current node we're generating code for (in addition
to the operand node) to Graph::methodOfGettingAValueProfileFor().  This way, we
know the profile is valid if and only if the current node and its operand node
does not have the same origin.

In this patch, we also fixed the following:
1. Teach Graph::methodOfGettingAValueProfileFor() to get the profile for
   BooleanToNumber's operand if the operand node it is given is BooleanToNumber.
2. Change JITCompiler::appendExceptionHandlingOSRExit() to explicitly pass an
   empty MethodOfGettingAValueProfile().  It was implicitly doing this before.
3. Change SpeculativeJIT::emitInvalidationPoint() to pass an empty
   MethodOfGettingAValueProfile().  It has no child node.  Hence, it doesn't
   make sense to call Graph::methodOfGettingAValueProfileFor() for a child node
   that does not exist.

* dfg/DFGGraph.cpp:
(JSC::DFG::Graph::methodOfGettingAValueProfileFor):
* dfg/DFGGraph.h:
* dfg/DFGJITCompiler.cpp:
(JSC::DFG::JITCompiler::appendExceptionHandlingOSRExit):
* dfg/DFGSpeculativeJIT.cpp:
(JSC::DFG::SpeculativeJIT::speculationCheck):
(JSC::DFG::SpeculativeJIT::emitInvalidationPoint):
* ftl/FTLLowerDFGToB3.cpp:
(JSC::FTL::DFG::LowerDFGToB3::appendOSRExitDescriptor):</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkJSTestsChangeLog">trunk/JSTests/ChangeLog</a></li>
<li><a href="#trunkSourceJavaScriptCoreChangeLog">trunk/Source/JavaScriptCore/ChangeLog</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGGraphcpp">trunk/Source/JavaScriptCore/dfg/DFGGraph.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGGraphh">trunk/Source/JavaScriptCore/dfg/DFGGraph.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGJITCompilercpp">trunk/Source/JavaScriptCore/dfg/DFGJITCompiler.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGSpeculativeJITcpp">trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreftlFTLLowerDFGToB3cpp">trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkJSTestsstressosrexitonopnegateshouldnofailassertionsjs">trunk/JSTests/stress/osr-exit-on-op-negate-should-no-fail-assertions.js</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkJSTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/JSTests/ChangeLog (208559 => 208560)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/JSTests/ChangeLog        2016-11-10 20:52:54 UTC (rev 208559)
+++ trunk/JSTests/ChangeLog        2016-11-10 21:19:52 UTC (rev 208560)
</span><span class="lines">@@ -1,3 +1,13 @@
</span><ins>+2016-11-10  Mark Lam  &lt;mark.lam@apple.com&gt;
+
+        Graph::methodOfGettingAValueProfileFor() should be returning the profile for the operand node.
+        https://bugs.webkit.org/show_bug.cgi?id=164600
+        &lt;rdar://problem/28828676&gt;
+
+        Reviewed by Filip Pizlo.
+
+        * stress/osr-exit-on-op-negate-should-no-fail-assertions.js: Added.
+
</ins><span class="cx"> 2016-11-08  Yusuke Suzuki  &lt;utatane.tea@gmail.com&gt;
</span><span class="cx"> 
</span><span class="cx">         [JSC] Avoid cloned arguments allocation in ArrayPrototype methods
</span></span></pre></div>
<a id="trunkJSTestsstressosrexitonopnegateshouldnofailassertionsjs"></a>
<div class="addfile"><h4>Added: trunk/JSTests/stress/osr-exit-on-op-negate-should-no-fail-assertions.js (0 => 208560)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/JSTests/stress/osr-exit-on-op-negate-should-no-fail-assertions.js                                (rev 0)
+++ trunk/JSTests/stress/osr-exit-on-op-negate-should-no-fail-assertions.js        2016-11-10 21:19:52 UTC (rev 208560)
</span><span class="lines">@@ -0,0 +1,22 @@
</span><ins>+//@ runFTLNoCJIT
+// This test passes if it does not crash or fail any assertions.
+
+function inlineable(x) {
+    return -x;
+}
+
+function test(y) {
+    var results = [];
+    for (var j = 0; j &lt; 300; j++) {
+        var k = j % y.length;
+        try {
+            results.push(inlineable(y[k]));
+        } catch (e) {
+        }
+    }
+}
+noInline(test);
+
+for (var i = 0; i &lt; 1000; i++) {
+    test([false, -Infinity, Infinity, 0x50505050, undefined]);
+}
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ChangeLog (208559 => 208560)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ChangeLog        2016-11-10 20:52:54 UTC (rev 208559)
+++ trunk/Source/JavaScriptCore/ChangeLog        2016-11-10 21:19:52 UTC (rev 208560)
</span><span class="lines">@@ -1,3 +1,68 @@
</span><ins>+2016-11-10  Mark Lam  &lt;mark.lam@apple.com&gt;
+
+        Graph::methodOfGettingAValueProfileFor() should be returning the profile for the operand node.
+        https://bugs.webkit.org/show_bug.cgi?id=164600
+        &lt;rdar://problem/28828676&gt;
+
+        Reviewed by Filip Pizlo.
+
+        Currently, Graph::methodOfGettingAValueProfileFor() assumes that the operand DFG
+        node that it is provided with always has a different origin than the node that is
+        using that operand.  For example, in a DFG graph that looks like this:
+
+            a: ...
+            b: ArithAdd(@a, ...)
+
+        ... when emitting speculation checks on @a for the ArithAdd node at @b,
+        Graph::methodOfGettingAValueProfileFor() is passed @a, and expects @a's to
+        originate from a different bytecode than @b.  The intent here is to get the
+        profile for @a so that the OSR exit ramp for @b can update @a's profile with the
+        observed result type from @a so that future type prediction on incoming args for
+        the ArithAdd node can take this into consideration.
+
+        However, op_negate can be compiled into the following series of nodes:
+
+            a: ...
+            b: BooleanToNumber(@a)
+            c: DoubleRep(@b)
+            d: ArithNegate(@c)
+
+        All 3 nodes @b, @c, and @d maps to the same op_negate bytecode i.e. they have the
+        same origin.  When the speculativeJIT emits a speculationCheck for DoubleRep, it
+        calls Graph::methodOfGettingAValueProfileFor() to get the ArithProfile for the
+        BooleanToNumber node.  But because all 3 nodes have the same origin,
+        Graph::methodOfGettingAValueProfileFor() erroneously returns the ArithProfile for
+        the op_negate.  Subsequently, the OSR exit ramp will modify the ArithProfile of
+        the op_negate and corrupt its profile.  Instead, what the OSR exit ramp should be
+        doing is update the ArithProfile of op_negate's operand i.e. BooleanToNumber's
+        operand @a in this case.
+
+        The fix is to always pass the current node we're generating code for (in addition
+        to the operand node) to Graph::methodOfGettingAValueProfileFor().  This way, we
+        know the profile is valid if and only if the current node and its operand node
+        does not have the same origin.
+
+        In this patch, we also fixed the following:
+        1. Teach Graph::methodOfGettingAValueProfileFor() to get the profile for
+           BooleanToNumber's operand if the operand node it is given is BooleanToNumber.
+        2. Change JITCompiler::appendExceptionHandlingOSRExit() to explicitly pass an
+           empty MethodOfGettingAValueProfile().  It was implicitly doing this before.
+        3. Change SpeculativeJIT::emitInvalidationPoint() to pass an empty
+           MethodOfGettingAValueProfile().  It has no child node.  Hence, it doesn't
+           make sense to call Graph::methodOfGettingAValueProfileFor() for a child node
+           that does not exist.
+
+        * dfg/DFGGraph.cpp:
+        (JSC::DFG::Graph::methodOfGettingAValueProfileFor):
+        * dfg/DFGGraph.h:
+        * dfg/DFGJITCompiler.cpp:
+        (JSC::DFG::JITCompiler::appendExceptionHandlingOSRExit):
+        * dfg/DFGSpeculativeJIT.cpp:
+        (JSC::DFG::SpeculativeJIT::speculationCheck):
+        (JSC::DFG::SpeculativeJIT::emitInvalidationPoint):
+        * ftl/FTLLowerDFGToB3.cpp:
+        (JSC::FTL::DFG::LowerDFGToB3::appendOSRExitDescriptor):
+
</ins><span class="cx"> 2016-11-10  Aaron Chu  &lt;aaron_chu@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Web Inspector: AXI: clarify button roles (e.g. toggle or popup button)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGGraphcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGGraph.cpp (208559 => 208560)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGGraph.cpp        2016-11-10 20:52:54 UTC (rev 208559)
+++ trunk/Source/JavaScriptCore/dfg/DFGGraph.cpp        2016-11-10 21:19:52 UTC (rev 208560)
</span><span class="lines">@@ -1613,45 +1613,47 @@
</span><span class="cx">     return *m_controlEquivalenceAnalysis;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-MethodOfGettingAValueProfile Graph::methodOfGettingAValueProfileFor(Node* node)
</del><ins>+MethodOfGettingAValueProfile Graph::methodOfGettingAValueProfileFor(Node* currentNode, Node* operandNode)
</ins><span class="cx"> {
</span><del>-    while (node) {
-        CodeBlock* profiledBlock = baselineCodeBlockFor(node-&gt;origin.semantic);
-        
-        if (node-&gt;accessesStack(*this)) {
-            ValueProfile* result = [&amp;] () -&gt; ValueProfile* {
-                if (!node-&gt;local().isArgument())
-                    return nullptr;
-                int argument = node-&gt;local().toArgument();
-                Node* argumentNode = m_arguments[argument];
-                if (!argumentNode)
-                    return nullptr;
-                if (node-&gt;variableAccessData() != argumentNode-&gt;variableAccessData())
-                    return nullptr;
-                return profiledBlock-&gt;valueProfileForArgument(argument);
-            }();
-            if (result)
-                return result;
-            
-            if (node-&gt;op() == GetLocal) {
-                return MethodOfGettingAValueProfile::fromLazyOperand(
-                    profiledBlock,
-                    LazyOperandValueProfileKey(
-                        node-&gt;origin.semantic.bytecodeIndex, node-&gt;local()));
</del><ins>+    for (Node* node = operandNode; node;) {
+        // currentNode is null when we're doing speculation checks for checkArgumentTypes().
+        if (!currentNode || node-&gt;origin != currentNode-&gt;origin) {
+            CodeBlock* profiledBlock = baselineCodeBlockFor(node-&gt;origin.semantic);
+
+            if (node-&gt;accessesStack(*this)) {
+                ValueProfile* result = [&amp;] () -&gt; ValueProfile* {
+                    if (!node-&gt;local().isArgument())
+                        return nullptr;
+                    int argument = node-&gt;local().toArgument();
+                    Node* argumentNode = m_arguments[argument];
+                    if (!argumentNode)
+                        return nullptr;
+                    if (node-&gt;variableAccessData() != argumentNode-&gt;variableAccessData())
+                        return nullptr;
+                    return profiledBlock-&gt;valueProfileForArgument(argument);
+                }();
+                if (result)
+                    return result;
+
+                if (node-&gt;op() == GetLocal) {
+                    return MethodOfGettingAValueProfile::fromLazyOperand(
+                        profiledBlock,
+                        LazyOperandValueProfileKey(
+                            node-&gt;origin.semantic.bytecodeIndex, node-&gt;local()));
+                }
</ins><span class="cx">             }
</span><del>-        }
-        
-        if (node-&gt;hasHeapPrediction())
-            return profiledBlock-&gt;valueProfileForBytecodeOffset(node-&gt;origin.semantic.bytecodeIndex);
-        
-        {
</del><ins>+
+            if (node-&gt;hasHeapPrediction())
+                return profiledBlock-&gt;valueProfileForBytecodeOffset(node-&gt;origin.semantic.bytecodeIndex);
+
</ins><span class="cx">             if (profiledBlock-&gt;hasBaselineJITProfiling()) {
</span><span class="cx">                 if (ArithProfile* result = profiledBlock-&gt;arithProfileForBytecodeOffset(node-&gt;origin.semantic.bytecodeIndex))
</span><span class="cx">                     return result;
</span><span class="cx">             }
</span><span class="cx">         }
</span><del>-        
</del><ins>+
</ins><span class="cx">         switch (node-&gt;op()) {
</span><ins>+        case BooleanToNumber:
</ins><span class="cx">         case Identity:
</span><span class="cx">         case ValueRep:
</span><span class="cx">         case DoubleRep:
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGGraphh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGGraph.h (208559 => 208560)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGGraph.h        2016-11-10 20:52:54 UTC (rev 208559)
+++ trunk/Source/JavaScriptCore/dfg/DFGGraph.h        2016-11-10 21:19:52 UTC (rev 208560)
</span><span class="lines">@@ -417,7 +417,7 @@
</span><span class="cx">         return hasExitSite(node-&gt;origin.semantic, exitKind);
</span><span class="cx">     }
</span><span class="cx">     
</span><del>-    MethodOfGettingAValueProfile methodOfGettingAValueProfileFor(Node*);
</del><ins>+    MethodOfGettingAValueProfile methodOfGettingAValueProfileFor(Node* currentNode, Node* operandNode);
</ins><span class="cx">     
</span><span class="cx">     BlockIndex numBlocks() const { return m_blocks.size(); }
</span><span class="cx">     BasicBlock* block(BlockIndex blockIndex) const { return m_blocks[blockIndex].get(); }
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGJITCompilercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGJITCompiler.cpp (208559 => 208560)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGJITCompiler.cpp        2016-11-10 20:52:54 UTC (rev 208559)
+++ trunk/Source/JavaScriptCore/dfg/DFGJITCompiler.cpp        2016-11-10 21:19:52 UTC (rev 208560)
</span><span class="lines">@@ -588,7 +588,7 @@
</span><span class="cx"> 
</span><span class="cx"> void JITCompiler::appendExceptionHandlingOSRExit(ExitKind kind, unsigned eventStreamIndex, CodeOrigin opCatchOrigin, HandlerInfo* exceptionHandler, CallSiteIndex callSite, MacroAssembler::JumpList jumpsToFail)
</span><span class="cx"> {
</span><del>-    OSRExit exit(kind, JSValueRegs(), graph().methodOfGettingAValueProfileFor(nullptr), m_speculative.get(), eventStreamIndex);
</del><ins>+    OSRExit exit(kind, JSValueRegs(), MethodOfGettingAValueProfile(), m_speculative.get(), eventStreamIndex);
</ins><span class="cx">     exit.m_codeOrigin = opCatchOrigin;
</span><span class="cx">     exit.m_exceptionHandlerCallSiteIndex = callSite;
</span><span class="cx">     OSRExitCompilationInfo&amp; exitInfo = appendExitInfo(jumpsToFail);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGSpeculativeJITcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp (208559 => 208560)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp        2016-11-10 20:52:54 UTC (rev 208559)
+++ trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp        2016-11-10 21:19:52 UTC (rev 208560)
</span><span class="lines">@@ -251,7 +251,7 @@
</span><span class="cx">         m_jit.appendExitInfo(jumpsToFail);
</span><span class="cx">     } else
</span><span class="cx">         m_jit.appendExitInfo(jumpToFail);
</span><del>-    m_jit.jitCode()-&gt;appendOSRExit(OSRExit(kind, jsValueSource, m_jit.graph().methodOfGettingAValueProfileFor(node), this, m_stream-&gt;size()));
</del><ins>+    m_jit.jitCode()-&gt;appendOSRExit(OSRExit(kind, jsValueSource, m_jit.graph().methodOfGettingAValueProfileFor(m_currentNode, node), this, m_stream-&gt;size()));
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void SpeculativeJIT::speculationCheck(ExitKind kind, JSValueSource jsValueSource, Node* node, const MacroAssembler::JumpList&amp; jumpsToFail)
</span><span class="lines">@@ -266,7 +266,7 @@
</span><span class="cx">         m_jit.appendExitInfo(myJumpsToFail);
</span><span class="cx">     } else
</span><span class="cx">         m_jit.appendExitInfo(jumpsToFail);
</span><del>-    m_jit.jitCode()-&gt;appendOSRExit(OSRExit(kind, jsValueSource, m_jit.graph().methodOfGettingAValueProfileFor(node), this, m_stream-&gt;size()));
</del><ins>+    m_jit.jitCode()-&gt;appendOSRExit(OSRExit(kind, jsValueSource, m_jit.graph().methodOfGettingAValueProfileFor(m_currentNode, node), this, m_stream-&gt;size()));
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> OSRExitJumpPlaceholder SpeculativeJIT::speculationCheck(ExitKind kind, JSValueSource jsValueSource, Node* node)
</span><span class="lines">@@ -275,7 +275,7 @@
</span><span class="cx">         return OSRExitJumpPlaceholder();
</span><span class="cx">     unsigned index = m_jit.jitCode()-&gt;osrExit.size();
</span><span class="cx">     m_jit.appendExitInfo();
</span><del>-    m_jit.jitCode()-&gt;appendOSRExit(OSRExit(kind, jsValueSource, m_jit.graph().methodOfGettingAValueProfileFor(node), this, m_stream-&gt;size()));
</del><ins>+    m_jit.jitCode()-&gt;appendOSRExit(OSRExit(kind, jsValueSource, m_jit.graph().methodOfGettingAValueProfileFor(m_currentNode, node), this, m_stream-&gt;size()));
</ins><span class="cx">     return OSRExitJumpPlaceholder(index);
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -300,7 +300,7 @@
</span><span class="cx">         return;
</span><span class="cx">     unsigned recoveryIndex = m_jit.jitCode()-&gt;appendSpeculationRecovery(recovery);
</span><span class="cx">     m_jit.appendExitInfo(jumpToFail);
</span><del>-    m_jit.jitCode()-&gt;appendOSRExit(OSRExit(kind, jsValueSource, m_jit.graph().methodOfGettingAValueProfileFor(node), this, m_stream-&gt;size(), recoveryIndex));
</del><ins>+    m_jit.jitCode()-&gt;appendOSRExit(OSRExit(kind, jsValueSource, m_jit.graph().methodOfGettingAValueProfileFor(m_currentNode, node), this, m_stream-&gt;size(), recoveryIndex));
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void SpeculativeJIT::speculationCheck(ExitKind kind, JSValueSource jsValueSource, Edge nodeUse, MacroAssembler::Jump jumpToFail, const SpeculationRecovery&amp; recovery)
</span><span class="lines">@@ -314,8 +314,7 @@
</span><span class="cx">         return;
</span><span class="cx">     OSRExitCompilationInfo&amp; info = m_jit.appendExitInfo(JITCompiler::JumpList());
</span><span class="cx">     m_jit.jitCode()-&gt;appendOSRExit(OSRExit(
</span><del>-        UncountableInvalidation, JSValueSource(),
-        m_jit.graph().methodOfGettingAValueProfileFor(node),
</del><ins>+        UncountableInvalidation, JSValueSource(), MethodOfGettingAValueProfile(),
</ins><span class="cx">         this, m_stream-&gt;size()));
</span><span class="cx">     info.m_replacementSource = m_jit.watchpointLabel();
</span><span class="cx">     ASSERT(info.m_replacementSource.isSet());
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLLowerDFGToB3cpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp (208559 => 208560)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp        2016-11-10 20:52:54 UTC (rev 208559)
+++ trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp        2016-11-10 21:19:52 UTC (rev 208560)
</span><span class="lines">@@ -12412,7 +12412,7 @@
</span><span class="cx">     OSRExitDescriptor* appendOSRExitDescriptor(FormattedValue lowValue, Node* highValue)
</span><span class="cx">     {
</span><span class="cx">         return &amp;m_ftlState.jitCode-&gt;osrExitDescriptors.alloc(
</span><del>-            lowValue.format(), m_graph.methodOfGettingAValueProfileFor(highValue),
</del><ins>+            lowValue.format(), m_graph.methodOfGettingAValueProfileFor(m_node, highValue),
</ins><span class="cx">             availabilityMap().m_locals.numberOfArguments(),
</span><span class="cx">             availabilityMap().m_locals.numberOfLocals());
</span><span class="cx">     }
</span></span></pre>
</div>
</div>

</body>
</html>