<!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>[193640] 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/193640">193640</a></dd>
<dt>Author</dt> <dd>fpizlo@apple.com</dd>
<dt>Date</dt> <dd>2015-12-07 11:17:56 -0800 (Mon, 07 Dec 2015)</dd>
</dl>

<h3>Log Message</h3>
<pre>FTL B3 should be able to make JS-&gt;JS calls
https://bugs.webkit.org/show_bug.cgi?id=151901

Reviewed by Saam Barati.

This adds support for the Call and InvalidationPoint opcodes in DFG IR. This required doing some
clean-up in the OSR exit code. We don't want the B3 FTL to use a bunch of vectors to hold
side-state, so the use of OSRExitDescriptorImpl is not right. It makes sense in the LLVM FTL
because that code needs some way of saving some state from LowerDFGToLLVM to compile(), but
that's not how B3 FTL works. It turns out that for B3 FTL, there isn't anything in
OSRExitDescriptorImpl that the code in LowerDFGToLLVM can't just capture in a lambda.

This also simplifies some stackmap-related APIs, since I got tired of writing boilerplate.

* CMakeLists.txt:
* JavaScriptCore.xcodeproj/project.pbxproj:
* assembler/AbstractMacroAssembler.h:
(JSC::AbstractMacroAssembler::replaceWithAddressComputation):
(JSC::AbstractMacroAssembler::addLinkTask):
* b3/B3CheckSpecial.cpp:
(JSC::B3::CheckSpecial::generate):
* b3/B3Effects.h:
* b3/B3PatchpointSpecial.cpp:
(JSC::B3::PatchpointSpecial::generate):
* b3/B3Procedure.cpp:
(JSC::B3::Procedure::addDataSection):
(JSC::B3::Procedure::callArgAreaSize):
(JSC::B3::Procedure::requestCallArgAreaSize):
(JSC::B3::Procedure::frameSize):
* b3/B3Procedure.h:
(JSC::B3::Procedure::releaseByproducts):
(JSC::B3::Procedure::code):
* b3/B3StackmapGenerationParams.cpp: Added.
(JSC::B3::StackmapGenerationParams::usedRegisters):
(JSC::B3::StackmapGenerationParams::proc):
(JSC::B3::StackmapGenerationParams::StackmapGenerationParams):
* b3/B3StackmapGenerationParams.h: Added.
(JSC::B3::StackmapGenerationParams::value):
(JSC::B3::StackmapGenerationParams::reps):
(JSC::B3::StackmapGenerationParams::size):
(JSC::B3::StackmapGenerationParams::at):
(JSC::B3::StackmapGenerationParams::operator[]):
(JSC::B3::StackmapGenerationParams::begin):
(JSC::B3::StackmapGenerationParams::end):
(JSC::B3::StackmapGenerationParams::context):
(JSC::B3::StackmapGenerationParams::addLatePath):
* b3/B3StackmapValue.h:
* b3/B3ValueRep.h:
(JSC::B3::ValueRep::doubleValue):
(JSC::B3::ValueRep::withOffset):
* b3/air/AirGenerationContext.h:
* b3/testb3.cpp:
(JSC::B3::testSimplePatchpoint):
(JSC::B3::testSimplePatchpointWithoutOuputClobbersGPArgs):
(JSC::B3::testSimplePatchpointWithOuputClobbersGPArgs):
(JSC::B3::testSimplePatchpointWithoutOuputClobbersFPArgs):
(JSC::B3::testSimplePatchpointWithOuputClobbersFPArgs):
(JSC::B3::testPatchpointWithEarlyClobber):
(JSC::B3::testPatchpointCallArg):
(JSC::B3::testPatchpointFixedRegister):
(JSC::B3::testPatchpointAny):
(JSC::B3::testPatchpointLotsOfLateAnys):
(JSC::B3::testPatchpointAnyImm):
(JSC::B3::testPatchpointManyImms):
(JSC::B3::testPatchpointWithRegisterResult):
(JSC::B3::testPatchpointWithStackArgumentResult):
(JSC::B3::testPatchpointWithAnyResult):
(JSC::B3::testSimpleCheck):
(JSC::B3::testCheckLessThan):
(JSC::B3::testCheckMegaCombo):
(JSC::B3::testCheckAddImm):
(JSC::B3::testCheckAddImmCommute):
(JSC::B3::testCheckAddImmSomeRegister):
(JSC::B3::testCheckAdd):
(JSC::B3::testCheckAdd64):
(JSC::B3::testCheckSubImm):
(JSC::B3::testCheckSubBadImm):
(JSC::B3::testCheckSub):
(JSC::B3::testCheckSub64):
(JSC::B3::testCheckNeg):
(JSC::B3::testCheckNeg64):
(JSC::B3::testCheckMul):
(JSC::B3::testCheckMulMemory):
(JSC::B3::testCheckMul2):
(JSC::B3::testCheckMul64):
(JSC::B3::genericTestCompare):
* ftl/FTLExceptionHandlerManager.cpp:
* ftl/FTLExceptionHandlerManager.h:
* ftl/FTLJSCall.cpp:
* ftl/FTLJSCall.h:
* ftl/FTLJSCallBase.cpp:
(JSC::FTL::JSCallBase::emit):
* ftl/FTLJSCallBase.h:
* ftl/FTLJSCallVarargs.cpp:
* ftl/FTLJSCallVarargs.h:
* ftl/FTLJSTailCall.cpp:
(JSC::FTL::DFG::getRegisterWithAddend):
(JSC::FTL::JSTailCall::emit):
(JSC::FTL::JSTailCall::JSTailCall): Deleted.
* ftl/FTLJSTailCall.h:
(JSC::FTL::JSTailCall::stackmapID):
(JSC::FTL::JSTailCall::estimatedSize):
(JSC::FTL::JSTailCall::operator&lt;):
(JSC::FTL::JSTailCall::patchpoint): Deleted.
* ftl/FTLLowerDFGToLLVM.cpp:
(JSC::FTL::DFG::LowerDFGToLLVM::compileCallOrConstruct):
(JSC::FTL::DFG::LowerDFGToLLVM::compileInvalidationPoint):
(JSC::FTL::DFG::LowerDFGToLLVM::lazySlowPath):
(JSC::FTL::DFG::LowerDFGToLLVM::callCheck):
(JSC::FTL::DFG::LowerDFGToLLVM::appendOSRExitArgumentsForPatchpointIfWillCatchException):
(JSC::FTL::DFG::LowerDFGToLLVM::emitBranchToOSRExitIfWillCatchException):
(JSC::FTL::DFG::LowerDFGToLLVM::lowBlock):
(JSC::FTL::DFG::LowerDFGToLLVM::appendOSRExitDescriptor):
(JSC::FTL::DFG::LowerDFGToLLVM::appendOSRExit):
(JSC::FTL::DFG::LowerDFGToLLVM::blessSpeculation):
(JSC::FTL::DFG::LowerDFGToLLVM::emitOSRExitCall):
(JSC::FTL::DFG::LowerDFGToLLVM::buildExitArguments):
(JSC::FTL::DFG::LowerDFGToLLVM::exitValueForNode):
* ftl/FTLOSRExit.cpp:
(JSC::FTL::OSRExitDescriptor::OSRExitDescriptor):
(JSC::FTL::OSRExitDescriptor::emitOSRExit):
(JSC::FTL::OSRExitDescriptor::emitOSRExitLater):
(JSC::FTL::OSRExitDescriptor::prepareOSRExitHandle):
(JSC::FTL::OSRExit::OSRExit):
(JSC::FTL::OSRExit::codeLocationForRepatch):
(JSC::FTL::OSRExit::recoverRegistersFromSpillSlot):
(JSC::FTL::OSRExit::willArriveAtExitFromIndirectExceptionCheck):
(JSC::FTL::OSRExit::needsRegisterRecoveryOnGenericUnwindOSRExitPath):
* ftl/FTLOSRExit.h:
(JSC::FTL::OSRExitDescriptorImpl::OSRExitDescriptorImpl):
(JSC::FTL::OSRExit::considerAddingAsFrequentExitSite):
* ftl/FTLOSRExitCompiler.cpp:
(JSC::FTL::compileStub):
(JSC::FTL::compileFTLOSRExit):
* ftl/FTLState.h:</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="#trunkSourceJavaScriptCoreJavaScriptCorexcodeprojprojectpbxproj">trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj</a></li>
<li><a href="#trunkSourceJavaScriptCoreassemblerAbstractMacroAssemblerh">trunk/Source/JavaScriptCore/assembler/AbstractMacroAssembler.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3B3CheckSpecialcpp">trunk/Source/JavaScriptCore/b3/B3CheckSpecial.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3B3Effectsh">trunk/Source/JavaScriptCore/b3/B3Effects.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3B3PatchpointSpecialcpp">trunk/Source/JavaScriptCore/b3/B3PatchpointSpecial.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3B3Procedurecpp">trunk/Source/JavaScriptCore/b3/B3Procedure.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3B3Procedureh">trunk/Source/JavaScriptCore/b3/B3Procedure.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3B3StackmapValueh">trunk/Source/JavaScriptCore/b3/B3StackmapValue.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3B3ValueReph">trunk/Source/JavaScriptCore/b3/B3ValueRep.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3airAirGenerationContexth">trunk/Source/JavaScriptCore/b3/air/AirGenerationContext.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3testb3cpp">trunk/Source/JavaScriptCore/b3/testb3.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreftlFTLExceptionHandlerManagercpp">trunk/Source/JavaScriptCore/ftl/FTLExceptionHandlerManager.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreftlFTLExceptionHandlerManagerh">trunk/Source/JavaScriptCore/ftl/FTLExceptionHandlerManager.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreftlFTLJSCallcpp">trunk/Source/JavaScriptCore/ftl/FTLJSCall.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreftlFTLJSCallh">trunk/Source/JavaScriptCore/ftl/FTLJSCall.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreftlFTLJSCallBasecpp">trunk/Source/JavaScriptCore/ftl/FTLJSCallBase.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreftlFTLJSCallBaseh">trunk/Source/JavaScriptCore/ftl/FTLJSCallBase.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreftlFTLJSCallVarargscpp">trunk/Source/JavaScriptCore/ftl/FTLJSCallVarargs.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreftlFTLJSCallVarargsh">trunk/Source/JavaScriptCore/ftl/FTLJSCallVarargs.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreftlFTLJSTailCallcpp">trunk/Source/JavaScriptCore/ftl/FTLJSTailCall.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreftlFTLJSTailCallh">trunk/Source/JavaScriptCore/ftl/FTLJSTailCall.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreftlFTLLowerDFGToLLVMcpp">trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreftlFTLOSRExitcpp">trunk/Source/JavaScriptCore/ftl/FTLOSRExit.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreftlFTLOSRExith">trunk/Source/JavaScriptCore/ftl/FTLOSRExit.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreftlFTLOSRExitCompilercpp">trunk/Source/JavaScriptCore/ftl/FTLOSRExitCompiler.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreftlFTLStateh">trunk/Source/JavaScriptCore/ftl/FTLState.h</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkSourceJavaScriptCoreb3B3StackmapGenerationParamscpp">trunk/Source/JavaScriptCore/b3/B3StackmapGenerationParams.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3B3StackmapGenerationParamsh">trunk/Source/JavaScriptCore/b3/B3StackmapGenerationParams.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 (193639 => 193640)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/CMakeLists.txt        2015-12-07 18:54:33 UTC (rev 193639)
+++ trunk/Source/JavaScriptCore/CMakeLists.txt        2015-12-07 19:17:56 UTC (rev 193640)
</span><span class="lines">@@ -125,6 +125,7 @@
</span><span class="cx">     b3/B3PhiChildren.cpp
</span><span class="cx">     b3/B3Procedure.cpp
</span><span class="cx">     b3/B3ReduceStrength.cpp
</span><ins>+    b3/B3StackmapGenerationParams.cpp
</ins><span class="cx">     b3/B3StackmapSpecial.cpp
</span><span class="cx">     b3/B3StackmapValue.cpp
</span><span class="cx">     b3/B3StackSlotKind.cpp
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ChangeLog (193639 => 193640)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ChangeLog        2015-12-07 18:54:33 UTC (rev 193639)
+++ trunk/Source/JavaScriptCore/ChangeLog        2015-12-07 19:17:56 UTC (rev 193640)
</span><span class="lines">@@ -1,3 +1,141 @@
</span><ins>+2015-12-06  Filip Pizlo  &lt;fpizlo@apple.com&gt;
+
+        FTL B3 should be able to make JS-&gt;JS calls
+        https://bugs.webkit.org/show_bug.cgi?id=151901
+
+        Reviewed by Saam Barati.
+
+        This adds support for the Call and InvalidationPoint opcodes in DFG IR. This required doing some
+        clean-up in the OSR exit code. We don't want the B3 FTL to use a bunch of vectors to hold
+        side-state, so the use of OSRExitDescriptorImpl is not right. It makes sense in the LLVM FTL
+        because that code needs some way of saving some state from LowerDFGToLLVM to compile(), but
+        that's not how B3 FTL works. It turns out that for B3 FTL, there isn't anything in
+        OSRExitDescriptorImpl that the code in LowerDFGToLLVM can't just capture in a lambda.
+
+        This also simplifies some stackmap-related APIs, since I got tired of writing boilerplate.
+
+        * CMakeLists.txt:
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        * assembler/AbstractMacroAssembler.h:
+        (JSC::AbstractMacroAssembler::replaceWithAddressComputation):
+        (JSC::AbstractMacroAssembler::addLinkTask):
+        * b3/B3CheckSpecial.cpp:
+        (JSC::B3::CheckSpecial::generate):
+        * b3/B3Effects.h:
+        * b3/B3PatchpointSpecial.cpp:
+        (JSC::B3::PatchpointSpecial::generate):
+        * b3/B3Procedure.cpp:
+        (JSC::B3::Procedure::addDataSection):
+        (JSC::B3::Procedure::callArgAreaSize):
+        (JSC::B3::Procedure::requestCallArgAreaSize):
+        (JSC::B3::Procedure::frameSize):
+        * b3/B3Procedure.h:
+        (JSC::B3::Procedure::releaseByproducts):
+        (JSC::B3::Procedure::code):
+        * b3/B3StackmapGenerationParams.cpp: Added.
+        (JSC::B3::StackmapGenerationParams::usedRegisters):
+        (JSC::B3::StackmapGenerationParams::proc):
+        (JSC::B3::StackmapGenerationParams::StackmapGenerationParams):
+        * b3/B3StackmapGenerationParams.h: Added.
+        (JSC::B3::StackmapGenerationParams::value):
+        (JSC::B3::StackmapGenerationParams::reps):
+        (JSC::B3::StackmapGenerationParams::size):
+        (JSC::B3::StackmapGenerationParams::at):
+        (JSC::B3::StackmapGenerationParams::operator[]):
+        (JSC::B3::StackmapGenerationParams::begin):
+        (JSC::B3::StackmapGenerationParams::end):
+        (JSC::B3::StackmapGenerationParams::context):
+        (JSC::B3::StackmapGenerationParams::addLatePath):
+        * b3/B3StackmapValue.h:
+        * b3/B3ValueRep.h:
+        (JSC::B3::ValueRep::doubleValue):
+        (JSC::B3::ValueRep::withOffset):
+        * b3/air/AirGenerationContext.h:
+        * b3/testb3.cpp:
+        (JSC::B3::testSimplePatchpoint):
+        (JSC::B3::testSimplePatchpointWithoutOuputClobbersGPArgs):
+        (JSC::B3::testSimplePatchpointWithOuputClobbersGPArgs):
+        (JSC::B3::testSimplePatchpointWithoutOuputClobbersFPArgs):
+        (JSC::B3::testSimplePatchpointWithOuputClobbersFPArgs):
+        (JSC::B3::testPatchpointWithEarlyClobber):
+        (JSC::B3::testPatchpointCallArg):
+        (JSC::B3::testPatchpointFixedRegister):
+        (JSC::B3::testPatchpointAny):
+        (JSC::B3::testPatchpointLotsOfLateAnys):
+        (JSC::B3::testPatchpointAnyImm):
+        (JSC::B3::testPatchpointManyImms):
+        (JSC::B3::testPatchpointWithRegisterResult):
+        (JSC::B3::testPatchpointWithStackArgumentResult):
+        (JSC::B3::testPatchpointWithAnyResult):
+        (JSC::B3::testSimpleCheck):
+        (JSC::B3::testCheckLessThan):
+        (JSC::B3::testCheckMegaCombo):
+        (JSC::B3::testCheckAddImm):
+        (JSC::B3::testCheckAddImmCommute):
+        (JSC::B3::testCheckAddImmSomeRegister):
+        (JSC::B3::testCheckAdd):
+        (JSC::B3::testCheckAdd64):
+        (JSC::B3::testCheckSubImm):
+        (JSC::B3::testCheckSubBadImm):
+        (JSC::B3::testCheckSub):
+        (JSC::B3::testCheckSub64):
+        (JSC::B3::testCheckNeg):
+        (JSC::B3::testCheckNeg64):
+        (JSC::B3::testCheckMul):
+        (JSC::B3::testCheckMulMemory):
+        (JSC::B3::testCheckMul2):
+        (JSC::B3::testCheckMul64):
+        (JSC::B3::genericTestCompare):
+        * ftl/FTLExceptionHandlerManager.cpp:
+        * ftl/FTLExceptionHandlerManager.h:
+        * ftl/FTLJSCall.cpp:
+        * ftl/FTLJSCall.h:
+        * ftl/FTLJSCallBase.cpp:
+        (JSC::FTL::JSCallBase::emit):
+        * ftl/FTLJSCallBase.h:
+        * ftl/FTLJSCallVarargs.cpp:
+        * ftl/FTLJSCallVarargs.h:
+        * ftl/FTLJSTailCall.cpp:
+        (JSC::FTL::DFG::getRegisterWithAddend):
+        (JSC::FTL::JSTailCall::emit):
+        (JSC::FTL::JSTailCall::JSTailCall): Deleted.
+        * ftl/FTLJSTailCall.h:
+        (JSC::FTL::JSTailCall::stackmapID):
+        (JSC::FTL::JSTailCall::estimatedSize):
+        (JSC::FTL::JSTailCall::operator&lt;):
+        (JSC::FTL::JSTailCall::patchpoint): Deleted.
+        * ftl/FTLLowerDFGToLLVM.cpp:
+        (JSC::FTL::DFG::LowerDFGToLLVM::compileCallOrConstruct):
+        (JSC::FTL::DFG::LowerDFGToLLVM::compileInvalidationPoint):
+        (JSC::FTL::DFG::LowerDFGToLLVM::lazySlowPath):
+        (JSC::FTL::DFG::LowerDFGToLLVM::callCheck):
+        (JSC::FTL::DFG::LowerDFGToLLVM::appendOSRExitArgumentsForPatchpointIfWillCatchException):
+        (JSC::FTL::DFG::LowerDFGToLLVM::emitBranchToOSRExitIfWillCatchException):
+        (JSC::FTL::DFG::LowerDFGToLLVM::lowBlock):
+        (JSC::FTL::DFG::LowerDFGToLLVM::appendOSRExitDescriptor):
+        (JSC::FTL::DFG::LowerDFGToLLVM::appendOSRExit):
+        (JSC::FTL::DFG::LowerDFGToLLVM::blessSpeculation):
+        (JSC::FTL::DFG::LowerDFGToLLVM::emitOSRExitCall):
+        (JSC::FTL::DFG::LowerDFGToLLVM::buildExitArguments):
+        (JSC::FTL::DFG::LowerDFGToLLVM::exitValueForNode):
+        * ftl/FTLOSRExit.cpp:
+        (JSC::FTL::OSRExitDescriptor::OSRExitDescriptor):
+        (JSC::FTL::OSRExitDescriptor::emitOSRExit):
+        (JSC::FTL::OSRExitDescriptor::emitOSRExitLater):
+        (JSC::FTL::OSRExitDescriptor::prepareOSRExitHandle):
+        (JSC::FTL::OSRExit::OSRExit):
+        (JSC::FTL::OSRExit::codeLocationForRepatch):
+        (JSC::FTL::OSRExit::recoverRegistersFromSpillSlot):
+        (JSC::FTL::OSRExit::willArriveAtExitFromIndirectExceptionCheck):
+        (JSC::FTL::OSRExit::needsRegisterRecoveryOnGenericUnwindOSRExitPath):
+        * ftl/FTLOSRExit.h:
+        (JSC::FTL::OSRExitDescriptorImpl::OSRExitDescriptorImpl):
+        (JSC::FTL::OSRExit::considerAddingAsFrequentExitSite):
+        * ftl/FTLOSRExitCompiler.cpp:
+        (JSC::FTL::compileStub):
+        (JSC::FTL::compileFTLOSRExit):
+        * ftl/FTLState.h:
+
</ins><span class="cx"> 2015-12-07  Saam barati  &lt;sbarati@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Rename Watchdog::didFire to Watchdog::shouldTerminate because that's what didFire really meant
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreJavaScriptCorexcodeprojprojectpbxproj"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj (193639 => 193640)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj        2015-12-07 18:54:33 UTC (rev 193639)
+++ trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj        2015-12-07 19:17:56 UTC (rev 193640)
</span><span class="lines">@@ -304,6 +304,8 @@
</span><span class="cx">                 0F338E1C1BF286EA0013C88F /* B3BlockInsertionSet.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F338E181BF286EA0013C88F /* B3BlockInsertionSet.h */; };
</span><span class="cx">                 0F338E1D1BF286EA0013C88F /* B3LowerMacros.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F338E191BF286EA0013C88F /* B3LowerMacros.cpp */; };
</span><span class="cx">                 0F338E1E1BF286EA0013C88F /* B3LowerMacros.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F338E1A1BF286EA0013C88F /* B3LowerMacros.h */; };
</span><ins>+                0F33FCF71C136E2500323F67 /* B3StackmapGenerationParams.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F33FCF51C136E2500323F67 /* B3StackmapGenerationParams.cpp */; };
+                0F33FCF81C136E2500323F67 /* B3StackmapGenerationParams.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F33FCF61C136E2500323F67 /* B3StackmapGenerationParams.h */; };
</ins><span class="cx">                 0F34B14916D42010001CDA5A /* DFGUseKind.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F34B14716D4200E001CDA5A /* DFGUseKind.cpp */; };
</span><span class="cx">                 0F34B14A16D42013001CDA5A /* DFGUseKind.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F34B14816D4200E001CDA5A /* DFGUseKind.h */; };
</span><span class="cx">                 0F37308C1C0BD29100052BFA /* B3PhiChildren.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F37308A1C0BD29100052BFA /* B3PhiChildren.cpp */; };
</span><span class="lines">@@ -2400,6 +2402,8 @@
</span><span class="cx">                 0F338E181BF286EA0013C88F /* B3BlockInsertionSet.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = B3BlockInsertionSet.h; path = b3/B3BlockInsertionSet.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0F338E191BF286EA0013C88F /* B3LowerMacros.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = B3LowerMacros.cpp; path = b3/B3LowerMacros.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0F338E1A1BF286EA0013C88F /* B3LowerMacros.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = B3LowerMacros.h; path = b3/B3LowerMacros.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><ins>+                0F33FCF51C136E2500323F67 /* B3StackmapGenerationParams.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = B3StackmapGenerationParams.cpp; path = b3/B3StackmapGenerationParams.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
+                0F33FCF61C136E2500323F67 /* B3StackmapGenerationParams.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = B3StackmapGenerationParams.h; path = b3/B3StackmapGenerationParams.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</ins><span class="cx">                 0F34B14716D4200E001CDA5A /* DFGUseKind.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGUseKind.cpp; path = dfg/DFGUseKind.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0F34B14816D4200E001CDA5A /* DFGUseKind.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGUseKind.h; path = dfg/DFGUseKind.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0F37308A1C0BD29100052BFA /* B3PhiChildren.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = B3PhiChildren.cpp; path = b3/B3PhiChildren.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="lines">@@ -4629,6 +4633,8 @@
</span><span class="cx">                                 0FEC84E31BDACDAC0080FF74 /* B3ProcedureInlines.h */,
</span><span class="cx">                                 0FEC85B71BE1462F0080FF74 /* B3ReduceStrength.cpp */,
</span><span class="cx">                                 0FEC85B81BE1462F0080FF74 /* B3ReduceStrength.h */,
</span><ins>+                                0F33FCF51C136E2500323F67 /* B3StackmapGenerationParams.cpp */,
+                                0F33FCF61C136E2500323F67 /* B3StackmapGenerationParams.h */,
</ins><span class="cx">                                 0FEC84E61BDACDAC0080FF74 /* B3StackmapSpecial.cpp */,
</span><span class="cx">                                 0FEC84E71BDACDAC0080FF74 /* B3StackmapSpecial.h */,
</span><span class="cx">                                 0F338DEF1BE93AD10013C88F /* B3StackmapValue.cpp */,
</span><span class="lines">@@ -6976,6 +6982,7 @@
</span><span class="cx">                                 0FD3E4021B618AAF00C80E1E /* DFGAdaptiveInferredPropertyValueWatchpoint.h in Headers */,
</span><span class="cx">                                 0F18D3D01B55A6E0002C5C9F /* DFGAdaptiveStructureWatchpoint.h in Headers */,
</span><span class="cx">                                 998ED6751BED768C00DD8017 /* RemoteControllableTarget.h in Headers */,
</span><ins>+                                0F33FCF81C136E2500323F67 /* B3StackmapGenerationParams.h in Headers */,
</ins><span class="cx">                                 0F66E16B14DF3F1600B7B2E4 /* DFGAdjacencyList.h in Headers */,
</span><span class="cx">                                 0FFB921816D02EB20055A5DB /* DFGAllocator.h in Headers */,
</span><span class="cx">                                 0F1E3A461534CBAF000F9456 /* DFGArgumentPosition.h in Headers */,
</span><span class="lines">@@ -8493,6 +8500,7 @@
</span><span class="cx">                                 0F8F943C1667631300D61971 /* CodeSpecializationKind.cpp in Sources */,
</span><span class="cx">                                 0F8F94421667633500D61971 /* CodeType.cpp in Sources */,
</span><span class="cx">                                 147F39C1107EC37600427A48 /* CommonIdentifiers.cpp in Sources */,
</span><ins>+                                0F33FCF71C136E2500323F67 /* B3StackmapGenerationParams.cpp in Sources */,
</ins><span class="cx">                                 A709F2F217A0AC2A00512E98 /* CommonSlowPaths.cpp in Sources */,
</span><span class="cx">                                 6553A33117A1F1EE008CF6F3 /* CommonSlowPathsExceptions.cpp in Sources */,
</span><span class="cx">                                 A7E5A3A71797432D00E893C0 /* CompilationResult.cpp in Sources */,
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreassemblerAbstractMacroAssemblerh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/assembler/AbstractMacroAssembler.h (193639 => 193640)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/assembler/AbstractMacroAssembler.h        2015-12-07 18:54:33 UTC (rev 193639)
+++ trunk/Source/JavaScriptCore/assembler/AbstractMacroAssembler.h        2015-12-07 19:17:56 UTC (rev 193640)
</span><span class="lines">@@ -1016,11 +1016,6 @@
</span><span class="cx">         AssemblerType::replaceWithAddressComputation(label.dataLocation());
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    void addLinkTask(RefPtr&lt;SharedTask&lt;void(LinkBuffer&amp;)&gt;&gt; task)
-    {
-        m_linkTasks.append(task);
-    }
-
</del><span class="cx">     template&lt;typename Functor&gt;
</span><span class="cx">     void addLinkTask(const Functor&amp; functor)
</span><span class="cx">     {
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3B3CheckSpecialcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/B3CheckSpecial.cpp (193639 => 193640)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3CheckSpecial.cpp        2015-12-07 18:54:33 UTC (rev 193639)
+++ trunk/Source/JavaScriptCore/b3/B3CheckSpecial.cpp        2015-12-07 19:17:56 UTC (rev 193640)
</span><span class="lines">@@ -31,6 +31,7 @@
</span><span class="cx"> #include &quot;AirCode.h&quot;
</span><span class="cx"> #include &quot;AirGenerationContext.h&quot;
</span><span class="cx"> #include &quot;AirInstInlines.h&quot;
</span><ins>+#include &quot;B3StackmapGenerationParams.h&quot;
</ins><span class="cx"> #include &quot;B3ValueInlines.h&quot;
</span><span class="cx"> 
</span><span class="cx"> namespace JSC { namespace B3 {
</span><span class="lines">@@ -208,13 +209,7 @@
</span><span class="cx">                     break;
</span><span class="cx">                 }
</span><span class="cx">                 
</span><del>-                StackmapGenerationParams params;
-                params.value = value;
-                params.reps = reps;
-                params.usedRegisters = value-&gt;m_usedRegisters;
-                params.context = &amp;context;
-
-                value-&gt;m_generator-&gt;run(jit, params);
</del><ins>+                value-&gt;m_generator-&gt;run(jit, StackmapGenerationParams(value, reps, context));
</ins><span class="cx">             }));
</span><span class="cx"> 
</span><span class="cx">     return CCallHelpers::Jump(); // As far as Air thinks, we are not a terminal.
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3B3Effectsh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/B3Effects.h (193639 => 193640)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3Effects.h        2015-12-07 18:54:33 UTC (rev 193639)
+++ trunk/Source/JavaScriptCore/b3/B3Effects.h        2015-12-07 19:17:56 UTC (rev 193640)
</span><span class="lines">@@ -37,7 +37,11 @@
</span><span class="cx">     // True if this cannot continue execution in the current block.
</span><span class="cx">     bool terminal { false };
</span><span class="cx"> 
</span><del>-    // True if this value can cause execution to terminate abruptly.
</del><ins>+    // True if this value can cause execution to terminate abruptly, and that this abrupt termination is
+    // observable. Note that if exitsSideways is set to true but reads is bottom, then B3 is free to
+    // assume that after abrupt termination of this procedure, none of the heap will be read. That's
+    // usually false, so make sure that reads corresponds to the set of things that are readable after
+    // this function terminates abruptly.
</ins><span class="cx">     bool exitsSideways { false };
</span><span class="cx"> 
</span><span class="cx">     // True if the instruction may change semantics if hoisted above some control flow.
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3B3PatchpointSpecialcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/B3PatchpointSpecial.cpp (193639 => 193640)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3PatchpointSpecial.cpp        2015-12-07 18:54:33 UTC (rev 193639)
+++ trunk/Source/JavaScriptCore/b3/B3PatchpointSpecial.cpp        2015-12-07 19:17:56 UTC (rev 193640)
</span><span class="lines">@@ -29,6 +29,7 @@
</span><span class="cx"> #if ENABLE(B3_JIT)
</span><span class="cx"> 
</span><span class="cx"> #include &quot;AirGenerationContext.h&quot;
</span><ins>+#include &quot;B3StackmapGenerationParams.h&quot;
</ins><span class="cx"> #include &quot;B3ValueInlines.h&quot;
</span><span class="cx"> 
</span><span class="cx"> namespace JSC { namespace B3 {
</span><span class="lines">@@ -107,14 +108,8 @@
</span><span class="cx">         reps.append(repForArg(*context.code, inst.args[offset++]));
</span><span class="cx">     appendRepsImpl(context, offset, inst, reps);
</span><span class="cx">     
</span><del>-    StackmapGenerationParams params;
-    params.value = value;
-    params.reps = reps;
-    params.usedRegisters = value-&gt;m_usedRegisters;
-    params.context = &amp;context;
</del><ins>+    value-&gt;m_generator-&gt;run(jit, StackmapGenerationParams(value, reps, context));
</ins><span class="cx"> 
</span><del>-    value-&gt;m_generator-&gt;run(jit, params);
-
</del><span class="cx">     return CCallHelpers::Jump();
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3B3Procedurecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/B3Procedure.cpp (193639 => 193640)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3Procedure.cpp        2015-12-07 18:54:33 UTC (rev 193639)
+++ trunk/Source/JavaScriptCore/b3/B3Procedure.cpp        2015-12-07 19:17:56 UTC (rev 193640)
</span><span class="lines">@@ -148,6 +148,16 @@
</span><span class="cx">     return result;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+unsigned Procedure::callArgAreaSize() const
+{
+    return code().callArgAreaSize();
+}
+
+void Procedure::requestCallArgAreaSize(unsigned size)
+{
+    code().requestCallArgAreaSize(size);
+}
+
</ins><span class="cx"> unsigned Procedure::frameSize() const
</span><span class="cx"> {
</span><span class="cx">     return code().frameSize();
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3B3Procedureh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/B3Procedure.h (193639 => 193640)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3Procedure.h        2015-12-07 18:54:33 UTC (rev 193639)
+++ trunk/Source/JavaScriptCore/b3/B3Procedure.h        2015-12-07 19:17:56 UTC (rev 193640)
</span><span class="lines">@@ -221,9 +221,14 @@
</span><span class="cx">     // that API, then you don't have to worry about this.
</span><span class="cx">     std::unique_ptr&lt;OpaqueByproducts&gt; releaseByproducts() { return WTF::move(m_byproducts); }
</span><span class="cx"> 
</span><ins>+    // This gives you direct access to Code. However, the idea is that clients of B3 shouldn't have to
+    // call this. So, Procedure has some methods (below) that expose some Air::Code functionality.
</ins><span class="cx">     const Air::Code&amp; code() const { return *m_code; }
</span><span class="cx">     Air::Code&amp; code() { return *m_code; }
</span><span class="cx"> 
</span><ins>+    unsigned callArgAreaSize() const;
+    void requestCallArgAreaSize(unsigned size);
+
</ins><span class="cx">     JS_EXPORT_PRIVATE unsigned frameSize() const;
</span><span class="cx">     const RegisterAtOffsetList&amp; calleeSaveRegisters() const;
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3B3StackmapGenerationParamscpp"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/b3/B3StackmapGenerationParams.cpp (0 => 193640)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3StackmapGenerationParams.cpp                                (rev 0)
+++ trunk/Source/JavaScriptCore/b3/B3StackmapGenerationParams.cpp        2015-12-07 19:17:56 UTC (rev 193640)
</span><span class="lines">@@ -0,0 +1,60 @@
</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;B3StackmapGenerationParams.h&quot;
+
+#if ENABLE(B3_JIT)
+
+#include &quot;AirCode.h&quot;
+#include &quot;AirGenerationContext.h&quot;
+#include &quot;B3StackmapValue.h&quot;
+
+namespace JSC { namespace B3 {
+
+using namespace Air;
+
+const RegisterSet&amp; StackmapGenerationParams::usedRegisters() const
+{
+    return m_value-&gt;m_usedRegisters;
+}
+
+Procedure&amp; StackmapGenerationParams::proc() const
+{
+    return m_context.code-&gt;proc();
+}
+
+StackmapGenerationParams::StackmapGenerationParams(
+    StackmapValue* value, const Vector&lt;ValueRep&gt;&amp; reps, Air::GenerationContext&amp; context)
+    : m_value(value)
+    , m_reps(reps)
+    , m_context(context)
+{
+}
+
+} } // namespace JSC::B3
+
+#endif // ENABLE(B3_JIT)
+
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3B3StackmapGenerationParamsh"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/b3/B3StackmapGenerationParams.h (0 => 193640)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3StackmapGenerationParams.h                                (rev 0)
+++ trunk/Source/JavaScriptCore/b3/B3StackmapGenerationParams.h        2015-12-07 19:17:56 UTC (rev 193640)
</span><span class="lines">@@ -0,0 +1,94 @@
</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 B3StackmapGenerationParams_h
+#define B3StackmapGenerationParams_h
+
+#if ENABLE(B3_JIT)
+
+#include &quot;AirGenerationContext.h&quot;
+#include &quot;B3ValueRep.h&quot;
+#include &quot;RegisterSet.h&quot;
+
+namespace JSC { namespace B3 {
+
+class CheckSpecial;
+class PatchpointSpecial;
+class Procedure;
+class StackmapValue;
+
+class StackmapGenerationParams {
+public:
+    // This is the stackmap value that we're generating.
+    StackmapValue* value() const { return m_value; }
+    
+    // This tells you the actual value representations that were chosen. This is usually different
+    // from the constraints we supplied.
+    const Vector&lt;ValueRep&gt;&amp; reps() const { return m_reps; };
+
+    // Usually we wish to access the reps. We make this easy by making ourselves appear to be a
+    // collection of reps.
+    unsigned size() const { return m_reps.size(); }
+    const ValueRep&amp; at(unsigned index) const { return m_reps[index]; }
+    const ValueRep&amp; operator[](unsigned index) const { return at(index); }
+    Vector&lt;ValueRep&gt;::const_iterator begin() const { return m_reps.begin(); }
+    Vector&lt;ValueRep&gt;::const_iterator end() const { return m_reps.end(); }
+    
+    // This tells you the registers that were used.
+    const RegisterSet&amp; usedRegisters() const;
+
+    // This is provided for convenience; it means that you don't have to capture it if you don't want to.
+    Procedure&amp; proc() const;
+    
+    // The Air::GenerationContext gives you even more power.
+    Air::GenerationContext&amp; context() const { return m_context; };
+
+    template&lt;typename Functor&gt;
+    void addLatePath(const Functor&amp; functor) const
+    {
+        context().latePaths.append(
+            createSharedTask&lt;Air::GenerationContext::LatePathFunction&gt;(
+                [=] (CCallHelpers&amp; jit, Air::GenerationContext&amp;) {
+                    functor(jit);
+                }));
+    }
+
+private:
+    friend class CheckSpecial;
+    friend class PatchpointSpecial;
+    
+    StackmapGenerationParams(StackmapValue*, const Vector&lt;ValueRep&gt;&amp; reps, Air::GenerationContext&amp;);
+
+    StackmapValue* m_value;
+    Vector&lt;ValueRep&gt; m_reps;
+    Air::GenerationContext&amp; m_context;
+};
+
+} } // namespace JSC::B3
+
+#endif // ENABLE(B3_JIT)
+
+#endif // B3StackmapGenerationParams_h
+
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3B3StackmapValueh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/B3StackmapValue.h (193639 => 193640)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3StackmapValue.h        2015-12-07 18:54:33 UTC (rev 193639)
+++ trunk/Source/JavaScriptCore/b3/B3StackmapValue.h        2015-12-07 19:17:56 UTC (rev 193640)
</span><span class="lines">@@ -37,27 +37,8 @@
</span><span class="cx"> 
</span><span class="cx"> namespace JSC { namespace B3 {
</span><span class="cx"> 
</span><del>-class StackmapValue;
</del><ins>+class StackmapGenerationParams;
</ins><span class="cx"> 
</span><del>-namespace Air {
-struct GenerationContext;
-}
-
-struct StackmapGenerationParams {
-    // This is the stackmap value that we're generating.
-    StackmapValue* value;
-    
-    // This tells you the actual value representations that were chosen. This is usually different
-    // from the constraints we supplied.
-    Vector&lt;ValueRep&gt; reps;
-    
-    // This tells you the registers that were used.
-    RegisterSet usedRegisters;
-
-    // The Air::GenerationContext gives you even more power.
-    Air::GenerationContext* context;
-};
-
</del><span class="cx"> typedef void StackmapGeneratorFunction(CCallHelpers&amp;, const StackmapGenerationParams&amp;);
</span><span class="cx"> typedef SharedTask&lt;StackmapGeneratorFunction&gt; StackmapGenerator;
</span><span class="cx"> 
</span><span class="lines">@@ -84,6 +65,13 @@
</span><span class="cx">     // children().append(). That will work fine, but it's not recommended.
</span><span class="cx">     void append(const ConstrainedValue&amp;);
</span><span class="cx"> 
</span><ins>+    template&lt;typename VectorType&gt;
+    void appendVector(const VectorType&amp; vector)
+    {
+        for (const auto&amp; value : vector)
+            append(value);
+    }
+
</ins><span class="cx">     // Helper for appending cold any's. This often used by clients to implement OSR.
</span><span class="cx">     template&lt;typename VectorType&gt;
</span><span class="cx">     void appendColdAnys(const VectorType&amp; vector)
</span><span class="lines">@@ -285,6 +273,7 @@
</span><span class="cx"> private:
</span><span class="cx">     friend class CheckSpecial;
</span><span class="cx">     friend class PatchpointSpecial;
</span><ins>+    friend class StackmapGenerationParams;
</ins><span class="cx">     friend class StackmapSpecial;
</span><span class="cx">     
</span><span class="cx">     Vector&lt;ValueRep&gt; m_reps;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3B3ValueReph"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/B3ValueRep.h (193639 => 193640)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3ValueRep.h        2015-12-07 18:54:33 UTC (rev 193639)
+++ trunk/Source/JavaScriptCore/b3/B3ValueRep.h        2015-12-07 19:17:56 UTC (rev 193640)
</span><span class="lines">@@ -30,6 +30,7 @@
</span><span class="cx"> 
</span><span class="cx"> #include &quot;FPRInfo.h&quot;
</span><span class="cx"> #include &quot;GPRInfo.h&quot;
</span><ins>+#include &quot;JSCJSValue.h&quot;
</ins><span class="cx"> #include &quot;Reg.h&quot;
</span><span class="cx"> #include &lt;wtf/PrintStream.h&gt;
</span><span class="cx"> 
</span><span class="lines">@@ -201,6 +202,18 @@
</span><span class="cx">         return bitwise_cast&lt;double&gt;(value());
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    ValueRep withOffset(intptr_t offset)
+    {
+        switch (kind()) {
+        case Stack:
+            return stack(offsetFromFP() + offset);
+        case StackArgument:
+            return stackArgument(offsetFromSP() + offset);
+        default:
+            return *this;
+        }
+    }
+
</ins><span class="cx">     JS_EXPORT_PRIVATE void dump(PrintStream&amp;) const;
</span><span class="cx"> 
</span><span class="cx"> private:
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3airAirGenerationContexth"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/air/AirGenerationContext.h (193639 => 193640)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/air/AirGenerationContext.h        2015-12-07 18:54:33 UTC (rev 193639)
+++ trunk/Source/JavaScriptCore/b3/air/AirGenerationContext.h        2015-12-07 19:17:56 UTC (rev 193640)
</span><span class="lines">@@ -31,8 +31,12 @@
</span><span class="cx"> #include &lt;wtf/SharedTask.h&gt;
</span><span class="cx"> #include &lt;wtf/Vector.h&gt;
</span><span class="cx"> 
</span><del>-namespace JSC { namespace B3 { namespace Air {
</del><ins>+namespace JSC {
</ins><span class="cx"> 
</span><ins>+class CCallHelpers;
+
+namespace B3 { namespace Air {
+
</ins><span class="cx"> class Code;
</span><span class="cx"> 
</span><span class="cx"> struct GenerationContext {
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3testb3cpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/testb3.cpp (193639 => 193640)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/testb3.cpp        2015-12-07 18:54:33 UTC (rev 193639)
+++ trunk/Source/JavaScriptCore/b3/testb3.cpp        2015-12-07 19:17:56 UTC (rev 193640)
</span><span class="lines">@@ -37,6 +37,7 @@
</span><span class="cx"> #include &quot;B3MemoryValue.h&quot;
</span><span class="cx"> #include &quot;B3Procedure.h&quot;
</span><span class="cx"> #include &quot;B3StackSlotValue.h&quot;
</span><ins>+#include &quot;B3StackmapGenerationParams.h&quot;
</ins><span class="cx"> #include &quot;B3SwitchValue.h&quot;
</span><span class="cx"> #include &quot;B3UpsilonValue.h&quot;
</span><span class="cx"> #include &quot;B3ValueInlines.h&quot;
</span><span class="lines">@@ -3413,11 +3414,11 @@
</span><span class="cx">     patchpoint-&gt;setGenerator(
</span><span class="cx">         [&amp;] (CCallHelpers&amp; jit, const StackmapGenerationParams&amp; params) {
</span><span class="cx">             AllowMacroScratchRegisterUsage allowScratch(jit);
</span><del>-            CHECK(params.reps.size() == 3);
-            CHECK(params.reps[0].isGPR());
-            CHECK(params.reps[1].isGPR());
-            CHECK(params.reps[2].isGPR());
-            add32(jit, params.reps[1].gpr(), params.reps[2].gpr(), params.reps[0].gpr());
</del><ins>+            CHECK(params.size() == 3);
+            CHECK(params[0].isGPR());
+            CHECK(params[1].isGPR());
+            CHECK(params[2].isGPR());
+            add32(jit, params[1].gpr(), params[2].gpr(), params[0].gpr());
</ins><span class="cx">         });
</span><span class="cx">     root-&gt;appendNew&lt;ControlValue&gt;(proc, Return, Origin(), patchpoint);
</span><span class="cx"> 
</span><span class="lines">@@ -3440,11 +3441,11 @@
</span><span class="cx">     patchpoint-&gt;setGenerator(
</span><span class="cx">         [&amp;] (CCallHelpers&amp; jit, const StackmapGenerationParams&amp; params) {
</span><span class="cx">             AllowMacroScratchRegisterUsage allowScratch(jit);
</span><del>-            CHECK(params.reps.size() == 2);
-            CHECK(params.reps[0].isGPR());
-            CHECK(params.reps[1].isGPR());
-            jit.move(CCallHelpers::TrustedImm32(0x00ff00ff), params.reps[0].gpr());
-            jit.move(CCallHelpers::TrustedImm32(0x00ff00ff), params.reps[1].gpr());
</del><ins>+            CHECK(params.size() == 2);
+            CHECK(params[0].isGPR());
+            CHECK(params[1].isGPR());
+            jit.move(CCallHelpers::TrustedImm32(0x00ff00ff), params[0].gpr());
+            jit.move(CCallHelpers::TrustedImm32(0x00ff00ff), params[1].gpr());
</ins><span class="cx">             jit.move(CCallHelpers::TrustedImm32(0x00ff00ff), GPRInfo::argumentGPR0);
</span><span class="cx">             jit.move(CCallHelpers::TrustedImm32(0x00ff00ff), GPRInfo::argumentGPR1);
</span><span class="cx">         });
</span><span class="lines">@@ -3485,12 +3486,12 @@
</span><span class="cx">     patchpoint-&gt;setGenerator(
</span><span class="cx">         [&amp;] (CCallHelpers&amp; jit, const StackmapGenerationParams&amp; params) {
</span><span class="cx">             AllowMacroScratchRegisterUsage allowScratch(jit);
</span><del>-            CHECK(params.reps.size() == 3);
-            CHECK(params.reps[0].isGPR());
-            CHECK(params.reps[1].isGPR());
-            CHECK(params.reps[2].isGPR());
-            jit.move(params.reps[1].gpr(), params.reps[0].gpr());
-            jit.add64(params.reps[2].gpr(), params.reps[0].gpr());
</del><ins>+            CHECK(params.size() == 3);
+            CHECK(params[0].isGPR());
+            CHECK(params[1].isGPR());
+            CHECK(params[2].isGPR());
+            jit.move(params[1].gpr(), params[0].gpr());
+            jit.add64(params[2].gpr(), params[0].gpr());
</ins><span class="cx"> 
</span><span class="cx">             clobberAll.forEach([&amp;] (Reg reg) {
</span><span class="cx">                 jit.move(CCallHelpers::TrustedImm32(0x00ff00ff), reg.gpr());
</span><span class="lines">@@ -3520,11 +3521,11 @@
</span><span class="cx">     patchpoint-&gt;setGenerator(
</span><span class="cx">         [&amp;] (CCallHelpers&amp; jit, const StackmapGenerationParams&amp; params) {
</span><span class="cx">             AllowMacroScratchRegisterUsage allowScratch(jit);
</span><del>-            CHECK(params.reps.size() == 2);
-            CHECK(params.reps[0].isFPR());
-            CHECK(params.reps[1].isFPR());
-            jit.moveZeroToDouble(params.reps[0].fpr());
-            jit.moveZeroToDouble(params.reps[1].fpr());
</del><ins>+            CHECK(params.size() == 2);
+            CHECK(params[0].isFPR());
+            CHECK(params[1].isFPR());
+            jit.moveZeroToDouble(params[0].fpr());
+            jit.moveZeroToDouble(params[1].fpr());
</ins><span class="cx">             jit.moveZeroToDouble(FPRInfo::argumentFPR0);
</span><span class="cx">             jit.moveZeroToDouble(FPRInfo::argumentFPR1);
</span><span class="cx">         });
</span><span class="lines">@@ -3558,11 +3559,11 @@
</span><span class="cx">     patchpoint-&gt;setGenerator(
</span><span class="cx">         [&amp;] (CCallHelpers&amp; jit, const StackmapGenerationParams&amp; params) {
</span><span class="cx">             AllowMacroScratchRegisterUsage allowScratch(jit);
</span><del>-            CHECK(params.reps.size() == 3);
-            CHECK(params.reps[0].isFPR());
-            CHECK(params.reps[1].isFPR());
-            CHECK(params.reps[2].isFPR());
-            jit.addDouble(params.reps[1].fpr(), params.reps[2].fpr(), params.reps[0].fpr());
</del><ins>+            CHECK(params.size() == 3);
+            CHECK(params[0].isFPR());
+            CHECK(params[1].isFPR());
+            CHECK(params[2].isFPR());
+            jit.addDouble(params[1].fpr(), params[2].fpr(), params[0].fpr());
</ins><span class="cx"> 
</span><span class="cx">             clobberAll.forEach([&amp;] (Reg reg) {
</span><span class="cx">                 jit.moveZeroToDouble(reg.fpr());
</span><span class="lines">@@ -3590,10 +3591,10 @@
</span><span class="cx">         patchpoint-&gt;clobberEarly(RegisterSet(registerToClobber));
</span><span class="cx">         patchpoint-&gt;setGenerator(
</span><span class="cx">             [&amp;] (CCallHelpers&amp; jit, const StackmapGenerationParams&amp; params) {
</span><del>-                CHECK((params.reps[1].gpr() == GPRInfo::argumentGPR0) == arg1InArgGPR);
-                CHECK((params.reps[2].gpr() == GPRInfo::argumentGPR1) == arg2InArgGPR);
</del><ins>+                CHECK((params[1].gpr() == GPRInfo::argumentGPR0) == arg1InArgGPR);
+                CHECK((params[2].gpr() == GPRInfo::argumentGPR1) == arg2InArgGPR);
</ins><span class="cx">                 
</span><del>-                add32(jit, params.reps[1].gpr(), params.reps[2].gpr(), params.reps[0].gpr());
</del><ins>+                add32(jit, params[1].gpr(), params[2].gpr(), params[0].gpr());
</ins><span class="cx">             });
</span><span class="cx"> 
</span><span class="cx">         root-&gt;appendNew&lt;ControlValue&gt;(proc, Return, Origin(), patchpoint);
</span><span class="lines">@@ -3618,16 +3619,16 @@
</span><span class="cx">     patchpoint-&gt;setGenerator(
</span><span class="cx">         [&amp;] (CCallHelpers&amp; jit, const StackmapGenerationParams&amp; params) {
</span><span class="cx">             AllowMacroScratchRegisterUsage allowScratch(jit);
</span><del>-            CHECK(params.reps.size() == 3);
-            CHECK(params.reps[0].isGPR());
-            CHECK(params.reps[1].isStack());
-            CHECK(params.reps[2].isStack());
</del><ins>+            CHECK(params.size() == 3);
+            CHECK(params[0].isGPR());
+            CHECK(params[1].isStack());
+            CHECK(params[2].isStack());
</ins><span class="cx">             jit.load32(
</span><del>-                CCallHelpers::Address(GPRInfo::callFrameRegister, params.reps[1].offsetFromFP()),
-                params.reps[0].gpr());
</del><ins>+                CCallHelpers::Address(GPRInfo::callFrameRegister, params[1].offsetFromFP()),
+                params[0].gpr());
</ins><span class="cx">             jit.add32(
</span><del>-                CCallHelpers::Address(GPRInfo::callFrameRegister, params.reps[2].offsetFromFP()),
-                params.reps[0].gpr());
</del><ins>+                CCallHelpers::Address(GPRInfo::callFrameRegister, params[2].offsetFromFP()),
+                params[0].gpr());
</ins><span class="cx">         });
</span><span class="cx">     root-&gt;appendNew&lt;ControlValue&gt;(proc, Return, Origin(), patchpoint);
</span><span class="cx"> 
</span><span class="lines">@@ -3646,11 +3647,11 @@
</span><span class="cx">     patchpoint-&gt;setGenerator(
</span><span class="cx">         [&amp;] (CCallHelpers&amp; jit, const StackmapGenerationParams&amp; params) {
</span><span class="cx">             AllowMacroScratchRegisterUsage allowScratch(jit);
</span><del>-            CHECK(params.reps.size() == 3);
-            CHECK(params.reps[0].isGPR());
-            CHECK(params.reps[1] == ValueRep(GPRInfo::regT0));
-            CHECK(params.reps[2] == ValueRep(GPRInfo::regT1));
-            add32(jit, GPRInfo::regT0, GPRInfo::regT1, params.reps[0].gpr());
</del><ins>+            CHECK(params.size() == 3);
+            CHECK(params[0].isGPR());
+            CHECK(params[1] == ValueRep(GPRInfo::regT0));
+            CHECK(params[2] == ValueRep(GPRInfo::regT1));
+            add32(jit, GPRInfo::regT0, GPRInfo::regT1, params[0].gpr());
</ins><span class="cx">         });
</span><span class="cx">     root-&gt;appendNew&lt;ControlValue&gt;(proc, Return, Origin(), patchpoint);
</span><span class="cx"> 
</span><span class="lines">@@ -3670,11 +3671,11 @@
</span><span class="cx">         [&amp;] (CCallHelpers&amp; jit, const StackmapGenerationParams&amp; params) {
</span><span class="cx">             AllowMacroScratchRegisterUsage allowScratch(jit);
</span><span class="cx">             // We shouldn't have spilled the inputs, so we assert that they're in registers.
</span><del>-            CHECK(params.reps.size() == 3);
-            CHECK(params.reps[0].isGPR());
-            CHECK(params.reps[1].isGPR());
-            CHECK(params.reps[2].isGPR());
-            add32(jit, params.reps[1].gpr(), params.reps[2].gpr(), params.reps[0].gpr());
</del><ins>+            CHECK(params.size() == 3);
+            CHECK(params[0].isGPR());
+            CHECK(params[1].isGPR());
+            CHECK(params[2].isGPR());
+            add32(jit, params[1].gpr(), params[2].gpr(), params[0].gpr());
</ins><span class="cx">         });
</span><span class="cx">     root-&gt;appendNew&lt;ControlValue&gt;(proc, Return, Origin(), patchpoint);
</span><span class="cx"> 
</span><span class="lines">@@ -3704,16 +3705,16 @@
</span><span class="cx">         [&amp;] (CCallHelpers&amp; jit, const StackmapGenerationParams&amp; params) {
</span><span class="cx">             AllowMacroScratchRegisterUsage allowScratch(jit);
</span><span class="cx">             // We shouldn't have spilled the inputs, so we assert that they're in registers.
</span><del>-            CHECK(params.reps.size() == things.size() + 1);
-            CHECK(params.reps[0].isGPR());
-            jit.move(CCallHelpers::TrustedImm32(0), params.reps[0].gpr());
-            for (unsigned i = 1; i &lt; params.reps.size(); ++i) {
-                if (params.reps[i].isGPR()) {
-                    CHECK(params.reps[i] != params.reps[0]);
-                    jit.add32(params.reps[i].gpr(), params.reps[0].gpr());
</del><ins>+            CHECK(params.size() == things.size() + 1);
+            CHECK(params[0].isGPR());
+            jit.move(CCallHelpers::TrustedImm32(0), params[0].gpr());
+            for (unsigned i = 1; i &lt; params.size(); ++i) {
+                if (params[i].isGPR()) {
+                    CHECK(params[i] != params[0]);
+                    jit.add32(params[i].gpr(), params[0].gpr());
</ins><span class="cx">                 } else {
</span><del>-                    CHECK(params.reps[i].isStack());
-                    jit.add32(CCallHelpers::Address(GPRInfo::callFrameRegister, params.reps[i].offsetFromFP()), params.reps[0].gpr());
</del><ins>+                    CHECK(params[i].isStack());
+                    jit.add32(CCallHelpers::Address(GPRInfo::callFrameRegister, params[i].offsetFromFP()), params[0].gpr());
</ins><span class="cx">                 }
</span><span class="cx">             }
</span><span class="cx">         });
</span><span class="lines">@@ -3736,14 +3737,14 @@
</span><span class="cx">     patchpoint-&gt;setGenerator(
</span><span class="cx">         [&amp;] (CCallHelpers&amp; jit, const StackmapGenerationParams&amp; params) {
</span><span class="cx">             AllowMacroScratchRegisterUsage allowScratch(jit);
</span><del>-            CHECK(params.reps.size() == 3);
-            CHECK(params.reps[0].isGPR());
-            CHECK(params.reps[1].isGPR());
-            CHECK(params.reps[2].isConstant());
-            CHECK(params.reps[2].value() == 42);
</del><ins>+            CHECK(params.size() == 3);
+            CHECK(params[0].isGPR());
+            CHECK(params[1].isGPR());
+            CHECK(params[2].isConstant());
+            CHECK(params[2].value() == 42);
</ins><span class="cx">             jit.add32(
</span><del>-                CCallHelpers::TrustedImm32(static_cast&lt;int32_t&gt;(params.reps[2].value())),
-                params.reps[1].gpr(), params.reps[0].gpr());
</del><ins>+                CCallHelpers::TrustedImm32(static_cast&lt;int32_t&gt;(params[2].value())),
+                params[1].gpr(), params[0].gpr());
</ins><span class="cx">         });
</span><span class="cx">     root-&gt;appendNew&lt;ControlValue&gt;(proc, Return, Origin(), patchpoint);
</span><span class="cx"> 
</span><span class="lines">@@ -3765,11 +3766,11 @@
</span><span class="cx">     patchpoint-&gt;append(ConstrainedValue(arg4, ValueRep::WarmAny));
</span><span class="cx">     patchpoint-&gt;setGenerator(
</span><span class="cx">         [&amp;] (CCallHelpers&amp;, const StackmapGenerationParams&amp; params) {
</span><del>-            CHECK(params.reps.size() == 4);
-            CHECK(params.reps[0] == ValueRep::constant(42));
-            CHECK(params.reps[1] == ValueRep::constant(43));
-            CHECK(params.reps[2] == ValueRep::constant(43000000000000ll));
-            CHECK(params.reps[3] == ValueRep::constant(bitwise_cast&lt;int64_t&gt;(42.5)));
</del><ins>+            CHECK(params.size() == 4);
+            CHECK(params[0] == ValueRep::constant(42));
+            CHECK(params[1] == ValueRep::constant(43));
+            CHECK(params[2] == ValueRep::constant(43000000000000ll));
+            CHECK(params[3] == ValueRep::constant(bitwise_cast&lt;int64_t&gt;(42.5)));
</ins><span class="cx">         });
</span><span class="cx">     root-&gt;appendNew&lt;ControlValue&gt;(
</span><span class="cx">         proc, Return, Origin(),
</span><span class="lines">@@ -3791,11 +3792,11 @@
</span><span class="cx">     patchpoint-&gt;setGenerator(
</span><span class="cx">         [&amp;] (CCallHelpers&amp; jit, const StackmapGenerationParams&amp; params) {
</span><span class="cx">             AllowMacroScratchRegisterUsage allowScratch(jit);
</span><del>-            CHECK(params.reps.size() == 3);
-            CHECK(params.reps[0] == ValueRep::reg(GPRInfo::nonArgGPR0));
-            CHECK(params.reps[1].isGPR());
-            CHECK(params.reps[2].isGPR());
-            add32(jit, params.reps[1].gpr(), params.reps[2].gpr(), GPRInfo::nonArgGPR0);
</del><ins>+            CHECK(params.size() == 3);
+            CHECK(params[0] == ValueRep::reg(GPRInfo::nonArgGPR0));
+            CHECK(params[1].isGPR());
+            CHECK(params[2].isGPR());
+            add32(jit, params[1].gpr(), params[2].gpr(), GPRInfo::nonArgGPR0);
</ins><span class="cx">         });
</span><span class="cx">     root-&gt;appendNew&lt;ControlValue&gt;(proc, Return, Origin(), patchpoint);
</span><span class="cx"> 
</span><span class="lines">@@ -3816,12 +3817,12 @@
</span><span class="cx">     patchpoint-&gt;setGenerator(
</span><span class="cx">         [&amp;] (CCallHelpers&amp; jit, const StackmapGenerationParams&amp; params) {
</span><span class="cx">             AllowMacroScratchRegisterUsage allowScratch(jit);
</span><del>-            CHECK(params.reps.size() == 3);
-            CHECK(params.reps[0] == ValueRep::stack(-static_cast&lt;intptr_t&gt;(proc.frameSize())));
-            CHECK(params.reps[1].isGPR());
-            CHECK(params.reps[2].isGPR());
-            jit.store32(params.reps[1].gpr(), CCallHelpers::Address(CCallHelpers::stackPointerRegister, 0));
-            jit.add32(params.reps[2].gpr(), CCallHelpers::Address(CCallHelpers::stackPointerRegister, 0));
</del><ins>+            CHECK(params.size() == 3);
+            CHECK(params[0] == ValueRep::stack(-static_cast&lt;intptr_t&gt;(proc.frameSize())));
+            CHECK(params[1].isGPR());
+            CHECK(params[2].isGPR());
+            jit.store32(params[1].gpr(), CCallHelpers::Address(CCallHelpers::stackPointerRegister, 0));
+            jit.add32(params[2].gpr(), CCallHelpers::Address(CCallHelpers::stackPointerRegister, 0));
</ins><span class="cx">         });
</span><span class="cx">     root-&gt;appendNew&lt;ControlValue&gt;(proc, Return, Origin(), patchpoint);
</span><span class="cx"> 
</span><span class="lines">@@ -3844,13 +3845,13 @@
</span><span class="cx">     patchpoint-&gt;setGenerator(
</span><span class="cx">         [&amp;] (CCallHelpers&amp; jit, const StackmapGenerationParams&amp; params) {
</span><span class="cx">             AllowMacroScratchRegisterUsage allowScratch(jit);
</span><del>-            CHECK(params.reps.size() == 3);
-            CHECK(params.reps[0].isStack());
-            CHECK(params.reps[1].isGPR());
-            CHECK(params.reps[2].isGPR());
-            add32(jit, params.reps[1].gpr(), params.reps[2].gpr(), GPRInfo::regT0);
</del><ins>+            CHECK(params.size() == 3);
+            CHECK(params[0].isStack());
+            CHECK(params[1].isGPR());
+            CHECK(params[2].isGPR());
+            add32(jit, params[1].gpr(), params[2].gpr(), GPRInfo::regT0);
</ins><span class="cx">             jit.convertInt32ToDouble(GPRInfo::regT0, FPRInfo::fpRegT0);
</span><del>-            jit.storeDouble(FPRInfo::fpRegT0, CCallHelpers::Address(GPRInfo::callFrameRegister, params.reps[0].offsetFromFP()));
</del><ins>+            jit.storeDouble(FPRInfo::fpRegT0, CCallHelpers::Address(GPRInfo::callFrameRegister, params[0].offsetFromFP()));
</ins><span class="cx">         });
</span><span class="cx">     root-&gt;appendNew&lt;ControlValue&gt;(proc, Return, Origin(), patchpoint);
</span><span class="cx"> 
</span><span class="lines">@@ -3866,7 +3867,7 @@
</span><span class="cx">     check-&gt;setGenerator(
</span><span class="cx">         [&amp;] (CCallHelpers&amp; jit, const StackmapGenerationParams&amp; params) {
</span><span class="cx">             AllowMacroScratchRegisterUsage allowScratch(jit);
</span><del>-            CHECK(params.reps.size() == 1);
</del><ins>+            CHECK(params.size() == 1);
</ins><span class="cx"> 
</span><span class="cx">             // This should always work because a function this simple should never have callee
</span><span class="cx">             // saves.
</span><span class="lines">@@ -3898,7 +3899,7 @@
</span><span class="cx">     check-&gt;setGenerator(
</span><span class="cx">         [&amp;] (CCallHelpers&amp; jit, const StackmapGenerationParams&amp; params) {
</span><span class="cx">             AllowMacroScratchRegisterUsage allowScratch(jit);
</span><del>-            CHECK(params.reps.size() == 1);
</del><ins>+            CHECK(params.size() == 1);
</ins><span class="cx"> 
</span><span class="cx">             // This should always work because a function this simple should never have callee
</span><span class="cx">             // saves.
</span><span class="lines">@@ -3944,7 +3945,7 @@
</span><span class="cx">     check-&gt;setGenerator(
</span><span class="cx">         [&amp;] (CCallHelpers&amp; jit, const StackmapGenerationParams&amp; params) {
</span><span class="cx">             AllowMacroScratchRegisterUsage allowScratch(jit);
</span><del>-            CHECK(params.reps.size() == 1);
</del><ins>+            CHECK(params.size() == 1);
</ins><span class="cx"> 
</span><span class="cx">             // This should always work because a function this simple should never have callee
</span><span class="cx">             // saves.
</span><span class="lines">@@ -3984,11 +3985,11 @@
</span><span class="cx">     checkAdd-&gt;setGenerator(
</span><span class="cx">         [&amp;] (CCallHelpers&amp; jit, const StackmapGenerationParams&amp; params) {
</span><span class="cx">             AllowMacroScratchRegisterUsage allowScratch(jit);
</span><del>-            CHECK(params.reps.size() == 4);
-            CHECK(params.reps[2].isGPR());
-            CHECK(params.reps[3].isConstant());
-            CHECK(params.reps[3].value() == 42);
-            jit.convertInt32ToDouble(params.reps[2].gpr(), FPRInfo::fpRegT0);
</del><ins>+            CHECK(params.size() == 4);
+            CHECK(params[2].isGPR());
+            CHECK(params[3].isConstant());
+            CHECK(params[3].value() == 42);
+            jit.convertInt32ToDouble(params[2].gpr(), FPRInfo::fpRegT0);
</ins><span class="cx">             jit.convertInt32ToDouble(CCallHelpers::TrustedImm32(42), FPRInfo::fpRegT1);
</span><span class="cx">             jit.addDouble(FPRInfo::fpRegT1, FPRInfo::fpRegT0);
</span><span class="cx">             jit.emitFunctionEpilogue();
</span><span class="lines">@@ -4020,11 +4021,11 @@
</span><span class="cx">     checkAdd-&gt;setGenerator(
</span><span class="cx">         [&amp;] (CCallHelpers&amp; jit, const StackmapGenerationParams&amp; params) {
</span><span class="cx">             AllowMacroScratchRegisterUsage allowScratch(jit);
</span><del>-            CHECK(params.reps.size() == 4);
-            CHECK(params.reps[2].isGPR());
-            CHECK(params.reps[3].isConstant());
-            CHECK(params.reps[3].value() == 42);
-            jit.convertInt32ToDouble(params.reps[2].gpr(), FPRInfo::fpRegT0);
</del><ins>+            CHECK(params.size() == 4);
+            CHECK(params[2].isGPR());
+            CHECK(params[3].isConstant());
+            CHECK(params[3].value() == 42);
+            jit.convertInt32ToDouble(params[2].gpr(), FPRInfo::fpRegT0);
</ins><span class="cx">             jit.convertInt32ToDouble(CCallHelpers::TrustedImm32(42), FPRInfo::fpRegT1);
</span><span class="cx">             jit.addDouble(FPRInfo::fpRegT1, FPRInfo::fpRegT0);
</span><span class="cx">             jit.emitFunctionEpilogue();
</span><span class="lines">@@ -4056,11 +4057,11 @@
</span><span class="cx">     checkAdd-&gt;setGenerator(
</span><span class="cx">         [&amp;] (CCallHelpers&amp; jit, const StackmapGenerationParams&amp; params) {
</span><span class="cx">             AllowMacroScratchRegisterUsage allowScratch(jit);
</span><del>-            CHECK(params.reps.size() == 4);
-            CHECK(params.reps[2].isGPR());
-            CHECK(params.reps[3].isGPR());
-            jit.convertInt32ToDouble(params.reps[2].gpr(), FPRInfo::fpRegT0);
-            jit.convertInt32ToDouble(params.reps[3].gpr(), FPRInfo::fpRegT1);
</del><ins>+            CHECK(params.size() == 4);
+            CHECK(params[2].isGPR());
+            CHECK(params[3].isGPR());
+            jit.convertInt32ToDouble(params[2].gpr(), FPRInfo::fpRegT0);
+            jit.convertInt32ToDouble(params[3].gpr(), FPRInfo::fpRegT1);
</ins><span class="cx">             jit.addDouble(FPRInfo::fpRegT1, FPRInfo::fpRegT0);
</span><span class="cx">             jit.emitFunctionEpilogue();
</span><span class="cx">             jit.ret();
</span><span class="lines">@@ -4093,11 +4094,11 @@
</span><span class="cx">     checkAdd-&gt;setGenerator(
</span><span class="cx">         [&amp;] (CCallHelpers&amp; jit, const StackmapGenerationParams&amp; params) {
</span><span class="cx">             AllowMacroScratchRegisterUsage allowScratch(jit);
</span><del>-            CHECK(params.reps.size() == 4);
-            CHECK(params.reps[2].isGPR());
-            CHECK(params.reps[3].isGPR());
-            jit.convertInt32ToDouble(params.reps[2].gpr(), FPRInfo::fpRegT0);
-            jit.convertInt32ToDouble(params.reps[3].gpr(), FPRInfo::fpRegT1);
</del><ins>+            CHECK(params.size() == 4);
+            CHECK(params[2].isGPR());
+            CHECK(params[3].isGPR());
+            jit.convertInt32ToDouble(params[2].gpr(), FPRInfo::fpRegT0);
+            jit.convertInt32ToDouble(params[3].gpr(), FPRInfo::fpRegT1);
</ins><span class="cx">             jit.addDouble(FPRInfo::fpRegT1, FPRInfo::fpRegT0);
</span><span class="cx">             jit.emitFunctionEpilogue();
</span><span class="cx">             jit.ret();
</span><span class="lines">@@ -4126,11 +4127,11 @@
</span><span class="cx">     checkAdd-&gt;setGenerator(
</span><span class="cx">         [&amp;] (CCallHelpers&amp; jit, const StackmapGenerationParams&amp; params) {
</span><span class="cx">             AllowMacroScratchRegisterUsage allowScratch(jit);
</span><del>-            CHECK(params.reps.size() == 4);
-            CHECK(params.reps[2].isGPR());
-            CHECK(params.reps[3].isGPR());
-            jit.convertInt64ToDouble(params.reps[2].gpr(), FPRInfo::fpRegT0);
-            jit.convertInt64ToDouble(params.reps[3].gpr(), FPRInfo::fpRegT1);
</del><ins>+            CHECK(params.size() == 4);
+            CHECK(params[2].isGPR());
+            CHECK(params[3].isGPR());
+            jit.convertInt64ToDouble(params[2].gpr(), FPRInfo::fpRegT0);
+            jit.convertInt64ToDouble(params[3].gpr(), FPRInfo::fpRegT1);
</ins><span class="cx">             jit.addDouble(FPRInfo::fpRegT1, FPRInfo::fpRegT0);
</span><span class="cx">             jit.emitFunctionEpilogue();
</span><span class="cx">             jit.ret();
</span><span class="lines">@@ -4200,11 +4201,11 @@
</span><span class="cx">     checkSub-&gt;setGenerator(
</span><span class="cx">         [&amp;] (CCallHelpers&amp; jit, const StackmapGenerationParams&amp; params) {
</span><span class="cx">             AllowMacroScratchRegisterUsage allowScratch(jit);
</span><del>-            CHECK(params.reps.size() == 4);
-            CHECK(params.reps[2].isGPR());
-            CHECK(params.reps[3].isConstant());
-            CHECK(params.reps[3].value() == 42);
-            jit.convertInt32ToDouble(params.reps[2].gpr(), FPRInfo::fpRegT0);
</del><ins>+            CHECK(params.size() == 4);
+            CHECK(params[2].isGPR());
+            CHECK(params[3].isConstant());
+            CHECK(params[3].value() == 42);
+            jit.convertInt32ToDouble(params[2].gpr(), FPRInfo::fpRegT0);
</ins><span class="cx">             jit.convertInt32ToDouble(CCallHelpers::TrustedImm32(42), FPRInfo::fpRegT1);
</span><span class="cx">             jit.subDouble(FPRInfo::fpRegT1, FPRInfo::fpRegT0);
</span><span class="cx">             jit.emitFunctionEpilogue();
</span><span class="lines">@@ -4237,11 +4238,11 @@
</span><span class="cx">     checkSub-&gt;setGenerator(
</span><span class="cx">         [&amp;] (CCallHelpers&amp; jit, const StackmapGenerationParams&amp; params) {
</span><span class="cx">             AllowMacroScratchRegisterUsage allowScratch(jit);
</span><del>-            CHECK(params.reps.size() == 4);
-            CHECK(params.reps[2].isGPR());
-            CHECK(params.reps[3].isConstant());
-            CHECK(params.reps[3].value() == badImm);
-            jit.convertInt32ToDouble(params.reps[2].gpr(), FPRInfo::fpRegT0);
</del><ins>+            CHECK(params.size() == 4);
+            CHECK(params[2].isGPR());
+            CHECK(params[3].isConstant());
+            CHECK(params[3].value() == badImm);
+            jit.convertInt32ToDouble(params[2].gpr(), FPRInfo::fpRegT0);
</ins><span class="cx">             jit.convertInt32ToDouble(CCallHelpers::TrustedImm32(badImm), FPRInfo::fpRegT1);
</span><span class="cx">             jit.subDouble(FPRInfo::fpRegT1, FPRInfo::fpRegT0);
</span><span class="cx">             jit.emitFunctionEpilogue();
</span><span class="lines">@@ -4275,11 +4276,11 @@
</span><span class="cx">     checkSub-&gt;setGenerator(
</span><span class="cx">         [&amp;] (CCallHelpers&amp; jit, const StackmapGenerationParams&amp; params) {
</span><span class="cx">             AllowMacroScratchRegisterUsage allowScratch(jit);
</span><del>-            CHECK(params.reps.size() == 4);
-            CHECK(params.reps[2].isGPR());
-            CHECK(params.reps[3].isGPR());
-            jit.convertInt32ToDouble(params.reps[2].gpr(), FPRInfo::fpRegT0);
-            jit.convertInt32ToDouble(params.reps[3].gpr(), FPRInfo::fpRegT1);
</del><ins>+            CHECK(params.size() == 4);
+            CHECK(params[2].isGPR());
+            CHECK(params[3].isGPR());
+            jit.convertInt32ToDouble(params[2].gpr(), FPRInfo::fpRegT0);
+            jit.convertInt32ToDouble(params[3].gpr(), FPRInfo::fpRegT1);
</ins><span class="cx">             jit.subDouble(FPRInfo::fpRegT1, FPRInfo::fpRegT0);
</span><span class="cx">             jit.emitFunctionEpilogue();
</span><span class="cx">             jit.ret();
</span><span class="lines">@@ -4313,11 +4314,11 @@
</span><span class="cx">     checkSub-&gt;setGenerator(
</span><span class="cx">         [&amp;] (CCallHelpers&amp; jit, const StackmapGenerationParams&amp; params) {
</span><span class="cx">             AllowMacroScratchRegisterUsage allowScratch(jit);
</span><del>-            CHECK(params.reps.size() == 4);
-            CHECK(params.reps[2].isGPR());
-            CHECK(params.reps[3].isGPR());
-            jit.convertInt64ToDouble(params.reps[2].gpr(), FPRInfo::fpRegT0);
-            jit.convertInt64ToDouble(params.reps[3].gpr(), FPRInfo::fpRegT1);
</del><ins>+            CHECK(params.size() == 4);
+            CHECK(params[2].isGPR());
+            CHECK(params[3].isGPR());
+            jit.convertInt64ToDouble(params[2].gpr(), FPRInfo::fpRegT0);
+            jit.convertInt64ToDouble(params[3].gpr(), FPRInfo::fpRegT1);
</ins><span class="cx">             jit.subDouble(FPRInfo::fpRegT1, FPRInfo::fpRegT0);
</span><span class="cx">             jit.emitFunctionEpilogue();
</span><span class="cx">             jit.ret();
</span><span class="lines">@@ -4386,9 +4387,9 @@
</span><span class="cx">     checkNeg-&gt;setGenerator(
</span><span class="cx">         [&amp;] (CCallHelpers&amp; jit, const StackmapGenerationParams&amp; params) {
</span><span class="cx">             AllowMacroScratchRegisterUsage allowScratch(jit);
</span><del>-            CHECK(params.reps.size() == 3);
-            CHECK(params.reps[2].isGPR());
-            jit.convertInt32ToDouble(params.reps[2].gpr(), FPRInfo::fpRegT1);
</del><ins>+            CHECK(params.size() == 3);
+            CHECK(params[2].isGPR());
+            jit.convertInt32ToDouble(params[2].gpr(), FPRInfo::fpRegT1);
</ins><span class="cx">             jit.negateDouble(FPRInfo::fpRegT1, FPRInfo::fpRegT0);
</span><span class="cx">             jit.emitFunctionEpilogue();
</span><span class="cx">             jit.ret();
</span><span class="lines">@@ -4416,9 +4417,9 @@
</span><span class="cx">     checkNeg-&gt;setGenerator(
</span><span class="cx">         [&amp;] (CCallHelpers&amp; jit, const StackmapGenerationParams&amp; params) {
</span><span class="cx">             AllowMacroScratchRegisterUsage allowScratch(jit);
</span><del>-            CHECK(params.reps.size() == 3);
-            CHECK(params.reps[2].isGPR());
-            jit.convertInt64ToDouble(params.reps[2].gpr(), FPRInfo::fpRegT1);
</del><ins>+            CHECK(params.size() == 3);
+            CHECK(params[2].isGPR());
+            jit.convertInt64ToDouble(params[2].gpr(), FPRInfo::fpRegT1);
</ins><span class="cx">             jit.negateDouble(FPRInfo::fpRegT1, FPRInfo::fpRegT0);
</span><span class="cx">             jit.emitFunctionEpilogue();
</span><span class="cx">             jit.ret();
</span><span class="lines">@@ -4451,11 +4452,11 @@
</span><span class="cx">     checkMul-&gt;setGenerator(
</span><span class="cx">         [&amp;] (CCallHelpers&amp; jit, const StackmapGenerationParams&amp; params) {
</span><span class="cx">             AllowMacroScratchRegisterUsage allowScratch(jit);
</span><del>-            CHECK(params.reps.size() == 4);
-            CHECK(params.reps[2].isGPR());
-            CHECK(params.reps[3].isGPR());
-            jit.convertInt32ToDouble(params.reps[2].gpr(), FPRInfo::fpRegT0);
-            jit.convertInt32ToDouble(params.reps[3].gpr(), FPRInfo::fpRegT1);
</del><ins>+            CHECK(params.size() == 4);
+            CHECK(params[2].isGPR());
+            CHECK(params[3].isGPR());
+            jit.convertInt32ToDouble(params[2].gpr(), FPRInfo::fpRegT0);
+            jit.convertInt32ToDouble(params[3].gpr(), FPRInfo::fpRegT1);
</ins><span class="cx">             jit.mulDouble(FPRInfo::fpRegT1, FPRInfo::fpRegT0);
</span><span class="cx">             jit.emitFunctionEpilogue();
</span><span class="cx">             jit.ret();
</span><span class="lines">@@ -4492,11 +4493,11 @@
</span><span class="cx">     checkMul-&gt;setGenerator(
</span><span class="cx">         [&amp;] (CCallHelpers&amp; jit, const StackmapGenerationParams&amp; params) {
</span><span class="cx">             AllowMacroScratchRegisterUsage allowScratch(jit);
</span><del>-            CHECK(params.reps.size() == 4);
-            CHECK(params.reps[2].isGPR());
-            CHECK(params.reps[3].isGPR());
-            jit.convertInt32ToDouble(params.reps[2].gpr(), FPRInfo::fpRegT0);
-            jit.convertInt32ToDouble(params.reps[3].gpr(), FPRInfo::fpRegT1);
</del><ins>+            CHECK(params.size() == 4);
+            CHECK(params[2].isGPR());
+            CHECK(params[3].isGPR());
+            jit.convertInt32ToDouble(params[2].gpr(), FPRInfo::fpRegT0);
+            jit.convertInt32ToDouble(params[3].gpr(), FPRInfo::fpRegT1);
</ins><span class="cx">             jit.mulDouble(FPRInfo::fpRegT1, FPRInfo::fpRegT0);
</span><span class="cx">             jit.emitFunctionEpilogue();
</span><span class="cx">             jit.ret();
</span><span class="lines">@@ -4538,11 +4539,11 @@
</span><span class="cx">     checkMul-&gt;setGenerator(
</span><span class="cx">         [&amp;] (CCallHelpers&amp; jit, const StackmapGenerationParams&amp; params) {
</span><span class="cx">             AllowMacroScratchRegisterUsage allowScratch(jit);
</span><del>-            CHECK(params.reps.size() == 4);
-            CHECK(params.reps[2].isGPR());
-            CHECK(params.reps[3].isConstant());
-            CHECK(params.reps[3].value() == 2);
-            jit.convertInt32ToDouble(params.reps[2].gpr(), FPRInfo::fpRegT0);
</del><ins>+            CHECK(params.size() == 4);
+            CHECK(params[2].isGPR());
+            CHECK(params[3].isConstant());
+            CHECK(params[3].value() == 2);
+            jit.convertInt32ToDouble(params[2].gpr(), FPRInfo::fpRegT0);
</ins><span class="cx">             jit.convertInt32ToDouble(CCallHelpers::TrustedImm32(2), FPRInfo::fpRegT1);
</span><span class="cx">             jit.mulDouble(FPRInfo::fpRegT1, FPRInfo::fpRegT0);
</span><span class="cx">             jit.emitFunctionEpilogue();
</span><span class="lines">@@ -4572,11 +4573,11 @@
</span><span class="cx">     checkMul-&gt;setGenerator(
</span><span class="cx">         [&amp;] (CCallHelpers&amp; jit, const StackmapGenerationParams&amp; params) {
</span><span class="cx">             AllowMacroScratchRegisterUsage allowScratch(jit);
</span><del>-            CHECK(params.reps.size() == 4);
-            CHECK(params.reps[2].isGPR());
-            CHECK(params.reps[3].isGPR());
-            jit.convertInt64ToDouble(params.reps[2].gpr(), FPRInfo::fpRegT0);
-            jit.convertInt64ToDouble(params.reps[3].gpr(), FPRInfo::fpRegT1);
</del><ins>+            CHECK(params.size() == 4);
+            CHECK(params[2].isGPR());
+            CHECK(params[3].isGPR());
+            jit.convertInt64ToDouble(params[2].gpr(), FPRInfo::fpRegT0);
+            jit.convertInt64ToDouble(params[3].gpr(), FPRInfo::fpRegT1);
</ins><span class="cx">             jit.mulDouble(FPRInfo::fpRegT1, FPRInfo::fpRegT0);
</span><span class="cx">             jit.emitFunctionEpilogue();
</span><span class="cx">             jit.ret();
</span><span class="lines">@@ -4675,9 +4676,9 @@
</span><span class="cx">         patchpoint-&gt;setGenerator(
</span><span class="cx">             [&amp;] (CCallHelpers&amp; jit, const StackmapGenerationParams&amp; params) {
</span><span class="cx">                 AllowMacroScratchRegisterUsage allowScratch(jit);
</span><del>-                CHECK(params.reps.size() == 1);
-                CHECK(params.reps[0].isGPR());
-                jit.move(CCallHelpers::TrustedImm32(1), params.reps[0].gpr());
</del><ins>+                CHECK(params.size() == 1);
+                CHECK(params[0].isGPR());
+                jit.move(CCallHelpers::TrustedImm32(1), params[0].gpr());
</ins><span class="cx">             });
</span><span class="cx">         thenCase-&gt;appendNew&lt;ControlValue&gt;(proc, Return, Origin(), patchpoint);
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLExceptionHandlerManagercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ftl/FTLExceptionHandlerManager.cpp (193639 => 193640)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLExceptionHandlerManager.cpp        2015-12-07 18:54:33 UTC (rev 193639)
+++ trunk/Source/JavaScriptCore/ftl/FTLExceptionHandlerManager.cpp        2015-12-07 19:17:56 UTC (rev 193640)
</span><span class="lines">@@ -26,7 +26,7 @@
</span><span class="cx"> #include &quot;config.h&quot;
</span><span class="cx"> #include &quot;FTLExceptionHandlerManager.h&quot;
</span><span class="cx"> 
</span><del>-#if ENABLE(FTL_JIT)
</del><ins>+#if ENABLE(FTL_JIT) &amp;&amp; !FTL_USES_B3
</ins><span class="cx"> 
</span><span class="cx"> #include &quot;FTLState.h&quot;
</span><span class="cx"> 
</span><span class="lines">@@ -164,4 +164,4 @@
</span><span class="cx"> 
</span><span class="cx"> } } // namespace JSC::FTL
</span><span class="cx"> 
</span><del>-#endif // ENABLE(FTL_JIT)
</del><ins>+#endif // ENABLE(FTL_JIT) &amp;&amp; !FTL_USES_B3
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLExceptionHandlerManagerh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ftl/FTLExceptionHandlerManager.h (193639 => 193640)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLExceptionHandlerManager.h        2015-12-07 18:54:33 UTC (rev 193639)
+++ trunk/Source/JavaScriptCore/ftl/FTLExceptionHandlerManager.h        2015-12-07 19:17:56 UTC (rev 193640)
</span><span class="lines">@@ -26,8 +26,10 @@
</span><span class="cx"> #ifndef FTLExceptionHandlerManager_h
</span><span class="cx"> #define FTLExceptionHandlerManager_h
</span><span class="cx"> 
</span><del>-#if ENABLE(FTL_JIT)
</del><ins>+#include &quot;DFGCommon.h&quot;
</ins><span class="cx"> 
</span><ins>+#if ENABLE(FTL_JIT) &amp;&amp; !FTL_USES_B3
+
</ins><span class="cx"> #include &quot;CallFrame.h&quot;
</span><span class="cx"> #include &quot;FTLJSCall.h&quot;
</span><span class="cx"> #include &quot;FTLJSCallVarargs.h&quot;
</span><span class="lines">@@ -83,6 +85,6 @@
</span><span class="cx"> 
</span><span class="cx"> } } // namespace JSC::FTL
</span><span class="cx"> 
</span><del>-#endif // ENABLE(FTL_JIT)
</del><ins>+#endif // ENABLE(FTL_JIT) &amp;&amp; !FTL_USES_B3
</ins><span class="cx"> 
</span><span class="cx"> #endif // FTLExceptionHandlerManager_h
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLJSCallcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ftl/FTLJSCall.cpp (193639 => 193640)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLJSCall.cpp        2015-12-07 18:54:33 UTC (rev 193639)
+++ trunk/Source/JavaScriptCore/ftl/FTLJSCall.cpp        2015-12-07 19:17:56 UTC (rev 193640)
</span><span class="lines">@@ -26,7 +26,7 @@
</span><span class="cx"> #include &quot;config.h&quot;
</span><span class="cx"> #include &quot;FTLJSCall.h&quot;
</span><span class="cx"> 
</span><del>-#if ENABLE(FTL_JIT)
</del><ins>+#if ENABLE(FTL_JIT) &amp;&amp; !FTL_USES_B3
</ins><span class="cx"> 
</span><span class="cx"> #include &quot;DFGNode.h&quot;
</span><span class="cx"> #include &quot;FTLState.h&quot;
</span><span class="lines">@@ -63,5 +63,5 @@
</span><span class="cx"> 
</span><span class="cx"> } } // namespace JSC::FTL
</span><span class="cx"> 
</span><del>-#endif // ENABLE(FTL_JIT)
</del><ins>+#endif // ENABLE(FTL_JIT) &amp;&amp; !FTL_USES_B3
</ins><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLJSCallh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ftl/FTLJSCall.h (193639 => 193640)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLJSCall.h        2015-12-07 18:54:33 UTC (rev 193639)
+++ trunk/Source/JavaScriptCore/ftl/FTLJSCall.h        2015-12-07 19:17:56 UTC (rev 193640)
</span><span class="lines">@@ -26,8 +26,10 @@
</span><span class="cx"> #ifndef FTLJSCall_h
</span><span class="cx"> #define FTLJSCall_h
</span><span class="cx"> 
</span><del>-#if ENABLE(FTL_JIT)
</del><ins>+#include &quot;DFGCommon.h&quot;
</ins><span class="cx"> 
</span><ins>+#if ENABLE(FTL_JIT) &amp;&amp; !FTL_USES_B3
+
</ins><span class="cx"> #include &quot;FTLJSCallBase.h&quot;
</span><span class="cx"> 
</span><span class="cx"> namespace JSC {
</span><span class="lines">@@ -61,7 +63,7 @@
</span><span class="cx"> 
</span><span class="cx"> } } // namespace JSC::FTL
</span><span class="cx"> 
</span><del>-#endif // ENABLE(FTL_JIT)
</del><ins>+#endif // ENABLE(FTL_JIT) &amp;&amp; !FTL_USES_B3
</ins><span class="cx"> 
</span><span class="cx"> #endif // FTLJSCall_h
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLJSCallBasecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ftl/FTLJSCallBase.cpp (193639 => 193640)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLJSCallBase.cpp        2015-12-07 18:54:33 UTC (rev 193639)
+++ trunk/Source/JavaScriptCore/ftl/FTLJSCallBase.cpp        2015-12-07 19:17:56 UTC (rev 193640)
</span><span class="lines">@@ -26,7 +26,7 @@
</span><span class="cx"> #include &quot;config.h&quot;
</span><span class="cx"> #include &quot;FTLJSCallBase.h&quot;
</span><span class="cx"> 
</span><del>-#if ENABLE(FTL_JIT)
</del><ins>+#if ENABLE(FTL_JIT) &amp;&amp; !FTL_USES_B3
</ins><span class="cx"> 
</span><span class="cx"> #include &quot;DFGNode.h&quot;
</span><span class="cx"> #include &quot;FTLState.h&quot;
</span><span class="lines">@@ -55,12 +55,8 @@
</span><span class="cx"> {
</span><span class="cx">     RELEASE_ASSERT(!!m_callSiteIndex);
</span><span class="cx"> 
</span><del>-#if FTL_USES_B3
-    UNUSED_PARAM(osrExitFromGenericUnwindStackSpillSlot);
-#else // FTL_USES_B3
</del><span class="cx">     if (m_correspondingGenericUnwindOSRExit)
</span><span class="cx">         m_correspondingGenericUnwindOSRExit-&gt;spillRegistersToSpillSlot(jit, osrExitFromGenericUnwindStackSpillSlot);
</span><del>-#endif // FTL_USES_B3
</del><span class="cx"> 
</span><span class="cx">     jit.store32(CCallHelpers::TrustedImm32(m_callSiteIndex.bits()), CCallHelpers::tagFor(static_cast&lt;VirtualRegister&gt;(JSStack::ArgumentCount)));
</span><span class="cx"> 
</span><span class="lines">@@ -107,5 +103,5 @@
</span><span class="cx"> 
</span><span class="cx"> } } // namespace JSC::FTL
</span><span class="cx"> 
</span><del>-#endif // ENABLE(FTL_JIT)
</del><ins>+#endif // ENABLE(FTL_JIT) &amp;&amp; !FTL_USES_B3
</ins><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLJSCallBaseh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ftl/FTLJSCallBase.h (193639 => 193640)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLJSCallBase.h        2015-12-07 18:54:33 UTC (rev 193639)
+++ trunk/Source/JavaScriptCore/ftl/FTLJSCallBase.h        2015-12-07 19:17:56 UTC (rev 193640)
</span><span class="lines">@@ -26,8 +26,10 @@
</span><span class="cx"> #ifndef FTLJSCallBase_h
</span><span class="cx"> #define FTLJSCallBase_h
</span><span class="cx"> 
</span><del>-#if ENABLE(FTL_JIT)
</del><ins>+#include &quot;DFGCommon.h&quot;
</ins><span class="cx"> 
</span><ins>+#if ENABLE(FTL_JIT) &amp;&amp; !FTL_USES_B3
+
</ins><span class="cx"> #include &quot;CCallHelpers.h&quot;
</span><span class="cx"> #include &quot;CallLinkInfo.h&quot;
</span><span class="cx"> #include &quot;CodeOrigin.h&quot;
</span><span class="lines">@@ -73,7 +75,7 @@
</span><span class="cx"> 
</span><span class="cx"> } } // namespace JSC::FTL
</span><span class="cx"> 
</span><del>-#endif // ENABLE(FTL_JIT)
</del><ins>+#endif // ENABLE(FTL_JIT) &amp;&amp; !FTL_USES_B3
</ins><span class="cx"> 
</span><span class="cx"> #endif // FTLJSCallBase_h
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLJSCallVarargscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ftl/FTLJSCallVarargs.cpp (193639 => 193640)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLJSCallVarargs.cpp        2015-12-07 18:54:33 UTC (rev 193639)
+++ trunk/Source/JavaScriptCore/ftl/FTLJSCallVarargs.cpp        2015-12-07 19:17:56 UTC (rev 193640)
</span><span class="lines">@@ -26,7 +26,7 @@
</span><span class="cx"> #include &quot;config.h&quot;
</span><span class="cx"> #include &quot;FTLJSCallVarargs.h&quot;
</span><span class="cx"> 
</span><del>-#if ENABLE(FTL_JIT)
</del><ins>+#if ENABLE(FTL_JIT) &amp;&amp; !FTL_USES_B3
</ins><span class="cx"> 
</span><span class="cx"> #include &quot;DFGNode.h&quot;
</span><span class="cx"> #include &quot;DFGOperations.h&quot;
</span><span class="lines">@@ -225,5 +225,5 @@
</span><span class="cx"> 
</span><span class="cx"> } } // namespace JSC::FTL
</span><span class="cx"> 
</span><del>-#endif // ENABLE(FTL_JIT)
</del><ins>+#endif // ENABLE(FTL_JIT) &amp;&amp; !FTL_USES_B3
</ins><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLJSCallVarargsh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ftl/FTLJSCallVarargs.h (193639 => 193640)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLJSCallVarargs.h        2015-12-07 18:54:33 UTC (rev 193639)
+++ trunk/Source/JavaScriptCore/ftl/FTLJSCallVarargs.h        2015-12-07 19:17:56 UTC (rev 193640)
</span><span class="lines">@@ -26,8 +26,10 @@
</span><span class="cx"> #ifndef FTLJSCallVarargs_h
</span><span class="cx"> #define FTLJSCallVarargs_h
</span><span class="cx"> 
</span><del>-#if ENABLE(FTL_JIT)
</del><ins>+#include &quot;DFGCommon.h&quot;
</ins><span class="cx"> 
</span><ins>+#if ENABLE(FTL_JIT) &amp;&amp; !FTL_USES_B3
+
</ins><span class="cx"> #include &quot;FTLJSCallBase.h&quot;
</span><span class="cx"> 
</span><span class="cx"> namespace JSC {
</span><span class="lines">@@ -75,7 +77,7 @@
</span><span class="cx"> 
</span><span class="cx"> } } // namespace JSC::FTL
</span><span class="cx"> 
</span><del>-#endif // ENABLE(FTL_JIT)
</del><ins>+#endif // ENABLE(FTL_JIT) &amp;&amp; !FTL_USES_B3
</ins><span class="cx"> 
</span><span class="cx"> #endif // FTLJSCallVarargs_h
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLJSTailCallcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ftl/FTLJSTailCall.cpp (193639 => 193640)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLJSTailCall.cpp        2015-12-07 18:54:33 UTC (rev 193639)
+++ trunk/Source/JavaScriptCore/ftl/FTLJSTailCall.cpp        2015-12-07 19:17:56 UTC (rev 193640)
</span><span class="lines">@@ -26,7 +26,7 @@
</span><span class="cx"> #include &quot;config.h&quot;
</span><span class="cx"> #include &quot;FTLJSTailCall.h&quot;
</span><span class="cx"> 
</span><del>-#if ENABLE(FTL_JIT)
</del><ins>+#if ENABLE(FTL_JIT) &amp;&amp; !FTL_USES_B3
</ins><span class="cx"> 
</span><span class="cx"> #include &quot;CallFrameShuffler.h&quot;
</span><span class="cx"> #include &quot;DFGNode.h&quot;
</span><span class="lines">@@ -38,27 +38,8 @@
</span><span class="cx"> 
</span><span class="cx"> namespace JSC { namespace FTL {
</span><span class="cx"> 
</span><del>-using namespace B3;
</del><span class="cx"> using namespace DFG;
</span><span class="cx"> 
</span><del>-#if FTL_USES_B3
-
-JSTailCall::JSTailCall(PatchpointValue* patchpoint, Node* node, const Vector&lt;ExitValue&gt;&amp; arguments)
-    : JSCallBase(CallLinkInfo::TailCall, node-&gt;origin.semantic, node-&gt;origin.semantic)
-    , m_patchpoint(patchpoint)
-    , m_arguments(arguments)
-    , m_instructionOffset(0)
-{
-    UNREACHABLE_FOR_PLATFORM();
-}
-
-void JSTailCall::emit(JITCode&amp;, CCallHelpers&amp;)
-{
-    UNREACHABLE_FOR_PLATFORM();
-}
-
-#else // FTL_USES_B3
-
</del><span class="cx"> namespace {
</span><span class="cx"> 
</span><span class="cx"> FTL::Location getRegisterWithAddend(const ExitValue&amp; value, StackMaps::Record&amp; record, StackMaps&amp; stackmaps)
</span><span class="lines">@@ -342,8 +323,6 @@
</span><span class="cx">     m_callLinkInfo-&gt;setUpCall(m_type, m_semanticeOrigin, calleeGPR);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-#endif // FTL_USES_B3
-
</del><span class="cx"> } } // namespace JSC::FTL
</span><span class="cx"> 
</span><del>-#endif // ENABLE(FTL_JIT)
</del><ins>+#endif // ENABLE(FTL_JIT) &amp;&amp; !FTL_USES_B3
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLJSTailCallh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ftl/FTLJSTailCall.h (193639 => 193640)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLJSTailCall.h        2015-12-07 18:54:33 UTC (rev 193639)
+++ trunk/Source/JavaScriptCore/ftl/FTLJSTailCall.h        2015-12-07 19:17:56 UTC (rev 193640)
</span><span class="lines">@@ -26,8 +26,10 @@
</span><span class="cx"> #ifndef FTLJSTailCall_h
</span><span class="cx"> #define FTLJSTailCall_h
</span><span class="cx"> 
</span><del>-#if ENABLE(FTL_JIT)
</del><ins>+#include &quot;DFGCommon.h&quot;
</ins><span class="cx"> 
</span><ins>+#if ENABLE(FTL_JIT) &amp;&amp; !FTL_USES_B3
+
</ins><span class="cx"> #include &quot;B3PatchpointValue.h&quot;
</span><span class="cx"> #include &quot;DFGCommon.h&quot;
</span><span class="cx"> #include &quot;FTLExitValue.h&quot;
</span><span class="lines">@@ -45,20 +47,12 @@
</span><span class="cx"> class JSTailCall : public JSCallBase {
</span><span class="cx"> public:
</span><span class="cx">     JSTailCall(
</span><del>-#if FTL_USES_B3
-        B3::PatchpointValue*,
-#else // FTL_USES_B3
</del><span class="cx">         unsigned stackmapID,
</span><del>-#endif // FTL_USES_B3
</del><span class="cx">         DFG::Node*, const Vector&lt;ExitValue&gt;&amp; arguments);
</span><span class="cx"> 
</span><span class="cx">     void emit(JITCode&amp;, CCallHelpers&amp;);
</span><span class="cx"> 
</span><del>-#if FTL_USES_B3
-    B3::PatchpointValue* patchpoint() const { return m_patchpoint; }
-#else // FTL_USES_B3
</del><span class="cx">     unsigned stackmapID() const { return m_stackmapID; }
</span><del>-#endif // FTL_USES_B3
</del><span class="cx"> 
</span><span class="cx">     unsigned estimatedSize() const { return m_estimatedSize; }
</span><span class="cx"> 
</span><span class="lines">@@ -70,11 +64,7 @@
</span><span class="cx">     }
</span><span class="cx">     
</span><span class="cx"> private:
</span><del>-#if FTL_USES_B3
-    B3::PatchpointValue* m_patchpoint;
-#else // FTL_USES_B3
</del><span class="cx">     unsigned m_stackmapID;
</span><del>-#endif // FTL_USES_B3
</del><span class="cx">     Vector&lt;ExitValue&gt; m_arguments;
</span><span class="cx">     unsigned m_estimatedSize;
</span><span class="cx"> 
</span><span class="lines">@@ -84,7 +74,7 @@
</span><span class="cx"> 
</span><span class="cx"> } } // namespace JSC::FTL
</span><span class="cx"> 
</span><del>-#endif // ENABLE(FTL_JIT)
</del><ins>+#endif // ENABLE(FTL_JIT) &amp;&amp; !FTL_USES_B3
</ins><span class="cx"> 
</span><span class="cx"> #endif // FTLJSTailCall_h
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLLowerDFGToLLVMcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp (193639 => 193640)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp        2015-12-07 18:54:33 UTC (rev 193639)
+++ trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp        2015-12-07 19:17:56 UTC (rev 193640)
</span><span class="lines">@@ -30,6 +30,7 @@
</span><span class="cx"> 
</span><span class="cx"> #include &quot;AirGenerationContext.h&quot;
</span><span class="cx"> #include &quot;AllowMacroScratchRegisterUsage.h&quot;
</span><ins>+#include &quot;B3StackmapGenerationParams.h&quot;
</ins><span class="cx"> #include &quot;CodeBlockWithJITType.h&quot;
</span><span class="cx"> #include &quot;DFGAbstractInterpreterInlines.h&quot;
</span><span class="cx"> #include &quot;DFGDominators.h&quot;
</span><span class="lines">@@ -4828,14 +4829,105 @@
</span><span class="cx"> 
</span><span class="cx">     void compileCallOrConstruct()
</span><span class="cx">     {
</span><ins>+        Node* node = m_node;
+        unsigned numArgs = node-&gt;numChildren() - 1;
+
+        LValue jsCallee = lowJSValue(m_graph.varArgChild(node, 0));
+
</ins><span class="cx"> #if FTL_USES_B3
</span><del>-        if (verboseCompilationEnabled() || !verboseCompilationEnabled())
-            CRASH();
-#else
-        int numArgs = m_node-&gt;numChildren() - 1;
</del><ins>+        unsigned frameSize = JSStack::CallFrameHeaderSize + numArgs;
+        unsigned alignedFrameSize = WTF::roundUpToMultipleOf(stackAlignmentRegisters(), frameSize);
</ins><span class="cx"> 
</span><del>-        LValue jsCallee = lowJSValue(m_graph.varArgChild(m_node, 0));
</del><ins>+        // JS-&gt;JS calling convention requires that the caller allows this much space on top of stack to
+        // get trashed by the callee, even if not all of that space is used to pass arguments. We tell
+        // B3 this explicitly for two reasons:
+        //
+        // - We will only pass frameSize worth of stuff.
+        // - The trashed stack guarantee is logically separate from the act of passing arguments, so we
+        //   shouldn't rely on Air to infer the trashed stack property based on the arguments it ends
+        //   up seeing.
+        m_proc.requestCallArgAreaSize(alignedFrameSize);
</ins><span class="cx"> 
</span><ins>+        // Collect the arguments, since this can generate code and we want to generate it before we emit
+        // the call.
+        Vector&lt;ConstrainedValue&gt; arguments;
+
+        // Make sure that the callee goes into GPR0 because that's where the slow path thunks expect the
+        // callee to be.
+        arguments.append(ConstrainedValue(jsCallee, ValueRep::reg(GPRInfo::regT0)));
+
+        auto addArgument = [&amp;] (LValue value, VirtualRegister reg, int offset) {
+            intptr_t offsetFromSP =
+                (reg.offset() - JSStack::CallerFrameAndPCSize) * sizeof(EncodedJSValue) + offset;
+            arguments.append(ConstrainedValue(value, ValueRep::stackArgument(offsetFromSP)));
+        };
+
+        addArgument(jsCallee, VirtualRegister(JSStack::Callee), 0);
+        addArgument(m_out.constInt32(numArgs), VirtualRegister(JSStack::ArgumentCount), PayloadOffset);
+        for (unsigned i = 0; i &lt; numArgs; ++i)
+            addArgument(lowJSValue(m_graph.varArgChild(node, 1 + i)), virtualRegisterForArgument(i), 0);
+
+        PatchpointValue* patchpoint = m_out.patchpoint(Int64);
+        patchpoint-&gt;appendVector(arguments);
+        patchpoint-&gt;clobber(RegisterSet::macroScratchRegisters());
+        patchpoint-&gt;clobberLate(RegisterSet::volatileRegistersForJSCall());
+        patchpoint-&gt;resultConstraint = ValueRep::reg(GPRInfo::returnValueGPR);
+
+        CodeOrigin codeOrigin = codeOriginDescriptionOfCallSite();
+        State* state = &amp;m_ftlState;
+        patchpoint-&gt;setGenerator(
+            [=] (CCallHelpers&amp; jit, const StackmapGenerationParams&amp; params) {
+                AllowMacroScratchRegisterUsage allowScratch(jit);
+                CallSiteIndex callSiteIndex = state-&gt;jitCode-&gt;common.addUniqueCallSiteIndex(codeOrigin);
+
+                // FIXME: If we were handling exceptions, then at this point we would ask our descriptor
+                // to prepare and then we would modify the OSRExit data structure inside the
+                // OSRExitHandle to link it up to this call.
+                // https://bugs.webkit.org/show_bug.cgi?id=151686
+
+                jit.store32(
+                    CCallHelpers::TrustedImm32(callSiteIndex.bits()),
+                    CCallHelpers::tagFor(VirtualRegister(JSStack::ArgumentCount)));
+
+                CallLinkInfo* callLinkInfo = jit.codeBlock()-&gt;addCallLinkInfo();
+
+                CCallHelpers::DataLabelPtr targetToCheck;
+                CCallHelpers::Jump slowPath = jit.branchPtrWithPatch(
+                    CCallHelpers::NotEqual, GPRInfo::regT0, targetToCheck,
+                    CCallHelpers::TrustedImmPtr(0));
+
+                CCallHelpers::Call fastCall = jit.nearCall();
+                CCallHelpers::Jump done = jit.jump();
+
+                slowPath.link(&amp;jit);
+
+                jit.move(CCallHelpers::TrustedImmPtr(callLinkInfo), GPRInfo::regT2);
+                CCallHelpers::Call slowCall = jit.nearCall();
+                done.link(&amp;jit);
+
+                callLinkInfo-&gt;setUpCall(
+                    node-&gt;op() == Construct ? CallLinkInfo::Construct : CallLinkInfo::Call,
+                    node-&gt;origin.semantic, GPRInfo::regT0);
+
+                jit.addPtr(
+                    CCallHelpers::TrustedImm32(-params.proc().frameSize()),
+                    GPRInfo::callFrameRegister, CCallHelpers::stackPointerRegister);
+
+                jit.addLinkTask(
+                    [=] (LinkBuffer&amp; linkBuffer) {
+                        MacroAssemblerCodePtr linkCall =
+                            linkBuffer.vm().getCTIStub(linkCallThunkGenerator).code();
+                        linkBuffer.link(slowCall, FunctionPtr(linkCall.executableAddress()));
+
+                        callLinkInfo-&gt;setCallLocations(
+                            linkBuffer.locationOfNearCall(slowCall),
+                            linkBuffer.locationOf(targetToCheck),
+                            linkBuffer.locationOfNearCall(fastCall));
+                    });
+            });
+
+        setJSValue(patchpoint);
+#else
</ins><span class="cx">         unsigned stackmapID = m_stackmapIDs++;
</span><span class="cx"> 
</span><span class="cx">         unsigned frameSize = JSStack::CallFrameHeaderSize + numArgs;
</span><span class="lines">@@ -4848,8 +4940,8 @@
</span><span class="cx">         arguments.append(getUndef(m_out.int64)); // code block
</span><span class="cx">         arguments.append(jsCallee); // callee -&gt; stack
</span><span class="cx">         arguments.append(m_out.constInt64(numArgs)); // argument count and zeros for the tag
</span><del>-        for (int i = 0; i &lt; numArgs; ++i)
-            arguments.append(lowJSValue(m_graph.varArgChild(m_node, 1 + i)));
</del><ins>+        for (unsigned i = 0; i &lt; numArgs; ++i)
+            arguments.append(lowJSValue(m_graph.varArgChild(node, 1 + i)));
</ins><span class="cx">         for (unsigned i = 0; i &lt; padding; ++i)
</span><span class="cx">             arguments.append(getUndef(m_out.int64));
</span><span class="cx"> 
</span><span class="lines">@@ -4863,7 +4955,7 @@
</span><span class="cx">         LValue call = m_out.call(m_out.int64, m_out.patchpointInt64Intrinsic(), arguments);
</span><span class="cx">         setInstructionCallingConvention(call, LLVMWebKitJSCallConv);
</span><span class="cx">         
</span><del>-        m_ftlState.jsCalls.append(JSCall(stackmapID, m_node, codeOriginDescriptionOfCallSite()));
</del><ins>+        m_ftlState.jsCalls.append(JSCall(stackmapID, node, codeOriginDescriptionOfCallSite()));
</ins><span class="cx">         
</span><span class="cx">         setJSValue(call);
</span><span class="cx"> #endif
</span><span class="lines">@@ -5322,18 +5414,63 @@
</span><span class="cx">     
</span><span class="cx">     void compileInvalidationPoint()
</span><span class="cx">     {
</span><del>-#if FTL_USES_B3
-        UNREACHABLE_FOR_PLATFORM();
-#else // FTL_USES_B3
</del><span class="cx">         if (verboseCompilationEnabled())
</span><span class="cx">             dataLog(&quot;    Invalidation point with availability: &quot;, availabilityMap(), &quot;\n&quot;);
</span><span class="cx"> 
</span><span class="cx">         DFG_ASSERT(m_graph, m_node, m_origin.exitOK);
</span><span class="cx">         
</span><ins>+#if FTL_USES_B3
+        B3::PatchpointValue* patchpoint = m_out.patchpoint(Void);
+        OSRExitDescriptor* descriptor = appendOSRExitDescriptor(noValue(), nullptr);
+        NodeOrigin origin = m_origin;
+        patchpoint-&gt;appendColdAnys(buildExitArguments(descriptor, origin.forExit, noValue()));
+        
+        State* state = &amp;m_ftlState;
</ins><span class="cx"> 
</span><ins>+        patchpoint-&gt;setGenerator(
+            [=] (CCallHelpers&amp; jit, const B3::StackmapGenerationParams&amp; params) {
+                // The MacroAssembler knows more about this than B3 does. The watchpointLabel() method
+                // will ensure that this is followed by a nop shadow but only when this is actually
+                // necessary.
+                CCallHelpers::Label label = jit.watchpointLabel();
+
+                RefPtr&lt;OSRExitHandle&gt; handle = descriptor-&gt;emitOSRExitLater(
+                    *state, UncountableInvalidation, origin, params);
+
+                RefPtr&lt;JITCode&gt; jitCode = state-&gt;jitCode.get();
+
+                jit.addLinkTask(
+                    [=] (LinkBuffer&amp; linkBuffer) {
+                        JumpReplacement jumpReplacement(
+                            linkBuffer.locationOf(label),
+                            linkBuffer.locationOf(handle-&gt;label));
+                        jitCode-&gt;common.jumpReplacements.append(jumpReplacement);
+                    });
+            });
+
+        // Set some obvious things.
+        patchpoint-&gt;effects.terminal = false;
+        patchpoint-&gt;effects.writesSSAState = false;
+        patchpoint-&gt;effects.readsSSAState = false;
+        
+        // This is how we tell B3 about the possibility of jump replacement.
+        patchpoint-&gt;effects.exitsSideways = true;
+        
+        // It's not possible for some prior branch to determine the safety of this operation. It's always
+        // fine to execute this on some path that wouldn't have originally executed it before
+        // optimization.
+        patchpoint-&gt;effects.controlDependent = false;
+
+        // If this falls through then it won't write anything.
+        patchpoint-&gt;effects.writes = HeapRange();
+
+        // When this abruptly terminates, it could read any heap location.
+        patchpoint-&gt;effects.reads = HeapRange::top();
+#else // FTL_USES_B3
+
</ins><span class="cx">         OSRExitDescriptor* exitDescriptor = appendOSRExitDescriptor(UncountableInvalidation, ExceptionType::None, noValue(), nullptr, m_origin);
</span><span class="cx">         
</span><del>-        StackmapArgumentList arguments = buildExitArguments(exitDescriptor, m_ftlState.osrExitDescriptorImpls.last(), FormattedValue());
</del><ins>+        StackmapArgumentList arguments = buildExitArguments(exitDescriptor, m_ftlState.osrExitDescriptorImpls.last().m_codeOrigin, FormattedValue());
</ins><span class="cx">         callStackmap(exitDescriptor, arguments);
</span><span class="cx">         
</span><span class="cx">         exitDescriptor-&gt;m_isInvalidationPoint = true;
</span><span class="lines">@@ -7901,7 +8038,7 @@
</span><span class="cx">         result-&gt;setGenerator(
</span><span class="cx">             [=] (CCallHelpers&amp; jit, const StackmapGenerationParams&amp; params) {
</span><span class="cx">                 Vector&lt;Location&gt; locations;
</span><del>-                for (const B3::ValueRep&amp; rep : params.reps)
</del><ins>+                for (const B3::ValueRep&amp; rep : params)
</ins><span class="cx">                     locations.append(Location::forValueRep(rep));
</span><span class="cx"> 
</span><span class="cx">                 RefPtr&lt;LazySlowPath::Generator&gt; generator = functor(locations);
</span><span class="lines">@@ -7909,56 +8046,55 @@
</span><span class="cx">                 CCallHelpers::PatchableJump patchableJump = jit.patchableJump();
</span><span class="cx">                 CCallHelpers::Label done = jit.label();
</span><span class="cx"> 
</span><del>-                RegisterSet usedRegisters = params.usedRegisters;
</del><ins>+                RegisterSet usedRegisters = params.usedRegisters();
</ins><span class="cx"> 
</span><span class="cx">                 // FIXME: As part of handling exceptions, we need to create a concrete OSRExit here.
</span><span class="cx">                 // Doing so should automagically register late paths that emit exit thunks.
</span><del>-                
-                params.context-&gt;latePaths.append(
-                    createSharedTask&lt;Air::GenerationContext::LatePathFunction&gt;(
-                        [=] (CCallHelpers&amp; jit, Air::GenerationContext&amp;) {
-                            AllowMacroScratchRegisterUsage allowScratch(jit);
-                            patchableJump.m_jump.link(&amp;jit);
-                            unsigned index = state-&gt;jitCode-&gt;lazySlowPaths.size();
-                            state-&gt;jitCode-&gt;lazySlowPaths.append(nullptr);
-                            jit.pushToSaveImmediateWithoutTouchingRegisters(
-                                CCallHelpers::TrustedImm32(index));
-                            CCallHelpers::Jump generatorJump = jit.jump();
</del><span class="cx"> 
</span><del>-                            // Note that so long as we're here, we don't really know if our late path
-                            // runs before or after any other late paths that we might depend on, like
-                            // the exception thunk.
</del><ins>+                params.addLatePath(
+                    [=] (CCallHelpers&amp; jit) {
+                        AllowMacroScratchRegisterUsage allowScratch(jit);
+                        patchableJump.m_jump.link(&amp;jit);
+                        unsigned index = state-&gt;jitCode-&gt;lazySlowPaths.size();
+                        state-&gt;jitCode-&gt;lazySlowPaths.append(nullptr);
+                        jit.pushToSaveImmediateWithoutTouchingRegisters(
+                            CCallHelpers::TrustedImm32(index));
+                        CCallHelpers::Jump generatorJump = jit.jump();
</ins><span class="cx"> 
</span><del>-                            RefPtr&lt;JITCode&gt; jitCode = state-&gt;jitCode;
-                            VM* vm = &amp;state-&gt;graph.m_vm;
</del><ins>+                        // Note that so long as we're here, we don't really know if our late path
+                        // runs before or after any other late paths that we might depend on, like
+                        // the exception thunk.
</ins><span class="cx"> 
</span><del>-                            jit.addLinkTask(
-                                [=] (LinkBuffer&amp; linkBuffer) {
-                                    linkBuffer.link(
-                                        generatorJump, CodeLocationLabel(
-                                            vm-&gt;getCTIStub(
-                                                lazySlowPathGenerationThunkGenerator).code()));
</del><ins>+                        RefPtr&lt;JITCode&gt; jitCode = state-&gt;jitCode;
+                        VM* vm = &amp;state-&gt;graph.m_vm;
+
+                        jit.addLinkTask(
+                            [=] (LinkBuffer&amp; linkBuffer) {
+                                linkBuffer.link(
+                                    generatorJump, CodeLocationLabel(
+                                        vm-&gt;getCTIStub(
+                                            lazySlowPathGenerationThunkGenerator).code()));
</ins><span class="cx">                                     
</span><del>-                                    CodeLocationJump linkedPatchableJump = CodeLocationJump(
-                                        linkBuffer.locationOf(patchableJump));
-                                    CodeLocationLabel linkedDone = linkBuffer.locationOf(done);
</del><ins>+                                CodeLocationJump linkedPatchableJump = CodeLocationJump(
+                                    linkBuffer.locationOf(patchableJump));
+                                CodeLocationLabel linkedDone = linkBuffer.locationOf(done);
</ins><span class="cx"> 
</span><del>-                                    // FIXME: Need a story for exceptions in FTL-B3. That basically means
-                                    // doing a lookup of the exception entrypoint here. We will have an
-                                    // OSR exit data structure of some sort.
-                                    // https://bugs.webkit.org/show_bug.cgi?id=151686
-                                    CodeLocationLabel exceptionTarget;
-                                    CallSiteIndex callSiteIndex =
-                                        jitCode-&gt;common.addUniqueCallSiteIndex(origin);
</del><ins>+                                // FIXME: Need a story for exceptions in FTL-B3. That basically means
+                                // doing a lookup of the exception entrypoint here. We will have an
+                                // OSR exit data structure of some sort.
+                                // https://bugs.webkit.org/show_bug.cgi?id=151686
+                                CodeLocationLabel exceptionTarget;
+                                CallSiteIndex callSiteIndex =
+                                    jitCode-&gt;common.addUniqueCallSiteIndex(origin);
</ins><span class="cx">                                     
</span><del>-                                    std::unique_ptr&lt;LazySlowPath&gt; lazySlowPath =
-                                        std::make_unique&lt;LazySlowPath&gt;(
-                                            linkedPatchableJump, linkedDone, exceptionTarget,
-                                            usedRegisters, callSiteIndex, generator);
</del><ins>+                                std::unique_ptr&lt;LazySlowPath&gt; lazySlowPath =
+                                    std::make_unique&lt;LazySlowPath&gt;(
+                                        linkedPatchableJump, linkedDone, exceptionTarget,
+                                        usedRegisters, callSiteIndex, generator);
</ins><span class="cx">                                     
</span><del>-                                    jitCode-&gt;lazySlowPaths[index] = WTF::move(lazySlowPath);
-                                });
-                        }));
</del><ins>+                                jitCode-&gt;lazySlowPaths[index] = WTF::move(lazySlowPath);
+                            });
+                    });
</ins><span class="cx">             });
</span><span class="cx">         return result;
</span><span class="cx"> #else
</span><span class="lines">@@ -9213,6 +9349,7 @@
</span><span class="cx">         m_out.appendTo(continuation);
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+#if !FTL_USES_B3
</ins><span class="cx">     void appendOSRExitArgumentsForPatchpointIfWillCatchException(StackmapArgumentList&amp; arguments, ExceptionType exceptionType, unsigned offsetOfExitArguments)
</span><span class="cx">     {
</span><span class="cx">         CodeOrigin opCatchOrigin;
</span><span class="lines">@@ -9230,9 +9367,10 @@
</span><span class="cx">         exitDescriptorImpl.m_baselineExceptionHandler = *exceptionHandler;
</span><span class="cx"> 
</span><span class="cx">         StackmapArgumentList freshList =
</span><del>-            buildExitArguments(exitDescriptor, exitDescriptorImpl, noValue(), offsetOfExitArguments);
</del><ins>+            buildExitArguments(exitDescriptor, exitDescriptorImpl.m_codeOrigin, noValue(), offsetOfExitArguments);
</ins><span class="cx">         arguments.appendVector(freshList);
</span><span class="cx">     }
</span><ins>+#endif // !FTL_USES_B3
</ins><span class="cx"> 
</span><span class="cx">     bool emitBranchToOSRExitIfWillCatchException(LValue hadException)
</span><span class="cx">     {
</span><span class="lines">@@ -9251,6 +9389,16 @@
</span><span class="cx">         return m_blocks.get(block);
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+
+#if FTL_USES_B3
+    OSRExitDescriptor* appendOSRExitDescriptor(FormattedValue lowValue, Node* highValue)
+    {
+        return &amp;m_ftlState.jitCode-&gt;osrExitDescriptors.alloc(
+            lowValue.format(), m_graph.methodOfGettingAValueProfileFor(highValue),
+            availabilityMap().m_locals.numberOfArguments(),
+            availabilityMap().m_locals.numberOfLocals());
+    }
+#else // FTL_USES_B3
</ins><span class="cx">     OSRExitDescriptor* appendOSRExitDescriptor(ExitKind kind, ExceptionType exceptionType, FormattedValue lowValue, Node* highValue, NodeOrigin origin)
</span><span class="cx">     {
</span><span class="cx">         OSRExitDescriptor&amp; result = m_ftlState.jitCode-&gt;osrExitDescriptors.alloc(
</span><span class="lines">@@ -9261,6 +9409,7 @@
</span><span class="cx">             kind, origin.forExit, origin.semantic, exceptionType);
</span><span class="cx">         return &amp;result;
</span><span class="cx">     }
</span><ins>+#endif // FTL_USES_B3
</ins><span class="cx">     
</span><span class="cx">     void appendOSRExit(
</span><span class="cx">         ExitKind kind, FormattedValue lowValue, Node* highValue, LValue failCondition, 
</span><span class="lines">@@ -9328,18 +9477,16 @@
</span><span class="cx"> #if FTL_USES_B3
</span><span class="cx">     void blessSpeculation(B3::CheckValue* value, ExitKind kind, FormattedValue lowValue, Node* highValue, NodeOrigin origin, bool isExceptionHandler = false)
</span><span class="cx">     {
</span><del>-        OSRExitDescriptor* exitDescriptor = appendOSRExitDescriptor(
-            kind, isExceptionHandler ? ExceptionType::CCallException : ExceptionType::None, lowValue,
-            highValue, origin);
-        OSRExitDescriptorImpl* exitDescriptorImpl = &amp;m_ftlState.osrExitDescriptorImpls.last();
</del><ins>+        OSRExitDescriptor* exitDescriptor = appendOSRExitDescriptor(lowValue, highValue);
</ins><span class="cx">         
</span><span class="cx">         unsigned offset = value-&gt;numChildren();
</span><del>-        value-&gt;appendColdAnys(buildExitArguments(exitDescriptor, m_ftlState.osrExitDescriptorImpls.last(), lowValue));
</del><ins>+        value-&gt;appendColdAnys(buildExitArguments(exitDescriptor, origin.forExit, lowValue));
</ins><span class="cx"> 
</span><span class="cx">         State* state = &amp;m_ftlState;
</span><span class="cx">         value-&gt;setGenerator(
</span><span class="cx">             [=] (CCallHelpers&amp; jit, const B3::StackmapGenerationParams&amp; params) {
</span><del>-                exitDescriptor-&gt;emitOSRExit(*state, exitDescriptorImpl, jit, params, offset);
</del><ins>+                exitDescriptor-&gt;emitOSRExit(
+                    *state, kind, origin, jit, params, offset, isExceptionHandler);
</ins><span class="cx">             });
</span><span class="cx">     }
</span><span class="cx"> #endif
</span><span class="lines">@@ -9347,29 +9494,29 @@
</span><span class="cx"> #if !FTL_USES_B3
</span><span class="cx">     void emitOSRExitCall(OSRExitDescriptor* exitDescriptor, FormattedValue lowValue)
</span><span class="cx">     {
</span><del>-        callStackmap(exitDescriptor, buildExitArguments(exitDescriptor, m_ftlState.osrExitDescriptorImpls.last(), lowValue));
</del><ins>+        callStackmap(exitDescriptor, buildExitArguments(exitDescriptor, m_ftlState.osrExitDescriptorImpls.last().m_codeOrigin, lowValue));
</ins><span class="cx">     }
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><span class="cx">     StackmapArgumentList buildExitArguments(
</span><del>-        OSRExitDescriptor* exitDescriptor, OSRExitDescriptorImpl&amp; exitDescriptorImpl, FormattedValue lowValue,
</del><ins>+        OSRExitDescriptor* exitDescriptor, CodeOrigin exitOrigin, FormattedValue lowValue,
</ins><span class="cx">         unsigned offsetOfExitArgumentsInStackmapLocations = 0)
</span><span class="cx">     {
</span><span class="cx">         StackmapArgumentList result;
</span><span class="cx">         buildExitArguments(
</span><del>-            exitDescriptor, exitDescriptorImpl, result, lowValue, offsetOfExitArgumentsInStackmapLocations);
</del><ins>+            exitDescriptor, exitOrigin, result, lowValue, offsetOfExitArgumentsInStackmapLocations);
</ins><span class="cx">         return result;
</span><span class="cx">     }
</span><span class="cx">     
</span><span class="cx">     void buildExitArguments(
</span><del>-        OSRExitDescriptor* exitDescriptor, OSRExitDescriptorImpl&amp; exitDescriptorImpl, StackmapArgumentList&amp; arguments, FormattedValue lowValue,
</del><ins>+        OSRExitDescriptor* exitDescriptor, CodeOrigin exitOrigin, StackmapArgumentList&amp; arguments, FormattedValue lowValue,
</ins><span class="cx">         unsigned offsetOfExitArgumentsInStackmapLocations = 0)
</span><span class="cx">     {
</span><span class="cx">         if (!!lowValue)
</span><span class="cx">             arguments.append(lowValue.value());
</span><span class="cx">         
</span><span class="cx">         AvailabilityMap availabilityMap = this-&gt;availabilityMap();
</span><del>-        availabilityMap.pruneByLiveness(m_graph, exitDescriptorImpl.m_codeOrigin);
</del><ins>+        availabilityMap.pruneByLiveness(m_graph, exitOrigin);
</ins><span class="cx">         
</span><span class="cx">         HashMap&lt;Node*, ExitTimeObjectMaterialization*&gt; map;
</span><span class="cx">         availabilityMap.forEachAvailability(
</span><span class="lines">@@ -9396,7 +9543,7 @@
</span><span class="cx">             if (Options::validateFTLOSRExitLiveness()) {
</span><span class="cx">                 DFG_ASSERT(
</span><span class="cx">                     m_graph, m_node,
</span><del>-                    (!(availability.isDead() &amp;&amp; m_graph.isLiveInBytecode(VirtualRegister(operand), exitDescriptorImpl.m_codeOrigin))) || m_graph.m_plan.mode == FTLForOSREntryMode);
</del><ins>+                    (!(availability.isDead() &amp;&amp; m_graph.isLiveInBytecode(VirtualRegister(operand), exitOrigin))) || m_graph.m_plan.mode == FTLForOSREntryMode);
</ins><span class="cx">             }
</span><span class="cx">             ExitValue exitValue = exitValueForAvailability(arguments, map, availability);
</span><span class="cx">             if (exitValue.hasIndexInStackmapLocations())
</span><span class="lines">@@ -9475,6 +9622,10 @@
</span><span class="cx">         StackmapArgumentList&amp; arguments, const HashMap&lt;Node*, ExitTimeObjectMaterialization*&gt;&amp; map,
</span><span class="cx">         Node* node)
</span><span class="cx">     {
</span><ins>+        // NOTE: In FTL-&gt;B3, we cannot generate code here, because m_output is positioned after the
+        // stackmap value. Like all values, the stackmap value cannot use a child that is defined after
+        // it.
+        
</ins><span class="cx">         ASSERT(node-&gt;shouldGenerate());
</span><span class="cx">         ASSERT(node-&gt;hasResult());
</span><span class="cx"> 
</span><span class="lines">@@ -9522,10 +9673,15 @@
</span><span class="cx">             return exitArgument(arguments, DataFormatStrictInt52, value.value());
</span><span class="cx">         
</span><span class="cx">         value = m_booleanValues.get(node);
</span><ins>+#if FTL_USES_B3
+        if (isValid(value))
+            return exitArgument(arguments, DataFormatBoolean, value.value());
+#else // FTL_USES_B3
</ins><span class="cx">         if (isValid(value)) {
</span><span class="cx">             LValue valueToPass = m_out.zeroExt(value.value(), m_out.int32);
</span><span class="cx">             return exitArgument(arguments, DataFormatBoolean, valueToPass);
</span><span class="cx">         }
</span><ins>+#endif // FTL_USES_B3
</ins><span class="cx">         
</span><span class="cx">         value = m_jsValueValues.get(node);
</span><span class="cx">         if (isValid(value))
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLOSRExitcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ftl/FTLOSRExit.cpp (193639 => 193640)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLOSRExit.cpp        2015-12-07 18:54:33 UTC (rev 193639)
+++ trunk/Source/JavaScriptCore/ftl/FTLOSRExit.cpp        2015-12-07 19:17:56 UTC (rev 193640)
</span><span class="lines">@@ -29,6 +29,7 @@
</span><span class="cx"> #if ENABLE(FTL_JIT)
</span><span class="cx"> 
</span><span class="cx"> #include &quot;AirGenerationContext.h&quot;
</span><ins>+#include &quot;B3StackmapGenerationParams.h&quot;
</ins><span class="cx"> #include &quot;B3StackmapValue.h&quot;
</span><span class="cx"> #include &quot;CodeBlock.h&quot;
</span><span class="cx"> #include &quot;DFGBasicBlock.h&quot;
</span><span class="lines">@@ -50,7 +51,9 @@
</span><span class="cx">     : m_profileDataFormat(profileDataFormat)
</span><span class="cx">     , m_valueProfile(valueProfile)
</span><span class="cx">     , m_values(numberOfArguments, numberOfLocals)
</span><ins>+#if !FTL_USES_B3
</ins><span class="cx">     , m_isInvalidationPoint(false)
</span><ins>+#endif // !FTL_USES_B3
</ins><span class="cx"> {
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -65,53 +68,65 @@
</span><span class="cx"> 
</span><span class="cx"> #if FTL_USES_B3
</span><span class="cx"> RefPtr&lt;OSRExitHandle&gt; OSRExitDescriptor::emitOSRExit(
</span><del>-    State&amp; state, OSRExitDescriptorImpl* exitDescriptorImpl, CCallHelpers&amp; jit, const StackmapGenerationParams&amp; params, unsigned offset)
</del><ins>+    State&amp; state, ExitKind exitKind, const NodeOrigin&amp; nodeOrigin, CCallHelpers&amp; jit,
+    const StackmapGenerationParams&amp; params, unsigned offset, bool isExceptionHandler)
</ins><span class="cx"> {
</span><del>-    RefPtr&lt;OSRExitHandle&gt; handle = prepareOSRExitHandle(state, exitDescriptorImpl, params, offset);
</del><ins>+    RefPtr&lt;OSRExitHandle&gt; handle =
+        prepareOSRExitHandle(state, exitKind, nodeOrigin, params, offset, isExceptionHandler);
</ins><span class="cx">     handle-&gt;emitExitThunk(jit);
</span><span class="cx">     return handle;
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> RefPtr&lt;OSRExitHandle&gt; OSRExitDescriptor::emitOSRExitLater(
</span><del>-    State&amp; state, OSRExitDescriptorImpl* exitDescriptorImpl, const StackmapGenerationParams&amp; params, unsigned offset)
</del><ins>+    State&amp; state, ExitKind exitKind, const NodeOrigin&amp; nodeOrigin,
+    const StackmapGenerationParams&amp; params, unsigned offset, bool isExceptionHandler)
</ins><span class="cx"> {
</span><del>-    RefPtr&lt;OSRExitHandle&gt; handle = prepareOSRExitHandle(state, exitDescriptorImpl, params, offset);
-    params.context-&gt;latePaths.append(
-        createSharedTask&lt;Air::GenerationContext::LatePathFunction&gt;(
-            [handle] (CCallHelpers&amp; jit, Air::GenerationContext&amp;) {
-                handle-&gt;emitExitThunk(jit);
-            }));
</del><ins>+    RefPtr&lt;OSRExitHandle&gt; handle =
+        prepareOSRExitHandle(state, exitKind, nodeOrigin, params, offset, isExceptionHandler);
+    params.addLatePath(
+        [handle] (CCallHelpers&amp; jit) {
+            handle-&gt;emitExitThunk(jit);
+        });
</ins><span class="cx">     return handle;
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> RefPtr&lt;OSRExitHandle&gt; OSRExitDescriptor::prepareOSRExitHandle(
</span><del>-    State&amp; state, OSRExitDescriptorImpl* exitDescriptorImpl, const StackmapGenerationParams&amp; params, unsigned offset)
</del><ins>+    State&amp; state, ExitKind exitKind, const NodeOrigin&amp; nodeOrigin,
+    const StackmapGenerationParams&amp; params, unsigned offset, bool isExceptionHandler)
</ins><span class="cx"> {
</span><span class="cx">     unsigned index = state.jitCode-&gt;osrExit.size();
</span><del>-    RefPtr&lt;OSRExitHandle&gt; handle = adoptRef(
-        new OSRExitHandle(index, state.jitCode-&gt;osrExit.alloc(this, *exitDescriptorImpl)));
-    for (unsigned i = offset; i &lt; params.reps.size(); ++i)
-        handle-&gt;exit.m_valueReps.append(params.reps[i]);
-    handle-&gt;exit.m_valueReps.shrinkToFit();
</del><ins>+    OSRExit&amp; exit = state.jitCode-&gt;osrExit.alloc(
+        this, exitKind, nodeOrigin.forExit, nodeOrigin.semantic, isExceptionHandler);
+    RefPtr&lt;OSRExitHandle&gt; handle = adoptRef(new OSRExitHandle(index, exit));
+    for (unsigned i = offset; i &lt; params.size(); ++i)
+        exit.m_valueReps.append(params[i]);
+    exit.m_valueReps.shrinkToFit();
</ins><span class="cx">     return handle;
</span><span class="cx"> }
</span><span class="cx"> #endif // FTL_USES_B3
</span><span class="cx"> 
</span><ins>+#if FTL_USES_B3
</ins><span class="cx"> OSRExit::OSRExit(
</span><del>-    OSRExitDescriptor* descriptor, OSRExitDescriptorImpl&amp; exitDescriptorImpl
-#if !FTL_USES_B3
-    , uint32_t stackmapRecordIndex
-#endif // !FTL_USES_B3
-    )
</del><ins>+    OSRExitDescriptor* descriptor,
+    ExitKind exitKind, CodeOrigin codeOrigin, CodeOrigin codeOriginForExitProfile,
+    bool isExceptionHandler)
+    : OSRExitBase(exitKind, codeOrigin, codeOriginForExitProfile)
+    , m_descriptor(descriptor)
+{
+    m_isExceptionHandler = isExceptionHandler;
+}
+#else // FTL_USES_B3
+OSRExit::OSRExit(
+    OSRExitDescriptor* descriptor, OSRExitDescriptorImpl&amp; exitDescriptorImpl,
+    uint32_t stackmapRecordIndex)
</ins><span class="cx">     : OSRExitBase(exitDescriptorImpl.m_kind, exitDescriptorImpl.m_codeOrigin, exitDescriptorImpl.m_codeOriginForExitProfile)
</span><span class="cx">     , m_descriptor(descriptor)
</span><del>-#if !FTL_USES_B3
</del><span class="cx">     , m_stackmapRecordIndex(stackmapRecordIndex)
</span><del>-#endif // !FTL_USES_B3
</del><span class="cx">     , m_exceptionType(exitDescriptorImpl.m_exceptionType)
</span><span class="cx"> {
</span><span class="cx">     m_isExceptionHandler = exitDescriptorImpl.m_exceptionType != ExceptionType::None;
</span><span class="cx"> }
</span><ins>+#endif // FTL_USES_B3
</ins><span class="cx"> 
</span><span class="cx"> CodeLocationJump OSRExit::codeLocationForRepatch(CodeBlock* ftlCodeBlock) const
</span><span class="cx"> {
</span><span class="lines">@@ -196,7 +211,6 @@
</span><span class="cx">         }
</span><span class="cx">     }
</span><span class="cx"> }
</span><del>-#endif // !FTL_USES_B3
</del><span class="cx"> 
</span><span class="cx"> bool OSRExit::willArriveAtExitFromIndirectExceptionCheck() const
</span><span class="cx"> {
</span><span class="lines">@@ -260,6 +274,7 @@
</span><span class="cx">     // recover the spilled registers.
</span><span class="cx">     return m_exceptionType == ExceptionType::JSCall;
</span><span class="cx"> }
</span><ins>+#endif // !FTL_USES_B3
</ins><span class="cx"> 
</span><span class="cx"> } } // namespace JSC::FTL
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLOSRExith"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ftl/FTLOSRExit.h (193639 => 193640)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLOSRExit.h        2015-12-07 18:54:33 UTC (rev 193639)
+++ trunk/Source/JavaScriptCore/ftl/FTLOSRExit.h        2015-12-07 19:17:56 UTC (rev 193640)
</span><span class="lines">@@ -31,6 +31,7 @@
</span><span class="cx"> #include &quot;B3ValueRep.h&quot;
</span><span class="cx"> #include &quot;CodeOrigin.h&quot;
</span><span class="cx"> #include &quot;DFGExitProfile.h&quot;
</span><ins>+#include &quot;DFGNodeOrigin.h&quot;
</ins><span class="cx"> #include &quot;DFGOSRExitBase.h&quot;
</span><span class="cx"> #include &quot;FTLAbbreviatedTypes.h&quot;
</span><span class="cx"> #include &quot;FTLExitTimeObjectMaterialization.h&quot;
</span><span class="lines">@@ -51,17 +52,23 @@
</span><span class="cx"> class TrackedReferences;
</span><span class="cx"> 
</span><span class="cx"> namespace B3 {
</span><del>-struct StackmapGenerationParams;
</del><ins>+class StackmapGenerationParams;
</ins><span class="cx"> namespace Air {
</span><span class="cx"> struct GenerationContext;
</span><span class="cx"> } // namespace Air
</span><span class="cx"> } // namespace B3
</span><span class="cx"> 
</span><ins>+namespace DFG {
+struct NodeOrigin;
+} // namespace DFG;
+
</ins><span class="cx"> namespace FTL {
</span><span class="cx"> 
</span><span class="cx"> class State;
</span><span class="cx"> struct OSRExitDescriptorImpl;
</span><ins>+struct OSRExitHandle;
</ins><span class="cx"> 
</span><ins>+#if !FTL_USES_B3
</ins><span class="cx"> enum class ExceptionType : uint8_t {
</span><span class="cx">     None,
</span><span class="cx">     CCallException,
</span><span class="lines">@@ -75,6 +82,7 @@
</span><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> bool exceptionTypeWillArriveAtOSRExitFromGenericUnwind(ExceptionType);
</span><ins>+#endif // !FTL_USES_B3
</ins><span class="cx"> 
</span><span class="cx"> struct OSRExitDescriptor {
</span><span class="cx">     OSRExitDescriptor(
</span><span class="lines">@@ -91,9 +99,11 @@
</span><span class="cx">     
</span><span class="cx">     Operands&lt;ExitValue&gt; m_values;
</span><span class="cx">     Bag&lt;ExitTimeObjectMaterialization&gt; m_materializations;
</span><del>-    
</del><ins>+
+#if !FTL_USES_B3
</ins><span class="cx">     uint32_t m_stackmapID;
</span><span class="cx">     bool m_isInvalidationPoint;
</span><ins>+#endif // !FTL_USES_B3
</ins><span class="cx">     
</span><span class="cx">     void validateReferences(const TrackedReferences&amp;);
</span><span class="cx"> 
</span><span class="lines">@@ -105,7 +115,8 @@
</span><span class="cx">     // on the ground. It contains information that is mostly not useful if you use this API, since after
</span><span class="cx">     // this call, the OSRExit is simply ready to go.
</span><span class="cx">     RefPtr&lt;OSRExitHandle&gt; emitOSRExit(
</span><del>-        State&amp;, OSRExitDescriptorImpl*, CCallHelpers&amp;, const B3::StackmapGenerationParams&amp;, unsigned offset);
</del><ins>+        State&amp;, ExitKind, const DFG::NodeOrigin&amp;, CCallHelpers&amp;, const B3::StackmapGenerationParams&amp;,
+        unsigned offset = 0, bool isExceptionHandler = false);
</ins><span class="cx"> 
</span><span class="cx">     // In some cases you want an OSRExit to come into existence, but you don't want to emit it right now.
</span><span class="cx">     // This will emit the OSR exit in a late path. You can't be sure exactly when that will happen, but
</span><span class="lines">@@ -116,16 +127,19 @@
</span><span class="cx">     // have a place to jump to for OSR exit. It doesn't care where that OSR exit is emitted so long as it
</span><span class="cx">     // eventually gets access to its label.
</span><span class="cx">     RefPtr&lt;OSRExitHandle&gt; emitOSRExitLater(
</span><del>-        State&amp;, OSRExitDescriptorImpl*, const B3::StackmapGenerationParams&amp;, unsigned offset);
</del><ins>+        State&amp;, ExitKind, const DFG::NodeOrigin&amp;, const B3::StackmapGenerationParams&amp;,
+        unsigned offset = 0, bool isExceptionHandler = false);
</ins><span class="cx"> 
</span><span class="cx">     // This is the low-level interface. It will create a handle representing the desire to emit code for
</span><span class="cx">     // an OSR exit. You can call OSRExitHandle::emitExitThunk() once you have a place to emit it. Note
</span><span class="cx">     // that the above two APIs are written in terms of this and OSRExitHandle::emitExitThunk().
</span><span class="cx">     RefPtr&lt;OSRExitHandle&gt; prepareOSRExitHandle(
</span><del>-        State&amp;, OSRExitDescriptorImpl*, const B3::StackmapGenerationParams&amp;, unsigned offset);
</del><ins>+        State&amp;, ExitKind, const DFG::NodeOrigin&amp;, const B3::StackmapGenerationParams&amp;,
+        unsigned offset = 0, bool isExceptionHandler = false);
</ins><span class="cx"> #endif // FTL_USES_B3
</span><span class="cx"> };
</span><span class="cx"> 
</span><ins>+#if !FTL_USES_B3
</ins><span class="cx"> struct OSRExitDescriptorImpl {
</span><span class="cx">     OSRExitDescriptorImpl(ExitKind kind, CodeOrigin exitOrigin, CodeOrigin forExitProfile, ExceptionType exceptionType)
</span><span class="cx">         : m_kind(kind)
</span><span class="lines">@@ -142,13 +156,16 @@
</span><span class="cx">     CodeOrigin m_semanticCodeOriginForCallFrameHeader;
</span><span class="cx">     HandlerInfo m_baselineExceptionHandler;
</span><span class="cx"> };
</span><ins>+#endif // !FTL_USES_B3
</ins><span class="cx"> 
</span><span class="cx"> struct OSRExit : public DFG::OSRExitBase {
</span><span class="cx">     OSRExit(
</span><del>-        OSRExitDescriptor*, OSRExitDescriptorImpl&amp;
-#if !FTL_USES_B3
-        , uint32_t stackmapRecordIndex
-#endif // !FTL_USES_B3
</del><ins>+        OSRExitDescriptor*,
+#if FTL_USES_B3
+        ExitKind, CodeOrigin, CodeOrigin codeOriginForExitProfile, bool isExceptionHandler
+#else // FTL_USES_B3
+        OSRExitDescriptorImpl&amp;, uint32_t stackmapRecordIndex
+#endif // FTL_USES_B3
</ins><span class="cx">         );
</span><span class="cx"> 
</span><span class="cx">     OSRExitDescriptor* m_descriptor;
</span><span class="lines">@@ -157,15 +174,18 @@
</span><span class="cx">     // This tells us where to place a jump.
</span><span class="cx">     CodeLocationJump m_patchableJump;
</span><span class="cx">     Vector&lt;B3::ValueRep&gt; m_valueReps;
</span><ins>+    // True if this exit is used as an exception handler for unwinding. This happens to only be set when
+    // isExceptionHandler is true, but all this actually means is that the OSR exit will assume that the
+    // machine state is as it would be coming out of genericUnwind.
+    bool m_isUnwindHandler { false };
</ins><span class="cx"> #else // FTL_USES_B3
</span><span class="cx">     // Offset within the exit stubs of the stub for this exit.
</span><span class="cx">     unsigned m_patchableCodeOffset;
</span><span class="cx">     // Offset within Stackmap::records
</span><span class="cx">     uint32_t m_stackmapRecordIndex;
</span><del>-#endif // FTL_USES_B3
</del><span class="cx">     ExceptionType m_exceptionType;
</span><del>-
</del><span class="cx">     RegisterSet registersToPreserveForCallThatMightThrow;
</span><ins>+#endif // FTL_USES_B3
</ins><span class="cx"> 
</span><span class="cx">     CodeLocationJump codeLocationForRepatch(CodeBlock* ftlCodeBlock) const;
</span><span class="cx">     void considerAddingAsFrequentExitSite(CodeBlock* profiledCodeBlock)
</span><span class="lines">@@ -177,12 +197,12 @@
</span><span class="cx">     void gatherRegistersToSpillForCallIfException(StackMaps&amp;, StackMaps::Record&amp;);
</span><span class="cx">     void spillRegistersToSpillSlot(CCallHelpers&amp;, int32_t stackSpillSlot);
</span><span class="cx">     void recoverRegistersFromSpillSlot(CCallHelpers&amp; jit, int32_t stackSpillSlot);
</span><del>-#endif // !FTL_USES_B3
</del><span class="cx"> 
</span><span class="cx">     bool willArriveAtOSRExitFromGenericUnwind() const;
</span><span class="cx">     bool willArriveAtExitFromIndirectExceptionCheck() const;
</span><span class="cx">     bool willArriveAtOSRExitFromCallOperation() const;
</span><span class="cx">     bool needsRegisterRecoveryOnGenericUnwindOSRExitPath() const;
</span><ins>+#endif // !FTL_USES_B3
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLOSRExitCompilercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ftl/FTLOSRExitCompiler.cpp (193639 => 193640)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLOSRExitCompiler.cpp        2015-12-07 18:54:33 UTC (rev 193639)
+++ trunk/Source/JavaScriptCore/ftl/FTLOSRExitCompiler.cpp        2015-12-07 19:17:56 UTC (rev 193640)
</span><span class="lines">@@ -207,23 +207,34 @@
</span><span class="cx">     CCallHelpers jit(vm, codeBlock);
</span><span class="cx"> 
</span><span class="cx">     // The first thing we need to do is restablish our frame in the case of an exception.
</span><del>-    if (exit.willArriveAtOSRExitFromGenericUnwind()) {
</del><ins>+    if (
+#if FTL_USES_B3
+        exit.m_isUnwindHandler
+#else // FTL_USES_B3
+        exit.willArriveAtOSRExitFromGenericUnwind()
+#endif // FTL_USES_B3
+        ) {
</ins><span class="cx">         RELEASE_ASSERT(vm-&gt;callFrameForCatch); // The first time we hit this exit, like at all other times, this field should be non-null.
</span><span class="cx">         jit.restoreCalleeSavesFromVMCalleeSavesBuffer();
</span><span class="cx">         jit.loadPtr(vm-&gt;addressOfCallFrameForCatch(), MacroAssembler::framePointerRegister);
</span><span class="cx">         jit.addPtr(CCallHelpers::TrustedImm32(codeBlock-&gt;stackPointerOffset() * sizeof(Register)),
</span><span class="cx">             MacroAssembler::framePointerRegister, CCallHelpers::stackPointerRegister);
</span><span class="cx"> 
</span><ins>+#if !FTL_USES_B3
</ins><span class="cx">         if (exit.needsRegisterRecoveryOnGenericUnwindOSRExitPath())
</span><span class="cx">             exit.recoverRegistersFromSpillSlot(jit, jitCode-&gt;osrExitFromGenericUnwindStackSpillSlot);
</span><ins>+#endif // !FTL_USES_B3
</ins><span class="cx"> 
</span><span class="cx">         // Do a pushToSave because that's what the exit compiler below expects the stack
</span><span class="cx">         // to look like because that's the last thing the ExitThunkGenerator does. The code
</span><span class="cx">         // below doesn't actually use the value that was pushed, but it does rely on the
</span><span class="cx">         // general shape of the stack being as it is in the non-exception OSR case.
</span><span class="cx">         jit.pushToSaveImmediateWithoutTouchingRegisters(CCallHelpers::TrustedImm32(0xbadbeef));
</span><del>-    } else if (exit.willArriveAtOSRExitFromCallOperation())
</del><ins>+    }
+#if !FTL_USES_B3
+    if (exit.willArriveAtOSRExitFromCallOperation())
</ins><span class="cx">         exit.recoverRegistersFromSpillSlot(jit, jitCode-&gt;osrExitFromGenericUnwindStackSpillSlot);
</span><ins>+#endif // !FTL_USES_B3
</ins><span class="cx">     
</span><span class="cx"> 
</span><span class="cx">     // We need scratch space to save all registers, to build up the JS stack, to deal with unwind
</span><span class="lines">@@ -603,11 +614,17 @@
</span><span class="cx">         dataLog(&quot;    Origin: &quot;, exit.m_codeOrigin, &quot;\n&quot;);
</span><span class="cx">         if (exit.m_codeOriginForExitProfile != exit.m_codeOrigin)
</span><span class="cx">             dataLog(&quot;    Origin for exit profile: &quot;, exit.m_codeOriginForExitProfile, &quot;\n&quot;);
</span><ins>+#if !FTL_USES_B3
</ins><span class="cx">         dataLog(&quot;    Exit stackmap ID: &quot;, exit.m_descriptor-&gt;m_stackmapID, &quot;\n&quot;);
</span><ins>+#endif // !FTL_USES_B3
</ins><span class="cx">         dataLog(&quot;    Current call site index: &quot;, exec-&gt;callSiteIndex().bits(), &quot;\n&quot;);
</span><del>-        dataLog(&quot;    Exit is exception handler: &quot;, exit.m_isExceptionHandler,
-            &quot; will arrive at exit from genericUnwind(): &quot;, exit.willArriveAtOSRExitFromGenericUnwind(), 
-            &quot; will arrive at exit from lazy slow path: &quot;, exit.m_exceptionType == ExceptionType::LazySlowPath, &quot;\n&quot;);
</del><ins>+        dataLog(&quot;    Exit is exception handler: &quot;, exit.m_isExceptionHandler, &quot;\n&quot;);
+#if FTL_USES_B3
+        dataLog(&quot;    Is unwind handler: &quot;, exit.m_isUnwindHandler, &quot;\n&quot;);
+#else // FTL_USES_B3
+        dataLog(&quot;    Will arrive at exit from genericUnwind(): &quot;, exit.willArriveAtOSRExitFromGenericUnwind(), &quot;\n&quot;);
+        dataLog(&quot;    Will arrive at exit from lazy slow path: &quot;, exit.m_exceptionType == ExceptionType::LazySlowPath, &quot;\n&quot;);
+#endif // FTL_USES_B3
</ins><span class="cx">         dataLog(&quot;    Exit values: &quot;, exit.m_descriptor-&gt;m_values, &quot;\n&quot;);
</span><span class="cx">         if (!exit.m_descriptor-&gt;m_materializations.isEmpty()) {
</span><span class="cx">             dataLog(&quot;    Materializations:\n&quot;);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLStateh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ftl/FTLState.h (193639 => 193640)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLState.h        2015-12-07 18:54:33 UTC (rev 193639)
+++ trunk/Source/JavaScriptCore/ftl/FTLState.h        2015-12-07 19:17:56 UTC (rev 193640)
</span><span class="lines">@@ -96,12 +96,14 @@
</span><span class="cx"> #if ENABLE(MASM_PROBE)
</span><span class="cx">     SegmentedVector&lt;ProbeDescriptor&gt; probes;
</span><span class="cx"> #endif
</span><ins>+#if !FTL_USES_B3
</ins><span class="cx">     Vector&lt;JSCall&gt; jsCalls;
</span><span class="cx">     Vector&lt;JSCallVarargs&gt; jsCallVarargses;
</span><span class="cx">     Vector&lt;JSTailCall&gt; jsTailCalls;
</span><span class="cx">     Vector&lt;CString&gt; codeSectionNames;
</span><span class="cx">     Vector&lt;CString&gt; dataSectionNames;
</span><span class="cx">     SegmentedVector&lt;OSRExitDescriptorImpl&gt; osrExitDescriptorImpls;
</span><ins>+#endif // !FTL_USES_B3
</ins><span class="cx">     void* unwindDataSection;
</span><span class="cx">     size_t unwindDataSectionSize;
</span><span class="cx">     RefPtr&lt;DataSection&gt; stackmapsSection;
</span></span></pre>
</div>
</div>

</body>
</html>