<!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>[187639] branches/jsc-tailcall/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/187639">187639</a></dd>
<dt>Author</dt> <dd>msaboff@apple.com</dd>
<dt>Date</dt> <dd>2015-07-30 23:02:40 -0700 (Thu, 30 Jul 2015)</dd>
</dl>

<h3>Log Message</h3>
<pre>jsc-tailcall: LLint, Baseline and DFG JIT should save &amp; restore platform's callee-save registers
https://bugs.webkit.org/show_bug.cgi?id=146946

Reviewed by Basile Clement.

We save platform callee save registers right below the call frame header, in the location(s)
starting with VirtualRegister 0.  Allocated local space in the bytecode compiler.
This space is the maximum space needed for the callee registers that the LLInt or baseline JIT
will used, rounded up to number of VirtualRegisters.  The LLInt explicitly saves and restores
the registers in the functions preserveCalleeSavesUsedByLLInt and restoreCalleeSavesUsedByLLInt.
The baseline and DFG JITs saves and restores callee saves registers by what registers are included
in m_calleeSaveRegisters in the code block.

Added code to transition callee saves from one VM's format to the another as part of OSR entry and
OSR exit.  Added a helper class RegisterSaveMap that has the cannonical locations for a set of
saved registers.  This is used not only to save and restore registers on function entry and exit,
but also to handle OSR entry and exit cases.

* CMakeLists.txt:
* JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
* JavaScriptCore.xcodeproj/project.pbxproj:
Added RegisterSaveMap to build configurations.

* bytecode/CodeBlock.cpp:
(JSC::CodeBlock::setCalleeSaveRegisters):
(JSC::roundCalleeSaveSpaceAsVirtualRegisters):
(JSC::CodeBlock::llintBaselineCalleeSaveSpaceAsVirtualRegisters):
(JSC::CodeBlock::calleeSaveSpaceAsVirtualRegisters):
(JSC::CodeBlock::countReoptimization):
* bytecode/CodeBlock.h:
(JSC::CodeBlock::numberOfLLIntBaselineCalleeSaveRegisters):
(JSC::CodeBlock::calleeSaveRegisters):
(JSC::CodeBlock::llintBaselineCalleeSaveSpaceAsVirtualRegisters):
(JSC::CodeBlock::optimizeAfterWarmUp):
(JSC::CodeBlock::numberOfDFGCompiles):
Methods to manage a set of callee save registers.  Also to allocate the appropriate
number of VritualRegisters for callee saves.

* bytecompiler/BytecodeGenerator.cpp:
(JSC::BytecodeGenerator::allocateCalleeSaveSpace):
* bytecompiler/BytecodeGenerator.h:
Allocate the appropriate number of VritualRegisters for callee saves needed by LLInt or baseline JIT.

* dfg/DFGJITCompiler.cpp:
(JSC::DFG::JITCompiler::compileEntry):
(JSC::DFG::JITCompiler::compileSetupRegistersForEntry):
(JSC::DFG::JITCompiler::compileBody):
(JSC::DFG::JITCompiler::compile):
(JSC::DFG::JITCompiler::compileFunction):
* dfg/DFGJITCompiler.h:

* dfg/DFGOSREntry.cpp:
(JSC::DFG::prepareOSREntry):
* dfg/DFGOSRExitCompiler64.cpp:
(JSC::DFG::OSRExitCompiler::compileExit):
* dfg/DFGOSRExitCompilerCommon.cpp:
(JSC::DFG::reifyInlinedCallFrames):
(JSC::DFG::adjustAndJumpToTarget):
* dfg/DFGPlan.cpp:
(JSC::DFG::Plan::compileInThreadImpl):
* dfg/DFGSpeculativeJIT32_64.cpp:
(JSC::DFG::SpeculativeJIT::compile):
* dfg/DFGSpeculativeJIT64.cpp:
(JSC::DFG::SpeculativeJIT::compile):

* dfg/DFGStackLayoutPhase.cpp:
(JSC::DFG::StackLayoutPhase::run):
Properly handle VirtualRegisters set aside for LLInt or baseline JIT callee saves.

* jit/AssemblyHelpers.h:
(JSC::AssemblyHelpers::storeTrustedValue):
(JSC::AssemblyHelpers::emitSaveCalleeSavesFor):
(JSC::AssemblyHelpers::emitRestoreCalleeSavesFor):
(JSC::AssemblyHelpers::emitSaveCalleeSaves):
(JSC::AssemblyHelpers::emitRestoreCalleeSaves):
(JSC::AssemblyHelpers::copyCalleeSavesFromFrameOrRegisterToVMCalleeSavesBuffer):
(JSC::AssemblyHelpers::emitMaterializeTagCheckRegisters):
(JSC::AssemblyHelpers::prologueStackPointerDelta):
Functions to save and restore callee save registers in a stack frame or other buffer.

(JSC::AssemblyHelpers::emitMaterializeTagCheckRegisters):
Helper to populate tagTypeNumberRegister and tagMaskRegister with the appropriate
constants.

* jit/GPRInfo.h:
(JSC::GPRInfo::numberOfLLIntBaselineCalleeSaveRegisters):
Added this constant to hold the maximum number of callee save registers that we use in
the LLInt or baseline JIT.

* jit/JIT.cpp:
(JSC::JIT::privateCompile):
* jit/JITCall.cpp:
(JSC::JIT::compileOpCall):
(JSC::JIT::compileOpCallSlowCase):
* jit/JITCall32_64.cpp:
(JSC::JIT::emit_op_ret):
(JSC::JIT::compileOpCall):
(JSC::JIT::compileOpCallSlowCase):
* jit/JITOpcodes.cpp:
(JSC::JIT::emit_op_end):
(JSC::JIT::emit_op_ret):
(JSC::JIT::emit_op_enter):
(JSC::JIT::emitSlow_op_loop_hint):
* jit/JITOpcodes32_64.cpp:
(JSC::JIT::emit_op_end):
* jit/JITOperations.cpp:
* jit/Repatch.cpp:
(JSC::linkPolymorphicCall):
Emit code to save and restore callee save registers and materialize tagTypeNumberRegister
and tagMaskRegister.  Also handle callee saves when tiering up to the DFG.

* jit/RegisterSaveMap.cpp: Added.
(JSC::RegisterSaveMap::RegisterSaveMap):
(JSC::RegisterSaveMap::getIndexFor):
* jit/RegisterSaveMap.h: Added.
(JSC::RegisterSaveMap::size):
(JSC::RegisterSaveMap::has):
(JSC::RegisterSaveMap::maxOffset):
(JSC::RegisterSaveMap::getOffsetFor):
New class to track register offsets in the stack or other memory.

* jit/RegisterSet.cpp:
(JSC::RegisterSet::allVMCalleeSaveRegisters):
(JSC::RegisterSet::baselineCalleeSaveRegisters):
(JSC::RegisterSet::dfgCalleeSaveRegisters):
* jit/RegisterSet.h:
Fixed set of callee save registers for callee save regsiters in any VM, for the baseline JIT and for the
DFG.

* llint/LLIntData.cpp:
(JSC::LLInt::Data::performAssertions):
* llint/LowLevelInterpreter.asm:
* llint/LowLevelInterpreter64.asm:
Save and restor callee saves used by the LLInt.  Added code to handle OSR entry.
Changed the LLInt arity fixup to always use the LLInt supplied loop as the LLInt needs to include
callee saves as they need to be saved before calling the slow path that does arity checking since the
PC register is derived from the value in a callee save register.  Therefore that callee save needs to
be used before arity fixup, meaning that we need to save the prior contents.

* runtime/VM.cpp:
(JSC::VM::VM):
* runtime/VM.h:
(JSC::VM::calleeSaveRegistersBufferOffset):
(JSC::VM::getAllCalleeSaveRegistersMap):
Provide a RegisterSaveMap that has all registers that might be saved.  Added a callee save buffer to be
used for OSR exit and for exception processing in a future patch.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#branchesjsctailcallSourceJavaScriptCoreCMakeListstxt">branches/jsc-tailcall/Source/JavaScriptCore/CMakeLists.txt</a></li>
<li><a href="#branchesjsctailcallSourceJavaScriptCoreChangeLog">branches/jsc-tailcall/Source/JavaScriptCore/ChangeLog</a></li>
<li><a href="#branchesjsctailcallSourceJavaScriptCoreJavaScriptCorevcxprojJavaScriptCorevcxproj">branches/jsc-tailcall/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj</a></li>
<li><a href="#branchesjsctailcallSourceJavaScriptCoreJavaScriptCorexcodeprojprojectpbxproj">branches/jsc-tailcall/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj</a></li>
<li><a href="#branchesjsctailcallSourceJavaScriptCorebytecodeCodeBlockcpp">branches/jsc-tailcall/Source/JavaScriptCore/bytecode/CodeBlock.cpp</a></li>
<li><a href="#branchesjsctailcallSourceJavaScriptCorebytecodeCodeBlockh">branches/jsc-tailcall/Source/JavaScriptCore/bytecode/CodeBlock.h</a></li>
<li><a href="#branchesjsctailcallSourceJavaScriptCorebytecompilerBytecodeGeneratorcpp">branches/jsc-tailcall/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp</a></li>
<li><a href="#branchesjsctailcallSourceJavaScriptCorebytecompilerBytecodeGeneratorh">branches/jsc-tailcall/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h</a></li>
<li><a href="#branchesjsctailcallSourceJavaScriptCoredfgDFGJITCompilercpp">branches/jsc-tailcall/Source/JavaScriptCore/dfg/DFGJITCompiler.cpp</a></li>
<li><a href="#branchesjsctailcallSourceJavaScriptCoredfgDFGJITCompilerh">branches/jsc-tailcall/Source/JavaScriptCore/dfg/DFGJITCompiler.h</a></li>
<li><a href="#branchesjsctailcallSourceJavaScriptCoredfgDFGOSREntrycpp">branches/jsc-tailcall/Source/JavaScriptCore/dfg/DFGOSREntry.cpp</a></li>
<li><a href="#branchesjsctailcallSourceJavaScriptCoredfgDFGOSRExitCompiler64cpp">branches/jsc-tailcall/Source/JavaScriptCore/dfg/DFGOSRExitCompiler64.cpp</a></li>
<li><a href="#branchesjsctailcallSourceJavaScriptCoredfgDFGOSRExitCompilerCommoncpp">branches/jsc-tailcall/Source/JavaScriptCore/dfg/DFGOSRExitCompilerCommon.cpp</a></li>
<li><a href="#branchesjsctailcallSourceJavaScriptCoredfgDFGPlancpp">branches/jsc-tailcall/Source/JavaScriptCore/dfg/DFGPlan.cpp</a></li>
<li><a href="#branchesjsctailcallSourceJavaScriptCoredfgDFGSpeculativeJIT32_64cpp">branches/jsc-tailcall/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp</a></li>
<li><a href="#branchesjsctailcallSourceJavaScriptCoredfgDFGSpeculativeJIT64cpp">branches/jsc-tailcall/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp</a></li>
<li><a href="#branchesjsctailcallSourceJavaScriptCoredfgDFGStackLayoutPhasecpp">branches/jsc-tailcall/Source/JavaScriptCore/dfg/DFGStackLayoutPhase.cpp</a></li>
<li><a href="#branchesjsctailcallSourceJavaScriptCorejitAssemblyHelpersh">branches/jsc-tailcall/Source/JavaScriptCore/jit/AssemblyHelpers.h</a></li>
<li><a href="#branchesjsctailcallSourceJavaScriptCorejitGPRInfoh">branches/jsc-tailcall/Source/JavaScriptCore/jit/GPRInfo.h</a></li>
<li><a href="#branchesjsctailcallSourceJavaScriptCorejitJITcpp">branches/jsc-tailcall/Source/JavaScriptCore/jit/JIT.cpp</a></li>
<li><a href="#branchesjsctailcallSourceJavaScriptCorejitJITCallcpp">branches/jsc-tailcall/Source/JavaScriptCore/jit/JITCall.cpp</a></li>
<li><a href="#branchesjsctailcallSourceJavaScriptCorejitJITCall32_64cpp">branches/jsc-tailcall/Source/JavaScriptCore/jit/JITCall32_64.cpp</a></li>
<li><a href="#branchesjsctailcallSourceJavaScriptCorejitJITOpcodescpp">branches/jsc-tailcall/Source/JavaScriptCore/jit/JITOpcodes.cpp</a></li>
<li><a href="#branchesjsctailcallSourceJavaScriptCorejitJITOpcodes32_64cpp">branches/jsc-tailcall/Source/JavaScriptCore/jit/JITOpcodes32_64.cpp</a></li>
<li><a href="#branchesjsctailcallSourceJavaScriptCorejitJITOperationscpp">branches/jsc-tailcall/Source/JavaScriptCore/jit/JITOperations.cpp</a></li>
<li><a href="#branchesjsctailcallSourceJavaScriptCorejitRegisterSetcpp">branches/jsc-tailcall/Source/JavaScriptCore/jit/RegisterSet.cpp</a></li>
<li><a href="#branchesjsctailcallSourceJavaScriptCorejitRegisterSeth">branches/jsc-tailcall/Source/JavaScriptCore/jit/RegisterSet.h</a></li>
<li><a href="#branchesjsctailcallSourceJavaScriptCorejitRepatchcpp">branches/jsc-tailcall/Source/JavaScriptCore/jit/Repatch.cpp</a></li>
<li><a href="#branchesjsctailcallSourceJavaScriptCorellintLLIntDatacpp">branches/jsc-tailcall/Source/JavaScriptCore/llint/LLIntData.cpp</a></li>
<li><a href="#branchesjsctailcallSourceJavaScriptCorellintLowLevelInterpreterasm">branches/jsc-tailcall/Source/JavaScriptCore/llint/LowLevelInterpreter.asm</a></li>
<li><a href="#branchesjsctailcallSourceJavaScriptCorellintLowLevelInterpreter64asm">branches/jsc-tailcall/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm</a></li>
<li><a href="#branchesjsctailcallSourceJavaScriptCoreruntimeVMcpp">branches/jsc-tailcall/Source/JavaScriptCore/runtime/VM.cpp</a></li>
<li><a href="#branchesjsctailcallSourceJavaScriptCoreruntimeVMh">branches/jsc-tailcall/Source/JavaScriptCore/runtime/VM.h</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#branchesjsctailcallSourceJavaScriptCorejitRegisterSaveMapcpp">branches/jsc-tailcall/Source/JavaScriptCore/jit/RegisterSaveMap.cpp</a></li>
<li><a href="#branchesjsctailcallSourceJavaScriptCorejitRegisterSaveMaph">branches/jsc-tailcall/Source/JavaScriptCore/jit/RegisterSaveMap.h</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="branchesjsctailcallSourceJavaScriptCoreCMakeListstxt"></a>
<div class="modfile"><h4>Modified: branches/jsc-tailcall/Source/JavaScriptCore/CMakeLists.txt (187638 => 187639)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsc-tailcall/Source/JavaScriptCore/CMakeLists.txt        2015-07-31 03:48:40 UTC (rev 187638)
+++ branches/jsc-tailcall/Source/JavaScriptCore/CMakeLists.txt        2015-07-31 06:02:40 UTC (rev 187639)
</span><span class="lines">@@ -369,6 +369,7 @@
</span><span class="cx">     jit/PolymorphicCallStubRoutine.cpp
</span><span class="cx">     jit/Reg.cpp
</span><span class="cx">     jit/RegisterPreservationWrapperGenerator.cpp
</span><ins>+    jit/RegisterSaveMap.cpp
</ins><span class="cx">     jit/RegisterSet.cpp
</span><span class="cx">     jit/Repatch.cpp
</span><span class="cx">     jit/ScratchRegisterAllocator.cpp
</span></span></pre></div>
<a id="branchesjsctailcallSourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: branches/jsc-tailcall/Source/JavaScriptCore/ChangeLog (187638 => 187639)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsc-tailcall/Source/JavaScriptCore/ChangeLog        2015-07-31 03:48:40 UTC (rev 187638)
+++ branches/jsc-tailcall/Source/JavaScriptCore/ChangeLog        2015-07-31 06:02:40 UTC (rev 187639)
</span><span class="lines">@@ -1,5 +1,154 @@
</span><span class="cx"> 2015-07-30  Michael Saboff  &lt;msaboff@apple.com&gt;
</span><span class="cx"> 
</span><ins>+        jsc-tailcall: LLint, Baseline and DFG JIT should save &amp; restore platform's callee-save registers
+        https://bugs.webkit.org/show_bug.cgi?id=146946
+
+        Reviewed by Basile Clement.
+
+        We save platform callee save registers right below the call frame header, in the location(s)
+        starting with VirtualRegister 0.  Allocated local space in the bytecode compiler.
+        This space is the maximum space needed for the callee registers that the LLInt or baseline JIT
+        will used, rounded up to number of VirtualRegisters.  The LLInt explicitly saves and restores
+        the registers in the functions preserveCalleeSavesUsedByLLInt and restoreCalleeSavesUsedByLLInt.
+        The baseline and DFG JITs saves and restores callee saves registers by what registers are included
+        in m_calleeSaveRegisters in the code block.
+
+        Added code to transition callee saves from one VM's format to the another as part of OSR entry and
+        OSR exit.  Added a helper class RegisterSaveMap that has the cannonical locations for a set of
+        saved registers.  This is used not only to save and restore registers on function entry and exit,
+        but also to handle OSR entry and exit cases.
+
+        * CMakeLists.txt:
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        Added RegisterSaveMap to build configurations.
+
+        * bytecode/CodeBlock.cpp:
+        (JSC::CodeBlock::setCalleeSaveRegisters):
+        (JSC::roundCalleeSaveSpaceAsVirtualRegisters):
+        (JSC::CodeBlock::llintBaselineCalleeSaveSpaceAsVirtualRegisters):
+        (JSC::CodeBlock::calleeSaveSpaceAsVirtualRegisters):
+        (JSC::CodeBlock::countReoptimization):
+        * bytecode/CodeBlock.h:
+        (JSC::CodeBlock::numberOfLLIntBaselineCalleeSaveRegisters):
+        (JSC::CodeBlock::calleeSaveRegisters):
+        (JSC::CodeBlock::llintBaselineCalleeSaveSpaceAsVirtualRegisters):
+        (JSC::CodeBlock::optimizeAfterWarmUp):
+        (JSC::CodeBlock::numberOfDFGCompiles):
+        Methods to manage a set of callee save registers.  Also to allocate the appropriate
+        number of VritualRegisters for callee saves.
+
+        * bytecompiler/BytecodeGenerator.cpp:
+        (JSC::BytecodeGenerator::allocateCalleeSaveSpace):
+        * bytecompiler/BytecodeGenerator.h:
+        Allocate the appropriate number of VritualRegisters for callee saves needed by LLInt or baseline JIT.
+
+        * dfg/DFGJITCompiler.cpp:
+        (JSC::DFG::JITCompiler::compileEntry):
+        (JSC::DFG::JITCompiler::compileSetupRegistersForEntry):
+        (JSC::DFG::JITCompiler::compileBody):
+        (JSC::DFG::JITCompiler::compile):
+        (JSC::DFG::JITCompiler::compileFunction):
+        * dfg/DFGJITCompiler.h:
+
+        * dfg/DFGOSREntry.cpp:
+        (JSC::DFG::prepareOSREntry):
+        * dfg/DFGOSRExitCompiler64.cpp:
+        (JSC::DFG::OSRExitCompiler::compileExit):
+        * dfg/DFGOSRExitCompilerCommon.cpp:
+        (JSC::DFG::reifyInlinedCallFrames):
+        (JSC::DFG::adjustAndJumpToTarget):
+        * dfg/DFGPlan.cpp:
+        (JSC::DFG::Plan::compileInThreadImpl):
+        * dfg/DFGSpeculativeJIT32_64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+        * dfg/DFGSpeculativeJIT64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+
+        * dfg/DFGStackLayoutPhase.cpp:
+        (JSC::DFG::StackLayoutPhase::run):
+        Properly handle VirtualRegisters set aside for LLInt or baseline JIT callee saves.
+
+        * jit/AssemblyHelpers.h:
+        (JSC::AssemblyHelpers::storeTrustedValue):
+        (JSC::AssemblyHelpers::emitSaveCalleeSavesFor):
+        (JSC::AssemblyHelpers::emitRestoreCalleeSavesFor):
+        (JSC::AssemblyHelpers::emitSaveCalleeSaves):
+        (JSC::AssemblyHelpers::emitRestoreCalleeSaves):
+        (JSC::AssemblyHelpers::copyCalleeSavesFromFrameOrRegisterToVMCalleeSavesBuffer):
+        (JSC::AssemblyHelpers::emitMaterializeTagCheckRegisters):
+        (JSC::AssemblyHelpers::prologueStackPointerDelta):
+        Functions to save and restore callee save registers in a stack frame or other buffer.
+
+        (JSC::AssemblyHelpers::emitMaterializeTagCheckRegisters):
+        Helper to populate tagTypeNumberRegister and tagMaskRegister with the appropriate
+        constants.
+
+        * jit/GPRInfo.h:
+        (JSC::GPRInfo::numberOfLLIntBaselineCalleeSaveRegisters):
+        Added this constant to hold the maximum number of callee save registers that we use in
+        the LLInt or baseline JIT.
+
+        * jit/JIT.cpp:
+        (JSC::JIT::privateCompile):
+        * jit/JITCall.cpp:
+        (JSC::JIT::compileOpCall):
+        (JSC::JIT::compileOpCallSlowCase):
+        * jit/JITCall32_64.cpp:
+        (JSC::JIT::emit_op_ret):
+        (JSC::JIT::compileOpCall):
+        (JSC::JIT::compileOpCallSlowCase):
+        * jit/JITOpcodes.cpp:
+        (JSC::JIT::emit_op_end):
+        (JSC::JIT::emit_op_ret):
+        (JSC::JIT::emit_op_enter):
+        (JSC::JIT::emitSlow_op_loop_hint):
+        * jit/JITOpcodes32_64.cpp:
+        (JSC::JIT::emit_op_end):
+        * jit/JITOperations.cpp:
+        * jit/Repatch.cpp:
+        (JSC::linkPolymorphicCall):
+        Emit code to save and restore callee save registers and materialize tagTypeNumberRegister
+        and tagMaskRegister.  Also handle callee saves when tiering up to the DFG.
+
+        * jit/RegisterSaveMap.cpp: Added.
+        (JSC::RegisterSaveMap::RegisterSaveMap):
+        (JSC::RegisterSaveMap::getIndexFor):
+        * jit/RegisterSaveMap.h: Added.
+        (JSC::RegisterSaveMap::size):
+        (JSC::RegisterSaveMap::has):
+        (JSC::RegisterSaveMap::maxOffset):
+        (JSC::RegisterSaveMap::getOffsetFor):
+        New class to track register offsets in the stack or other memory.
+
+        * jit/RegisterSet.cpp:
+        (JSC::RegisterSet::allVMCalleeSaveRegisters):
+        (JSC::RegisterSet::baselineCalleeSaveRegisters):
+        (JSC::RegisterSet::dfgCalleeSaveRegisters):
+        * jit/RegisterSet.h:
+        Fixed set of callee save registers for callee save regsiters in any VM, for the baseline JIT and for the
+        DFG.
+
+        * llint/LLIntData.cpp:
+        (JSC::LLInt::Data::performAssertions):
+        * llint/LowLevelInterpreter.asm:
+        * llint/LowLevelInterpreter64.asm:
+        Save and restor callee saves used by the LLInt.  Added code to handle OSR entry.
+        Changed the LLInt arity fixup to always use the LLInt supplied loop as the LLInt needs to include
+        callee saves as they need to be saved before calling the slow path that does arity checking since the
+        PC register is derived from the value in a callee save register.  Therefore that callee save needs to
+        be used before arity fixup, meaning that we need to save the prior contents.
+
+        * runtime/VM.cpp:
+        (JSC::VM::VM):
+        * runtime/VM.h:
+        (JSC::VM::calleeSaveRegistersBufferOffset):
+        (JSC::VM::getAllCalleeSaveRegistersMap):
+        Provide a RegisterSaveMap that has all registers that might be saved.  Added a callee save buffer to be
+        used for OSR exit and for exception processing in a future patch.
+
+2015-07-30  Michael Saboff  &lt;msaboff@apple.com&gt;
+
</ins><span class="cx">         jsc-tailcall: Eliminate rdi from temp register list for X86-64 Windows
</span><span class="cx">         https://bugs.webkit.org/show_bug.cgi?id=147461
</span><span class="cx"> 
</span></span></pre></div>
<a id="branchesjsctailcallSourceJavaScriptCoreJavaScriptCorevcxprojJavaScriptCorevcxproj"></a>
<div class="modfile"><h4>Modified: branches/jsc-tailcall/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj (187638 => 187639)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsc-tailcall/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj        2015-07-31 03:48:40 UTC (rev 187638)
+++ branches/jsc-tailcall/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj        2015-07-31 06:02:40 UTC (rev 187639)
</span><span class="lines">@@ -635,6 +635,7 @@
</span><span class="cx">     &lt;ClCompile Include=&quot;..\jit\PolymorphicCallStubRoutine.cpp&quot; /&gt;
</span><span class="cx">     &lt;ClCompile Include=&quot;..\jit\Reg.cpp&quot; /&gt;
</span><span class="cx">     &lt;ClCompile Include=&quot;..\jit\RegisterPreservationWrapperGenerator.cpp&quot; /&gt;
</span><ins>+    &lt;ClCompile Include=&quot;..\jit\RegisterSaveMap.cpp&quot; /&gt;
</ins><span class="cx">     &lt;ClCompile Include=&quot;..\jit\RegisterSet.cpp&quot; /&gt;
</span><span class="cx">     &lt;ClCompile Include=&quot;..\jit\Repatch.cpp&quot; /&gt;
</span><span class="cx">     &lt;ClCompile Include=&quot;..\jit\ScratchRegisterAllocator.cpp&quot; /&gt;
</span><span class="lines">@@ -1399,6 +1400,7 @@
</span><span class="cx">     &lt;ClInclude Include=&quot;..\jit\PolymorphicCallStubRoutine.h&quot; /&gt;
</span><span class="cx">     &lt;ClInclude Include=&quot;..\jit\Reg.h&quot; /&gt;
</span><span class="cx">     &lt;ClInclude Include=&quot;..\jit\RegisterPreservationWrapperGenerator.h&quot; /&gt;
</span><ins>+    &lt;ClInclude Include=&quot;..\jit\RegisterSaveMap.h&quot; /&gt;
</ins><span class="cx">     &lt;ClInclude Include=&quot;..\jit\RegisterSet.h&quot; /&gt;
</span><span class="cx">     &lt;ClInclude Include=&quot;..\jit\Repatch.h&quot; /&gt;
</span><span class="cx">     &lt;ClInclude Include=&quot;..\jit\ScratchRegisterAllocator.h&quot; /&gt;
</span></span></pre></div>
<a id="branchesjsctailcallSourceJavaScriptCoreJavaScriptCorexcodeprojprojectpbxproj"></a>
<div class="modfile"><h4>Modified: branches/jsc-tailcall/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj (187638 => 187639)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsc-tailcall/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj        2015-07-31 03:48:40 UTC (rev 187638)
+++ branches/jsc-tailcall/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj        2015-07-31 06:02:40 UTC (rev 187639)
</span><span class="lines">@@ -974,6 +974,8 @@
</span><span class="cx">                 6511230714046B0A002B101D /* testRegExp.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 651122E5140469BA002B101D /* testRegExp.cpp */; };
</span><span class="cx">                 6514F21918B3E1670098FF8B /* Bytecodes.h in Headers */ = {isa = PBXBuildFile; fileRef = 6514F21718B3E1670098FF8B /* Bytecodes.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 65303D641447B9E100D3F904 /* ParserTokens.h in Headers */ = {isa = PBXBuildFile; fileRef = 65303D631447B9E100D3F904 /* ParserTokens.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><ins>+                653D508A1B5D9F9C00DD4BCD /* RegisterSaveMap.h in Headers */ = {isa = PBXBuildFile; fileRef = 65AD9B191B5D9B750098556D /* RegisterSaveMap.h */; settings = {ATTRIBUTES = (Private, ); }; };
+                653D508B1B5DC29000DD4BCD /* RegisterSaveMap.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 65AD9B181B5D9B750098556D /* RegisterSaveMap.cpp */; };
</ins><span class="cx">                 6546F5211A32B313006F07D5 /* NullGetterFunction.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6546F51F1A32A59C006F07D5 /* NullGetterFunction.cpp */; };
</span><span class="cx">                 65525FC51A6DD801007B5495 /* NullSetterFunction.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 65525FC31A6DD3B3007B5495 /* NullSetterFunction.cpp */; };
</span><span class="cx">                 6553A33117A1F1EE008CF6F3 /* CommonSlowPathsExceptions.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6553A32F17A1F1EE008CF6F3 /* CommonSlowPathsExceptions.cpp */; };
</span><span class="lines">@@ -2714,6 +2716,8 @@
</span><span class="cx">                 658D3A5519638268003C45D6 /* VMEntryRecord.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = VMEntryRecord.h; sourceTree = &quot;&lt;group&gt;&quot;; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; };
</span><span class="cx">                 65987F2C167FE84B003C2F8D /* DFGOSRExitCompilationInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGOSRExitCompilationInfo.h; path = dfg/DFGOSRExitCompilationInfo.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 65987F2F16828A7E003C2F8D /* UnusedPointer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UnusedPointer.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><ins>+                65AD9B181B5D9B750098556D /* RegisterSaveMap.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RegisterSaveMap.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
+                65AD9B191B5D9B750098556D /* RegisterSaveMap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RegisterSaveMap.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</ins><span class="cx">                 65C0284F171795E200351E35 /* ARMv7Disassembler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ARMv7Disassembler.cpp; path = disassembler/ARMv7Disassembler.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 65C0285A1717966800351E35 /* ARMv7DOpcode.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ARMv7DOpcode.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 65C0285B1717966800351E35 /* ARMv7DOpcode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ARMv7DOpcode.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="lines">@@ -3965,6 +3969,8 @@
</span><span class="cx">                                 0FA7A8EA18B413C80052371D /* Reg.h */,
</span><span class="cx">                                 0F6B1CBB1861246A00845D97 /* RegisterPreservationWrapperGenerator.cpp */,
</span><span class="cx">                                 0F6B1CBC1861246A00845D97 /* RegisterPreservationWrapperGenerator.h */,
</span><ins>+                                65AD9B181B5D9B750098556D /* RegisterSaveMap.cpp */,
+                                65AD9B191B5D9B750098556D /* RegisterSaveMap.h */,
</ins><span class="cx">                                 0FC3141418146D7000033232 /* RegisterSet.cpp */,
</span><span class="cx">                                 0FC314101814559100033232 /* RegisterSet.h */,
</span><span class="cx">                                 0F24E54917EE274900ABB217 /* Repatch.cpp */,
</span><span class="lines">@@ -5625,6 +5631,7 @@
</span><span class="cx">                                 52678F911A04177C006A306D /* ControlFlowProfiler.h in Headers */,
</span><span class="cx">                                 52678F8F1A031009006A306D /* BasicBlockLocation.h in Headers */,
</span><span class="cx">                                 A5EA710E19F6DF810098F5EC /* InspectorAlternateBackendDispatchers.h in Headers */,
</span><ins>+                                653D508A1B5D9F9C00DD4BCD /* RegisterSaveMap.h in Headers */,
</ins><span class="cx">                                 A5EA70EC19F5B3EA0098F5EC /* generate_cpp_alternate_backend_dispatcher_header.py in Headers */,
</span><span class="cx">                                 C4F4B6F31A05C944005CAB76 /* cpp_generator_templates.py in Headers */,
</span><span class="cx">                                 A5EF9B151A1D43FA00702E90 /* generate_cpp_backend_dispatcher_implementation.py in Headers */,
</span><span class="lines">@@ -7004,6 +7011,7 @@
</span><span class="cx">                         isa = PBXSourcesBuildPhase;
</span><span class="cx">                         buildActionMask = 2147483647;
</span><span class="cx">                         files = (
</span><ins>+                                653D508B1B5DC29000DD4BCD /* RegisterSaveMap.cpp in Sources */,
</ins><span class="cx">                                 9EA5C7A2190F088700508EBE /* InitializeLLVMMac.cpp in Sources */,
</span><span class="cx">                                 9EA5C7A1190F084200508EBE /* BundlePath.mm in Sources */,
</span><span class="cx">                                 52B310FF1975B4240080857C /* TypeLocationCache.cpp in Sources */,
</span></span></pre></div>
<a id="branchesjsctailcallSourceJavaScriptCorebytecodeCodeBlockcpp"></a>
<div class="modfile"><h4>Modified: branches/jsc-tailcall/Source/JavaScriptCore/bytecode/CodeBlock.cpp (187638 => 187639)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsc-tailcall/Source/JavaScriptCore/bytecode/CodeBlock.cpp        2015-07-31 03:48:40 UTC (rev 187638)
+++ branches/jsc-tailcall/Source/JavaScriptCore/bytecode/CodeBlock.cpp        2015-07-31 06:02:40 UTC (rev 187639)
</span><span class="lines">@@ -68,6 +68,10 @@
</span><span class="cx"> #include &lt;wtf/StringPrintStream.h&gt;
</span><span class="cx"> #include &lt;wtf/text/UniquedStringImpl.h&gt;
</span><span class="cx"> 
</span><ins>+#if ENABLE(JIT)
+#include &quot;RegisterSaveMap.h&quot;
+#endif
+
</ins><span class="cx"> #if ENABLE(DFG_JIT)
</span><span class="cx"> #include &quot;DFGOperations.h&quot;
</span><span class="cx"> #endif
</span><span class="lines">@@ -3293,6 +3297,28 @@
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> #if ENABLE(JIT)
</span><ins>+void CodeBlock::setCalleeSaveRegisters(RegisterSet calleeSaveRegisters)
+{
+    m_calleeSaveRegisters = std::make_unique&lt;RegisterSaveMap&gt;(calleeSaveRegisters);
+}
+
+static size_t roundCalleeSaveSpaceAsVirtualRegisters(size_t calleeSaveRegisters)
+{
+    static const unsigned cpuRegisterSize = sizeof(void*);
+    return (WTF::roundUpToMultipleOf(sizeof(Register), calleeSaveRegisters * cpuRegisterSize) / sizeof(Register));
+
+}
+
+size_t CodeBlock::llintBaselineCalleeSaveSpaceAsVirtualRegisters()
+{
+    return roundCalleeSaveSpaceAsVirtualRegisters(numberOfLLIntBaselineCalleeSaveRegisters());
+}
+
+size_t CodeBlock::calleeSaveSpaceAsVirtualRegisters()
+{
+    return roundCalleeSaveSpaceAsVirtualRegisters(m_calleeSaveRegisters-&gt;size());
+}
+
</ins><span class="cx"> void CodeBlock::countReoptimization()
</span><span class="cx"> {
</span><span class="cx">     m_reoptimizationRetryCounter++;
</span></span></pre></div>
<a id="branchesjsctailcallSourceJavaScriptCorebytecodeCodeBlockh"></a>
<div class="modfile"><h4>Modified: branches/jsc-tailcall/Source/JavaScriptCore/bytecode/CodeBlock.h (187638 => 187639)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsc-tailcall/Source/JavaScriptCore/bytecode/CodeBlock.h        2015-07-31 03:48:40 UTC (rev 187638)
+++ branches/jsc-tailcall/Source/JavaScriptCore/bytecode/CodeBlock.h        2015-07-31 06:02:40 UTC (rev 187639)
</span><span class="lines">@@ -80,6 +80,7 @@
</span><span class="cx"> 
</span><span class="cx"> class ExecState;
</span><span class="cx"> class LLIntOffsetsExtractor;
</span><ins>+class RegisterSaveMap;
</ins><span class="cx"> class RepatchBuffer;
</span><span class="cx"> class TypeLocation;
</span><span class="cx"> 
</span><span class="lines">@@ -732,6 +733,10 @@
</span><span class="cx">     JS_EXPORT_PRIVATE unsigned reoptimizationRetryCounter() const;
</span><span class="cx">     void countReoptimization();
</span><span class="cx"> #if ENABLE(JIT)
</span><ins>+    static unsigned numberOfLLIntBaselineCalleeSaveRegisters() { return GPRInfo::numberOfLLIntBaselineCalleeSaveRegisters; }
+    static size_t llintBaselineCalleeSaveSpaceAsVirtualRegisters();
+    size_t calleeSaveSpaceAsVirtualRegisters();
+
</ins><span class="cx">     unsigned numberOfDFGCompiles();
</span><span class="cx"> 
</span><span class="cx">     int32_t codeTypeThresholdMultiplier() const;
</span><span class="lines">@@ -817,7 +822,13 @@
</span><span class="cx">     uint32_t exitCountThresholdForReoptimizationFromLoop();
</span><span class="cx">     bool shouldReoptimizeNow();
</span><span class="cx">     bool shouldReoptimizeFromLoopNow();
</span><ins>+
+    void setCalleeSaveRegisters(RegisterSet);
+    
+    RegisterSaveMap* calleeSaveRegisters() const { return m_calleeSaveRegisters.get(); }
</ins><span class="cx"> #else // No JIT
</span><ins>+    static unsigned numberOfLLIntBaselineCalleeSaveRegisters() { return 0; }
+    static size_t llintBaselineCalleeSaveSpaceAsVirtualRegisters() { return 0; };
</ins><span class="cx">     void optimizeAfterWarmUp() { }
</span><span class="cx">     unsigned numberOfDFGCompiles() { return 0; }
</span><span class="cx"> #endif
</span><span class="lines">@@ -856,6 +867,7 @@
</span><span class="cx">     
</span><span class="cx">     // FIXME: Make these remaining members private.
</span><span class="cx"> 
</span><ins>+    int m_numLocalRegistersForCalleeSaves;
</ins><span class="cx">     int m_numCalleeRegisters;
</span><span class="cx">     int m_numVars;
</span><span class="cx">     bool m_isConstructor : 1;
</span><span class="lines">@@ -1013,6 +1025,7 @@
</span><span class="cx">     SentinelLinkedList&lt;LLIntCallLinkInfo, BasicRawSentinelNode&lt;LLIntCallLinkInfo&gt;&gt; m_incomingLLIntCalls;
</span><span class="cx">     RefPtr&lt;JITCode&gt; m_jitCode;
</span><span class="cx"> #if ENABLE(JIT)
</span><ins>+    std::unique_ptr&lt;RegisterSaveMap&gt; m_calleeSaveRegisters;
</ins><span class="cx">     Bag&lt;StructureStubInfo&gt; m_stubInfos;
</span><span class="cx">     Vector&lt;ByValInfo&gt; m_byValInfos;
</span><span class="cx">     Bag&lt;CallLinkInfo&gt; m_callLinkInfos;
</span></span></pre></div>
<a id="branchesjsctailcallSourceJavaScriptCorebytecompilerBytecodeGeneratorcpp"></a>
<div class="modfile"><h4>Modified: branches/jsc-tailcall/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp (187638 => 187639)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsc-tailcall/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp        2015-07-31 03:48:40 UTC (rev 187638)
+++ branches/jsc-tailcall/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp        2015-07-31 06:02:40 UTC (rev 187639)
</span><span class="lines">@@ -160,6 +160,8 @@
</span><span class="cx">     for (auto&amp; constantRegister : m_linkTimeConstantRegisters)
</span><span class="cx">         constantRegister = nullptr;
</span><span class="cx"> 
</span><ins>+    allocateCalleeSaveSpace();
+
</ins><span class="cx">     m_codeBlock-&gt;setNumParameters(1); // Allocate space for &quot;this&quot;
</span><span class="cx"> 
</span><span class="cx">     emitOpcode(op_enter);
</span><span class="lines">@@ -195,6 +197,8 @@
</span><span class="cx">     if (m_isBuiltinFunction)
</span><span class="cx">         m_shouldEmitDebugHooks = false;
</span><span class="cx">     
</span><ins>+    allocateCalleeSaveSpace();
+
</ins><span class="cx">     m_symbolTable-&gt;setUsesNonStrictEval(codeBlock-&gt;usesEval() &amp;&amp; !codeBlock-&gt;isStrictMode());
</span><span class="cx">     Vector&lt;Identifier&gt; boundParameterProperties;
</span><span class="cx">     FunctionParameters&amp; parameters = *functionNode-&gt;parameters();
</span><span class="lines">@@ -510,6 +514,8 @@
</span><span class="cx">     for (auto&amp; constantRegister : m_linkTimeConstantRegisters)
</span><span class="cx">         constantRegister = nullptr;
</span><span class="cx"> 
</span><ins>+    allocateCalleeSaveSpace();
+
</ins><span class="cx">     m_symbolTable-&gt;setUsesNonStrictEval(codeBlock-&gt;usesEval() &amp;&amp; !codeBlock-&gt;isStrictMode());
</span><span class="cx">     m_codeBlock-&gt;setNumParameters(1);
</span><span class="cx"> 
</span><span class="lines">@@ -2373,6 +2379,17 @@
</span><span class="cx">     return LabelScopePtr::null();
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void BytecodeGenerator::allocateCalleeSaveSpace()
+{
+    size_t virtualRegisterCountForCalleeSaves = CodeBlock::llintBaselineCalleeSaveSpaceAsVirtualRegisters();
+
+    for (size_t i = 0; i &lt; virtualRegisterCountForCalleeSaves; i++) {
+        RegisterID* localRegister = addVar();
+        localRegister-&gt;ref();
+        m_localRegistersForCalleeSaveRegisters.append(localRegister);
+    }
+}
+
</ins><span class="cx"> void BytecodeGenerator::allocateAndEmitScope()
</span><span class="cx"> {
</span><span class="cx">     m_scopeRegister = addVar();
</span></span></pre></div>
<a id="branchesjsctailcallSourceJavaScriptCorebytecompilerBytecodeGeneratorh"></a>
<div class="modfile"><h4>Modified: branches/jsc-tailcall/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h (187638 => 187639)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsc-tailcall/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h        2015-07-31 03:48:40 UTC (rev 187638)
+++ branches/jsc-tailcall/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h        2015-07-31 06:02:40 UTC (rev 187639)
</span><span class="lines">@@ -627,6 +627,7 @@
</span><span class="cx">         ALWAYS_INLINE void rewindBinaryOp();
</span><span class="cx">         ALWAYS_INLINE void rewindUnaryOp();
</span><span class="cx"> 
</span><ins>+        void allocateCalleeSaveSpace();
</ins><span class="cx">         void allocateAndEmitScope();
</span><span class="cx">         void emitComplexPopScopes(RegisterID*, ControlFlowContext* topScope, ControlFlowContext* bottomScope);
</span><span class="cx"> 
</span><span class="lines">@@ -745,6 +746,7 @@
</span><span class="cx">         RegisterID* m_newTargetRegister { nullptr };
</span><span class="cx">         RegisterID* m_linkTimeConstantRegisters[LinkTimeConstantCount];
</span><span class="cx"> 
</span><ins>+        SegmentedVector&lt;RegisterID*, 16&gt; m_localRegistersForCalleeSaveRegisters;
</ins><span class="cx">         SegmentedVector&lt;RegisterID, 32&gt; m_constantPoolRegisters;
</span><span class="cx">         SegmentedVector&lt;RegisterID, 32&gt; m_calleeRegisters;
</span><span class="cx">         SegmentedVector&lt;RegisterID, 32&gt; m_parameters;
</span></span></pre></div>
<a id="branchesjsctailcallSourceJavaScriptCoredfgDFGJITCompilercpp"></a>
<div class="modfile"><h4>Modified: branches/jsc-tailcall/Source/JavaScriptCore/dfg/DFGJITCompiler.cpp (187638 => 187639)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsc-tailcall/Source/JavaScriptCore/dfg/DFGJITCompiler.cpp        2015-07-31 03:48:40 UTC (rev 187638)
+++ branches/jsc-tailcall/Source/JavaScriptCore/dfg/DFGJITCompiler.cpp        2015-07-31 06:02:40 UTC (rev 187639)
</span><span class="lines">@@ -101,9 +101,14 @@
</span><span class="cx">     // both normal return code and when jumping to an exception handler).
</span><span class="cx">     emitFunctionPrologue();
</span><span class="cx">     emitPutImmediateToCallFrameHeader(m_codeBlock, JSStack::CodeBlock);
</span><del>-    jitAssertTagsInPlace();
</del><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void JITCompiler::compileSetupRegistersForEntry()
+{
+    emitSaveCalleeSaves();
+    emitMaterializeTagCheckRegisters();    
+}
+
</ins><span class="cx"> void JITCompiler::compileBody()
</span><span class="cx"> {
</span><span class="cx">     // We generate the speculative code path, followed by OSR exit code to return
</span><span class="lines">@@ -285,6 +290,7 @@
</span><span class="cx"> 
</span><span class="cx">     setStartOfCode();
</span><span class="cx">     compileEntry();
</span><ins>+    compileSetupRegistersForEntry();
</ins><span class="cx">     m_speculative = std::make_unique&lt;SpeculativeJIT&gt;(*this);
</span><span class="cx"> 
</span><span class="cx">     // Plant a check that sufficient space is available in the JSStack.
</span><span class="lines">@@ -357,6 +363,8 @@
</span><span class="cx">     addPtr(TrustedImm32(m_graph.stackPointerOffset() * sizeof(Register)), GPRInfo::callFrameRegister, stackPointerRegister);
</span><span class="cx">     checkStackPointerAlignment();
</span><span class="cx"> 
</span><ins>+    compileSetupRegistersForEntry();
+
</ins><span class="cx">     // === Function body code generation ===
</span><span class="cx">     m_speculative = std::make_unique&lt;SpeculativeJIT&gt;(*this);
</span><span class="cx">     compileBody();
</span></span></pre></div>
<a id="branchesjsctailcallSourceJavaScriptCoredfgDFGJITCompilerh"></a>
<div class="modfile"><h4>Modified: branches/jsc-tailcall/Source/JavaScriptCore/dfg/DFGJITCompiler.h (187638 => 187639)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsc-tailcall/Source/JavaScriptCore/dfg/DFGJITCompiler.h        2015-07-31 03:48:40 UTC (rev 187638)
+++ branches/jsc-tailcall/Source/JavaScriptCore/dfg/DFGJITCompiler.h        2015-07-31 06:02:40 UTC (rev 187639)
</span><span class="lines">@@ -322,6 +322,7 @@
</span><span class="cx">     
</span><span class="cx">     // Internal implementation to compile.
</span><span class="cx">     void compileEntry();
</span><ins>+    void compileSetupRegistersForEntry();
</ins><span class="cx">     void compileBody();
</span><span class="cx">     void link(LinkBuffer&amp;);
</span><span class="cx">     
</span></span></pre></div>
<a id="branchesjsctailcallSourceJavaScriptCoredfgDFGOSREntrycpp"></a>
<div class="modfile"><h4>Modified: branches/jsc-tailcall/Source/JavaScriptCore/dfg/DFGOSREntry.cpp (187638 => 187639)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsc-tailcall/Source/JavaScriptCore/dfg/DFGOSREntry.cpp        2015-07-31 03:48:40 UTC (rev 187638)
+++ branches/jsc-tailcall/Source/JavaScriptCore/dfg/DFGOSREntry.cpp        2015-07-31 06:02:40 UTC (rev 187639)
</span><span class="lines">@@ -255,6 +255,13 @@
</span><span class="cx">             continue;
</span><span class="cx">         pivot[i] = JSValue();
</span><span class="cx">     }
</span><ins>+
+    RegisterSaveMap* registerSaveLocations = codeBlock-&gt;calleeSaveRegisters();
+    unsigned numberRegistersToSave = registerSaveLocations-&gt;size();
+    for (Reg reg = Reg::first(); reg &lt;= Reg::last(); reg = reg.next()) {
+        if (registerSaveLocations-&gt;has(reg) &amp;&amp; reg.isGPR())
+            *(bitwise_cast&lt;intptr_t*&gt;(pivot) + numberRegistersToSave - registerSaveLocations-&gt;getIndexFor(reg) - 1) = vm-&gt;calleeSaveRegistersBuffer[vm-&gt;getAllCalleeSaveRegistersMap()-&gt;getIndexFor(reg)];
+    }
</ins><span class="cx">     
</span><span class="cx">     // 6) Fix the call frame to have the right code block.
</span><span class="cx">     
</span></span></pre></div>
<a id="branchesjsctailcallSourceJavaScriptCoredfgDFGOSRExitCompiler64cpp"></a>
<div class="modfile"><h4>Modified: branches/jsc-tailcall/Source/JavaScriptCore/dfg/DFGOSRExitCompiler64.cpp (187638 => 187639)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsc-tailcall/Source/JavaScriptCore/dfg/DFGOSRExitCompiler64.cpp        2015-07-31 03:48:40 UTC (rev 187638)
+++ branches/jsc-tailcall/Source/JavaScriptCore/dfg/DFGOSRExitCompiler64.cpp        2015-07-31 06:02:40 UTC (rev 187639)
</span><span class="lines">@@ -202,6 +202,9 @@
</span><span class="cx">     }
</span><span class="cx">     
</span><span class="cx">     // And voila, all GPRs are free to reuse.
</span><ins>+
+    m_jit.emitRestoreCalleeSaves();
+    // The code below cannot use any callee save registers.
</ins><span class="cx">     
</span><span class="cx">     // Save all state from FPRs into the scratch buffer.
</span><span class="cx">     
</span><span class="lines">@@ -318,6 +321,10 @@
</span><span class="cx">             break;
</span><span class="cx">         }
</span><span class="cx">     }
</span><ins>+
+    // The DFG callee saves were restored up above. Save the ones the baseline JIT uses.
+
+    m_jit.emitSaveCalleeSavesFor(m_jit.baselineCodeBlock());
</ins><span class="cx">     
</span><span class="cx">     // Now that things on the stack are recovered, do the arguments recovery. We assume that arguments
</span><span class="cx">     // recoveries don't recursively refer to each other. But, we don't try to assume that they only
</span><span class="lines">@@ -368,7 +375,7 @@
</span><span class="cx">     // Reify inlined call frames.
</span><span class="cx">     
</span><span class="cx">     reifyInlinedCallFrames(m_jit, exit);
</span><del>-    
</del><ins>+
</ins><span class="cx">     // And finish.
</span><span class="cx">     adjustAndJumpToTarget(m_jit, exit);
</span><span class="cx"> }
</span></span></pre></div>
<a id="branchesjsctailcallSourceJavaScriptCoredfgDFGOSRExitCompilerCommoncpp"></a>
<div class="modfile"><h4>Modified: branches/jsc-tailcall/Source/JavaScriptCore/dfg/DFGOSRExitCompilerCommon.cpp (187638 => 187639)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsc-tailcall/Source/JavaScriptCore/dfg/DFGOSRExitCompilerCommon.cpp        2015-07-31 03:48:40 UTC (rev 187638)
+++ branches/jsc-tailcall/Source/JavaScriptCore/dfg/DFGOSRExitCompilerCommon.cpp        2015-07-31 06:02:40 UTC (rev 187639)
</span><span class="lines">@@ -197,6 +197,7 @@
</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><ins>+        jit.emitSaveCalleeSavesFor(baselineCodeBlock, static_cast&lt;VirtualRegister&gt;(inlineCallFrame-&gt;stackOffset));
</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 class="lines">@@ -250,14 +251,14 @@
</span><span class="cx"> void adjustAndJumpToTarget(CCallHelpers&amp; jit, const OSRExitBase&amp; exit)
</span><span class="cx"> {
</span><span class="cx"> #if ENABLE(GGC) 
</span><del>-    jit.move(AssemblyHelpers::TrustedImmPtr(jit.codeBlock()-&gt;ownerExecutable()), GPRInfo::nonArgGPR0);
-    osrWriteBarrier(jit, GPRInfo::nonArgGPR0, GPRInfo::nonArgGPR1);
</del><ins>+    jit.move(AssemblyHelpers::TrustedImmPtr(jit.codeBlock()-&gt;ownerExecutable()), GPRInfo::argumentGPR1);
+    osrWriteBarrier(jit, GPRInfo::argumentGPR1, GPRInfo::nonArgGPR0);
</ins><span class="cx">     InlineCallFrameSet* inlineCallFrames = jit.codeBlock()-&gt;jitCode()-&gt;dfgCommon()-&gt;inlineCallFrames.get();
</span><span class="cx">     if (inlineCallFrames) {
</span><span class="cx">         for (InlineCallFrame* inlineCallFrame : *inlineCallFrames) {
</span><span class="cx">             ScriptExecutable* ownerExecutable = inlineCallFrame-&gt;executable.get();
</span><del>-            jit.move(AssemblyHelpers::TrustedImmPtr(ownerExecutable), GPRInfo::nonArgGPR0); 
-            osrWriteBarrier(jit, GPRInfo::nonArgGPR0, GPRInfo::nonArgGPR1);
</del><ins>+            jit.move(AssemblyHelpers::TrustedImmPtr(ownerExecutable), GPRInfo::argumentGPR1);
+            osrWriteBarrier(jit, GPRInfo::argumentGPR1, GPRInfo::nonArgGPR0);
</ins><span class="cx">         }
</span><span class="cx">     }
</span><span class="cx"> #endif
</span><span class="lines">@@ -277,7 +278,7 @@
</span><span class="cx"> 
</span><span class="cx">     jit.addPtr(AssemblyHelpers::TrustedImm32(JIT::stackPointerOffsetFor(baselineCodeBlock) * sizeof(Register)), GPRInfo::callFrameRegister, AssemblyHelpers::stackPointerRegister);
</span><span class="cx">     
</span><del>-    jit.jitAssertTagsInPlace();
</del><ins>+    jit.emitMaterializeTagCheckRegisters();
</ins><span class="cx"> 
</span><span class="cx">     jit.move(AssemblyHelpers::TrustedImmPtr(jumpTarget), GPRInfo::regT2);
</span><span class="cx">     jit.jump(GPRInfo::regT2);
</span></span></pre></div>
<a id="branchesjsctailcallSourceJavaScriptCoredfgDFGPlancpp"></a>
<div class="modfile"><h4>Modified: branches/jsc-tailcall/Source/JavaScriptCore/dfg/DFGPlan.cpp (187638 => 187639)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsc-tailcall/Source/JavaScriptCore/dfg/DFGPlan.cpp        2015-07-31 03:48:40 UTC (rev 187638)
+++ branches/jsc-tailcall/Source/JavaScriptCore/dfg/DFGPlan.cpp        2015-07-31 06:02:40 UTC (rev 187639)
</span><span class="lines">@@ -213,6 +213,8 @@
</span><span class="cx">         finalizer = std::make_unique&lt;FailedFinalizer&gt;(*this);
</span><span class="cx">         return FailPath;
</span><span class="cx">     }
</span><ins>+
+    codeBlock-&gt;setCalleeSaveRegisters(RegisterSet::dfgCalleeSaveRegisters());
</ins><span class="cx">     
</span><span class="cx">     // By this point the DFG bytecode parser will have potentially mutated various tables
</span><span class="cx">     // in the CodeBlock. This is a good time to perform an early shrink, which is more
</span></span></pre></div>
<a id="branchesjsctailcallSourceJavaScriptCoredfgDFGSpeculativeJIT32_64cpp"></a>
<div class="modfile"><h4>Modified: branches/jsc-tailcall/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp (187638 => 187639)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsc-tailcall/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp        2015-07-31 03:48:40 UTC (rev 187638)
+++ branches/jsc-tailcall/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp        2015-07-31 06:02:40 UTC (rev 187639)
</span><span class="lines">@@ -3082,6 +3082,7 @@
</span><span class="cx">             }
</span><span class="cx">         }
</span><span class="cx"> 
</span><ins>+        m_jit.emitRestoreCalleeSaves();
</ins><span class="cx">         m_jit.emitFunctionEpilogue();
</span><span class="cx">         m_jit.ret();
</span><span class="cx">         
</span></span></pre></div>
<a id="branchesjsctailcallSourceJavaScriptCoredfgDFGSpeculativeJIT64cpp"></a>
<div class="modfile"><h4>Modified: branches/jsc-tailcall/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp (187638 => 187639)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsc-tailcall/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp        2015-07-31 03:48:40 UTC (rev 187638)
+++ branches/jsc-tailcall/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp        2015-07-31 06:02:40 UTC (rev 187639)
</span><span class="lines">@@ -3158,6 +3158,7 @@
</span><span class="cx">         JSValueOperand op1(this, node-&gt;child1());
</span><span class="cx">         m_jit.move(op1.gpr(), GPRInfo::returnValueGPR);
</span><span class="cx"> 
</span><ins>+        m_jit.emitRestoreCalleeSaves();
</ins><span class="cx">         m_jit.emitFunctionEpilogue();
</span><span class="cx">         m_jit.ret();
</span><span class="cx">         
</span></span></pre></div>
<a id="branchesjsctailcallSourceJavaScriptCoredfgDFGStackLayoutPhasecpp"></a>
<div class="modfile"><h4>Modified: branches/jsc-tailcall/Source/JavaScriptCore/dfg/DFGStackLayoutPhase.cpp (187638 => 187639)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsc-tailcall/Source/JavaScriptCore/dfg/DFGStackLayoutPhase.cpp        2015-07-31 03:48:40 UTC (rev 187638)
+++ branches/jsc-tailcall/Source/JavaScriptCore/dfg/DFGStackLayoutPhase.cpp        2015-07-31 06:02:40 UTC (rev 187639)
</span><span class="lines">@@ -129,7 +129,7 @@
</span><span class="cx">         }
</span><span class="cx">         
</span><span class="cx">         Vector&lt;unsigned&gt; allocation(usedLocals.size());
</span><del>-        m_graph.m_nextMachineLocal = 0;
</del><ins>+        m_graph.m_nextMachineLocal = codeBlock()-&gt;calleeSaveSpaceAsVirtualRegisters();
</ins><span class="cx">         for (unsigned i = 0; i &lt; usedLocals.size(); ++i) {
</span><span class="cx">             if (!usedLocals.get(i)) {
</span><span class="cx">                 allocation[i] = UINT_MAX;
</span></span></pre></div>
<a id="branchesjsctailcallSourceJavaScriptCorejitAssemblyHelpersh"></a>
<div class="modfile"><h4>Modified: branches/jsc-tailcall/Source/JavaScriptCore/jit/AssemblyHelpers.h (187638 => 187639)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsc-tailcall/Source/JavaScriptCore/jit/AssemblyHelpers.h        2015-07-31 03:48:40 UTC (rev 187638)
+++ branches/jsc-tailcall/Source/JavaScriptCore/jit/AssemblyHelpers.h        2015-07-31 06:02:40 UTC (rev 187639)
</span><span class="lines">@@ -33,6 +33,7 @@
</span><span class="cx"> #include &quot;GPRInfo.h&quot;
</span><span class="cx"> #include &quot;JITCode.h&quot;
</span><span class="cx"> #include &quot;MacroAssembler.h&quot;
</span><ins>+#include &quot;RegisterSaveMap.h&quot;
</ins><span class="cx"> #include &quot;TypeofType.h&quot;
</span><span class="cx"> #include &quot;VM.h&quot;
</span><span class="cx"> 
</span><span class="lines">@@ -174,6 +175,87 @@
</span><span class="cx"> #endif
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    void emitSaveCalleeSavesFor(CodeBlock* codeBlock, VirtualRegister offsetVirtualRegister = static_cast&lt;VirtualRegister&gt;(0))
+    {
+        ASSERT(codeBlock);
+
+        RegisterSaveMap* calleeSavesMap = codeBlock-&gt;calleeSaveRegisters();
+
+        if (!calleeSavesMap-&gt;size())
+            return;
+
+        VirtualRegister baseVirtualRegister = virtualRegisterForLocal(codeBlock-&gt;calleeSaveSpaceAsVirtualRegisters() - 1) + offsetVirtualRegister;
+
+        for (Reg reg = Reg::first(); reg &lt;= Reg::last(); reg = reg.next()) {
+            if (calleeSavesMap-&gt;has(reg) &amp;&amp; reg.isGPR())
+                storePtr(reg.gpr(), Address(framePointerRegister, baseVirtualRegister.offsetInBytes() + calleeSavesMap-&gt;getOffsetFor(reg)));
+        }
+    }
+
+    void emitRestoreCalleeSavesFor(CodeBlock* codeBlock)
+    {
+        ASSERT(codeBlock);
+
+        RegisterSaveMap* calleeSavesMap = codeBlock-&gt;calleeSaveRegisters();
+
+        if (!calleeSavesMap-&gt;size())
+            return;
+
+        VirtualRegister baseVirtualRegister = virtualRegisterForLocal(codeBlock-&gt;calleeSaveSpaceAsVirtualRegisters() - 1);
+
+        for (Reg reg = Reg::first(); reg &lt;= Reg::last(); reg = reg.next()) {
+            if (calleeSavesMap-&gt;has(reg) &amp;&amp; reg.isGPR())
+                loadPtr(Address(framePointerRegister, baseVirtualRegister.offsetInBytes() + calleeSavesMap-&gt;getOffsetFor(reg)), reg.gpr());
+        }
+    }
+
+    void emitSaveCalleeSaves()
+    {
+        emitSaveCalleeSavesFor(codeBlock());
+    }
+
+    void emitRestoreCalleeSaves()
+    {
+        emitRestoreCalleeSavesFor(codeBlock());
+    }
+
+    void copyCalleeSavesFromFrameOrRegisterToVMCalleeSavesBuffer(GPRReg tempGPR)
+    {
+        ASSERT(codeBlock());
+
+        // Copy saved calleeSaves on stack or unsaved calleeSaves in register to vm calleeSave buffer
+        move(TrustedImmPtr(m_vm), tempGPR);
+        addPtr(TrustedImm32(VM::calleeSaveRegistersBufferOffset()), tempGPR);
+
+        RegisterSaveMap* allCalleeSavesMap = m_vm-&gt;getAllCalleeSaveRegistersMap();
+        RegisterSaveMap* currentCalleeSaves = codeBlock()-&gt;calleeSaveRegisters();
+        VirtualRegister calleeSaveBase = virtualRegisterForLocal(codeBlock()-&gt;calleeSaveSpaceAsVirtualRegisters() - 1);
+
+        for (Reg reg = Reg::first(); reg &lt;= Reg::last(); reg = reg.next()) {
+            GPRReg regToStore;
+
+            if (allCalleeSavesMap-&gt;has(reg) &amp;&amp; reg.isGPR()) {
+                if (currentCalleeSaves-&gt;has(reg)) {
+                    // Load calleeSave from stack into temp register
+                    regToStore = GPRInfo::regT0;
+                    loadPtr(Address(framePointerRegister,  calleeSaveBase.offsetInBytes() + currentCalleeSaves-&gt;getOffsetFor(reg)), regToStore);
+                } else
+                    // Just store callee save directly
+                    regToStore = reg.gpr();
+                
+                storePtr(regToStore, Address(tempGPR, allCalleeSavesMap-&gt;getOffsetFor(reg)));
+            }
+        }
+    }
+
+    void emitMaterializeTagCheckRegisters()
+    {
+#if USE(JSVALUE64)
+        move(MacroAssembler::TrustedImm64(TagTypeNumber), GPRInfo::tagTypeNumberRegister);
+        orPtr(MacroAssembler::TrustedImm32(TagBitTypeOther), GPRInfo::tagTypeNumberRegister, GPRInfo::tagMaskRegister);
+#endif
+    }
+
</ins><span class="cx"> #if CPU(X86_64) || CPU(X86)
</span><span class="cx">     static size_t prologueStackPointerDelta()
</span><span class="cx">     {
</span></span></pre></div>
<a id="branchesjsctailcallSourceJavaScriptCorejitGPRInfoh"></a>
<div class="modfile"><h4>Modified: branches/jsc-tailcall/Source/JavaScriptCore/jit/GPRInfo.h (187638 => 187639)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsc-tailcall/Source/JavaScriptCore/jit/GPRInfo.h        2015-07-31 03:48:40 UTC (rev 187638)
+++ branches/jsc-tailcall/Source/JavaScriptCore/jit/GPRInfo.h        2015-07-31 06:02:40 UTC (rev 187639)
</span><span class="lines">@@ -326,6 +326,8 @@
</span><span class="cx">     static const GPRReg returnValueGPR = X86Registers::eax; // regT0
</span><span class="cx">     static const GPRReg returnValueGPR2 = X86Registers::edx; // regT1
</span><span class="cx">     static const GPRReg nonPreservedNonReturnGPR = X86Registers::ecx;
</span><ins>+    static const int numberOfLLIntBaselineCalleeSaveRegisters = 0;
+    static const int numberCalleeSaveRegisters = 0;
</ins><span class="cx"> 
</span><span class="cx">     static GPRReg toRegister(unsigned index)
</span><span class="cx">     {
</span><span class="lines">@@ -435,6 +437,13 @@
</span><span class="cx">     static const GPRReg nonPreservedNonReturnGPR = X86Registers::r10; // regT5 (regT4 on Windows)
</span><span class="cx">     static const GPRReg nonPreservedNonArgumentGPR = X86Registers::r10; // regT5 (regT4 on Windows)
</span><span class="cx">     static const GPRReg patchpointScratchRegister = MacroAssembler::scratchRegister;
</span><ins>+#if !OS(WINDOWS)
+    static const int numberOfLLIntBaselineCalleeSaveRegisters = 3; // rbx, r14 &amp; r15
+    static const int numberCalleeSaveRegisters = 5;
+#else
+    static const int numberOfLLIntBaselineCalleeSaveRegisters = 4; // rbx, rdi, r14 &amp; r15
+    static const int numberCalleeSaveRegisters = 7;
+#endif
</ins><span class="cx"> 
</span><span class="cx">     static GPRReg toRegister(unsigned index)
</span><span class="cx">     {
</span><span class="lines">@@ -524,6 +533,8 @@
</span><span class="cx">     static const GPRReg returnValueGPR = ARMRegisters::r0; // regT0
</span><span class="cx">     static const GPRReg returnValueGPR2 = ARMRegisters::r1; // regT1
</span><span class="cx">     static const GPRReg nonPreservedNonReturnGPR = ARMRegisters::r5;
</span><ins>+    static const int numberOfLLIntBaselineCalleeSaveRegisters = 0;
+    static const int numberCalleeSaveRegisters = 0;
</ins><span class="cx"> 
</span><span class="cx">     static GPRReg toRegister(unsigned index)
</span><span class="cx">     {
</span><span class="lines">@@ -619,6 +630,8 @@
</span><span class="cx">     static const GPRReg nonPreservedNonReturnGPR = ARM64Registers::x2;
</span><span class="cx">     static const GPRReg nonPreservedNonArgumentGPR = ARM64Registers::x8;
</span><span class="cx">     static const GPRReg patchpointScratchRegister = ARM64Registers::ip0;
</span><ins>+    static const int numberOfLLIntBaselineCalleeSaveRegisters = 3; // x26 (LLInt only), x27 &amp; x28
+    static const int numberCalleeSaveRegisters = 3;
</ins><span class="cx"> 
</span><span class="cx">     // GPRReg mapping is direct, the machine regsiter numbers can
</span><span class="cx">     // be used directly as indices into the GPR RegisterBank.
</span><span class="lines">@@ -706,6 +719,8 @@
</span><span class="cx">     static const GPRReg returnValueGPR = regT0;
</span><span class="cx">     static const GPRReg returnValueGPR2 = regT1;
</span><span class="cx">     static const GPRReg nonPreservedNonReturnGPR = regT2;
</span><ins>+    static const int numberOfLLIntBaselineCalleeSaveRegisters = 0;
+    static const int numberCalleeSaveRegisters = 0;
</ins><span class="cx"> 
</span><span class="cx">     static GPRReg toRegister(unsigned index)
</span><span class="cx">     {
</span><span class="lines">@@ -780,6 +795,8 @@
</span><span class="cx">     static const GPRReg returnValueGPR = regT0;
</span><span class="cx">     static const GPRReg returnValueGPR2 = regT1;
</span><span class="cx">     static const GPRReg nonPreservedNonReturnGPR = regT2;
</span><ins>+    static const int numberOfLLIntBaselineCalleeSaveRegisters = 0;
+    static const int numberCalleeSaveRegisters = 0;
</ins><span class="cx"> 
</span><span class="cx">     static GPRReg toRegister(unsigned index)
</span><span class="cx">     {
</span></span></pre></div>
<a id="branchesjsctailcallSourceJavaScriptCorejitJITcpp"></a>
<div class="modfile"><h4>Modified: branches/jsc-tailcall/Source/JavaScriptCore/jit/JIT.cpp (187638 => 187639)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsc-tailcall/Source/JavaScriptCore/jit/JIT.cpp        2015-07-31 03:48:40 UTC (rev 187638)
+++ branches/jsc-tailcall/Source/JavaScriptCore/jit/JIT.cpp        2015-07-31 06:02:40 UTC (rev 187639)
</span><span class="lines">@@ -90,6 +90,9 @@
</span><span class="cx">     
</span><span class="cx">     skipOptimize.append(branchAdd32(Signed, TrustedImm32(Options::executionCounterIncrementForEntry()), AbsoluteAddress(m_codeBlock-&gt;addressOfJITExecuteCounter())));
</span><span class="cx">     ASSERT(!m_bytecodeOffset);
</span><ins>+
+    copyCalleeSavesFromFrameOrRegisterToVMCalleeSavesBuffer(regT1);
+
</ins><span class="cx">     callOperation(operationOptimize, m_bytecodeOffset);
</span><span class="cx">     skipOptimize.append(branchTestPtr(Zero, returnValueGPR));
</span><span class="cx">     move(returnValueGPR2, stackPointerRegister);
</span><span class="lines">@@ -495,6 +498,8 @@
</span><span class="cx">         break;
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    m_codeBlock-&gt;setCalleeSaveRegisters(RegisterSet::baselineCalleeSaveRegisters());
+
</ins><span class="cx">     // This ensures that we have the most up to date type information when performing typecheck optimizations for op_profile_type.
</span><span class="cx">     if (m_vm-&gt;typeProfiler())
</span><span class="cx">         m_vm-&gt;typeProfilerLog()-&gt;processLogEntries(ASCIILiteral(&quot;Preparing for JIT compilation.&quot;));
</span><span class="lines">@@ -521,6 +526,9 @@
</span><span class="cx"> 
</span><span class="cx">     Label beginLabel(this);
</span><span class="cx"> 
</span><ins>+    emitSaveCalleeSaves();
+    emitMaterializeTagCheckRegisters();
+
</ins><span class="cx">     sampleCodeBlock(m_codeBlock);
</span><span class="cx"> #if ENABLE(OPCODE_SAMPLING)
</span><span class="cx">     sampleInstruction(m_codeBlock-&gt;instructions().begin());
</span></span></pre></div>
<a id="branchesjsctailcallSourceJavaScriptCorejitJITCallcpp"></a>
<div class="modfile"><h4>Modified: branches/jsc-tailcall/Source/JavaScriptCore/jit/JITCall.cpp (187638 => 187639)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsc-tailcall/Source/JavaScriptCore/jit/JITCall.cpp        2015-07-31 03:48:40 UTC (rev 187638)
+++ branches/jsc-tailcall/Source/JavaScriptCore/jit/JITCall.cpp        2015-07-31 06:02:40 UTC (rev 187639)
</span><span class="lines">@@ -192,6 +192,7 @@
</span><span class="cx">     m_callCompilationInfo[callLinkInfoIndex].callLinkInfo = info;
</span><span class="cx"> 
</span><span class="cx">     if (opcodeID == op_tail_call || opcodeID == op_tail_call_varargs) {
</span><ins>+        emitRestoreCalleeSaves();
</ins><span class="cx">         prepareForTailCallSlow();
</span><span class="cx">         m_callCompilationInfo[callLinkInfoIndex].hotPathOther = emitNakedTailCall();
</span><span class="cx">         // We must never come back here
</span><span class="lines">@@ -220,6 +221,9 @@
</span><span class="cx"> 
</span><span class="cx">     move(TrustedImmPtr(m_callCompilationInfo[callLinkInfoIndex].callLinkInfo), regT2);
</span><span class="cx"> 
</span><ins>+    if (opcodeID == op_tail_call || opcodeID == op_tail_call_varargs)
+        emitRestoreCalleeSaves();
+
</ins><span class="cx">     m_callCompilationInfo[callLinkInfoIndex].callReturnLocation = emitNakedCall(m_vm-&gt;getCTIStub(linkCallThunkGenerator).code());
</span><span class="cx"> 
</span><span class="cx">     if (opcodeID == op_tail_call || opcodeID == op_tail_call_varargs) {
</span></span></pre></div>
<a id="branchesjsctailcallSourceJavaScriptCorejitJITCall32_64cpp"></a>
<div class="modfile"><h4>Modified: branches/jsc-tailcall/Source/JavaScriptCore/jit/JITCall32_64.cpp (187638 => 187639)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsc-tailcall/Source/JavaScriptCore/jit/JITCall32_64.cpp        2015-07-31 03:48:40 UTC (rev 187638)
+++ branches/jsc-tailcall/Source/JavaScriptCore/jit/JITCall32_64.cpp        2015-07-31 06:02:40 UTC (rev 187639)
</span><span class="lines">@@ -60,6 +60,7 @@
</span><span class="cx">     emitLoad(dst, regT1, regT0);
</span><span class="cx"> 
</span><span class="cx">     checkStackPointerAlignment();
</span><ins>+    emitRestoreCalleeSaves();
</ins><span class="cx">     emitFunctionEpilogue();
</span><span class="cx">     ret();
</span><span class="cx"> }
</span><span class="lines">@@ -276,6 +277,7 @@
</span><span class="cx"> 
</span><span class="cx">     checkStackPointerAlignment();
</span><span class="cx">     if (opcodeID == op_tail_call || opcodeID == op_tail_call_varargs) {
</span><ins>+        emitRestoreCalleeSaves();
</ins><span class="cx">         prepareForTailCallSlow();
</span><span class="cx">         m_callCompilationInfo[callLinkInfoIndex].hotPathOther = emitNakedTailCall();
</span><span class="cx">         // We must never come back here
</span><span class="lines">@@ -304,6 +306,9 @@
</span><span class="cx"> 
</span><span class="cx">     move(TrustedImmPtr(m_callCompilationInfo[callLinkInfoIndex].callLinkInfo), regT2);
</span><span class="cx"> 
</span><ins>+    if (opcodeID == op_tail_call || opcodeID == op_tail_call_varargs)
+        emitRestoreCalleeSaves();
+
</ins><span class="cx">     m_callCompilationInfo[callLinkInfoIndex].callReturnLocation = emitNakedCall(m_vm-&gt;getCTIStub(linkCallThunkGenerator).code());
</span><span class="cx"> 
</span><span class="cx">     if (opcodeID == op_tail_call || opcodeID == op_tail_call_varargs) {
</span></span></pre></div>
<a id="branchesjsctailcallSourceJavaScriptCorejitJITOpcodescpp"></a>
<div class="modfile"><h4>Modified: branches/jsc-tailcall/Source/JavaScriptCore/jit/JITOpcodes.cpp (187638 => 187639)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsc-tailcall/Source/JavaScriptCore/jit/JITOpcodes.cpp        2015-07-31 03:48:40 UTC (rev 187638)
+++ branches/jsc-tailcall/Source/JavaScriptCore/jit/JITOpcodes.cpp        2015-07-31 06:02:40 UTC (rev 187639)
</span><span class="lines">@@ -70,6 +70,7 @@
</span><span class="cx"> {
</span><span class="cx">     RELEASE_ASSERT(returnValueGPR != callFrameRegister);
</span><span class="cx">     emitGetVirtualRegister(currentInstruction[1].u.operand, returnValueGPR);
</span><ins>+    emitRestoreCalleeSaves();
</ins><span class="cx">     emitFunctionEpilogue();
</span><span class="cx">     ret();
</span><span class="cx"> }
</span><span class="lines">@@ -255,6 +256,7 @@
</span><span class="cx">     emitGetVirtualRegister(currentInstruction[1].u.operand, returnValueGPR);
</span><span class="cx"> 
</span><span class="cx">     checkStackPointerAlignment();
</span><ins>+    emitRestoreCalleeSaves();
</ins><span class="cx">     emitFunctionEpilogue();
</span><span class="cx">     ret();
</span><span class="cx"> }
</span><span class="lines">@@ -665,7 +667,7 @@
</span><span class="cx">     // registers to zap stale pointers, to avoid unnecessarily prolonging
</span><span class="cx">     // object lifetime and increasing GC pressure.
</span><span class="cx">     size_t count = m_codeBlock-&gt;m_numVars;
</span><del>-    for (size_t j = 0; j &lt; count; ++j)
</del><ins>+    for (size_t j = CodeBlock::llintBaselineCalleeSaveSpaceAsVirtualRegisters(); j &lt; count; ++j)
</ins><span class="cx">         emitInitRegister(virtualRegisterForLocal(j).offset());
</span><span class="cx"> 
</span><span class="cx">     emitWriteBarrier(m_codeBlock-&gt;ownerExecutable());
</span><span class="lines">@@ -935,6 +937,8 @@
</span><span class="cx">     if (canBeOptimized()) {
</span><span class="cx">         linkSlowCase(iter);
</span><span class="cx">         
</span><ins>+        copyCalleeSavesFromFrameOrRegisterToVMCalleeSavesBuffer(regT1);
+
</ins><span class="cx">         callOperation(operationOptimize, m_bytecodeOffset);
</span><span class="cx">         Jump noOptimizedEntry = branchTestPtr(Zero, returnValueGPR);
</span><span class="cx">         if (!ASSERT_DISABLED) {
</span></span></pre></div>
<a id="branchesjsctailcallSourceJavaScriptCorejitJITOpcodes32_64cpp"></a>
<div class="modfile"><h4>Modified: branches/jsc-tailcall/Source/JavaScriptCore/jit/JITOpcodes32_64.cpp (187638 => 187639)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsc-tailcall/Source/JavaScriptCore/jit/JITOpcodes32_64.cpp        2015-07-31 03:48:40 UTC (rev 187638)
+++ branches/jsc-tailcall/Source/JavaScriptCore/jit/JITOpcodes32_64.cpp        2015-07-31 06:02:40 UTC (rev 187639)
</span><span class="lines">@@ -149,6 +149,7 @@
</span><span class="cx"> {
</span><span class="cx">     ASSERT(returnValueGPR != callFrameRegister);
</span><span class="cx">     emitLoad(currentInstruction[1].u.operand, regT1, returnValueGPR);
</span><ins>+    emitRestoreCalleeSaves();
</ins><span class="cx">     emitFunctionEpilogue();
</span><span class="cx">     ret();
</span><span class="cx"> }
</span></span></pre></div>
<a id="branchesjsctailcallSourceJavaScriptCorejitJITOperationscpp"></a>
<div class="modfile"><h4>Modified: branches/jsc-tailcall/Source/JavaScriptCore/jit/JITOperations.cpp (187638 => 187639)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsc-tailcall/Source/JavaScriptCore/jit/JITOperations.cpp        2015-07-31 03:48:40 UTC (rev 187638)
+++ branches/jsc-tailcall/Source/JavaScriptCore/jit/JITOperations.cpp        2015-07-31 06:02:40 UTC (rev 187639)
</span><span class="lines">@@ -1216,8 +1216,11 @@
</span><span class="cx">         else
</span><span class="cx">             numVarsWithValues = 0;
</span><span class="cx">         Operands&lt;JSValue&gt; mustHandleValues(codeBlock-&gt;numParameters(), numVarsWithValues);
</span><ins>+        int localsUsedForCalleeSaves = static_cast&lt;int&gt;(CodeBlock::llintBaselineCalleeSaveSpaceAsVirtualRegisters());
</ins><span class="cx">         for (size_t i = 0; i &lt; mustHandleValues.size(); ++i) {
</span><span class="cx">             int operand = mustHandleValues.operandForIndex(i);
</span><ins>+            if (operandIsLocal(operand) &amp;&amp; VirtualRegister(operand).toLocal() &lt; localsUsedForCalleeSaves)
+                continue;
</ins><span class="cx">             mustHandleValues[i] = exec-&gt;uncheckedR(operand).jsValue();
</span><span class="cx">         }
</span><span class="cx"> 
</span></span></pre></div>
<a id="branchesjsctailcallSourceJavaScriptCorejitRegisterSaveMapcpp"></a>
<div class="addfile"><h4>Added: branches/jsc-tailcall/Source/JavaScriptCore/jit/RegisterSaveMap.cpp (0 => 187639)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsc-tailcall/Source/JavaScriptCore/jit/RegisterSaveMap.cpp                                (rev 0)
+++ branches/jsc-tailcall/Source/JavaScriptCore/jit/RegisterSaveMap.cpp        2015-07-31 06:02:40 UTC (rev 187639)
</span><span class="lines">@@ -0,0 +1,56 @@
</span><ins>+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#include &quot;config.h&quot;
+#include &quot;RegisterSaveMap.h&quot;
+
+#if ENABLE(JIT)
+
+#include &quot;MacroAssembler.h&quot;
+
+namespace JSC {
+
+RegisterSaveMap::RegisterSaveMap(RegisterSet registers)
+{
+    m_numberOfRegisters = 0;
+    for (Reg reg = Reg::first(); reg &lt;= Reg::last();reg = reg.next()) {
+        if (registers.get(reg) &amp;&amp; reg.isGPR()) {
+            m_indexForRegister.set(reg.index(), m_numberOfRegisters);
+            m_numberOfRegisters++;
+        }
+    }
+}
+
+unsigned RegisterSaveMap::getIndexFor(Reg reg) const
+{
+    auto iter = m_indexForRegister.find(reg.index());
+    ASSERT(iter != m_indexForRegister.end());
+    return iter-&gt;value;
+}
+
+} // namespace JSC
+
+#endif // ENABLE(JIT)
+
</ins></span></pre></div>
<a id="branchesjsctailcallSourceJavaScriptCorejitRegisterSaveMaph"></a>
<div class="addfile"><h4>Added: branches/jsc-tailcall/Source/JavaScriptCore/jit/RegisterSaveMap.h (0 => 187639)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsc-tailcall/Source/JavaScriptCore/jit/RegisterSaveMap.h                                (rev 0)
+++ branches/jsc-tailcall/Source/JavaScriptCore/jit/RegisterSaveMap.h        2015-07-31 06:02:40 UTC (rev 187639)
</span><span class="lines">@@ -0,0 +1,59 @@
</span><ins>+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#ifndef RegisterSaveMap_h
+#define RegisterSaveMap_h
+
+#if ENABLE(JIT)
+
+#include &quot;GPRInfo.h&quot;
+#include &quot;Reg.h&quot;
+#include &quot;RegisterSet.h&quot;
+#include &lt;wtf/HashMap.h&gt;
+
+namespace JSC {
+
+class RegisterSaveMap {
+public:
+    RegisterSaveMap(RegisterSet registers);
+
+    unsigned size() { return m_numberOfRegisters; }
+    bool has(Reg reg) { return m_indexForRegister.contains(reg.index()); }
+    unsigned maxOffset() { return size() * cpuRegisterSize; }
+    unsigned getIndexFor(Reg) const;
+    unsigned getOffsetFor(Reg reg) const { return getIndexFor(reg) * cpuRegisterSize; }
+private:
+    static const unsigned cpuRegisterSize = sizeof(intptr_t);
+
+    unsigned m_numberOfRegisters;
+    HashMap&lt;unsigned, unsigned, WTF::IntHash&lt;unsigned&gt;, WTF::UnsignedWithZeroKeyHashTraits&lt;unsigned&gt; &gt; m_indexForRegister;
+};
+
+} // namespace JSC
+
+#endif // ENABLE(JIT)
+
+#endif // RegisterSaveMap_h
+
</ins></span></pre></div>
<a id="branchesjsctailcallSourceJavaScriptCorejitRegisterSetcpp"></a>
<div class="modfile"><h4>Modified: branches/jsc-tailcall/Source/JavaScriptCore/jit/RegisterSet.cpp (187638 => 187639)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsc-tailcall/Source/JavaScriptCore/jit/RegisterSet.cpp        2015-07-31 03:48:40 UTC (rev 187638)
+++ branches/jsc-tailcall/Source/JavaScriptCore/jit/RegisterSet.cpp        2015-07-31 06:02:40 UTC (rev 187639)
</span><span class="lines">@@ -122,6 +122,112 @@
</span><span class="cx">     return result;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+RegisterSet RegisterSet::allVMCalleeSaveRegisters()
+{
+    RegisterSet result;
+#if CPU(X86)
+#elif CPU(X86_64)
+    result.set(GPRInfo::regCS0);
+    result.set(GPRInfo::regCS1);
+    result.set(GPRInfo::regCS2);
+#if !OS(WINDOWS)
+    ASSERT(GPRInfo::regCS3 == GPRInfo::tagTypeNumberRegister);
+    ASSERT(GPRInfo::regCS4 == GPRInfo::tagMaskRegister);
+    result.set(GPRInfo::regCS3);
+    result.set(GPRInfo::regCS4);
+#else
+    result.set(GPRInfo::regCS3);
+    result.set(GPRInfo::regCS4);
+    ASSERT(GPRInfo::regCS5 == GPRInfo::tagTypeNumberRegister);
+    ASSERT(GPRInfo::regCS6 == GPRInfo::tagMaskRegister);
+    result.set(GPRInfo::regCS5);
+    result.set(GPRInfo::regCS6);
+#endif
+#elif CPU(ARM_THUMB2)
+#elif CPU(ARM_TRADITIONAL)
+#elif CPU(ARM64)
+    result.set(ARM64Registers::x26);
+    ASSERT(GPRInfo::regCS0 == GPRInfo::tagTypeNumberRegister);
+    ASSERT(GPRInfo::regCS1 == GPRInfo::tagMaskRegister);
+    result.set(GPRInfo::regCS0);
+    result.set(GPRInfo::regCS1);
+#elif CPU(MIPS)
+#elif CPU(SH4)
+#else
+    UNREACHABLE_FOR_PLATFORM();
+#endif
+    return result;
+}
+
+RegisterSet RegisterSet::baselineCalleeSaveRegisters()
+{
+    RegisterSet result;
+#if CPU(X86)
+#elif CPU(X86_64)
+    result.set(GPRInfo::regCS0);
+#if !OS(WINDOWS)
+    ASSERT(GPRInfo::regCS3 == GPRInfo::tagTypeNumberRegister);
+    ASSERT(GPRInfo::regCS4 == GPRInfo::tagMaskRegister);
+    result.set(GPRInfo::regCS3);
+    result.set(GPRInfo::regCS4);
+#else
+    result.set(GPRInfo::regCS4);
+    ASSERT(GPRInfo::regCS5 == GPRInfo::tagTypeNumberRegister);
+    ASSERT(GPRInfo::regCS6 == GPRInfo::tagMaskRegister);
+    result.set(GPRInfo::regCS5);
+    result.set(GPRInfo::regCS6);
+#endif
+#elif CPU(ARM_THUMB2)
+#elif CPU(ARM_TRADITIONAL)
+#elif CPU(ARM64)
+    ASSERT(GPRInfo::regCS0 == GPRInfo::tagTypeNumberRegister);
+    ASSERT(GPRInfo::regCS1 == GPRInfo::tagMaskRegister);
+    result.set(GPRInfo::regCS0);
+    result.set(GPRInfo::regCS1);
+#elif CPU(MIPS)
+#elif CPU(SH4)
+#else
+    UNREACHABLE_FOR_PLATFORM();
+#endif
+    return result;
+}
+
+RegisterSet RegisterSet::dfgCalleeSaveRegisters()
+{
+    RegisterSet result;
+#if CPU(X86)
+#elif CPU(X86_64)
+    result.set(GPRInfo::regCS0);
+    result.set(GPRInfo::regCS1);
+    result.set(GPRInfo::regCS2);
+#if !OS(WINDOWS)
+    ASSERT(GPRInfo::regCS3 == GPRInfo::tagTypeNumberRegister);
+    ASSERT(GPRInfo::regCS4 == GPRInfo::tagMaskRegister);
+    result.set(GPRInfo::regCS3);
+    result.set(GPRInfo::regCS4);
+#else
+    result.set(GPRInfo::regCS3);
+    result.set(GPRInfo::regCS4);
+    ASSERT(GPRInfo::regCS5 == GPRInfo::tagTypeNumberRegister);
+    ASSERT(GPRInfo::regCS6 == GPRInfo::tagMaskRegister);
+    result.set(GPRInfo::regCS5);
+    result.set(GPRInfo::regCS6);
+#endif
+#elif CPU(ARM_THUMB2)
+#elif CPU(ARM_TRADITIONAL)
+#elif CPU(ARM64)
+    ASSERT(GPRInfo::regCS0 == GPRInfo::tagTypeNumberRegister);
+    ASSERT(GPRInfo::regCS1 == GPRInfo::tagMaskRegister);
+    result.set(GPRInfo::regCS0);
+    result.set(GPRInfo::regCS1);
+#elif CPU(MIPS)
+#elif CPU(SH4)
+#else
+    UNREACHABLE_FOR_PLATFORM();
+#endif
+    return result;
+}
+
</ins><span class="cx"> RegisterSet RegisterSet::allGPRs()
</span><span class="cx"> {
</span><span class="cx">     RegisterSet result;
</span></span></pre></div>
<a id="branchesjsctailcallSourceJavaScriptCorejitRegisterSeth"></a>
<div class="modfile"><h4>Modified: branches/jsc-tailcall/Source/JavaScriptCore/jit/RegisterSet.h (187638 => 187639)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsc-tailcall/Source/JavaScriptCore/jit/RegisterSet.h        2015-07-31 03:48:40 UTC (rev 187638)
+++ branches/jsc-tailcall/Source/JavaScriptCore/jit/RegisterSet.h        2015-07-31 06:02:40 UTC (rev 187639)
</span><span class="lines">@@ -50,6 +50,9 @@
</span><span class="cx">     static RegisterSet runtimeRegisters();
</span><span class="cx">     static RegisterSet specialRegisters(); // The union of stack, reserved hardware, and runtime registers.
</span><span class="cx">     static RegisterSet calleeSaveRegisters();
</span><ins>+    static RegisterSet allVMCalleeSaveRegisters(); // The union of egisters saved and used by any VM.
+    static RegisterSet baselineCalleeSaveRegisters(); // Registers saved and used by the baseline JIT.
+    static RegisterSet dfgCalleeSaveRegisters(); // Registers saved and used by the DFG JIT.
</ins><span class="cx">     static RegisterSet allGPRs();
</span><span class="cx">     static RegisterSet allFPRs();
</span><span class="cx">     static RegisterSet allRegisters();
</span></span></pre></div>
<a id="branchesjsctailcallSourceJavaScriptCorejitRepatchcpp"></a>
<div class="modfile"><h4>Modified: branches/jsc-tailcall/Source/JavaScriptCore/jit/Repatch.cpp (187638 => 187639)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsc-tailcall/Source/JavaScriptCore/jit/Repatch.cpp        2015-07-31 03:48:40 UTC (rev 187638)
+++ branches/jsc-tailcall/Source/JavaScriptCore/jit/Repatch.cpp        2015-07-31 06:02:40 UTC (rev 187639)
</span><span class="lines">@@ -1881,6 +1881,7 @@
</span><span class="cx">                 CCallHelpers::Address(fastCountsBaseGPR, caseIndex * sizeof(uint32_t)));
</span><span class="cx">         }
</span><span class="cx">         if (callLinkInfo.isTailCall()) {
</span><ins>+            stubJit.emitRestoreCalleeSaves();
</ins><span class="cx">             stubJit.prepareForTailCallSlow();
</span><span class="cx">             calls[caseIndex].call = stubJit.nearTailCall();
</span><span class="cx">         } else
</span></span></pre></div>
<a id="branchesjsctailcallSourceJavaScriptCorellintLLIntDatacpp"></a>
<div class="modfile"><h4>Modified: branches/jsc-tailcall/Source/JavaScriptCore/llint/LLIntData.cpp (187638 => 187639)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsc-tailcall/Source/JavaScriptCore/llint/LLIntData.cpp        2015-07-31 03:48:40 UTC (rev 187638)
+++ branches/jsc-tailcall/Source/JavaScriptCore/llint/LLIntData.cpp        2015-07-31 06:02:40 UTC (rev 187639)
</span><span class="lines">@@ -26,6 +26,7 @@
</span><span class="cx"> #include &quot;config.h&quot;
</span><span class="cx"> #include &quot;LLIntData.h&quot;
</span><span class="cx"> #include &quot;BytecodeConventions.h&quot;
</span><ins>+#include &quot;CodeBlock.h&quot;
</ins><span class="cx"> #include &quot;CodeType.h&quot;
</span><span class="cx"> #include &quot;Instruction.h&quot;
</span><span class="cx"> #include &quot;JSScope.h&quot;
</span><span class="lines">@@ -131,6 +132,15 @@
</span><span class="cx"> #elif CPU(X86_64) &amp;&amp; OS(WINDOWS)
</span><span class="cx">     ASSERT(maxFrameExtentForSlowPathCall == 64);
</span><span class="cx"> #endif
</span><ins>+
+#if !ENABLE(JIT) || USE(JSVALUE32_64)
+    ASSERT(!CodeBlock::llintBaselineCalleeSaveSpaceAsVirtualRegisters());
+#elif (CPU(X86_64) &amp;&amp; !OS(WINDOWS))  || CPU(ARM64)
+    ASSERT(CodeBlock::llintBaselineCalleeSaveSpaceAsVirtualRegisters() == 3);
+#elif (CPU(X86_64) &amp;&amp; OS(WINDOWS))
+    ASSERT(CodeBlock::llintBaselineCalleeSaveSpaceAsVirtualRegisters() == 4);
+#endif
+    
</ins><span class="cx">     ASSERT(StringType == 6);
</span><span class="cx">     ASSERT(ObjectType == 18);
</span><span class="cx">     ASSERT(FinalObjectType == 19);
</span></span></pre></div>
<a id="branchesjsctailcallSourceJavaScriptCorellintLowLevelInterpreterasm"></a>
<div class="modfile"><h4>Modified: branches/jsc-tailcall/Source/JavaScriptCore/llint/LowLevelInterpreter.asm (187638 => 187639)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsc-tailcall/Source/JavaScriptCore/llint/LowLevelInterpreter.asm        2015-07-31 03:48:40 UTC (rev 187638)
+++ branches/jsc-tailcall/Source/JavaScriptCore/llint/LowLevelInterpreter.asm        2015-07-31 06:02:40 UTC (rev 187639)
</span><span class="lines">@@ -217,6 +217,14 @@
</span><span class="cx">     const maxFrameExtentForSlowPathCall = 64
</span><span class="cx"> end
</span><span class="cx"> 
</span><ins>+if X86_64 or ARM64
+    const CalleeSaveSpaceAsVirtualRegisters = 3
+elsif X86_64_WIN
+    const CalleeSaveSpaceAsVirtualRegisters = 4
+else
+    const CalleeSaveSpaceAsVirtualRegisters = 0
+end
+
</ins><span class="cx"> # Watchpoint states
</span><span class="cx"> const ClearWatchpoint = 0
</span><span class="cx"> const IsWatched = 1
</span><span class="lines">@@ -526,6 +534,52 @@
</span><span class="cx">     end
</span><span class="cx"> end
</span><span class="cx"> 
</span><ins>+macro preserveCalleeSavesUsedByLLInt()
+    if C_LOOP
+    elsif ARM or ARMv7_TRADITIONAL
+    elsif ARMv7
+    elsif ARM64
+        emit &quot;stp x27, x28, [fp, #-16]&quot;
+        emit &quot;stp xzr, x26, [fp, #-32]&quot;
+    elsif MIPS
+    elsif SH4
+    elsif X86
+    elsif X86_WIN
+    elsif X86_64
+        storep csr2, -8[cfr]
+        storep csr1, -16[cfr]
+        storep csr0, -24[cfr]
+    elsif X86_64_WIN
+        storep t4, -8[cfr]
+        storep csr2, -16[cfr]
+        storep csr1, -24[cfr]
+        storep csr0, -32[cfr]
+    end
+end
+
+macro restoreCalleeSavesUsedByLLInt()
+    if C_LOOP
+    elsif ARM or ARMv7_TRADITIONAL
+    elsif ARMv7
+    elsif ARM64
+        emit &quot;ldp xzr, x26, [fp, #-32]&quot;
+        emit &quot;ldp x27, x28, [fp, #-16]&quot;
+    elsif MIPS
+    elsif SH4
+    elsif X86
+    elsif X86_WIN
+    elsif X86_64
+        loadp -24[cfr], csr0
+        loadp -16[cfr], csr1
+        loadp -8[cfr], csr2
+    elsif X86_64_WIN
+        loadp -32[cfr], csr0
+        loadp -24[cfr], csr1
+        loadp -16[cfr], csr2
+        loadp -8[cfr], t4
+    end
+end
+
</ins><span class="cx"> macro preserveReturnAddressAfterCall(destinationRegister)
</span><span class="cx">     if C_LOOP or ARM or ARMv7 or ARMv7_TRADITIONAL or ARM64 or MIPS or SH4
</span><span class="cx">         # In C_LOOP case, we're only preserving the bytecode vPC.
</span><span class="lines">@@ -769,6 +823,13 @@
</span><span class="cx"> 
</span><span class="cx">     codeBlockSetter(t1)
</span><span class="cx"> 
</span><ins>+    preserveCalleeSavesUsedByLLInt()
+
+    if JSVALUE64
+        move TagTypeNumber, tagTypeNumber
+        addp TagBitTypeOther, tagTypeNumber, tagMask
+    end
+
</ins><span class="cx">     # Set up the PC.
</span><span class="cx">     if JSVALUE64
</span><span class="cx">         loadp CodeBlock::m_instructions[t1], PB
</span><span class="lines">@@ -854,6 +915,7 @@
</span><span class="cx"> end
</span><span class="cx"> 
</span><span class="cx"> macro doReturn()
</span><ins>+    restoreCalleeSavesUsedByLLInt()
</ins><span class="cx">     restoreCallerPCAndCFR()
</span><span class="cx">     ret
</span><span class="cx"> end
</span></span></pre></div>
<a id="branchesjsctailcallSourceJavaScriptCorellintLowLevelInterpreter64asm"></a>
<div class="modfile"><h4>Modified: branches/jsc-tailcall/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm (187638 => 187639)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsc-tailcall/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm        2015-07-31 03:48:40 UTC (rev 187638)
+++ branches/jsc-tailcall/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm        2015-07-31 06:02:40 UTC (rev 187639)
</span><span class="lines">@@ -493,19 +493,6 @@
</span><span class="cx">     jmp _llint_throw_from_slow_path_trampoline
</span><span class="cx"> 
</span><span class="cx"> .noError:
</span><del>-    # r1 points to ArityCheckData.
-    loadp CommonSlowPaths::ArityCheckData::thunkToCall[r1], t3
-    btpz t3, .proceedInline
-    
-    loadp CommonSlowPaths::ArityCheckData::paddedStackSpace[r1], a0
-    call t3
-    if ASSERT_ENABLED
-        loadp ReturnPC[cfr], t0
-        loadp [t0], t0
-    end
-    jmp .continue
-
-.proceedInline:
</del><span class="cx">     loadi CommonSlowPaths::ArityCheckData::paddedStackSpace[r1], t1
</span><span class="cx">     btiz t1, .continue
</span><span class="cx"> 
</span><span class="lines">@@ -513,8 +500,9 @@
</span><span class="cx">     lshiftp 1, t1
</span><span class="cx">     negq t1
</span><span class="cx">     move cfr, t3
</span><ins>+    subp CalleeSaveSpaceAsVirtualRegisters * 8, t3
</ins><span class="cx">     loadi PayloadOffset + ArgumentCount[cfr], t2
</span><del>-    addi CallFrameHeaderSlots, t2
</del><ins>+    addi CallFrameHeaderSlots + CalleeSaveSpaceAsVirtualRegisters, t2
</ins><span class="cx"> .copyLoop:
</span><span class="cx">     loadq [t3], t0
</span><span class="cx">     storeq t0, [t3, t1, 8]
</span><span class="lines">@@ -557,12 +545,15 @@
</span><span class="cx">     checkStackPointerAlignment(t2, 0xdead00e1)
</span><span class="cx">     loadp CodeBlock[cfr], t2                // t2&lt;CodeBlock&gt; = cfr.CodeBlock
</span><span class="cx">     loadi CodeBlock::m_numVars[t2], t2      // t2&lt;size_t&gt; = t2&lt;CodeBlock&gt;.m_numVars
</span><ins>+    subq CalleeSaveSpaceAsVirtualRegisters, t2
+    move cfr, t1
+    subq CalleeSaveSpaceAsVirtualRegisters * 8, t1
</ins><span class="cx">     btiz t2, .opEnterDone
</span><span class="cx">     move ValueUndefined, t0
</span><span class="cx">     negi t2
</span><span class="cx">     sxi2q t2, t2
</span><span class="cx"> .opEnterLoop:
</span><del>-    storeq t0, [cfr, t2, 8]
</del><ins>+    storeq t0, [t1, t2, 8]
</ins><span class="cx">     addq 1, t2
</span><span class="cx">     btqnz t2, .opEnterLoop
</span><span class="cx"> .opEnterDone:
</span></span></pre></div>
<a id="branchesjsctailcallSourceJavaScriptCoreruntimeVMcpp"></a>
<div class="modfile"><h4>Modified: branches/jsc-tailcall/Source/JavaScriptCore/runtime/VM.cpp (187638 => 187639)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsc-tailcall/Source/JavaScriptCore/runtime/VM.cpp        2015-07-31 03:48:40 UTC (rev 187638)
+++ branches/jsc-tailcall/Source/JavaScriptCore/runtime/VM.cpp        2015-07-31 06:02:40 UTC (rev 187639)
</span><span class="lines">@@ -75,6 +75,7 @@
</span><span class="cx"> #include &quot;PropertyMapHashTable.h&quot;
</span><span class="cx"> #include &quot;RegExpCache.h&quot;
</span><span class="cx"> #include &quot;RegExpObject.h&quot;
</span><ins>+#include &quot;RegisterSaveMap.h&quot;
</ins><span class="cx"> #include &quot;RuntimeType.h&quot;
</span><span class="cx"> #include &quot;SimpleTypedArrayController.h&quot;
</span><span class="cx"> #include &quot;SourceProviderCache.h&quot;
</span><span class="lines">@@ -245,6 +246,7 @@
</span><span class="cx"> 
</span><span class="cx"> #if ENABLE(JIT)
</span><span class="cx">     jitStubs = std::make_unique&lt;JITThunks&gt;();
</span><ins>+    allCalleeSaveRegistersMap = std::make_unique&lt;RegisterSaveMap&gt;(RegisterSet::allVMCalleeSaveRegisters());
</ins><span class="cx"> #endif
</span><span class="cx">     arityCheckData = std::make_unique&lt;CommonSlowPaths::ArityCheckData&gt;();
</span><span class="cx"> 
</span></span></pre></div>
<a id="branchesjsctailcallSourceJavaScriptCoreruntimeVMh"></a>
<div class="modfile"><h4>Modified: branches/jsc-tailcall/Source/JavaScriptCore/runtime/VM.h (187638 => 187639)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsc-tailcall/Source/JavaScriptCore/runtime/VM.h        2015-07-31 03:48:40 UTC (rev 187638)
+++ branches/jsc-tailcall/Source/JavaScriptCore/runtime/VM.h        2015-07-31 06:02:40 UTC (rev 187639)
</span><span class="lines">@@ -33,6 +33,9 @@
</span><span class="cx"> #include &quot;DateInstanceCache.h&quot;
</span><span class="cx"> #include &quot;ExecutableAllocator.h&quot;
</span><span class="cx"> #include &quot;FunctionHasExecutedCache.h&quot;
</span><ins>+#if ENABLE(JIT)
+#include &quot;GPRInfo.h&quot;
+#endif
</ins><span class="cx"> #include &quot;Heap.h&quot;
</span><span class="cx"> #include &quot;Intrinsic.h&quot;
</span><span class="cx"> #include &quot;JITThunks.h&quot;
</span><span class="lines">@@ -89,6 +92,7 @@
</span><span class="cx"> class LegacyProfiler;
</span><span class="cx"> class NativeExecutable;
</span><span class="cx"> class RegExpCache;
</span><ins>+class RegisterSaveMap;
</ins><span class="cx"> class ScriptExecutable;
</span><span class="cx"> class SourceProvider;
</span><span class="cx"> class SourceProviderCache;
</span><span class="lines">@@ -331,12 +335,23 @@
</span><span class="cx">     std::unique_ptr&lt;Keywords&gt; keywords;
</span><span class="cx">     Interpreter* interpreter;
</span><span class="cx"> #if ENABLE(JIT)
</span><ins>+    intptr_t calleeSaveRegistersBuffer[GPRInfo::numberCalleeSaveRegisters];
+
+    static ptrdiff_t calleeSaveRegistersBufferOffset()
+    {
+        return OBJECT_OFFSETOF(VM, calleeSaveRegistersBuffer);
+    }
+
</ins><span class="cx">     std::unique_ptr&lt;JITThunks&gt; jitStubs;
</span><span class="cx">     MacroAssemblerCodeRef getCTIStub(ThunkGenerator generator)
</span><span class="cx">     {
</span><span class="cx">         return jitStubs-&gt;ctiStub(this, generator);
</span><span class="cx">     }
</span><span class="cx">     NativeExecutable* getHostFunction(NativeFunction, Intrinsic);
</span><ins>+    
+    std::unique_ptr&lt;RegisterSaveMap&gt; allCalleeSaveRegistersMap;
+    
+    RegisterSaveMap* getAllCalleeSaveRegistersMap() { return allCalleeSaveRegistersMap.get(); }
</ins><span class="cx"> 
</span><span class="cx"> #endif // ENABLE(JIT)
</span><span class="cx">     std::unique_ptr&lt;CommonSlowPaths::ArityCheckData&gt; arityCheckData;
</span></span></pre>
</div>
</div>

</body>
</html>