<!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>[194126] 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/194126">194126</a></dd>
<dt>Author</dt> <dd>mark.lam@apple.com</dd>
<dt>Date</dt> <dd>2015-12-15 17:05:00 -0800 (Tue, 15 Dec 2015)</dd>
</dl>

<h3>Log Message</h3>
<pre>Introducing ScratchRegisterAllocator::PreservedState.
https://bugs.webkit.org/show_bug.cgi?id=152315

Reviewed by Geoffrey Garen.

restoreReusedRegistersByPopping() should always be called with 2 values that
matches the expectation of preserveReusedRegistersByPushing().  Those 2 values
are the number of bytes preserved and the ExtraStackSpace requirement.  By
encapsulating them in a ScratchRegisterAllocator::PreservedState, we can make
it less error prone when calling restoreReusedRegistersByPopping().  Now, we only
need to pass it the appropriate PreservedState that its matching
preserveReusedRegistersByPushing() returned.

* bytecode/PolymorphicAccess.cpp:
(JSC::AccessGenerationState::restoreScratch):
(JSC::AccessCase::generate):
(JSC::PolymorphicAccess::regenerate):
* bytecode/PolymorphicAccess.h:
(JSC::AccessGenerationState::AccessGenerationState):
* ftl/FTLCompileBinaryOp.cpp:
(JSC::FTL::generateBinaryBitOpFastPath):
(JSC::FTL::generateRightShiftFastPath):
(JSC::FTL::generateBinaryArithOpFastPath):
* ftl/FTLLazySlowPath.cpp:
(JSC::FTL::LazySlowPath::generate):
* ftl/FTLLowerDFGToLLVM.cpp:
(JSC::FTL::DFG::LowerDFGToLLVM::emitStoreBarrier):
* jit/ScratchRegisterAllocator.cpp:
(JSC::ScratchRegisterAllocator::allocateScratchGPR):
(JSC::ScratchRegisterAllocator::allocateScratchFPR):
(JSC::ScratchRegisterAllocator::preserveReusedRegistersByPushing):
(JSC::ScratchRegisterAllocator::restoreReusedRegistersByPopping):
* jit/ScratchRegisterAllocator.h:
(JSC::ScratchRegisterAllocator::usedRegisters):
(JSC::ScratchRegisterAllocator::PreservedState::PreservedState):</pre>

<h3>Modified Paths</h3>
<ul>
<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="#trunkSourceJavaScriptCorebytecodePolymorphicAccesscpp">trunk/Source/JavaScriptCore/bytecode/PolymorphicAccess.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodePolymorphicAccessh">trunk/Source/JavaScriptCore/bytecode/PolymorphicAccess.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreftlFTLCompileBinaryOpcpp">trunk/Source/JavaScriptCore/ftl/FTLCompileBinaryOp.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreftlFTLLazySlowPathcpp">trunk/Source/JavaScriptCore/ftl/FTLLazySlowPath.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreftlFTLLowerDFGToLLVMcpp">trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorejitScratchRegisterAllocatorcpp">trunk/Source/JavaScriptCore/jit/ScratchRegisterAllocator.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorejitScratchRegisterAllocatorh">trunk/Source/JavaScriptCore/jit/ScratchRegisterAllocator.h</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ChangeLog (194125 => 194126)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ChangeLog        2015-12-16 00:55:49 UTC (rev 194125)
+++ trunk/Source/JavaScriptCore/ChangeLog        2015-12-16 01:05:00 UTC (rev 194126)
</span><span class="lines">@@ -1,5 +1,43 @@
</span><span class="cx"> 2015-12-15  Mark Lam  &lt;mark.lam@apple.com&gt;
</span><span class="cx"> 
</span><ins>+        Introducing ScratchRegisterAllocator::PreservedState.
+        https://bugs.webkit.org/show_bug.cgi?id=152315
+
+        Reviewed by Geoffrey Garen.
+
+        restoreReusedRegistersByPopping() should always be called with 2 values that
+        matches the expectation of preserveReusedRegistersByPushing().  Those 2 values
+        are the number of bytes preserved and the ExtraStackSpace requirement.  By
+        encapsulating them in a ScratchRegisterAllocator::PreservedState, we can make
+        it less error prone when calling restoreReusedRegistersByPopping().  Now, we only
+        need to pass it the appropriate PreservedState that its matching
+        preserveReusedRegistersByPushing() returned.
+
+        * bytecode/PolymorphicAccess.cpp:
+        (JSC::AccessGenerationState::restoreScratch):
+        (JSC::AccessCase::generate):
+        (JSC::PolymorphicAccess::regenerate):
+        * bytecode/PolymorphicAccess.h:
+        (JSC::AccessGenerationState::AccessGenerationState):
+        * ftl/FTLCompileBinaryOp.cpp:
+        (JSC::FTL::generateBinaryBitOpFastPath):
+        (JSC::FTL::generateRightShiftFastPath):
+        (JSC::FTL::generateBinaryArithOpFastPath):
+        * ftl/FTLLazySlowPath.cpp:
+        (JSC::FTL::LazySlowPath::generate):
+        * ftl/FTLLowerDFGToLLVM.cpp:
+        (JSC::FTL::DFG::LowerDFGToLLVM::emitStoreBarrier):
+        * jit/ScratchRegisterAllocator.cpp:
+        (JSC::ScratchRegisterAllocator::allocateScratchGPR):
+        (JSC::ScratchRegisterAllocator::allocateScratchFPR):
+        (JSC::ScratchRegisterAllocator::preserveReusedRegistersByPushing):
+        (JSC::ScratchRegisterAllocator::restoreReusedRegistersByPopping):
+        * jit/ScratchRegisterAllocator.h:
+        (JSC::ScratchRegisterAllocator::usedRegisters):
+        (JSC::ScratchRegisterAllocator::PreservedState::PreservedState):
+
+2015-12-15  Mark Lam  &lt;mark.lam@apple.com&gt;
+
</ins><span class="cx">         Polymorphic operand types for DFG and FTL bit operators.
</span><span class="cx">         https://bugs.webkit.org/show_bug.cgi?id=152191
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreJavaScriptCorexcodeprojprojectpbxproj"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj (194125 => 194126)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj        2015-12-16 00:55:49 UTC (rev 194125)
+++ trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj        2015-12-16 01:05:00 UTC (rev 194126)
</span><span class="lines">@@ -158,7 +158,7 @@
</span><span class="cx">                 0F24E54F17EE274900ABB217 /* TempRegisterSet.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F24E54817EE274900ABB217 /* TempRegisterSet.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 0F24E55017EE274900ABB217 /* Repatch.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F24E54917EE274900ABB217 /* Repatch.cpp */; };
</span><span class="cx">                 0F24E55117EE274900ABB217 /* Repatch.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F24E54A17EE274900ABB217 /* Repatch.h */; };
</span><del>-                0F24E55217EE274900ABB217 /* ScratchRegisterAllocator.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F24E54B17EE274900ABB217 /* ScratchRegisterAllocator.h */; };
</del><ins>+                0F24E55217EE274900ABB217 /* ScratchRegisterAllocator.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F24E54B17EE274900ABB217 /* ScratchRegisterAllocator.h */; settings = {ATTRIBUTES = (Private, ); }; };
</ins><span class="cx">                 0F24E55517F0B71C00ABB217 /* InlineCallFrameSet.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F24E55317F0B71C00ABB217 /* InlineCallFrameSet.cpp */; };
</span><span class="cx">                 0F24E55617F0B71C00ABB217 /* InlineCallFrameSet.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F24E55417F0B71C00ABB217 /* InlineCallFrameSet.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 0F24E55817F74EDB00ABB217 /* ValueRecovery.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F24E55717F74EDB00ABB217 /* ValueRecovery.cpp */; };
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodePolymorphicAccesscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/PolymorphicAccess.cpp (194125 => 194126)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/PolymorphicAccess.cpp        2015-12-16 00:55:49 UTC (rev 194125)
+++ trunk/Source/JavaScriptCore/bytecode/PolymorphicAccess.cpp        2015-12-16 01:05:00 UTC (rev 194126)
</span><span class="lines">@@ -54,7 +54,7 @@
</span><span class="cx"> 
</span><span class="cx"> void AccessGenerationState::restoreScratch()
</span><span class="cx"> {
</span><del>-    allocator-&gt;restoreReusedRegistersByPopping(*jit, numberOfBytesUsedToPreserveReusedRegisters, ScratchRegisterAllocator::ExtraStackSpace::NoExtraSpace);
</del><ins>+    allocator-&gt;restoreReusedRegistersByPopping(*jit, preservedReusedRegisterState);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void AccessGenerationState::succeed()
</span><span class="lines">@@ -727,7 +727,7 @@
</span><span class="cx"> 
</span><span class="cx">             done.link(&amp;jit);
</span><span class="cx"> 
</span><del>-            jit.addPtr(CCallHelpers::TrustedImm32((jit.codeBlock()-&gt;stackPointerOffset() * sizeof(Register)) - state.numberOfBytesUsedToPreserveReusedRegisters - state.numberOfStackBytesUsedForRegisterPreservation()),
</del><ins>+            jit.addPtr(CCallHelpers::TrustedImm32((jit.codeBlock()-&gt;stackPointerOffset() * sizeof(Register)) - state.preservedReusedRegisterState.numberOfBytesPreserved - state.numberOfStackBytesUsedForRegisterPreservation()),
</ins><span class="cx">                 GPRInfo::callFrameRegister, CCallHelpers::stackPointerRegister);
</span><span class="cx">             state.restoreLiveRegistersFromStackForCall(isGetter());
</span><span class="cx"> 
</span><span class="lines">@@ -886,12 +886,13 @@
</span><span class="cx">         else
</span><span class="cx">             scratchGPR3 = InvalidGPRReg;
</span><span class="cx"> 
</span><del>-        size_t numberOfBytesUsedToPreserveReusedRegisters = allocator.preserveReusedRegistersByPushing(jit, ScratchRegisterAllocator::ExtraStackSpace::SpaceForCCall);
</del><ins>+        ScratchRegisterAllocator::PreservedState preservedState =
+            allocator.preserveReusedRegistersByPushing(jit, ScratchRegisterAllocator::ExtraStackSpace::SpaceForCCall);
</ins><span class="cx"> 
</span><span class="cx">         ASSERT(structure()-&gt;transitionWatchpointSetHasBeenInvalidated());
</span><span class="cx"> 
</span><span class="cx">         bool scratchGPRHasStorage = false;
</span><del>-        bool needsToMakeRoomOnStackForCCall = !numberOfBytesUsedToPreserveReusedRegisters &amp;&amp; codeBlock-&gt;jitType() == JITCode::FTLJIT;
</del><ins>+        bool needsToMakeRoomOnStackForCCall = !preservedState.numberOfBytesPreserved &amp;&amp; codeBlock-&gt;jitType() == JITCode::FTLJIT;
</ins><span class="cx"> 
</span><span class="cx">         if (newStructure()-&gt;outOfLineCapacity() != structure()-&gt;outOfLineCapacity()) {
</span><span class="cx">             size_t newSize = newStructure()-&gt;outOfLineCapacity() * sizeof(JSValue);
</span><span class="lines">@@ -1016,12 +1017,12 @@
</span><span class="cx">                 });
</span><span class="cx">         }
</span><span class="cx">         
</span><del>-        allocator.restoreReusedRegistersByPopping(jit, numberOfBytesUsedToPreserveReusedRegisters, ScratchRegisterAllocator::ExtraStackSpace::SpaceForCCall);
</del><ins>+        allocator.restoreReusedRegistersByPopping(jit, preservedState);
</ins><span class="cx">         state.succeed();
</span><span class="cx"> 
</span><span class="cx">         if (newStructure()-&gt;outOfLineCapacity() != structure()-&gt;outOfLineCapacity()) {
</span><span class="cx">             slowPath.link(&amp;jit);
</span><del>-            allocator.restoreReusedRegistersByPopping(jit, numberOfBytesUsedToPreserveReusedRegisters, ScratchRegisterAllocator::ExtraStackSpace::SpaceForCCall);
</del><ins>+            allocator.restoreReusedRegistersByPopping(jit, preservedState);
</ins><span class="cx">             allocator.preserveUsedRegistersToScratchBufferForCall(jit, scratchBuffer, scratchGPR);
</span><span class="cx">             if (needsToMakeRoomOnStackForCCall)
</span><span class="cx">                 jit.makeSpaceOnStackForCCall();
</span><span class="lines">@@ -1245,7 +1246,8 @@
</span><span class="cx">     CCallHelpers jit(&amp;vm, codeBlock);
</span><span class="cx">     state.jit = &amp;jit;
</span><span class="cx"> 
</span><del>-    state.numberOfBytesUsedToPreserveReusedRegisters = allocator.preserveReusedRegistersByPushing(jit, ScratchRegisterAllocator::ExtraStackSpace::NoExtraSpace);
</del><ins>+    state.preservedReusedRegisterState =
+        allocator.preserveReusedRegistersByPushing(jit, ScratchRegisterAllocator::ExtraStackSpace::NoExtraSpace);
</ins><span class="cx"> 
</span><span class="cx">     bool allGuardedByStructureCheck = true;
</span><span class="cx">     bool hasJSGetterSetterCall = false;
</span><span class="lines">@@ -1315,7 +1317,7 @@
</span><span class="cx">         MacroAssembler::Label makeshiftCatchHandler = jit.label();
</span><span class="cx"> 
</span><span class="cx">         int stackPointerOffset = codeBlock-&gt;stackPointerOffset() * sizeof(EncodedJSValue);
</span><del>-        stackPointerOffset -= state.numberOfBytesUsedToPreserveReusedRegisters;
</del><ins>+        stackPointerOffset -= state.preservedReusedRegisterState.numberOfBytesPreserved;
</ins><span class="cx">         stackPointerOffset -= state.numberOfStackBytesUsedForRegisterPreservation();
</span><span class="cx"> 
</span><span class="cx">         jit.loadPtr(vm.addressOfCallFrameForCatch(), GPRInfo::callFrameRegister);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodePolymorphicAccessh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/PolymorphicAccess.h (194125 => 194126)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/PolymorphicAccess.h        2015-12-16 00:55:49 UTC (rev 194125)
+++ trunk/Source/JavaScriptCore/bytecode/PolymorphicAccess.h        2015-12-16 01:05:00 UTC (rev 194126)
</span><span class="lines">@@ -33,6 +33,7 @@
</span><span class="cx"> #include &quot;MacroAssembler.h&quot;
</span><span class="cx"> #include &quot;ObjectPropertyConditionSet.h&quot;
</span><span class="cx"> #include &quot;Opcode.h&quot;
</span><ins>+#include &quot;ScratchRegisterAllocator.h&quot;
</ins><span class="cx"> #include &quot;Structure.h&quot;
</span><span class="cx"> #include &lt;wtf/Vector.h&gt;
</span><span class="cx"> 
</span><span class="lines">@@ -349,7 +350,7 @@
</span><span class="cx">     }
</span><span class="cx">     CCallHelpers* jit { nullptr };
</span><span class="cx">     ScratchRegisterAllocator* allocator;
</span><del>-    unsigned numberOfBytesUsedToPreserveReusedRegisters { 0 };
</del><ins>+    ScratchRegisterAllocator::PreservedState preservedReusedRegisterState;
</ins><span class="cx">     PolymorphicAccess* access { nullptr };
</span><span class="cx">     StructureStubInfo* stubInfo { nullptr };
</span><span class="cx">     MacroAssembler::JumpList success;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLCompileBinaryOpcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ftl/FTLCompileBinaryOp.cpp (194125 => 194126)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLCompileBinaryOp.cpp        2015-12-16 00:55:49 UTC (rev 194125)
+++ trunk/Source/JavaScriptCore/ftl/FTLCompileBinaryOp.cpp        2015-12-16 01:05:00 UTC (rev 194126)
</span><span class="lines">@@ -178,7 +178,7 @@
</span><span class="cx">     SnippetGenerator gen(ic.leftOperand(), ic.rightOperand(), JSValueRegs(result),
</span><span class="cx">         JSValueRegs(left), JSValueRegs(right), scratchGPR);
</span><span class="cx"> 
</span><del>-    unsigned numberOfBytesUsedToPreserveReusedRegisters =
</del><ins>+    ScratchRegisterAllocator::PreservedState preservedState =
</ins><span class="cx">         allocator.preserveReusedRegistersByPushing(jit, ScratchRegisterAllocator::ExtraStackSpace::NoExtraSpace);
</span><span class="cx"> 
</span><span class="cx">     context.initializeRegisters(jit);
</span><span class="lines">@@ -188,14 +188,12 @@
</span><span class="cx">     gen.endJumpList().link(&amp;jit);
</span><span class="cx"> 
</span><span class="cx">     context.restoreRegisters(jit);
</span><del>-    allocator.restoreReusedRegistersByPopping(jit, numberOfBytesUsedToPreserveReusedRegisters,
-        ScratchRegisterAllocator::ExtraStackSpace::NoExtraSpace);
</del><ins>+    allocator.restoreReusedRegistersByPopping(jit, preservedState);
</ins><span class="cx">     done = jit.jump();
</span><span class="cx"> 
</span><span class="cx">     gen.slowPathJumpList().link(&amp;jit);
</span><span class="cx">     context.restoreRegisters(jit);
</span><del>-    allocator.restoreReusedRegistersByPopping(jit, numberOfBytesUsedToPreserveReusedRegisters,
-        ScratchRegisterAllocator::ExtraStackSpace::NoExtraSpace);
</del><ins>+    allocator.restoreReusedRegistersByPopping(jit, preservedState);
</ins><span class="cx">     slowPathStart = jit.jump();
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -214,7 +212,7 @@
</span><span class="cx">     JITRightShiftGenerator gen(ic.leftOperand(), ic.rightOperand(), JSValueRegs(result),
</span><span class="cx">         JSValueRegs(left), JSValueRegs(right), leftFPR, scratchGPR, InvalidFPRReg, shiftType);
</span><span class="cx"> 
</span><del>-    unsigned numberOfBytesUsedToPreserveReusedRegisters =
</del><ins>+    ScratchRegisterAllocator::PreservedState preservedState =
</ins><span class="cx">         allocator.preserveReusedRegistersByPushing(jit, ScratchRegisterAllocator::ExtraStackSpace::NoExtraSpace);
</span><span class="cx"> 
</span><span class="cx">     context.initializeRegisters(jit);
</span><span class="lines">@@ -223,14 +221,12 @@
</span><span class="cx">     ASSERT(gen.didEmitFastPath());
</span><span class="cx">     gen.endJumpList().link(&amp;jit);
</span><span class="cx">     context.restoreRegisters(jit);
</span><del>-    allocator.restoreReusedRegistersByPopping(jit, numberOfBytesUsedToPreserveReusedRegisters,
-        ScratchRegisterAllocator::ExtraStackSpace::NoExtraSpace);
</del><ins>+    allocator.restoreReusedRegistersByPopping(jit, preservedState);
</ins><span class="cx">     done = jit.jump();
</span><span class="cx"> 
</span><span class="cx">     gen.slowPathJumpList().link(&amp;jit);
</span><span class="cx">     context.restoreRegisters(jit);
</span><del>-    allocator.restoreReusedRegistersByPopping(jit, numberOfBytesUsedToPreserveReusedRegisters,
-        ScratchRegisterAllocator::ExtraStackSpace::NoExtraSpace);
</del><ins>+    allocator.restoreReusedRegistersByPopping(jit, preservedState);
</ins><span class="cx">     slowPathStart = jit.jump();
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -253,7 +249,7 @@
</span><span class="cx">     BinaryArithOpGenerator gen(ic.leftOperand(), ic.rightOperand(), JSValueRegs(result),
</span><span class="cx">         JSValueRegs(left), JSValueRegs(right), leftFPR, rightFPR, scratchGPR, scratchFPR);
</span><span class="cx"> 
</span><del>-    unsigned numberOfBytesUsedToPreserveReusedRegisters =
</del><ins>+    ScratchRegisterAllocator::PreservedState preservedState =
</ins><span class="cx">         allocator.preserveReusedRegistersByPushing(jit, ScratchRegisterAllocator::ExtraStackSpace::NoExtraSpace);
</span><span class="cx"> 
</span><span class="cx">     context.initializeRegisters(jit);
</span><span class="lines">@@ -262,14 +258,12 @@
</span><span class="cx">     ASSERT(gen.didEmitFastPath());
</span><span class="cx">     gen.endJumpList().link(&amp;jit);
</span><span class="cx">     context.restoreRegisters(jit);
</span><del>-    allocator.restoreReusedRegistersByPopping(jit, numberOfBytesUsedToPreserveReusedRegisters,
-        ScratchRegisterAllocator::ExtraStackSpace::NoExtraSpace);
</del><ins>+    allocator.restoreReusedRegistersByPopping(jit, preservedState);
</ins><span class="cx">     done = jit.jump();
</span><span class="cx"> 
</span><span class="cx">     gen.slowPathJumpList().link(&amp;jit);
</span><span class="cx">     context.restoreRegisters(jit);
</span><del>-    allocator.restoreReusedRegistersByPopping(jit, numberOfBytesUsedToPreserveReusedRegisters,
-        ScratchRegisterAllocator::ExtraStackSpace::NoExtraSpace);
</del><ins>+    allocator.restoreReusedRegistersByPopping(jit, preservedState);
</ins><span class="cx">     slowPathStart = jit.jump();
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLLazySlowPathcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ftl/FTLLazySlowPath.cpp (194125 => 194126)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLLazySlowPath.cpp        2015-12-16 00:55:49 UTC (rev 194125)
+++ trunk/Source/JavaScriptCore/ftl/FTLLazySlowPath.cpp        2015-12-16 01:05:00 UTC (rev 194126)
</span><span class="lines">@@ -79,7 +79,8 @@
</span><span class="cx">     params.lazySlowPath = this;
</span><span class="cx"> 
</span><span class="cx"> #if !FTL_USES_B3
</span><del>-    unsigned bytesSaved = m_scratchRegisterAllocator.preserveReusedRegistersByPushing(jit, ScratchRegisterAllocator::ExtraStackSpace::NoExtraSpace);
</del><ins>+    ScratchRegisterAllocator::PreservedState preservedState =
+        m_scratchRegisterAllocator.preserveReusedRegistersByPushing(jit, ScratchRegisterAllocator::ExtraStackSpace::NoExtraSpace);
</ins><span class="cx">     // This is needed because LLVM may create a stackmap location that is the register SP.
</span><span class="cx">     // But on arm64, SP is also the same register number as ZR, so LLVM is telling us that it has
</span><span class="cx">     // proven something is zero. Our MASM isn't universally compatible with arm64's context dependent
</span><span class="lines">@@ -94,9 +95,9 @@
</span><span class="cx"> #if !FTL_USES_B3
</span><span class="cx">     CCallHelpers::Label doneLabel;
</span><span class="cx">     CCallHelpers::Jump jumpToEndOfPatchpoint;
</span><del>-    if (bytesSaved) {
</del><ins>+    if (preservedState.numberOfBytesPreserved) {
</ins><span class="cx">         doneLabel = jit.label();
</span><del>-        m_scratchRegisterAllocator.restoreReusedRegistersByPopping(jit, bytesSaved, ScratchRegisterAllocator::ExtraStackSpace::NoExtraSpace);
</del><ins>+        m_scratchRegisterAllocator.restoreReusedRegistersByPopping(jit, preservedState);
</ins><span class="cx">         jumpToEndOfPatchpoint = jit.jump();
</span><span class="cx">     }
</span><span class="cx"> #endif // !FTL_USES_B3
</span><span class="lines">@@ -105,7 +106,7 @@
</span><span class="cx"> #if FTL_USES_B3
</span><span class="cx">     linkBuffer.link(params.doneJumps, m_done);
</span><span class="cx"> #else // FTL_USES_B3
</span><del>-    if (bytesSaved) {
</del><ins>+    if (preservedState.numberOfBytesPreserved) {
</ins><span class="cx">         linkBuffer.link(params.doneJumps, linkBuffer.locationOf(doneLabel));
</span><span class="cx">         linkBuffer.link(jumpToEndOfPatchpoint, m_patchpoint.labelAtOffset(MacroAssembler::maxJumpReplacementSize()));
</span><span class="cx">     } else
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLLowerDFGToLLVMcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp (194125 => 194126)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp        2015-12-16 00:55:49 UTC (rev 194125)
+++ trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp        2015-12-16 01:05:00 UTC (rev 194126)
</span><span class="lines">@@ -9342,7 +9342,7 @@
</span><span class="cx">                         GPRReg scratch1 = scratchRegisterAllocator.allocateScratchGPR();
</span><span class="cx">                         GPRReg scratch2 = scratchRegisterAllocator.allocateScratchGPR();
</span><span class="cx"> 
</span><del>-                        unsigned bytesPushed =
</del><ins>+                        ScratchRegisterAllocator::PreservedState preservedState =
</ins><span class="cx">                             scratchRegisterAllocator.preserveReusedRegistersByPushing(jit, ScratchRegisterAllocator::ExtraStackSpace::SpaceForCCall);
</span><span class="cx"> 
</span><span class="cx">                         // We've already saved these, so when we make a slow path call, we don't have
</span><span class="lines">@@ -9365,7 +9365,7 @@
</span><span class="cx">                                 scratch1, scratch2, CCallHelpers::ScalePtr,
</span><span class="cx">                                 static_cast&lt;int32_t&gt;(-sizeof(void*))));
</span><span class="cx"> 
</span><del>-                        scratchRegisterAllocator.restoreReusedRegistersByPopping(jit, bytesPushed, ScratchRegisterAllocator::ExtraStackSpace::SpaceForCCall);
</del><ins>+                        scratchRegisterAllocator.restoreReusedRegistersByPopping(jit, preservedState);
</ins><span class="cx"> 
</span><span class="cx">                         params.doneJumps.append(jit.jump());
</span><span class="cx"> 
</span><span class="lines">@@ -9374,7 +9374,7 @@
</span><span class="cx">                             usedRegisters, jit, params.lazySlowPath-&gt;callSiteIndex(),
</span><span class="cx">                             params.exceptionJumps, operationFlushWriteBarrierBuffer, InvalidGPRReg,
</span><span class="cx">                             baseGPR);
</span><del>-                        scratchRegisterAllocator.restoreReusedRegistersByPopping(jit, bytesPushed, ScratchRegisterAllocator::ExtraStackSpace::SpaceForCCall);
</del><ins>+                        scratchRegisterAllocator.restoreReusedRegistersByPopping(jit, preservedState);
</ins><span class="cx">                         params.doneJumps.append(jit.jump());
</span><span class="cx">                     });
</span><span class="cx">             },
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitScratchRegisterAllocatorcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/ScratchRegisterAllocator.cpp (194125 => 194126)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/ScratchRegisterAllocator.cpp        2015-12-16 00:55:49 UTC (rev 194125)
+++ trunk/Source/JavaScriptCore/jit/ScratchRegisterAllocator.cpp        2015-12-16 01:05:00 UTC (rev 194126)
</span><span class="lines">@@ -102,10 +102,10 @@
</span><span class="cx"> GPRReg ScratchRegisterAllocator::allocateScratchGPR() { return allocateScratch&lt;GPRInfo&gt;(); }
</span><span class="cx"> FPRReg ScratchRegisterAllocator::allocateScratchFPR() { return allocateScratch&lt;FPRInfo&gt;(); }
</span><span class="cx"> 
</span><del>-unsigned ScratchRegisterAllocator::preserveReusedRegistersByPushing(MacroAssembler&amp; jit, ExtraStackSpace extraStackSpace)
</del><ins>+ScratchRegisterAllocator::PreservedState ScratchRegisterAllocator::preserveReusedRegistersByPushing(MacroAssembler&amp; jit, ExtraStackSpace extraStackSpace)
</ins><span class="cx"> {
</span><span class="cx">     if (!didReuseRegisters())
</span><del>-        return 0;
</del><ins>+        return PreservedState(0, extraStackSpace);
</ins><span class="cx"> 
</span><span class="cx">     RegisterSet registersToSpill;
</span><span class="cx">     for (unsigned i = 0; i &lt; FPRInfo::numberOfRegisters; ++i) {
</span><span class="lines">@@ -122,10 +122,10 @@
</span><span class="cx">     unsigned extraStackBytesAtTopOfStack = extraStackSpace == ExtraStackSpace::SpaceForCCall ? maxFrameExtentForSlowPathCall : 0;
</span><span class="cx">     unsigned stackAdjustmentSize = ScratchRegisterAllocator::preserveRegistersToStackForCall(jit, registersToSpill, extraStackBytesAtTopOfStack);
</span><span class="cx"> 
</span><del>-    return stackAdjustmentSize;
</del><ins>+    return PreservedState(stackAdjustmentSize, extraStackSpace);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-void ScratchRegisterAllocator::restoreReusedRegistersByPopping(MacroAssembler&amp; jit, unsigned numberOfBytesUsedToPreserveReusedRegisters, ExtraStackSpace extraStackSpace)
</del><ins>+void ScratchRegisterAllocator::restoreReusedRegistersByPopping(MacroAssembler&amp; jit, const ScratchRegisterAllocator::PreservedState preservedState)
</ins><span class="cx"> {
</span><span class="cx">     if (!didReuseRegisters())
</span><span class="cx">         return;
</span><span class="lines">@@ -142,9 +142,11 @@
</span><span class="cx">             registersToFill.set(reg);
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    unsigned extraStackBytesAtTopOfStack = extraStackSpace == ExtraStackSpace::SpaceForCCall ? maxFrameExtentForSlowPathCall : 0;
</del><ins>+    unsigned extraStackBytesAtTopOfStack =
+        preservedState.extraStackSpaceRequirement == ExtraStackSpace::SpaceForCCall ? maxFrameExtentForSlowPathCall : 0;
</ins><span class="cx">     RegisterSet dontRestore; // Empty set. We want to restore everything.
</span><del>-    ScratchRegisterAllocator::restoreRegistersFromStackForCall(jit, registersToFill, dontRestore, numberOfBytesUsedToPreserveReusedRegisters, extraStackBytesAtTopOfStack);
</del><ins>+    ScratchRegisterAllocator::restoreRegistersFromStackForCall(jit, registersToFill, dontRestore,
+        preservedState.numberOfBytesPreserved, extraStackBytesAtTopOfStack);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> RegisterSet ScratchRegisterAllocator::usedRegistersForCall() const
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitScratchRegisterAllocatorh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/ScratchRegisterAllocator.h (194125 => 194126)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/ScratchRegisterAllocator.h        2015-12-16 00:55:49 UTC (rev 194125)
+++ trunk/Source/JavaScriptCore/jit/ScratchRegisterAllocator.h        2015-12-16 01:05:00 UTC (rev 194126)
</span><span class="lines">@@ -67,8 +67,23 @@
</span><span class="cx">     RegisterSet usedRegisters() const { return m_usedRegisters; }
</span><span class="cx">     
</span><span class="cx">     enum class ExtraStackSpace { SpaceForCCall, NoExtraSpace };
</span><del>-    unsigned preserveReusedRegistersByPushing(MacroAssembler&amp; jit, ExtraStackSpace);
-    void restoreReusedRegistersByPopping(MacroAssembler&amp; jit, unsigned numberOfBytesUsedToPreserveReusedRegisters, ExtraStackSpace);
</del><ins>+
+    struct PreservedState {
+        PreservedState()
+            : PreservedState(0)
+        { }
+
+        PreservedState(unsigned numberOfBytes, ExtraStackSpace extraStackSpace = ExtraStackSpace::NoExtraSpace)
+            : numberOfBytesPreserved(numberOfBytes)
+            , extraStackSpaceRequirement(extraStackSpace)
+        { }
+
+        unsigned numberOfBytesPreserved;
+        ExtraStackSpace extraStackSpaceRequirement;
+    };
+
+    PreservedState preserveReusedRegistersByPushing(MacroAssembler&amp; jit, ExtraStackSpace);
+    void restoreReusedRegistersByPopping(MacroAssembler&amp; jit, PreservedState);
</ins><span class="cx">     
</span><span class="cx">     RegisterSet usedRegistersForCall() const;
</span><span class="cx">     
</span></span></pre>
</div>
</div>

</body>
</html>