<!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>[191394] 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/191394">191394</a></dd>
<dt>Author</dt> <dd>sbarati@apple.com</dd>
<dt>Date</dt> <dd>2015-10-21 11:44:44 -0700 (Wed, 21 Oct 2015)</dd>
</dl>

<h3>Log Message</h3>
<pre>The FTL should place the CallSiteIndex on the call frame for JS calls when it fills in the patchpoint
https://bugs.webkit.org/show_bug.cgi?id=150104

Reviewed by Filip Pizlo.

We lower JS Calls to patchpoints in LLVM. LLVM may decide to duplicate
these patchpoints (or remove them). We eagerly store the CallSiteIndex on the 
call frame when lowering DFG to LLVM. But, because the patchpoint we lower to may
be duplicated, we really don't know the unique CallSiteIndex until we've
actually seen the resulting patchpoints after LLVM has completed its transformations.
To solve this, we now store the unique CallSiteIndex on the call frame header 
when generating code to fill into the patchpoint.

* ftl/FTLCompile.cpp:
(JSC::FTL::mmAllocateDataSection):
* ftl/FTLJSCall.cpp:
(JSC::FTL::JSCall::JSCall):
(JSC::FTL::JSCall::emit):
* ftl/FTLJSCall.h:
(JSC::FTL::JSCall::stackmapID):
* ftl/FTLJSCallBase.cpp:
(JSC::FTL::JSCallBase::JSCallBase):
(JSC::FTL::JSCallBase::emit):
(JSC::FTL::JSCallBase::link):
* ftl/FTLJSCallBase.h:
* ftl/FTLJSCallVarargs.cpp:
(JSC::FTL::JSCallVarargs::JSCallVarargs):
(JSC::FTL::JSCallVarargs::numSpillSlotsNeeded):
(JSC::FTL::JSCallVarargs::emit):
* ftl/FTLJSCallVarargs.h:
(JSC::FTL::JSCallVarargs::node):
(JSC::FTL::JSCallVarargs::stackmapID):
* ftl/FTLJSTailCall.cpp:
(JSC::FTL::JSTailCall::JSTailCall):
(JSC::FTL::m_instructionOffset):
(JSC::FTL::JSTailCall::emit):
* ftl/FTLLowerDFGToLLVM.cpp:
(JSC::FTL::DFG::LowerDFGToLLVM::compileCallOrConstruct):
(JSC::FTL::DFG::LowerDFGToLLVM::compileCallOrConstructVarargs):
(JSC::FTL::DFG::LowerDFGToLLVM::callPreflight):
(JSC::FTL::DFG::LowerDFGToLLVM::codeOriginDescriptionOfCallSite):
(JSC::FTL::DFG::LowerDFGToLLVM::callCheck):</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceJavaScriptCoreChangeLog">trunk/Source/JavaScriptCore/ChangeLog</a></li>
<li><a href="#trunkSourceJavaScriptCoreftlFTLCompilecpp">trunk/Source/JavaScriptCore/ftl/FTLCompile.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreftlFTLJSCallcpp">trunk/Source/JavaScriptCore/ftl/FTLJSCall.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreftlFTLJSCallh">trunk/Source/JavaScriptCore/ftl/FTLJSCall.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreftlFTLJSCallBasecpp">trunk/Source/JavaScriptCore/ftl/FTLJSCallBase.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreftlFTLJSCallBaseh">trunk/Source/JavaScriptCore/ftl/FTLJSCallBase.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreftlFTLJSCallVarargscpp">trunk/Source/JavaScriptCore/ftl/FTLJSCallVarargs.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreftlFTLJSCallVarargsh">trunk/Source/JavaScriptCore/ftl/FTLJSCallVarargs.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreftlFTLJSTailCallcpp">trunk/Source/JavaScriptCore/ftl/FTLJSTailCall.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 (191393 => 191394)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ChangeLog        2015-10-21 18:42:06 UTC (rev 191393)
+++ trunk/Source/JavaScriptCore/ChangeLog        2015-10-21 18:44:44 UTC (rev 191394)
</span><span class="lines">@@ -1,3 +1,48 @@
</span><ins>+2015-10-21  Saam barati  &lt;sbarati@apple.com&gt;
+
+        The FTL should place the CallSiteIndex on the call frame for JS calls when it fills in the patchpoint
+        https://bugs.webkit.org/show_bug.cgi?id=150104
+
+        Reviewed by Filip Pizlo.
+
+        We lower JS Calls to patchpoints in LLVM. LLVM may decide to duplicate
+        these patchpoints (or remove them). We eagerly store the CallSiteIndex on the 
+        call frame when lowering DFG to LLVM. But, because the patchpoint we lower to may
+        be duplicated, we really don't know the unique CallSiteIndex until we've
+        actually seen the resulting patchpoints after LLVM has completed its transformations.
+        To solve this, we now store the unique CallSiteIndex on the call frame header 
+        when generating code to fill into the patchpoint.
+
+        * ftl/FTLCompile.cpp:
+        (JSC::FTL::mmAllocateDataSection):
+        * ftl/FTLJSCall.cpp:
+        (JSC::FTL::JSCall::JSCall):
+        (JSC::FTL::JSCall::emit):
+        * ftl/FTLJSCall.h:
+        (JSC::FTL::JSCall::stackmapID):
+        * ftl/FTLJSCallBase.cpp:
+        (JSC::FTL::JSCallBase::JSCallBase):
+        (JSC::FTL::JSCallBase::emit):
+        (JSC::FTL::JSCallBase::link):
+        * ftl/FTLJSCallBase.h:
+        * ftl/FTLJSCallVarargs.cpp:
+        (JSC::FTL::JSCallVarargs::JSCallVarargs):
+        (JSC::FTL::JSCallVarargs::numSpillSlotsNeeded):
+        (JSC::FTL::JSCallVarargs::emit):
+        * ftl/FTLJSCallVarargs.h:
+        (JSC::FTL::JSCallVarargs::node):
+        (JSC::FTL::JSCallVarargs::stackmapID):
+        * ftl/FTLJSTailCall.cpp:
+        (JSC::FTL::JSTailCall::JSTailCall):
+        (JSC::FTL::m_instructionOffset):
+        (JSC::FTL::JSTailCall::emit):
+        * ftl/FTLLowerDFGToLLVM.cpp:
+        (JSC::FTL::DFG::LowerDFGToLLVM::compileCallOrConstruct):
+        (JSC::FTL::DFG::LowerDFGToLLVM::compileCallOrConstructVarargs):
+        (JSC::FTL::DFG::LowerDFGToLLVM::callPreflight):
+        (JSC::FTL::DFG::LowerDFGToLLVM::codeOriginDescriptionOfCallSite):
+        (JSC::FTL::DFG::LowerDFGToLLVM::callCheck):
+
</ins><span class="cx"> 2015-10-21  Geoffrey Garen  &lt;ggaren@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Date creation should share a little code
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLCompilecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ftl/FTLCompile.cpp (191393 => 191394)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLCompile.cpp        2015-10-21 18:42:06 UTC (rev 191393)
+++ trunk/Source/JavaScriptCore/ftl/FTLCompile.cpp        2015-10-21 18:44:44 UTC (rev 191394)
</span><span class="lines">@@ -657,7 +657,7 @@
</span><span class="cx">         JSCall&amp; call = state.jsCalls[i];
</span><span class="cx"> 
</span><span class="cx">         CCallHelpers fastPathJIT(&amp;vm, codeBlock);
</span><del>-        call.emit(fastPathJIT, state.jitCode-&gt;stackmaps.stackSizeForLocals());
</del><ins>+        call.emit(fastPathJIT, state);
</ins><span class="cx"> 
</span><span class="cx">         char* startOfIC = bitwise_cast&lt;char*&gt;(generatedFunction) + call.m_instructionOffset;
</span><span class="cx"> 
</span><span class="lines">@@ -672,7 +672,7 @@
</span><span class="cx">         JSCallVarargs&amp; call = state.jsCallVarargses[i];
</span><span class="cx">         
</span><span class="cx">         CCallHelpers fastPathJIT(&amp;vm, codeBlock);
</span><del>-        call.emit(fastPathJIT, varargsSpillSlotsOffset);
</del><ins>+        call.emit(fastPathJIT, state, varargsSpillSlotsOffset);
</ins><span class="cx"> 
</span><span class="cx">         char* startOfIC = bitwise_cast&lt;char*&gt;(generatedFunction) + call.m_instructionOffset;
</span><span class="cx">         size_t sizeOfIC = sizeOfICFor(call.node());
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLJSCallcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ftl/FTLJSCall.cpp (191393 => 191394)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLJSCall.cpp        2015-10-21 18:42:06 UTC (rev 191393)
+++ trunk/Source/JavaScriptCore/ftl/FTLJSCall.cpp        2015-10-21 18:44:44 UTC (rev 191394)
</span><span class="lines">@@ -29,6 +29,7 @@
</span><span class="cx"> #if ENABLE(FTL_JIT)
</span><span class="cx"> 
</span><span class="cx"> #include &quot;DFGNode.h&quot;
</span><ins>+#include &quot;FTLState.h&quot;
</ins><span class="cx"> #include &quot;LinkBuffer.h&quot;
</span><span class="cx"> 
</span><span class="cx"> namespace JSC { namespace FTL {
</span><span class="lines">@@ -41,21 +42,19 @@
</span><span class="cx"> {
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-JSCall::JSCall(unsigned stackmapID, Node* node)
-    : JSCallBase(
-        node-&gt;op() == Construct ? CallLinkInfo::Construct : CallLinkInfo::Call,
-        node-&gt;origin.semantic)
</del><ins>+JSCall::JSCall(unsigned stackmapID, Node* node, CodeOrigin callSiteDescriptionOrigin)
+    : JSCallBase(node-&gt;op() == Construct ? CallLinkInfo::Construct : CallLinkInfo::Call, node-&gt;origin.semantic, callSiteDescriptionOrigin)
</ins><span class="cx">     , m_stackmapID(stackmapID)
</span><span class="cx">     , m_instructionOffset(0)
</span><span class="cx"> {
</span><span class="cx">     ASSERT(node-&gt;op() == Call || node-&gt;op() == Construct || node-&gt;op() == TailCallInlinedCaller);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void JSCall::emit(CCallHelpers&amp; jit, unsigned stackSizeForLocals)
</del><ins>+void JSCall::emit(CCallHelpers&amp; jit, State&amp; state)
</ins><span class="cx"> {
</span><del>-    JSCallBase::emit(jit);
</del><ins>+    JSCallBase::emit(jit, state);
</ins><span class="cx"> 
</span><del>-    jit.addPtr(CCallHelpers::TrustedImm32(- static_cast&lt;int64_t&gt;(stackSizeForLocals)), CCallHelpers::framePointerRegister, CCallHelpers::stackPointerRegister);
</del><ins>+    jit.addPtr(CCallHelpers::TrustedImm32(- static_cast&lt;int64_t&gt;(state.jitCode-&gt;stackmaps.stackSizeForLocals())), CCallHelpers::framePointerRegister, CCallHelpers::stackPointerRegister);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> } } // namespace JSC::FTL
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLJSCallh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ftl/FTLJSCall.h (191393 => 191394)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLJSCall.h        2015-10-21 18:42:06 UTC (rev 191393)
+++ trunk/Source/JavaScriptCore/ftl/FTLJSCall.h        2015-10-21 18:44:44 UTC (rev 191394)
</span><span class="lines">@@ -41,9 +41,9 @@
</span><span class="cx"> class JSCall : public JSCallBase {
</span><span class="cx"> public:
</span><span class="cx">     JSCall();
</span><del>-    JSCall(unsigned stackmapID, DFG::Node*);
</del><ins>+    JSCall(unsigned stackmapID, DFG::Node*, CodeOrigin callSiteDescriptionOrigin);
</ins><span class="cx"> 
</span><del>-    void emit(CCallHelpers&amp;, unsigned stackSizeForLocals);
</del><ins>+    void emit(CCallHelpers&amp;, State&amp;);
</ins><span class="cx">     
</span><span class="cx">     unsigned stackmapID() const { return m_stackmapID; }
</span><span class="cx">     
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLJSCallBasecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ftl/FTLJSCallBase.cpp (191393 => 191394)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLJSCallBase.cpp        2015-10-21 18:42:06 UTC (rev 191393)
+++ trunk/Source/JavaScriptCore/ftl/FTLJSCallBase.cpp        2015-10-21 18:44:44 UTC (rev 191394)
</span><span class="lines">@@ -29,6 +29,7 @@
</span><span class="cx"> #if ENABLE(FTL_JIT)
</span><span class="cx"> 
</span><span class="cx"> #include &quot;DFGNode.h&quot;
</span><ins>+#include &quot;FTLState.h&quot;
</ins><span class="cx"> #include &quot;LinkBuffer.h&quot;
</span><span class="cx"> 
</span><span class="cx"> namespace JSC { namespace FTL {
</span><span class="lines">@@ -41,15 +42,19 @@
</span><span class="cx"> {
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-JSCallBase::JSCallBase(CallLinkInfo::CallType type, CodeOrigin origin)
</del><ins>+JSCallBase::JSCallBase(CallLinkInfo::CallType type, CodeOrigin semantic, CodeOrigin callSiteDescription)
</ins><span class="cx">     : m_type(type)
</span><del>-    , m_origin(origin)
</del><ins>+    , m_semanticeOrigin(semantic)
+    , m_callSiteDescriptionOrigin(callSiteDescription)
</ins><span class="cx">     , m_callLinkInfo(nullptr)
</span><span class="cx"> {
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void JSCallBase::emit(CCallHelpers&amp; jit)
</del><ins>+void JSCallBase::emit(CCallHelpers&amp; jit, State&amp; state)
</ins><span class="cx"> {
</span><ins>+    CallSiteIndex callSiteIndex = state.jitCode-&gt;common.addUniqueCallSiteIndex(m_callSiteDescriptionOrigin);
+    jit.store32(CCallHelpers::TrustedImm32(callSiteIndex.bits()), CCallHelpers::tagFor(static_cast&lt;VirtualRegister&gt;(JSStack::ArgumentCount)));
+
</ins><span class="cx">     m_callLinkInfo = jit.codeBlock()-&gt;addCallLinkInfo();
</span><span class="cx">     
</span><span class="cx">     if (CallLinkInfo::callModeFor(m_type) == CallMode::Tail)
</span><span class="lines">@@ -79,7 +84,7 @@
</span><span class="cx">     else
</span><span class="cx">         done.link(&amp;jit);
</span><span class="cx"> 
</span><del>-    m_callLinkInfo-&gt;setUpCall(m_type, m_origin, GPRInfo::regT0);
</del><ins>+    m_callLinkInfo-&gt;setUpCall(m_type, m_semanticeOrigin, GPRInfo::regT0);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void JSCallBase::link(VM&amp; vm, LinkBuffer&amp; linkBuffer)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLJSCallBaseh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ftl/FTLJSCallBase.h (191393 => 191394)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLJSCallBase.h        2015-10-21 18:42:06 UTC (rev 191393)
+++ trunk/Source/JavaScriptCore/ftl/FTLJSCallBase.h        2015-10-21 18:44:44 UTC (rev 191394)
</span><span class="lines">@@ -42,17 +42,20 @@
</span><span class="cx"> 
</span><span class="cx"> namespace FTL {
</span><span class="cx"> 
</span><ins>+class State;
+
</ins><span class="cx"> class JSCallBase {
</span><span class="cx"> public:
</span><span class="cx">     JSCallBase();
</span><del>-    JSCallBase(CallLinkInfo::CallType, CodeOrigin);
</del><ins>+    JSCallBase(CallLinkInfo::CallType, CodeOrigin semantic, CodeOrigin callSiteDescription);
</ins><span class="cx">     
</span><del>-    void emit(CCallHelpers&amp;);
</del><ins>+    void emit(CCallHelpers&amp;, State&amp;);
</ins><span class="cx">     void link(VM&amp;, LinkBuffer&amp;);
</span><span class="cx">     
</span><span class="cx"> protected:
</span><span class="cx">     CallLinkInfo::CallType m_type;
</span><del>-    CodeOrigin m_origin;
</del><ins>+    CodeOrigin m_semanticeOrigin;
+    CodeOrigin m_callSiteDescriptionOrigin; // These two code origins may be different with tail calls under some circumstances of inlining. See relevant comment in LowerDFGToLLVM.
</ins><span class="cx">     CCallHelpers::DataLabelPtr m_targetToCheck;
</span><span class="cx">     CCallHelpers::Call m_fastCall;
</span><span class="cx">     CCallHelpers::Call m_slowCall;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLJSCallVarargscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ftl/FTLJSCallVarargs.cpp (191393 => 191394)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLJSCallVarargs.cpp        2015-10-21 18:42:06 UTC (rev 191393)
+++ trunk/Source/JavaScriptCore/ftl/FTLJSCallVarargs.cpp        2015-10-21 18:44:44 UTC (rev 191394)
</span><span class="lines">@@ -30,6 +30,7 @@
</span><span class="cx"> 
</span><span class="cx"> #include &quot;DFGNode.h&quot;
</span><span class="cx"> #include &quot;DFGOperations.h&quot;
</span><ins>+#include &quot;FTLState.h&quot;
</ins><span class="cx"> #include &quot;JSCInlines.h&quot;
</span><span class="cx"> #include &quot;LinkBuffer.h&quot;
</span><span class="cx"> #include &quot;ScratchRegisterAllocator.h&quot;
</span><span class="lines">@@ -46,14 +47,14 @@
</span><span class="cx"> {
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-JSCallVarargs::JSCallVarargs(unsigned stackmapID, Node* node)
</del><ins>+JSCallVarargs::JSCallVarargs(unsigned stackmapID, Node* node, CodeOrigin callSiteDescriptionOrigin)
</ins><span class="cx">     : m_stackmapID(stackmapID)
</span><span class="cx">     , m_node(node)
</span><span class="cx">     , m_callBase(
</span><span class="cx">         (node-&gt;op() == ConstructVarargs || node-&gt;op() == ConstructForwardVarargs)
</span><span class="cx">         ? CallLinkInfo::ConstructVarargs : (node-&gt;op() == TailCallVarargs || node-&gt;op() == TailCallForwardVarargs)
</span><span class="cx">         ? CallLinkInfo::TailCallVarargs : CallLinkInfo::CallVarargs,
</span><del>-        node-&gt;origin.semantic)
</del><ins>+        node-&gt;origin.semantic, callSiteDescriptionOrigin)
</ins><span class="cx">     , m_instructionOffset(0)
</span><span class="cx"> {
</span><span class="cx">     ASSERT(
</span><span class="lines">@@ -68,7 +69,7 @@
</span><span class="cx">     return 4;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void JSCallVarargs::emit(CCallHelpers&amp; jit, int32_t spillSlotsOffset)
</del><ins>+void JSCallVarargs::emit(CCallHelpers&amp; jit, State&amp; state, int32_t spillSlotsOffset)
</ins><span class="cx"> {
</span><span class="cx">     // We are passed three pieces of information:
</span><span class="cx">     // - The callee.
</span><span class="lines">@@ -204,7 +205,7 @@
</span><span class="cx">     // stack frame to already be set up, which it is.
</span><span class="cx">     jit.store64(GPRInfo::regT0, CCallHelpers::calleeFrameSlot(JSStack::Callee));
</span><span class="cx"> 
</span><del>-    m_callBase.emit(jit);
</del><ins>+    m_callBase.emit(jit, state);
</ins><span class="cx">     
</span><span class="cx">     // Undo the damage we've done.
</span><span class="cx">     if (isARM64()) {
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLJSCallVarargsh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ftl/FTLJSCallVarargs.h (191393 => 191394)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLJSCallVarargs.h        2015-10-21 18:42:06 UTC (rev 191393)
+++ trunk/Source/JavaScriptCore/ftl/FTLJSCallVarargs.h        2015-10-21 18:44:44 UTC (rev 191394)
</span><span class="lines">@@ -43,13 +43,13 @@
</span><span class="cx"> class JSCallVarargs {
</span><span class="cx"> public:
</span><span class="cx">     JSCallVarargs();
</span><del>-    JSCallVarargs(unsigned stackmapID, DFG::Node*);
</del><ins>+    JSCallVarargs(unsigned stackmapID, DFG::Node*, CodeOrigin callSiteDescriptionOrigin);
</ins><span class="cx">     
</span><span class="cx">     DFG::Node* node() const { return m_node; }
</span><span class="cx">     
</span><span class="cx">     static unsigned numSpillSlotsNeeded();
</span><span class="cx">     
</span><del>-    void emit(CCallHelpers&amp;, int32_t spillSlotsOffset);
</del><ins>+    void emit(CCallHelpers&amp;, State&amp;, int32_t spillSlotsOffset);
</ins><span class="cx">     void link(VM&amp;, LinkBuffer&amp;, CodeLocationLabel exceptionHandler);
</span><span class="cx">     
</span><span class="cx">     unsigned stackmapID() const { return m_stackmapID; }
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLJSTailCallcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ftl/FTLJSTailCall.cpp (191393 => 191394)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLJSTailCall.cpp        2015-10-21 18:42:06 UTC (rev 191393)
+++ trunk/Source/JavaScriptCore/ftl/FTLJSTailCall.cpp        2015-10-21 18:44:44 UTC (rev 191394)
</span><span class="lines">@@ -179,7 +179,7 @@
</span><span class="cx"> } // anonymous namespace
</span><span class="cx"> 
</span><span class="cx"> JSTailCall::JSTailCall(unsigned stackmapID, Node* node, Vector&lt;ExitValue&gt; arguments)
</span><del>-    : JSCallBase(CallLinkInfo::TailCall, node-&gt;origin.semantic)
</del><ins>+    : JSCallBase(CallLinkInfo::TailCall, node-&gt;origin.semantic, node-&gt;origin.semantic)
</ins><span class="cx">     , m_stackmapID(stackmapID)
</span><span class="cx">     , m_arguments { WTF::move(arguments) }
</span><span class="cx">     , m_instructionOffset(0)
</span><span class="lines">@@ -318,7 +318,7 @@
</span><span class="cx"> 
</span><span class="cx">     jit.abortWithReason(JITDidReturnFromTailCall);
</span><span class="cx"> 
</span><del>-    m_callLinkInfo-&gt;setUpCall(m_type, m_origin, calleeGPR);
</del><ins>+    m_callLinkInfo-&gt;setUpCall(m_type, m_semanticeOrigin, calleeGPR);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> } } // namespace JSC::FTL
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLLowerDFGToLLVMcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp (191393 => 191394)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp        2015-10-21 18:42:06 UTC (rev 191393)
+++ trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp        2015-10-21 18:44:44 UTC (rev 191394)
</span><span class="lines">@@ -4462,12 +4462,10 @@
</span><span class="cx">         for (unsigned i = 0; i &lt; padding; ++i)
</span><span class="cx">             arguments.append(getUndef(m_out.int64));
</span><span class="cx">         
</span><del>-        callPreflight();
-        
</del><span class="cx">         LValue call = m_out.call(m_out.patchpointInt64Intrinsic(), arguments);
</span><span class="cx">         setInstructionCallingConvention(call, LLVMWebKitJSCallConv);
</span><span class="cx">         
</span><del>-        m_ftlState.jsCalls.append(JSCall(stackmapID, m_node));
</del><ins>+        m_ftlState.jsCalls.append(JSCall(stackmapID, m_node, codeOriginDescriptionOfCallSite()));
</ins><span class="cx">         
</span><span class="cx">         setJSValue(call);
</span><span class="cx">     }
</span><span class="lines">@@ -4544,12 +4542,10 @@
</span><span class="cx">         ASSERT(thisArg);
</span><span class="cx">         arguments.append(thisArg);
</span><span class="cx">         
</span><del>-        callPreflight();
-        
</del><span class="cx">         LValue call = m_out.call(m_out.patchpointInt64Intrinsic(), arguments);
</span><span class="cx">         setInstructionCallingConvention(call, LLVMCCallConv);
</span><span class="cx">         
</span><del>-        m_ftlState.jsCallVarargses.append(JSCallVarargs(stackmapID, m_node));
</del><ins>+        m_ftlState.jsCallVarargses.append(JSCallVarargs(stackmapID, m_node, codeOriginDescriptionOfCallSite()));
</ins><span class="cx"> 
</span><span class="cx">         switch (m_node-&gt;op()) {
</span><span class="cx">         case TailCallVarargs:
</span><span class="lines">@@ -8665,16 +8661,27 @@
</span><span class="cx">                 m_ftlState.jitCode-&gt;common.addCodeOrigin(codeOrigin).bits()),
</span><span class="cx">             tagFor(JSStack::ArgumentCount));
</span><span class="cx">     }
</span><ins>+
</ins><span class="cx">     void callPreflight()
</span><span class="cx">     {
</span><ins>+        callPreflight(codeOriginDescriptionOfCallSite());
+    }
+
+    CodeOrigin codeOriginDescriptionOfCallSite() const
+    {
</ins><span class="cx">         CodeOrigin codeOrigin = m_node-&gt;origin.semantic;
</span><del>-
</del><span class="cx">         if (m_node-&gt;op() == TailCallInlinedCaller
</span><span class="cx">             || m_node-&gt;op() == TailCallVarargsInlinedCaller
</span><del>-            || m_node-&gt;op() == TailCallForwardVarargsInlinedCaller)
</del><ins>+            || m_node-&gt;op() == TailCallForwardVarargsInlinedCaller) {
+            // This case arises when you have a situation like this:
+            // foo makes a call to bar, bar is inlined in foo. bar makes a call
+            // to baz and baz is inlined in bar. And then baz makes a tail-call to jaz,
+            // and jaz is inlined in baz. We want the callframe for jaz to appear to 
+            // have caller be bar.
</ins><span class="cx">             codeOrigin = *codeOrigin.inlineCallFrame-&gt;getCallerSkippingDeadFrames();
</span><ins>+        }
</ins><span class="cx"> 
</span><del>-        callPreflight(codeOrigin);
</del><ins>+        return codeOrigin;
</ins><span class="cx">     }
</span><span class="cx">     
</span><span class="cx">     void callCheck()
</span></span></pre>
</div>
</div>

</body>
</html>