Changeset 194126 in webkit


Ignore:
Timestamp:
Dec 15, 2015, 5:05:00 PM (9 years ago)
Author:
mark.lam@apple.com
Message:

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):

Location:
trunk/Source/JavaScriptCore
Files:
9 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/ChangeLog

    r194113 r194126  
     12015-12-15  Mark Lam  <mark.lam@apple.com>
     2
     3        Introducing ScratchRegisterAllocator::PreservedState.
     4        https://bugs.webkit.org/show_bug.cgi?id=152315
     5
     6        Reviewed by Geoffrey Garen.
     7
     8        restoreReusedRegistersByPopping() should always be called with 2 values that
     9        matches the expectation of preserveReusedRegistersByPushing().  Those 2 values
     10        are the number of bytes preserved and the ExtraStackSpace requirement.  By
     11        encapsulating them in a ScratchRegisterAllocator::PreservedState, we can make
     12        it less error prone when calling restoreReusedRegistersByPopping().  Now, we only
     13        need to pass it the appropriate PreservedState that its matching
     14        preserveReusedRegistersByPushing() returned.
     15
     16        * bytecode/PolymorphicAccess.cpp:
     17        (JSC::AccessGenerationState::restoreScratch):
     18        (JSC::AccessCase::generate):
     19        (JSC::PolymorphicAccess::regenerate):
     20        * bytecode/PolymorphicAccess.h:
     21        (JSC::AccessGenerationState::AccessGenerationState):
     22        * ftl/FTLCompileBinaryOp.cpp:
     23        (JSC::FTL::generateBinaryBitOpFastPath):
     24        (JSC::FTL::generateRightShiftFastPath):
     25        (JSC::FTL::generateBinaryArithOpFastPath):
     26        * ftl/FTLLazySlowPath.cpp:
     27        (JSC::FTL::LazySlowPath::generate):
     28        * ftl/FTLLowerDFGToLLVM.cpp:
     29        (JSC::FTL::DFG::LowerDFGToLLVM::emitStoreBarrier):
     30        * jit/ScratchRegisterAllocator.cpp:
     31        (JSC::ScratchRegisterAllocator::allocateScratchGPR):
     32        (JSC::ScratchRegisterAllocator::allocateScratchFPR):
     33        (JSC::ScratchRegisterAllocator::preserveReusedRegistersByPushing):
     34        (JSC::ScratchRegisterAllocator::restoreReusedRegistersByPopping):
     35        * jit/ScratchRegisterAllocator.h:
     36        (JSC::ScratchRegisterAllocator::usedRegisters):
     37        (JSC::ScratchRegisterAllocator::PreservedState::PreservedState):
     38
    1392015-12-15  Mark Lam  <mark.lam@apple.com>
    240
  • trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj

    r194067 r194126  
    159159                0F24E55017EE274900ABB217 /* Repatch.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F24E54917EE274900ABB217 /* Repatch.cpp */; };
    160160                0F24E55117EE274900ABB217 /* Repatch.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F24E54A17EE274900ABB217 /* Repatch.h */; };
    161                 0F24E55217EE274900ABB217 /* ScratchRegisterAllocator.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F24E54B17EE274900ABB217 /* ScratchRegisterAllocator.h */; };
     161                0F24E55217EE274900ABB217 /* ScratchRegisterAllocator.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F24E54B17EE274900ABB217 /* ScratchRegisterAllocator.h */; settings = {ATTRIBUTES = (Private, ); }; };
    162162                0F24E55517F0B71C00ABB217 /* InlineCallFrameSet.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F24E55317F0B71C00ABB217 /* InlineCallFrameSet.cpp */; };
    163163                0F24E55617F0B71C00ABB217 /* InlineCallFrameSet.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F24E55417F0B71C00ABB217 /* InlineCallFrameSet.h */; settings = {ATTRIBUTES = (Private, ); }; };
  • trunk/Source/JavaScriptCore/bytecode/PolymorphicAccess.cpp

    r192600 r194126  
    5555void AccessGenerationState::restoreScratch()
    5656{
    57     allocator->restoreReusedRegistersByPopping(*jit, numberOfBytesUsedToPreserveReusedRegisters, ScratchRegisterAllocator::ExtraStackSpace::NoExtraSpace);
     57    allocator->restoreReusedRegistersByPopping(*jit, preservedReusedRegisterState);
    5858}
    5959
     
    728728            done.link(&jit);
    729729
    730             jit.addPtr(CCallHelpers::TrustedImm32((jit.codeBlock()->stackPointerOffset() * sizeof(Register)) - state.numberOfBytesUsedToPreserveReusedRegisters - state.numberOfStackBytesUsedForRegisterPreservation()),
     730            jit.addPtr(CCallHelpers::TrustedImm32((jit.codeBlock()->stackPointerOffset() * sizeof(Register)) - state.preservedReusedRegisterState.numberOfBytesPreserved - state.numberOfStackBytesUsedForRegisterPreservation()),
    731731                GPRInfo::callFrameRegister, CCallHelpers::stackPointerRegister);
    732732            state.restoreLiveRegistersFromStackForCall(isGetter());
     
    887887            scratchGPR3 = InvalidGPRReg;
    888888
    889         size_t numberOfBytesUsedToPreserveReusedRegisters = allocator.preserveReusedRegistersByPushing(jit, ScratchRegisterAllocator::ExtraStackSpace::SpaceForCCall);
     889        ScratchRegisterAllocator::PreservedState preservedState =
     890            allocator.preserveReusedRegistersByPushing(jit, ScratchRegisterAllocator::ExtraStackSpace::SpaceForCCall);
    890891
    891892        ASSERT(structure()->transitionWatchpointSetHasBeenInvalidated());
    892893
    893894        bool scratchGPRHasStorage = false;
    894         bool needsToMakeRoomOnStackForCCall = !numberOfBytesUsedToPreserveReusedRegisters && codeBlock->jitType() == JITCode::FTLJIT;
     895        bool needsToMakeRoomOnStackForCCall = !preservedState.numberOfBytesPreserved && codeBlock->jitType() == JITCode::FTLJIT;
    895896
    896897        if (newStructure()->outOfLineCapacity() != structure()->outOfLineCapacity()) {
     
    10171018        }
    10181019       
    1019         allocator.restoreReusedRegistersByPopping(jit, numberOfBytesUsedToPreserveReusedRegisters, ScratchRegisterAllocator::ExtraStackSpace::SpaceForCCall);
     1020        allocator.restoreReusedRegistersByPopping(jit, preservedState);
    10201021        state.succeed();
    10211022
    10221023        if (newStructure()->outOfLineCapacity() != structure()->outOfLineCapacity()) {
    10231024            slowPath.link(&jit);
    1024             allocator.restoreReusedRegistersByPopping(jit, numberOfBytesUsedToPreserveReusedRegisters, ScratchRegisterAllocator::ExtraStackSpace::SpaceForCCall);
     1025            allocator.restoreReusedRegistersByPopping(jit, preservedState);
    10251026            allocator.preserveUsedRegistersToScratchBufferForCall(jit, scratchBuffer, scratchGPR);
    10261027            if (needsToMakeRoomOnStackForCCall)
     
    12461247    state.jit = &jit;
    12471248
    1248     state.numberOfBytesUsedToPreserveReusedRegisters = allocator.preserveReusedRegistersByPushing(jit, ScratchRegisterAllocator::ExtraStackSpace::NoExtraSpace);
     1249    state.preservedReusedRegisterState =
     1250        allocator.preserveReusedRegistersByPushing(jit, ScratchRegisterAllocator::ExtraStackSpace::NoExtraSpace);
    12491251
    12501252    bool allGuardedByStructureCheck = true;
     
    13161318
    13171319        int stackPointerOffset = codeBlock->stackPointerOffset() * sizeof(EncodedJSValue);
    1318         stackPointerOffset -= state.numberOfBytesUsedToPreserveReusedRegisters;
     1320        stackPointerOffset -= state.preservedReusedRegisterState.numberOfBytesPreserved;
    13191321        stackPointerOffset -= state.numberOfStackBytesUsedForRegisterPreservation();
    13201322
  • trunk/Source/JavaScriptCore/bytecode/PolymorphicAccess.h

    r191215 r194126  
    3434#include "ObjectPropertyConditionSet.h"
    3535#include "Opcode.h"
     36#include "ScratchRegisterAllocator.h"
    3637#include "Structure.h"
    3738#include <wtf/Vector.h>
     
    350351    CCallHelpers* jit { nullptr };
    351352    ScratchRegisterAllocator* allocator;
    352     unsigned numberOfBytesUsedToPreserveReusedRegisters { 0 };
     353    ScratchRegisterAllocator::PreservedState preservedReusedRegisterState;
    353354    PolymorphicAccess* access { nullptr };
    354355    StructureStubInfo* stubInfo { nullptr };
  • trunk/Source/JavaScriptCore/ftl/FTLCompileBinaryOp.cpp

    r194113 r194126  
    179179        JSValueRegs(left), JSValueRegs(right), scratchGPR);
    180180
    181     unsigned numberOfBytesUsedToPreserveReusedRegisters =
     181    ScratchRegisterAllocator::PreservedState preservedState =
    182182        allocator.preserveReusedRegistersByPushing(jit, ScratchRegisterAllocator::ExtraStackSpace::NoExtraSpace);
    183183
     
    189189
    190190    context.restoreRegisters(jit);
    191     allocator.restoreReusedRegistersByPopping(jit, numberOfBytesUsedToPreserveReusedRegisters,
    192         ScratchRegisterAllocator::ExtraStackSpace::NoExtraSpace);
     191    allocator.restoreReusedRegistersByPopping(jit, preservedState);
    193192    done = jit.jump();
    194193
    195194    gen.slowPathJumpList().link(&jit);
    196195    context.restoreRegisters(jit);
    197     allocator.restoreReusedRegistersByPopping(jit, numberOfBytesUsedToPreserveReusedRegisters,
    198         ScratchRegisterAllocator::ExtraStackSpace::NoExtraSpace);
     196    allocator.restoreReusedRegistersByPopping(jit, preservedState);
    199197    slowPathStart = jit.jump();
    200198}
     
    215213        JSValueRegs(left), JSValueRegs(right), leftFPR, scratchGPR, InvalidFPRReg, shiftType);
    216214
    217     unsigned numberOfBytesUsedToPreserveReusedRegisters =
     215    ScratchRegisterAllocator::PreservedState preservedState =
    218216        allocator.preserveReusedRegistersByPushing(jit, ScratchRegisterAllocator::ExtraStackSpace::NoExtraSpace);
    219217
     
    224222    gen.endJumpList().link(&jit);
    225223    context.restoreRegisters(jit);
    226     allocator.restoreReusedRegistersByPopping(jit, numberOfBytesUsedToPreserveReusedRegisters,
    227         ScratchRegisterAllocator::ExtraStackSpace::NoExtraSpace);
     224    allocator.restoreReusedRegistersByPopping(jit, preservedState);
    228225    done = jit.jump();
    229226
    230227    gen.slowPathJumpList().link(&jit);
    231228    context.restoreRegisters(jit);
    232     allocator.restoreReusedRegistersByPopping(jit, numberOfBytesUsedToPreserveReusedRegisters,
    233         ScratchRegisterAllocator::ExtraStackSpace::NoExtraSpace);
     229    allocator.restoreReusedRegistersByPopping(jit, preservedState);
    234230    slowPathStart = jit.jump();
    235231}
     
    254250        JSValueRegs(left), JSValueRegs(right), leftFPR, rightFPR, scratchGPR, scratchFPR);
    255251
    256     unsigned numberOfBytesUsedToPreserveReusedRegisters =
     252    ScratchRegisterAllocator::PreservedState preservedState =
    257253        allocator.preserveReusedRegistersByPushing(jit, ScratchRegisterAllocator::ExtraStackSpace::NoExtraSpace);
    258254
     
    263259    gen.endJumpList().link(&jit);
    264260    context.restoreRegisters(jit);
    265     allocator.restoreReusedRegistersByPopping(jit, numberOfBytesUsedToPreserveReusedRegisters,
    266         ScratchRegisterAllocator::ExtraStackSpace::NoExtraSpace);
     261    allocator.restoreReusedRegistersByPopping(jit, preservedState);
    267262    done = jit.jump();
    268263
    269264    gen.slowPathJumpList().link(&jit);
    270265    context.restoreRegisters(jit);
    271     allocator.restoreReusedRegistersByPopping(jit, numberOfBytesUsedToPreserveReusedRegisters,
    272         ScratchRegisterAllocator::ExtraStackSpace::NoExtraSpace);
     266    allocator.restoreReusedRegistersByPopping(jit, preservedState);
    273267    slowPathStart = jit.jump();
    274268}
  • trunk/Source/JavaScriptCore/ftl/FTLLazySlowPath.cpp

    r192856 r194126  
    8080
    8181#if !FTL_USES_B3
    82     unsigned bytesSaved = m_scratchRegisterAllocator.preserveReusedRegistersByPushing(jit, ScratchRegisterAllocator::ExtraStackSpace::NoExtraSpace);
     82    ScratchRegisterAllocator::PreservedState preservedState =
     83        m_scratchRegisterAllocator.preserveReusedRegistersByPushing(jit, ScratchRegisterAllocator::ExtraStackSpace::NoExtraSpace);
    8384    // This is needed because LLVM may create a stackmap location that is the register SP.
    8485    // But on arm64, SP is also the same register number as ZR, so LLVM is telling us that it has
     
    9596    CCallHelpers::Label doneLabel;
    9697    CCallHelpers::Jump jumpToEndOfPatchpoint;
    97     if (bytesSaved) {
     98    if (preservedState.numberOfBytesPreserved) {
    9899        doneLabel = jit.label();
    99         m_scratchRegisterAllocator.restoreReusedRegistersByPopping(jit, bytesSaved, ScratchRegisterAllocator::ExtraStackSpace::NoExtraSpace);
     100        m_scratchRegisterAllocator.restoreReusedRegistersByPopping(jit, preservedState);
    100101        jumpToEndOfPatchpoint = jit.jump();
    101102    }
     
    106107    linkBuffer.link(params.doneJumps, m_done);
    107108#else // FTL_USES_B3
    108     if (bytesSaved) {
     109    if (preservedState.numberOfBytesPreserved) {
    109110        linkBuffer.link(params.doneJumps, linkBuffer.locationOf(doneLabel));
    110111        linkBuffer.link(jumpToEndOfPatchpoint, m_patchpoint.labelAtOffset(MacroAssembler::maxJumpReplacementSize()));
  • trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp

    r194113 r194126  
    93439343                        GPRReg scratch2 = scratchRegisterAllocator.allocateScratchGPR();
    93449344
    9345                         unsigned bytesPushed =
     9345                        ScratchRegisterAllocator::PreservedState preservedState =
    93469346                            scratchRegisterAllocator.preserveReusedRegistersByPushing(jit, ScratchRegisterAllocator::ExtraStackSpace::SpaceForCCall);
    93479347
     
    93669366                                static_cast<int32_t>(-sizeof(void*))));
    93679367
    9368                         scratchRegisterAllocator.restoreReusedRegistersByPopping(jit, bytesPushed, ScratchRegisterAllocator::ExtraStackSpace::SpaceForCCall);
     9368                        scratchRegisterAllocator.restoreReusedRegistersByPopping(jit, preservedState);
    93699369
    93709370                        params.doneJumps.append(jit.jump());
     
    93759375                            params.exceptionJumps, operationFlushWriteBarrierBuffer, InvalidGPRReg,
    93769376                            baseGPR);
    9377                         scratchRegisterAllocator.restoreReusedRegistersByPopping(jit, bytesPushed, ScratchRegisterAllocator::ExtraStackSpace::SpaceForCCall);
     9377                        scratchRegisterAllocator.restoreReusedRegistersByPopping(jit, preservedState);
    93789378                        params.doneJumps.append(jit.jump());
    93799379                    });
  • trunk/Source/JavaScriptCore/jit/ScratchRegisterAllocator.cpp

    r191404 r194126  
    103103FPRReg ScratchRegisterAllocator::allocateScratchFPR() { return allocateScratch<FPRInfo>(); }
    104104
    105 unsigned ScratchRegisterAllocator::preserveReusedRegistersByPushing(MacroAssembler& jit, ExtraStackSpace extraStackSpace)
     105ScratchRegisterAllocator::PreservedState ScratchRegisterAllocator::preserveReusedRegistersByPushing(MacroAssembler& jit, ExtraStackSpace extraStackSpace)
    106106{
    107107    if (!didReuseRegisters())
    108         return 0;
     108        return PreservedState(0, extraStackSpace);
    109109
    110110    RegisterSet registersToSpill;
     
    123123    unsigned stackAdjustmentSize = ScratchRegisterAllocator::preserveRegistersToStackForCall(jit, registersToSpill, extraStackBytesAtTopOfStack);
    124124
    125     return stackAdjustmentSize;
    126 }
    127 
    128 void ScratchRegisterAllocator::restoreReusedRegistersByPopping(MacroAssembler& jit, unsigned numberOfBytesUsedToPreserveReusedRegisters, ExtraStackSpace extraStackSpace)
     125    return PreservedState(stackAdjustmentSize, extraStackSpace);
     126}
     127
     128void ScratchRegisterAllocator::restoreReusedRegistersByPopping(MacroAssembler& jit, const ScratchRegisterAllocator::PreservedState preservedState)
    129129{
    130130    if (!didReuseRegisters())
     
    143143    }
    144144
    145     unsigned extraStackBytesAtTopOfStack = extraStackSpace == ExtraStackSpace::SpaceForCCall ? maxFrameExtentForSlowPathCall : 0;
     145    unsigned extraStackBytesAtTopOfStack =
     146        preservedState.extraStackSpaceRequirement == ExtraStackSpace::SpaceForCCall ? maxFrameExtentForSlowPathCall : 0;
    146147    RegisterSet dontRestore; // Empty set. We want to restore everything.
    147     ScratchRegisterAllocator::restoreRegistersFromStackForCall(jit, registersToFill, dontRestore, numberOfBytesUsedToPreserveReusedRegisters, extraStackBytesAtTopOfStack);
     148    ScratchRegisterAllocator::restoreRegistersFromStackForCall(jit, registersToFill, dontRestore,
     149        preservedState.numberOfBytesPreserved, extraStackBytesAtTopOfStack);
    148150}
    149151
  • trunk/Source/JavaScriptCore/jit/ScratchRegisterAllocator.h

    r191404 r194126  
    6868   
    6969    enum class ExtraStackSpace { SpaceForCCall, NoExtraSpace };
    70     unsigned preserveReusedRegistersByPushing(MacroAssembler& jit, ExtraStackSpace);
    71     void restoreReusedRegistersByPopping(MacroAssembler& jit, unsigned numberOfBytesUsedToPreserveReusedRegisters, ExtraStackSpace);
     70
     71    struct PreservedState {
     72        PreservedState()
     73            : PreservedState(0)
     74        { }
     75
     76        PreservedState(unsigned numberOfBytes, ExtraStackSpace extraStackSpace = ExtraStackSpace::NoExtraSpace)
     77            : numberOfBytesPreserved(numberOfBytes)
     78            , extraStackSpaceRequirement(extraStackSpace)
     79        { }
     80
     81        unsigned numberOfBytesPreserved;
     82        ExtraStackSpace extraStackSpaceRequirement;
     83    };
     84
     85    PreservedState preserveReusedRegistersByPushing(MacroAssembler& jit, ExtraStackSpace);
     86    void restoreReusedRegistersByPopping(MacroAssembler& jit, PreservedState);
    7287   
    7388    RegisterSet usedRegistersForCall() const;
Note: See TracChangeset for help on using the changeset viewer.