Introducing ScratchRegisterAllocator::PreservedState.
authormark.lam@apple.com <mark.lam@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 16 Dec 2015 01:05:00 +0000 (01:05 +0000)
committermark.lam@apple.com <mark.lam@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 16 Dec 2015 01:05:00 +0000 (01:05 +0000)
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):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@194126 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
Source/JavaScriptCore/bytecode/PolymorphicAccess.cpp
Source/JavaScriptCore/bytecode/PolymorphicAccess.h
Source/JavaScriptCore/ftl/FTLCompileBinaryOp.cpp
Source/JavaScriptCore/ftl/FTLLazySlowPath.cpp
Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp
Source/JavaScriptCore/jit/ScratchRegisterAllocator.cpp
Source/JavaScriptCore/jit/ScratchRegisterAllocator.h

index 8492bfa..df5b844 100644 (file)
@@ -1,5 +1,43 @@
 2015-12-15  Mark Lam  <mark.lam@apple.com>
 
+        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  <mark.lam@apple.com>
+
         Polymorphic operand types for DFG and FTL bit operators.
         https://bugs.webkit.org/show_bug.cgi?id=152191
 
index 3a25eba..256732d 100644 (file)
                0F24E54F17EE274900ABB217 /* TempRegisterSet.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F24E54817EE274900ABB217 /* TempRegisterSet.h */; settings = {ATTRIBUTES = (Private, ); }; };
                0F24E55017EE274900ABB217 /* Repatch.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F24E54917EE274900ABB217 /* Repatch.cpp */; };
                0F24E55117EE274900ABB217 /* Repatch.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F24E54A17EE274900ABB217 /* Repatch.h */; };
-               0F24E55217EE274900ABB217 /* ScratchRegisterAllocator.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F24E54B17EE274900ABB217 /* ScratchRegisterAllocator.h */; };
+               0F24E55217EE274900ABB217 /* ScratchRegisterAllocator.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F24E54B17EE274900ABB217 /* ScratchRegisterAllocator.h */; settings = {ATTRIBUTES = (Private, ); }; };
                0F24E55517F0B71C00ABB217 /* InlineCallFrameSet.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F24E55317F0B71C00ABB217 /* InlineCallFrameSet.cpp */; };
                0F24E55617F0B71C00ABB217 /* InlineCallFrameSet.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F24E55417F0B71C00ABB217 /* InlineCallFrameSet.h */; settings = {ATTRIBUTES = (Private, ); }; };
                0F24E55817F74EDB00ABB217 /* ValueRecovery.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F24E55717F74EDB00ABB217 /* ValueRecovery.cpp */; };
index 983ec47..a48998c 100644 (file)
@@ -54,7 +54,7 @@ Watchpoint* AccessGenerationState::addWatchpoint(const ObjectPropertyCondition&
 
 void AccessGenerationState::restoreScratch()
 {
-    allocator->restoreReusedRegistersByPopping(*jit, numberOfBytesUsedToPreserveReusedRegisters, ScratchRegisterAllocator::ExtraStackSpace::NoExtraSpace);
+    allocator->restoreReusedRegistersByPopping(*jit, preservedReusedRegisterState);
 }
 
 void AccessGenerationState::succeed()
@@ -727,7 +727,7 @@ void AccessCase::generate(AccessGenerationState& state)
 
             done.link(&jit);
 
-            jit.addPtr(CCallHelpers::TrustedImm32((jit.codeBlock()->stackPointerOffset() * sizeof(Register)) - state.numberOfBytesUsedToPreserveReusedRegisters - state.numberOfStackBytesUsedForRegisterPreservation()),
+            jit.addPtr(CCallHelpers::TrustedImm32((jit.codeBlock()->stackPointerOffset() * sizeof(Register)) - state.preservedReusedRegisterState.numberOfBytesPreserved - state.numberOfStackBytesUsedForRegisterPreservation()),
                 GPRInfo::callFrameRegister, CCallHelpers::stackPointerRegister);
             state.restoreLiveRegistersFromStackForCall(isGetter());
 
@@ -886,12 +886,13 @@ void AccessCase::generate(AccessGenerationState& state)
         else
             scratchGPR3 = InvalidGPRReg;
 
-        size_t numberOfBytesUsedToPreserveReusedRegisters = allocator.preserveReusedRegistersByPushing(jit, ScratchRegisterAllocator::ExtraStackSpace::SpaceForCCall);
+        ScratchRegisterAllocator::PreservedState preservedState =
+            allocator.preserveReusedRegistersByPushing(jit, ScratchRegisterAllocator::ExtraStackSpace::SpaceForCCall);
 
         ASSERT(structure()->transitionWatchpointSetHasBeenInvalidated());
 
         bool scratchGPRHasStorage = false;
-        bool needsToMakeRoomOnStackForCCall = !numberOfBytesUsedToPreserveReusedRegisters && codeBlock->jitType() == JITCode::FTLJIT;
+        bool needsToMakeRoomOnStackForCCall = !preservedState.numberOfBytesPreserved && codeBlock->jitType() == JITCode::FTLJIT;
 
         if (newStructure()->outOfLineCapacity() != structure()->outOfLineCapacity()) {
             size_t newSize = newStructure()->outOfLineCapacity() * sizeof(JSValue);
@@ -1016,12 +1017,12 @@ void AccessCase::generate(AccessGenerationState& state)
                 });
         }
         
-        allocator.restoreReusedRegistersByPopping(jit, numberOfBytesUsedToPreserveReusedRegisters, ScratchRegisterAllocator::ExtraStackSpace::SpaceForCCall);
+        allocator.restoreReusedRegistersByPopping(jit, preservedState);
         state.succeed();
 
         if (newStructure()->outOfLineCapacity() != structure()->outOfLineCapacity()) {
             slowPath.link(&jit);
-            allocator.restoreReusedRegistersByPopping(jit, numberOfBytesUsedToPreserveReusedRegisters, ScratchRegisterAllocator::ExtraStackSpace::SpaceForCCall);
+            allocator.restoreReusedRegistersByPopping(jit, preservedState);
             allocator.preserveUsedRegistersToScratchBufferForCall(jit, scratchBuffer, scratchGPR);
             if (needsToMakeRoomOnStackForCCall)
                 jit.makeSpaceOnStackForCCall();
@@ -1245,7 +1246,8 @@ MacroAssemblerCodePtr PolymorphicAccess::regenerate(
     CCallHelpers jit(&vm, codeBlock);
     state.jit = &jit;
 
-    state.numberOfBytesUsedToPreserveReusedRegisters = allocator.preserveReusedRegistersByPushing(jit, ScratchRegisterAllocator::ExtraStackSpace::NoExtraSpace);
+    state.preservedReusedRegisterState =
+        allocator.preserveReusedRegistersByPushing(jit, ScratchRegisterAllocator::ExtraStackSpace::NoExtraSpace);
 
     bool allGuardedByStructureCheck = true;
     bool hasJSGetterSetterCall = false;
@@ -1315,7 +1317,7 @@ MacroAssemblerCodePtr PolymorphicAccess::regenerate(
         MacroAssembler::Label makeshiftCatchHandler = jit.label();
 
         int stackPointerOffset = codeBlock->stackPointerOffset() * sizeof(EncodedJSValue);
-        stackPointerOffset -= state.numberOfBytesUsedToPreserveReusedRegisters;
+        stackPointerOffset -= state.preservedReusedRegisterState.numberOfBytesPreserved;
         stackPointerOffset -= state.numberOfStackBytesUsedForRegisterPreservation();
 
         jit.loadPtr(vm.addressOfCallFrameForCatch(), GPRInfo::callFrameRegister);
index 3505281..280d46e 100644 (file)
@@ -33,6 +33,7 @@
 #include "MacroAssembler.h"
 #include "ObjectPropertyConditionSet.h"
 #include "Opcode.h"
+#include "ScratchRegisterAllocator.h"
 #include "Structure.h"
 #include <wtf/Vector.h>
 
@@ -349,7 +350,7 @@ struct AccessGenerationState {
     }
     CCallHelpers* jit { nullptr };
     ScratchRegisterAllocator* allocator;
-    unsigned numberOfBytesUsedToPreserveReusedRegisters { 0 };
+    ScratchRegisterAllocator::PreservedState preservedReusedRegisterState;
     PolymorphicAccess* access { nullptr };
     StructureStubInfo* stubInfo { nullptr };
     MacroAssembler::JumpList success;
index 6c23d43..4345f84 100644 (file)
@@ -178,7 +178,7 @@ void generateBinaryBitOpFastPath(BinaryOpDescriptor& ic, CCallHelpers& jit,
     SnippetGenerator gen(ic.leftOperand(), ic.rightOperand(), JSValueRegs(result),
         JSValueRegs(left), JSValueRegs(right), scratchGPR);
 
-    unsigned numberOfBytesUsedToPreserveReusedRegisters =
+    ScratchRegisterAllocator::PreservedState preservedState =
         allocator.preserveReusedRegistersByPushing(jit, ScratchRegisterAllocator::ExtraStackSpace::NoExtraSpace);
 
     context.initializeRegisters(jit);
@@ -188,14 +188,12 @@ void generateBinaryBitOpFastPath(BinaryOpDescriptor& ic, CCallHelpers& jit,
     gen.endJumpList().link(&jit);
 
     context.restoreRegisters(jit);
-    allocator.restoreReusedRegistersByPopping(jit, numberOfBytesUsedToPreserveReusedRegisters,
-        ScratchRegisterAllocator::ExtraStackSpace::NoExtraSpace);
+    allocator.restoreReusedRegistersByPopping(jit, preservedState);
     done = jit.jump();
 
     gen.slowPathJumpList().link(&jit);
     context.restoreRegisters(jit);
-    allocator.restoreReusedRegistersByPopping(jit, numberOfBytesUsedToPreserveReusedRegisters,
-        ScratchRegisterAllocator::ExtraStackSpace::NoExtraSpace);
+    allocator.restoreReusedRegistersByPopping(jit, preservedState);
     slowPathStart = jit.jump();
 }
 
@@ -214,7 +212,7 @@ static void generateRightShiftFastPath(BinaryOpDescriptor& ic, CCallHelpers& jit
     JITRightShiftGenerator gen(ic.leftOperand(), ic.rightOperand(), JSValueRegs(result),
         JSValueRegs(left), JSValueRegs(right), leftFPR, scratchGPR, InvalidFPRReg, shiftType);
 
-    unsigned numberOfBytesUsedToPreserveReusedRegisters =
+    ScratchRegisterAllocator::PreservedState preservedState =
         allocator.preserveReusedRegistersByPushing(jit, ScratchRegisterAllocator::ExtraStackSpace::NoExtraSpace);
 
     context.initializeRegisters(jit);
@@ -223,14 +221,12 @@ static void generateRightShiftFastPath(BinaryOpDescriptor& ic, CCallHelpers& jit
     ASSERT(gen.didEmitFastPath());
     gen.endJumpList().link(&jit);
     context.restoreRegisters(jit);
-    allocator.restoreReusedRegistersByPopping(jit, numberOfBytesUsedToPreserveReusedRegisters,
-        ScratchRegisterAllocator::ExtraStackSpace::NoExtraSpace);
+    allocator.restoreReusedRegistersByPopping(jit, preservedState);
     done = jit.jump();
 
     gen.slowPathJumpList().link(&jit);
     context.restoreRegisters(jit);
-    allocator.restoreReusedRegistersByPopping(jit, numberOfBytesUsedToPreserveReusedRegisters,
-        ScratchRegisterAllocator::ExtraStackSpace::NoExtraSpace);
+    allocator.restoreReusedRegistersByPopping(jit, preservedState);
     slowPathStart = jit.jump();
 }
 
@@ -253,7 +249,7 @@ void generateBinaryArithOpFastPath(BinaryOpDescriptor& ic, CCallHelpers& jit,
     BinaryArithOpGenerator gen(ic.leftOperand(), ic.rightOperand(), JSValueRegs(result),
         JSValueRegs(left), JSValueRegs(right), leftFPR, rightFPR, scratchGPR, scratchFPR);
 
-    unsigned numberOfBytesUsedToPreserveReusedRegisters =
+    ScratchRegisterAllocator::PreservedState preservedState =
         allocator.preserveReusedRegistersByPushing(jit, ScratchRegisterAllocator::ExtraStackSpace::NoExtraSpace);
 
     context.initializeRegisters(jit);
@@ -262,14 +258,12 @@ void generateBinaryArithOpFastPath(BinaryOpDescriptor& ic, CCallHelpers& jit,
     ASSERT(gen.didEmitFastPath());
     gen.endJumpList().link(&jit);
     context.restoreRegisters(jit);
-    allocator.restoreReusedRegistersByPopping(jit, numberOfBytesUsedToPreserveReusedRegisters,
-        ScratchRegisterAllocator::ExtraStackSpace::NoExtraSpace);
+    allocator.restoreReusedRegistersByPopping(jit, preservedState);
     done = jit.jump();
 
     gen.slowPathJumpList().link(&jit);
     context.restoreRegisters(jit);
-    allocator.restoreReusedRegistersByPopping(jit, numberOfBytesUsedToPreserveReusedRegisters,
-        ScratchRegisterAllocator::ExtraStackSpace::NoExtraSpace);
+    allocator.restoreReusedRegistersByPopping(jit, preservedState);
     slowPathStart = jit.jump();
 }
 
index f04b9ba..78a28ff 100644 (file)
@@ -79,7 +79,8 @@ void LazySlowPath::generate(CodeBlock* codeBlock)
     params.lazySlowPath = this;
 
 #if !FTL_USES_B3
-    unsigned bytesSaved = m_scratchRegisterAllocator.preserveReusedRegistersByPushing(jit, ScratchRegisterAllocator::ExtraStackSpace::NoExtraSpace);
+    ScratchRegisterAllocator::PreservedState preservedState =
+        m_scratchRegisterAllocator.preserveReusedRegistersByPushing(jit, ScratchRegisterAllocator::ExtraStackSpace::NoExtraSpace);
     // This is needed because LLVM may create a stackmap location that is the register SP.
     // But on arm64, SP is also the same register number as ZR, so LLVM is telling us that it has
     // proven something is zero. Our MASM isn't universally compatible with arm64's context dependent
@@ -94,9 +95,9 @@ void LazySlowPath::generate(CodeBlock* codeBlock)
 #if !FTL_USES_B3
     CCallHelpers::Label doneLabel;
     CCallHelpers::Jump jumpToEndOfPatchpoint;
-    if (bytesSaved) {
+    if (preservedState.numberOfBytesPreserved) {
         doneLabel = jit.label();
-        m_scratchRegisterAllocator.restoreReusedRegistersByPopping(jit, bytesSaved, ScratchRegisterAllocator::ExtraStackSpace::NoExtraSpace);
+        m_scratchRegisterAllocator.restoreReusedRegistersByPopping(jit, preservedState);
         jumpToEndOfPatchpoint = jit.jump();
     }
 #endif // !FTL_USES_B3
@@ -105,7 +106,7 @@ void LazySlowPath::generate(CodeBlock* codeBlock)
 #if FTL_USES_B3
     linkBuffer.link(params.doneJumps, m_done);
 #else // FTL_USES_B3
-    if (bytesSaved) {
+    if (preservedState.numberOfBytesPreserved) {
         linkBuffer.link(params.doneJumps, linkBuffer.locationOf(doneLabel));
         linkBuffer.link(jumpToEndOfPatchpoint, m_patchpoint.labelAtOffset(MacroAssembler::maxJumpReplacementSize()));
     } else
index 541328f..06b5bc0 100644 (file)
@@ -9342,7 +9342,7 @@ private:
                         GPRReg scratch1 = scratchRegisterAllocator.allocateScratchGPR();
                         GPRReg scratch2 = scratchRegisterAllocator.allocateScratchGPR();
 
-                        unsigned bytesPushed =
+                        ScratchRegisterAllocator::PreservedState preservedState =
                             scratchRegisterAllocator.preserveReusedRegistersByPushing(jit, ScratchRegisterAllocator::ExtraStackSpace::SpaceForCCall);
 
                         // We've already saved these, so when we make a slow path call, we don't have
@@ -9365,7 +9365,7 @@ private:
                                 scratch1, scratch2, CCallHelpers::ScalePtr,
                                 static_cast<int32_t>(-sizeof(void*))));
 
-                        scratchRegisterAllocator.restoreReusedRegistersByPopping(jit, bytesPushed, ScratchRegisterAllocator::ExtraStackSpace::SpaceForCCall);
+                        scratchRegisterAllocator.restoreReusedRegistersByPopping(jit, preservedState);
 
                         params.doneJumps.append(jit.jump());
 
@@ -9374,7 +9374,7 @@ private:
                             usedRegisters, jit, params.lazySlowPath->callSiteIndex(),
                             params.exceptionJumps, operationFlushWriteBarrierBuffer, InvalidGPRReg,
                             baseGPR);
-                        scratchRegisterAllocator.restoreReusedRegistersByPopping(jit, bytesPushed, ScratchRegisterAllocator::ExtraStackSpace::SpaceForCCall);
+                        scratchRegisterAllocator.restoreReusedRegistersByPopping(jit, preservedState);
                         params.doneJumps.append(jit.jump());
                     });
             },
index 70c4d4c..7b05be7 100644 (file)
@@ -102,10 +102,10 @@ typename BankInfo::RegisterType ScratchRegisterAllocator::allocateScratch()
 GPRReg ScratchRegisterAllocator::allocateScratchGPR() { return allocateScratch<GPRInfo>(); }
 FPRReg ScratchRegisterAllocator::allocateScratchFPR() { return allocateScratch<FPRInfo>(); }
 
-unsigned ScratchRegisterAllocator::preserveReusedRegistersByPushing(MacroAssembler& jit, ExtraStackSpace extraStackSpace)
+ScratchRegisterAllocator::PreservedState ScratchRegisterAllocator::preserveReusedRegistersByPushing(MacroAssembler& jit, ExtraStackSpace extraStackSpace)
 {
     if (!didReuseRegisters())
-        return 0;
+        return PreservedState(0, extraStackSpace);
 
     RegisterSet registersToSpill;
     for (unsigned i = 0; i < FPRInfo::numberOfRegisters; ++i) {
@@ -122,10 +122,10 @@ unsigned ScratchRegisterAllocator::preserveReusedRegistersByPushing(MacroAssembl
     unsigned extraStackBytesAtTopOfStack = extraStackSpace == ExtraStackSpace::SpaceForCCall ? maxFrameExtentForSlowPathCall : 0;
     unsigned stackAdjustmentSize = ScratchRegisterAllocator::preserveRegistersToStackForCall(jit, registersToSpill, extraStackBytesAtTopOfStack);
 
-    return stackAdjustmentSize;
+    return PreservedState(stackAdjustmentSize, extraStackSpace);
 }
 
-void ScratchRegisterAllocator::restoreReusedRegistersByPopping(MacroAssembler& jit, unsigned numberOfBytesUsedToPreserveReusedRegisters, ExtraStackSpace extraStackSpace)
+void ScratchRegisterAllocator::restoreReusedRegistersByPopping(MacroAssembler& jit, const ScratchRegisterAllocator::PreservedState preservedState)
 {
     if (!didReuseRegisters())
         return;
@@ -142,9 +142,11 @@ void ScratchRegisterAllocator::restoreReusedRegistersByPopping(MacroAssembler& j
             registersToFill.set(reg);
     }
 
-    unsigned extraStackBytesAtTopOfStack = extraStackSpace == ExtraStackSpace::SpaceForCCall ? maxFrameExtentForSlowPathCall : 0;
+    unsigned extraStackBytesAtTopOfStack =
+        preservedState.extraStackSpaceRequirement == ExtraStackSpace::SpaceForCCall ? maxFrameExtentForSlowPathCall : 0;
     RegisterSet dontRestore; // Empty set. We want to restore everything.
-    ScratchRegisterAllocator::restoreRegistersFromStackForCall(jit, registersToFill, dontRestore, numberOfBytesUsedToPreserveReusedRegisters, extraStackBytesAtTopOfStack);
+    ScratchRegisterAllocator::restoreRegistersFromStackForCall(jit, registersToFill, dontRestore,
+        preservedState.numberOfBytesPreserved, extraStackBytesAtTopOfStack);
 }
 
 RegisterSet ScratchRegisterAllocator::usedRegistersForCall() const
index 889cea5..f93b90a 100644 (file)
@@ -67,8 +67,23 @@ public:
     RegisterSet usedRegisters() const { return m_usedRegisters; }
     
     enum class ExtraStackSpace { SpaceForCCall, NoExtraSpace };
-    unsigned preserveReusedRegistersByPushing(MacroAssembler& jit, ExtraStackSpace);
-    void restoreReusedRegistersByPopping(MacroAssembler& jit, unsigned numberOfBytesUsedToPreserveReusedRegisters, ExtraStackSpace);
+
+    struct PreservedState {
+        PreservedState()
+            : PreservedState(0)
+        { }
+
+        PreservedState(unsigned numberOfBytes, ExtraStackSpace extraStackSpace = ExtraStackSpace::NoExtraSpace)
+            : numberOfBytesPreserved(numberOfBytes)
+            , extraStackSpaceRequirement(extraStackSpace)
+        { }
+
+        unsigned numberOfBytesPreserved;
+        ExtraStackSpace extraStackSpaceRequirement;
+    };
+
+    PreservedState preserveReusedRegistersByPushing(MacroAssembler& jit, ExtraStackSpace);
+    void restoreReusedRegistersByPopping(MacroAssembler& jit, PreservedState);
     
     RegisterSet usedRegistersForCall() const;