<!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>[194048] 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/194048">194048</a></dd>
<dt>Author</dt> <dd>fpizlo@apple.com</dd>
<dt>Date</dt> <dd>2015-12-14 12:25:30 -0800 (Mon, 14 Dec 2015)</dd>
</dl>

<h3>Log Message</h3>
<pre>B3 should not give ValueReps for the non-stackmap children of a CheckValue to the generator callback
https://bugs.webkit.org/show_bug.cgi?id=152224

Reviewed by Geoffrey Garen.

Previously, a stackmap generator for a Check had to know how many children the B3 value for the
Check had at the time of code generation. That meant that B3 could not change the kind of Check
that it was - for example it cannot turn a Check into a Patchpoint and it cannot turn a CheckAdd
into a Check. But just changing the contract so that the stackmap generation params only get the
stackmap children of the check means that B3 can transform Checks as it likes.

This is meant to aid sinking values into checks.

Also, I found that the effects of a Check did not include HeapRange::top(). I think it's best if
exitsSideways does not imply reading top, the way that it does in DFG. In the DFG, that makes
sense because the exit analysis is orthogonal, so the clobber analysis tells you about the reads
not counting OSR exit - if you need to you can conditionally merge that with World based on a
separate exit analysis. But in B3, the Effects object tells you about both exiting and reading,
and it's computed by one analysis. Prior to this change, Check was not setting reads to top() so
we were effectively saying that Effects::reads is meaningless when exitsSideways is true. It
seems more sensible to instead force the analysis to set reads to top() when setting
exitsSideways to true, not least because we only have one such analysis and many users. But it
also makes sense for another reason: it allows us to bound the set of things that the program
will read after it exits. That might not be useful to us now, but it's a nice feature to get for
free. I've seen language features that have behave like exitsSideways that don't also read top,
like an array bounds check that causes sudden termination without making any promises about how
pretty the crash dump will look.

* b3/B3CheckSpecial.cpp:
(JSC::B3::CheckSpecial::generate):
* b3/B3Opcode.h:
* b3/B3Value.cpp:
(JSC::B3::Value::effects):
* b3/testb3.cpp:
(JSC::B3::testSimpleCheck):
(JSC::B3::testCheckLessThan):
(JSC::B3::testCheckMegaCombo):
(JSC::B3::testCheckAddImm):
(JSC::B3::testCheckAddImmCommute):
(JSC::B3::testCheckAddImmSomeRegister):
(JSC::B3::testCheckAdd):
(JSC::B3::testCheckAdd64):
(JSC::B3::testCheckSubImm):
(JSC::B3::testCheckSubBadImm):
(JSC::B3::testCheckSub):
(JSC::B3::testCheckSub64):
(JSC::B3::testCheckNeg):
(JSC::B3::testCheckNeg64):
(JSC::B3::testCheckMul):
(JSC::B3::testCheckMulMemory):
(JSC::B3::testCheckMul2):
(JSC::B3::testCheckMul64):
* ftl/FTLLowerDFGToLLVM.cpp:
(JSC::FTL::DFG::LowerDFGToLLVM::blessSpeculation):</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceJavaScriptCoreChangeLog">trunk/Source/JavaScriptCore/ChangeLog</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3B3CheckSpecialcpp">trunk/Source/JavaScriptCore/b3/B3CheckSpecial.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3B3Effectsh">trunk/Source/JavaScriptCore/b3/B3Effects.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3B3Opcodeh">trunk/Source/JavaScriptCore/b3/B3Opcode.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3B3Valuecpp">trunk/Source/JavaScriptCore/b3/B3Value.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3testb3cpp">trunk/Source/JavaScriptCore/b3/testb3.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreftlFTLLowerDFGToLLVMcpp">trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ChangeLog (194047 => 194048)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ChangeLog        2015-12-14 19:58:14 UTC (rev 194047)
+++ trunk/Source/JavaScriptCore/ChangeLog        2015-12-14 20:25:30 UTC (rev 194048)
</span><span class="lines">@@ -1,5 +1,62 @@
</span><span class="cx"> 2015-12-14  Filip Pizlo  &lt;fpizlo@apple.com&gt;
</span><span class="cx"> 
</span><ins>+        B3 should not give ValueReps for the non-stackmap children of a CheckValue to the generator callback
+        https://bugs.webkit.org/show_bug.cgi?id=152224
+
+        Reviewed by Geoffrey Garen.
+
+        Previously, a stackmap generator for a Check had to know how many children the B3 value for the
+        Check had at the time of code generation. That meant that B3 could not change the kind of Check
+        that it was - for example it cannot turn a Check into a Patchpoint and it cannot turn a CheckAdd
+        into a Check. But just changing the contract so that the stackmap generation params only get the
+        stackmap children of the check means that B3 can transform Checks as it likes.
+
+        This is meant to aid sinking values into checks.
+
+        Also, I found that the effects of a Check did not include HeapRange::top(). I think it's best if
+        exitsSideways does not imply reading top, the way that it does in DFG. In the DFG, that makes
+        sense because the exit analysis is orthogonal, so the clobber analysis tells you about the reads
+        not counting OSR exit - if you need to you can conditionally merge that with World based on a
+        separate exit analysis. But in B3, the Effects object tells you about both exiting and reading,
+        and it's computed by one analysis. Prior to this change, Check was not setting reads to top() so
+        we were effectively saying that Effects::reads is meaningless when exitsSideways is true. It
+        seems more sensible to instead force the analysis to set reads to top() when setting
+        exitsSideways to true, not least because we only have one such analysis and many users. But it
+        also makes sense for another reason: it allows us to bound the set of things that the program
+        will read after it exits. That might not be useful to us now, but it's a nice feature to get for
+        free. I've seen language features that have behave like exitsSideways that don't also read top,
+        like an array bounds check that causes sudden termination without making any promises about how
+        pretty the crash dump will look.
+
+        * b3/B3CheckSpecial.cpp:
+        (JSC::B3::CheckSpecial::generate):
+        * b3/B3Opcode.h:
+        * b3/B3Value.cpp:
+        (JSC::B3::Value::effects):
+        * b3/testb3.cpp:
+        (JSC::B3::testSimpleCheck):
+        (JSC::B3::testCheckLessThan):
+        (JSC::B3::testCheckMegaCombo):
+        (JSC::B3::testCheckAddImm):
+        (JSC::B3::testCheckAddImmCommute):
+        (JSC::B3::testCheckAddImmSomeRegister):
+        (JSC::B3::testCheckAdd):
+        (JSC::B3::testCheckAdd64):
+        (JSC::B3::testCheckSubImm):
+        (JSC::B3::testCheckSubBadImm):
+        (JSC::B3::testCheckSub):
+        (JSC::B3::testCheckSub64):
+        (JSC::B3::testCheckNeg):
+        (JSC::B3::testCheckNeg64):
+        (JSC::B3::testCheckMul):
+        (JSC::B3::testCheckMulMemory):
+        (JSC::B3::testCheckMul2):
+        (JSC::B3::testCheckMul64):
+        * ftl/FTLLowerDFGToLLVM.cpp:
+        (JSC::FTL::DFG::LowerDFGToLLVM::blessSpeculation):
+
+2015-12-14  Filip Pizlo  &lt;fpizlo@apple.com&gt;
+
</ins><span class="cx">         Air: Support Architecture-specific forms and Opcodes
</span><span class="cx">         https://bugs.webkit.org/show_bug.cgi?id=151736
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3B3CheckSpecialcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/B3CheckSpecial.cpp (194047 => 194048)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3CheckSpecial.cpp        2015-12-14 19:58:14 UTC (rev 194047)
+++ trunk/Source/JavaScriptCore/b3/B3CheckSpecial.cpp        2015-12-14 20:25:30 UTC (rev 194048)
</span><span class="lines">@@ -143,9 +143,6 @@
</span><span class="cx">     ASSERT(value);
</span><span class="cx"> 
</span><span class="cx">     Vector&lt;ValueRep&gt; reps;
</span><del>-    for (unsigned i = numB3Args(value); i--;)
-        reps.append(ValueRep());
-
</del><span class="cx">     appendRepsImpl(context, m_numCheckArgs + 1, inst, reps);
</span><span class="cx"> 
</span><span class="cx">     // Set aside the args that are relevant to undoing the operation. This is because we don't want to
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3B3Effectsh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/B3Effects.h (194047 => 194048)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3Effects.h        2015-12-14 19:58:14 UTC (rev 194047)
+++ trunk/Source/JavaScriptCore/b3/B3Effects.h        2015-12-14 20:25:30 UTC (rev 194048)
</span><span class="lines">@@ -38,10 +38,11 @@
</span><span class="cx">     bool terminal { false };
</span><span class="cx"> 
</span><span class="cx">     // True if this value can cause execution to terminate abruptly, and that this abrupt termination is
</span><del>-    // observable. Note that if exitsSideways is set to true but reads is bottom, then B3 is free to
-    // assume that after abrupt termination of this procedure, none of the heap will be read. That's
-    // usually false, so make sure that reads corresponds to the set of things that are readable after
-    // this function terminates abruptly.
</del><ins>+    // observable. An example of how this gets used is to limit the hoisting of controlDependent values.
+    // Note that if exitsSideways is set to true but reads is bottom, then B3 is free to assume that
+    // after abrupt termination of this procedure, none of the heap will be read. That's usually false,
+    // so make sure that reads corresponds to the set of things that are readable after this function
+    // terminates abruptly.
</ins><span class="cx">     bool exitsSideways { false };
</span><span class="cx"> 
</span><span class="cx">     // True if the instruction may change semantics if hoisted above some control flow.
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3B3Opcodeh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/B3Opcode.h (194047 => 194048)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3Opcode.h        2015-12-14 19:58:14 UTC (rev 194047)
+++ trunk/Source/JavaScriptCore/b3/B3Opcode.h        2015-12-14 20:25:30 UTC (rev 194048)
</span><span class="lines">@@ -174,9 +174,8 @@
</span><span class="cx">     // after the first CheckAdd executes, the second CheckAdd could not have possibly taken slow
</span><span class="cx">     // path. Therefore, the second CheckAdd's callback is irrelevant.
</span><span class="cx">     //
</span><del>-    // Note that the first two children of these operations have ValueRep's, both as input constraints and
-    // in the reps provided to the generator. The output constraints could be anything, and should not be
-    // inspected for meaning. If you want to capture the values of the inputs, use stackmap arguments.
</del><ins>+    // Note that the first two children of these operations have ValueRep's as input constraints but do
+    // not have output constraints.
</ins><span class="cx">     CheckAdd,
</span><span class="cx">     CheckSub,
</span><span class="cx">     CheckMul,
</span><span class="lines">@@ -184,8 +183,8 @@
</span><span class="cx">     // Check that side-exits. Use the CheckValue class. Like CheckAdd and friends, this has a
</span><span class="cx">     // stackmap with a generation callback. This takes an int argument that this branches on, with
</span><span class="cx">     // full branch fusion in the instruction selector. A true value jumps to the generator's slow
</span><del>-    // path. Note that the predicate child is has both an input and output ValueRep. The input constraint
-    // must be Any, and the output could be anything.
</del><ins>+    // path. Note that the predicate child is has both an input ValueRep. The input constraint must be
+    // WarmAny. It will not have an output constraint.
</ins><span class="cx">     Check,
</span><span class="cx"> 
</span><span class="cx">     // SSA support, in the style of DFG SSA.
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3B3Valuecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/B3Value.cpp (194047 => 194048)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3Value.cpp        2015-12-14 19:58:14 UTC (rev 194047)
+++ trunk/Source/JavaScriptCore/b3/B3Value.cpp        2015-12-14 20:25:30 UTC (rev 194048)
</span><span class="lines">@@ -415,6 +415,8 @@
</span><span class="cx">     case CheckMul:
</span><span class="cx">     case Check:
</span><span class="cx">         result.exitsSideways = true;
</span><ins>+        // The program could read anything after exiting, and it's on us to declare this.
+        result.reads = HeapRange::top();
</ins><span class="cx">         break;
</span><span class="cx">     case Upsilon:
</span><span class="cx">         result.writesSSAState = true;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3testb3cpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/testb3.cpp (194047 => 194048)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/testb3.cpp        2015-12-14 19:58:14 UTC (rev 194047)
+++ trunk/Source/JavaScriptCore/b3/testb3.cpp        2015-12-14 20:25:30 UTC (rev 194048)
</span><span class="lines">@@ -5597,7 +5597,7 @@
</span><span class="cx">     check-&gt;setGenerator(
</span><span class="cx">         [&amp;] (CCallHelpers&amp; jit, const StackmapGenerationParams&amp; params) {
</span><span class="cx">             AllowMacroScratchRegisterUsage allowScratch(jit);
</span><del>-            CHECK(params.size() == 1);
</del><ins>+            CHECK(!params.size());
</ins><span class="cx"> 
</span><span class="cx">             // This should always work because a function this simple should never have callee
</span><span class="cx">             // saves.
</span><span class="lines">@@ -5629,7 +5629,7 @@
</span><span class="cx">     check-&gt;setGenerator(
</span><span class="cx">         [&amp;] (CCallHelpers&amp; jit, const StackmapGenerationParams&amp; params) {
</span><span class="cx">             AllowMacroScratchRegisterUsage allowScratch(jit);
</span><del>-            CHECK(params.size() == 1);
</del><ins>+            CHECK(!params.size());
</ins><span class="cx"> 
</span><span class="cx">             // This should always work because a function this simple should never have callee
</span><span class="cx">             // saves.
</span><span class="lines">@@ -5675,7 +5675,7 @@
</span><span class="cx">     check-&gt;setGenerator(
</span><span class="cx">         [&amp;] (CCallHelpers&amp; jit, const StackmapGenerationParams&amp; params) {
</span><span class="cx">             AllowMacroScratchRegisterUsage allowScratch(jit);
</span><del>-            CHECK(params.size() == 1);
</del><ins>+            CHECK(!params.size());
</ins><span class="cx"> 
</span><span class="cx">             // This should always work because a function this simple should never have callee
</span><span class="cx">             // saves.
</span><span class="lines">@@ -5872,11 +5872,11 @@
</span><span class="cx">     checkAdd-&gt;setGenerator(
</span><span class="cx">         [&amp;] (CCallHelpers&amp; jit, const StackmapGenerationParams&amp; params) {
</span><span class="cx">             AllowMacroScratchRegisterUsage allowScratch(jit);
</span><del>-            CHECK(params.size() == 4);
-            CHECK(params[2].isGPR());
-            CHECK(params[3].isConstant());
-            CHECK(params[3].value() == 42);
-            jit.convertInt32ToDouble(params[2].gpr(), FPRInfo::fpRegT0);
</del><ins>+            CHECK(params.size() == 2);
+            CHECK(params[0].isGPR());
+            CHECK(params[1].isConstant());
+            CHECK(params[1].value() == 42);
+            jit.convertInt32ToDouble(params[0].gpr(), FPRInfo::fpRegT0);
</ins><span class="cx">             jit.convertInt32ToDouble(CCallHelpers::TrustedImm32(42), FPRInfo::fpRegT1);
</span><span class="cx">             jit.addDouble(FPRInfo::fpRegT1, FPRInfo::fpRegT0);
</span><span class="cx">             jit.emitFunctionEpilogue();
</span><span class="lines">@@ -5908,11 +5908,11 @@
</span><span class="cx">     checkAdd-&gt;setGenerator(
</span><span class="cx">         [&amp;] (CCallHelpers&amp; jit, const StackmapGenerationParams&amp; params) {
</span><span class="cx">             AllowMacroScratchRegisterUsage allowScratch(jit);
</span><del>-            CHECK(params.size() == 4);
-            CHECK(params[2].isGPR());
-            CHECK(params[3].isConstant());
-            CHECK(params[3].value() == 42);
-            jit.convertInt32ToDouble(params[2].gpr(), FPRInfo::fpRegT0);
</del><ins>+            CHECK(params.size() == 2);
+            CHECK(params[0].isGPR());
+            CHECK(params[1].isConstant());
+            CHECK(params[1].value() == 42);
+            jit.convertInt32ToDouble(params[0].gpr(), FPRInfo::fpRegT0);
</ins><span class="cx">             jit.convertInt32ToDouble(CCallHelpers::TrustedImm32(42), FPRInfo::fpRegT1);
</span><span class="cx">             jit.addDouble(FPRInfo::fpRegT1, FPRInfo::fpRegT0);
</span><span class="cx">             jit.emitFunctionEpilogue();
</span><span class="lines">@@ -5944,11 +5944,11 @@
</span><span class="cx">     checkAdd-&gt;setGenerator(
</span><span class="cx">         [&amp;] (CCallHelpers&amp; jit, const StackmapGenerationParams&amp; params) {
</span><span class="cx">             AllowMacroScratchRegisterUsage allowScratch(jit);
</span><del>-            CHECK(params.size() == 4);
-            CHECK(params[2].isGPR());
-            CHECK(params[3].isGPR());
-            jit.convertInt32ToDouble(params[2].gpr(), FPRInfo::fpRegT0);
-            jit.convertInt32ToDouble(params[3].gpr(), FPRInfo::fpRegT1);
</del><ins>+            CHECK(params.size() == 2);
+            CHECK(params[0].isGPR());
+            CHECK(params[1].isGPR());
+            jit.convertInt32ToDouble(params[0].gpr(), FPRInfo::fpRegT0);
+            jit.convertInt32ToDouble(params[1].gpr(), FPRInfo::fpRegT1);
</ins><span class="cx">             jit.addDouble(FPRInfo::fpRegT1, FPRInfo::fpRegT0);
</span><span class="cx">             jit.emitFunctionEpilogue();
</span><span class="cx">             jit.ret();
</span><span class="lines">@@ -5981,11 +5981,11 @@
</span><span class="cx">     checkAdd-&gt;setGenerator(
</span><span class="cx">         [&amp;] (CCallHelpers&amp; jit, const StackmapGenerationParams&amp; params) {
</span><span class="cx">             AllowMacroScratchRegisterUsage allowScratch(jit);
</span><del>-            CHECK(params.size() == 4);
-            CHECK(params[2].isGPR());
-            CHECK(params[3].isGPR());
-            jit.convertInt32ToDouble(params[2].gpr(), FPRInfo::fpRegT0);
-            jit.convertInt32ToDouble(params[3].gpr(), FPRInfo::fpRegT1);
</del><ins>+            CHECK(params.size() == 2);
+            CHECK(params[0].isGPR());
+            CHECK(params[1].isGPR());
+            jit.convertInt32ToDouble(params[0].gpr(), FPRInfo::fpRegT0);
+            jit.convertInt32ToDouble(params[1].gpr(), FPRInfo::fpRegT1);
</ins><span class="cx">             jit.addDouble(FPRInfo::fpRegT1, FPRInfo::fpRegT0);
</span><span class="cx">             jit.emitFunctionEpilogue();
</span><span class="cx">             jit.ret();
</span><span class="lines">@@ -6014,11 +6014,11 @@
</span><span class="cx">     checkAdd-&gt;setGenerator(
</span><span class="cx">         [&amp;] (CCallHelpers&amp; jit, const StackmapGenerationParams&amp; params) {
</span><span class="cx">             AllowMacroScratchRegisterUsage allowScratch(jit);
</span><del>-            CHECK(params.size() == 4);
-            CHECK(params[2].isGPR());
-            CHECK(params[3].isGPR());
-            jit.convertInt64ToDouble(params[2].gpr(), FPRInfo::fpRegT0);
-            jit.convertInt64ToDouble(params[3].gpr(), FPRInfo::fpRegT1);
</del><ins>+            CHECK(params.size() == 2);
+            CHECK(params[0].isGPR());
+            CHECK(params[1].isGPR());
+            jit.convertInt64ToDouble(params[0].gpr(), FPRInfo::fpRegT0);
+            jit.convertInt64ToDouble(params[1].gpr(), FPRInfo::fpRegT1);
</ins><span class="cx">             jit.addDouble(FPRInfo::fpRegT1, FPRInfo::fpRegT0);
</span><span class="cx">             jit.emitFunctionEpilogue();
</span><span class="cx">             jit.ret();
</span><span class="lines">@@ -6088,11 +6088,11 @@
</span><span class="cx">     checkSub-&gt;setGenerator(
</span><span class="cx">         [&amp;] (CCallHelpers&amp; jit, const StackmapGenerationParams&amp; params) {
</span><span class="cx">             AllowMacroScratchRegisterUsage allowScratch(jit);
</span><del>-            CHECK(params.size() == 4);
-            CHECK(params[2].isGPR());
-            CHECK(params[3].isConstant());
-            CHECK(params[3].value() == 42);
-            jit.convertInt32ToDouble(params[2].gpr(), FPRInfo::fpRegT0);
</del><ins>+            CHECK(params.size() == 2);
+            CHECK(params[0].isGPR());
+            CHECK(params[1].isConstant());
+            CHECK(params[1].value() == 42);
+            jit.convertInt32ToDouble(params[0].gpr(), FPRInfo::fpRegT0);
</ins><span class="cx">             jit.convertInt32ToDouble(CCallHelpers::TrustedImm32(42), FPRInfo::fpRegT1);
</span><span class="cx">             jit.subDouble(FPRInfo::fpRegT1, FPRInfo::fpRegT0);
</span><span class="cx">             jit.emitFunctionEpilogue();
</span><span class="lines">@@ -6125,11 +6125,11 @@
</span><span class="cx">     checkSub-&gt;setGenerator(
</span><span class="cx">         [&amp;] (CCallHelpers&amp; jit, const StackmapGenerationParams&amp; params) {
</span><span class="cx">             AllowMacroScratchRegisterUsage allowScratch(jit);
</span><del>-            CHECK(params.size() == 4);
-            CHECK(params[2].isGPR());
-            CHECK(params[3].isConstant());
-            CHECK(params[3].value() == badImm);
-            jit.convertInt32ToDouble(params[2].gpr(), FPRInfo::fpRegT0);
</del><ins>+            CHECK(params.size() == 2);
+            CHECK(params[0].isGPR());
+            CHECK(params[1].isConstant());
+            CHECK(params[1].value() == badImm);
+            jit.convertInt32ToDouble(params[0].gpr(), FPRInfo::fpRegT0);
</ins><span class="cx">             jit.convertInt32ToDouble(CCallHelpers::TrustedImm32(badImm), FPRInfo::fpRegT1);
</span><span class="cx">             jit.subDouble(FPRInfo::fpRegT1, FPRInfo::fpRegT0);
</span><span class="cx">             jit.emitFunctionEpilogue();
</span><span class="lines">@@ -6163,11 +6163,11 @@
</span><span class="cx">     checkSub-&gt;setGenerator(
</span><span class="cx">         [&amp;] (CCallHelpers&amp; jit, const StackmapGenerationParams&amp; params) {
</span><span class="cx">             AllowMacroScratchRegisterUsage allowScratch(jit);
</span><del>-            CHECK(params.size() == 4);
-            CHECK(params[2].isGPR());
-            CHECK(params[3].isGPR());
-            jit.convertInt32ToDouble(params[2].gpr(), FPRInfo::fpRegT0);
-            jit.convertInt32ToDouble(params[3].gpr(), FPRInfo::fpRegT1);
</del><ins>+            CHECK(params.size() == 2);
+            CHECK(params[0].isGPR());
+            CHECK(params[1].isGPR());
+            jit.convertInt32ToDouble(params[0].gpr(), FPRInfo::fpRegT0);
+            jit.convertInt32ToDouble(params[1].gpr(), FPRInfo::fpRegT1);
</ins><span class="cx">             jit.subDouble(FPRInfo::fpRegT1, FPRInfo::fpRegT0);
</span><span class="cx">             jit.emitFunctionEpilogue();
</span><span class="cx">             jit.ret();
</span><span class="lines">@@ -6201,11 +6201,11 @@
</span><span class="cx">     checkSub-&gt;setGenerator(
</span><span class="cx">         [&amp;] (CCallHelpers&amp; jit, const StackmapGenerationParams&amp; params) {
</span><span class="cx">             AllowMacroScratchRegisterUsage allowScratch(jit);
</span><del>-            CHECK(params.size() == 4);
-            CHECK(params[2].isGPR());
-            CHECK(params[3].isGPR());
-            jit.convertInt64ToDouble(params[2].gpr(), FPRInfo::fpRegT0);
-            jit.convertInt64ToDouble(params[3].gpr(), FPRInfo::fpRegT1);
</del><ins>+            CHECK(params.size() == 2);
+            CHECK(params[0].isGPR());
+            CHECK(params[1].isGPR());
+            jit.convertInt64ToDouble(params[0].gpr(), FPRInfo::fpRegT0);
+            jit.convertInt64ToDouble(params[1].gpr(), FPRInfo::fpRegT1);
</ins><span class="cx">             jit.subDouble(FPRInfo::fpRegT1, FPRInfo::fpRegT0);
</span><span class="cx">             jit.emitFunctionEpilogue();
</span><span class="cx">             jit.ret();
</span><span class="lines">@@ -6274,9 +6274,9 @@
</span><span class="cx">     checkNeg-&gt;setGenerator(
</span><span class="cx">         [&amp;] (CCallHelpers&amp; jit, const StackmapGenerationParams&amp; params) {
</span><span class="cx">             AllowMacroScratchRegisterUsage allowScratch(jit);
</span><del>-            CHECK(params.size() == 3);
-            CHECK(params[2].isGPR());
-            jit.convertInt32ToDouble(params[2].gpr(), FPRInfo::fpRegT1);
</del><ins>+            CHECK(params.size() == 1);
+            CHECK(params[0].isGPR());
+            jit.convertInt32ToDouble(params[0].gpr(), FPRInfo::fpRegT1);
</ins><span class="cx">             jit.negateDouble(FPRInfo::fpRegT1, FPRInfo::fpRegT0);
</span><span class="cx">             jit.emitFunctionEpilogue();
</span><span class="cx">             jit.ret();
</span><span class="lines">@@ -6304,9 +6304,9 @@
</span><span class="cx">     checkNeg-&gt;setGenerator(
</span><span class="cx">         [&amp;] (CCallHelpers&amp; jit, const StackmapGenerationParams&amp; params) {
</span><span class="cx">             AllowMacroScratchRegisterUsage allowScratch(jit);
</span><del>-            CHECK(params.size() == 3);
-            CHECK(params[2].isGPR());
-            jit.convertInt64ToDouble(params[2].gpr(), FPRInfo::fpRegT1);
</del><ins>+            CHECK(params.size() == 1);
+            CHECK(params[0].isGPR());
+            jit.convertInt64ToDouble(params[0].gpr(), FPRInfo::fpRegT1);
</ins><span class="cx">             jit.negateDouble(FPRInfo::fpRegT1, FPRInfo::fpRegT0);
</span><span class="cx">             jit.emitFunctionEpilogue();
</span><span class="cx">             jit.ret();
</span><span class="lines">@@ -6339,11 +6339,11 @@
</span><span class="cx">     checkMul-&gt;setGenerator(
</span><span class="cx">         [&amp;] (CCallHelpers&amp; jit, const StackmapGenerationParams&amp; params) {
</span><span class="cx">             AllowMacroScratchRegisterUsage allowScratch(jit);
</span><del>-            CHECK(params.size() == 4);
-            CHECK(params[2].isGPR());
-            CHECK(params[3].isGPR());
-            jit.convertInt32ToDouble(params[2].gpr(), FPRInfo::fpRegT0);
-            jit.convertInt32ToDouble(params[3].gpr(), FPRInfo::fpRegT1);
</del><ins>+            CHECK(params.size() == 2);
+            CHECK(params[0].isGPR());
+            CHECK(params[1].isGPR());
+            jit.convertInt32ToDouble(params[0].gpr(), FPRInfo::fpRegT0);
+            jit.convertInt32ToDouble(params[1].gpr(), FPRInfo::fpRegT1);
</ins><span class="cx">             jit.mulDouble(FPRInfo::fpRegT1, FPRInfo::fpRegT0);
</span><span class="cx">             jit.emitFunctionEpilogue();
</span><span class="cx">             jit.ret();
</span><span class="lines">@@ -6380,11 +6380,11 @@
</span><span class="cx">     checkMul-&gt;setGenerator(
</span><span class="cx">         [&amp;] (CCallHelpers&amp; jit, const StackmapGenerationParams&amp; params) {
</span><span class="cx">             AllowMacroScratchRegisterUsage allowScratch(jit);
</span><del>-            CHECK(params.size() == 4);
-            CHECK(params[2].isGPR());
-            CHECK(params[3].isGPR());
-            jit.convertInt32ToDouble(params[2].gpr(), FPRInfo::fpRegT0);
-            jit.convertInt32ToDouble(params[3].gpr(), FPRInfo::fpRegT1);
</del><ins>+            CHECK(params.size() == 2);
+            CHECK(params[0].isGPR());
+            CHECK(params[1].isGPR());
+            jit.convertInt32ToDouble(params[0].gpr(), FPRInfo::fpRegT0);
+            jit.convertInt32ToDouble(params[1].gpr(), FPRInfo::fpRegT1);
</ins><span class="cx">             jit.mulDouble(FPRInfo::fpRegT1, FPRInfo::fpRegT0);
</span><span class="cx">             jit.emitFunctionEpilogue();
</span><span class="cx">             jit.ret();
</span><span class="lines">@@ -6426,11 +6426,11 @@
</span><span class="cx">     checkMul-&gt;setGenerator(
</span><span class="cx">         [&amp;] (CCallHelpers&amp; jit, const StackmapGenerationParams&amp; params) {
</span><span class="cx">             AllowMacroScratchRegisterUsage allowScratch(jit);
</span><del>-            CHECK(params.size() == 4);
-            CHECK(params[2].isGPR());
-            CHECK(params[3].isConstant());
-            CHECK(params[3].value() == 2);
-            jit.convertInt32ToDouble(params[2].gpr(), FPRInfo::fpRegT0);
</del><ins>+            CHECK(params.size() == 2);
+            CHECK(params[0].isGPR());
+            CHECK(params[1].isConstant());
+            CHECK(params[1].value() == 2);
+            jit.convertInt32ToDouble(params[0].gpr(), FPRInfo::fpRegT0);
</ins><span class="cx">             jit.convertInt32ToDouble(CCallHelpers::TrustedImm32(2), FPRInfo::fpRegT1);
</span><span class="cx">             jit.mulDouble(FPRInfo::fpRegT1, FPRInfo::fpRegT0);
</span><span class="cx">             jit.emitFunctionEpilogue();
</span><span class="lines">@@ -6460,11 +6460,11 @@
</span><span class="cx">     checkMul-&gt;setGenerator(
</span><span class="cx">         [&amp;] (CCallHelpers&amp; jit, const StackmapGenerationParams&amp; params) {
</span><span class="cx">             AllowMacroScratchRegisterUsage allowScratch(jit);
</span><del>-            CHECK(params.size() == 4);
-            CHECK(params[2].isGPR());
-            CHECK(params[3].isGPR());
-            jit.convertInt64ToDouble(params[2].gpr(), FPRInfo::fpRegT0);
-            jit.convertInt64ToDouble(params[3].gpr(), FPRInfo::fpRegT1);
</del><ins>+            CHECK(params.size() == 2);
+            CHECK(params[0].isGPR());
+            CHECK(params[1].isGPR());
+            jit.convertInt64ToDouble(params[0].gpr(), FPRInfo::fpRegT0);
+            jit.convertInt64ToDouble(params[1].gpr(), FPRInfo::fpRegT1);
</ins><span class="cx">             jit.mulDouble(FPRInfo::fpRegT1, FPRInfo::fpRegT0);
</span><span class="cx">             jit.emitFunctionEpilogue();
</span><span class="cx">             jit.ret();
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLLowerDFGToLLVMcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp (194047 => 194048)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp        2015-12-14 19:58:14 UTC (rev 194047)
+++ trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp        2015-12-14 20:25:30 UTC (rev 194048)
</span><span class="lines">@@ -9442,14 +9442,13 @@
</span><span class="cx">     {
</span><span class="cx">         OSRExitDescriptor* exitDescriptor = appendOSRExitDescriptor(lowValue, highValue);
</span><span class="cx">         
</span><del>-        unsigned offset = value-&gt;numChildren();
</del><span class="cx">         value-&gt;appendColdAnys(buildExitArguments(exitDescriptor, origin.forExit, lowValue));
</span><span class="cx"> 
</span><span class="cx">         State* state = &amp;m_ftlState;
</span><span class="cx">         value-&gt;setGenerator(
</span><span class="cx">             [=] (CCallHelpers&amp; jit, const B3::StackmapGenerationParams&amp; params) {
</span><span class="cx">                 exitDescriptor-&gt;emitOSRExit(
</span><del>-                    *state, kind, origin, jit, params, offset, isExceptionHandler);
</del><ins>+                    *state, kind, origin, jit, params, 0, isExceptionHandler);
</ins><span class="cx">             });
</span><span class="cx">     }
</span><span class="cx"> #endif
</span></span></pre>
</div>
</div>

</body>
</html>