<!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>[189575] trunk/Source/JavaScriptCore</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/189575">189575</a></dd>
<dt>Author</dt> <dd>msaboff@apple.com</dd>
<dt>Date</dt> <dd>2015-09-10 10:47:16 -0700 (Thu, 10 Sep 2015)</dd>
</dl>

<h3>Log Message</h3>
<pre>Add support for Callee-Saves registers
https://bugs.webkit.org/show_bug.cgi?id=148666

Reviewed by Filip Pizlo.

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

Added handling of callee save register restoration to exception handling.
The basic flow is when an exception is thrown or one is recognized to
have been generated in C++ code, we save the current state of all
callee save registers to VM::calleeSaveRegistersBuffer.  As we unwind
looking for the corresponding catch, we copy the callee saves from call 
frames to the same VM::calleeSaveRegistersBuffer.  This is done for all
call frames on the stack up to but not including the call frame that has
the corresponding catch block.  When we process the catch, we restore
the callee save registers with the contents of VM::calleeSaveRegistersBuffer.
If there isn't a catch, then handleUncaughtException will restore callee
saves before it returns back to the calling C++.

Eliminated callee saves registers as free registers for various thunk
generators as the callee saves may not have been saved by the function
calling the thunk.

Added code to transition callee saves from one VM's format to the another
as part of OSR entry and OSR exit.

Cleaned up the static RegisterSet's including adding one for LLInt and 
baseline JIT callee saves and one to be used to allocate local registers
not including the callee saves or other special registers.

Moved ftl/FTLRegisterAtOffset.{cpp,h} to jit/RegisterAtOffset.{cpp,h}.
Factored out the vector of RegisterAtOffsets in ftl/FTLUnwindInfo.{cpp,h}
into a new class in jit/RegisterAtOffsetList.{cpp,h}.
Eliminted UnwindInfo and changed UnwindInfo::parse() into a standalone
function named parseUnwindInfo.  That standalone function now returns
the callee saves RegisterAtOffsetList.  This is stored in the CodeBlock
and used instead of UnwindInfo.

Turned off register preservation thunks for outgoing calls from FTL
generated code.  THey'll be removed in a subsequent patch.

Changed specialized thinks to save and restore the contents of
tagTypeNumberRegister and tagMaskRegister as they can be called by FTL
compiled functions.  We materialize those tag registers for the thunk's
use and then restore the prior contents on function exit.

Also removed the arity check fail return thunk since it is now the
caller's responsibility to restore the stack pointer.

Removed saving of callee save registers and materialization of special
tag registers for 64 bit platforms from vmEntryToJavaScript and
vmEntryToNative.

* CMakeLists.txt:
* JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
* JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters:
* JavaScriptCore.xcodeproj/project.pbxproj:
* ftl/FTLJITCode.h:
* ftl/FTLRegisterAtOffset.cpp: Removed.
* ftl/FTLRegisterAtOffset.h: Removed.
* ftl/FTLUnwindInfo.cpp:
(JSC::FTL::parseUnwindInfo):
(JSC::FTL::UnwindInfo::UnwindInfo): Deleted.
(JSC::FTL::UnwindInfo::~UnwindInfo): Deleted.
(JSC::FTL::UnwindInfo::parse): Deleted.
(JSC::FTL::UnwindInfo::dump): Deleted.
(JSC::FTL::UnwindInfo::find): Deleted.
(JSC::FTL::UnwindInfo::indexOf): Deleted.
* ftl/FTLUnwindInfo.h:
(JSC::RegisterAtOffset::dump):
* jit/RegisterAtOffset.cpp: Added.
* jit/RegisterAtOffset.h: Added.
(JSC::RegisterAtOffset::RegisterAtOffset):
(JSC::RegisterAtOffset::operator!):
(JSC::RegisterAtOffset::reg):
(JSC::RegisterAtOffset::offset):
(JSC::RegisterAtOffset::offsetAsIndex):
(JSC::RegisterAtOffset::operator==):
(JSC::RegisterAtOffset::operator&lt;):
(JSC::RegisterAtOffset::getReg):
* jit/RegisterAtOffsetList.cpp: Added.
(JSC::RegisterAtOffsetList::RegisterAtOffsetList):
(JSC::RegisterAtOffsetList::sort):
(JSC::RegisterAtOffsetList::dump):
(JSC::RegisterAtOffsetList::find):
(JSC::RegisterAtOffsetList::indexOf):
* jit/RegisterAtOffsetList.h: Added.
(JSC::RegisterAtOffsetList::clear):
(JSC::RegisterAtOffsetList::size):
(JSC::RegisterAtOffsetList::at):
(JSC::RegisterAtOffsetList::append):
Move and refactored use of FTLRegisterAtOffset to RegisterAtOffset.
Added RegisterAtOffset and RegisterAtOffsetList to build configurations.
Remove FTLRegisterAtOffset files.

* bytecode/CallLinkInfo.h:
(JSC::CallLinkInfo::setUpCallFromFTL):
Turned off FTL register preservation thunks.

* bytecode/CodeBlock.cpp:
(JSC::CodeBlock::CodeBlock):
(JSC::CodeBlock::setCalleeSaveRegisters):
(JSC::roundCalleeSaveSpaceAsVirtualRegisters):
(JSC::CodeBlock::llintBaselineCalleeSaveSpaceAsVirtualRegisters):
(JSC::CodeBlock::calleeSaveSpaceAsVirtualRegisters):
* 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 VirtualRegisters for callee saves.

* bytecompiler/BytecodeGenerator.cpp:
(JSC::BytecodeGenerator::BytecodeGenerator):
(JSC::BytecodeGenerator::allocateCalleeSaveSpace):
* bytecompiler/BytecodeGenerator.h:
Allocate the appropriate number of VirtualRegisters 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::compileExceptionHandlers):
(JSC::DFG::JITCompiler::compile):
(JSC::DFG::JITCompiler::compileFunction):
* dfg/DFGJITCompiler.h:
* interpreter/Interpreter.cpp:
(JSC::UnwindFunctor::operator()):
(JSC::UnwindFunctor::copyCalleeSavesToVMCalleeSavesBuffer):
* dfg/DFGPlan.cpp:
(JSC::DFG::Plan::compileInThreadImpl):
* dfg/DFGSpeculativeJIT.cpp:
(JSC::DFG::SpeculativeJIT::usedRegisters):
* dfg/DFGSpeculativeJIT32_64.cpp:
(JSC::DFG::SpeculativeJIT::compile):
* dfg/DFGSpeculativeJIT64.cpp:
(JSC::DFG::SpeculativeJIT::compile):
* dfg/DFGStackLayoutPhase.cpp:
(JSC::DFG::StackLayoutPhase::run):
* ftl/FTLCompile.cpp:
(JSC::FTL::fixFunctionBasedOnStackMaps):
(JSC::FTL::compile):
* ftl/FTLLink.cpp:
(JSC::FTL::link):
* ftl/FTLOSRExitCompiler.cpp:
(JSC::FTL::compileStub):
* ftl/FTLThunks.cpp:
(JSC::FTL::osrExitGenerationThunkGenerator):
* jit/ArityCheckFailReturnThunks.cpp: Removed.
* jit/ArityCheckFailReturnThunks.h: Removed.
* jit/JIT.cpp:
(JSC::JIT::emitEnterOptimizationCheck):
(JSC::JIT::privateCompile):
(JSC::JIT::privateCompileExceptionHandlers):
* jit/JITCall32_64.cpp:
(JSC::JIT::emit_op_ret):
* jit/JITExceptions.cpp:
(JSC::genericUnwind):
* jit/JITExceptions.h:
* jit/JITOpcodes.cpp:
(JSC::JIT::emit_op_end):
(JSC::JIT::emit_op_ret):
(JSC::JIT::emit_op_throw):
(JSC::JIT::emit_op_catch):
(JSC::JIT::emit_op_enter):
(JSC::JIT::emitSlow_op_loop_hint):
* jit/JITOpcodes32_64.cpp:
(JSC::JIT::emit_op_end):
(JSC::JIT::emit_op_throw):
(JSC::JIT::emit_op_catch):
* jit/JITOperations.cpp:
* jit/Repatch.cpp:
(JSC::generateByIdStub):
* jit/ThunkGenerators.cpp:
* llint/LLIntData.cpp:
(JSC::LLInt::Data::performAssertions):
* llint/LLIntSlowPaths.cpp:
(JSC::LLInt::LLINT_SLOW_PATH_DECL):
* llint/LowLevelInterpreter.asm:
* llint/LowLevelInterpreter32_64.asm:
* llint/LowLevelInterpreter64.asm:
(JSC::throwExceptionFromCallSlowPathGenerator):
(JSC::arityFixupGenerator):
* runtime/CommonSlowPaths.cpp:
(JSC::setupArityCheckData):
* runtime/CommonSlowPaths.h:
(JSC::CommonSlowPaths::arityCheckFor):
Emit code to save and restore callee save registers and materialize tagTypeNumberRegister
and tagMaskRegister.
Handle callee saves when tiering up.
Copy callee saves register contents to VM::calleeSaveRegistersBuffer at beginning of
exception processing.
Process callee save registers in frames when unwinding from an exception.
Restore callee saves register contents from VM::calleeSaveRegistersBuffer on catch.
Use appropriate register set to make sure we don't allocate a callee save register when
compiling a thunk.
Helper to populate tagTypeNumberRegister and tagMaskRegister with the appropriate
constants.
Removed arity fixup return thunks.

* dfg/DFGOSREntry.cpp:
(JSC::DFG::prepareOSREntry):
* dfg/DFGOSRExitCompiler32_64.cpp:
(JSC::DFG::OSRExitCompiler::compileExit):
* dfg/DFGOSRExitCompiler64.cpp:
(JSC::DFG::OSRExitCompiler::compileExit):
* dfg/DFGOSRExitCompilerCommon.cpp:
(JSC::DFG::reifyInlinedCallFrames):
(JSC::DFG::adjustAndJumpToTarget):
Restore callee saves from the DFG and save the appropriate ones for the baseline JIT.
Materialize the tag registers on 64 bit platforms.

* jit/AssemblyHelpers.h:
(JSC::AssemblyHelpers::emitSaveCalleeSavesFor):
(JSC::AssemblyHelpers::emitRestoreCalleeSavesFor):
(JSC::AssemblyHelpers::emitSaveCalleeSaves):
(JSC::AssemblyHelpers::emitRestoreCalleeSaves):
(JSC::AssemblyHelpers::copyCalleeSavesToVMCalleeSavesBuffer):
(JSC::AssemblyHelpers::restoreCalleeSavesFromVMCalleeSavesBuffer):
(JSC::AssemblyHelpers::copyCalleeSavesFromFrameOrRegisterToVMCalleeSavesBuffer):
(JSC::AssemblyHelpers::emitMaterializeTagCheckRegisters):
New helpers to save and restore callee saves as well as materialize the tag registers
contents.

* jit/FPRInfo.h:
* jit/GPRInfo.h:
(JSC::GPRInfo::toRegister):
Updated to include FP callee save registers.  Added number of callee saves registers and
cleanup register aliases that collide with callee save registers.

* jit/JITPropertyAccess.cpp:
(JSC::JIT::emitGetByValWithCachedId):
(JSC::JIT::emitPutByValWithCachedId):
(JSC::JIT::emit_op_get_by_id):
(JSC::JIT::emit_op_put_by_id):
* jit/JITPropertyAccess32_64.cpp:
(JSC::JIT::emitGetByValWithCachedId):
(JSC::JIT::emitPutByValWithCachedId):
(JSC::JIT::emit_op_get_by_id):
(JSC::JIT::emit_op_put_by_id):
Uses new stubUnavailableRegisters register set to limit what registers are available for 
temporaries.

* jit/RegisterSet.cpp:
(JSC::RegisterSet::stubUnavailableRegisters):
(JSC::RegisterSet::calleeSaveRegisters):
(JSC::RegisterSet::llintBaselineCalleeSaveRegisters):
(JSC::RegisterSet::dfgCalleeSaveRegisters):
(JSC::RegisterSet::ftlCalleeSaveRegisters):
* jit/RegisterSet.h:
New register sets with the callee saves used by various tiers as well as one listing registers
not availble to stub code.

* jit/SpecializedThunkJIT.h:
(JSC::SpecializedThunkJIT::SpecializedThunkJIT):
(JSC::SpecializedThunkJIT::loadDoubleArgument):
(JSC::SpecializedThunkJIT::returnJSValue):
(JSC::SpecializedThunkJIT::returnDouble):
(JSC::SpecializedThunkJIT::returnInt32):
(JSC::SpecializedThunkJIT::returnJSCell):
(JSC::SpecializedThunkJIT::callDoubleToDoublePreservingReturn):
(JSC::SpecializedThunkJIT::emitSaveThenMaterializeTagRegisters):
(JSC::SpecializedThunkJIT::emitRestoreSavedTagRegisters):
(JSC::SpecializedThunkJIT::tagReturnAsInt32):
* jit/ThunkGenerators.cpp:
(JSC::nativeForGenerator):
Changed to save and restore existing tag register contents as the may contain other values.
After saving the existing values, we materialize the tag constants.

* jit/TempRegisterSet.h:
(JSC::TempRegisterSet::getFPRByIndex):
(JSC::TempRegisterSet::getFreeFPR):
(JSC::TempRegisterSet::setByIndex):
* offlineasm/arm64.rb:
* offlineasm/registers.rb:
Added methods for floating point registers to support callee save FP registers.

* jit/JITArithmetic32_64.cpp:
(JSC::JIT::emit_op_mod):
Removed unnecessary #if CPU(X86_64) check to this 32 bit only file.

* offlineasm/x86.rb:
Fixed Windows callee saves naming.

* 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="#trunkSourceJavaScriptCoreCMakeListstxt">trunk/Source/JavaScriptCore/CMakeLists.txt</a></li>
<li><a href="#trunkSourceJavaScriptCoreChangeLog">trunk/Source/JavaScriptCore/ChangeLog</a></li>
<li><a href="#trunkSourceJavaScriptCoreJavaScriptCorevcxprojJavaScriptCorevcxproj">trunk/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj</a></li>
<li><a href="#trunkSourceJavaScriptCoreJavaScriptCorevcxprojJavaScriptCorevcxprojfilters">trunk/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters</a></li>
<li><a href="#trunkSourceJavaScriptCoreJavaScriptCorexcodeprojprojectpbxproj">trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodeCallLinkInfoh">trunk/Source/JavaScriptCore/bytecode/CallLinkInfo.h</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodeCodeBlockcpp">trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodeCodeBlockh">trunk/Source/JavaScriptCore/bytecode/CodeBlock.h</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecompilerBytecodeGeneratorcpp">trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecompilerBytecodeGeneratorh">trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGJITCompilercpp">trunk/Source/JavaScriptCore/dfg/DFGJITCompiler.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGJITCompilerh">trunk/Source/JavaScriptCore/dfg/DFGJITCompiler.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGOSREntrycpp">trunk/Source/JavaScriptCore/dfg/DFGOSREntry.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGOSRExitCompiler32_64cpp">trunk/Source/JavaScriptCore/dfg/DFGOSRExitCompiler32_64.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGOSRExitCompiler64cpp">trunk/Source/JavaScriptCore/dfg/DFGOSRExitCompiler64.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGOSRExitCompilerCommoncpp">trunk/Source/JavaScriptCore/dfg/DFGOSRExitCompilerCommon.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGPlancpp">trunk/Source/JavaScriptCore/dfg/DFGPlan.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGSpeculativeJITcpp">trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGSpeculativeJIT32_64cpp">trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGSpeculativeJIT64cpp">trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGStackLayoutPhasecpp">trunk/Source/JavaScriptCore/dfg/DFGStackLayoutPhase.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreftlFTLCompilecpp">trunk/Source/JavaScriptCore/ftl/FTLCompile.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreftlFTLJITCodeh">trunk/Source/JavaScriptCore/ftl/FTLJITCode.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreftlFTLLinkcpp">trunk/Source/JavaScriptCore/ftl/FTLLink.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreftlFTLOSRExitCompilercpp">trunk/Source/JavaScriptCore/ftl/FTLOSRExitCompiler.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreftlFTLThunkscpp">trunk/Source/JavaScriptCore/ftl/FTLThunks.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreftlFTLUnwindInfocpp">trunk/Source/JavaScriptCore/ftl/FTLUnwindInfo.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreftlFTLUnwindInfoh">trunk/Source/JavaScriptCore/ftl/FTLUnwindInfo.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreinterpreterInterpretercpp">trunk/Source/JavaScriptCore/interpreter/Interpreter.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorejitAssemblyHelpersh">trunk/Source/JavaScriptCore/jit/AssemblyHelpers.h</a></li>
<li><a href="#trunkSourceJavaScriptCorejitFPRInfoh">trunk/Source/JavaScriptCore/jit/FPRInfo.h</a></li>
<li><a href="#trunkSourceJavaScriptCorejitGPRInfoh">trunk/Source/JavaScriptCore/jit/GPRInfo.h</a></li>
<li><a href="#trunkSourceJavaScriptCorejitJITcpp">trunk/Source/JavaScriptCore/jit/JIT.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorejitJITArithmetic32_64cpp">trunk/Source/JavaScriptCore/jit/JITArithmetic32_64.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorejitJITCall32_64cpp">trunk/Source/JavaScriptCore/jit/JITCall32_64.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorejitJITOpcodescpp">trunk/Source/JavaScriptCore/jit/JITOpcodes.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorejitJITOpcodes32_64cpp">trunk/Source/JavaScriptCore/jit/JITOpcodes32_64.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorejitJITOperationscpp">trunk/Source/JavaScriptCore/jit/JITOperations.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorejitJITPropertyAccesscpp">trunk/Source/JavaScriptCore/jit/JITPropertyAccess.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorejitJITPropertyAccess32_64cpp">trunk/Source/JavaScriptCore/jit/JITPropertyAccess32_64.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorejitRegisterSetcpp">trunk/Source/JavaScriptCore/jit/RegisterSet.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorejitRegisterSeth">trunk/Source/JavaScriptCore/jit/RegisterSet.h</a></li>
<li><a href="#trunkSourceJavaScriptCorejitRepatchcpp">trunk/Source/JavaScriptCore/jit/Repatch.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorejitSpecializedThunkJITh">trunk/Source/JavaScriptCore/jit/SpecializedThunkJIT.h</a></li>
<li><a href="#trunkSourceJavaScriptCorejitTempRegisterSeth">trunk/Source/JavaScriptCore/jit/TempRegisterSet.h</a></li>
<li><a href="#trunkSourceJavaScriptCorejitThunkGeneratorscpp">trunk/Source/JavaScriptCore/jit/ThunkGenerators.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorellintLLIntDatacpp">trunk/Source/JavaScriptCore/llint/LLIntData.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorellintLLIntSlowPathscpp">trunk/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorellintLowLevelInterpreterasm">trunk/Source/JavaScriptCore/llint/LowLevelInterpreter.asm</a></li>
<li><a href="#trunkSourceJavaScriptCorellintLowLevelInterpreter32_64asm">trunk/Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm</a></li>
<li><a href="#trunkSourceJavaScriptCorellintLowLevelInterpreter64asm">trunk/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm</a></li>
<li><a href="#trunkSourceJavaScriptCoreofflineasmarm64rb">trunk/Source/JavaScriptCore/offlineasm/arm64.rb</a></li>
<li><a href="#trunkSourceJavaScriptCoreofflineasmregistersrb">trunk/Source/JavaScriptCore/offlineasm/registers.rb</a></li>
<li><a href="#trunkSourceJavaScriptCoreofflineasmx86rb">trunk/Source/JavaScriptCore/offlineasm/x86.rb</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeCommonSlowPathscpp">trunk/Source/JavaScriptCore/runtime/CommonSlowPaths.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeCommonSlowPathsh">trunk/Source/JavaScriptCore/runtime/CommonSlowPaths.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeVMcpp">trunk/Source/JavaScriptCore/runtime/VM.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeVMh">trunk/Source/JavaScriptCore/runtime/VM.h</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkSourceJavaScriptCorejitRegisterAtOffsetcpp">trunk/Source/JavaScriptCore/jit/RegisterAtOffset.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorejitRegisterAtOffseth">trunk/Source/JavaScriptCore/jit/RegisterAtOffset.h</a></li>
<li><a href="#trunkSourceJavaScriptCorejitRegisterAtOffsetListcpp">trunk/Source/JavaScriptCore/jit/RegisterAtOffsetList.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorejitRegisterAtOffsetListh">trunk/Source/JavaScriptCore/jit/RegisterAtOffsetList.h</a></li>
</ul>

<h3>Removed Paths</h3>
<ul>
<li><a href="#trunkSourceJavaScriptCoreftlFTLRegisterAtOffsetcpp">trunk/Source/JavaScriptCore/ftl/FTLRegisterAtOffset.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreftlFTLRegisterAtOffseth">trunk/Source/JavaScriptCore/ftl/FTLRegisterAtOffset.h</a></li>
<li><a href="#trunkSourceJavaScriptCorejitArityCheckFailReturnThunkscpp">trunk/Source/JavaScriptCore/jit/ArityCheckFailReturnThunks.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorejitArityCheckFailReturnThunksh">trunk/Source/JavaScriptCore/jit/ArityCheckFailReturnThunks.h</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceJavaScriptCoreCMakeListstxt"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/CMakeLists.txt (189574 => 189575)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/CMakeLists.txt        2015-09-10 17:31:42 UTC (rev 189574)
+++ trunk/Source/JavaScriptCore/CMakeLists.txt        2015-09-10 17:47:16 UTC (rev 189575)
</span><span class="lines">@@ -358,7 +358,6 @@
</span><span class="cx">     interpreter/StackVisitor.cpp
</span><span class="cx"> 
</span><span class="cx">     jit/AccessorCallJITStubRoutine.cpp
</span><del>-    jit/ArityCheckFailReturnThunks.cpp
</del><span class="cx">     jit/AssemblyHelpers.cpp
</span><span class="cx">     jit/BinarySwitch.cpp
</span><span class="cx">     jit/ExecutableAllocationFuzz.cpp
</span><span class="lines">@@ -386,6 +385,8 @@
</span><span class="cx">     jit/JITToDFGDeferredCompilationCallback.cpp
</span><span class="cx">     jit/PolymorphicCallStubRoutine.cpp
</span><span class="cx">     jit/Reg.cpp
</span><ins>+    jit/RegisterAtOffset.cpp
+    jit/RegisterAtOffsetList.cpp
</ins><span class="cx">     jit/RegisterPreservationWrapperGenerator.cpp
</span><span class="cx">     jit/RegisterSet.cpp
</span><span class="cx">     jit/Repatch.cpp
</span><span class="lines">@@ -904,7 +905,6 @@
</span><span class="cx">         ftl/FTLOperations.cpp
</span><span class="cx">         ftl/FTLOutput.cpp
</span><span class="cx">         ftl/FTLRecoveryOpcode.cpp
</span><del>-        ftl/FTLRegisterAtOffset.cpp
</del><span class="cx">         ftl/FTLSaveRestore.cpp
</span><span class="cx">         ftl/FTLSlowPathCall.cpp
</span><span class="cx">         ftl/FTLSlowPathCallKey.cpp
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ChangeLog (189574 => 189575)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ChangeLog        2015-09-10 17:31:42 UTC (rev 189574)
+++ trunk/Source/JavaScriptCore/ChangeLog        2015-09-10 17:47:16 UTC (rev 189575)
</span><span class="lines">@@ -1,3 +1,307 @@
</span><ins>+2015-09-10  Michael Saboff  &lt;msaboff@apple.com&gt;
+
+        Add support for Callee-Saves registers
+        https://bugs.webkit.org/show_bug.cgi?id=148666
+
+        Reviewed by Filip Pizlo.
+
+        We save platform callee save registers right below the call frame header,
+        in the location(s) starting with VirtualRegister 0.  This local space is
+        allocated in the bytecode compiler.  This space is the maximum space
+        needed for the callee registers that the LLInt and baseline JIT use,
+        rounded up to a stack aligned number of VirtualRegisters.
+        The LLInt explicitly saves and restores the registers in the macros
+        preserveCalleeSavesUsedByLLInt and restoreCalleeSavesUsedByLLInt.
+        The JITs saves and restores callee saves registers by what registers
+        are included in m_calleeSaveRegisters in the code block.
+
+        Added handling of callee save register restoration to exception handling.
+        The basic flow is when an exception is thrown or one is recognized to
+        have been generated in C++ code, we save the current state of all
+        callee save registers to VM::calleeSaveRegistersBuffer.  As we unwind
+        looking for the corresponding catch, we copy the callee saves from call 
+        frames to the same VM::calleeSaveRegistersBuffer.  This is done for all
+        call frames on the stack up to but not including the call frame that has
+        the corresponding catch block.  When we process the catch, we restore
+        the callee save registers with the contents of VM::calleeSaveRegistersBuffer.
+        If there isn't a catch, then handleUncaughtException will restore callee
+        saves before it returns back to the calling C++.
+
+        Eliminated callee saves registers as free registers for various thunk
+        generators as the callee saves may not have been saved by the function
+        calling the thunk.
+
+        Added code to transition callee saves from one VM's format to the another
+        as part of OSR entry and OSR exit.
+
+        Cleaned up the static RegisterSet's including adding one for LLInt and 
+        baseline JIT callee saves and one to be used to allocate local registers
+        not including the callee saves or other special registers.
+
+        Moved ftl/FTLRegisterAtOffset.{cpp,h} to jit/RegisterAtOffset.{cpp,h}.
+        Factored out the vector of RegisterAtOffsets in ftl/FTLUnwindInfo.{cpp,h}
+        into a new class in jit/RegisterAtOffsetList.{cpp,h}.
+        Eliminted UnwindInfo and changed UnwindInfo::parse() into a standalone
+        function named parseUnwindInfo.  That standalone function now returns
+        the callee saves RegisterAtOffsetList.  This is stored in the CodeBlock
+        and used instead of UnwindInfo.
+
+        Turned off register preservation thunks for outgoing calls from FTL
+        generated code.  THey'll be removed in a subsequent patch.
+
+        Changed specialized thinks to save and restore the contents of
+        tagTypeNumberRegister and tagMaskRegister as they can be called by FTL
+        compiled functions.  We materialize those tag registers for the thunk's
+        use and then restore the prior contents on function exit.
+
+        Also removed the arity check fail return thunk since it is now the
+        caller's responsibility to restore the stack pointer.
+
+        Removed saving of callee save registers and materialization of special
+        tag registers for 64 bit platforms from vmEntryToJavaScript and
+        vmEntryToNative.
+
+        * CMakeLists.txt:
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters:
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        * ftl/FTLJITCode.h:
+        * ftl/FTLRegisterAtOffset.cpp: Removed.
+        * ftl/FTLRegisterAtOffset.h: Removed.
+        * ftl/FTLUnwindInfo.cpp:
+        (JSC::FTL::parseUnwindInfo):
+        (JSC::FTL::UnwindInfo::UnwindInfo): Deleted.
+        (JSC::FTL::UnwindInfo::~UnwindInfo): Deleted.
+        (JSC::FTL::UnwindInfo::parse): Deleted.
+        (JSC::FTL::UnwindInfo::dump): Deleted.
+        (JSC::FTL::UnwindInfo::find): Deleted.
+        (JSC::FTL::UnwindInfo::indexOf): Deleted.
+        * ftl/FTLUnwindInfo.h:
+        (JSC::RegisterAtOffset::dump):
+        * jit/RegisterAtOffset.cpp: Added.
+        * jit/RegisterAtOffset.h: Added.
+        (JSC::RegisterAtOffset::RegisterAtOffset):
+        (JSC::RegisterAtOffset::operator!):
+        (JSC::RegisterAtOffset::reg):
+        (JSC::RegisterAtOffset::offset):
+        (JSC::RegisterAtOffset::offsetAsIndex):
+        (JSC::RegisterAtOffset::operator==):
+        (JSC::RegisterAtOffset::operator&lt;):
+        (JSC::RegisterAtOffset::getReg):
+        * jit/RegisterAtOffsetList.cpp: Added.
+        (JSC::RegisterAtOffsetList::RegisterAtOffsetList):
+        (JSC::RegisterAtOffsetList::sort):
+        (JSC::RegisterAtOffsetList::dump):
+        (JSC::RegisterAtOffsetList::find):
+        (JSC::RegisterAtOffsetList::indexOf):
+        * jit/RegisterAtOffsetList.h: Added.
+        (JSC::RegisterAtOffsetList::clear):
+        (JSC::RegisterAtOffsetList::size):
+        (JSC::RegisterAtOffsetList::at):
+        (JSC::RegisterAtOffsetList::append):
+        Move and refactored use of FTLRegisterAtOffset to RegisterAtOffset.
+        Added RegisterAtOffset and RegisterAtOffsetList to build configurations.
+        Remove FTLRegisterAtOffset files.
+
+        * bytecode/CallLinkInfo.h:
+        (JSC::CallLinkInfo::setUpCallFromFTL):
+        Turned off FTL register preservation thunks.
+
+        * bytecode/CodeBlock.cpp:
+        (JSC::CodeBlock::CodeBlock):
+        (JSC::CodeBlock::setCalleeSaveRegisters):
+        (JSC::roundCalleeSaveSpaceAsVirtualRegisters):
+        (JSC::CodeBlock::llintBaselineCalleeSaveSpaceAsVirtualRegisters):
+        (JSC::CodeBlock::calleeSaveSpaceAsVirtualRegisters):
+        * 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 VirtualRegisters for callee saves.
+
+        * bytecompiler/BytecodeGenerator.cpp:
+        (JSC::BytecodeGenerator::BytecodeGenerator):
+        (JSC::BytecodeGenerator::allocateCalleeSaveSpace):
+        * bytecompiler/BytecodeGenerator.h:
+        Allocate the appropriate number of VirtualRegisters 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::compileExceptionHandlers):
+        (JSC::DFG::JITCompiler::compile):
+        (JSC::DFG::JITCompiler::compileFunction):
+        * dfg/DFGJITCompiler.h:
+        * interpreter/Interpreter.cpp:
+        (JSC::UnwindFunctor::operator()):
+        (JSC::UnwindFunctor::copyCalleeSavesToVMCalleeSavesBuffer):
+        * dfg/DFGPlan.cpp:
+        (JSC::DFG::Plan::compileInThreadImpl):
+        * dfg/DFGSpeculativeJIT.cpp:
+        (JSC::DFG::SpeculativeJIT::usedRegisters):
+        * dfg/DFGSpeculativeJIT32_64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+        * dfg/DFGSpeculativeJIT64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+        * dfg/DFGStackLayoutPhase.cpp:
+        (JSC::DFG::StackLayoutPhase::run):
+        * ftl/FTLCompile.cpp:
+        (JSC::FTL::fixFunctionBasedOnStackMaps):
+        (JSC::FTL::compile):
+        * ftl/FTLLink.cpp:
+        (JSC::FTL::link):
+        * ftl/FTLOSRExitCompiler.cpp:
+        (JSC::FTL::compileStub):
+        * ftl/FTLThunks.cpp:
+        (JSC::FTL::osrExitGenerationThunkGenerator):
+        * jit/ArityCheckFailReturnThunks.cpp: Removed.
+        * jit/ArityCheckFailReturnThunks.h: Removed.
+        * jit/JIT.cpp:
+        (JSC::JIT::emitEnterOptimizationCheck):
+        (JSC::JIT::privateCompile):
+        (JSC::JIT::privateCompileExceptionHandlers):
+        * jit/JITCall32_64.cpp:
+        (JSC::JIT::emit_op_ret):
+        * jit/JITExceptions.cpp:
+        (JSC::genericUnwind):
+        * jit/JITExceptions.h:
+        * jit/JITOpcodes.cpp:
+        (JSC::JIT::emit_op_end):
+        (JSC::JIT::emit_op_ret):
+        (JSC::JIT::emit_op_throw):
+        (JSC::JIT::emit_op_catch):
+        (JSC::JIT::emit_op_enter):
+        (JSC::JIT::emitSlow_op_loop_hint):
+        * jit/JITOpcodes32_64.cpp:
+        (JSC::JIT::emit_op_end):
+        (JSC::JIT::emit_op_throw):
+        (JSC::JIT::emit_op_catch):
+        * jit/JITOperations.cpp:
+        * jit/Repatch.cpp:
+        (JSC::generateByIdStub):
+        * jit/ThunkGenerators.cpp:
+        * llint/LLIntData.cpp:
+        (JSC::LLInt::Data::performAssertions):
+        * llint/LLIntSlowPaths.cpp:
+        (JSC::LLInt::LLINT_SLOW_PATH_DECL):
+        * llint/LowLevelInterpreter.asm:
+        * llint/LowLevelInterpreter32_64.asm:
+        * llint/LowLevelInterpreter64.asm:
+        (JSC::throwExceptionFromCallSlowPathGenerator):
+        (JSC::arityFixupGenerator):
+        * runtime/CommonSlowPaths.cpp:
+        (JSC::setupArityCheckData):
+        * runtime/CommonSlowPaths.h:
+        (JSC::CommonSlowPaths::arityCheckFor):
+        Emit code to save and restore callee save registers and materialize tagTypeNumberRegister
+        and tagMaskRegister.
+        Handle callee saves when tiering up.
+        Copy callee saves register contents to VM::calleeSaveRegistersBuffer at beginning of
+        exception processing.
+        Process callee save registers in frames when unwinding from an exception.
+        Restore callee saves register contents from VM::calleeSaveRegistersBuffer on catch.
+        Use appropriate register set to make sure we don't allocate a callee save register when
+        compiling a thunk.
+        Helper to populate tagTypeNumberRegister and tagMaskRegister with the appropriate
+        constants.
+        Removed arity fixup return thunks.
+
+        * dfg/DFGOSREntry.cpp:
+        (JSC::DFG::prepareOSREntry):
+        * dfg/DFGOSRExitCompiler32_64.cpp:
+        (JSC::DFG::OSRExitCompiler::compileExit):
+        * dfg/DFGOSRExitCompiler64.cpp:
+        (JSC::DFG::OSRExitCompiler::compileExit):
+        * dfg/DFGOSRExitCompilerCommon.cpp:
+        (JSC::DFG::reifyInlinedCallFrames):
+        (JSC::DFG::adjustAndJumpToTarget):
+        Restore callee saves from the DFG and save the appropriate ones for the baseline JIT.
+        Materialize the tag registers on 64 bit platforms.
+
+        * jit/AssemblyHelpers.h:
+        (JSC::AssemblyHelpers::emitSaveCalleeSavesFor):
+        (JSC::AssemblyHelpers::emitRestoreCalleeSavesFor):
+        (JSC::AssemblyHelpers::emitSaveCalleeSaves):
+        (JSC::AssemblyHelpers::emitRestoreCalleeSaves):
+        (JSC::AssemblyHelpers::copyCalleeSavesToVMCalleeSavesBuffer):
+        (JSC::AssemblyHelpers::restoreCalleeSavesFromVMCalleeSavesBuffer):
+        (JSC::AssemblyHelpers::copyCalleeSavesFromFrameOrRegisterToVMCalleeSavesBuffer):
+        (JSC::AssemblyHelpers::emitMaterializeTagCheckRegisters):
+        New helpers to save and restore callee saves as well as materialize the tag registers
+        contents.
+
+        * jit/FPRInfo.h:
+        * jit/GPRInfo.h:
+        (JSC::GPRInfo::toRegister):
+        Updated to include FP callee save registers.  Added number of callee saves registers and
+        cleanup register aliases that collide with callee save registers.
+
+        * jit/JITPropertyAccess.cpp:
+        (JSC::JIT::emitGetByValWithCachedId):
+        (JSC::JIT::emitPutByValWithCachedId):
+        (JSC::JIT::emit_op_get_by_id):
+        (JSC::JIT::emit_op_put_by_id):
+        * jit/JITPropertyAccess32_64.cpp:
+        (JSC::JIT::emitGetByValWithCachedId):
+        (JSC::JIT::emitPutByValWithCachedId):
+        (JSC::JIT::emit_op_get_by_id):
+        (JSC::JIT::emit_op_put_by_id):
+        Uses new stubUnavailableRegisters register set to limit what registers are available for 
+        temporaries.
+
+        * jit/RegisterSet.cpp:
+        (JSC::RegisterSet::stubUnavailableRegisters):
+        (JSC::RegisterSet::calleeSaveRegisters):
+        (JSC::RegisterSet::llintBaselineCalleeSaveRegisters):
+        (JSC::RegisterSet::dfgCalleeSaveRegisters):
+        (JSC::RegisterSet::ftlCalleeSaveRegisters):
+        * jit/RegisterSet.h:
+        New register sets with the callee saves used by various tiers as well as one listing registers
+        not availble to stub code.
+
+        * jit/SpecializedThunkJIT.h:
+        (JSC::SpecializedThunkJIT::SpecializedThunkJIT):
+        (JSC::SpecializedThunkJIT::loadDoubleArgument):
+        (JSC::SpecializedThunkJIT::returnJSValue):
+        (JSC::SpecializedThunkJIT::returnDouble):
+        (JSC::SpecializedThunkJIT::returnInt32):
+        (JSC::SpecializedThunkJIT::returnJSCell):
+        (JSC::SpecializedThunkJIT::callDoubleToDoublePreservingReturn):
+        (JSC::SpecializedThunkJIT::emitSaveThenMaterializeTagRegisters):
+        (JSC::SpecializedThunkJIT::emitRestoreSavedTagRegisters):
+        (JSC::SpecializedThunkJIT::tagReturnAsInt32):
+        * jit/ThunkGenerators.cpp:
+        (JSC::nativeForGenerator):
+        Changed to save and restore existing tag register contents as the may contain other values.
+        After saving the existing values, we materialize the tag constants.
+
+        * jit/TempRegisterSet.h:
+        (JSC::TempRegisterSet::getFPRByIndex):
+        (JSC::TempRegisterSet::getFreeFPR):
+        (JSC::TempRegisterSet::setByIndex):
+        * offlineasm/arm64.rb:
+        * offlineasm/registers.rb:
+        Added methods for floating point registers to support callee save FP registers.
+
+        * jit/JITArithmetic32_64.cpp:
+        (JSC::JIT::emit_op_mod):
+        Removed unnecessary #if CPU(X86_64) check to this 32 bit only file.
+
+        * offlineasm/x86.rb:
+        Fixed Windows callee saves naming.
+
+        * 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.
+
</ins><span class="cx"> 2015-09-10  Yusuke Suzuki  &lt;utatane.tea@gmail.com&gt;
</span><span class="cx"> 
</span><span class="cx">         ModuleProgramExecutable should provide CodeBlock to ScriptExecutable::forEachCodeBlock
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreJavaScriptCorevcxprojJavaScriptCorevcxproj"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj (189574 => 189575)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj        2015-09-10 17:31:42 UTC (rev 189574)
+++ trunk/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj        2015-09-10 17:47:16 UTC (rev 189575)
</span><span class="lines">@@ -545,7 +545,6 @@
</span><span class="cx">     &lt;ClCompile Include=&quot;..\ftl\FTLOperations.cpp&quot; /&gt;
</span><span class="cx">     &lt;ClCompile Include=&quot;..\ftl\FTLOutput.cpp&quot; /&gt;
</span><span class="cx">     &lt;ClCompile Include=&quot;..\ftl\FTLRecoveryOpcode.cpp&quot; /&gt;
</span><del>-    &lt;ClCompile Include=&quot;..\ftl\FTLRegisterAtOffset.cpp&quot; /&gt;
</del><span class="cx">     &lt;ClCompile Include=&quot;..\ftl\FTLSaveRestore.cpp&quot; /&gt;
</span><span class="cx">     &lt;ClCompile Include=&quot;..\ftl\FTLSlowPathCall.cpp&quot; /&gt;
</span><span class="cx">     &lt;ClCompile Include=&quot;..\ftl\FTLSlowPathCallKey.cpp&quot; /&gt;
</span><span class="lines">@@ -619,7 +618,6 @@
</span><span class="cx">     &lt;ClCompile Include=&quot;..\interpreter\ProtoCallFrame.cpp&quot; /&gt;
</span><span class="cx">     &lt;ClCompile Include=&quot;..\interpreter\StackVisitor.cpp&quot; /&gt;
</span><span class="cx">     &lt;ClCompile Include=&quot;..\jit\AccessorCallJITStubRoutine.cpp&quot; /&gt;
</span><del>-    &lt;ClCompile Include=&quot;..\jit\ArityCheckFailReturnThunks.cpp&quot; /&gt;
</del><span class="cx">     &lt;ClCompile Include=&quot;..\jit\AssemblyHelpers.cpp&quot; /&gt;
</span><span class="cx">     &lt;ClCompile Include=&quot;..\jit\BinarySwitch.cpp&quot; /&gt;
</span><span class="cx">     &lt;ClCompile Include=&quot;..\jit\ExecutableAllocationFuzz.cpp&quot; /&gt;
</span><span class="lines">@@ -649,6 +647,8 @@
</span><span class="cx">     &lt;ClCompile Include=&quot;..\jit\SetupVarargsFrame.cpp&quot; /&gt;
</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><ins>+    &lt;ClCompile Include=&quot;..\jit\RegisterAtOffset.cpp&quot; /&gt;
+    &lt;ClCompile Include=&quot;..\jit\RegisterAtOffsetList.cpp&quot; /&gt;
</ins><span class="cx">     &lt;ClCompile Include=&quot;..\jit\RegisterPreservationWrapperGenerator.cpp&quot; /&gt;
</span><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="lines">@@ -1297,7 +1297,6 @@
</span><span class="cx">     &lt;ClInclude Include=&quot;..\ftl\FTLOperations.h&quot; /&gt;
</span><span class="cx">     &lt;ClInclude Include=&quot;..\ftl\FTLOutput.h&quot; /&gt;
</span><span class="cx">     &lt;ClInclude Include=&quot;..\ftl\FTLRecoveryOpcode.h&quot; /&gt;
</span><del>-    &lt;ClInclude Include=&quot;..\ftl\FTLRegisterAtOffset.h&quot; /&gt;
</del><span class="cx">     &lt;ClInclude Include=&quot;..\ftl\FTLSaveRestore.h&quot; /&gt;
</span><span class="cx">     &lt;ClInclude Include=&quot;..\ftl\FTLSlowPathCall.h&quot; /&gt;
</span><span class="cx">     &lt;ClInclude Include=&quot;..\ftl\FTLSlowPathCallKey.h&quot; /&gt;
</span><span class="lines">@@ -1419,7 +1418,6 @@
</span><span class="cx">     &lt;ClInclude Include=&quot;..\interpreter\Register.h&quot; /&gt;
</span><span class="cx">     &lt;ClInclude Include=&quot;..\interpreter\StackVisitor.h&quot; /&gt;
</span><span class="cx">     &lt;ClInclude Include=&quot;..\jit\AccessorCallJITStubRoutine.h&quot; /&gt;
</span><del>-    &lt;ClInclude Include=&quot;..\jit\ArityCheckFailReturnThunks.h&quot; /&gt;
</del><span class="cx">     &lt;ClInclude Include=&quot;..\jit\AssemblyHelpers.h&quot; /&gt;
</span><span class="cx">     &lt;ClInclude Include=&quot;..\jit\BinarySwitch.h&quot; /&gt;
</span><span class="cx">     &lt;ClInclude Include=&quot;..\jit\CCallHelpers.h&quot; /&gt;
</span><span class="lines">@@ -1450,6 +1448,8 @@
</span><span class="cx">     &lt;ClInclude Include=&quot;..\jit\SetupVarargsFrame.h&quot; /&gt;
</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><ins>+    &lt;ClInclude Include=&quot;..\jit\RegisterAtOffset.h&quot; /&gt;
+    &lt;ClInclude Include=&quot;..\jit\RegisterAtOffsetList.h&quot; /&gt;
</ins><span class="cx">     &lt;ClInclude Include=&quot;..\jit\RegisterMap.h&quot; /&gt;
</span><span class="cx">     &lt;ClInclude Include=&quot;..\jit\RegisterPreservationWrapperGenerator.h&quot; /&gt;
</span><span class="cx">     &lt;ClInclude Include=&quot;..\jit\RegisterSet.h&quot; /&gt;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreJavaScriptCorevcxprojJavaScriptCorevcxprojfilters"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters (189574 => 189575)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters        2015-09-10 17:31:42 UTC (rev 189574)
+++ trunk/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters        2015-09-10 17:47:16 UTC (rev 189575)
</span><span class="lines">@@ -1491,9 +1491,6 @@
</span><span class="cx">     &lt;ClCompile Include=&quot;$(ConfigurationBuildDir)\obj$(PlatformArchitecture)\$(ProjectName)\DerivedSources\InspectorProtocolObjects.cpp&quot;&gt;
</span><span class="cx">       &lt;Filter&gt;Derived Sources&lt;/Filter&gt;
</span><span class="cx">     &lt;/ClCompile&gt;
</span><del>-    &lt;ClCompile Include=&quot;..\jit\ArityCheckFailReturnThunks.cpp&quot;&gt;
-      &lt;Filter&gt;jit&lt;/Filter&gt;
-    &lt;/ClCompile&gt;
</del><span class="cx">     &lt;ClCompile Include=&quot;..\jit\RegisterPreservationWrapperGenerator.cpp&quot;&gt;
</span><span class="cx">       &lt;Filter&gt;jit&lt;/Filter&gt;
</span><span class="cx">     &lt;/ClCompile&gt;
</span><span class="lines">@@ -4037,9 +4034,6 @@
</span><span class="cx">       &lt;Filter&gt;runtime&lt;/Filter&gt;
</span><span class="cx">     &lt;/ClInclude&gt;
</span><span class="cx">     &lt;ClInclude Include=&quot;$(ConfigurationBuildDir)\obj$(PlatformArchitecture)\$(ProjectName)\DerivedSources\JSDataViewPrototype.lut.h&quot; /&gt;
</span><del>-    &lt;ClInclude Include=&quot;..\jit\ArityCheckFailReturnThunks.h&quot;&gt;
-      &lt;Filter&gt;jit&lt;/Filter&gt;
-    &lt;/ClInclude&gt;
</del><span class="cx">     &lt;ClInclude Include=&quot;..\jit\RegisterPreservationWrapperGenerator.h&quot;&gt;
</span><span class="cx">       &lt;Filter&gt;jit&lt;/Filter&gt;
</span><span class="cx">     &lt;/ClInclude&gt;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreJavaScriptCorexcodeprojprojectpbxproj"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj (189574 => 189575)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj        2015-09-10 17:31:42 UTC (rev 189574)
+++ trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj        2015-09-10 17:47:16 UTC (rev 189575)
</span><span class="lines">@@ -382,12 +382,8 @@
</span><span class="cx">                 0F6B1CBA1861244C00845D97 /* RegisterPreservationMode.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F6B1CB81861244C00845D97 /* RegisterPreservationMode.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 0F6B1CBD1861246A00845D97 /* RegisterPreservationWrapperGenerator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F6B1CBB1861246A00845D97 /* RegisterPreservationWrapperGenerator.cpp */; };
</span><span class="cx">                 0F6B1CBE1861246A00845D97 /* RegisterPreservationWrapperGenerator.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F6B1CBC1861246A00845D97 /* RegisterPreservationWrapperGenerator.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><del>-                0F6B1CC31862C47800845D97 /* FTLRegisterAtOffset.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F6B1CBF1862C47800845D97 /* FTLRegisterAtOffset.cpp */; };
-                0F6B1CC41862C47800845D97 /* FTLRegisterAtOffset.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F6B1CC01862C47800845D97 /* FTLRegisterAtOffset.h */; settings = {ATTRIBUTES = (Private, ); }; };
</del><span class="cx">                 0F6B1CC51862C47800845D97 /* FTLUnwindInfo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F6B1CC11862C47800845D97 /* FTLUnwindInfo.cpp */; };
</span><span class="cx">                 0F6B1CC61862C47800845D97 /* FTLUnwindInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F6B1CC21862C47800845D97 /* FTLUnwindInfo.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><del>-                0F6B1CC918641DF800845D97 /* ArityCheckFailReturnThunks.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F6B1CC718641DF800845D97 /* ArityCheckFailReturnThunks.cpp */; };
-                0F6B1CCA18641DF800845D97 /* ArityCheckFailReturnThunks.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F6B1CC818641DF800845D97 /* ArityCheckFailReturnThunks.h */; settings = {ATTRIBUTES = (Private, ); }; };
</del><span class="cx">                 0F6C73501AC9F99F00BE1682 /* VariableWriteFireDetail.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F6C734E1AC9F99F00BE1682 /* VariableWriteFireDetail.cpp */; };
</span><span class="cx">                 0F6C73511AC9F99F00BE1682 /* VariableWriteFireDetail.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F6C734F1AC9F99F00BE1682 /* VariableWriteFireDetail.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 0F6E845A19030BEF00562741 /* DFGVariableAccessData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F6E845919030BEF00562741 /* DFGVariableAccessData.cpp */; };
</span><span class="lines">@@ -987,6 +983,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>+                6540C7A01B82E1C3000F6B79 /* RegisterAtOffset.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6540C79E1B82D9CE000F6B79 /* RegisterAtOffset.cpp */; };
+                6540C7A11B82E1C3000F6B79 /* RegisterAtOffsetList.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6540C79C1B82D99D000F6B79 /* RegisterAtOffsetList.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">@@ -2216,12 +2214,8 @@
</span><span class="cx">                 0F6B1CB81861244C00845D97 /* RegisterPreservationMode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RegisterPreservationMode.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0F6B1CBB1861246A00845D97 /* RegisterPreservationWrapperGenerator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RegisterPreservationWrapperGenerator.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0F6B1CBC1861246A00845D97 /* RegisterPreservationWrapperGenerator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RegisterPreservationWrapperGenerator.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><del>-                0F6B1CBF1862C47800845D97 /* FTLRegisterAtOffset.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = FTLRegisterAtOffset.cpp; path = ftl/FTLRegisterAtOffset.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
-                0F6B1CC01862C47800845D97 /* FTLRegisterAtOffset.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = FTLRegisterAtOffset.h; path = ftl/FTLRegisterAtOffset.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</del><span class="cx">                 0F6B1CC11862C47800845D97 /* FTLUnwindInfo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = FTLUnwindInfo.cpp; path = ftl/FTLUnwindInfo.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0F6B1CC21862C47800845D97 /* FTLUnwindInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = FTLUnwindInfo.h; path = ftl/FTLUnwindInfo.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><del>-                0F6B1CC718641DF800845D97 /* ArityCheckFailReturnThunks.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ArityCheckFailReturnThunks.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
-                0F6B1CC818641DF800845D97 /* ArityCheckFailReturnThunks.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ArityCheckFailReturnThunks.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</del><span class="cx">                 0F6C734E1AC9F99F00BE1682 /* VariableWriteFireDetail.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = VariableWriteFireDetail.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0F6C734F1AC9F99F00BE1682 /* VariableWriteFireDetail.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VariableWriteFireDetail.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0F6E845919030BEF00562741 /* DFGVariableAccessData.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGVariableAccessData.cpp; path = dfg/DFGVariableAccessData.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="lines">@@ -2801,6 +2795,10 @@
</span><span class="cx">                 652A3A231651C69700A80AFE /* A64DOpcode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = A64DOpcode.h; path = disassembler/ARM64/A64DOpcode.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 65303D631447B9E100D3F904 /* ParserTokens.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ParserTokens.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 65400C100A69BAF200509887 /* PropertyNameArray.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = PropertyNameArray.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><ins>+                6540C79C1B82D99D000F6B79 /* RegisterAtOffsetList.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RegisterAtOffsetList.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
+                6540C79D1B82D99D000F6B79 /* RegisterAtOffsetList.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RegisterAtOffsetList.h; sourceTree = &quot;&lt;group&gt;&quot;; };
+                6540C79E1B82D9CE000F6B79 /* RegisterAtOffset.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RegisterAtOffset.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
+                6540C79F1B82D9CE000F6B79 /* RegisterAtOffset.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RegisterAtOffset.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</ins><span class="cx">                 6546F51F1A32A59C006F07D5 /* NullGetterFunction.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 0; path = NullGetterFunction.cpp; sourceTree = &quot;&lt;group&gt;&quot;; xcLanguageSpecificationIdentifier = xcode.lang.cpp; };
</span><span class="cx">                 6546F5201A32A59C006F07D5 /* NullGetterFunction.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NullGetterFunction.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 65525FC31A6DD3B3007B5495 /* NullSetterFunction.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = NullSetterFunction.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="lines">@@ -3972,8 +3970,6 @@
</span><span class="cx">                                 0FEA0A06170513DB00BB722C /* FTLOutput.h */,
</span><span class="cx">                                 0F485325187DFDEC0083B687 /* FTLRecoveryOpcode.cpp */,
</span><span class="cx">                                 0F485326187DFDEC0083B687 /* FTLRecoveryOpcode.h */,
</span><del>-                                0F6B1CBF1862C47800845D97 /* FTLRegisterAtOffset.cpp */,
-                                0F6B1CC01862C47800845D97 /* FTLRegisterAtOffset.h */,
</del><span class="cx">                                 0FCEFAA91804C13E00472CE4 /* FTLSaveRestore.cpp */,
</span><span class="cx">                                 0FCEFAAA1804C13E00472CE4 /* FTLSaveRestore.h */,
</span><span class="cx">                                 0F25F1AA181635F300522F39 /* FTLSlowPathCall.cpp */,
</span><span class="lines">@@ -4104,8 +4100,6 @@
</span><span class="cx">                                 0FF054F81AC35B4400E5BE57 /* ExecutableAllocationFuzz.h */,
</span><span class="cx">                                 0F7576D018E1FEE9002EF4CD /* AccessorCallJITStubRoutine.cpp */,
</span><span class="cx">                                 0F7576D118E1FEE9002EF4CD /* AccessorCallJITStubRoutine.h */,
</span><del>-                                0F6B1CC718641DF800845D97 /* ArityCheckFailReturnThunks.cpp */,
-                                0F6B1CC818641DF800845D97 /* ArityCheckFailReturnThunks.h */,
</del><span class="cx">                                 0F24E53B17EA9F5900ABB217 /* AssemblyHelpers.cpp */,
</span><span class="cx">                                 0F24E53C17EA9F5900ABB217 /* AssemblyHelpers.h */,
</span><span class="cx">                                 0F64B26F1A784BAF006E4E66 /* BinarySwitch.cpp */,
</span><span class="lines">@@ -4158,12 +4152,14 @@
</span><span class="cx">                                 0FC712E117CD878F008CC93C /* JITToDFGDeferredCompilationCallback.h */,
</span><span class="cx">                                 A76F54A213B28AAB00EF2BCE /* JITWriteBarrier.h */,
</span><span class="cx">                                 A76C51741182748D00715B05 /* JSInterfaceJIT.h */,
</span><del>-                                0FEE98421A89227500754E93 /* SetupVarargsFrame.cpp */,
-                                0FEE98401A8865B600754E93 /* SetupVarargsFrame.h */,
</del><span class="cx">                                 0FE834151A6EF97B00D04847 /* PolymorphicCallStubRoutine.cpp */,
</span><span class="cx">                                 0FE834161A6EF97B00D04847 /* PolymorphicCallStubRoutine.h */,
</span><span class="cx">                                 0FA7A8E918B413C80052371D /* Reg.cpp */,
</span><span class="cx">                                 0FA7A8EA18B413C80052371D /* Reg.h */,
</span><ins>+                                6540C79E1B82D9CE000F6B79 /* RegisterAtOffset.cpp */,
+                                6540C79F1B82D9CE000F6B79 /* RegisterAtOffset.h */,
+                                6540C79C1B82D99D000F6B79 /* RegisterAtOffsetList.cpp */,
+                                6540C79D1B82D99D000F6B79 /* RegisterAtOffsetList.h */,
</ins><span class="cx">                                 623A37EB1B87A7BD00754209 /* RegisterMap.h */,
</span><span class="cx">                                 0F6B1CBB1861246A00845D97 /* RegisterPreservationWrapperGenerator.cpp */,
</span><span class="cx">                                 0F6B1CBC1861246A00845D97 /* RegisterPreservationWrapperGenerator.h */,
</span><span class="lines">@@ -4173,6 +4169,8 @@
</span><span class="cx">                                 0F24E54A17EE274900ABB217 /* Repatch.h */,
</span><span class="cx">                                 0FA7A8ED18CE4FD80052371D /* ScratchRegisterAllocator.cpp */,
</span><span class="cx">                                 0F24E54B17EE274900ABB217 /* ScratchRegisterAllocator.h */,
</span><ins>+                                0FEE98421A89227500754E93 /* SetupVarargsFrame.cpp */,
+                                0FEE98401A8865B600754E93 /* SetupVarargsFrame.h */,
</ins><span class="cx">                                 A709F2EF17A0AC0400512E98 /* SlowPathCall.h */,
</span><span class="cx">                                 A7386551118697B400540279 /* SpecializedThunkJIT.h */,
</span><span class="cx">                                 A7FF647A18C52E8500B55307 /* SpillRegistersMode.h */,
</span><span class="lines">@@ -5925,7 +5923,6 @@
</span><span class="cx">                                 BC18C3E50E16F5CD00B34460 /* APICast.h in Headers */,
</span><span class="cx">                                 BCF605140E203EF800B9A64D /* ArgList.h in Headers */,
</span><span class="cx">                                 2A88067919107D5500CB0BBB /* DFGFunctionWhitelist.h in Headers */,
</span><del>-                                0F6B1CCA18641DF800845D97 /* ArityCheckFailReturnThunks.h in Headers */,
</del><span class="cx">                                 0F6B1CB91861244C00845D97 /* ArityCheckMode.h in Headers */,
</span><span class="cx">                                 A1A009C11831A26E00CF8711 /* ARM64Assembler.h in Headers */,
</span><span class="cx">                                 0F898F321B27689F0083A33C /* DFGIntegerRangeOptimizationPhase.h in Headers */,
</span><span class="lines">@@ -6325,7 +6322,6 @@
</span><span class="cx">                                 9E72940B190F0514001A91B5 /* BundlePath.h in Headers */,
</span><span class="cx">                                 0F48532A187DFDEC0083B687 /* FTLRecoveryOpcode.h in Headers */,
</span><span class="cx">                                 E3794E761B77EB97005543AE /* ModuleAnalyzer.h in Headers */,
</span><del>-                                0F6B1CC41862C47800845D97 /* FTLRegisterAtOffset.h in Headers */,
</del><span class="cx">                                 0FCEFAAC1804C13E00472CE4 /* FTLSaveRestore.h in Headers */,
</span><span class="cx">                                 0F25F1B2181635F300522F39 /* FTLSlowPathCall.h in Headers */,
</span><span class="cx">                                 E354622B1B6065D100545386 /* ConstructAbility.h in Headers */,
</span><span class="lines">@@ -7392,7 +7388,6 @@
</span><span class="cx">                                 0FE050151AA9091100D33B33 /* DirectArgumentsOffset.cpp in Sources */,
</span><span class="cx">                                 0F55F0F414D1063900AC7649 /* AbstractPC.cpp in Sources */,
</span><span class="cx">                                 147F39BD107EC37600427A48 /* ArgList.cpp in Sources */,
</span><del>-                                0F6B1CC918641DF800845D97 /* ArityCheckFailReturnThunks.cpp in Sources */,
</del><span class="cx">                                 797E07A91B8FCFB9008400BA /* JSGlobalLexicalEnvironment.cpp in Sources */,
</span><span class="cx">                                 E3794E751B77EB97005543AE /* ModuleAnalyzer.cpp in Sources */,
</span><span class="cx">                                 0F743BAA16B88249009F9277 /* ARM64Disassembler.cpp in Sources */,
</span><span class="lines">@@ -7655,7 +7650,6 @@
</span><span class="cx">                                 8B0F424C1ABD6DE2003917EA /* JSArrowFunction.cpp in Sources */,
</span><span class="cx">                                 0FEA0A2A1709629600BB722C /* FTLOutput.cpp in Sources */,
</span><span class="cx">                                 0F485329187DFDEC0083B687 /* FTLRecoveryOpcode.cpp in Sources */,
</span><del>-                                0F6B1CC31862C47800845D97 /* FTLRegisterAtOffset.cpp in Sources */,
</del><span class="cx">                                 0FCEFAAB1804C13E00472CE4 /* FTLSaveRestore.cpp in Sources */,
</span><span class="cx">                                 0F25F1B1181635F300522F39 /* FTLSlowPathCall.cpp in Sources */,
</span><span class="cx">                                 0F25F1B3181635F300522F39 /* FTLSlowPathCallKey.cpp in Sources */,
</span><span class="lines">@@ -7926,6 +7920,8 @@
</span><span class="cx">                                 0F3E01AA19D353A500F61B7F /* DFGPrePostNumbering.cpp in Sources */,
</span><span class="cx">                                 0FF60AC316740F8800029779 /* ReduceWhitespace.cpp in Sources */,
</span><span class="cx">                                 0FA7A8EB18B413C80052371D /* Reg.cpp in Sources */,
</span><ins>+                                6540C7A11B82E1C3000F6B79 /* RegisterAtOffsetList.cpp in Sources */,
+                                6540C7A01B82E1C3000F6B79 /* RegisterAtOffset.cpp in Sources */,
</ins><span class="cx">                                 14280841107EC0930013E7B2 /* RegExp.cpp in Sources */,
</span><span class="cx">                                 A1712B3B11C7B212007A5315 /* RegExpCache.cpp in Sources */,
</span><span class="cx">                                 0FE0502C1AA9095600D33B33 /* VarOffset.cpp in Sources */,
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeCallLinkInfoh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/CallLinkInfo.h (189574 => 189575)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/CallLinkInfo.h        2015-09-10 17:31:42 UTC (rev 189574)
+++ trunk/Source/JavaScriptCore/bytecode/CallLinkInfo.h        2015-09-10 17:47:16 UTC (rev 189575)
</span><span class="lines">@@ -117,7 +117,7 @@
</span><span class="cx">         CodeLocationNearCall callReturnLocation, CodeLocationDataLabelPtr hotPathBegin,
</span><span class="cx">         CodeLocationNearCall hotPathOther, unsigned calleeGPR)
</span><span class="cx">     {
</span><del>-        m_registerPreservationMode = static_cast&lt;unsigned&gt;(MustPreserveRegisters);
</del><ins>+        m_registerPreservationMode = static_cast&lt;unsigned&gt;(RegisterPreservationNotRequired);
</ins><span class="cx">         m_callType = callType;
</span><span class="cx">         m_codeOrigin = codeOrigin;
</span><span class="cx">         m_callReturnLocation = callReturnLocation;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeCodeBlockcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp (189574 => 189575)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp        2015-09-10 17:31:42 UTC (rev 189574)
+++ trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp        2015-09-10 17:47:16 UTC (rev 189575)
</span><span class="lines">@@ -69,6 +69,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;RegisterAtOffsetList.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">@@ -1887,6 +1891,10 @@
</span><span class="cx">     if (size_t size = unlinkedCodeBlock-&gt;numberOfObjectAllocationProfiles())
</span><span class="cx">         m_objectAllocationProfiles.resizeToFit(size);
</span><span class="cx"> 
</span><ins>+#if ENABLE(JIT)
+    setCalleeSaveRegisters(RegisterSet::llintBaselineCalleeSaveRegisters());
+#endif
+
</ins><span class="cx">     // Copy and translate the UnlinkedInstructions
</span><span class="cx">     unsigned instructionCount = unlinkedCodeBlock-&gt;instructions().count();
</span><span class="cx">     UnlinkedInstructionStream::Reader instructionReader(unlinkedCodeBlock-&gt;instructions());
</span><span class="lines">@@ -3329,6 +3337,33 @@
</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;RegisterAtOffsetList&gt;(calleeSaveRegisters);
+}
+
+void CodeBlock::setCalleeSaveRegisters(std::unique_ptr&lt;RegisterAtOffsetList&gt; registerAtOffsetList)
+{
+    m_calleeSaveRegisters = WTF::move(registerAtOffsetList);
+}
+    
+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="trunkSourceJavaScriptCorebytecodeCodeBlockh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/CodeBlock.h (189574 => 189575)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/CodeBlock.h        2015-09-10 17:31:42 UTC (rev 189574)
+++ trunk/Source/JavaScriptCore/bytecode/CodeBlock.h        2015-09-10 17:47:16 UTC (rev 189575)
</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 RegisterAtOffsetList;
</ins><span class="cx"> class TypeLocation;
</span><span class="cx"> class JSModuleEnvironment;
</span><span class="cx"> 
</span><span class="lines">@@ -731,6 +732,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 RegisterSet::llintBaselineCalleeSaveRegisters().numberOfSetRegisters(); }
+    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">@@ -816,7 +821,14 @@
</span><span class="cx">     uint32_t exitCountThresholdForReoptimizationFromLoop();
</span><span class="cx">     bool shouldReoptimizeNow();
</span><span class="cx">     bool shouldReoptimizeFromLoopNow();
</span><ins>+
+    void setCalleeSaveRegisters(RegisterSet);
+    void setCalleeSaveRegisters(std::unique_ptr&lt;RegisterAtOffsetList&gt;);
+    
+    RegisterAtOffsetList* 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">@@ -855,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">@@ -1015,6 +1028,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;RegisterAtOffsetList&gt; m_calleeSaveRegisters;
</ins><span class="cx">     Bag&lt;StructureStubInfo&gt; m_stubInfos;
</span><span class="cx">     Bag&lt;ByValInfo&gt; m_byValInfos;
</span><span class="cx">     Bag&lt;CallLinkInfo&gt; m_callLinkInfos;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecompilerBytecodeGeneratorcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp (189574 => 189575)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp        2015-09-10 17:31:42 UTC (rev 189574)
+++ trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp        2015-09-10 17:47:16 UTC (rev 189575)
</span><span class="lines">@@ -158,6 +158,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">@@ -198,6 +200,8 @@
</span><span class="cx"> 
</span><span class="cx">     if (m_isBuiltinFunction)
</span><span class="cx">         m_shouldEmitDebugHooks = false;
</span><ins>+
+    allocateCalleeSaveSpace();
</ins><span class="cx">     
</span><span class="cx">     SymbolTable* functionSymbolTable = SymbolTable::create(*m_vm);
</span><span class="cx">     functionSymbolTable-&gt;setUsesNonStrictEval(m_usesNonStrictEval);
</span><span class="lines">@@ -493,6 +497,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);
</span><span class="cx"> 
</span><span class="cx">     emitOpcode(op_enter);
</span><span class="lines">@@ -537,6 +543,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">     SymbolTable* moduleEnvironmentSymbolTable = SymbolTable::create(*m_vm);
</span><span class="cx">     moduleEnvironmentSymbolTable-&gt;setUsesNonStrictEval(m_usesNonStrictEval);
</span><span class="cx">     moduleEnvironmentSymbolTable-&gt;setScopeType(SymbolTable::ScopeType::LexicalScope);
</span><span class="lines">@@ -3064,6 +3072,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="trunkSourceJavaScriptCorebytecompilerBytecodeGeneratorh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h (189574 => 189575)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h        2015-09-10 17:31:42 UTC (rev 189574)
+++ trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h        2015-09-10 17:47:16 UTC (rev 189575)
</span><span class="lines">@@ -697,6 +697,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">         RegisterID* emitLoadArrowFunctionThis(RegisterID*);
</span><span class="cx">         void emitComplexPopScopes(RegisterID*, ControlFlowContext* topScope, ControlFlowContext* bottomScope);
</span><span class="lines">@@ -810,6 +811,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="trunkSourceJavaScriptCoredfgDFGJITCompilercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGJITCompiler.cpp (189574 => 189575)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGJITCompiler.cpp        2015-09-10 17:31:42 UTC (rev 189574)
+++ trunk/Source/JavaScriptCore/dfg/DFGJITCompiler.cpp        2015-09-10 17:47:16 UTC (rev 189575)
</span><span class="lines">@@ -28,7 +28,6 @@
</span><span class="cx"> 
</span><span class="cx"> #if ENABLE(DFG_JIT)
</span><span class="cx"> 
</span><del>-#include &quot;ArityCheckFailReturnThunks.h&quot;
</del><span class="cx"> #include &quot;CodeBlock.h&quot;
</span><span class="cx"> #include &quot;DFGFailedFinalizer.h&quot;
</span><span class="cx"> #include &quot;DFGInlineCacheWrapperInlines.h&quot;
</span><span class="lines">@@ -102,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">@@ -119,6 +123,8 @@
</span><span class="cx">     if (!m_exceptionChecksWithCallFrameRollback.empty()) {
</span><span class="cx">         m_exceptionChecksWithCallFrameRollback.link(this);
</span><span class="cx"> 
</span><ins>+        copyCalleeSavesToVMCalleeSavesBuffer();
+
</ins><span class="cx">         // lookupExceptionHandlerFromCallerFrame is passed two arguments, the VM and the exec (the CallFrame*).
</span><span class="cx">         move(TrustedImmPtr(vm()), GPRInfo::argumentGPR0);
</span><span class="cx">         move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR1);
</span><span class="lines">@@ -137,6 +143,8 @@
</span><span class="cx">     if (!m_exceptionChecks.empty()) {
</span><span class="cx">         m_exceptionChecks.link(this);
</span><span class="cx"> 
</span><ins>+        copyCalleeSavesToVMCalleeSavesBuffer();
+
</ins><span class="cx">         // lookupExceptionHandler is passed two arguments, the VM and the exec (the CallFrame*).
</span><span class="cx">         move(TrustedImmPtr(vm()), GPRInfo::argumentGPR0);
</span><span class="cx">         move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR1);
</span><span class="lines">@@ -294,6 +302,7 @@
</span><span class="cx"> 
</span><span class="cx">     addPtr(TrustedImm32(m_graph.stackPointerOffset() * sizeof(Register)), GPRInfo::callFrameRegister, stackPointerRegister);
</span><span class="cx">     checkStackPointerAlignment();
</span><ins>+    compileSetupRegistersForEntry();
</ins><span class="cx">     compileBody();
</span><span class="cx">     setEndOfMainPath();
</span><span class="cx"> 
</span><span class="lines">@@ -358,6 +367,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 class="lines">@@ -397,11 +408,6 @@
</span><span class="cx">         addPtr(TrustedImm32(maxFrameExtentForSlowPathCall), stackPointerRegister);
</span><span class="cx">     branchTest32(Zero, GPRInfo::returnValueGPR).linkTo(fromArityCheck, this);
</span><span class="cx">     emitStoreCodeOrigin(CodeOrigin(0));
</span><del>-    GPRReg thunkReg = GPRInfo::argumentGPR1;
-    CodeLocationLabel* arityThunkLabels =
-        m_vm-&gt;arityCheckFailReturnThunks-&gt;returnPCsFor(*m_vm, m_codeBlock-&gt;numParameters());
-    move(TrustedImmPtr(arityThunkLabels), thunkReg);
-    loadPtr(BaseIndex(thunkReg, GPRInfo::returnValueGPR, timesPtr()), thunkReg);
</del><span class="cx">     move(GPRInfo::returnValueGPR, GPRInfo::argumentGPR0);
</span><span class="cx">     m_callArityFixup = call();
</span><span class="cx">     jump(fromArityCheck);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGJITCompilerh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGJITCompiler.h (189574 => 189575)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGJITCompiler.h        2015-09-10 17:31:42 UTC (rev 189574)
+++ trunk/Source/JavaScriptCore/dfg/DFGJITCompiler.h        2015-09-10 17:47:16 UTC (rev 189575)
</span><span class="lines">@@ -265,6 +265,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="trunkSourceJavaScriptCoredfgDFGOSREntrycpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGOSREntry.cpp (189574 => 189575)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGOSREntry.cpp        2015-09-10 17:31:42 UTC (rev 189574)
+++ trunk/Source/JavaScriptCore/dfg/DFGOSREntry.cpp        2015-09-10 17:47:16 UTC (rev 189575)
</span><span class="lines">@@ -308,8 +308,25 @@
</span><span class="cx">             continue;
</span><span class="cx">         pivot[i] = JSValue();
</span><span class="cx">     }
</span><ins>+
+    // 6) Copy our callee saves to buffer.
+#if NUMBER_OF_CALLEE_SAVES_REGISTERS &gt; 0
+    RegisterAtOffsetList* registerSaveLocations = codeBlock-&gt;calleeSaveRegisters();
+    RegisterAtOffsetList* allCalleeSaves = vm-&gt;getAllCalleeSaveRegisterOffsets();
+    RegisterSet dontSaveRegisters = RegisterSet(RegisterSet::stackRegisters(), RegisterSet::allFPRs());
+
+    unsigned registerCount = registerSaveLocations-&gt;size();
+    for (unsigned i = 0; i &lt; registerCount; i++) {
+        RegisterAtOffset currentEntry = registerSaveLocations-&gt;at(i);
+        if (dontSaveRegisters.get(currentEntry.reg()))
+            continue;
+        RegisterAtOffset* vmCalleeSavesEntry = allCalleeSaves-&gt;find(currentEntry.reg());
+        
+        *(bitwise_cast&lt;intptr_t*&gt;(pivot - 1) - currentEntry.offsetAsIndex()) = vm-&gt;calleeSaveRegistersBuffer[vmCalleeSavesEntry-&gt;offsetAsIndex()];
+    }
+#endif
</ins><span class="cx">     
</span><del>-    // 6) Fix the call frame to have the right code block.
</del><ins>+    // 7) Fix the call frame to have the right code block.
</ins><span class="cx">     
</span><span class="cx">     *bitwise_cast&lt;CodeBlock**&gt;(pivot - 1 - JSStack::CodeBlock) = codeBlock;
</span><span class="cx">     
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGOSRExitCompiler32_64cpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGOSRExitCompiler32_64.cpp (189574 => 189575)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGOSRExitCompiler32_64.cpp        2015-09-10 17:31:42 UTC (rev 189574)
+++ trunk/Source/JavaScriptCore/dfg/DFGOSRExitCompiler32_64.cpp        2015-09-10 17:47:16 UTC (rev 189575)
</span><span class="lines">@@ -244,12 +244,21 @@
</span><span class="cx">             -m_jit.codeBlock()-&gt;jitCode()-&gt;dfgCommon()-&gt;requiredRegisterCountForExit * sizeof(Register)),
</span><span class="cx">         CCallHelpers::framePointerRegister, CCallHelpers::stackPointerRegister);
</span><span class="cx">     
</span><ins>+    // Restore the DFG callee saves and then save the ones the baseline JIT uses.
+    m_jit.emitRestoreCalleeSaves();
+    m_jit.emitSaveCalleeSavesFor(m_jit.baselineCodeBlock());
+
</ins><span class="cx">     // Do all data format conversions and store the results into the stack.
</span><span class="cx">     
</span><span class="cx">     for (size_t index = 0; index &lt; operands.size(); ++index) {
</span><span class="cx">         const ValueRecovery&amp; recovery = operands[index];
</span><del>-        int operand = operands.operandForIndex(index);
-        
</del><ins>+        VirtualRegister reg = operands.virtualRegisterForIndex(index);
+
+        if (reg.isLocal() &amp;&amp; reg.toLocal() &lt; static_cast&lt;int&gt;(m_jit.baselineCodeBlock()-&gt;calleeSaveSpaceAsVirtualRegisters()))
+            continue;
+
+        int operand = reg.offset();
+
</ins><span class="cx">         switch (recovery.technique()) {
</span><span class="cx">         case InPair:
</span><span class="cx">         case DisplacedInJSStack:
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGOSRExitCompiler64cpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGOSRExitCompiler64.cpp (189574 => 189575)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGOSRExitCompiler64.cpp        2015-09-10 17:31:42 UTC (rev 189574)
+++ trunk/Source/JavaScriptCore/dfg/DFGOSRExitCompiler64.cpp        2015-09-10 17:47:16 UTC (rev 189575)
</span><span class="lines">@@ -202,7 +202,7 @@
</span><span class="cx">     }
</span><span class="cx">     
</span><span class="cx">     // And voila, all GPRs are free to reuse.
</span><del>-    
</del><ins>+
</ins><span class="cx">     // Save all state from FPRs into the scratch buffer.
</span><span class="cx">     
</span><span class="cx">     for (size_t index = 0; index &lt; operands.size(); ++index) {
</span><span class="lines">@@ -254,12 +254,24 @@
</span><span class="cx">             -m_jit.codeBlock()-&gt;jitCode()-&gt;dfgCommon()-&gt;requiredRegisterCountForExit * sizeof(Register)),
</span><span class="cx">         CCallHelpers::framePointerRegister, CCallHelpers::stackPointerRegister);
</span><span class="cx">     
</span><ins>+    // Restore the DFG callee saves and then save the ones the baseline JIT uses.
+    m_jit.emitRestoreCalleeSaves();
+    m_jit.emitSaveCalleeSavesFor(m_jit.baselineCodeBlock());
+
+    // The tag registers are needed to materialize recoveries below.
+    m_jit.emitMaterializeTagCheckRegisters();
+
</ins><span class="cx">     // Do all data format conversions and store the results into the stack.
</span><span class="cx">     
</span><span class="cx">     for (size_t index = 0; index &lt; operands.size(); ++index) {
</span><span class="cx">         const ValueRecovery&amp; recovery = operands[index];
</span><del>-        int operand = operands.operandForIndex(index);
-        
</del><ins>+        VirtualRegister reg = operands.virtualRegisterForIndex(index);
+
+        if (reg.isLocal() &amp;&amp; reg.toLocal() &lt; static_cast&lt;int&gt;(m_jit.baselineCodeBlock()-&gt;calleeSaveSpaceAsVirtualRegisters()))
+            continue;
+
+        int operand = reg.offset();
+
</ins><span class="cx">         switch (recovery.technique()) {
</span><span class="cx">         case InGPR:
</span><span class="cx">         case UnboxedCellInGPR:
</span><span class="lines">@@ -320,7 +332,7 @@
</span><span class="cx">             break;
</span><span class="cx">         }
</span><span class="cx">     }
</span><del>-    
</del><ins>+
</ins><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="cx">     // refer to certain ranges of locals. Hence why we need to do this here, once the stack is sensible.
</span><span class="lines">@@ -370,7 +382,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="trunkSourceJavaScriptCoredfgDFGOSRExitCompilerCommoncpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGOSRExitCompilerCommon.cpp (189574 => 189575)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGOSRExitCompilerCommon.cpp        2015-09-10 17:31:42 UTC (rev 189574)
+++ trunk/Source/JavaScriptCore/dfg/DFGOSRExitCompilerCommon.cpp        2015-09-10 17:47:16 UTC (rev 189575)
</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,8 +278,6 @@
</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><span class="cx">     jit.move(AssemblyHelpers::TrustedImmPtr(jumpTarget), GPRInfo::regT2);
</span><span class="cx">     jit.jump(GPRInfo::regT2);
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGPlancpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGPlan.cpp (189574 => 189575)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGPlan.cpp        2015-09-10 17:31:42 UTC (rev 189574)
+++ trunk/Source/JavaScriptCore/dfg/DFGPlan.cpp        2015-09-10 17:47:16 UTC (rev 189575)
</span><span class="lines">@@ -242,6 +242,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="trunkSourceJavaScriptCoredfgDFGSpeculativeJITcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp (189574 => 189575)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp        2015-09-10 17:31:42 UTC (rev 189574)
+++ trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp        2015-09-10 17:47:16 UTC (rev 189575)
</span><span class="lines">@@ -311,7 +311,7 @@
</span><span class="cx">             result.set(fpr);
</span><span class="cx">     }
</span><span class="cx">     
</span><del>-    result.merge(RegisterSet::specialRegisters());
</del><ins>+    result.merge(RegisterSet::stubUnavailableRegisters());
</ins><span class="cx">     
</span><span class="cx">     return result;
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGSpeculativeJIT32_64cpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp (189574 => 189575)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp        2015-09-10 17:31:42 UTC (rev 189574)
+++ trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp        2015-09-10 17:47:16 UTC (rev 189575)
</span><span class="lines">@@ -3131,6 +3131,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="trunkSourceJavaScriptCoredfgDFGSpeculativeJIT64cpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp (189574 => 189575)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp        2015-09-10 17:31:42 UTC (rev 189574)
+++ trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp        2015-09-10 17:47:16 UTC (rev 189575)
</span><span class="lines">@@ -3190,6 +3190,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 class="lines">@@ -4790,6 +4791,7 @@
</span><span class="cx">             TrustedImm32(m_stream-&gt;size()));
</span><span class="cx">         appendCallSetResult(triggerOSREntryNow, tempGPR);
</span><span class="cx">         MacroAssembler::Jump dontEnter = m_jit.branchTestPtr(MacroAssembler::Zero, tempGPR);
</span><ins>+        m_jit.emitRestoreCalleeSaves();
</ins><span class="cx">         m_jit.jump(tempGPR);
</span><span class="cx">         dontEnter.link(&amp;m_jit);
</span><span class="cx">         silentFillAllRegisters(tempGPR);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGStackLayoutPhasecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGStackLayoutPhase.cpp (189574 => 189575)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGStackLayoutPhase.cpp        2015-09-10 17:31:42 UTC (rev 189574)
+++ trunk/Source/JavaScriptCore/dfg/DFGStackLayoutPhase.cpp        2015-09-10 17:47:16 UTC (rev 189575)
</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="trunkSourceJavaScriptCoreftlFTLCompilecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ftl/FTLCompile.cpp (189574 => 189575)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLCompile.cpp        2015-09-10 17:31:42 UTC (rev 189574)
+++ trunk/Source/JavaScriptCore/ftl/FTLCompile.cpp        2015-09-10 17:47:16 UTC (rev 189575)
</span><span class="lines">@@ -329,7 +329,7 @@
</span><span class="cx"> 
</span><span class="cx"> static void fixFunctionBasedOnStackMaps(
</span><span class="cx">     State&amp; state, CodeBlock* codeBlock, JITCode* jitCode, GeneratedFunction generatedFunction,
</span><del>-    StackMaps::RecordMap&amp; recordMap, bool didSeeUnwindInfo)
</del><ins>+    StackMaps::RecordMap&amp; recordMap)
</ins><span class="cx"> {
</span><span class="cx">     Graph&amp; graph = state.graph;
</span><span class="cx">     VM&amp; vm = graph.m_vm;
</span><span class="lines">@@ -365,12 +365,14 @@
</span><span class="cx">         
</span><span class="cx">         // At this point it's perfectly fair to just blow away all state and restore the
</span><span class="cx">         // JS JIT view of the universe.
</span><ins>+        checkJIT.copyCalleeSavesToVMCalleeSavesBuffer();
</ins><span class="cx">         checkJIT.move(MacroAssembler::TrustedImmPtr(&amp;vm), GPRInfo::argumentGPR0);
</span><span class="cx">         checkJIT.move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR1);
</span><span class="cx">         MacroAssembler::Call callLookupExceptionHandler = checkJIT.call();
</span><span class="cx">         checkJIT.jumpToExceptionHandler();
</span><span class="cx"> 
</span><span class="cx">         stackOverflowException = checkJIT.label();
</span><ins>+        checkJIT.copyCalleeSavesToVMCalleeSavesBuffer();
</ins><span class="cx">         checkJIT.move(MacroAssembler::TrustedImmPtr(&amp;vm), GPRInfo::argumentGPR0);
</span><span class="cx">         checkJIT.move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR1);
</span><span class="cx">         MacroAssembler::Call callLookupExceptionHandlerFromCallerFrame = checkJIT.call();
</span><span class="lines">@@ -392,7 +394,6 @@
</span><span class="cx">     exitThunkGenerator.emitThunks();
</span><span class="cx">     if (exitThunkGenerator.didThings()) {
</span><span class="cx">         RELEASE_ASSERT(state.finalizer-&gt;osrExit.size());
</span><del>-        RELEASE_ASSERT(didSeeUnwindInfo);
</del><span class="cx">         
</span><span class="cx">         auto linkBuffer = std::make_unique&lt;LinkBuffer&gt;(
</span><span class="cx">             vm, exitThunkGenerator, codeBlock, JITCompilationCanFail);
</span><span class="lines">@@ -814,16 +815,14 @@
</span><span class="cx">         }
</span><span class="cx">     }
</span><span class="cx">     
</span><del>-    bool didSeeUnwindInfo = state.jitCode-&gt;unwindInfo.parse(
</del><ins>+    std::unique_ptr&lt;RegisterAtOffsetList&gt; registerOffsets = parseUnwindInfo(
</ins><span class="cx">         state.unwindDataSection, state.unwindDataSectionSize,
</span><span class="cx">         state.generatedFunction);
</span><span class="cx">     if (shouldShowDisassembly()) {
</span><span class="cx">         dataLog(&quot;Unwind info for &quot;, CodeBlockWithJITType(state.graph.m_codeBlock, JITCode::FTLJIT), &quot;:\n&quot;);
</span><del>-        if (didSeeUnwindInfo)
-            dataLog(&quot;    &quot;, state.jitCode-&gt;unwindInfo, &quot;\n&quot;);
-        else
-            dataLog(&quot;    &lt;no unwind info&gt;\n&quot;);
</del><ins>+        dataLog(&quot;    &quot;, *registerOffsets, &quot;\n&quot;);
</ins><span class="cx">     }
</span><ins>+    state.graph.m_codeBlock-&gt;setCalleeSaveRegisters(WTF::move(registerOffsets));
</ins><span class="cx">     
</span><span class="cx">     if (state.stackmapsSection &amp;&amp; state.stackmapsSection-&gt;size()) {
</span><span class="cx">         if (shouldShowDisassembly()) {
</span><span class="lines">@@ -846,7 +845,7 @@
</span><span class="cx">         StackMaps::RecordMap recordMap = state.jitCode-&gt;stackmaps.computeRecordMap();
</span><span class="cx">         fixFunctionBasedOnStackMaps(
</span><span class="cx">             state, state.graph.m_codeBlock, state.jitCode.get(), state.generatedFunction,
</span><del>-            recordMap, didSeeUnwindInfo);
</del><ins>+            recordMap);
</ins><span class="cx">         if (state.allocationFailed)
</span><span class="cx">             return;
</span><span class="cx">         
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLJITCodeh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ftl/FTLJITCode.h (189574 => 189575)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLJITCode.h        2015-09-10 17:31:42 UTC (rev 189574)
+++ trunk/Source/JavaScriptCore/ftl/FTLJITCode.h        2015-09-10 17:47:16 UTC (rev 189575)
</span><span class="lines">@@ -84,7 +84,6 @@
</span><span class="cx">     DFG::CommonData common;
</span><span class="cx">     SegmentedVector&lt;OSRExit, 8&gt; osrExit;
</span><span class="cx">     StackMaps stackmaps;
</span><del>-    UnwindInfo unwindInfo;
</del><span class="cx">     
</span><span class="cx"> private:
</span><span class="cx">     Vector&lt;RefPtr&lt;DataSection&gt;&gt; m_dataSections;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLLinkcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ftl/FTLLink.cpp (189574 => 189575)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLLink.cpp        2015-09-10 17:31:42 UTC (rev 189574)
+++ trunk/Source/JavaScriptCore/ftl/FTLLink.cpp        2015-09-10 17:47:16 UTC (rev 189575)
</span><span class="lines">@@ -28,7 +28,6 @@
</span><span class="cx"> 
</span><span class="cx"> #if ENABLE(FTL_JIT)
</span><span class="cx"> 
</span><del>-#include &quot;ArityCheckFailReturnThunks.h&quot;
</del><span class="cx"> #include &quot;CCallHelpers.h&quot;
</span><span class="cx"> #include &quot;CodeBlockWithJITType.h&quot;
</span><span class="cx"> #include &quot;DFGCommon.h&quot;
</span><span class="lines">@@ -54,9 +53,7 @@
</span><span class="cx">     // LLVM will create its own jump tables as needed.
</span><span class="cx">     codeBlock-&gt;clearSwitchJumpTables();
</span><span class="cx">     
</span><del>-    // FIXME: Need to know the real frame register count.
-    // https://bugs.webkit.org/show_bug.cgi?id=125727
-    state.jitCode-&gt;common.frameRegisterCount = 1000;
</del><ins>+    state.jitCode-&gt;common.frameRegisterCount = state.jitCode-&gt;stackmaps.stackSizeForLocals() / sizeof(void*);
</ins><span class="cx">     
</span><span class="cx">     state.jitCode-&gt;common.requiredRegisterCountForExit = graph.requiredRegisterCountForExit();
</span><span class="cx">     
</span><span class="lines">@@ -169,10 +166,6 @@
</span><span class="cx">         jit.emitFunctionEpilogue();
</span><span class="cx">         mainPathJumps.append(jit.branchTest32(CCallHelpers::Zero, GPRInfo::argumentGPR0));
</span><span class="cx">         jit.emitFunctionPrologue();
</span><del>-        CodeLocationLabel* arityThunkLabels =
-            vm.arityCheckFailReturnThunks-&gt;returnPCsFor(vm, codeBlock-&gt;numParameters());
-        jit.move(CCallHelpers::TrustedImmPtr(arityThunkLabels), GPRInfo::argumentGPR1);
-        jit.loadPtr(CCallHelpers::BaseIndex(GPRInfo::argumentGPR1, GPRInfo::argumentGPR0, CCallHelpers::timesPtr()), GPRInfo::argumentGPR1);
</del><span class="cx">         CCallHelpers::Call callArityFixup = jit.call();
</span><span class="cx">         jit.emitFunctionEpilogue();
</span><span class="cx">         mainPathJumps.append(jit.jump());
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLOSRExitCompilercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ftl/FTLOSRExitCompiler.cpp (189574 => 189575)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLOSRExitCompiler.cpp        2015-09-10 17:31:42 UTC (rev 189574)
+++ trunk/Source/JavaScriptCore/ftl/FTLOSRExitCompiler.cpp        2015-09-10 17:47:16 UTC (rev 189575)
</span><span class="lines">@@ -211,7 +211,7 @@
</span><span class="cx">         sizeof(EncodedJSValue) * (
</span><span class="cx">             exit.m_values.size() + numMaterializations + maxMaterializationNumArguments) +
</span><span class="cx">         requiredScratchMemorySizeInBytes() +
</span><del>-        jitCode-&gt;unwindInfo.m_registers.size() * sizeof(uint64_t));
</del><ins>+        codeBlock-&gt;calleeSaveRegisters()-&gt;size() * sizeof(uint64_t));
</ins><span class="cx">     EncodedJSValue* scratch = scratchBuffer ? static_cast&lt;EncodedJSValue*&gt;(scratchBuffer-&gt;dataBuffer()) : 0;
</span><span class="cx">     EncodedJSValue* materializationPointers = scratch + exit.m_values.size();
</span><span class="cx">     EncodedJSValue* materializationArguments = materializationPointers + numMaterializations;
</span><span class="lines">@@ -384,8 +384,8 @@
</span><span class="cx">     
</span><span class="cx">     // Before we start messing with the frame, we need to set aside any registers that the
</span><span class="cx">     // FTL code was preserving.
</span><del>-    for (unsigned i = jitCode-&gt;unwindInfo.m_registers.size(); i--;) {
-        RegisterAtOffset entry = jitCode-&gt;unwindInfo.m_registers[i];
</del><ins>+    for (unsigned i = codeBlock-&gt;calleeSaveRegisters()-&gt;size(); i--;) {
+        RegisterAtOffset entry = codeBlock-&gt;calleeSaveRegisters()-&gt;at(i);
</ins><span class="cx">         jit.load64(
</span><span class="cx">             MacroAssembler::Address(MacroAssembler::framePointerRegister, entry.offset()),
</span><span class="cx">             GPRInfo::regT0);
</span><span class="lines">@@ -432,10 +432,12 @@
</span><span class="cx">     jit.add32(GPRInfo::regT3, GPRInfo::regT2);
</span><span class="cx">     arityIntact.link(&amp;jit);
</span><span class="cx"> 
</span><ins>+    CodeBlock* baselineCodeBlock = jit.baselineCodeBlockFor(exit.m_codeOrigin);
+
</ins><span class="cx">     // First set up SP so that our data doesn't get clobbered by signals.
</span><span class="cx">     unsigned conservativeStackDelta =
</span><span class="cx">         registerPreservationOffset() +
</span><del>-        exit.m_values.numberOfLocals() * sizeof(Register) +
</del><ins>+        (exit.m_values.numberOfLocals() + baselineCodeBlock-&gt;calleeSaveSpaceAsVirtualRegisters()) * sizeof(Register) +
</ins><span class="cx">         maxFrameExtentForSlowPathCall;
</span><span class="cx">     conservativeStackDelta = WTF::roundUpToMultipleOf(
</span><span class="cx">         stackAlignmentBytes(), conservativeStackDelta);
</span><span class="lines">@@ -457,67 +459,59 @@
</span><span class="cx">     jit.store64(GPRInfo::regT0, GPRInfo::regT1);
</span><span class="cx">     jit.addPtr(MacroAssembler::TrustedImm32(sizeof(Register)), GPRInfo::regT1);
</span><span class="cx">     jit.branchTest32(MacroAssembler::NonZero, GPRInfo::regT2).linkTo(loop, &amp;jit);
</span><del>-    
-    // At this point regT1 points to where we would save our registers. Save them here.
-    ptrdiff_t currentOffset = 0;
</del><ins>+
+    RegisterAtOffsetList* baselineCalleeSaves = baselineCodeBlock-&gt;calleeSaveRegisters();
+
</ins><span class="cx">     for (Reg reg = Reg::first(); reg &lt;= Reg::last(); reg = reg.next()) {
</span><del>-        if (!toSave.get(reg))
</del><ins>+        if (!toSave.get(reg) || !reg.isGPR())
</ins><span class="cx">             continue;
</span><del>-        currentOffset += sizeof(Register);
-        unsigned unwindIndex = jitCode-&gt;unwindInfo.indexOf(reg);
-        if (unwindIndex == UINT_MAX) {
-            // The FTL compilation didn't preserve this register. This means that it also
-            // didn't use the register. So its value at the beginning of OSR exit should be
-            // preserved by the thunk. Luckily, we saved all registers into the register
-            // scratch buffer, so we can restore them from there.
-            jit.load64(registerScratch + offsetOfReg(reg), GPRInfo::regT0);
</del><ins>+        unsigned unwindIndex = codeBlock-&gt;calleeSaveRegisters()-&gt;indexOf(reg);
+        RegisterAtOffset* baselineRegisterOffset = baselineCalleeSaves-&gt;find(reg);
+
+        if (reg.isGPR()) {
+            GPRReg regToLoad = baselineRegisterOffset ? GPRInfo::regT0 : reg.gpr();
+
+            if (unwindIndex == UINT_MAX) {
+                // The FTL compilation didn't preserve this register. This means that it also
+                // didn't use the register. So its value at the beginning of OSR exit should be
+                // preserved by the thunk. Luckily, we saved all registers into the register
+                // scratch buffer, so we can restore them from there.
+                jit.load64(registerScratch + offsetOfReg(reg), regToLoad);
+            } else {
+                // The FTL compilation preserved the register. Its new value is therefore
+                // irrelevant, but we can get the value that was preserved by using the unwind
+                // data. We've already copied all unwind-able preserved registers into the unwind
+                // scratch buffer, so we can get it from there.
+                jit.load64(unwindScratch + unwindIndex, regToLoad);
+            }
+
+            if (baselineRegisterOffset)
+                jit.store64(regToLoad, MacroAssembler::Address(MacroAssembler::framePointerRegister, baselineRegisterOffset-&gt;offset()));
</ins><span class="cx">         } else {
</span><del>-            // The FTL compilation preserved the register. Its new value is therefore
-            // irrelevant, but we can get the value that was preserved by using the unwind
-            // data. We've already copied all unwind-able preserved registers into the unwind
-            // scratch buffer, so we can get it from there.
-            jit.load64(unwindScratch + unwindIndex, GPRInfo::regT0);
</del><ins>+            FPRReg fpRegToLoad = baselineRegisterOffset ? FPRInfo::fpRegT0 : reg.fpr();
+
+            if (unwindIndex == UINT_MAX)
+                jit.loadDouble(MacroAssembler::TrustedImmPtr(registerScratch + offsetOfReg(reg)), fpRegToLoad);
+            else
+                jit.loadDouble(MacroAssembler::TrustedImmPtr(unwindScratch + unwindIndex), fpRegToLoad);
+
+            if (baselineRegisterOffset)
+                jit.storeDouble(fpRegToLoad, MacroAssembler::Address(MacroAssembler::framePointerRegister, baselineRegisterOffset-&gt;offset()));
</ins><span class="cx">         }
</span><del>-        jit.store64(GPRInfo::regT0, AssemblyHelpers::Address(GPRInfo::regT1, currentOffset));
</del><span class="cx">     }
</span><del>-    
-    // We need to make sure that we return into the register restoration thunk. This works
-    // differently depending on whether or not we had arity issues.
-    MacroAssembler::Jump arityIntactForReturnPC = jit.branch32(
-        MacroAssembler::GreaterThanOrEqual,
-        CCallHelpers::payloadFor(JSStack::ArgumentCount),
-        MacroAssembler::TrustedImm32(codeBlock-&gt;numParameters()));
-    
-    // The return PC in the call frame header points at exactly the right arity restoration
-    // thunk. We don't want to change that. But the arity restoration thunk's frame has a
-    // return PC and we want to reroute that to our register restoration thunk. The arity
-    // restoration's return PC just just below regT1, and the register restoration's return PC
-    // is right at regT1.
-    jit.loadPtr(MacroAssembler::Address(GPRInfo::regT1, -static_cast&lt;ptrdiff_t&gt;(sizeof(Register))), GPRInfo::regT0);
-    jit.storePtr(GPRInfo::regT0, GPRInfo::regT1);
-    jit.storePtr(
-        MacroAssembler::TrustedImmPtr(vm-&gt;getCTIStub(registerRestorationThunkGenerator).code().executableAddress()),
-        MacroAssembler::Address(GPRInfo::regT1, -static_cast&lt;ptrdiff_t&gt;(sizeof(Register))));
-    
-    MacroAssembler::Jump arityReturnPCReady = jit.jump();
</del><span class="cx"> 
</span><del>-    arityIntactForReturnPC.link(&amp;jit);
-    
-    jit.loadPtr(MacroAssembler::Address(MacroAssembler::framePointerRegister, CallFrame::returnPCOffset()), GPRInfo::regT0);
-    jit.storePtr(GPRInfo::regT0, GPRInfo::regT1);
-    jit.storePtr(
-        MacroAssembler::TrustedImmPtr(vm-&gt;getCTIStub(registerRestorationThunkGenerator).code().executableAddress()),
-        MacroAssembler::Address(MacroAssembler::framePointerRegister, CallFrame::returnPCOffset()));
-    
-    arityReturnPCReady.link(&amp;jit);
-    
</del><ins>+    size_t baselineVirtualRegistersForCalleeSaves = baselineCodeBlock-&gt;calleeSaveSpaceAsVirtualRegisters();
+
</ins><span class="cx">     // Now get state out of the scratch buffer and place it back into the stack. The values are
</span><span class="cx">     // already reboxed so we just move them.
</span><span class="cx">     for (unsigned index = exit.m_values.size(); index--;) {
</span><del>-        int operand = exit.m_values.operandForIndex(index);
-        
</del><ins>+        VirtualRegister reg = exit.m_values.virtualRegisterForIndex(index);
+
+        if (reg.isLocal() &amp;&amp; reg.toLocal() &lt; static_cast&lt;int&gt;(baselineVirtualRegistersForCalleeSaves))
+            continue;
+
</ins><span class="cx">         jit.load64(scratch + index, GPRInfo::regT0);
</span><del>-        jit.store64(GPRInfo::regT0, AssemblyHelpers::addressFor(static_cast&lt;VirtualRegister&gt;(operand)));
</del><ins>+        jit.store64(GPRInfo::regT0, AssemblyHelpers::addressFor(reg));
</ins><span class="cx">     }
</span><span class="cx">     
</span><span class="cx">     handleExitCounts(jit, exit);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLRegisterAtOffsetcpp"></a>
<div class="delfile"><h4>Deleted: trunk/Source/JavaScriptCore/ftl/FTLRegisterAtOffset.cpp (189574 => 189575)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLRegisterAtOffset.cpp        2015-09-10 17:31:42 UTC (rev 189574)
+++ trunk/Source/JavaScriptCore/ftl/FTLRegisterAtOffset.cpp        2015-09-10 17:47:16 UTC (rev 189575)
</span><span class="lines">@@ -1,41 +0,0 @@
</span><del>-/*
- * Copyright (C) 2013, 2014 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;FTLRegisterAtOffset.h&quot;
-
-#if ENABLE(FTL_JIT)
-
-namespace JSC { namespace FTL {
-
-void RegisterAtOffset::dump(PrintStream&amp; out) const
-{
-    out.print(reg(), &quot; at &quot;, offset());
-}
-
-} } // namespace JSC::FTL
-
-#endif // ENABLE(FTL_JIT)
-
</del></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLRegisterAtOffseth"></a>
<div class="delfile"><h4>Deleted: trunk/Source/JavaScriptCore/ftl/FTLRegisterAtOffset.h (189574 => 189575)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLRegisterAtOffset.h        2015-09-10 17:31:42 UTC (rev 189574)
+++ trunk/Source/JavaScriptCore/ftl/FTLRegisterAtOffset.h        2015-09-10 17:47:16 UTC (rev 189575)
</span><span class="lines">@@ -1,80 +0,0 @@
</span><del>-/*
- * Copyright (C) 2013, 2014 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 FTLRegisterAtOffset_h
-#define FTLRegisterAtOffset_h
-
-#if ENABLE(FTL_JIT)
-
-#include &quot;Reg.h&quot;
-#include &lt;wtf/PrintStream.h&gt;
-
-namespace JSC { namespace FTL {
-
-class RegisterAtOffset {
-public:
-    RegisterAtOffset()
-        : m_offset(0)
-    {
-    }
-    
-    RegisterAtOffset(Reg reg, ptrdiff_t offset)
-        : m_reg(reg)
-        , m_offset(offset)
-    {
-    }
-    
-    bool operator!() const { return !m_reg; }
-    
-    Reg reg() const { return m_reg; }
-    ptrdiff_t offset() const { return m_offset; }
-    
-    bool operator==(const RegisterAtOffset&amp; other) const
-    {
-        return reg() == other.reg() &amp;&amp; offset() == other.offset();
-    }
-    
-    bool operator&lt;(const RegisterAtOffset&amp; other) const
-    {
-        if (reg() != other.reg())
-            return reg() &lt; other.reg();
-        return offset() &lt; other.offset();
-    }
-    
-    static Reg getReg(RegisterAtOffset* value) { return value-&gt;reg(); }
-    
-    void dump(PrintStream&amp; out) const;
-
-private:
-    Reg m_reg;
-    ptrdiff_t m_offset;
-};
-
-} } // namespace JSC::FTL
-
-#endif // ENABLE(FTL_JIT)
-
-#endif // FTLRegisterAtOffset_h
-
</del></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLThunkscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ftl/FTLThunks.cpp (189574 => 189575)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLThunks.cpp        2015-09-10 17:31:42 UTC (rev 189574)
+++ trunk/Source/JavaScriptCore/ftl/FTLThunks.cpp        2015-09-10 17:47:16 UTC (rev 189575)
</span><span class="lines">@@ -66,8 +66,8 @@
</span><span class="cx">     saveAllRegisters(jit, buffer);
</span><span class="cx">     
</span><span class="cx">     // Tell GC mark phase how much of the scratch buffer is active during call.
</span><del>-    jit.move(MacroAssembler::TrustedImmPtr(scratchBuffer-&gt;activeLengthPtr()), GPRInfo::nonArgGPR1);
-    jit.storePtr(MacroAssembler::TrustedImmPtr(requiredScratchMemorySizeInBytes()), GPRInfo::nonArgGPR1);
</del><ins>+    jit.move(MacroAssembler::TrustedImmPtr(scratchBuffer-&gt;activeLengthPtr()), GPRInfo::nonArgGPR0);
+    jit.storePtr(MacroAssembler::TrustedImmPtr(requiredScratchMemorySizeInBytes()), GPRInfo::nonArgGPR0);
</ins><span class="cx"> 
</span><span class="cx">     jit.loadPtr(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
</span><span class="cx">     jit.peek(
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLUnwindInfocpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ftl/FTLUnwindInfo.cpp (189574 => 189575)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLUnwindInfo.cpp        2015-09-10 17:31:42 UTC (rev 189574)
+++ trunk/Source/JavaScriptCore/ftl/FTLUnwindInfo.cpp        2015-09-10 17:47:16 UTC (rev 189575)
</span><span class="lines">@@ -94,6 +94,9 @@
</span><span class="cx"> #include &quot;config.h&quot;
</span><span class="cx"> #include &quot;FTLUnwindInfo.h&quot;
</span><span class="cx"> 
</span><ins>+#include &quot;CodeBlock.h&quot;
+#include &quot;RegisterAtOffsetList.h&quot;
+
</ins><span class="cx"> #if ENABLE(FTL_JIT)
</span><span class="cx"> 
</span><span class="cx"> #if OS(DARWIN)
</span><span class="lines">@@ -103,10 +106,6 @@
</span><span class="cx"> 
</span><span class="cx"> namespace JSC { namespace FTL {
</span><span class="cx"> 
</span><del>-UnwindInfo::UnwindInfo() { }
-UnwindInfo::~UnwindInfo() { }
-
-
</del><span class="cx"> namespace {
</span><span class="cx"> #if OS(DARWIN)
</span><span class="cx"> struct CompactUnwind {
</span><span class="lines">@@ -654,13 +653,12 @@
</span><span class="cx"> #endif
</span><span class="cx"> } // anonymous namespace
</span><span class="cx"> 
</span><del>-bool UnwindInfo::parse(void* section, size_t size, GeneratedFunction generatedFunction)
</del><ins>+std::unique_ptr&lt;RegisterAtOffsetList&gt; parseUnwindInfo(void* section, size_t size, GeneratedFunction generatedFunction)
</ins><span class="cx"> {
</span><del>-    m_registers.clear();
</del><span class="cx">     RELEASE_ASSERT(!!section);
</span><del>-    if (!section)
-        return false;
</del><span class="cx"> 
</span><ins>+    std::unique_ptr&lt;RegisterAtOffsetList&gt; registerOffsets = std::make_unique&lt;RegisterAtOffsetList&gt;();
+
</ins><span class="cx"> #if OS(DARWIN)
</span><span class="cx">     RELEASE_ASSERT(size &gt;= sizeof(CompactUnwind));
</span><span class="cx">     
</span><span class="lines">@@ -689,27 +687,27 @@
</span><span class="cx">             break;
</span><span class="cx">             
</span><span class="cx">         case UNWIND_X86_64_REG_RBX:
</span><del>-            m_registers.append(RegisterAtOffset(X86Registers::ebx, offset));
</del><ins>+            registerOffsets-&gt;append(RegisterAtOffset(X86Registers::ebx, offset));
</ins><span class="cx">             break;
</span><span class="cx">             
</span><span class="cx">         case UNWIND_X86_64_REG_R12:
</span><del>-            m_registers.append(RegisterAtOffset(X86Registers::r12, offset));
</del><ins>+            registerOffsets-&gt;append(RegisterAtOffset(X86Registers::r12, offset));
</ins><span class="cx">             break;
</span><span class="cx">             
</span><span class="cx">         case UNWIND_X86_64_REG_R13:
</span><del>-            m_registers.append(RegisterAtOffset(X86Registers::r13, offset));
</del><ins>+            registerOffsets-&gt;append(RegisterAtOffset(X86Registers::r13, offset));
</ins><span class="cx">             break;
</span><span class="cx">             
</span><span class="cx">         case UNWIND_X86_64_REG_R14:
</span><del>-            m_registers.append(RegisterAtOffset(X86Registers::r14, offset));
</del><ins>+            registerOffsets-&gt;append(RegisterAtOffset(X86Registers::r14, offset));
</ins><span class="cx">             break;
</span><span class="cx">             
</span><span class="cx">         case UNWIND_X86_64_REG_R15:
</span><del>-            m_registers.append(RegisterAtOffset(X86Registers::r15, offset));
</del><ins>+            registerOffsets-&gt;append(RegisterAtOffset(X86Registers::r15, offset));
</ins><span class="cx">             break;
</span><span class="cx">             
</span><span class="cx">         case UNWIND_X86_64_REG_RBP:
</span><del>-            m_registers.append(RegisterAtOffset(X86Registers::ebp, offset));
</del><ins>+            registerOffsets-&gt;append(RegisterAtOffset(X86Registers::ebp, offset));
</ins><span class="cx">             break;
</span><span class="cx">             
</span><span class="cx">         default:
</span><span class="lines">@@ -721,44 +719,44 @@
</span><span class="cx"> #elif CPU(ARM64)
</span><span class="cx">     RELEASE_ASSERT((encoding &amp; UNWIND_ARM64_MODE_MASK) == UNWIND_ARM64_MODE_FRAME);
</span><span class="cx">     
</span><del>-    m_registers.append(RegisterAtOffset(ARM64Registers::fp, 0));
</del><ins>+    registerOffsets-&gt;append(RegisterAtOffset(ARM64Registers::fp, 0));
</ins><span class="cx">     
</span><span class="cx">     int32_t offset = 0;
</span><span class="cx">     if (encoding &amp; UNWIND_ARM64_FRAME_X19_X20_PAIR) {
</span><del>-        m_registers.append(RegisterAtOffset(ARM64Registers::x19, offset -= 8));
-        m_registers.append(RegisterAtOffset(ARM64Registers::x20, offset -= 8));
</del><ins>+        registerOffsets-&gt;append(RegisterAtOffset(ARM64Registers::x19, offset -= 8));
+        registerOffsets-&gt;append(RegisterAtOffset(ARM64Registers::x20, offset -= 8));
</ins><span class="cx">     }
</span><span class="cx">     if (encoding &amp; UNWIND_ARM64_FRAME_X21_X22_PAIR) {
</span><del>-        m_registers.append(RegisterAtOffset(ARM64Registers::x21, offset -= 8));
-        m_registers.append(RegisterAtOffset(ARM64Registers::x22, offset -= 8));
</del><ins>+        registerOffsets-&gt;append(RegisterAtOffset(ARM64Registers::x21, offset -= 8));
+        registerOffsets-&gt;append(RegisterAtOffset(ARM64Registers::x22, offset -= 8));
</ins><span class="cx">     }
</span><span class="cx">     if (encoding &amp; UNWIND_ARM64_FRAME_X23_X24_PAIR) {
</span><del>-        m_registers.append(RegisterAtOffset(ARM64Registers::x23, offset -= 8));
-        m_registers.append(RegisterAtOffset(ARM64Registers::x24, offset -= 8));
</del><ins>+        registerOffsets-&gt;append(RegisterAtOffset(ARM64Registers::x23, offset -= 8));
+        registerOffsets-&gt;append(RegisterAtOffset(ARM64Registers::x24, offset -= 8));
</ins><span class="cx">     }
</span><span class="cx">     if (encoding &amp; UNWIND_ARM64_FRAME_X25_X26_PAIR) {
</span><del>-        m_registers.append(RegisterAtOffset(ARM64Registers::x25, offset -= 8));
-        m_registers.append(RegisterAtOffset(ARM64Registers::x26, offset -= 8));
</del><ins>+        registerOffsets-&gt;append(RegisterAtOffset(ARM64Registers::x25, offset -= 8));
+        registerOffsets-&gt;append(RegisterAtOffset(ARM64Registers::x26, offset -= 8));
</ins><span class="cx">     }
</span><span class="cx">     if (encoding &amp; UNWIND_ARM64_FRAME_X27_X28_PAIR) {
</span><del>-        m_registers.append(RegisterAtOffset(ARM64Registers::x27, offset -= 8));
-        m_registers.append(RegisterAtOffset(ARM64Registers::x28, offset -= 8));
</del><ins>+        registerOffsets-&gt;append(RegisterAtOffset(ARM64Registers::x27, offset -= 8));
+        registerOffsets-&gt;append(RegisterAtOffset(ARM64Registers::x28, offset -= 8));
</ins><span class="cx">     }
</span><span class="cx">     if (encoding &amp; UNWIND_ARM64_FRAME_D8_D9_PAIR) {
</span><del>-        m_registers.append(RegisterAtOffset(ARM64Registers::q8, offset -= 8));
-        m_registers.append(RegisterAtOffset(ARM64Registers::q9, offset -= 8));
</del><ins>+        registerOffsets-&gt;append(RegisterAtOffset(ARM64Registers::q8, offset -= 8));
+        registerOffsets-&gt;append(RegisterAtOffset(ARM64Registers::q9, offset -= 8));
</ins><span class="cx">     }
</span><span class="cx">     if (encoding &amp; UNWIND_ARM64_FRAME_D10_D11_PAIR) {
</span><del>-        m_registers.append(RegisterAtOffset(ARM64Registers::q10, offset -= 8));
-        m_registers.append(RegisterAtOffset(ARM64Registers::q11, offset -= 8));
</del><ins>+        registerOffsets-&gt;append(RegisterAtOffset(ARM64Registers::q10, offset -= 8));
+        registerOffsets-&gt;append(RegisterAtOffset(ARM64Registers::q11, offset -= 8));
</ins><span class="cx">     }
</span><span class="cx">     if (encoding &amp; UNWIND_ARM64_FRAME_D12_D13_PAIR) {
</span><del>-        m_registers.append(RegisterAtOffset(ARM64Registers::q12, offset -= 8));
-        m_registers.append(RegisterAtOffset(ARM64Registers::q13, offset -= 8));
</del><ins>+        registerOffsets-&gt;append(RegisterAtOffset(ARM64Registers::q12, offset -= 8));
+        registerOffsets-&gt;append(RegisterAtOffset(ARM64Registers::q13, offset -= 8));
</ins><span class="cx">     }
</span><span class="cx">     if (encoding &amp; UNWIND_ARM64_FRAME_D14_D15_PAIR) {
</span><del>-        m_registers.append(RegisterAtOffset(ARM64Registers::q14, offset -= 8));
-        m_registers.append(RegisterAtOffset(ARM64Registers::q15, offset -= 8));
</del><ins>+        registerOffsets-&gt;append(RegisterAtOffset(ARM64Registers::q14, offset -= 8));
+        registerOffsets-&gt;append(RegisterAtOffset(ARM64Registers::q15, offset -= 8));
</ins><span class="cx">     }
</span><span class="cx"> #else
</span><span class="cx"> #error &quot;Unrecognized architecture&quot;
</span><span class="lines">@@ -782,22 +780,22 @@
</span><span class="cx">         if (prolog.savedRegisters[i].saved) {
</span><span class="cx">             switch (i) {
</span><span class="cx">             case UNW_X86_64_rbx:
</span><del>-                m_registers.append(RegisterAtOffset(X86Registers::ebx, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
</del><ins>+                registerOffsets-&gt;append(RegisterAtOffset(X86Registers::ebx, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
</ins><span class="cx">                 break;
</span><span class="cx">             case UNW_X86_64_r12:
</span><del>-                m_registers.append(RegisterAtOffset(X86Registers::r12, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
</del><ins>+                registerOffsets-&gt;append(RegisterAtOffset(X86Registers::r12, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
</ins><span class="cx">                 break;
</span><span class="cx">             case UNW_X86_64_r13:
</span><del>-                m_registers.append(RegisterAtOffset(X86Registers::r13, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
</del><ins>+                registerOffsets-&gt;append(RegisterAtOffset(X86Registers::r13, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
</ins><span class="cx">                 break;
</span><span class="cx">             case UNW_X86_64_r14:
</span><del>-                m_registers.append(RegisterAtOffset(X86Registers::r14, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
</del><ins>+                registerOffsets-&gt;append(RegisterAtOffset(X86Registers::r14, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
</ins><span class="cx">                 break;
</span><span class="cx">             case UNW_X86_64_r15:
</span><del>-                m_registers.append(RegisterAtOffset(X86Registers::r15, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
</del><ins>+                registerOffsets-&gt;append(RegisterAtOffset(X86Registers::r15, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
</ins><span class="cx">                 break;
</span><span class="cx">             case UNW_X86_64_rbp:
</span><del>-                m_registers.append(RegisterAtOffset(X86Registers::ebp, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
</del><ins>+                registerOffsets-&gt;append(RegisterAtOffset(X86Registers::ebp, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
</ins><span class="cx">                 break;
</span><span class="cx">             case DW_X86_64_RET_addr:
</span><span class="cx">                 break;
</span><span class="lines">@@ -816,196 +814,196 @@
</span><span class="cx">         if (prolog.savedRegisters[i].saved) {
</span><span class="cx">             switch (i) {
</span><span class="cx">             case UNW_ARM64_x0:
</span><del>-                m_registers.append(RegisterAtOffset(ARM64Registers::x0, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
</del><ins>+                registerOffsets-&gt;append(RegisterAtOffset(ARM64Registers::x0, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
</ins><span class="cx">                 break;
</span><span class="cx">             case UNW_ARM64_x1:
</span><del>-                m_registers.append(RegisterAtOffset(ARM64Registers::x1, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
</del><ins>+                registerOffsets-&gt;append(RegisterAtOffset(ARM64Registers::x1, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
</ins><span class="cx">                 break;
</span><span class="cx">             case UNW_ARM64_x2:
</span><del>-                m_registers.append(RegisterAtOffset(ARM64Registers::x2, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
</del><ins>+                registerOffsets-&gt;append(RegisterAtOffset(ARM64Registers::x2, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
</ins><span class="cx">                 break;
</span><span class="cx">             case UNW_ARM64_x3:
</span><del>-                m_registers.append(RegisterAtOffset(ARM64Registers::x3, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
</del><ins>+                registerOffsets-&gt;append(RegisterAtOffset(ARM64Registers::x3, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
</ins><span class="cx">                 break;
</span><span class="cx">             case UNW_ARM64_x4:
</span><del>-                m_registers.append(RegisterAtOffset(ARM64Registers::x4, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
</del><ins>+                registerOffsets-&gt;append(RegisterAtOffset(ARM64Registers::x4, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
</ins><span class="cx">                 break;
</span><span class="cx">             case UNW_ARM64_x5:
</span><del>-                m_registers.append(RegisterAtOffset(ARM64Registers::x5, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
</del><ins>+                registerOffsets-&gt;append(RegisterAtOffset(ARM64Registers::x5, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
</ins><span class="cx">                 break;
</span><span class="cx">             case UNW_ARM64_x6:
</span><del>-                m_registers.append(RegisterAtOffset(ARM64Registers::x6, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
</del><ins>+                registerOffsets-&gt;append(RegisterAtOffset(ARM64Registers::x6, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
</ins><span class="cx">                 break;
</span><span class="cx">             case UNW_ARM64_x7:
</span><del>-                m_registers.append(RegisterAtOffset(ARM64Registers::x7, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
</del><ins>+                registerOffsets-&gt;append(RegisterAtOffset(ARM64Registers::x7, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
</ins><span class="cx">                 break;
</span><span class="cx">             case UNW_ARM64_x8:
</span><del>-                m_registers.append(RegisterAtOffset(ARM64Registers::x8, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
</del><ins>+                registerOffsets-&gt;append(RegisterAtOffset(ARM64Registers::x8, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
</ins><span class="cx">                 break;
</span><span class="cx">             case UNW_ARM64_x9:
</span><del>-                m_registers.append(RegisterAtOffset(ARM64Registers::x9, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
</del><ins>+                registerOffsets-&gt;append(RegisterAtOffset(ARM64Registers::x9, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
</ins><span class="cx">                 break;
</span><span class="cx">             case UNW_ARM64_x10:
</span><del>-                m_registers.append(RegisterAtOffset(ARM64Registers::x10, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
</del><ins>+                registerOffsets-&gt;append(RegisterAtOffset(ARM64Registers::x10, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
</ins><span class="cx">                 break;
</span><span class="cx">             case UNW_ARM64_x11:
</span><del>-                m_registers.append(RegisterAtOffset(ARM64Registers::x11, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
</del><ins>+                registerOffsets-&gt;append(RegisterAtOffset(ARM64Registers::x11, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
</ins><span class="cx">                 break;
</span><span class="cx">             case UNW_ARM64_x12:
</span><del>-                m_registers.append(RegisterAtOffset(ARM64Registers::x12, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
</del><ins>+                registerOffsets-&gt;append(RegisterAtOffset(ARM64Registers::x12, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
</ins><span class="cx">                 break;
</span><span class="cx">             case UNW_ARM64_x13:
</span><del>-                m_registers.append(RegisterAtOffset(ARM64Registers::x13, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
</del><ins>+                registerOffsets-&gt;append(RegisterAtOffset(ARM64Registers::x13, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
</ins><span class="cx">                 break;
</span><span class="cx">             case UNW_ARM64_x14:
</span><del>-                m_registers.append(RegisterAtOffset(ARM64Registers::x14, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
</del><ins>+                registerOffsets-&gt;append(RegisterAtOffset(ARM64Registers::x14, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
</ins><span class="cx">                 break;
</span><span class="cx">             case UNW_ARM64_x15:
</span><del>-                m_registers.append(RegisterAtOffset(ARM64Registers::x15, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
</del><ins>+                registerOffsets-&gt;append(RegisterAtOffset(ARM64Registers::x15, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
</ins><span class="cx">                 break;
</span><span class="cx">             case UNW_ARM64_x16:
</span><del>-                m_registers.append(RegisterAtOffset(ARM64Registers::x16, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
</del><ins>+                registerOffsets-&gt;append(RegisterAtOffset(ARM64Registers::x16, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
</ins><span class="cx">                 break;
</span><span class="cx">             case UNW_ARM64_x17:
</span><del>-                m_registers.append(RegisterAtOffset(ARM64Registers::x17, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
</del><ins>+                registerOffsets-&gt;append(RegisterAtOffset(ARM64Registers::x17, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
</ins><span class="cx">                 break;
</span><span class="cx">             case UNW_ARM64_x18:
</span><del>-                m_registers.append(RegisterAtOffset(ARM64Registers::x18, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
</del><ins>+                registerOffsets-&gt;append(RegisterAtOffset(ARM64Registers::x18, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
</ins><span class="cx">                 break;
</span><span class="cx">             case UNW_ARM64_x19:
</span><del>-                m_registers.append(RegisterAtOffset(ARM64Registers::x19, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
</del><ins>+                registerOffsets-&gt;append(RegisterAtOffset(ARM64Registers::x19, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
</ins><span class="cx">                 break;
</span><span class="cx">             case UNW_ARM64_x20:
</span><del>-                m_registers.append(RegisterAtOffset(ARM64Registers::x20, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
</del><ins>+                registerOffsets-&gt;append(RegisterAtOffset(ARM64Registers::x20, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
</ins><span class="cx">                 break;
</span><span class="cx">             case UNW_ARM64_x21:
</span><del>-                m_registers.append(RegisterAtOffset(ARM64Registers::x21, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
</del><ins>+                registerOffsets-&gt;append(RegisterAtOffset(ARM64Registers::x21, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
</ins><span class="cx">                 break;
</span><span class="cx">             case UNW_ARM64_x22:
</span><del>-                m_registers.append(RegisterAtOffset(ARM64Registers::x22, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
</del><ins>+                registerOffsets-&gt;append(RegisterAtOffset(ARM64Registers::x22, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
</ins><span class="cx">                 break;
</span><span class="cx">             case UNW_ARM64_x23:
</span><del>-                m_registers.append(RegisterAtOffset(ARM64Registers::x23, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
</del><ins>+                registerOffsets-&gt;append(RegisterAtOffset(ARM64Registers::x23, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
</ins><span class="cx">                 break;
</span><span class="cx">             case UNW_ARM64_x24:
</span><del>-                m_registers.append(RegisterAtOffset(ARM64Registers::x24, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
</del><ins>+                registerOffsets-&gt;append(RegisterAtOffset(ARM64Registers::x24, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
</ins><span class="cx">                 break;
</span><span class="cx">             case UNW_ARM64_x25:
</span><del>-                m_registers.append(RegisterAtOffset(ARM64Registers::x25, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
</del><ins>+                registerOffsets-&gt;append(RegisterAtOffset(ARM64Registers::x25, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
</ins><span class="cx">                 break;
</span><span class="cx">             case UNW_ARM64_x26:
</span><del>-                m_registers.append(RegisterAtOffset(ARM64Registers::x26, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
</del><ins>+                registerOffsets-&gt;append(RegisterAtOffset(ARM64Registers::x26, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
</ins><span class="cx">                 break;
</span><span class="cx">             case UNW_ARM64_x27:
</span><del>-                m_registers.append(RegisterAtOffset(ARM64Registers::x27, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
</del><ins>+                registerOffsets-&gt;append(RegisterAtOffset(ARM64Registers::x27, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
</ins><span class="cx">                 break;
</span><span class="cx">             case UNW_ARM64_x28:
</span><del>-                m_registers.append(RegisterAtOffset(ARM64Registers::x28, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
</del><ins>+                registerOffsets-&gt;append(RegisterAtOffset(ARM64Registers::x28, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
</ins><span class="cx">                 break;
</span><span class="cx">             case UNW_ARM64_fp:
</span><del>-                m_registers.append(RegisterAtOffset(ARM64Registers::fp, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
</del><ins>+                registerOffsets-&gt;append(RegisterAtOffset(ARM64Registers::fp, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
</ins><span class="cx">                 break;
</span><span class="cx">             case UNW_ARM64_x30:
</span><del>-                m_registers.append(RegisterAtOffset(ARM64Registers::x30, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
</del><ins>+                registerOffsets-&gt;append(RegisterAtOffset(ARM64Registers::x30, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
</ins><span class="cx">                 break;
</span><span class="cx">             case UNW_ARM64_sp:
</span><del>-                m_registers.append(RegisterAtOffset(ARM64Registers::sp, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
</del><ins>+                registerOffsets-&gt;append(RegisterAtOffset(ARM64Registers::sp, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
</ins><span class="cx">                 break;
</span><span class="cx">             case UNW_ARM64_v0:
</span><del>-                m_registers.append(RegisterAtOffset(ARM64Registers::q0, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
</del><ins>+                registerOffsets-&gt;append(RegisterAtOffset(ARM64Registers::q0, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
</ins><span class="cx">                 break;
</span><span class="cx">             case UNW_ARM64_v1:
</span><del>-                m_registers.append(RegisterAtOffset(ARM64Registers::q1, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
</del><ins>+                registerOffsets-&gt;append(RegisterAtOffset(ARM64Registers::q1, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
</ins><span class="cx">                 break;
</span><span class="cx">             case UNW_ARM64_v2:
</span><del>-                m_registers.append(RegisterAtOffset(ARM64Registers::q2, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
</del><ins>+                registerOffsets-&gt;append(RegisterAtOffset(ARM64Registers::q2, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
</ins><span class="cx">                 break;
</span><span class="cx">             case UNW_ARM64_v3:
</span><del>-                m_registers.append(RegisterAtOffset(ARM64Registers::q3, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
</del><ins>+                registerOffsets-&gt;append(RegisterAtOffset(ARM64Registers::q3, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
</ins><span class="cx">                 break;
</span><span class="cx">             case UNW_ARM64_v4:
</span><del>-                m_registers.append(RegisterAtOffset(ARM64Registers::q4, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
</del><ins>+                registerOffsets-&gt;append(RegisterAtOffset(ARM64Registers::q4, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
</ins><span class="cx">                 break;
</span><span class="cx">             case UNW_ARM64_v5:
</span><del>-                m_registers.append(RegisterAtOffset(ARM64Registers::q5, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
</del><ins>+                registerOffsets-&gt;append(RegisterAtOffset(ARM64Registers::q5, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
</ins><span class="cx">                 break;
</span><span class="cx">             case UNW_ARM64_v6:
</span><del>-                m_registers.append(RegisterAtOffset(ARM64Registers::q6, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
</del><ins>+                registerOffsets-&gt;append(RegisterAtOffset(ARM64Registers::q6, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
</ins><span class="cx">                 break;
</span><span class="cx">             case UNW_ARM64_v7:
</span><del>-                m_registers.append(RegisterAtOffset(ARM64Registers::q7, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
</del><ins>+                registerOffsets-&gt;append(RegisterAtOffset(ARM64Registers::q7, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
</ins><span class="cx">                 break;
</span><span class="cx">             case UNW_ARM64_v8:
</span><del>-                m_registers.append(RegisterAtOffset(ARM64Registers::q8, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
</del><ins>+                registerOffsets-&gt;append(RegisterAtOffset(ARM64Registers::q8, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
</ins><span class="cx">                 break;
</span><span class="cx">             case UNW_ARM64_v9:
</span><del>-                m_registers.append(RegisterAtOffset(ARM64Registers::q9, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
</del><ins>+                registerOffsets-&gt;append(RegisterAtOffset(ARM64Registers::q9, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
</ins><span class="cx">                 break;
</span><span class="cx">             case UNW_ARM64_v10:
</span><del>-                m_registers.append(RegisterAtOffset(ARM64Registers::q10, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
</del><ins>+                registerOffsets-&gt;append(RegisterAtOffset(ARM64Registers::q10, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
</ins><span class="cx">                 break;
</span><span class="cx">             case UNW_ARM64_v11:
</span><del>-                m_registers.append(RegisterAtOffset(ARM64Registers::q11, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
</del><ins>+                registerOffsets-&gt;append(RegisterAtOffset(ARM64Registers::q11, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
</ins><span class="cx">                 break;
</span><span class="cx">             case UNW_ARM64_v12:
</span><del>-                m_registers.append(RegisterAtOffset(ARM64Registers::q12, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
</del><ins>+                registerOffsets-&gt;append(RegisterAtOffset(ARM64Registers::q12, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
</ins><span class="cx">                 break;
</span><span class="cx">             case UNW_ARM64_v13:
</span><del>-                m_registers.append(RegisterAtOffset(ARM64Registers::q13, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
</del><ins>+                registerOffsets-&gt;append(RegisterAtOffset(ARM64Registers::q13, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
</ins><span class="cx">                 break;
</span><span class="cx">             case UNW_ARM64_v14:
</span><del>-                m_registers.append(RegisterAtOffset(ARM64Registers::q14, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
</del><ins>+                registerOffsets-&gt;append(RegisterAtOffset(ARM64Registers::q14, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
</ins><span class="cx">                 break;
</span><span class="cx">             case UNW_ARM64_v15:
</span><del>-                m_registers.append(RegisterAtOffset(ARM64Registers::q15, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
</del><ins>+                registerOffsets-&gt;append(RegisterAtOffset(ARM64Registers::q15, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
</ins><span class="cx">                 break;
</span><span class="cx">             case UNW_ARM64_v16:
</span><del>-                m_registers.append(RegisterAtOffset(ARM64Registers::q16, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
</del><ins>+                registerOffsets-&gt;append(RegisterAtOffset(ARM64Registers::q16, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
</ins><span class="cx">                 break;
</span><span class="cx">             case UNW_ARM64_v17:
</span><del>-                m_registers.append(RegisterAtOffset(ARM64Registers::q17, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
</del><ins>+                registerOffsets-&gt;append(RegisterAtOffset(ARM64Registers::q17, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
</ins><span class="cx">                 break;
</span><span class="cx">             case UNW_ARM64_v18:
</span><del>-                m_registers.append(RegisterAtOffset(ARM64Registers::q18, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
</del><ins>+                registerOffsets-&gt;append(RegisterAtOffset(ARM64Registers::q18, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
</ins><span class="cx">                 break;
</span><span class="cx">             case UNW_ARM64_v19:
</span><del>-                m_registers.append(RegisterAtOffset(ARM64Registers::q19, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
</del><ins>+                registerOffsets-&gt;append(RegisterAtOffset(ARM64Registers::q19, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
</ins><span class="cx">                 break;
</span><span class="cx">             case UNW_ARM64_v20:
</span><del>-                m_registers.append(RegisterAtOffset(ARM64Registers::q20, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
</del><ins>+                registerOffsets-&gt;append(RegisterAtOffset(ARM64Registers::q20, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
</ins><span class="cx">                 break;
</span><span class="cx">             case UNW_ARM64_v21:
</span><del>-                m_registers.append(RegisterAtOffset(ARM64Registers::q21, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
</del><ins>+                append(RegisterAtOffset(ARM64Registers::q21, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
</ins><span class="cx">                 break;
</span><span class="cx">             case UNW_ARM64_v22:
</span><del>-                m_registers.append(RegisterAtOffset(ARM64Registers::q22, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
</del><ins>+                registerOffsets-&gt;append(RegisterAtOffset(ARM64Registers::q22, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
</ins><span class="cx">                 break;
</span><span class="cx">             case UNW_ARM64_v23:
</span><del>-                m_registers.append(RegisterAtOffset(ARM64Registers::q23, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
</del><ins>+                registerOffsets-&gt;append(RegisterAtOffset(ARM64Registers::q23, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
</ins><span class="cx">                 break;
</span><span class="cx">             case UNW_ARM64_v24:
</span><del>-                m_registers.append(RegisterAtOffset(ARM64Registers::q24, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
</del><ins>+                registerOffsets-&gt;append(RegisterAtOffset(ARM64Registers::q24, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
</ins><span class="cx">                 break;
</span><span class="cx">             case UNW_ARM64_v25:
</span><del>-                m_registers.append(RegisterAtOffset(ARM64Registers::q25, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
</del><ins>+                registerOffsets-&gt;append(RegisterAtOffset(ARM64Registers::q25, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
</ins><span class="cx">                 break;
</span><span class="cx">             case UNW_ARM64_v26:
</span><del>-                m_registers.append(RegisterAtOffset(ARM64Registers::q26, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
</del><ins>+                registerOffsets-&gt;append(RegisterAtOffset(ARM64Registers::q26, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
</ins><span class="cx">                 break;
</span><span class="cx">             case UNW_ARM64_v27:
</span><del>-                m_registers.append(RegisterAtOffset(ARM64Registers::q27, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
</del><ins>+                registerOffsets-&gt;append(RegisterAtOffset(ARM64Registers::q27, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
</ins><span class="cx">                 break;
</span><span class="cx">             case UNW_ARM64_v28:
</span><del>-                m_registers.append(RegisterAtOffset(ARM64Registers::q28, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
</del><ins>+                registerOffsets-&gt;append(RegisterAtOffset(ARM64Registers::q28, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
</ins><span class="cx">                 break;
</span><span class="cx">             case UNW_ARM64_v29:
</span><del>-                m_registers.append(RegisterAtOffset(ARM64Registers::q29, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
</del><ins>+                registerOffsets-&gt;append(RegisterAtOffset(ARM64Registers::q29, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
</ins><span class="cx">                 break;
</span><span class="cx">             case UNW_ARM64_v30:
</span><del>-                m_registers.append(RegisterAtOffset(ARM64Registers::q30, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
</del><ins>+                registerOffsets-&gt;append(RegisterAtOffset(ARM64Registers::q30, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
</ins><span class="cx">                 break;
</span><span class="cx">             case UNW_ARM64_v31:
</span><del>-                m_registers.append(RegisterAtOffset(ARM64Registers::q31, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
</del><ins>+                registerOffsets-&gt;append(RegisterAtOffset(ARM64Registers::q31, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
</ins><span class="cx">                 break;
</span><span class="cx">             default:
</span><span class="cx">                 RELEASE_ASSERT_NOT_REACHED(); // non-standard register being saved in prolog
</span><span class="lines">@@ -1017,27 +1015,10 @@
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><span class="cx"> #endif
</span><del>-    std::sort(m_registers.begin(), m_registers.end());
-    return true;
</del><ins>+    registerOffsets-&gt;sort();
+    return WTF::move(registerOffsets);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-void UnwindInfo::dump(PrintStream&amp; out) const
-{
-    out.print(listDump(m_registers));
-}
-
-RegisterAtOffset* UnwindInfo::find(Reg reg) const
-{
-    return tryBinarySearch&lt;RegisterAtOffset, Reg&gt;(m_registers, m_registers.size(), reg, RegisterAtOffset::getReg);
-}
-
-unsigned UnwindInfo::indexOf(Reg reg) const
-{
-    if (RegisterAtOffset* pointer = find(reg))
-        return pointer - m_registers.begin();
-    return UINT_MAX;
-}
-
</del><span class="cx"> } } // namespace JSC::FTL
</span><span class="cx"> 
</span><span class="cx"> #endif // ENABLE(FTL_JIT)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLUnwindInfoh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ftl/FTLUnwindInfo.h (189574 => 189575)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLUnwindInfo.h        2015-09-10 17:31:42 UTC (rev 189574)
+++ trunk/Source/JavaScriptCore/ftl/FTLUnwindInfo.h        2015-09-10 17:47:16 UTC (rev 189575)
</span><span class="lines">@@ -31,23 +31,11 @@
</span><span class="cx"> #if ENABLE(FTL_JIT)
</span><span class="cx"> 
</span><span class="cx"> #include &quot;FTLGeneratedFunction.h&quot;
</span><del>-#include &quot;FTLRegisterAtOffset.h&quot;
</del><ins>+class RegisterAtOffsetList;
</ins><span class="cx"> 
</span><span class="cx"> namespace JSC { namespace FTL {
</span><span class="cx"> 
</span><del>-struct UnwindInfo {
-    UnwindInfo();
-    ~UnwindInfo();
-    
-    bool parse(void*, size_t, GeneratedFunction);
-    
-    void dump(PrintStream&amp;) const;
-    
-    RegisterAtOffset* find(Reg) const;
-    unsigned indexOf(Reg) const; // Returns UINT_MAX if not found.
-    
-    Vector&lt;RegisterAtOffset&gt; m_registers;
-};
</del><ins>+std::unique_ptr&lt;RegisterAtOffsetList&gt;  parseUnwindInfo(void*, size_t, GeneratedFunction);
</ins><span class="cx"> 
</span><span class="cx"> } } // namespace JSC::FTL
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreinterpreterInterpretercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/interpreter/Interpreter.cpp (189574 => 189575)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/interpreter/Interpreter.cpp        2015-09-10 17:31:42 UTC (rev 189574)
+++ trunk/Source/JavaScriptCore/interpreter/Interpreter.cpp        2015-09-10 17:47:16 UTC (rev 189575)
</span><span class="lines">@@ -650,15 +650,55 @@
</span><span class="cx">             if (!unwindCallFrame(visitor)) {
</span><span class="cx">                 if (LegacyProfiler* profiler = vm.enabledProfiler())
</span><span class="cx">                     profiler-&gt;exceptionUnwind(m_callFrame);
</span><ins>+
+                copyCalleeSavesToVMCalleeSavesBuffer(visitor);
+
</ins><span class="cx">                 return StackVisitor::Done;
</span><span class="cx">             }
</span><span class="cx">         } else
</span><span class="cx">             return StackVisitor::Done;
</span><span class="cx"> 
</span><ins>+        copyCalleeSavesToVMCalleeSavesBuffer(visitor);
+
</ins><span class="cx">         return StackVisitor::Continue;
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx"> private:
</span><ins>+    void copyCalleeSavesToVMCalleeSavesBuffer(StackVisitor&amp; visitor)
+    {
+#if ENABLE(JIT) &amp;&amp; NUMBER_OF_CALLEE_SAVES_REGISTERS &gt; 0
+
+        if (!visitor-&gt;isJSFrame())
+            return;
+
+#if ENABLE(DFG_JIT)
+        if (visitor-&gt;inlineCallFrame())
+            return;
+#endif
+        RegisterAtOffsetList* currentCalleeSaves = m_codeBlock ? m_codeBlock-&gt;calleeSaveRegisters() : nullptr;
+
+        if (!currentCalleeSaves)
+            return;
+
+        VM&amp; vm = m_callFrame-&gt;vm();
+        RegisterAtOffsetList* allCalleeSaves = vm.getAllCalleeSaveRegisterOffsets();
+        RegisterSet dontCopyRegisters = RegisterSet::stackRegisters();
+        intptr_t* frame = reinterpret_cast&lt;intptr_t*&gt;(m_callFrame-&gt;registers());
+
+        unsigned registerCount = currentCalleeSaves-&gt;size();
+        for (unsigned i = 0; i &lt; registerCount; i++) {
+            RegisterAtOffset currentEntry = currentCalleeSaves-&gt;at(i);
+            if (dontCopyRegisters.get(currentEntry.reg()))
+                continue;
+            RegisterAtOffset* vmCalleeSavesEntry = allCalleeSaves-&gt;find(currentEntry.reg());
+            
+            vm.calleeSaveRegistersBuffer[vmCalleeSavesEntry-&gt;offsetAsIndex()] = *(frame + currentEntry.offsetAsIndex());
+        }
+#else
+        UNUSED_PARAM(visitor);
+#endif
+    }
+
</ins><span class="cx">     CallFrame*&amp; m_callFrame;
</span><span class="cx">     bool m_isTermination;
</span><span class="cx">     CodeBlock*&amp; m_codeBlock;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitArityCheckFailReturnThunkscpp"></a>
<div class="delfile"><h4>Deleted: trunk/Source/JavaScriptCore/jit/ArityCheckFailReturnThunks.cpp (189574 => 189575)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/ArityCheckFailReturnThunks.cpp        2015-09-10 17:31:42 UTC (rev 189574)
+++ trunk/Source/JavaScriptCore/jit/ArityCheckFailReturnThunks.cpp        2015-09-10 17:47:16 UTC (rev 189575)
</span><span class="lines">@@ -1,135 +0,0 @@
</span><del>-/*
- * Copyright (C) 2013 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;ArityCheckFailReturnThunks.h&quot;
-
-#if ENABLE(JIT)
-
-#include &quot;AssemblyHelpers.h&quot;
-#include &quot;LinkBuffer.h&quot;
-#include &quot;JSCInlines.h&quot;
-#include &quot;StackAlignment.h&quot;
-
-namespace JSC {
-
-ArityCheckFailReturnThunks::ArityCheckFailReturnThunks()
-    : m_nextSize(0)
-{
-}
-
-ArityCheckFailReturnThunks::~ArityCheckFailReturnThunks() { }
-
-CodeLocationLabel* ArityCheckFailReturnThunks::returnPCsFor(
-    VM&amp; vm, unsigned numExpectedArgumentsIncludingThis)
-{
-    ASSERT(numExpectedArgumentsIncludingThis &gt;= 1);
-    
-    numExpectedArgumentsIncludingThis = WTF::roundUpToMultipleOf(
-        stackAlignmentRegisters(), numExpectedArgumentsIncludingThis);
-    
-    {
-        ConcurrentJITLocker locker(m_lock);
-        if (numExpectedArgumentsIncludingThis &lt; m_nextSize)
-            return m_returnPCArrays.last().get();
-    }
-    
-    ASSERT(!isCompilationThread());
-    
-    numExpectedArgumentsIncludingThis = std::max(numExpectedArgumentsIncludingThis, m_nextSize * 2);
-    
-    AssemblyHelpers jit(&amp;vm, 0);
-    
-    Vector&lt;AssemblyHelpers::Label&gt; labels;
-    
-    for (unsigned size = m_nextSize; size &lt;= numExpectedArgumentsIncludingThis; size += stackAlignmentRegisters()) {
-        labels.append(jit.label());
-        
-        jit.load32(
-            AssemblyHelpers::Address(
-                AssemblyHelpers::stackPointerRegister,
-                (JSStack::ArgumentCount - JSStack::CallerFrameAndPCSize) * sizeof(Register) +
-                PayloadOffset),
-            GPRInfo::regT4);
-        jit.add32(
-            AssemblyHelpers::TrustedImm32(
-                JSStack::CallFrameHeaderSize - JSStack::CallerFrameAndPCSize + size - 1),
-            GPRInfo::regT4, GPRInfo::regT2);
-        jit.lshift32(AssemblyHelpers::TrustedImm32(3), GPRInfo::regT2);
-        jit.addPtr(AssemblyHelpers::stackPointerRegister, GPRInfo::regT2);
-        jit.loadPtr(GPRInfo::regT2, GPRInfo::regT2);
-        
-        jit.addPtr(
-            AssemblyHelpers::TrustedImm32(size * sizeof(Register)),
-            AssemblyHelpers::stackPointerRegister);
-        
-        // Thunks like ours want to use the return PC to figure out where things
-        // were saved. So, we pay it forward.
-        jit.store32(
-            GPRInfo::regT4,
-            AssemblyHelpers::Address(
-                AssemblyHelpers::stackPointerRegister,
-                (JSStack::ArgumentCount - JSStack::CallerFrameAndPCSize) * sizeof(Register) +
-                PayloadOffset));
-        
-        jit.jump(GPRInfo::regT2);
-    }
-    
-    // Sadly, we cannot fail here because the LLInt may need us.
-    LinkBuffer linkBuffer(vm, jit, GLOBAL_THUNK_ID, JITCompilationMustSucceed);
-    
-    unsigned returnPCsSize = numExpectedArgumentsIncludingThis / stackAlignmentRegisters() + 1;
-    std::unique_ptr&lt;CodeLocationLabel[]&gt; returnPCs =
-        std::make_unique&lt;CodeLocationLabel[]&gt;(returnPCsSize);
-    for (unsigned size = 0; size &lt;= numExpectedArgumentsIncludingThis; size += stackAlignmentRegisters()) {
-        unsigned index = size / stackAlignmentRegisters();
-        RELEASE_ASSERT(index &lt; returnPCsSize);
-        if (size &lt; m_nextSize)
-            returnPCs[index] = m_returnPCArrays.last()[index];
-        else
-            returnPCs[index] = linkBuffer.locationOf(labels[(size - m_nextSize) / stackAlignmentRegisters()]);
-    }
-
-    CodeLocationLabel* result = returnPCs.get();
-
-    {
-        ConcurrentJITLocker locker(m_lock);
-        m_returnPCArrays.append(WTF::move(returnPCs));
-        m_refs.append(FINALIZE_CODE(linkBuffer, (&quot;Arity check fail return thunks for up to numArgs = %u&quot;, numExpectedArgumentsIncludingThis)));
-        m_nextSize = numExpectedArgumentsIncludingThis + stackAlignmentRegisters();
-    }
-    
-    return result;
-}
-
-CodeLocationLabel ArityCheckFailReturnThunks::returnPCFor(VM&amp; vm, unsigned slotsToAdd)
-{
-    return returnPCsFor(vm, slotsToAdd)[slotsToAdd / stackAlignmentRegisters()];
-}
-
-} // namespace JSC
-
-#endif // ENABLE(JIT)
-
</del></span></pre></div>
<a id="trunkSourceJavaScriptCorejitArityCheckFailReturnThunksh"></a>
<div class="delfile"><h4>Deleted: trunk/Source/JavaScriptCore/jit/ArityCheckFailReturnThunks.h (189574 => 189575)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/ArityCheckFailReturnThunks.h        2015-09-10 17:31:42 UTC (rev 189574)
+++ trunk/Source/JavaScriptCore/jit/ArityCheckFailReturnThunks.h        2015-09-10 17:47:16 UTC (rev 189575)
</span><span class="lines">@@ -1,59 +0,0 @@
</span><del>-/*
- * Copyright (C) 2013 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 ArityCheckFailReturnThunks_h
-#define ArityCheckFailReturnThunks_h
-
-#if ENABLE(JIT)
-
-#include &quot;CodeLocation.h&quot;
-#include &quot;ConcurrentJITLock.h&quot;
-#include &lt;wtf/HashMap.h&gt;
-
-namespace JSC {
-
-class ArityCheckFailReturnThunks {
-public:
-    ArityCheckFailReturnThunks();
-    ~ArityCheckFailReturnThunks();
-    
-    // Returns a pointer to an array of return labels indexed by missingArgs.
-    CodeLocationLabel* returnPCsFor(VM&amp;, unsigned numExpectedArgumentsIncludingThis);
-    
-    CodeLocationLabel returnPCFor(VM&amp;, unsigned slotsToAdd);
-    
-private:
-    Vector&lt;std::unique_ptr&lt;CodeLocationLabel[]&gt;&gt; m_returnPCArrays;
-    unsigned m_nextSize;
-    Vector&lt;MacroAssemblerCodeRef&gt; m_refs;
-    ConcurrentJITLock m_lock;
-};
-
-} // namespace JSC
-
-#endif // ENABLE(JIT)
-
-#endif // ArityCheckFailReturnThunks_h
-
</del></span></pre></div>
<a id="trunkSourceJavaScriptCorejitAssemblyHelpersh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/AssemblyHelpers.h (189574 => 189575)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/AssemblyHelpers.h        2015-09-10 17:31:42 UTC (rev 189574)
+++ trunk/Source/JavaScriptCore/jit/AssemblyHelpers.h        2015-09-10 17:47:16 UTC (rev 189575)
</span><span class="lines">@@ -34,6 +34,8 @@
</span><span class="cx"> #include &quot;InlineCallFrame.h&quot;
</span><span class="cx"> #include &quot;JITCode.h&quot;
</span><span class="cx"> #include &quot;MacroAssembler.h&quot;
</span><ins>+#include &quot;RegisterAtOffsetList.h&quot;
+#include &quot;RegisterSet.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">@@ -175,6 +177,159 @@
</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);
+
+        RegisterAtOffsetList* calleeSaves = codeBlock-&gt;calleeSaveRegisters();
+        RegisterSet dontSaveRegisters = RegisterSet(RegisterSet::stackRegisters(), RegisterSet::allFPRs());
+        unsigned registerCount = calleeSaves-&gt;size();
+
+        for (unsigned i = 0; i &lt; registerCount; i++) {
+            RegisterAtOffset entry = calleeSaves-&gt;at(i);
+            if (dontSaveRegisters.get(entry.reg()))
+                continue;
+            storePtr(entry.reg().gpr(), Address(framePointerRegister, offsetVirtualRegister.offsetInBytes() + entry.offset()));
+        }
+    }
+
+    void emitRestoreCalleeSavesFor(CodeBlock* codeBlock)
+    {
+        ASSERT(codeBlock);
+
+        RegisterAtOffsetList* calleeSaves = codeBlock-&gt;calleeSaveRegisters();
+        RegisterSet dontRestoreRegisters = RegisterSet(RegisterSet::stackRegisters(), RegisterSet::allFPRs());
+        unsigned registerCount = calleeSaves-&gt;size();
+        
+        for (unsigned i = 0; i &lt; registerCount; i++) {
+            RegisterAtOffset entry = calleeSaves-&gt;at(i);
+            if (dontRestoreRegisters.get(entry.reg()))
+                continue;
+            loadPtr(Address(framePointerRegister, entry.offset()), entry.reg().gpr());
+        }
+    }
+
+    void emitSaveCalleeSaves()
+    {
+        emitSaveCalleeSavesFor(codeBlock());
+    }
+
+    void emitRestoreCalleeSaves()
+    {
+        emitRestoreCalleeSavesFor(codeBlock());
+    }
+
+    void copyCalleeSavesToVMCalleeSavesBuffer(const TempRegisterSet&amp; usedRegisters = { RegisterSet::stubUnavailableRegisters() })
+    {
+#if NUMBER_OF_CALLEE_SAVES_REGISTERS &gt; 0
+        GPRReg temp1 = usedRegisters.getFreeGPR(0);
+
+        move(TrustedImmPtr(m_vm-&gt;calleeSaveRegistersBuffer), temp1);
+
+        RegisterAtOffsetList* allCalleeSaves = m_vm-&gt;getAllCalleeSaveRegisterOffsets();
+        RegisterSet dontCopyRegisters = RegisterSet::stackRegisters();
+        unsigned registerCount = allCalleeSaves-&gt;size();
+        
+        for (unsigned i = 0; i &lt; registerCount; i++) {
+            RegisterAtOffset entry = allCalleeSaves-&gt;at(i);
+            if (dontCopyRegisters.get(entry.reg()))
+                continue;
+            if (entry.reg().isGPR())
+                storePtr(entry.reg().gpr(), Address(temp1, entry.offset()));
+            else
+                storeDouble(entry.reg().fpr(), Address(temp1, entry.offset()));
+        }
+#else
+        UNUSED_PARAM(usedRegisters);
+#endif
+    }
+
+    void restoreCalleeSavesFromVMCalleeSavesBuffer(const TempRegisterSet&amp; usedRegisters = { RegisterSet::stubUnavailableRegisters() })
+    {
+#if NUMBER_OF_CALLEE_SAVES_REGISTERS &gt; 0
+        GPRReg temp1 = usedRegisters.getFreeGPR(0);
+        
+        move(TrustedImmPtr(m_vm-&gt;calleeSaveRegistersBuffer), temp1);
+
+        RegisterAtOffsetList* allCalleeSaves = m_vm-&gt;getAllCalleeSaveRegisterOffsets();
+        RegisterSet dontRestoreRegisters = RegisterSet::stackRegisters();
+        unsigned registerCount = allCalleeSaves-&gt;size();
+        
+        for (unsigned i = 0; i &lt; registerCount; i++) {
+            RegisterAtOffset entry = allCalleeSaves-&gt;at(i);
+            if (dontRestoreRegisters.get(entry.reg()))
+                continue;
+            if (entry.reg().isGPR())
+                loadPtr(Address(temp1, entry.offset()), entry.reg().gpr());
+            else
+                loadDouble(Address(temp1, entry.offset()), entry.reg().fpr());
+        }
+#else
+        UNUSED_PARAM(usedRegisters);
+#endif
+    }
+    
+    void copyCalleeSavesFromFrameOrRegisterToVMCalleeSavesBuffer(const TempRegisterSet&amp; usedRegisters = { RegisterSet::stubUnavailableRegisters() })
+    {
+#if NUMBER_OF_CALLEE_SAVES_REGISTERS &gt; 0
+        GPRReg temp1 = usedRegisters.getFreeGPR(0);
+        GPRReg temp2 = usedRegisters.getFreeGPR(1);
+        FPRReg fpTemp = usedRegisters.getFreeFPR();
+        ASSERT(temp2 != InvalidGPRReg);
+
+        ASSERT(codeBlock());
+
+        // Copy saved calleeSaves on stack or unsaved calleeSaves in register to vm calleeSave buffer
+        move(TrustedImmPtr(m_vm-&gt;calleeSaveRegistersBuffer), temp1);
+
+        RegisterAtOffsetList* allCalleeSaves = m_vm-&gt;getAllCalleeSaveRegisterOffsets();
+        RegisterAtOffsetList* currentCalleeSaves = codeBlock()-&gt;calleeSaveRegisters();
+        RegisterSet dontCopyRegisters = RegisterSet::stackRegisters();
+        unsigned registerCount = allCalleeSaves-&gt;size();
+
+        for (unsigned i = 0; i &lt; registerCount; i++) {
+            RegisterAtOffset vmEntry = allCalleeSaves-&gt;at(i);
+            if (dontCopyRegisters.get(vmEntry.reg()))
+                continue;
+            RegisterAtOffset* currentFrameEntry = currentCalleeSaves-&gt;find(vmEntry.reg());
+
+            if (vmEntry.reg().isGPR()) {
+                GPRReg regToStore;
+                if (currentFrameEntry) {
+                    // Load calleeSave from stack into temp register
+                    regToStore = temp2;
+                    loadPtr(Address(framePointerRegister, currentFrameEntry-&gt;offset()), regToStore);
+                } else
+                    // Just store callee save directly
+                    regToStore = vmEntry.reg().gpr();
+
+                storePtr(regToStore, Address(temp1, vmEntry.offset()));
+            } else {
+                FPRReg fpRegToStore;
+                if (currentFrameEntry) {
+                    // Load calleeSave from stack into temp register
+                    fpRegToStore = fpTemp;
+                    loadDouble(Address(framePointerRegister, currentFrameEntry-&gt;offset()), fpRegToStore);
+                } else
+                    // Just store callee save directly
+                    fpRegToStore = vmEntry.reg().fpr();
+
+                storeDouble(fpRegToStore, Address(temp1, vmEntry.offset()));
+            }
+        }
+#else
+        UNUSED_PARAM(usedRegisters);
+#endif
+    }
+
+    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="trunkSourceJavaScriptCorejitFPRInfoh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/FPRInfo.h (189574 => 189575)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/FPRInfo.h        2015-09-10 17:31:42 UTC (rev 189574)
+++ trunk/Source/JavaScriptCore/jit/FPRInfo.h        2015-09-10 17:47:16 UTC (rev 189575)
</span><span class="lines">@@ -208,6 +208,14 @@
</span><span class="cx">     static const FPRReg fpRegT20 = ARM64Registers::q28;
</span><span class="cx">     static const FPRReg fpRegT21 = ARM64Registers::q29;
</span><span class="cx">     static const FPRReg fpRegT22 = ARM64Registers::q30;
</span><ins>+    static const FPRReg fpRegCS0 = ARM64Registers::q8;
+    static const FPRReg fpRegCS1 = ARM64Registers::q9;
+    static const FPRReg fpRegCS2 = ARM64Registers::q10;
+    static const FPRReg fpRegCS3 = ARM64Registers::q11;
+    static const FPRReg fpRegCS4 = ARM64Registers::q12;
+    static const FPRReg fpRegCS5 = ARM64Registers::q13;
+    static const FPRReg fpRegCS6 = ARM64Registers::q14;
+    static const FPRReg fpRegCS7 = ARM64Registers::q15;
</ins><span class="cx"> 
</span><span class="cx">     static const FPRReg argumentFPR0 = ARM64Registers::q0; // fpRegT0
</span><span class="cx">     static const FPRReg argumentFPR1 = ARM64Registers::q1; // fpRegT1
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitGPRInfoh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/GPRInfo.h (189574 => 189575)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/GPRInfo.h        2015-09-10 17:31:42 UTC (rev 189574)
+++ trunk/Source/JavaScriptCore/jit/GPRInfo.h        2015-09-10 17:47:16 UTC (rev 189575)
</span><span class="lines">@@ -315,6 +315,7 @@
</span><span class="cx"> 
</span><span class="cx"> #if CPU(X86)
</span><span class="cx"> #define NUMBER_OF_ARGUMENT_REGISTERS 0u
</span><ins>+#define NUMBER_OF_CALLEE_SAVES_REGISTERS 0u
</ins><span class="cx"> 
</span><span class="cx"> class GPRInfo {
</span><span class="cx"> public:
</span><span class="lines">@@ -336,7 +337,6 @@
</span><span class="cx">     static const GPRReg argumentGPR2 = X86Registers::eax; // regT0
</span><span class="cx">     static const GPRReg argumentGPR3 = X86Registers::ebx; // regT3
</span><span class="cx">     static const GPRReg nonArgGPR0 = X86Registers::esi; // regT4
</span><del>-    static const GPRReg nonArgGPR1 = X86Registers::edi; // regT5
</del><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><span class="lines">@@ -382,8 +382,10 @@
</span><span class="cx"> #if CPU(X86_64)
</span><span class="cx"> #if !OS(WINDOWS)
</span><span class="cx"> #define NUMBER_OF_ARGUMENT_REGISTERS 6u
</span><ins>+#define NUMBER_OF_CALLEE_SAVES_REGISTERS 5u
</ins><span class="cx"> #else
</span><span class="cx"> #define NUMBER_OF_ARGUMENT_REGISTERS 4u
</span><ins>+#define NUMBER_OF_CALLEE_SAVES_REGISTERS 7u
</ins><span class="cx"> #endif
</span><span class="cx"> 
</span><span class="cx"> class GPRInfo {
</span><span class="lines">@@ -445,7 +447,6 @@
</span><span class="cx">     static const GPRReg argumentGPR3 = X86Registers::r9; // regT3
</span><span class="cx"> #endif
</span><span class="cx">     static const GPRReg nonArgGPR0 = X86Registers::r10; // regT5 (regT4 on Windows)
</span><del>-    static const GPRReg nonArgGPR1 = X86Registers::ebx; // Callee save
</del><span class="cx">     static const GPRReg returnValueGPR = X86Registers::eax; // regT0
</span><span class="cx">     static const GPRReg returnValueGPR2 = X86Registers::edx; // regT1 or regT2
</span><span class="cx">     static const GPRReg nonPreservedNonReturnGPR = X86Registers::r10; // regT5 (regT4 on Windows)
</span><span class="lines">@@ -506,6 +507,7 @@
</span><span class="cx"> 
</span><span class="cx"> #if CPU(ARM)
</span><span class="cx"> #define NUMBER_OF_ARGUMENT_REGISTERS 4u
</span><ins>+#define NUMBER_OF_CALLEE_SAVES_REGISTERS 0u
</ins><span class="cx"> 
</span><span class="cx"> class GPRInfo {
</span><span class="cx"> public:
</span><span class="lines">@@ -536,7 +538,6 @@
</span><span class="cx">     static const GPRReg argumentGPR3 = ARMRegisters::r3; // regT3
</span><span class="cx">     static const GPRReg nonArgGPR0 = ARMRegisters::r4; // regT8
</span><span class="cx">     static const GPRReg nonArgGPR1 = ARMRegisters::r8; // regT4
</span><del>-    static const GPRReg nonArgGPR2 = ARMRegisters::r9; // regT5
</del><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><span class="lines">@@ -589,6 +590,8 @@
</span><span class="cx"> 
</span><span class="cx"> #if CPU(ARM64)
</span><span class="cx"> #define NUMBER_OF_ARGUMENT_REGISTERS 8u
</span><ins>+// Callee Saves includes x19..x28 and FP registers q8..q15
+#define NUMBER_OF_CALLEE_SAVES_REGISTERS 18u
</ins><span class="cx"> 
</span><span class="cx"> class GPRInfo {
</span><span class="cx"> public:
</span><span class="lines">@@ -617,9 +620,16 @@
</span><span class="cx">     static const GPRReg regT13 = ARM64Registers::x13;
</span><span class="cx">     static const GPRReg regT14 = ARM64Registers::x14;
</span><span class="cx">     static const GPRReg regT15 = ARM64Registers::x15;
</span><del>-    static const GPRReg regCS0 = ARM64Registers::x26; // Used by LLInt only
-    static const GPRReg regCS1 = ARM64Registers::x27; // tagTypeNumber
-    static const GPRReg regCS2 = ARM64Registers::x28; // tagMask
</del><ins>+    static const GPRReg regCS0 = ARM64Registers::x19; // Used by FTL only
+    static const GPRReg regCS1 = ARM64Registers::x20; // Used by FTL only
+    static const GPRReg regCS2 = ARM64Registers::x21; // Used by FTL only
+    static const GPRReg regCS3 = ARM64Registers::x22; // Used by FTL only
+    static const GPRReg regCS4 = ARM64Registers::x23; // Used by FTL only
+    static const GPRReg regCS5 = ARM64Registers::x24; // Used by FTL only
+    static const GPRReg regCS6 = ARM64Registers::x25; // Used by FTL only
+    static const GPRReg regCS7 = ARM64Registers::x26;
+    static const GPRReg regCS8 = ARM64Registers::x27; // tagTypeNumber
+    static const GPRReg regCS9 = ARM64Registers::x28; // tagMask
</ins><span class="cx">     // These constants provide the names for the general purpose argument &amp; return value registers.
</span><span class="cx">     static const GPRReg argumentGPR0 = ARM64Registers::x0; // regT0
</span><span class="cx">     static const GPRReg argumentGPR1 = ARM64Registers::x1; // regT1
</span><span class="lines">@@ -637,7 +647,7 @@
</span><span class="cx">     static const GPRReg nonPreservedNonArgumentGPR = ARM64Registers::x8;
</span><span class="cx">     static const GPRReg patchpointScratchRegister = ARM64Registers::ip0;
</span><span class="cx"> 
</span><del>-    // GPRReg mapping is direct, the machine regsiter numbers can
</del><ins>+    // GPRReg mapping is direct, the machine register numbers can
</ins><span class="cx">     // be used directly as indices into the GPR RegisterBank.
</span><span class="cx">     COMPILE_ASSERT(ARM64Registers::q0 == 0, q0_is_0);
</span><span class="cx">     COMPILE_ASSERT(ARM64Registers::q1 == 1, q1_is_1);
</span><span class="lines">@@ -692,6 +702,7 @@
</span><span class="cx"> 
</span><span class="cx"> #if CPU(MIPS)
</span><span class="cx"> #define NUMBER_OF_ARGUMENT_REGISTERS 4u
</span><ins>+#define NUMBER_OF_CALLEE_SAVES_REGISTERS 0u
</ins><span class="cx"> 
</span><span class="cx"> class GPRInfo {
</span><span class="cx"> public:
</span><span class="lines">@@ -719,7 +730,6 @@
</span><span class="cx">     static const GPRReg argumentGPR2 = MIPSRegisters::a2;
</span><span class="cx">     static const GPRReg argumentGPR3 = MIPSRegisters::a3;
</span><span class="cx">     static const GPRReg nonArgGPR0 = regT0;
</span><del>-    static const GPRReg nonArgGPR1 = regT1;
</del><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><span class="lines">@@ -764,6 +774,7 @@
</span><span class="cx"> 
</span><span class="cx"> #if CPU(SH4)
</span><span class="cx"> #define NUMBER_OF_ARGUMENT_REGISTERS 4u
</span><ins>+#define NUMBER_OF_CALLEE_SAVES_REGISTERS 0u
</ins><span class="cx"> 
</span><span class="cx"> class GPRInfo {
</span><span class="cx"> public:
</span><span class="lines">@@ -793,7 +804,6 @@
</span><span class="cx">     static const GPRReg argumentGPR2 = SH4Registers::r6; // regT2
</span><span class="cx">     static const GPRReg argumentGPR3 = SH4Registers::r7; // regT3
</span><span class="cx">     static const GPRReg nonArgGPR0 = regT4;
</span><del>-    static const GPRReg nonArgGPR1 = regT5;
</del><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></span></pre></div>
<a id="trunkSourceJavaScriptCorejitJITcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/JIT.cpp (189574 => 189575)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/JIT.cpp        2015-09-10 17:31:42 UTC (rev 189574)
+++ trunk/Source/JavaScriptCore/jit/JIT.cpp        2015-09-10 17:47:16 UTC (rev 189575)
</span><span class="lines">@@ -29,7 +29,6 @@
</span><span class="cx"> 
</span><span class="cx"> #include &quot;JIT.h&quot;
</span><span class="cx"> 
</span><del>-#include &quot;ArityCheckFailReturnThunks.h&quot;
</del><span class="cx"> #include &quot;CodeBlock.h&quot;
</span><span class="cx"> #include &quot;CodeBlockWithJITType.h&quot;
</span><span class="cx"> #include &quot;DFGCapabilities.h&quot;
</span><span class="lines">@@ -85,6 +84,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();
+
</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">@@ -492,6 +494,8 @@
</span><span class="cx">         break;
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    m_codeBlock-&gt;setCalleeSaveRegisters(RegisterSet::llintBaselineCalleeSaveRegisters()); // Might be able to remove as this is probably already set to this value.
+
</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">@@ -549,6 +553,9 @@
</span><span class="cx">     move(regT1, stackPointerRegister);
</span><span class="cx">     checkStackPointerAlignment();
</span><span class="cx"> 
</span><ins>+    emitSaveCalleeSaves();
+    emitMaterializeTagCheckRegisters();
+
</ins><span class="cx">     privateCompileMainPass();
</span><span class="cx">     privateCompileLinkPass();
</span><span class="cx">     privateCompileSlowCases();
</span><span class="lines">@@ -580,11 +587,6 @@
</span><span class="cx">         if (maxFrameExtentForSlowPathCall)
</span><span class="cx">             addPtr(TrustedImm32(maxFrameExtentForSlowPathCall), stackPointerRegister);
</span><span class="cx">         branchTest32(Zero, returnValueGPR).linkTo(beginLabel, this);
</span><del>-        GPRReg thunkReg = GPRInfo::argumentGPR1;
-        CodeLocationLabel* failThunkLabels =
-            m_vm-&gt;arityCheckFailReturnThunks-&gt;returnPCsFor(*m_vm, m_codeBlock-&gt;numParameters());
-        move(TrustedImmPtr(failThunkLabels), thunkReg);
-        loadPtr(BaseIndex(thunkReg, returnValueGPR, timesPtr()), thunkReg);
</del><span class="cx">         move(returnValueGPR, GPRInfo::argumentGPR0);
</span><span class="cx">         emitNakedCall(m_vm-&gt;getCTIStub(arityFixupGenerator).code());
</span><span class="cx"> 
</span><span class="lines">@@ -722,6 +724,8 @@
</span><span class="cx">     if (!m_exceptionChecksWithCallFrameRollback.empty()) {
</span><span class="cx">         m_exceptionChecksWithCallFrameRollback.link(this);
</span><span class="cx"> 
</span><ins>+        copyCalleeSavesToVMCalleeSavesBuffer();
+
</ins><span class="cx">         // lookupExceptionHandlerFromCallerFrame is passed two arguments, the VM and the exec (the CallFrame*).
</span><span class="cx"> 
</span><span class="cx">         move(TrustedImmPtr(vm()), GPRInfo::argumentGPR0);
</span><span class="lines">@@ -739,6 +743,8 @@
</span><span class="cx">     if (!m_exceptionChecks.empty()) {
</span><span class="cx">         m_exceptionChecks.link(this);
</span><span class="cx"> 
</span><ins>+        copyCalleeSavesToVMCalleeSavesBuffer();
+
</ins><span class="cx">         // lookupExceptionHandler is passed two arguments, the VM and the exec (the CallFrame*).
</span><span class="cx">         move(TrustedImmPtr(vm()), GPRInfo::argumentGPR0);
</span><span class="cx">         move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR1);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitJITArithmetic32_64cpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/JITArithmetic32_64.cpp (189574 => 189575)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/JITArithmetic32_64.cpp        2015-09-10 17:31:42 UTC (rev 189574)
+++ trunk/Source/JavaScriptCore/jit/JITArithmetic32_64.cpp        2015-09-10 17:47:16 UTC (rev 189575)
</span><span class="lines">@@ -1069,7 +1069,7 @@
</span><span class="cx"> 
</span><span class="cx"> void JIT::emit_op_mod(Instruction* currentInstruction)
</span><span class="cx"> {
</span><del>-#if CPU(X86) || CPU(X86_64)
</del><ins>+#if CPU(X86)
</ins><span class="cx">     int dst = currentInstruction[1].u.operand;
</span><span class="cx">     int op1 = currentInstruction[2].u.operand;
</span><span class="cx">     int op2 = currentInstruction[3].u.operand;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitJITCall32_64cpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/JITCall32_64.cpp (189574 => 189575)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/JITCall32_64.cpp        2015-09-10 17:31:42 UTC (rev 189574)
+++ trunk/Source/JavaScriptCore/jit/JITCall32_64.cpp        2015-09-10 17:47:16 UTC (rev 189575)
</span><span class="lines">@@ -59,6 +59,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></pre></div>
<a id="trunkSourceJavaScriptCorejitJITOpcodescpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/JITOpcodes.cpp (189574 => 189575)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/JITOpcodes.cpp        2015-09-10 17:31:42 UTC (rev 189574)
+++ trunk/Source/JavaScriptCore/jit/JITOpcodes.cpp        2015-09-10 17:47:16 UTC (rev 189575)
</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">@@ -419,6 +421,7 @@
</span><span class="cx"> void JIT::emit_op_throw(Instruction* currentInstruction)
</span><span class="cx"> {
</span><span class="cx">     ASSERT(regT0 == returnValueGPR);
</span><ins>+    copyCalleeSavesToVMCalleeSavesBuffer();
</ins><span class="cx">     emitGetVirtualRegister(currentInstruction[1].u.operand, regT0);
</span><span class="cx">     callOperationNoExceptionCheck(operationThrow, regT0);
</span><span class="cx">     jumpToExceptionHandler();
</span><span class="lines">@@ -494,11 +497,8 @@
</span><span class="cx"> 
</span><span class="cx"> void JIT::emit_op_catch(Instruction* currentInstruction)
</span><span class="cx"> {
</span><del>-    // Gotta restore the tag registers. We could be throwing from FTL, which may
-    // clobber them.
-    move(TrustedImm64(TagTypeNumber), tagTypeNumberRegister);
-    move(TrustedImm64(TagMask), tagMaskRegister);
-    
</del><ins>+    restoreCalleeSavesFromVMCalleeSavesBuffer();
+
</ins><span class="cx">     move(TrustedImmPtr(m_vm), regT3);
</span><span class="cx">     load64(Address(regT3, VM::callFrameForThrowOffset()), callFrameRegister);
</span><span class="cx"> 
</span><span class="lines">@@ -656,7 +656,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">@@ -922,7 +922,9 @@
</span><span class="cx">     // Emit the slow path for the JIT optimization check:
</span><span class="cx">     if (canBeOptimized()) {
</span><span class="cx">         linkSlowCase(iter);
</span><del>-        
</del><ins>+
+        copyCalleeSavesFromFrameOrRegisterToVMCalleeSavesBuffer();
+
</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="trunkSourceJavaScriptCorejitJITOpcodes32_64cpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/JITOpcodes32_64.cpp (189574 => 189575)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/JITOpcodes32_64.cpp        2015-09-10 17:31:42 UTC (rev 189574)
+++ trunk/Source/JavaScriptCore/jit/JITOpcodes32_64.cpp        2015-09-10 17:47:16 UTC (rev 189575)
</span><span class="lines">@@ -148,6 +148,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 class="lines">@@ -741,6 +742,7 @@
</span><span class="cx"> void JIT::emit_op_throw(Instruction* currentInstruction)
</span><span class="cx"> {
</span><span class="cx">     ASSERT(regT0 == returnValueGPR);
</span><ins>+    copyCalleeSavesToVMCalleeSavesBuffer();
</ins><span class="cx">     emitLoad(currentInstruction[1].u.operand, regT1, regT0);
</span><span class="cx">     callOperationNoExceptionCheck(operationThrow, regT1, regT0);
</span><span class="cx">     jumpToExceptionHandler();
</span><span class="lines">@@ -800,6 +802,8 @@
</span><span class="cx"> 
</span><span class="cx"> void JIT::emit_op_catch(Instruction* currentInstruction)
</span><span class="cx"> {
</span><ins>+    restoreCalleeSavesFromVMCalleeSavesBuffer();
+
</ins><span class="cx">     move(TrustedImmPtr(m_vm), regT3);
</span><span class="cx">     // operationThrow returns the callFrame for the handler.
</span><span class="cx">     load32(Address(regT3, VM::callFrameForThrowOffset()), callFrameRegister);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitJITOperationscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/JITOperations.cpp (189574 => 189575)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/JITOperations.cpp        2015-09-10 17:31:42 UTC (rev 189574)
+++ trunk/Source/JavaScriptCore/jit/JITOperations.cpp        2015-09-10 17:47:16 UTC (rev 189575)
</span><span class="lines">@@ -1334,8 +1334,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="trunkSourceJavaScriptCorejitJITPropertyAccesscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/JITPropertyAccess.cpp (189574 => 189575)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/JITPropertyAccess.cpp        2015-09-10 17:31:42 UTC (rev 189574)
+++ trunk/Source/JavaScriptCore/jit/JITPropertyAccess.cpp        2015-09-10 17:47:16 UTC (rev 189575)
</span><span class="lines">@@ -213,7 +213,7 @@
</span><span class="cx">     emitIdentifierCheck(regT1, regT3, propertyName, slowCases);
</span><span class="cx"> 
</span><span class="cx">     JITGetByIdGenerator gen(
</span><del>-        m_codeBlock, CodeOrigin(m_bytecodeOffset), CallSiteIndex(m_bytecodeOffset), RegisterSet::specialRegisters(),
</del><ins>+        m_codeBlock, CodeOrigin(m_bytecodeOffset), CallSiteIndex(m_bytecodeOffset), RegisterSet::stubUnavailableRegisters(),
</ins><span class="cx">         JSValueRegs(regT0), JSValueRegs(regT0), DontSpill);
</span><span class="cx">     gen.generateFastPath(*this);
</span><span class="cx"> 
</span><span class="lines">@@ -446,7 +446,7 @@
</span><span class="cx">     emitGetVirtualRegisters(base, regT0, value, regT1);
</span><span class="cx"> 
</span><span class="cx">     JITPutByIdGenerator gen(
</span><del>-        m_codeBlock, CodeOrigin(m_bytecodeOffset), CallSiteIndex(m_bytecodeOffset), RegisterSet::specialRegisters(),
</del><ins>+        m_codeBlock, CodeOrigin(m_bytecodeOffset), CallSiteIndex(m_bytecodeOffset), RegisterSet::stubUnavailableRegisters(),
</ins><span class="cx">         JSValueRegs(regT0), JSValueRegs(regT1), regT2, DontSpill, m_codeBlock-&gt;ecmaMode(), putKind);
</span><span class="cx">     gen.generateFastPath(*this);
</span><span class="cx">     doneCases.append(jump());
</span><span class="lines">@@ -574,7 +574,7 @@
</span><span class="cx">         emitArrayProfilingSiteForBytecodeIndexWithCell(regT0, regT1, m_bytecodeOffset);
</span><span class="cx"> 
</span><span class="cx">     JITGetByIdGenerator gen(
</span><del>-        m_codeBlock, CodeOrigin(m_bytecodeOffset), CallSiteIndex(m_bytecodeOffset), RegisterSet::specialRegisters(),
</del><ins>+        m_codeBlock, CodeOrigin(m_bytecodeOffset), CallSiteIndex(m_bytecodeOffset), RegisterSet::stubUnavailableRegisters(),
</ins><span class="cx">         JSValueRegs(regT0), JSValueRegs(regT0), DontSpill);
</span><span class="cx">     gen.generateFastPath(*this);
</span><span class="cx">     addSlowCase(gen.slowPathJump());
</span><span class="lines">@@ -621,7 +621,7 @@
</span><span class="cx">     emitJumpSlowCaseIfNotJSCell(regT0, baseVReg);
</span><span class="cx"> 
</span><span class="cx">     JITPutByIdGenerator gen(
</span><del>-        m_codeBlock, CodeOrigin(m_bytecodeOffset), CallSiteIndex(m_bytecodeOffset), RegisterSet::specialRegisters(),
</del><ins>+        m_codeBlock, CodeOrigin(m_bytecodeOffset), CallSiteIndex(m_bytecodeOffset), RegisterSet::stubUnavailableRegisters(),
</ins><span class="cx">         JSValueRegs(regT0), JSValueRegs(regT1), regT2, DontSpill, m_codeBlock-&gt;ecmaMode(),
</span><span class="cx">         direct ? Direct : NotDirect);
</span><span class="cx">     
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitJITPropertyAccess32_64cpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/JITPropertyAccess32_64.cpp (189574 => 189575)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/JITPropertyAccess32_64.cpp        2015-09-10 17:31:42 UTC (rev 189574)
+++ trunk/Source/JavaScriptCore/jit/JITPropertyAccess32_64.cpp        2015-09-10 17:47:16 UTC (rev 189575)
</span><span class="lines">@@ -282,7 +282,7 @@
</span><span class="cx">     emitIdentifierCheck(regT2, regT4, propertyName, slowCases);
</span><span class="cx"> 
</span><span class="cx">     JITGetByIdGenerator gen(
</span><del>-        m_codeBlock, CodeOrigin(m_bytecodeOffset), CallSiteIndex(currentInstruction), RegisterSet::specialRegisters(),
</del><ins>+        m_codeBlock, CodeOrigin(m_bytecodeOffset), CallSiteIndex(currentInstruction), RegisterSet::stubUnavailableRegisters(),
</ins><span class="cx">         JSValueRegs::payloadOnly(regT0), JSValueRegs(regT1, regT0), DontSpill);
</span><span class="cx">     gen.generateFastPath(*this);
</span><span class="cx"> 
</span><span class="lines">@@ -494,7 +494,7 @@
</span><span class="cx">     emitLoad(value, regT3, regT2);
</span><span class="cx"> 
</span><span class="cx">     JITPutByIdGenerator gen(
</span><del>-        m_codeBlock, CodeOrigin(m_bytecodeOffset), CallSiteIndex(currentInstruction), RegisterSet::specialRegisters(),
</del><ins>+        m_codeBlock, CodeOrigin(m_bytecodeOffset), CallSiteIndex(currentInstruction), RegisterSet::stubUnavailableRegisters(),
</ins><span class="cx">         JSValueRegs::payloadOnly(regT0), JSValueRegs(regT3, regT2), regT1, DontSpill, m_codeBlock-&gt;ecmaMode(), putKind);
</span><span class="cx">     gen.generateFastPath(*this);
</span><span class="cx">     doneCases.append(jump());
</span><span class="lines">@@ -587,7 +587,7 @@
</span><span class="cx">         emitArrayProfilingSiteForBytecodeIndexWithCell(regT0, regT2, m_bytecodeOffset);
</span><span class="cx"> 
</span><span class="cx">     JITGetByIdGenerator gen(
</span><del>-        m_codeBlock, CodeOrigin(m_bytecodeOffset), CallSiteIndex(currentInstruction), RegisterSet::specialRegisters(),
</del><ins>+        m_codeBlock, CodeOrigin(m_bytecodeOffset), CallSiteIndex(currentInstruction), RegisterSet::stubUnavailableRegisters(),
</ins><span class="cx">         JSValueRegs::payloadOnly(regT0), JSValueRegs(regT1, regT0), DontSpill);
</span><span class="cx">     gen.generateFastPath(*this);
</span><span class="cx">     addSlowCase(gen.slowPathJump());
</span><span class="lines">@@ -632,7 +632,7 @@
</span><span class="cx">     emitJumpSlowCaseIfNotJSCell(base, regT1);
</span><span class="cx"> 
</span><span class="cx">     JITPutByIdGenerator gen(
</span><del>-        m_codeBlock, CodeOrigin(m_bytecodeOffset), CallSiteIndex(currentInstruction), RegisterSet::specialRegisters(),
</del><ins>+        m_codeBlock, CodeOrigin(m_bytecodeOffset), CallSiteIndex(currentInstruction), RegisterSet::stubUnavailableRegisters(),
</ins><span class="cx">         JSValueRegs::payloadOnly(regT0), JSValueRegs(regT3, regT2),
</span><span class="cx">         regT1, DontSpill, m_codeBlock-&gt;ecmaMode(), direct ? Direct : NotDirect);
</span><span class="cx">     
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitRegisterAtOffsetcpp"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/jit/RegisterAtOffset.cpp (0 => 189575)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/RegisterAtOffset.cpp                                (rev 0)
+++ trunk/Source/JavaScriptCore/jit/RegisterAtOffset.cpp        2015-09-10 17:47:16 UTC (rev 189575)
</span><span class="lines">@@ -0,0 +1,41 @@
</span><ins>+/*
+ * Copyright (C) 2013-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;RegisterAtOffset.h&quot;
+
+#if ENABLE(JIT)
+
+namespace JSC {
+
+void RegisterAtOffset::dump(PrintStream&amp; out) const
+{
+    out.print(reg(), &quot; at &quot;, offset());
+}
+
+} // namespace JSC
+
+#endif // ENABLE(JIT)
+
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCorejitRegisterAtOffseth"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/jit/RegisterAtOffset.h (0 => 189575)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/RegisterAtOffset.h                                (rev 0)
+++ trunk/Source/JavaScriptCore/jit/RegisterAtOffset.h        2015-09-10 17:47:16 UTC (rev 189575)
</span><span class="lines">@@ -0,0 +1,81 @@
</span><ins>+/*
+ * Copyright (C) 2013-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 RegisterAtOffset_h
+#define RegisterAtOffset_h
+
+#if ENABLE(JIT)
+
+#include &quot;Reg.h&quot;
+#include &lt;wtf/PrintStream.h&gt;
+
+namespace JSC {
+
+class RegisterAtOffset {
+public:
+    RegisterAtOffset()
+        : m_offset(0)
+    {
+    }
+    
+    RegisterAtOffset(Reg reg, ptrdiff_t offset)
+        : m_reg(reg)
+        , m_offset(offset)
+    {
+    }
+    
+    bool operator!() const { return !m_reg; }
+    
+    Reg reg() const { return m_reg; }
+    ptrdiff_t offset() const { return m_offset; }
+    int offsetAsIndex() const { return offset() / sizeof(void*); }
+    
+    bool operator==(const RegisterAtOffset&amp; other) const
+    {
+        return reg() == other.reg() &amp;&amp; offset() == other.offset();
+    }
+    
+    bool operator&lt;(const RegisterAtOffset&amp; other) const
+    {
+        if (reg() != other.reg())
+            return reg() &lt; other.reg();
+        return offset() &lt; other.offset();
+    }
+    
+    static Reg getReg(RegisterAtOffset* value) { return value-&gt;reg(); }
+    
+    void dump(PrintStream&amp; out) const;
+
+private:
+    Reg m_reg;
+    ptrdiff_t m_offset;
+};
+
+} // namespace JSC
+
+#endif // ENABLE(JIT)
+
+#endif // RegisterAtOffset_h
+
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCorejitRegisterAtOffsetListcpp"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/jit/RegisterAtOffsetList.cpp (0 => 189575)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/RegisterAtOffsetList.cpp                                (rev 0)
+++ trunk/Source/JavaScriptCore/jit/RegisterAtOffsetList.cpp        2015-09-10 17:47:16 UTC (rev 189575)
</span><span class="lines">@@ -0,0 +1,80 @@
</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;RegisterAtOffsetList.h&quot;
+
+#if ENABLE(JIT)
+
+#include &lt;wtf/ListDump.h&gt;
+
+namespace JSC {
+    
+RegisterAtOffsetList::RegisterAtOffsetList() { }
+
+RegisterAtOffsetList::RegisterAtOffsetList(RegisterSet registerSet, OffsetBaseType offsetBaseType)
+{
+    size_t numberOfRegisters = registerSet.numberOfSetRegisters();
+    ptrdiff_t offset = 0;
+    
+    if (offsetBaseType == FramePointerBased)
+        offset = -(static_cast&lt;ptrdiff_t&gt;(numberOfRegisters) * sizeof(void*));
+
+    for (Reg reg = Reg::first(); reg &lt;= Reg::last();reg = reg.next()) {
+        if (registerSet.get(reg)) {
+            append(RegisterAtOffset(reg, offset));
+            offset += sizeof(void*);
+        }
+    }
+
+    sort();
+}
+
+void RegisterAtOffsetList::sort()
+{
+    std::sort(m_registers.begin(), m_registers.end());
+}
+
+void RegisterAtOffsetList::dump(PrintStream&amp; out) const
+{
+    out.print(listDump(m_registers));
+}
+
+RegisterAtOffset* RegisterAtOffsetList::find(Reg reg) const
+{
+    return tryBinarySearch&lt;RegisterAtOffset, Reg&gt;(m_registers, m_registers.size(), reg, RegisterAtOffset::getReg);
+}
+
+unsigned RegisterAtOffsetList::indexOf(Reg reg) const
+{
+    if (RegisterAtOffset* pointer = find(reg))
+        return pointer - m_registers.begin();
+    return UINT_MAX;
+}
+
+} // namespace JSC
+
+#endif // ENABLE(JIT)
+
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCorejitRegisterAtOffsetListh"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/jit/RegisterAtOffsetList.h (0 => 189575)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/RegisterAtOffsetList.h                                (rev 0)
+++ trunk/Source/JavaScriptCore/jit/RegisterAtOffsetList.h        2015-09-10 17:47:16 UTC (rev 189575)
</span><span class="lines">@@ -0,0 +1,78 @@
</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 RegisterAtOffsetList_h
+#define RegisterAtOffsetList_h
+
+#if ENABLE(JIT)
+
+#include &quot;RegisterAtOffset.h&quot;
+#include &quot;RegisterSet.h&quot;
+
+namespace JSC {
+
+class RegisterAtOffsetList {
+public:
+    enum OffsetBaseType { FramePointerBased, ZeroBased };
+
+    RegisterAtOffsetList();
+    RegisterAtOffsetList(RegisterSet, OffsetBaseType = FramePointerBased);
+
+    void dump(PrintStream&amp;) const;
+
+    void clear()
+    {
+        m_registers.clear();
+    }
+
+    size_t size()
+    {
+        return m_registers.size();
+    }
+
+    RegisterAtOffset&amp; at(size_t index)
+    {
+        return m_registers.at(index);
+    }
+    
+    void append(RegisterAtOffset registerAtOffset)
+    {
+        m_registers.append(registerAtOffset);
+    }
+
+    void sort();
+    RegisterAtOffset* find(Reg) const;
+    unsigned indexOf(Reg) const; // Returns UINT_MAX if not found.
+
+private:
+    Vector&lt;RegisterAtOffset&gt; m_registers;
+};
+
+} // namespace JSC
+
+#endif // ENABLE(JIT)
+
+#endif // RegisterAtOffsetList_h
+
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCorejitRegisterSetcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/RegisterSet.cpp (189574 => 189575)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/RegisterSet.cpp        2015-09-10 17:31:42 UTC (rev 189574)
+++ trunk/Source/JavaScriptCore/jit/RegisterSet.cpp        2015-09-10 17:47:16 UTC (rev 189575)
</span><span class="lines">@@ -66,6 +66,11 @@
</span><span class="cx">         stackRegisters(), reservedHardwareRegisters(), runtimeRegisters());
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+RegisterSet RegisterSet::stubUnavailableRegisters()
+{
+    return RegisterSet(specialRegisters(), vmCalleeSaveRegisters());
+}
+
</ins><span class="cx"> RegisterSet RegisterSet::calleeSaveRegisters()
</span><span class="cx"> {
</span><span class="cx">     RegisterSet result;
</span><span class="lines">@@ -122,6 +127,153 @@
</span><span class="cx">     return result;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+RegisterSet RegisterSet::vmCalleeSaveRegisters()
+{
+    RegisterSet result;
+#if CPU(X86_64)
+    result.set(GPRInfo::regCS0);
+    result.set(GPRInfo::regCS1);
+    result.set(GPRInfo::regCS2);
+    result.set(GPRInfo::regCS3);
+    result.set(GPRInfo::regCS4);
+#if OS(WINDOWS)
+    result.set(GPRInfo::regCS5);
+    result.set(GPRInfo::regCS6);
+#endif
+#elif CPU(ARM64)
+    result.set(GPRInfo::regCS0);
+    result.set(GPRInfo::regCS1);
+    result.set(GPRInfo::regCS2);
+    result.set(GPRInfo::regCS3);
+    result.set(GPRInfo::regCS4);
+    result.set(GPRInfo::regCS5);
+    result.set(GPRInfo::regCS6);
+    result.set(GPRInfo::regCS7);
+    result.set(GPRInfo::regCS8);
+    result.set(GPRInfo::regCS9);
+    result.set(FPRInfo::fpRegCS0);
+    result.set(FPRInfo::fpRegCS1);
+    result.set(FPRInfo::fpRegCS2);
+    result.set(FPRInfo::fpRegCS3);
+    result.set(FPRInfo::fpRegCS4);
+    result.set(FPRInfo::fpRegCS5);
+    result.set(FPRInfo::fpRegCS6);
+    result.set(FPRInfo::fpRegCS7);
+#endif
+    return result;
+}
+
+RegisterSet RegisterSet::llintBaselineCalleeSaveRegisters()
+{
+    RegisterSet result;
+#if CPU(X86)
+#elif CPU(X86_64)
+#if !OS(WINDOWS)
+    result.set(GPRInfo::regCS2);
+    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)
+    result.set(GPRInfo::regCS7);
+    ASSERT(GPRInfo::regCS8 == GPRInfo::tagTypeNumberRegister);
+    ASSERT(GPRInfo::regCS9 == GPRInfo::tagMaskRegister);
+    result.set(GPRInfo::regCS8);
+    result.set(GPRInfo::regCS9);
+#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::regCS8 == GPRInfo::tagTypeNumberRegister);
+    ASSERT(GPRInfo::regCS9 == GPRInfo::tagMaskRegister);
+    result.set(GPRInfo::regCS8);
+    result.set(GPRInfo::regCS9);
+#elif CPU(MIPS)
+#elif CPU(SH4)
+#else
+    UNREACHABLE_FOR_PLATFORM();
+#endif
+    return result;
+}
+
+RegisterSet RegisterSet::ftlCalleeSaveRegisters()
+{
+    RegisterSet result;
+#if ENABLE(FTL_JIT)
+#if CPU(X86_64) &amp;&amp; !OS(WINDOWS)
+    result.set(GPRInfo::regCS0);
+    result.set(GPRInfo::regCS1);
+    result.set(GPRInfo::regCS2);
+    ASSERT(GPRInfo::regCS3 == GPRInfo::tagTypeNumberRegister);
+    ASSERT(GPRInfo::regCS4 == GPRInfo::tagMaskRegister);
+    result.set(GPRInfo::regCS3);
+    result.set(GPRInfo::regCS4);
+#elif CPU(ARM64)
+    // LLVM might save and use all ARM64 callee saves specified in the ABI.
+    result.set(GPRInfo::regCS0);
+    result.set(GPRInfo::regCS1);
+    result.set(GPRInfo::regCS2);
+    result.set(GPRInfo::regCS3);
+    result.set(GPRInfo::regCS4);
+    result.set(GPRInfo::regCS5);
+    result.set(GPRInfo::regCS6);
+    result.set(GPRInfo::regCS7);
+    ASSERT(GPRInfo::regCS8 == GPRInfo::tagTypeNumberRegister);
+    ASSERT(GPRInfo::regCS9 == GPRInfo::tagMaskRegister);
+    result.set(GPRInfo::regCS8);
+    result.set(GPRInfo::regCS9);
+    result.set(FPRInfo::fpRegCS0);
+    result.set(FPRInfo::fpRegCS1);
+    result.set(FPRInfo::fpRegCS2);
+    result.set(FPRInfo::fpRegCS3);
+    result.set(FPRInfo::fpRegCS4);
+    result.set(FPRInfo::fpRegCS5);
+    result.set(FPRInfo::fpRegCS6);
+    result.set(FPRInfo::fpRegCS7);
+#else
+    UNREACHABLE_FOR_PLATFORM();
+#endif
+#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="trunkSourceJavaScriptCorejitRegisterSeth"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/RegisterSet.h (189574 => 189575)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/RegisterSet.h        2015-09-10 17:31:42 UTC (rev 189574)
+++ trunk/Source/JavaScriptCore/jit/RegisterSet.h        2015-09-10 17:47:16 UTC (rev 189575)
</span><span class="lines">@@ -50,6 +50,11 @@
</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 vmCalleeSaveRegisters(); // Callee save registers that might be saved and used by any tier.
+    static RegisterSet llintBaselineCalleeSaveRegisters(); // Registers saved and used by the LLInt.
+    static RegisterSet dfgCalleeSaveRegisters(); // Registers saved and used by the DFG JIT.
+    static RegisterSet ftlCalleeSaveRegisters(); // Registers that might be saved and used by the FTL JIT.
+    static RegisterSet stubUnavailableRegisters(); // The union of callee saves and special registers.
</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="trunkSourceJavaScriptCorejitRepatchcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/Repatch.cpp (189574 => 189575)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/Repatch.cpp        2015-09-10 17:31:42 UTC (rev 189574)
+++ trunk/Source/JavaScriptCore/jit/Repatch.cpp        2015-09-10 17:47:16 UTC (rev 189575)
</span><span class="lines">@@ -555,7 +555,9 @@
</span><span class="cx">             if (kind == CallCustomGetter)
</span><span class="cx">                 stubJit.setupResults(valueRegs);
</span><span class="cx">             MacroAssembler::Jump noException = stubJit.emitExceptionCheck(CCallHelpers::InvertedExceptionCheck);
</span><del>-            
</del><ins>+
+            stubJit.copyCalleeSavesToVMCalleeSavesBuffer();
+
</ins><span class="cx">             stubJit.setupArguments(CCallHelpers::TrustedImmPtr(vm), GPRInfo::callFrameRegister);
</span><span class="cx">             handlerCall = stubJit.call();
</span><span class="cx">             stubJit.jumpToExceptionHandler();
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitSpecializedThunkJITh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/SpecializedThunkJIT.h (189574 => 189575)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/SpecializedThunkJIT.h        2015-09-10 17:31:42 UTC (rev 189574)
+++ trunk/Source/JavaScriptCore/jit/SpecializedThunkJIT.h        2015-09-10 17:47:16 UTC (rev 189575)
</span><span class="lines">@@ -44,6 +44,7 @@
</span><span class="cx">             : JSInterfaceJIT(vm)
</span><span class="cx">         {
</span><span class="cx">             emitFunctionPrologue();
</span><ins>+            emitSaveThenMaterializeTagRegisters();
</ins><span class="cx">             // Check that we have the expected number of arguments
</span><span class="cx">             m_failures.append(branch32(NotEqual, payloadFor(JSStack::ArgumentCount), TrustedImm32(expectedArgCount + 1)));
</span><span class="cx">         }
</span><span class="lines">@@ -52,6 +53,7 @@
</span><span class="cx">             : JSInterfaceJIT(vm)
</span><span class="cx">         {
</span><span class="cx">             emitFunctionPrologue();
</span><ins>+            emitSaveThenMaterializeTagRegisters();
</ins><span class="cx">         }
</span><span class="cx">         
</span><span class="cx">         void loadDoubleArgument(int argument, FPRegisterID dst, RegisterID scratch)
</span><span class="lines">@@ -105,6 +107,8 @@
</span><span class="cx">         {
</span><span class="cx">             if (src != regT0)
</span><span class="cx">                 move(src, regT0);
</span><ins>+            
+            emitRestoreSavedTagRegisters();
</ins><span class="cx">             emitFunctionEpilogue();
</span><span class="cx">             ret();
</span><span class="cx">         }
</span><span class="lines">@@ -113,6 +117,7 @@
</span><span class="cx">         {
</span><span class="cx">             ASSERT_UNUSED(payload, payload == regT0);
</span><span class="cx">             ASSERT_UNUSED(tag, tag == regT1);
</span><ins>+            emitRestoreSavedTagRegisters();
</ins><span class="cx">             emitFunctionEpilogue();
</span><span class="cx">             ret();
</span><span class="cx">         }
</span><span class="lines">@@ -137,6 +142,7 @@
</span><span class="cx">             lowNonZero.link(this);
</span><span class="cx">             highNonZero.link(this);
</span><span class="cx"> #endif
</span><ins>+            emitRestoreSavedTagRegisters();
</ins><span class="cx">             emitFunctionEpilogue();
</span><span class="cx">             ret();
</span><span class="cx">         }
</span><span class="lines">@@ -146,6 +152,7 @@
</span><span class="cx">             if (src != regT0)
</span><span class="cx">                 move(src, regT0);
</span><span class="cx">             tagReturnAsInt32();
</span><ins>+            emitRestoreSavedTagRegisters();
</ins><span class="cx">             emitFunctionEpilogue();
</span><span class="cx">             ret();
</span><span class="cx">         }
</span><span class="lines">@@ -155,6 +162,7 @@
</span><span class="cx">             if (src != regT0)
</span><span class="cx">                 move(src, regT0);
</span><span class="cx">             tagReturnAsJSCell();
</span><ins>+            emitRestoreSavedTagRegisters();
</ins><span class="cx">             emitFunctionEpilogue();
</span><span class="cx">             ret();
</span><span class="cx">         }
</span><span class="lines">@@ -185,7 +193,31 @@
</span><span class="cx">         }
</span><span class="cx"> 
</span><span class="cx">     private:
</span><ins>+        void emitSaveThenMaterializeTagRegisters()
+        {
+#if USE(JSVALUE64)
+#if CPU(ARM64)
+            pushPair(tagTypeNumberRegister, tagMaskRegister);
+#else
+            push(tagTypeNumberRegister);
+            push(tagMaskRegister);
+#endif
+            emitMaterializeTagCheckRegisters();
+#endif
+        }
</ins><span class="cx"> 
</span><ins>+        void emitRestoreSavedTagRegisters()
+        {
+#if USE(JSVALUE64)
+#if CPU(ARM64)
+            popPair(tagTypeNumberRegister, tagMaskRegister);
+#else
+            pop(tagMaskRegister);
+            pop(tagTypeNumberRegister);
+#endif
+#endif
+        }
+        
</ins><span class="cx">         void tagReturnAsInt32()
</span><span class="cx">         {
</span><span class="cx"> #if USE(JSVALUE64)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitTempRegisterSeth"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/TempRegisterSet.h (189574 => 189575)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/TempRegisterSet.h        2015-09-10 17:31:42 UTC (rev 189574)
+++ trunk/Source/JavaScriptCore/jit/TempRegisterSet.h        2015-09-10 17:47:16 UTC (rev 189575)
</span><span class="lines">@@ -115,6 +115,16 @@
</span><span class="cx">         return getBit(GPRInfo::numberOfRegisters + index);
</span><span class="cx">     }
</span><span class="cx">     
</span><ins>+    // Return the index'th free FPR.
+    FPRReg getFreeFPR(unsigned index = 0) const
+    {
+        for (unsigned i = FPRInfo::numberOfRegisters; i--;) {
+            if (!getFPRByIndex(i) &amp;&amp; !index--)
+                return FPRInfo::toRegister(i);
+        }
+        return InvalidFPRReg;
+    }
+
</ins><span class="cx">     template&lt;typename BankInfo&gt;
</span><span class="cx">     void setByIndex(unsigned index)
</span><span class="cx">     {
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitThunkGeneratorscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/ThunkGenerators.cpp (189574 => 189575)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/ThunkGenerators.cpp        2015-09-10 17:31:42 UTC (rev 189574)
+++ trunk/Source/JavaScriptCore/jit/ThunkGenerators.cpp        2015-09-10 17:47:16 UTC (rev 189575)
</span><span class="lines">@@ -66,6 +66,8 @@
</span><span class="cx">     // even though we won't use it.
</span><span class="cx">     jit.preserveReturnAddressAfterCall(GPRInfo::nonPreservedNonReturnGPR);
</span><span class="cx"> 
</span><ins>+    jit.copyCalleeSavesToVMCalleeSavesBuffer();
+
</ins><span class="cx">     jit.setupArguments(CCallHelpers::TrustedImmPtr(vm), GPRInfo::callFrameRegister);
</span><span class="cx">     jit.move(CCallHelpers::TrustedImmPtr(bitwise_cast&lt;void*&gt;(lookupExceptionHandler)), GPRInfo::nonArgGPR0);
</span><span class="cx">     emitPointerValidation(jit, GPRInfo::nonArgGPR0);
</span><span class="lines">@@ -209,6 +211,18 @@
</span><span class="cx"> 
</span><span class="cx">     if (entryType == EnterViaCall)
</span><span class="cx">         jit.emitFunctionPrologue();
</span><ins>+#if USE(JSVALUE64)
+    else if (entryType == EnterViaJump) {
+        // We're coming from a specialized thunk that has saved the prior tag registers' contents.
+        // Restore them now.
+#if CPU(ARM64)
+        jit.popPair(JSInterfaceJIT::tagTypeNumberRegister, JSInterfaceJIT::tagMaskRegister);
+#else
+        jit.pop(JSInterfaceJIT::tagMaskRegister);
+        jit.pop(JSInterfaceJIT::tagTypeNumberRegister);
+#endif
+    }
+#endif
</ins><span class="cx"> 
</span><span class="cx">     jit.emitPutImmediateToCallFrameHeader(0, JSStack::CodeBlock);
</span><span class="cx">     jit.storePtr(JSInterfaceJIT::callFrameRegister, &amp;vm-&gt;topCallFrame);
</span><span class="lines">@@ -306,6 +320,7 @@
</span><span class="cx">     // Handle an exception
</span><span class="cx">     exceptionHandler.link(&amp;jit);
</span><span class="cx"> 
</span><ins>+    jit.copyCalleeSavesToVMCalleeSavesBuffer();
</ins><span class="cx">     jit.storePtr(JSInterfaceJIT::callFrameRegister, &amp;vm-&gt;topCallFrame);
</span><span class="cx"> 
</span><span class="cx"> #if CPU(X86) &amp;&amp; USE(JSVALUE32_64)
</span><span class="lines">@@ -391,13 +406,6 @@
</span><span class="cx">     jit.addPtr(extraTemp, JSInterfaceJIT::callFrameRegister);
</span><span class="cx">     jit.addPtr(extraTemp, JSInterfaceJIT::stackPointerRegister);
</span><span class="cx"> 
</span><del>-    // Save the original return PC.
-    jit.loadPtr(JSInterfaceJIT::Address(JSInterfaceJIT::callFrameRegister, CallFrame::returnPCOffset()), extraTemp);
-    jit.storePtr(extraTemp, MacroAssembler::BaseIndex(JSInterfaceJIT::regT3, JSInterfaceJIT::argumentGPR0, JSInterfaceJIT::TimesEight));
-
-    // Install the new return PC.
-    jit.storePtr(GPRInfo::argumentGPR1, JSInterfaceJIT::Address(JSInterfaceJIT::callFrameRegister, CallFrame::returnPCOffset()));
-
</del><span class="cx"> #  if CPU(X86_64)
</span><span class="cx">     jit.push(JSInterfaceJIT::regT4);
</span><span class="cx"> #  endif
</span><span class="lines">@@ -439,13 +447,6 @@
</span><span class="cx">     jit.addPtr(JSInterfaceJIT::regT5, JSInterfaceJIT::callFrameRegister);
</span><span class="cx">     jit.addPtr(JSInterfaceJIT::regT5, JSInterfaceJIT::stackPointerRegister);
</span><span class="cx"> 
</span><del>-    // Save the original return PC.
-    jit.loadPtr(JSInterfaceJIT::Address(JSInterfaceJIT::callFrameRegister, CallFrame::returnPCOffset()), GPRInfo::regT5);
-    jit.storePtr(GPRInfo::regT5, MacroAssembler::BaseIndex(JSInterfaceJIT::regT3, JSInterfaceJIT::argumentGPR0, JSInterfaceJIT::TimesEight));
-    
-    // Install the new return PC.
-    jit.storePtr(GPRInfo::argumentGPR1, JSInterfaceJIT::Address(JSInterfaceJIT::callFrameRegister, CallFrame::returnPCOffset()));
-    
</del><span class="cx"> #  if CPU(X86)
</span><span class="cx">     jit.push(JSInterfaceJIT::regT4);
</span><span class="cx"> #  endif
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorellintLLIntDatacpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/llint/LLIntData.cpp (189574 => 189575)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/llint/LLIntData.cpp        2015-09-10 17:31:42 UTC (rev 189574)
+++ trunk/Source/JavaScriptCore/llint/LLIntData.cpp        2015-09-10 17:47:16 UTC (rev 189575)
</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() == 3);
+#endif
+    
</ins><span class="cx">     ASSERT(StringType == 6);
</span><span class="cx">     ASSERT(ObjectType == 21);
</span><span class="cx">     ASSERT(FinalObjectType == 22);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorellintLLIntSlowPathscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp (189574 => 189575)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp        2015-09-10 17:31:42 UTC (rev 189574)
+++ trunk/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp        2015-09-10 17:47:16 UTC (rev 189575)
</span><span class="lines">@@ -485,8 +485,8 @@
</span><span class="cx"> 
</span><span class="cx">     vm.topCallFrame = exec;
</span><span class="cx">     ErrorHandlingScope errorScope(vm);
</span><del>-    CommonSlowPaths::interpreterThrowInCaller(exec, createStackOverflowError(exec));
-    pc = returnToThrowForThrownException(exec);
</del><ins>+    vm.throwException(exec, createStackOverflowError(exec));
+    pc = returnToThrow(exec);
</ins><span class="cx">     LLINT_RETURN_TWO(pc, exec);
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorellintLowLevelInterpreterasm"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/llint/LowLevelInterpreter.asm (189574 => 189575)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/llint/LowLevelInterpreter.asm        2015-09-10 17:31:42 UTC (rev 189574)
+++ trunk/Source/JavaScriptCore/llint/LowLevelInterpreter.asm        2015-09-10 17:47:16 UTC (rev 189575)
</span><span class="lines">@@ -107,10 +107,9 @@
</span><span class="cx"> #  - t4 and t5 are never argument registers, t3 can only be a3, t1 can only be
</span><span class="cx"> #  a1; but t0 and t2 can be either a0 or a2.
</span><span class="cx"> #
</span><del>-#  - On 64 bits, csr0, csr1, csr2 and optionally csr3, csr4, csr5 and csr6
-#  are available as callee-save registers.
-#  csr0 is used to store the PC base, while the last two csr registers are used
-#  to store special tag values. Don't use them for anything else.
</del><ins>+#  - On 64 bits, there are callee-save registers named csr0, csr1, ... csrN.
+#  The last three csr registers are used used to store the PC base and
+#  two special tag values. Don't use them for anything else.
</ins><span class="cx"> #
</span><span class="cx"> # Additional platform-specific details (you shouldn't rely on this remaining
</span><span class="cx"> # true):
</span><span class="lines">@@ -218,6 +217,15 @@
</span><span class="cx">     const maxFrameExtentForSlowPathCall = 64
</span><span class="cx"> end
</span><span class="cx"> 
</span><ins>+if X86_64 or X86_64_WIN or ARM64
+    const CalleeSaveSpaceAsVirtualRegisters = 3
+else
+    const CalleeSaveSpaceAsVirtualRegisters = 0
+end
+
+const CalleeSaveSpaceStackAligned = (CalleeSaveSpaceAsVirtualRegisters * SlotSize + StackAlignment - 1) &amp; ~StackAlignmentMask
+
+
</ins><span class="cx"> # Watchpoint states
</span><span class="cx"> const ClearWatchpoint = 0
</span><span class="cx"> const IsWatched = 1
</span><span class="lines">@@ -231,17 +239,20 @@
</span><span class="cx">     # - C calls are still given the Instruction* rather than the PC index.
</span><span class="cx">     #   This requires an add before the call, and a sub after.
</span><span class="cx">     const PC = t4
</span><del>-    const PB = csr0
</del><span class="cx">     if ARM64
</span><del>-        const tagTypeNumber = csr1
-        const tagMask = csr2
</del><ins>+        const PB = csr7
+        const tagTypeNumber = csr8
+        const tagMask = csr9
</ins><span class="cx">     elsif X86_64
</span><ins>+        const PB = csr2
</ins><span class="cx">         const tagTypeNumber = csr3
</span><span class="cx">         const tagMask = csr4
</span><span class="cx">     elsif X86_64_WIN
</span><ins>+        const PB = csr4
</ins><span class="cx">         const tagTypeNumber = csr5
</span><span class="cx">         const tagMask = csr6
</span><span class="cx">     elsif C_LOOP
</span><ins>+        const PB = csr0
</ins><span class="cx">         const tagTypeNumber = csr1
</span><span class="cx">         const tagMask = csr2
</span><span class="cx">     end
</span><span class="lines">@@ -398,18 +409,14 @@
</span><span class="cx">     end
</span><span class="cx"> end
</span><span class="cx"> 
</span><del>-if C_LOOP
</del><ins>+if C_LOOP or ARM64 or X86_64 or X86_64_WIN
</ins><span class="cx">     const CalleeSaveRegisterCount = 0
</span><span class="cx"> elsif ARM or ARMv7_TRADITIONAL or ARMv7
</span><span class="cx">     const CalleeSaveRegisterCount = 7
</span><del>-elsif ARM64
-    const CalleeSaveRegisterCount = 10
-elsif SH4 or X86_64 or MIPS
</del><ins>+elsif SH4 or MIPS
</ins><span class="cx">     const CalleeSaveRegisterCount = 5
</span><span class="cx"> elsif X86 or X86_WIN
</span><span class="cx">     const CalleeSaveRegisterCount = 3
</span><del>-elsif X86_64_WIN
-    const CalleeSaveRegisterCount = 7
</del><span class="cx"> end
</span><span class="cx"> 
</span><span class="cx"> const CalleeRegisterSaveSize = CalleeSaveRegisterCount * PtrSize
</span><span class="lines">@@ -419,17 +426,11 @@
</span><span class="cx"> const VMEntryTotalFrameSize = (CalleeRegisterSaveSize + sizeof VMEntryRecord + StackAlignment - 1) &amp; ~StackAlignmentMask
</span><span class="cx"> 
</span><span class="cx"> macro pushCalleeSaves()
</span><del>-    if C_LOOP
</del><ins>+    if C_LOOP or ARM64 or X86_64 or X86_64_WIN
</ins><span class="cx">     elsif ARM or ARMv7_TRADITIONAL
</span><span class="cx">         emit &quot;push {r4-r10}&quot;
</span><span class="cx">     elsif ARMv7
</span><span class="cx">         emit &quot;push {r4-r6, r8-r11}&quot;
</span><del>-    elsif ARM64
-        emit &quot;stp x20, x19, [sp, #-16]!&quot;
-        emit &quot;stp x22, x21, [sp, #-16]!&quot;
-        emit &quot;stp x24, x23, [sp, #-16]!&quot;
-        emit &quot;stp x26, x25, [sp, #-16]!&quot;
-        emit &quot;stp x28, x27, [sp, #-16]!&quot;
</del><span class="cx">     elsif MIPS
</span><span class="cx">         emit &quot;addiu $sp, $sp, -20&quot;
</span><span class="cx">         emit &quot;sw $20, 16($sp)&quot;
</span><span class="lines">@@ -451,35 +452,15 @@
</span><span class="cx">         emit &quot;push esi&quot;
</span><span class="cx">         emit &quot;push edi&quot;
</span><span class="cx">         emit &quot;push ebx&quot;
</span><del>-    elsif X86_64
-        emit &quot;push %r12&quot;
-        emit &quot;push %r13&quot;
-        emit &quot;push %r14&quot;
-        emit &quot;push %r15&quot;
-        emit &quot;push %rbx&quot;
-    elsif X86_64_WIN
-        emit &quot;push r12&quot;
-        emit &quot;push r13&quot;
-        emit &quot;push r14&quot;
-        emit &quot;push r15&quot;
-        emit &quot;push rbx&quot;
-        emit &quot;push rdi&quot;
-        emit &quot;push rsi&quot;
</del><span class="cx">     end
</span><span class="cx"> end
</span><span class="cx"> 
</span><span class="cx"> macro popCalleeSaves()
</span><del>-    if C_LOOP
</del><ins>+    if C_LOOP or ARM64 or X86_64 or X86_64_WIN
</ins><span class="cx">     elsif ARM or ARMv7_TRADITIONAL
</span><span class="cx">         emit &quot;pop {r4-r10}&quot;
</span><span class="cx">     elsif ARMv7
</span><span class="cx">         emit &quot;pop {r4-r6, r8-r11}&quot;
</span><del>-    elsif ARM64
-        emit &quot;ldp x28, x27, [sp], #16&quot;
-        emit &quot;ldp x26, x25, [sp], #16&quot;
-        emit &quot;ldp x24, x23, [sp], #16&quot;
-        emit &quot;ldp x22, x21, [sp], #16&quot;
-        emit &quot;ldp x20, x19, [sp], #16&quot;
</del><span class="cx">     elsif MIPS
</span><span class="cx">         emit &quot;lw $16, 0($sp)&quot;
</span><span class="cx">         emit &quot;lw $17, 4($sp)&quot;
</span><span class="lines">@@ -501,20 +482,6 @@
</span><span class="cx">         emit &quot;pop ebx&quot;
</span><span class="cx">         emit &quot;pop edi&quot;
</span><span class="cx">         emit &quot;pop esi&quot;
</span><del>-    elsif X86_64
-        emit &quot;pop %rbx&quot;
-        emit &quot;pop %r15&quot;
-        emit &quot;pop %r14&quot;
-        emit &quot;pop %r13&quot;
-        emit &quot;pop %r12&quot;
-    elsif X86_64_WIN
-        emit &quot;pop rsi&quot;
-        emit &quot;pop rdi&quot;
-        emit &quot;pop rbx&quot;
-        emit &quot;pop r15&quot;
-        emit &quot;pop r14&quot;
-        emit &quot;pop r13&quot;
-        emit &quot;pop r12&quot;
</del><span class="cx">     end
</span><span class="cx"> end
</span><span class="cx"> 
</span><span class="lines">@@ -544,6 +511,131 @@
</span><span class="cx">     end
</span><span class="cx"> end
</span><span class="cx"> 
</span><ins>+macro preserveCalleeSavesUsedByLLInt()
+    subp CalleeSaveSpaceStackAligned, sp
+    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 csr4, -8[cfr]
+        storep csr3, -16[cfr]
+        storep csr2, -24[cfr]
+    elsif X86_64_WIN
+        storep csr6, -8[cfr]
+        storep csr5, -16[cfr]
+        storep csr4, -24[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], csr2
+        loadp -16[cfr], csr3
+        loadp -8[cfr], csr4
+    elsif X86_64_WIN
+        loadp -24[cfr], csr4
+        loadp -16[cfr], csr5
+        loadp -8[cfr], csr6
+    end
+end
+
+macro copyCalleeSavesToVMCalleeSavesBuffer(vm, temp)
+    if ARM64 or X86_64 or X86_64_WIN
+        leap VM::calleeSaveRegistersBuffer[vm], temp
+        if ARM64
+            storep csr0, [temp]
+            storep csr1, 8[temp]
+            storep csr2, 16[temp]
+            storep csr3, 24[temp]
+            storep csr4, 32[temp]
+            storep csr5, 40[temp]
+            storep csr6, 48[temp]
+            storep csr7, 56[temp]
+            storep csr8, 64[temp]
+            storep csr9, 72[temp]
+            stored csfr0, 80[temp]
+            stored csfr1, 88[temp]
+            stored csfr2, 96[temp]
+            stored csfr3, 104[temp]
+            stored csfr4, 112[temp]
+            stored csfr5, 120[temp]
+            stored csfr6, 128[temp]
+            stored csfr7, 136[temp]
+        elsif X86_64
+            storep csr0, [temp]
+            storep csr1, 8[temp]
+            storep csr2, 16[temp]
+            storep csr3, 24[temp]
+            storep csr4, 32[temp]
+        elsif X86_64_WIN
+            storep csr0, [temp]
+            storep csr1, 8[temp]
+            storep csr2, 16[temp]
+            storep csr3, 24[temp]
+            storep csr4, 32[temp]
+            storep csr5, 40[temp]
+            storep csr6, 48[temp]
+        end
+    end
+end
+
+macro restoreCalleeSavesFromVMCalleeSavesBuffer(vm, temp)
+    if ARM64 or X86_64 or X86_64_WIN
+        leap VM::calleeSaveRegistersBuffer[vm], temp
+        if ARM64
+            loadp [temp], csr0
+            loadp 8[temp], csr1
+            loadp 16[temp], csr2
+            loadp 24[temp], csr3
+            loadp 32[temp], csr4
+            loadp 40[temp], csr5
+            loadp 48[temp], csr6
+            loadp 56[temp], csr7
+            loadp 64[temp], csr8
+            loadp 72[temp], csr9
+            loadd 80[temp], csfr0
+            loadd 88[temp], csfr1
+            loadd 96[temp], csfr2
+            loadd 104[temp], csfr3
+            loadd 112[temp], csfr4
+            loadd 120[temp], csfr5
+            loadd 128[temp], csfr6
+            loadd 136[temp], csfr7
+        elsif X86_64
+            loadp [temp], csr0
+            loadp 8[temp], csr1
+            loadp 16[temp], csr2
+            loadp 24[temp], csr3
+            loadp 32[temp], csr4
+        elsif X86_64_WIN
+            loadp [temp], csr0
+            loadp 8[temp], csr1
+            loadp 16[temp], csr2
+            loadp 24[temp], csr3
+            loadp 32[temp], csr4
+            loadp 40[temp], csr5
+            loadp 48[temp], csr6
+        end
+    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">@@ -555,17 +647,6 @@
</span><span class="cx">     end
</span><span class="cx"> end
</span><span class="cx"> 
</span><del>-macro restoreReturnAddressBeforeReturn(sourceRegister)
-    if C_LOOP or ARM or ARMv7 or ARMv7_TRADITIONAL or ARM64 or MIPS or SH4
-        # In C_LOOP case, we're only restoring the bytecode vPC.
-        move sourceRegister, lr
-    elsif X86 or X86_WIN or X86_64 or X86_64_WIN
-        push sourceRegister
-    else
-        error
-    end
-end
-
</del><span class="cx"> macro functionPrologue()
</span><span class="cx">     if X86 or X86_WIN or X86_64 or X86_64_WIN
</span><span class="cx">         push cfr
</span><span class="lines">@@ -763,6 +844,8 @@
</span><span class="cx"> 
</span><span class="cx">     codeBlockSetter(t1)
</span><span class="cx"> 
</span><ins>+    preserveCalleeSavesUsedByLLInt()
+
</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">@@ -778,7 +861,8 @@
</span><span class="cx">     bpbeq VM::m_jsStackLimit[t2], t0, .stackHeightOK
</span><span class="cx"> 
</span><span class="cx">     # Stack height check failed - need to call a slow_path.
</span><del>-    subp maxFrameExtentForSlowPathCall, sp # Set up temporary stack pointer for call
</del><ins>+    # Set up temporary stack pointer for call including callee saves
+    subp maxFrameExtentForSlowPathCall, sp
</ins><span class="cx">     callSlowPath(_llint_stack_check)
</span><span class="cx">     bpeq r1, 0, .stackHeightOKGetCodeBlock
</span><span class="cx">     move r1, cfr
</span><span class="lines">@@ -793,6 +877,11 @@
</span><span class="cx"> 
</span><span class="cx"> .stackHeightOK:
</span><span class="cx">     move t0, sp
</span><ins>+
+    if JSVALUE64
+        move TagTypeNumber, tagTypeNumber
+        addp TagBitTypeOther, tagTypeNumber, tagMask
+    end
</ins><span class="cx"> end
</span><span class="cx"> 
</span><span class="cx"> # Expects that CodeBlock is in t1, which is what prologue() leaves behind.
</span><span class="lines">@@ -848,6 +937,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="trunkSourceJavaScriptCorellintLowLevelInterpreter32_64asm"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm (189574 => 189575)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm        2015-09-10 17:31:42 UTC (rev 189574)
+++ trunk/Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm        2015-09-10 17:47:16 UTC (rev 189575)
</span><span class="lines">@@ -302,6 +302,7 @@
</span><span class="cx">     loadp Callee + PayloadOffset[cfr], t3
</span><span class="cx">     andp MarkedBlockMask, t3
</span><span class="cx">     loadp MarkedBlock::m_weakSet + WeakSet::m_vm[t3], t3
</span><ins>+    restoreCalleeSavesFromVMCalleeSavesBuffer(t3, t0)
</ins><span class="cx">     loadp VM::callFrameForThrow[t3], cfr
</span><span class="cx"> 
</span><span class="cx">     loadp CallerFrame[cfr], cfr
</span><span class="lines">@@ -591,7 +592,6 @@
</span><span class="cx">     btpz t3, .proceedInline
</span><span class="cx">     
</span><span class="cx">     loadp CommonSlowPaths::ArityCheckData::paddedStackSpace[r1], a0
</span><del>-    loadp CommonSlowPaths::ArityCheckData::returnPC[r1], a1
</del><span class="cx">     call t3
</span><span class="cx">     if ASSERT_ENABLED
</span><span class="cx">         loadp ReturnPC[cfr], t0
</span><span class="lines">@@ -1878,6 +1878,7 @@
</span><span class="cx">     loadp Callee + PayloadOffset[cfr], t3
</span><span class="cx">     andp MarkedBlockMask, t3
</span><span class="cx">     loadp MarkedBlock::m_weakSet + WeakSet::m_vm[t3], t3
</span><ins>+    restoreCalleeSavesFromVMCalleeSavesBuffer(t3, t0)
</ins><span class="cx">     loadp VM::callFrameForThrow[t3], cfr
</span><span class="cx">     restoreStackPointerAfterCall()
</span><span class="cx"> 
</span><span class="lines">@@ -1916,6 +1917,7 @@
</span><span class="cx">     loadp Callee[cfr], t1
</span><span class="cx">     andp MarkedBlockMask, t1
</span><span class="cx">     loadp MarkedBlock::m_weakSet + WeakSet::m_vm[t1], t1
</span><ins>+    copyCalleeSavesToVMCalleeSavesBuffer(t1, t2)
</ins><span class="cx">     jmp VM::targetMachinePCForThrow[t1]
</span><span class="cx"> 
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorellintLowLevelInterpreter64asm"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm (189574 => 189575)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm        2015-09-10 17:31:42 UTC (rev 189574)
+++ trunk/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm        2015-09-10 17:47:16 UTC (rev 189575)
</span><span class="lines">@@ -215,9 +215,6 @@
</span><span class="cx">     end
</span><span class="cx">     storep cfr, VM::topVMEntryFrame[vm]
</span><span class="cx"> 
</span><del>-    move TagTypeNumber, tagTypeNumber
-    addp TagBitTypeOther, tagTypeNumber, tagMask
-
</del><span class="cx">     checkStackPointerAlignment(extraTempReg, 0xbad0dc02)
</span><span class="cx"> 
</span><span class="cx">     makeCall(entry, t3)
</span><span class="lines">@@ -277,6 +274,7 @@
</span><span class="cx">     loadp Callee[cfr], t3
</span><span class="cx">     andp MarkedBlockMask, t3
</span><span class="cx">     loadp MarkedBlock::m_weakSet + WeakSet::m_vm[t3], t3
</span><ins>+    restoreCalleeSavesFromVMCalleeSavesBuffer(t3, t0)
</ins><span class="cx">     loadp VM::callFrameForThrow[t3], cfr
</span><span class="cx"> 
</span><span class="cx">     loadp CallerFrame[cfr], cfr
</span><span class="lines">@@ -509,20 +507,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
-    loadp CommonSlowPaths::ArityCheckData::returnPC[r1], a1
-    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">@@ -530,8 +514,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">@@ -574,12 +559,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 class="lines">@@ -1761,11 +1749,6 @@
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="cx"> _llint_op_catch:
</span><del>-    # Gotta restore the tag registers. We could be throwing from FTL, which may
-    # clobber them.
-    move TagTypeNumber, tagTypeNumber
-    move TagMask, tagMask
-    
</del><span class="cx">     # This is where we end up from the JIT's throw trampoline (because the
</span><span class="cx">     # machine code return address will be set to _llint_op_catch), and from
</span><span class="cx">     # the interpreter's throw trampoline (see _llint_throw_trampoline).
</span><span class="lines">@@ -1774,6 +1757,7 @@
</span><span class="cx">     loadp Callee[cfr], t3
</span><span class="cx">     andp MarkedBlockMask, t3
</span><span class="cx">     loadp MarkedBlock::m_weakSet + WeakSet::m_vm[t3], t3
</span><ins>+    restoreCalleeSavesFromVMCalleeSavesBuffer(t3, t0)
</ins><span class="cx">     loadp VM::callFrameForThrow[t3], cfr
</span><span class="cx">     restoreStackPointerAfterCall()
</span><span class="cx"> 
</span><span class="lines">@@ -1806,6 +1790,11 @@
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="cx"> _llint_throw_from_slow_path_trampoline:
</span><ins>+    loadp Callee[cfr], t1
+    andp MarkedBlockMask, t1
+    loadp MarkedBlock::m_weakSet + WeakSet::m_vm[t1], t1
+    copyCalleeSavesToVMCalleeSavesBuffer(t1, t2)
+
</ins><span class="cx">     callSlowPath(_llint_slow_path_handle_exception)
</span><span class="cx"> 
</span><span class="cx">     # When throwing from the interpreter (i.e. throwing from LLIntSlowPaths), so
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreofflineasmarm64rb"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/offlineasm/arm64.rb (189574 => 189575)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/offlineasm/arm64.rb        2015-09-10 17:31:42 UTC (rev 189574)
+++ trunk/Source/JavaScriptCore/offlineasm/arm64.rb        2015-09-10 17:47:16 UTC (rev 189575)
</span><span class="lines">@@ -61,6 +61,14 @@
</span><span class="cx"> #  q3  =&gt; ft3, fa3
</span><span class="cx"> #  q4  =&gt; ft4          (unused in baseline)
</span><span class="cx"> #  q5  =&gt; ft5          (unused in baseline)
</span><ins>+#  q8  =&gt; csfr0        (Only the lower 64 bits)
+#  q9  =&gt; csfr1        (Only the lower 64 bits)
+# q10  =&gt; csfr2        (Only the lower 64 bits)
+# q11  =&gt; csfr3        (Only the lower 64 bits)
+# q12  =&gt; csfr4        (Only the lower 64 bits)
+# q13  =&gt; csfr5        (Only the lower 64 bits)
+# q14  =&gt; csfr6        (Only the lower 64 bits)
+# q15  =&gt; csfr7        (Only the lower 64 bits)
</ins><span class="cx"> # q31  =&gt; scratch
</span><span class="cx"> 
</span><span class="cx"> def arm64GPRName(name, kind)
</span><span class="lines">@@ -116,10 +124,24 @@
</span><span class="cx">         when 'cfr'
</span><span class="cx">             arm64GPRName('x29', kind)
</span><span class="cx">         when 'csr0'
</span><ins>+            arm64GPRName('x19', kind)
+        when 'csr1'
+            arm64GPRName('x20', kind)
+        when 'csr2'
+            arm64GPRName('x21', kind)
+        when 'csr3'
+            arm64GPRName('x22', kind)
+        when 'csr4'
+            arm64GPRName('x23', kind)
+        when 'csr5'
+            arm64GPRName('x24', kind)
+        when 'csr6'
+            arm64GPRName('x25', kind)
+        when 'csr7'
</ins><span class="cx">             arm64GPRName('x26', kind)
</span><del>-        when 'csr1'
</del><ins>+        when 'csr8'
</ins><span class="cx">             arm64GPRName('x27', kind)
</span><del>-        when 'csr2'
</del><ins>+        when 'csr9'
</ins><span class="cx">             arm64GPRName('x28', kind)
</span><span class="cx">         when 'sp'
</span><span class="cx">             'sp'
</span><span class="lines">@@ -146,6 +168,22 @@
</span><span class="cx">             arm64FPRName('q4', kind)
</span><span class="cx">         when 'ft5'
</span><span class="cx">             arm64FPRName('q5', kind)
</span><ins>+        when 'csfr0'
+            arm64FPRName('q8', kind)
+        when 'csfr1'
+            arm64FPRName('q9', kind)
+        when 'csfr2'
+            arm64FPRName('q10', kind)
+        when 'csfr3'
+            arm64FPRName('q11', kind)
+        when 'csfr4'
+            arm64FPRName('q12', kind)
+        when 'csfr5'
+            arm64FPRName('q13', kind)
+        when 'csfr6'
+            arm64FPRName('q14', kind)
+        when 'csfr7'
+            arm64FPRName('q15', kind)
</ins><span class="cx">         else &quot;Bad register name #{@name} at #{codeOriginString}&quot;
</span><span class="cx">         end
</span><span class="cx">     end
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreofflineasmregistersrb"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/offlineasm/registers.rb (189574 => 189575)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/offlineasm/registers.rb        2015-09-10 17:31:42 UTC (rev 189574)
+++ trunk/Source/JavaScriptCore/offlineasm/registers.rb        2015-09-10 17:47:16 UTC (rev 189575)
</span><span class="lines">@@ -48,7 +48,10 @@
</span><span class="cx">      &quot;csr3&quot;,
</span><span class="cx">      &quot;csr4&quot;,
</span><span class="cx">      &quot;csr5&quot;,
</span><del>-     &quot;csr6&quot;
</del><ins>+     &quot;csr6&quot;,
+     &quot;csr7&quot;,
+     &quot;csr8&quot;,
+     &quot;csr9&quot;
</ins><span class="cx">     ]
</span><span class="cx"> 
</span><span class="cx"> FPRS =
</span><span class="lines">@@ -63,6 +66,14 @@
</span><span class="cx">      &quot;fa1&quot;,
</span><span class="cx">      &quot;fa2&quot;,
</span><span class="cx">      &quot;fa3&quot;,
</span><ins>+     &quot;csfr0&quot;,
+     &quot;csfr1&quot;,
+     &quot;csfr2&quot;,
+     &quot;csfr3&quot;,
+     &quot;csfr4&quot;,
+     &quot;csfr5&quot;,
+     &quot;csfr6&quot;,
+     &quot;csfr7&quot;,
</ins><span class="cx">      &quot;fr&quot;
</span><span class="cx">     ]
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreofflineasmx86rb"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/offlineasm/x86.rb (189574 => 189575)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/offlineasm/x86.rb        2015-09-10 17:31:42 UTC (rev 189574)
+++ trunk/Source/JavaScriptCore/offlineasm/x86.rb        2015-09-10 17:47:16 UTC (rev 189575)
</span><span class="lines">@@ -290,14 +290,13 @@
</span><span class="cx">             when &quot;csr0&quot;
</span><span class="cx">                 &quot;ebx&quot;
</span><span class="cx">             when &quot;csr1&quot;
</span><del>-                &quot;r12&quot;
</del><ins>+                isWin ? &quot;esi&quot; : &quot;r12&quot;
</ins><span class="cx">             when &quot;csr2&quot;
</span><del>-                &quot;r13&quot;
</del><ins>+                isWin ? &quot;edi&quot; : &quot;r13&quot;
</ins><span class="cx">             when &quot;csr3&quot;
</span><del>-                isWin ? &quot;esi&quot; : &quot;r14&quot;
</del><ins>+                isWin ? &quot;r12&quot; : &quot;r14&quot;
</ins><span class="cx">             when &quot;csr4&quot;
</span><del>-                isWin ? &quot;edi&quot; : &quot;r15&quot;
-                &quot;r15&quot;
</del><ins>+                isWin ? &quot;r13&quot; : &quot;r15&quot;
</ins><span class="cx">             when &quot;csr5&quot;
</span><span class="cx">                 raise &quot;cannot use register #{name} on X86-64&quot; unless isWin
</span><span class="cx">                 &quot;r14&quot;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeCommonSlowPathscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/CommonSlowPaths.cpp (189574 => 189575)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/CommonSlowPaths.cpp        2015-09-10 17:31:42 UTC (rev 189574)
+++ trunk/Source/JavaScriptCore/runtime/CommonSlowPaths.cpp        2015-09-10 17:47:16 UTC (rev 189575)
</span><span class="lines">@@ -25,7 +25,6 @@
</span><span class="cx"> 
</span><span class="cx"> #include &quot;config.h&quot;
</span><span class="cx"> #include &quot;CommonSlowPaths.h&quot;
</span><del>-#include &quot;ArityCheckFailReturnThunks.h&quot;
</del><span class="cx"> #include &quot;ArrayConstructor.h&quot;
</span><span class="cx"> #include &quot;CallFrame.h&quot;
</span><span class="cx"> #include &quot;ClonedArguments.h&quot;
</span><span class="lines">@@ -166,15 +165,11 @@
</span><span class="cx">     CommonSlowPaths::ArityCheckData* result = vm.arityCheckData.get();
</span><span class="cx">     result-&gt;paddedStackSpace = slotsToAdd;
</span><span class="cx"> #if ENABLE(JIT)
</span><del>-    if (vm.canUseJIT()) {
</del><ins>+    if (vm.canUseJIT())
</ins><span class="cx">         result-&gt;thunkToCall = vm.getCTIStub(arityFixupGenerator).code().executableAddress();
</span><del>-        result-&gt;returnPC = vm.arityCheckFailReturnThunks-&gt;returnPCFor(vm, slotsToAdd * stackAlignmentRegisters()).executableAddress();
-    } else
</del><ins>+    else
</ins><span class="cx"> #endif
</span><del>-    {
</del><span class="cx">         result-&gt;thunkToCall = 0;
</span><del>-        result-&gt;returnPC = 0;
-    }
</del><span class="cx">     return result;
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeCommonSlowPathsh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/CommonSlowPaths.h (189574 => 189575)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/CommonSlowPaths.h        2015-09-10 17:31:42 UTC (rev 189574)
+++ trunk/Source/JavaScriptCore/runtime/CommonSlowPaths.h        2015-09-10 17:47:16 UTC (rev 189575)
</span><span class="lines">@@ -49,7 +49,6 @@
</span><span class="cx"> struct ArityCheckData {
</span><span class="cx">     unsigned paddedStackSpace;
</span><span class="cx">     void* thunkToCall;
</span><del>-    void* returnPC;
</del><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> ALWAYS_INLINE int arityCheckFor(ExecState* exec, JSStack* stack, CodeSpecializationKind kind)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeVMcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/VM.cpp (189574 => 189575)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/VM.cpp        2015-09-10 17:31:42 UTC (rev 189574)
+++ trunk/Source/JavaScriptCore/runtime/VM.cpp        2015-09-10 17:47:16 UTC (rev 189575)
</span><span class="lines">@@ -30,7 +30,6 @@
</span><span class="cx"> #include &quot;VM.h&quot;
</span><span class="cx"> 
</span><span class="cx"> #include &quot;ArgList.h&quot;
</span><del>-#include &quot;ArityCheckFailReturnThunks.h&quot;
</del><span class="cx"> #include &quot;ArrayBufferNeuteringWatchpoint.h&quot;
</span><span class="cx"> #include &quot;BuiltinExecutables.h&quot;
</span><span class="cx"> #include &quot;CodeBlock.h&quot;
</span><span class="lines">@@ -77,6 +76,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;RegisterAtOffsetList.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">@@ -253,7 +253,7 @@
</span><span class="cx"> 
</span><span class="cx"> #if ENABLE(JIT)
</span><span class="cx">     jitStubs = std::make_unique&lt;JITThunks&gt;();
</span><del>-    arityCheckFailReturnThunks = std::make_unique&lt;ArityCheckFailReturnThunks&gt;();
</del><ins>+    allCalleeSaveRegisterOffsets = std::make_unique&lt;RegisterAtOffsetList&gt;(RegisterSet::vmCalleeSaveRegisters(), RegisterAtOffsetList::ZeroBased);
</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="trunkSourceJavaScriptCoreruntimeVMh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/VM.h (189574 => 189575)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/VM.h        2015-09-10 17:31:42 UTC (rev 189574)
+++ trunk/Source/JavaScriptCore/runtime/VM.h        2015-09-10 17:47:16 UTC (rev 189575)
</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">@@ -72,7 +75,6 @@
</span><span class="cx"> 
</span><span class="cx"> namespace JSC {
</span><span class="cx"> 
</span><del>-class ArityCheckFailReturnThunks;
</del><span class="cx"> class BuiltinExecutables;
</span><span class="cx"> class CodeBlock;
</span><span class="cx"> class CodeCache;
</span><span class="lines">@@ -90,6 +92,7 @@
</span><span class="cx"> class LegacyProfiler;
</span><span class="cx"> class NativeExecutable;
</span><span class="cx"> class RegExpCache;
</span><ins>+class RegisterAtOffsetList;
</ins><span class="cx"> class ScriptExecutable;
</span><span class="cx"> class SourceProvider;
</span><span class="cx"> class SourceProviderCache;
</span><span class="lines">@@ -357,14 +360,26 @@
</span><span class="cx">     SourceProviderCacheMap sourceProviderCacheMap;
</span><span class="cx">     Interpreter* interpreter;
</span><span class="cx"> #if ENABLE(JIT)
</span><ins>+#if NUMBER_OF_CALLEE_SAVES_REGISTERS &gt; 0
+    intptr_t calleeSaveRegistersBuffer[NUMBER_OF_CALLEE_SAVES_REGISTERS];
+
+    static ptrdiff_t calleeSaveRegistersBufferOffset()
+    {
+        return OBJECT_OFFSETOF(VM, calleeSaveRegistersBuffer);
+    }
+#endif // NUMBER_OF_CALLEE_SAVES_REGISTERS &gt; 0
+
</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;RegisterAtOffsetList&gt; allCalleeSaveRegisterOffsets;
+    
+    RegisterAtOffsetList* getAllCalleeSaveRegisterOffsets() { return allCalleeSaveRegisterOffsets.get(); }
</ins><span class="cx"> 
</span><del>-    std::unique_ptr&lt;ArityCheckFailReturnThunks&gt; arityCheckFailReturnThunks;
</del><span class="cx"> #endif // ENABLE(JIT)
</span><span class="cx">     std::unique_ptr&lt;CommonSlowPaths::ArityCheckData&gt; arityCheckData;
</span><span class="cx"> #if ENABLE(FTL_JIT)
</span></span></pre>
</div>
</div>

</body>
</html>