<!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>[196232] 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/196232">196232</a></dd>
<dt>Author</dt> <dd>fpizlo@apple.com</dd>
<dt>Date</dt> <dd>2016-02-06 17:51:00 -0800 (Sat, 06 Feb 2016)</dd>
</dl>

<h3>Log Message</h3>
<pre>FTL must store the call site index before runtime calls, even if it's the tail call slow path
https://bugs.webkit.org/show_bug.cgi?id=153955
rdar://problem/24290970

Reviewed by Saam Barati.

This is necessary because you could throw an exception in a host call on the tail call's slow
path. That'll route us to lookupExceptionHandler(), which unwinds starting with the call site
index of our frame. Bad things happen if it's not set. Prior to this patch it was possible
for the call site index field to be uninitialized, which meant that the throwing machinery
was making a wild guess about where we are.

* ftl/FTLLowerDFGToLLVM.cpp:
(JSC::FTL::DFG::LowerDFGToLLVM::compileTailCall):
* tests/stress/tail-call-host-call-throw.js: Added.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceJavaScriptCoreChangeLog">trunk/Source/JavaScriptCore/ChangeLog</a></li>
<li><a href="#trunkSourceJavaScriptCoreftlFTLLowerDFGToLLVMcpp">trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkSourceJavaScriptCoretestsstresstailcallhostcallthrowjs">trunk/Source/JavaScriptCore/tests/stress/tail-call-host-call-throw.js</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ChangeLog (196231 => 196232)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ChangeLog        2016-02-07 00:45:43 UTC (rev 196231)
+++ trunk/Source/JavaScriptCore/ChangeLog        2016-02-07 01:51:00 UTC (rev 196232)
</span><span class="lines">@@ -1,3 +1,21 @@
</span><ins>+2016-02-06  Filip Pizlo  &lt;fpizlo@apple.com&gt;
+
+        FTL must store the call site index before runtime calls, even if it's the tail call slow path
+        https://bugs.webkit.org/show_bug.cgi?id=153955
+        rdar://problem/24290970
+
+        Reviewed by Saam Barati.
+
+        This is necessary because you could throw an exception in a host call on the tail call's slow
+        path. That'll route us to lookupExceptionHandler(), which unwinds starting with the call site
+        index of our frame. Bad things happen if it's not set. Prior to this patch it was possible
+        for the call site index field to be uninitialized, which meant that the throwing machinery
+        was making a wild guess about where we are.
+
+        * ftl/FTLLowerDFGToLLVM.cpp:
+        (JSC::FTL::DFG::LowerDFGToLLVM::compileTailCall):
+        * tests/stress/tail-call-host-call-throw.js: Added.
+
</ins><span class="cx"> 2016-02-06  Darin Adler  &lt;darin@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Finish auditing call sites of upper() and lower(), eliminate many, and rename the functions
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLLowerDFGToLLVMcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp (196231 => 196232)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp        2016-02-07 00:45:43 UTC (rev 196231)
+++ trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp        2016-02-07 01:51:00 UTC (rev 196232)
</span><span class="lines">@@ -5186,6 +5186,7 @@
</span><span class="cx">         patchpoint-&gt;setGenerator(
</span><span class="cx">             [=] (CCallHelpers&amp; jit, const StackmapGenerationParams&amp; params) {
</span><span class="cx">                 AllowMacroScratchRegisterUsage allowScratch(jit);
</span><ins>+                CallSiteIndex callSiteIndex = state-&gt;jitCode-&gt;common.addUniqueCallSiteIndex(codeOrigin);
</ins><span class="cx"> 
</span><span class="cx">                 CallFrameShuffleData shuffleData;
</span><span class="cx">                 shuffleData.numLocals = state-&gt;jitCode-&gt;common.frameRegisterCount;
</span><span class="lines">@@ -5210,6 +5211,13 @@
</span><span class="cx"> 
</span><span class="cx">                 slowPath.link(&amp;jit);
</span><span class="cx"> 
</span><ins>+                // Yes, this is really necessary. You could throw an exception in a host call on the
+                // slow path. That'll route us to lookupExceptionHandler(), which unwinds starting
+                // with the call site index of our frame. Bad things happen if it's not set.
+                jit.store32(
+                    CCallHelpers::TrustedImm32(callSiteIndex.bits()),
+                    CCallHelpers::tagFor(VirtualRegister(JSStack::ArgumentCount)));
+
</ins><span class="cx">                 CallFrameShuffler slowPathShuffler(jit, shuffleData);
</span><span class="cx">                 slowPathShuffler.setCalleeJSValueRegs(JSValueRegs(GPRInfo::regT0));
</span><span class="cx">                 slowPathShuffler.prepareForSlowPath();
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoretestsstresstailcallhostcallthrowjs"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/tests/stress/tail-call-host-call-throw.js (0 => 196232)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/tests/stress/tail-call-host-call-throw.js                                (rev 0)
+++ trunk/Source/JavaScriptCore/tests/stress/tail-call-host-call-throw.js        2016-02-07 01:51:00 UTC (rev 196232)
</span><span class="lines">@@ -0,0 +1,36 @@
</span><ins>+&quot;use strict&quot;;
+
+function foo(func, arg) {
+    return func(arg);
+}
+
+noInline(foo);
+
+function a() { return 1; }
+function b() { return 2; }
+function c() { return 3; }
+function d() { return 4; }
+function e() { return 5; }
+function f() { return 6; }
+function g() { return 7; }
+function h() { return 8; }
+function i() { return 9; }
+function j() { return 0; }
+function k() { return 1; }
+function l() { return 2; }
+function m() { return 3; }
+
+var funcs = [a, b, c, d, e, f, g, h, i, l, m, Array];
+
+for (var i = 0; i &lt; 100000; ++i)
+    foo(funcs[i % funcs.length], 1);
+
+var result = null;
+try {
+    result = foo(Array, -1);
+} catch (e) {
+    if (e.toString() != &quot;RangeError: Array size is not a small enough positive integer.&quot;)
+        throw &quot;Error: bad exception at end: &quot; + e;
+}
+if (result != null)
+    throw &quot;Error: bad result at end: &quot; + result;
</ins></span></pre>
</div>
</div>

</body>
</html>