<!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>[191360] 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/191360">191360</a></dd>
<dt>Author</dt> <dd>msaboff@apple.com</dd>
<dt>Date</dt> <dd>2015-10-20 15:02:37 -0700 (Tue, 20 Oct 2015)</dd>
</dl>

<h3>Log Message</h3>
<pre>REGRESSION (<a href="http://trac.webkit.org/projects/webkit/changeset/191175">r191175</a>): OSR Exit from an inlined tail callee trashes callee save registers
https://bugs.webkit.org/show_bug.cgi?id=150336

Reviewed by Mark Lam.

Source/JavaScriptCore:

During OSR exit, we need to restore and transform the active stack into what the baseline
JIT expects.  Inlined call frames become true call frames.  When we reify an inlined call
frame and it is a tail call which we will be continuing from, we need to restore the tag
constant callee save registers with what was saved by the outermost caller.

Re-enabled tail calls and restored tests for tail calls.

* dfg/DFGOSRExitCompilerCommon.cpp:
(JSC::DFG::reifyInlinedCallFrames): Select whether or not we use the callee save tag register
contents or what was saved by the inlining caller when populating an inlined callee's
callee save registers.
* jit/AssemblyHelpers.h:
(JSC::AssemblyHelpers::emitSaveCalleeSavesFor): This function no longer needs a stack offset.
(JSC::AssemblyHelpers::emitSaveOrCopyCalleeSavesFor): New helper.
* runtime/Options.h: Turned tail calls back on.
* tests/es6.yaml:
* tests/stress/dfg-tail-calls.js:
(nonInlinedTailCall.callee):
* tests/stress/mutual-tail-call-no-stack-overflow.js:
(shouldThrow):
* tests/stress/tail-call-in-inline-cache.js:
(tail):
* tests/stress/tail-call-no-stack-overflow.js:
(shouldThrow):
* tests/stress/tail-call-recognize.js:
(callerMustBeRun):
* tests/stress/tail-call-varargs-no-stack-overflow.js:
(shouldThrow):

LayoutTests:

Added a new regression test and restored tail call test results for js/caller-property.

* js/caller-property-expected.txt:
* js/regress-150336-expected.txt: Added.
* js/regress-150336.html: Added.
* js/script-tests/regress-150336.js: Added.
(bar):
(foo):
(test):</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsChangeLog">trunk/LayoutTests/ChangeLog</a></li>
<li><a href="#trunkLayoutTestsjscallerpropertyexpectedtxt">trunk/LayoutTests/js/caller-property-expected.txt</a></li>
<li><a href="#trunkSourceJavaScriptCoreChangeLog">trunk/Source/JavaScriptCore/ChangeLog</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGOSRExitCompilerCommoncpp">trunk/Source/JavaScriptCore/dfg/DFGOSRExitCompilerCommon.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorejitAssemblyHelpersh">trunk/Source/JavaScriptCore/jit/AssemblyHelpers.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeOptionsh">trunk/Source/JavaScriptCore/runtime/Options.h</a></li>
<li><a href="#trunkSourceJavaScriptCoretestses6yaml">trunk/Source/JavaScriptCore/tests/es6.yaml</a></li>
<li><a href="#trunkSourceJavaScriptCoretestsstressdfgtailcallsjs">trunk/Source/JavaScriptCore/tests/stress/dfg-tail-calls.js</a></li>
<li><a href="#trunkSourceJavaScriptCoretestsstressmutualtailcallnostackoverflowjs">trunk/Source/JavaScriptCore/tests/stress/mutual-tail-call-no-stack-overflow.js</a></li>
<li><a href="#trunkSourceJavaScriptCoretestsstresstailcallininlinecachejs">trunk/Source/JavaScriptCore/tests/stress/tail-call-in-inline-cache.js</a></li>
<li><a href="#trunkSourceJavaScriptCoretestsstresstailcallnostackoverflowjs">trunk/Source/JavaScriptCore/tests/stress/tail-call-no-stack-overflow.js</a></li>
<li><a href="#trunkSourceJavaScriptCoretestsstresstailcallrecognizejs">trunk/Source/JavaScriptCore/tests/stress/tail-call-recognize.js</a></li>
<li><a href="#trunkSourceJavaScriptCoretestsstresstailcallvarargsnostackoverflowjs">trunk/Source/JavaScriptCore/tests/stress/tail-call-varargs-no-stack-overflow.js</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsjsregress150336expectedtxt">trunk/LayoutTests/js/regress-150336-expected.txt</a></li>
<li><a href="#trunkLayoutTestsjsregress150336html">trunk/LayoutTests/js/regress-150336.html</a></li>
<li><a href="#trunkLayoutTestsjsscripttestsregress150336js">trunk/LayoutTests/js/script-tests/regress-150336.js</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkLayoutTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/ChangeLog (191359 => 191360)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/ChangeLog        2015-10-20 22:00:24 UTC (rev 191359)
+++ trunk/LayoutTests/ChangeLog        2015-10-20 22:02:37 UTC (rev 191360)
</span><span class="lines">@@ -1,3 +1,20 @@
</span><ins>+2015-10-20  Michael Saboff  &lt;msaboff@apple.com&gt;
+
+        REGRESSION (r191175): OSR Exit from an inlined tail callee trashes callee save registers
+        https://bugs.webkit.org/show_bug.cgi?id=150336
+
+        Reviewed by Mark Lam.
+
+        Added a new regression test and restored tail call test results for js/caller-property.
+
+        * js/caller-property-expected.txt:
+        * js/regress-150336-expected.txt: Added.
+        * js/regress-150336.html: Added.
+        * js/script-tests/regress-150336.js: Added.
+        (bar):
+        (foo):
+        (test):
+
</ins><span class="cx"> 2015-10-20  Ryan Haddad  &lt;ryanhaddad@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Take 2 on rebaselining fast/dynamic/insert-before-table-part-in-continuation.html
</span></span></pre></div>
<a id="trunkLayoutTestsjscallerpropertyexpectedtxt"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/js/caller-property-expected.txt (191359 => 191360)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/caller-property-expected.txt        2015-10-20 22:00:24 UTC (rev 191359)
+++ trunk/LayoutTests/js/caller-property-expected.txt        2015-10-20 22:02:37 UTC (rev 191360)
</span><span class="lines">@@ -10,13 +10,13 @@
</span><span class="cx"> PASS nonStrictCaller(strictCallee) threw exception TypeError: Type error.
</span><span class="cx"> PASS strictCaller(nonStrictCallee) threw exception TypeError: Function.caller used to retrieve strict caller.
</span><span class="cx"> PASS strictCaller(strictCallee) threw exception TypeError: Type error.
</span><del>-FAIL strictTailCaller(nonStrictCallee) should be null. Threw exception TypeError: Function.caller used to retrieve strict caller
</del><ins>+PASS strictTailCaller(nonStrictCallee) is null
</ins><span class="cx"> PASS strictTailCaller(strictCallee) threw exception TypeError: Type error.
</span><span class="cx"> PASS nonStrictCaller(boundNonStrictCallee) is nonStrictCaller
</span><span class="cx"> PASS nonStrictCaller(boundStrictCallee) threw exception TypeError: Type error.
</span><span class="cx"> PASS strictCaller(boundNonStrictCallee) threw exception TypeError: Function.caller used to retrieve strict caller.
</span><span class="cx"> PASS strictCaller(boundStrictCallee) threw exception TypeError: Type error.
</span><del>-FAIL strictTailCaller(boundNonStrictCallee) should be null. Threw exception TypeError: Function.caller used to retrieve strict caller
</del><ins>+PASS strictTailCaller(boundNonStrictCallee) is null
</ins><span class="cx"> PASS strictTailCaller(boundStrictCallee) threw exception TypeError: Type error.
</span><span class="cx"> PASS nonStrictGetter(nonStrictAccessor) is nonStrictGetter
</span><span class="cx"> PASS nonStrictSetter(nonStrictAccessor) is true
</span></span></pre></div>
<a id="trunkLayoutTestsjsregress150336expectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/js/regress-150336-expected.txt (0 => 191360)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/regress-150336-expected.txt                                (rev 0)
+++ trunk/LayoutTests/js/regress-150336-expected.txt        2015-10-20 22:02:37 UTC (rev 191360)
</span><span class="lines">@@ -0,0 +1,10 @@
</span><ins>+Regression test for https://webkit.org/b/150336.
+
+On success, you will see a series of &quot;PASS&quot; messages, followed by &quot;TEST COMPLETE&quot;.
+
+
+PASS Properly handled OSR exit from a bound function with an inlined tail callee.
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
</ins></span></pre></div>
<a id="trunkLayoutTestsjsregress150336html"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/js/regress-150336.html (0 => 191360)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/regress-150336.html                                (rev 0)
+++ trunk/LayoutTests/js/regress-150336.html        2015-10-20 22:02:37 UTC (rev 191360)
</span><span class="lines">@@ -0,0 +1,10 @@
</span><ins>+&lt;!DOCTYPE HTML PUBLIC &quot;-//IETF//DTD HTML//EN&quot;&gt;
+&lt;html&gt;
+&lt;head&gt;
+&lt;script src=&quot;../resources/js-test-pre.js&quot;&gt;&lt;/script&gt;
+&lt;/head&gt;
+&lt;body&gt;
+&lt;script src=&quot;script-tests/regress-150336.js&quot;&gt;&lt;/script&gt;
+&lt;script src=&quot;../resources/js-test-post.js&quot;&gt;&lt;/script&gt;
+&lt;/body&gt;
+&lt;/html&gt;
</ins></span></pre></div>
<a id="trunkLayoutTestsjsscripttestsregress150336js"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/js/script-tests/regress-150336.js (0 => 191360)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/script-tests/regress-150336.js                                (rev 0)
+++ trunk/LayoutTests/js/script-tests/regress-150336.js        2015-10-20 22:02:37 UTC (rev 191360)
</span><span class="lines">@@ -0,0 +1,45 @@
</span><ins>+description(&quot;Regression test for https://webkit.org/b/150336.&quot;);
+
+// This test verifies that an OSR exit from a bound function with an inlined tail callee
+// properly transitions to the baseline JIT without crashing.
+
+myObj = {
+    val: 1
+}
+
+function bar(a, idx)
+{
+    &quot;use strict&quot;;
+
+    if (idx == 9900)
+        myObj.dfgOSR = &quot;Test&quot;;
+
+    if (idx == 199900)
+        myObj.ftlOSR = &quot;Test&quot;;
+
+    return myObj.val + a;
+}
+
+function foo(a, idx)
+{
+    &quot;use strict&quot;;
+
+    return bar(a, idx);
+}
+
+boundFoo = foo.bind(null, 41);
+
+function test()
+{
+    for (var i = 0; i &lt; 200000; i++) {
+        got = boundFoo(i);
+        if (got != 42)
+            testFailed(&quot;Function returned &quot; + got + &quot; but expected 42!&quot;);
+    }
+}
+
+noInline(test);
+
+test();
+
+testPassed(&quot;Properly handled OSR exit from a bound function with an inlined tail callee.&quot;);
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ChangeLog (191359 => 191360)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ChangeLog        2015-10-20 22:00:24 UTC (rev 191359)
+++ trunk/Source/JavaScriptCore/ChangeLog        2015-10-20 22:02:37 UTC (rev 191360)
</span><span class="lines">@@ -1,3 +1,39 @@
</span><ins>+2015-10-20  Michael Saboff  &lt;msaboff@apple.com&gt;
+
+        REGRESSION (r191175): OSR Exit from an inlined tail callee trashes callee save registers
+        https://bugs.webkit.org/show_bug.cgi?id=150336
+
+        Reviewed by Mark Lam.
+
+        During OSR exit, we need to restore and transform the active stack into what the baseline
+        JIT expects.  Inlined call frames become true call frames.  When we reify an inlined call
+        frame and it is a tail call which we will be continuing from, we need to restore the tag
+        constant callee save registers with what was saved by the outermost caller.
+
+        Re-enabled tail calls and restored tests for tail calls.
+
+        * dfg/DFGOSRExitCompilerCommon.cpp:
+        (JSC::DFG::reifyInlinedCallFrames): Select whether or not we use the callee save tag register
+        contents or what was saved by the inlining caller when populating an inlined callee's
+        callee save registers.
+        * jit/AssemblyHelpers.h:
+        (JSC::AssemblyHelpers::emitSaveCalleeSavesFor): This function no longer needs a stack offset.
+        (JSC::AssemblyHelpers::emitSaveOrCopyCalleeSavesFor): New helper.
+        * runtime/Options.h: Turned tail calls back on.
+        * tests/es6.yaml:
+        * tests/stress/dfg-tail-calls.js:
+        (nonInlinedTailCall.callee):
+        * tests/stress/mutual-tail-call-no-stack-overflow.js:
+        (shouldThrow):
+        * tests/stress/tail-call-in-inline-cache.js:
+        (tail):
+        * tests/stress/tail-call-no-stack-overflow.js:
+        (shouldThrow):
+        * tests/stress/tail-call-recognize.js:
+        (callerMustBeRun):
+        * tests/stress/tail-call-varargs-no-stack-overflow.js:
+        (shouldThrow):
+
</ins><span class="cx"> 2015-10-20  Joseph Pecoraro  &lt;pecoraro@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Web Inspector: JavaScriptCore should parse sourceURL and sourceMappingURL directives
</span><span class="lines">@@ -68,6 +104,7 @@
</span><span class="cx">         (JSC::GCAwareJITStubRoutineWithExceptionHandler::~GCAwareJITStubRoutineWithExceptionHandler): Deleted.
</span><span class="cx">         * jit/GCAwareJITStubRoutine.h:
</span><span class="cx"> 
</span><ins>+&gt;&gt;&gt;&gt;&gt;&gt;&gt; .r191351
</ins><span class="cx"> 2015-10-20  Tim Horton  &lt;timothy_horton@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Try to fix the build by disabling MAC_GESTURE_EVENTS on 10.9 and 10.10
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGOSRExitCompilerCommoncpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGOSRExitCompilerCommon.cpp (191359 => 191360)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGOSRExitCompilerCommon.cpp        2015-10-20 22:00:24 UTC (rev 191359)
+++ trunk/Source/JavaScriptCore/dfg/DFGOSRExitCompilerCommon.cpp        2015-10-20 22:02:37 UTC (rev 191360)
</span><span class="lines">@@ -214,7 +214,16 @@
</span><span class="cx">             jit.storePtr(AssemblyHelpers::TrustedImmPtr(trueReturnPC), AssemblyHelpers::addressFor(inlineCallFrame-&gt;stackOffset + virtualRegisterForArgument(inlineCallFrame-&gt;arguments.size()).offset()));
</span><span class="cx">                          
</span><span class="cx">         jit.storePtr(AssemblyHelpers::TrustedImmPtr(baselineCodeBlock), AssemblyHelpers::addressFor((VirtualRegister)(inlineCallFrame-&gt;stackOffset + JSStack::CodeBlock)));
</span><del>-        jit.emitSaveCalleeSavesFor(baselineCodeBlock, static_cast&lt;VirtualRegister&gt;(inlineCallFrame-&gt;stackOffset));
</del><ins>+
+        // Restore the inline call frame's callee save registers.
+        // If this inlined frame is a tail call that will return back to the original caller, we need to
+        // copy the prior contents of the tag registers already saved for the outer frame to this frame.
+        jit.emitSaveOrCopyCalleeSavesFor(
+            baselineCodeBlock,
+            static_cast&lt;VirtualRegister&gt;(inlineCallFrame-&gt;stackOffset),
+            trueCaller ? AssemblyHelpers::UseExistingTagRegisterContents : AssemblyHelpers::CopySavedTagRegistersFromBaseFrame,
+            GPRInfo::regT2);
+
</ins><span class="cx">         if (!inlineCallFrame-&gt;isVarargs())
</span><span class="cx">             jit.store32(AssemblyHelpers::TrustedImm32(inlineCallFrame-&gt;arguments.size()), AssemblyHelpers::payloadFor((VirtualRegister)(inlineCallFrame-&gt;stackOffset + JSStack::ArgumentCount)));
</span><span class="cx"> #if USE(JSVALUE64)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitAssemblyHelpersh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/AssemblyHelpers.h (191359 => 191360)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/AssemblyHelpers.h        2015-10-20 22:00:24 UTC (rev 191359)
+++ trunk/Source/JavaScriptCore/jit/AssemblyHelpers.h        2015-10-20 22:02:37 UTC (rev 191360)
</span><span class="lines">@@ -178,7 +178,7 @@
</span><span class="cx"> #endif
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    void emitSaveCalleeSavesFor(CodeBlock* codeBlock, VirtualRegister offsetVirtualRegister = static_cast&lt;VirtualRegister&gt;(0))
</del><ins>+    void emitSaveCalleeSavesFor(CodeBlock* codeBlock)
</ins><span class="cx">     {
</span><span class="cx">         ASSERT(codeBlock);
</span><span class="cx"> 
</span><span class="lines">@@ -190,10 +190,43 @@
</span><span class="cx">             RegisterAtOffset entry = calleeSaves-&gt;at(i);
</span><span class="cx">             if (dontSaveRegisters.get(entry.reg()))
</span><span class="cx">                 continue;
</span><del>-            storePtr(entry.reg().gpr(), Address(framePointerRegister, offsetVirtualRegister.offsetInBytes() + entry.offset()));
</del><ins>+            storePtr(entry.reg().gpr(), Address(framePointerRegister, entry.offset()));
</ins><span class="cx">         }
</span><span class="cx">     }
</span><ins>+    
+    enum RestoreTagRegisterMode { UseExistingTagRegisterContents, CopySavedTagRegistersFromBaseFrame };
</ins><span class="cx"> 
</span><ins>+    void emitSaveOrCopyCalleeSavesFor(CodeBlock* codeBlock, VirtualRegister offsetVirtualRegister, RestoreTagRegisterMode tagRegisterMode, GPRReg temp)
+    {
+        ASSERT(codeBlock);
+        
+        RegisterAtOffsetList* calleeSaves = codeBlock-&gt;calleeSaveRegisters();
+        RegisterSet dontSaveRegisters = RegisterSet(RegisterSet::stackRegisters(), RegisterSet::allFPRs());
+        unsigned registerCount = calleeSaves-&gt;size();
+        
+        for (unsigned i = 0; i &lt; registerCount; i++) {
+            RegisterAtOffset entry = calleeSaves-&gt;at(i);
+            if (dontSaveRegisters.get(entry.reg()))
+                continue;
+            
+            GPRReg registerToWrite;
+            
+#if USE(JSVALUE32_64)
+            UNUSED_PARAM(tagRegisterMode);
+            UNUSED_PARAM(temp);
+#else
+            if (tagRegisterMode == CopySavedTagRegistersFromBaseFrame
+                &amp;&amp; (entry.reg() == GPRInfo::tagTypeNumberRegister || entry.reg() == GPRInfo::tagMaskRegister)) {
+                registerToWrite = temp;
+                loadPtr(AssemblyHelpers::Address(GPRInfo::callFrameRegister, entry.offset()), registerToWrite);
+            } else
+#endif
+                registerToWrite = entry.reg().gpr();
+
+            storePtr(registerToWrite, Address(framePointerRegister, offsetVirtualRegister.offsetInBytes() + entry.offset()));
+        }
+    }
+    
</ins><span class="cx">     void emitRestoreCalleeSavesFor(CodeBlock* codeBlock)
</span><span class="cx">     {
</span><span class="cx">         ASSERT(codeBlock);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeOptionsh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/Options.h (191359 => 191360)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/Options.h        2015-10-20 22:00:24 UTC (rev 191359)
+++ trunk/Source/JavaScriptCore/runtime/Options.h        2015-10-20 22:02:37 UTC (rev 191360)
</span><span class="lines">@@ -131,7 +131,7 @@
</span><span class="cx">     v(bool, forceProfilerBytecodeGeneration, false, nullptr) \
</span><span class="cx">     \
</span><span class="cx">     v(bool, useFunctionDotArguments, true, nullptr) \
</span><del>-    v(bool, useTailCalls, false, nullptr) \
</del><ins>+    v(bool, useTailCalls, true, nullptr) \
</ins><span class="cx">     \
</span><span class="cx">     /* dumpDisassembly implies dumpDFGDisassembly. */ \
</span><span class="cx">     v(bool, dumpDisassembly, false, &quot;dumps disassembly of all JIT compiled code upon compilation&quot;) \
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoretestses6yaml"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/tests/es6.yaml (191359 => 191360)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/tests/es6.yaml        2015-10-20 22:00:24 UTC (rev 191359)
+++ trunk/Source/JavaScriptCore/tests/es6.yaml        2015-10-20 22:02:37 UTC (rev 191360)
</span><span class="lines">@@ -879,9 +879,9 @@
</span><span class="cx"> - path: es6/Promise_Promise[Symbol.species].js
</span><span class="cx">   cmd: runES6 :fail
</span><span class="cx"> - path: es6/proper_tail_calls_tail_call_optimisation_direct_recursion.js
</span><del>-  cmd: runES6 :fail
</del><ins>+  cmd: runES6 :normal
</ins><span class="cx"> - path: es6/proper_tail_calls_tail_call_optimisation_mutual_recursion.js
</span><del>-  cmd: runES6 :fail
</del><ins>+  cmd: runES6 :normal
</ins><span class="cx"> - path: es6/prototype_of_bound_functions_arrow_functions.js
</span><span class="cx">   cmd: runES6 :fail
</span><span class="cx"> - path: es6/prototype_of_bound_functions_basic_functions.js
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoretestsstressdfgtailcallsjs"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/tests/stress/dfg-tail-calls.js (191359 => 191360)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/tests/stress/dfg-tail-calls.js        2015-10-20 22:00:24 UTC (rev 191359)
+++ trunk/Source/JavaScriptCore/tests/stress/dfg-tail-calls.js        2015-10-20 22:02:37 UTC (rev 191360)
</span><span class="lines">@@ -1,4 +1,3 @@
</span><del>-//@ skip
</del><span class="cx"> (function nonInlinedTailCall() {
</span><span class="cx">     function callee() { if (callee.caller != nonInlinedTailCall) throw new Error(); }
</span><span class="cx">     noInline(callee);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoretestsstressmutualtailcallnostackoverflowjs"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/tests/stress/mutual-tail-call-no-stack-overflow.js (191359 => 191360)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/tests/stress/mutual-tail-call-no-stack-overflow.js        2015-10-20 22:00:24 UTC (rev 191359)
+++ trunk/Source/JavaScriptCore/tests/stress/mutual-tail-call-no-stack-overflow.js        2015-10-20 22:02:37 UTC (rev 191360)
</span><span class="lines">@@ -1,4 +1,3 @@
</span><del>-//@ skip
</del><span class="cx"> function shouldThrow(func, errorMessage) {
</span><span class="cx">     var errorThrown = false;
</span><span class="cx">     var error = null;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoretestsstresstailcallininlinecachejs"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/tests/stress/tail-call-in-inline-cache.js (191359 => 191360)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/tests/stress/tail-call-in-inline-cache.js        2015-10-20 22:00:24 UTC (rev 191359)
+++ trunk/Source/JavaScriptCore/tests/stress/tail-call-in-inline-cache.js        2015-10-20 22:02:37 UTC (rev 191360)
</span><span class="lines">@@ -1,4 +1,3 @@
</span><del>-//@ skip
</del><span class="cx"> &quot;use strict&quot;;
</span><span class="cx"> 
</span><span class="cx"> function tail() { }
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoretestsstresstailcallnostackoverflowjs"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/tests/stress/tail-call-no-stack-overflow.js (191359 => 191360)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/tests/stress/tail-call-no-stack-overflow.js        2015-10-20 22:00:24 UTC (rev 191359)
+++ trunk/Source/JavaScriptCore/tests/stress/tail-call-no-stack-overflow.js        2015-10-20 22:02:37 UTC (rev 191360)
</span><span class="lines">@@ -1,4 +1,3 @@
</span><del>-//@ skip
</del><span class="cx"> function shouldThrow(func, errorMessage) {
</span><span class="cx">     var errorThrown = false;
</span><span class="cx">     var error = null;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoretestsstresstailcallrecognizejs"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/tests/stress/tail-call-recognize.js (191359 => 191360)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/tests/stress/tail-call-recognize.js        2015-10-20 22:00:24 UTC (rev 191359)
+++ trunk/Source/JavaScriptCore/tests/stress/tail-call-recognize.js        2015-10-20 22:02:37 UTC (rev 191360)
</span><span class="lines">@@ -1,4 +1,3 @@
</span><del>-//@ skip
</del><span class="cx"> function callerMustBeRun() {
</span><span class="cx">     if (!Object.is(callerMustBeRun.caller, runTests))
</span><span class="cx">         throw Error(&quot;Wrong caller, expected run but got &quot;, callerMustBeRun.caller);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoretestsstresstailcallvarargsnostackoverflowjs"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/tests/stress/tail-call-varargs-no-stack-overflow.js (191359 => 191360)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/tests/stress/tail-call-varargs-no-stack-overflow.js        2015-10-20 22:00:24 UTC (rev 191359)
+++ trunk/Source/JavaScriptCore/tests/stress/tail-call-varargs-no-stack-overflow.js        2015-10-20 22:02:37 UTC (rev 191360)
</span><span class="lines">@@ -1,4 +1,3 @@
</span><del>-//@ skip
</del><span class="cx"> function shouldThrow(func, errorMessage) {
</span><span class="cx">     var errorThrown = false;
</span><span class="cx">     var error = null;
</span></span></pre>
</div>
</div>

</body>
</html>