Changeset 250750 in webkit


Ignore:
Timestamp:
Oct 4, 2019, 3:20:57 PM (6 years ago)
Author:
[email protected]
Message:

Allow OSR exit to the LLInt
https://bugs.webkit.org/show_bug.cgi?id=197993

Reviewed by Tadeu Zagallo.

JSTests:

  • stress/exit-from-getter-by-val.js: Added.
  • stress/exit-from-setter-by-val.js: Added.

Source/JavaScriptCore:

This patch makes it so we can OSR exit to the LLInt.
Here are the interesting implementation details:

  1. We no longer baseline compile everything in the inline stack.
  1. When the top frame is a LLInt frame, we exit to the corresponding

LLInt bytecode. However, we need to materialize the LLInt registers
for PC, PB, and metadata.

  1. When dealing with inline call frames where the caller is LLInt, we

need to return to the appropriate place. Let's consider we're exiting
at a place A->B (A calls B), where A is LLInt. If A is a normal call,
we place the return PC in the frame we materialize to B to be right
after the LLInt's inline cache for calls. If A is a varargs call, we place
it at the return location for vararg calls. The interesting scenario here
is where A is a getter/setter. This means that A might be get_by_id,
get_by_val, put_by_id, or put_by_val. Since the LLInt does not have any
form of IC for getters/setters, we make this work by creating new LLInt
"return location" stubs for these opcodes.

  1. We need to update what callee saves we store in the callee if the caller frame

is a LLInt frame. Let's consider an inline stack A->B->C, where A is a LLInt frame.
When we materialize the stack frame for B, we need to ensure that the LLInt callee
saves that A uses is stored into B's preserved callee saves. Specifically, this
is just the PB/metadata registers.

This patch also fixes offlineasm's macro expansion to allow us to
use computed label names for global labels.

In a future bug, I'm going to investigate some kind of control system for
throwing away baseline code when we tier up:
https://bugs.webkit.org/show_bug.cgi?id=202503

  • JavaScriptCore.xcodeproj/project.pbxproj:
  • Sources.txt:
  • bytecode/CodeBlock.h:

(JSC::CodeBlock::metadataTable):
(JSC::CodeBlock::instructionsRawPointer):

  • dfg/DFGOSRExit.cpp:

(JSC::DFG::OSRExit::executeOSRExit):
(JSC::DFG::reifyInlinedCallFrames):
(JSC::DFG::adjustAndJumpToTarget):
(JSC::DFG::OSRExit::compileOSRExit):

  • dfg/DFGOSRExit.h:

(JSC::DFG::OSRExitState::OSRExitState):

  • dfg/DFGOSRExitCompilerCommon.cpp:

(JSC::DFG::callerReturnPC):
(JSC::DFG::calleeSaveSlot):
(JSC::DFG::reifyInlinedCallFrames):
(JSC::DFG::adjustAndJumpToTarget):

  • dfg/DFGOSRExitCompilerCommon.h:
  • dfg/DFGOSRExitPreparation.cpp:

(JSC::DFG::prepareCodeOriginForOSRExit): Deleted.

  • dfg/DFGOSRExitPreparation.h:
  • ftl/FTLOSRExitCompiler.cpp:

(JSC::FTL::compileFTLOSRExit):

  • llint/LLIntData.h:

(JSC::LLInt::getCodePtr):

  • llint/LowLevelInterpreter.asm:
  • llint/LowLevelInterpreter32_64.asm:
  • llint/LowLevelInterpreter64.asm:
  • offlineasm/asm.rb:
  • offlineasm/transform.rb:
  • runtime/OptionsList.h:

Tools:

  • Scripts/run-jsc-stress-tests:
Location:
trunk
Files:
2 added
2 deleted
20 edited

Legend:

Unmodified
Added
Removed
  • trunk/JSTests/ChangeLog

    r250720 r250750  
     12019-10-04  Saam Barati  <[email protected]>
     2
     3        Allow OSR exit to the LLInt
     4        https://bugs.webkit.org/show_bug.cgi?id=197993
     5
     6        Reviewed by Tadeu Zagallo.
     7
     8        * stress/exit-from-getter-by-val.js: Added.
     9        * stress/exit-from-setter-by-val.js: Added.
     10
    1112019-10-04  Paulo Matos  <[email protected]>
    212
  • trunk/Source/JavaScriptCore/ChangeLog

    r250725 r250750  
     12019-10-04  Saam Barati  <[email protected]>
     2
     3        Allow OSR exit to the LLInt
     4        https://bugs.webkit.org/show_bug.cgi?id=197993
     5
     6        Reviewed by Tadeu Zagallo.
     7
     8        This patch makes it so we can OSR exit to the LLInt.
     9        Here are the interesting implementation details:
     10       
     11        1. We no longer baseline compile everything in the inline stack.
     12       
     13        2. When the top frame is a LLInt frame, we exit to the corresponding
     14        LLInt bytecode. However, we need to materialize the LLInt registers
     15        for PC, PB, and metadata.
     16       
     17        3. When dealing with inline call frames where the caller is LLInt, we
     18        need to return to the appropriate place. Let's consider we're exiting
     19        at a place A->B (A calls B), where A is LLInt. If A is a normal call,
     20        we place the return PC in the frame we materialize to B to be right
     21        after the LLInt's inline cache for calls. If A is a varargs call, we place
     22        it at the return location for vararg calls. The interesting scenario here
     23        is where A is a getter/setter. This means that A might be get_by_id,
     24        get_by_val, put_by_id, or put_by_val. Since the LLInt does not have any
     25        form of IC for getters/setters, we make this work by creating new LLInt
     26        "return location" stubs for these opcodes.
     27       
     28        4. We need to update what callee saves we store in the callee if the caller frame
     29        is a LLInt frame. Let's consider an inline stack A->B->C, where A is a LLInt frame.
     30        When we materialize the stack frame for B, we need to ensure that the LLInt callee
     31        saves that A uses is stored into B's preserved callee saves. Specifically, this
     32        is just the PB/metadata registers.
     33       
     34        This patch also fixes offlineasm's macro expansion to allow us to
     35        use computed label names for global labels.
     36       
     37        In a future bug, I'm going to investigate some kind of control system for
     38        throwing away baseline code when we tier up:
     39        https://bugs.webkit.org/show_bug.cgi?id=202503
     40
     41        * JavaScriptCore.xcodeproj/project.pbxproj:
     42        * Sources.txt:
     43        * bytecode/CodeBlock.h:
     44        (JSC::CodeBlock::metadataTable):
     45        (JSC::CodeBlock::instructionsRawPointer):
     46        * dfg/DFGOSRExit.cpp:
     47        (JSC::DFG::OSRExit::executeOSRExit):
     48        (JSC::DFG::reifyInlinedCallFrames):
     49        (JSC::DFG::adjustAndJumpToTarget):
     50        (JSC::DFG::OSRExit::compileOSRExit):
     51        * dfg/DFGOSRExit.h:
     52        (JSC::DFG::OSRExitState::OSRExitState):
     53        * dfg/DFGOSRExitCompilerCommon.cpp:
     54        (JSC::DFG::callerReturnPC):
     55        (JSC::DFG::calleeSaveSlot):
     56        (JSC::DFG::reifyInlinedCallFrames):
     57        (JSC::DFG::adjustAndJumpToTarget):
     58        * dfg/DFGOSRExitCompilerCommon.h:
     59        * dfg/DFGOSRExitPreparation.cpp:
     60        (JSC::DFG::prepareCodeOriginForOSRExit): Deleted.
     61        * dfg/DFGOSRExitPreparation.h:
     62        * ftl/FTLOSRExitCompiler.cpp:
     63        (JSC::FTL::compileFTLOSRExit):
     64        * llint/LLIntData.h:
     65        (JSC::LLInt::getCodePtr):
     66        * llint/LowLevelInterpreter.asm:
     67        * llint/LowLevelInterpreter32_64.asm:
     68        * llint/LowLevelInterpreter64.asm:
     69        * offlineasm/asm.rb:
     70        * offlineasm/transform.rb:
     71        * runtime/OptionsList.h:
     72
    1732019-10-04  Truitt Savell  <[email protected]>
    274
  • trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj

    r250630 r250750  
    183183                0F235BE217178E1C00690C7F /* FTLThunks.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F235BCC17178E1C00690C7F /* FTLThunks.h */; settings = {ATTRIBUTES = (Private, ); }; };
    184184                0F235BEC17178E7300690C7F /* DFGOSRExitBase.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F235BE817178E7300690C7F /* DFGOSRExitBase.h */; };
    185                 0F235BEE17178E7300690C7F /* DFGOSRExitPreparation.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F235BEA17178E7300690C7F /* DFGOSRExitPreparation.h */; };
    186185                0F24E54117EA9F5900ABB217 /* AssemblyHelpers.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F24E53C17EA9F5900ABB217 /* AssemblyHelpers.h */; settings = {ATTRIBUTES = (Private, ); }; };
    187186                0F24E54217EA9F5900ABB217 /* CCallHelpers.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F24E53D17EA9F5900ABB217 /* CCallHelpers.h */; settings = {ATTRIBUTES = (Private, ); }; };
     
    22972296                0F235BE717178E7300690C7F /* DFGOSRExitBase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGOSRExitBase.cpp; path = dfg/DFGOSRExitBase.cpp; sourceTree = "<group>"; };
    22982297                0F235BE817178E7300690C7F /* DFGOSRExitBase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGOSRExitBase.h; path = dfg/DFGOSRExitBase.h; sourceTree = "<group>"; };
    2299                 0F235BE917178E7300690C7F /* DFGOSRExitPreparation.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGOSRExitPreparation.cpp; path = dfg/DFGOSRExitPreparation.cpp; sourceTree = "<group>"; };
    2300                 0F235BEA17178E7300690C7F /* DFGOSRExitPreparation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGOSRExitPreparation.h; path = dfg/DFGOSRExitPreparation.h; sourceTree = "<group>"; };
    23012298                0F24E53B17EA9F5900ABB217 /* AssemblyHelpers.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AssemblyHelpers.cpp; sourceTree = "<group>"; };
    23022299                0F24E53C17EA9F5900ABB217 /* AssemblyHelpers.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AssemblyHelpers.h; sourceTree = "<group>"; };
     
    78737870                                0FEFC9A71681A3B000567F53 /* DFGOSRExitJumpPlaceholder.cpp */,
    78747871                                0FEFC9A81681A3B000567F53 /* DFGOSRExitJumpPlaceholder.h */,
    7875                                 0F235BE917178E7300690C7F /* DFGOSRExitPreparation.cpp */,
    7876                                 0F235BEA17178E7300690C7F /* DFGOSRExitPreparation.h */,
    78777872                                0F6237951AE45CA700D402EA /* DFGPhantomInsertionPhase.cpp */,
    78787873                                0F6237961AE45CA700D402EA /* DFGPhantomInsertionPhase.h */,
     
    92409235                                0F392C8A1B46188400844728 /* DFGOSRExitFuzz.h in Headers */,
    92419236                                0FEFC9AB1681A3B600567F53 /* DFGOSRExitJumpPlaceholder.h in Headers */,
    9242                                 0F235BEE17178E7300690C7F /* DFGOSRExitPreparation.h in Headers */,
    92439237                                0F6237981AE45CA700D402EA /* DFGPhantomInsertionPhase.h in Headers */,
    92449238                                0FFFC95C14EF90AF00C72532 /* DFGPhase.h in Headers */,
  • trunk/Source/JavaScriptCore/Sources.txt

    r250630 r250750  
    383383dfg/DFGOSRExitFuzz.cpp
    384384dfg/DFGOSRExitJumpPlaceholder.cpp
    385 dfg/DFGOSRExitPreparation.cpp
    386385dfg/DFGObjectAllocationSinkingPhase.cpp
    387386dfg/DFGObjectMaterializationData.cpp
  • trunk/Source/JavaScriptCore/bytecode/CodeBlock.h

    r250655 r250750  
    893893    }
    894894
     895    MetadataTable* metadataTable() { return m_metadata.get(); }
     896    const void* instructionsRawPointer() { return m_instructionsRawPointer; }
     897
    895898protected:
    896899    void finalizeLLIntInlineCaches();
  • trunk/Source/JavaScriptCore/bytecode/InlineCallFrame.h

    r245239 r250750  
    241241inline CodeBlock* baselineCodeBlockForOriginAndBaselineCodeBlock(const CodeOrigin& codeOrigin, CodeBlock* baselineCodeBlock)
    242242{
    243     ASSERT(baselineCodeBlock->jitType() == JITType::BaselineJIT);
     243    ASSERT(JITCode::isBaselineCode(baselineCodeBlock->jitType()));
    244244    auto* inlineCallFrame = codeOrigin.inlineCallFrame();
    245245    if (inlineCallFrame)
  • trunk/Source/JavaScriptCore/dfg/DFGOSRExit.cpp

    r250486 r250750  
    3535#include "DFGMayExit.h"
    3636#include "DFGOSRExitCompilerCommon.h"
    37 #include "DFGOSRExitPreparation.h"
    3837#include "DFGOperations.h"
    3938#include "DFGSpeculativeJIT.h"
     
    373372        // exit ramp code.
    374373
    375         // Ensure we have baseline codeBlocks to OSR exit to.
    376         prepareCodeOriginForOSRExit(exec, exit.m_codeOrigin);
    377 
    378374        CodeBlock* baselineCodeBlock = codeBlock->baselineAlternative();
    379         ASSERT(baselineCodeBlock->jitType() == JITType::BaselineJIT);
     375        ASSERT(JITCode::isBaselineCode(baselineCodeBlock->jitType()));
    380376
    381377        SpeculationRecovery* recovery = nullptr;
     
    407403
    408404        CodeBlock* codeBlockForExit = baselineCodeBlockForOriginAndBaselineCodeBlock(exit.m_codeOrigin, baselineCodeBlock);
    409         const JITCodeMap& codeMap = codeBlockForExit->jitCodeMap();
    410         CodeLocationLabel<JSEntryPtrTag> codeLocation = codeMap.find(exit.m_codeOrigin.bytecodeIndex());
    411         ASSERT(codeLocation);
    412 
    413         void* jumpTarget = codeLocation.executableAddress();
     405        bool exitToLLInt = Options::forceOSRExitToLLInt() || codeBlockForExit->jitType() == JITType::InterpreterThunk;
     406        void* jumpTarget;
     407        if (exitToLLInt) {
     408            unsigned bytecodeOffset = exit.m_codeOrigin.bytecodeIndex();
     409            const Instruction& currentInstruction = *codeBlockForExit->instructions().at(bytecodeOffset).ptr();
     410            MacroAssemblerCodePtr<JSEntryPtrTag> destination = LLInt::getCodePtr<JSEntryPtrTag>(currentInstruction);
     411            jumpTarget = destination.executableAddress();   
     412        } else {
     413            const JITCodeMap& codeMap = codeBlockForExit->jitCodeMap();
     414            CodeLocationLabel<JSEntryPtrTag> codeLocation = codeMap.find(exit.m_codeOrigin.bytecodeIndex());
     415            ASSERT(codeLocation);
     416            jumpTarget = codeLocation.executableAddress();
     417        }
    414418
    415419        // Compute the value recoveries.
     
    419423        ptrdiff_t stackPointerOffset = -static_cast<ptrdiff_t>(codeBlock->jitCode()->dfgCommon()->requiredRegisterCountForExit) * sizeof(Register);
    420424
    421         exit.exitState = adoptRef(new OSRExitState(exit, codeBlock, baselineCodeBlock, operands, WTFMove(undefinedOperandSpans), recovery, stackPointerOffset, activeThreshold, adjustedThreshold, jumpTarget, arrayProfile));
     425        exit.exitState = adoptRef(new OSRExitState(exit, codeBlock, baselineCodeBlock, operands, WTFMove(undefinedOperandSpans), recovery, stackPointerOffset, activeThreshold, adjustedThreshold, jumpTarget, arrayProfile, exitToLLInt));
    422426
    423427        if (UNLIKELY(vm.m_perBytecodeProfiler && codeBlock->jitCode()->dfgCommon()->compilation)) {
     
    447451    OSRExitState& exitState = *exit.exitState.get();
    448452    CodeBlock* baselineCodeBlock = exitState.baselineCodeBlock;
    449     ASSERT(baselineCodeBlock->jitType() == JITType::BaselineJIT);
     453    ASSERT(JITCode::isBaselineCode(baselineCodeBlock->jitType()));
    450454
    451455    Operands<ValueRecovery>& operands = exitState.operands;
     
    758762    // in presence of inlined tail calls.
    759763    // https://bugs.webkit.org/show_bug.cgi?id=147511
    760     ASSERT(outermostBaselineCodeBlock->jitType() == JITType::BaselineJIT);
     764    ASSERT(JITCode::isBaselineCode(outermostBaselineCodeBlock->jitType()));
    761765    frame.setOperand<CodeBlock*>(CallFrameSlot::codeBlock, outermostBaselineCodeBlock);
    762766
     
    769773        void* callerFrame = cpu.fp();
    770774
     775        bool callerIsLLInt = false;
     776
    771777        if (!trueCaller) {
    772778            ASSERT(inlineCallFrame->isTail());
     
    782788            CodeBlock* baselineCodeBlockForCaller = baselineCodeBlockForOriginAndBaselineCodeBlock(*trueCaller, outermostBaselineCodeBlock);
    783789            unsigned callBytecodeIndex = trueCaller->bytecodeIndex();
    784             MacroAssemblerCodePtr<JSInternalPtrTag> jumpTarget;
    785 
    786             switch (trueCallerCallKind) {
    787             case InlineCallFrame::Call:
    788             case InlineCallFrame::Construct:
    789             case InlineCallFrame::CallVarargs:
    790             case InlineCallFrame::ConstructVarargs:
    791             case InlineCallFrame::TailCall:
    792             case InlineCallFrame::TailCallVarargs: {
    793                 CallLinkInfo* callLinkInfo =
    794                     baselineCodeBlockForCaller->getCallLinkInfoForBytecodeIndex(callBytecodeIndex);
    795                 RELEASE_ASSERT(callLinkInfo);
    796 
    797                 jumpTarget = callLinkInfo->callReturnLocation();
    798                 break;
    799             }
    800 
    801             case InlineCallFrame::GetterCall:
    802             case InlineCallFrame::SetterCall: {
    803                 StructureStubInfo* stubInfo =
    804                     baselineCodeBlockForCaller->findStubInfo(CodeOrigin(callBytecodeIndex));
    805                 RELEASE_ASSERT(stubInfo);
    806 
    807                 jumpTarget = stubInfo->doneLocation();
    808                 break;
    809             }
    810 
    811             default:
    812                 RELEASE_ASSERT_NOT_REACHED();
    813             }
     790            void* jumpTarget = callerReturnPC(baselineCodeBlockForCaller, callBytecodeIndex, trueCallerCallKind, callerIsLLInt);
    814791
    815792            if (trueCaller->inlineCallFrame())
    816793                callerFrame = cpu.fp<uint8_t*>() + trueCaller->inlineCallFrame()->stackOffset * sizeof(EncodedJSValue);
    817794
    818             void* targetAddress = jumpTarget.executableAddress();
    819795#if CPU(ARM64E)
    820796            void* newEntrySP = cpu.fp<uint8_t*>() + inlineCallFrame->returnPCOffset() + sizeof(void*);
    821             targetAddress = retagCodePtr(targetAddress, JSInternalPtrTag, bitwise_cast<PtrTag>(newEntrySP));
    822 #endif
    823             frame.set<void*>(inlineCallFrame->returnPCOffset(), targetAddress);
     797            jumpTarget = tagCodePtr(jumpTarget, bitwise_cast<PtrTag>(newEntrySP));
     798#endif
     799            frame.set<void*>(inlineCallFrame->returnPCOffset(), jumpTarget);
    824800        }
    825801
     
    830806        // copy the prior contents of the tag registers already saved for the outer frame to this frame.
    831807        saveOrCopyCalleeSavesFor(context, baselineCodeBlock, VirtualRegister(inlineCallFrame->stackOffset), !trueCaller);
     808
     809        if (callerIsLLInt) {
     810            CodeBlock* baselineCodeBlockForCaller = baselineCodeBlockForOriginAndBaselineCodeBlock(*trueCaller, outermostBaselineCodeBlock);
     811            frame.set<const void*>(calleeSaveSlot(inlineCallFrame, baselineCodeBlock, LLInt::Registers::metadataTableGPR).offset, baselineCodeBlockForCaller->metadataTable());
     812#if USE(JSVALUE64)
     813            frame.set<const void*>(calleeSaveSlot(inlineCallFrame, baselineCodeBlock, LLInt::Registers::pbGPR).offset, baselineCodeBlockForCaller->instructionsRawPointer());
     814#endif
     815        }
    832816
    833817        if (!inlineCallFrame->isVarargs())
     
    895879
    896880    vm.topCallFrame = context.fp<ExecState*>();
     881
     882    if (exitState->isJumpToLLInt) {
     883        CodeBlock* codeBlockForExit = baselineCodeBlockForOriginAndBaselineCodeBlock(exit.m_codeOrigin, baselineCodeBlock);
     884        unsigned bytecodeOffset = exit.m_codeOrigin.bytecodeIndex();
     885        const Instruction& currentInstruction = *codeBlockForExit->instructions().at(bytecodeOffset).ptr();
     886
     887        context.gpr(LLInt::Registers::metadataTableGPR) = bitwise_cast<uintptr_t>(codeBlockForExit->metadataTable());
     888#if USE(JSVALUE64)
     889        context.gpr(LLInt::Registers::pbGPR) = bitwise_cast<uintptr_t>(codeBlockForExit->instructionsRawPointer());
     890        context.gpr(LLInt::Registers::pcGPR) = static_cast<uintptr_t>(exit.m_codeOrigin.bytecodeIndex());
     891#else
     892        context.gpr(LLInt::Registers::pcGPR) = bitwise_cast<uintptr_t>(&currentInstruction);
     893#endif
     894
     895        if (exit.isExceptionHandler())
     896            vm.targetInterpreterPCForThrow = &currentInstruction;
     897    }
     898
    897899    context.pc() = untagCodePtr<JSEntryPtrTag>(jumpTarget);
    898900}
     
    10531055    EXCEPTION_ASSERT_UNUSED(scope, !!scope.exception() || !exit.isExceptionHandler());
    10541056   
    1055     prepareCodeOriginForOSRExit(exec, exit.m_codeOrigin);
    1056 
    10571057    // Compute the value recoveries.
    10581058    Operands<ValueRecovery> operands;
  • trunk/Source/JavaScriptCore/dfg/DFGOSRExit.h

    r248546 r250750  
    107107
    108108struct OSRExitState : RefCounted<OSRExitState> {
    109     OSRExitState(OSRExitBase& exit, CodeBlock* codeBlock, CodeBlock* baselineCodeBlock, Operands<ValueRecovery>& operands, Vector<UndefinedOperandSpan>&& undefinedOperandSpans, SpeculationRecovery* recovery, ptrdiff_t stackPointerOffset, int32_t activeThreshold, double memoryUsageAdjustedThreshold, void* jumpTarget, ArrayProfile* arrayProfile)
     109    OSRExitState(OSRExitBase& exit, CodeBlock* codeBlock, CodeBlock* baselineCodeBlock, Operands<ValueRecovery>& operands, Vector<UndefinedOperandSpan>&& undefinedOperandSpans, SpeculationRecovery* recovery, ptrdiff_t stackPointerOffset, int32_t activeThreshold, double memoryUsageAdjustedThreshold, void* jumpTarget, ArrayProfile* arrayProfile, bool isJumpToLLInt)
    110110        : exit(exit)
    111111        , codeBlock(codeBlock)
     
    119119        , jumpTarget(jumpTarget)
    120120        , arrayProfile(arrayProfile)
     121        , isJumpToLLInt(isJumpToLLInt)
    121122    { }
    122123
     
    132133    void* jumpTarget;
    133134    ArrayProfile* arrayProfile;
     135    bool isJumpToLLInt;
    134136
    135137    ExtraInitializationLevel extraInitializationLevel;
  • trunk/Source/JavaScriptCore/dfg/DFGOSRExitCompilerCommon.cpp

    r249880 r250750  
    3434#include "JSCJSValueInlines.h"
    3535#include "JSCInlines.h"
     36#include "LLIntData.h"
    3637#include "StructureStubInfo.h"
    3738
    3839namespace JSC { namespace DFG {
     40
     41// These are the LLInt OSR exit return points.
     42extern "C" void op_call_return_location_narrow();
     43extern "C" void op_call_return_location_wide_16();
     44extern "C" void op_call_return_location_wide_32();
     45
     46extern "C" void op_construct_return_location_narrow();
     47extern "C" void op_construct_return_location_wide_16();
     48extern "C" void op_construct_return_location_wide_32();
     49
     50extern "C" void op_call_varargs_slow_return_location_narrow();
     51extern "C" void op_call_varargs_slow_return_location_wide_16();
     52extern "C" void op_call_varargs_slow_return_location_wide_32();
     53
     54extern "C" void op_construct_varargs_slow_return_location_narrow();
     55extern "C" void op_construct_varargs_slow_return_location_wide_16();
     56extern "C" void op_construct_varargs_slow_return_location_wide_32();
     57
     58extern "C" void op_get_by_id_return_location_narrow();
     59extern "C" void op_get_by_id_return_location_wide_16();
     60extern "C" void op_get_by_id_return_location_wide_32();
     61
     62extern "C" void op_get_by_val_return_location_narrow();
     63extern "C" void op_get_by_val_return_location_wide_16();
     64extern "C" void op_get_by_val_return_location_wide_32();
     65
     66extern "C" void op_put_by_id_return_location_narrow();
     67extern "C" void op_put_by_id_return_location_wide_16();
     68extern "C" void op_put_by_id_return_location_wide_32();
     69
     70extern "C" void op_put_by_val_return_location_narrow();
     71extern "C" void op_put_by_val_return_location_wide_16();
     72extern "C" void op_put_by_val_return_location_wide_32();
    3973
    4074void handleExitCounts(CCallHelpers& jit, const OSRExitBase& exit)
     
    137171}
    138172
     173void* callerReturnPC(CodeBlock* baselineCodeBlockForCaller, unsigned callBytecodeIndex, InlineCallFrame::Kind trueCallerCallKind, bool& callerIsLLInt)
     174{
     175    callerIsLLInt = Options::forceOSRExitToLLInt() || baselineCodeBlockForCaller->jitType() == JITType::InterpreterThunk;
     176
     177    void* jumpTarget;
     178
     179    if (callerIsLLInt) {
     180        const Instruction& callInstruction = *baselineCodeBlockForCaller->instructions().at(callBytecodeIndex).ptr();
     181
     182#define LLINT_RETURN_LOCATION(name) FunctionPtr<NoPtrTag>(callInstruction.isWide16() ? name##_return_location_wide_16 : (callInstruction.isWide32() ? name##_return_location_wide_32 : name##_return_location_narrow)).executableAddress()
     183
     184        switch (trueCallerCallKind) {
     185        case InlineCallFrame::Call:
     186            jumpTarget = LLINT_RETURN_LOCATION(op_call);
     187            break;
     188        case InlineCallFrame::Construct:
     189            jumpTarget = LLINT_RETURN_LOCATION(op_construct);
     190            break;
     191        case InlineCallFrame::CallVarargs:
     192            jumpTarget = LLINT_RETURN_LOCATION(op_call_varargs_slow);
     193            break;
     194        case InlineCallFrame::ConstructVarargs:
     195            jumpTarget = LLINT_RETURN_LOCATION(op_construct_varargs_slow);
     196            break;
     197        case InlineCallFrame::GetterCall: {
     198            if (callInstruction.opcodeID() == op_get_by_id)
     199                jumpTarget = LLINT_RETURN_LOCATION(op_get_by_id);
     200            else if (callInstruction.opcodeID() == op_get_by_val)
     201                jumpTarget = LLINT_RETURN_LOCATION(op_get_by_val);
     202            else
     203                RELEASE_ASSERT_NOT_REACHED();
     204            break;
     205        }
     206        case InlineCallFrame::SetterCall: {
     207            if (callInstruction.opcodeID() == op_put_by_id)
     208                jumpTarget = LLINT_RETURN_LOCATION(op_put_by_id);
     209            else if (callInstruction.opcodeID() == op_put_by_val)
     210                jumpTarget = LLINT_RETURN_LOCATION(op_put_by_val);
     211            else
     212                RELEASE_ASSERT_NOT_REACHED();
     213            break;
     214        }
     215        default:
     216            RELEASE_ASSERT_NOT_REACHED();
     217        }
     218
     219#undef LLINT_RETURN_LOCATION
     220
     221    } else {
     222        switch (trueCallerCallKind) {
     223        case InlineCallFrame::Call:
     224        case InlineCallFrame::Construct:
     225        case InlineCallFrame::CallVarargs:
     226        case InlineCallFrame::ConstructVarargs: {
     227            CallLinkInfo* callLinkInfo =
     228                baselineCodeBlockForCaller->getCallLinkInfoForBytecodeIndex(callBytecodeIndex);
     229            RELEASE_ASSERT(callLinkInfo);
     230
     231            jumpTarget = callLinkInfo->callReturnLocation().untaggedExecutableAddress();
     232            break;
     233        }
     234
     235        case InlineCallFrame::GetterCall:
     236        case InlineCallFrame::SetterCall: {
     237            StructureStubInfo* stubInfo =
     238                baselineCodeBlockForCaller->findStubInfo(CodeOrigin(callBytecodeIndex));
     239            RELEASE_ASSERT(stubInfo);
     240
     241            jumpTarget = stubInfo->doneLocation().untaggedExecutableAddress();
     242            break;
     243        }
     244
     245        default:
     246            RELEASE_ASSERT_NOT_REACHED();
     247        }
     248    }
     249
     250    return jumpTarget;
     251}
     252
     253CCallHelpers::Address calleeSaveSlot(InlineCallFrame* inlineCallFrame, CodeBlock* baselineCodeBlock, GPRReg calleeSave)
     254{
     255    const RegisterAtOffsetList* calleeSaves = baselineCodeBlock->calleeSaveRegisters();
     256    for (unsigned i = 0; i < calleeSaves->size(); i++) {
     257        RegisterAtOffset entry = calleeSaves->at(i);
     258        if (entry.reg() != calleeSave)
     259            continue;
     260        return CCallHelpers::Address(CCallHelpers::framePointerRegister, static_cast<VirtualRegister>(inlineCallFrame->stackOffset).offsetInBytes() + entry.offset());
     261    }
     262
     263    RELEASE_ASSERT_NOT_REACHED();
     264    return CCallHelpers::Address(CCallHelpers::framePointerRegister);
     265}
     266
    139267void reifyInlinedCallFrames(CCallHelpers& jit, const OSRExitBase& exit)
    140268{
     
    142270    // in presence of inlined tail calls.
    143271    // https://bugs.webkit.org/show_bug.cgi?id=147511
    144     ASSERT(jit.baselineCodeBlock()->jitType() == JITType::BaselineJIT);
     272    ASSERT(JITCode::isBaselineCode(jit.baselineCodeBlock()->jitType()));
    145273    jit.storePtr(AssemblyHelpers::TrustedImmPtr(jit.baselineCodeBlock()), AssemblyHelpers::addressFor((VirtualRegister)CallFrameSlot::codeBlock));
    146274
     
    152280        CodeOrigin* trueCaller = inlineCallFrame->getCallerSkippingTailCalls(&trueCallerCallKind);
    153281        GPRReg callerFrameGPR = GPRInfo::callFrameRegister;
     282
     283        bool callerIsLLInt = false;
    154284
    155285        if (!trueCaller) {
     
    168298            CodeBlock* baselineCodeBlockForCaller = jit.baselineCodeBlockFor(*trueCaller);
    169299            unsigned callBytecodeIndex = trueCaller->bytecodeIndex();
    170             void* jumpTarget = nullptr;
    171 
    172             switch (trueCallerCallKind) {
    173             case InlineCallFrame::Call:
    174             case InlineCallFrame::Construct:
    175             case InlineCallFrame::CallVarargs:
    176             case InlineCallFrame::ConstructVarargs:
    177             case InlineCallFrame::TailCall:
    178             case InlineCallFrame::TailCallVarargs: {
    179                 CallLinkInfo* callLinkInfo =
    180                     baselineCodeBlockForCaller->getCallLinkInfoForBytecodeIndex(callBytecodeIndex);
    181                 RELEASE_ASSERT(callLinkInfo);
    182 
    183                 jumpTarget = callLinkInfo->callReturnLocation().untaggedExecutableAddress();
    184                 break;
    185             }
    186 
    187             case InlineCallFrame::GetterCall:
    188             case InlineCallFrame::SetterCall: {
    189                 StructureStubInfo* stubInfo =
    190                     baselineCodeBlockForCaller->findStubInfo(CodeOrigin(callBytecodeIndex));
    191                 RELEASE_ASSERT(stubInfo);
    192 
    193                 jumpTarget = stubInfo->doneLocation().untaggedExecutableAddress();
    194                 break;
    195             }
    196 
    197             default:
    198                 RELEASE_ASSERT_NOT_REACHED();
    199             }
     300            void* jumpTarget = callerReturnPC(baselineCodeBlockForCaller, callBytecodeIndex, trueCallerCallKind, callerIsLLInt);
    200301
    201302            if (trueCaller->inlineCallFrame()) {
     
    227328            trueCaller ? AssemblyHelpers::UseExistingTagRegisterContents : AssemblyHelpers::CopyBaselineCalleeSavedRegistersFromBaseFrame,
    228329            GPRInfo::regT2);
     330
     331        if (callerIsLLInt) {
     332            CodeBlock* baselineCodeBlockForCaller = jit.baselineCodeBlockFor(*trueCaller);
     333            jit.storePtr(CCallHelpers::TrustedImmPtr(baselineCodeBlockForCaller->metadataTable()), calleeSaveSlot(inlineCallFrame, baselineCodeBlock, LLInt::Registers::metadataTableGPR));
     334#if USE(JSVALUE64)
     335            jit.storePtr(CCallHelpers::TrustedImmPtr(baselineCodeBlockForCaller->instructionsRawPointer()), calleeSaveSlot(inlineCallFrame, baselineCodeBlock, LLInt::Registers::pbGPR));
     336#endif
     337        }
    229338
    230339        if (!inlineCallFrame->isVarargs())
     
    302411    CodeBlock* codeBlockForExit = jit.baselineCodeBlockFor(exit.m_codeOrigin);
    303412    ASSERT(codeBlockForExit == codeBlockForExit->baselineVersion());
    304     ASSERT(codeBlockForExit->jitType() == JITType::BaselineJIT);
    305     CodeLocationLabel<JSEntryPtrTag> codeLocation = codeBlockForExit->jitCodeMap().find(exit.m_codeOrigin.bytecodeIndex());
    306     ASSERT(codeLocation);
    307 
    308     void* jumpTarget = codeLocation.retagged<OSRExitPtrTag>().executableAddress();
     413    ASSERT(JITCode::isBaselineCode(codeBlockForExit->jitType()));
     414
     415    void* jumpTarget;
     416    bool exitToLLInt = Options::forceOSRExitToLLInt() || codeBlockForExit->jitType() == JITType::InterpreterThunk;
     417    if (exitToLLInt) {
     418        unsigned bytecodeOffset = exit.m_codeOrigin.bytecodeIndex();
     419        const Instruction& currentInstruction = *codeBlockForExit->instructions().at(bytecodeOffset).ptr();
     420        MacroAssemblerCodePtr<JSEntryPtrTag> destination = LLInt::getCodePtr<JSEntryPtrTag>(currentInstruction);
     421
     422        if (exit.isExceptionHandler()) {
     423            jit.move(CCallHelpers::TrustedImmPtr(&currentInstruction), GPRInfo::regT2);
     424            jit.storePtr(GPRInfo::regT2, &vm.targetInterpreterPCForThrow);
     425        }
     426
     427        jit.move(CCallHelpers::TrustedImmPtr(codeBlockForExit->metadataTable()), LLInt::Registers::metadataTableGPR);
     428#if USE(JSVALUE64)
     429        jit.move(CCallHelpers::TrustedImmPtr(codeBlockForExit->instructionsRawPointer()), LLInt::Registers::pbGPR);
     430        jit.move(CCallHelpers::TrustedImm32(bytecodeOffset), LLInt::Registers::pcGPR);
     431#else
     432        jit.move(CCallHelpers::TrustedImmPtr(&currentInstruction), LLInt::Registers::pcGPR);
     433#endif
     434        jumpTarget = destination.retagged<OSRExitPtrTag>().executableAddress();
     435    } else {
     436        CodeLocationLabel<JSEntryPtrTag> codeLocation = codeBlockForExit->jitCodeMap().find(exit.m_codeOrigin.bytecodeIndex());
     437        ASSERT(codeLocation);
     438
     439        jumpTarget = codeLocation.retagged<OSRExitPtrTag>().executableAddress();
     440    }
     441
    309442    jit.addPtr(AssemblyHelpers::TrustedImm32(JIT::stackPointerOffsetFor(codeBlockForExit) * sizeof(Register)), GPRInfo::callFrameRegister, AssemblyHelpers::stackPointerRegister);
    310443    if (exit.isExceptionHandler()) {
  • trunk/Source/JavaScriptCore/dfg/DFGOSRExitCompilerCommon.h

    r249175 r250750  
    4040void reifyInlinedCallFrames(CCallHelpers&, const OSRExitBase&);
    4141void adjustAndJumpToTarget(VM&, CCallHelpers&, const OSRExitBase&);
     42void* callerReturnPC(CodeBlock* baselineCodeBlockForCaller, unsigned callBytecodeOffset, InlineCallFrame::Kind callerKind, bool& callerIsLLInt);
     43CCallHelpers::Address calleeSaveSlot(InlineCallFrame*, CodeBlock* baselineCodeBlock, GPRReg calleeSave);
    4244
    4345template <typename JITCodeType>
  • trunk/Source/JavaScriptCore/ftl/FTLOSRExitCompiler.cpp

    r250629 r250750  
    3131#include "BytecodeStructs.h"
    3232#include "DFGOSRExitCompilerCommon.h"
    33 #include "DFGOSRExitPreparation.h"
    3433#include "FTLExitArgumentForOperand.h"
    3534#include "FTLJITCode.h"
     
    545544    }
    546545
    547     prepareCodeOriginForOSRExit(exec, exit.m_codeOrigin);
    548 
    549546    compileStub(exitID, jitCode, exit, &vm, codeBlock);
    550547
  • trunk/Source/JavaScriptCore/llint/LLIntData.h

    r245906 r250750  
    2626#pragma once
    2727
     28#include "GPRInfo.h"
     29#include "Instruction.h"
    2830#include "JSCJSValue.h"
    2931#include "MacroAssemblerCodeRef.h"
     
    3335
    3436class VM;
    35 struct Instruction;
    3637
    3738#if ENABLE(C_LOOP)
     
    146147
    147148template<PtrTag tag>
     149ALWAYS_INLINE MacroAssemblerCodePtr<tag> getCodePtr(const Instruction& instruction)
     150{
     151    if (instruction.isWide16())
     152        return getWide16CodePtr<tag>(instruction.opcodeID());
     153    if (instruction.isWide32())
     154        return getWide32CodePtr<tag>(instruction.opcodeID());
     155    return getCodePtr<tag>(instruction.opcodeID());
     156}
     157
     158template<PtrTag tag>
    148159ALWAYS_INLINE MacroAssemblerCodeRef<tag> getCodeRef(OpcodeID opcodeID)
    149160{
     
    185196}
    186197
     198#if ENABLE(JIT)
     199struct Registers {
     200    static const GPRReg pcGPR = GPRInfo::regT4;
     201
     202#if CPU(X86_64) && !OS(WINDOWS)
     203    static const GPRReg metadataTableGPR = GPRInfo::regCS1;
     204    static const GPRReg pbGPR = GPRInfo::regCS2;
     205#elif CPU(X86_64) && OS(WINDOWS)
     206    static const GPRReg metadataTableGPR = GPRInfo::regCS3;
     207    static const GPRReg pbGPR = GPRInfo::regCS4;
     208#elif CPU(ARM64)
     209    static const GPRReg metadataTableGPR = GPRInfo::regCS6;
     210    static const GPRReg pbGPR = GPRInfo::regCS7;
     211#elif CPU(MIPS) || CPU(ARM_THUMB2)
     212    static const GPRReg metadataTableGPR = GPRInfo::regCS0;
     213#endif
     214};
     215#endif
     216
    187217} } // namespace JSC::LLInt
  • trunk/Source/JavaScriptCore/llint/LowLevelInterpreter.asm

    r250630 r250750  
    930930end
    931931
    932 macro callTargetFunction(size, opcodeStruct, dispatch, callee, callPtrTag)
     932macro defineOSRExitReturnLabel(opcodeName, size)
     933    macro defineNarrow()
     934        global _%opcodeName%_return_location_narrow
     935        _%opcodeName%_return_location_narrow:
     936    end
     937
     938    macro defineWide16()
     939        global _%opcodeName%_return_location_wide_16
     940        _%opcodeName%_return_location_wide_16:
     941    end
     942
     943    macro defineWide32()
     944        global _%opcodeName%_return_location_wide_32
     945        _%opcodeName%_return_location_wide_32:
     946    end
     947
     948    size(defineNarrow, defineWide16, defineWide32, macro (f) f() end)
     949end
     950
     951macro callTargetFunction(opcodeName, size, opcodeStruct, dispatch, callee, callPtrTag)
    933952    if C_LOOP or C_LOOP_WIN
    934953        cloopCallJSFunction callee
     
    936955        call callee, callPtrTag
    937956    end
     957
     958    defineOSRExitReturnLabel(opcodeName, size)
    938959    restoreStackPointerAfterCall()
    939960    dispatchAfterCall(size, opcodeStruct, dispatch)
     
    10051026end
    10061027
    1007 macro slowPathForCall(size, opcodeStruct, dispatch, slowPath, prepareCall)
     1028macro slowPathForCall(opcodeName, size, opcodeStruct, dispatch, slowPath, prepareCall)
    10081029    callCallSlowPath(
    10091030        slowPath,
     
    10141035            prepareCall(callee, t2, t3, t4, SlowPathPtrTag)
    10151036        .dontUpdateSP:
    1016             callTargetFunction(size, opcodeStruct, dispatch, callee, SlowPathPtrTag)
     1037            callTargetFunction(%opcodeName%_slow, size, opcodeStruct, dispatch, callee, SlowPathPtrTag)
    10171038        end)
     1039end
     1040
     1041macro getterSetterOSRExitReturnPoint(opName, size)
     1042    crash() # We don't reach this in straight line code. We only reach it via returning to the code below when reconstructing stack frames during OSR exit.
     1043
     1044    defineOSRExitReturnLabel(opName, size)
     1045
     1046    restoreStackPointerAfterCall()
     1047    loadi ArgumentCount + TagOffset[cfr], PC
    10181048end
    10191049
     
    17421772
    17431773
    1744 macro doCallVarargs(size, opcodeStruct, dispatch, frameSlowPath, slowPath, prepareCall)
     1774macro doCallVarargs(opcodeName, size, opcodeStruct, dispatch, frameSlowPath, slowPath, prepareCall)
    17451775    callSlowPath(frameSlowPath)
    17461776    branchIfException(_llint_throw_from_slow_path_trampoline)
     
    17571787        end
    17581788    end
    1759     slowPathForCall(size, opcodeStruct, dispatch, slowPath, prepareCall)
     1789    slowPathForCall(opcodeName, size, opcodeStruct, dispatch, slowPath, prepareCall)
    17601790end
    17611791
    17621792
    17631793llintOp(op_call_varargs, OpCallVarargs, macro (size, get, dispatch)
    1764     doCallVarargs(size, OpCallVarargs, dispatch, _llint_slow_path_size_frame_for_varargs, _llint_slow_path_call_varargs, prepareForRegularCall)
     1794    doCallVarargs(op_call_varargs, size, OpCallVarargs, dispatch, _llint_slow_path_size_frame_for_varargs, _llint_slow_path_call_varargs, prepareForRegularCall)
    17651795end)
    17661796
     
    17691799    # We lie and perform the tail call instead of preparing it since we can't
    17701800    # prepare the frame for a call opcode
    1771     doCallVarargs(size, OpTailCallVarargs, dispatch, _llint_slow_path_size_frame_for_varargs, _llint_slow_path_tail_call_varargs, prepareForTailCall)
     1801    doCallVarargs(op_tail_call_varargs, size, OpTailCallVarargs, dispatch, _llint_slow_path_size_frame_for_varargs, _llint_slow_path_tail_call_varargs, prepareForTailCall)
    17721802end)
    17731803
     
    17771807    # We lie and perform the tail call instead of preparing it since we can't
    17781808    # prepare the frame for a call opcode
    1779     doCallVarargs(size, OpTailCallForwardArguments, dispatch, _llint_slow_path_size_frame_for_forward_arguments, _llint_slow_path_tail_call_forward_arguments, prepareForTailCall)
     1809    doCallVarargs(op_tail_call_forward_arguments, size, OpTailCallForwardArguments, dispatch, _llint_slow_path_size_frame_for_forward_arguments, _llint_slow_path_tail_call_forward_arguments, prepareForTailCall)
    17801810end)
    17811811
    17821812
    17831813llintOp(op_construct_varargs, OpConstructVarargs, macro (size, get, dispatch)
    1784     doCallVarargs(size, OpConstructVarargs, dispatch, _llint_slow_path_size_frame_for_varargs, _llint_slow_path_construct_varargs, prepareForRegularCall)
     1814    doCallVarargs(op_construct_varargs, size, OpConstructVarargs, dispatch, _llint_slow_path_size_frame_for_varargs, _llint_slow_path_construct_varargs, prepareForRegularCall)
    17851815end)
    17861816
     
    18211851_llint_op_call_eval:
    18221852    slowPathForCall(
     1853        op_call_eval_narrow,
    18231854        narrow,
    18241855        OpCallEval,
     
    18291860_llint_op_call_eval_wide16:
    18301861    slowPathForCall(
     1862        op_call_eval_wide16,
    18311863        wide16,
    18321864        OpCallEval,
     
    18371869_llint_op_call_eval_wide32:
    18381870    slowPathForCall(
     1871        op_call_eval_wide32,
    18391872        wide32,
    18401873        OpCallEval,
  • trunk/Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm

    r249547 r250750  
    13991399    callSlowPath(_llint_slow_path_get_by_id)
    14001400    dispatch()
     1401
     1402# osr return point
     1403    getterSetterOSRExitReturnPoint(op_get_by_id, size)
     1404    metadata(t2, t3)
     1405    valueProfile(OpGetById, t2, r1, r0)
     1406    return(r1, r0)
     1407
    14011408end)
    14021409
     
    14611468    callSlowPath(_llint_slow_path_put_by_id)
    14621469    dispatch()
     1470
     1471# osr return point
     1472    getterSetterOSRExitReturnPoint(op_put_by_id, size)
     1473    dispatch()
     1474
    14631475end)
    14641476
     
    15121524    callSlowPath(_llint_slow_path_get_by_val)
    15131525    dispatch()
    1514 end)
    1515 
    1516 
    1517 macro putByValOp(opcodeName, opcodeStruct)
     1526
     1527# osr return point
     1528    getterSetterOSRExitReturnPoint(op_get_by_val, size)
     1529    metadata(t2, t3)
     1530    valueProfile(OpGetByVal, t2, r1, r0)
     1531    return(r1, r0)
     1532
     1533end)
     1534
     1535
     1536macro putByValOp(opcodeName, opcodeStruct, osrExitPoint)
    15181537    llintOpWithMetadata(op_%opcodeName%, opcodeStruct, macro (size, get, dispatch, metadata, return)
    15191538        macro contiguousPutByVal(storeCallback)
     
    16031622        callSlowPath(_llint_slow_path_%opcodeName%)
    16041623        dispatch()
     1624
     1625    .osrExitPoint:
     1626        osrExitPoint(size, dispatch)
    16051627    end)
    16061628end
    16071629
    16081630
    1609 putByValOp(put_by_val, OpPutByVal)
    1610 
    1611 putByValOp(put_by_val_direct, OpPutByValDirect)
     1631putByValOp(put_by_val, OpPutByVal, macro (size, dispatch)
     1632    # osr return point
     1633    getterSetterOSRExitReturnPoint(op_put_by_val, size)
     1634    dispatch()
     1635end)
     1636
     1637putByValOp(put_by_val_direct, OpPutByValDirect, macro (a, b) end)
    16121638
    16131639
     
    18761902        move t3, sp
    18771903        prepareCall(%opcodeStruct%::Metadata::m_callLinkInfo.m_machineCodeTarget[t5], t2, t3, t4, JSEntryPtrTag)
    1878         callTargetFunction(size, opcodeStruct, dispatch, %opcodeStruct%::Metadata::m_callLinkInfo.m_machineCodeTarget[t5], JSEntryPtrTag)
     1904        callTargetFunction(opcodeName, size, opcodeStruct, dispatch, %opcodeStruct%::Metadata::m_callLinkInfo.m_machineCodeTarget[t5], JSEntryPtrTag)
    18791905
    18801906    .opCallSlow:
    1881         slowPathForCall(size, opcodeStruct, dispatch, slowPath, prepareCall)
     1907        slowPathForCall(opcodeName, size, opcodeStruct, dispatch, slowPath, prepareCall)
    18821908    end)
    18831909end
  • trunk/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm

    r250313 r250750  
    13261326end)
    13271327
    1328 
    13291328llintOpWithMetadata(op_get_by_id, OpGetById, macro (size, get, dispatch, metadata, return)
    13301329    metadata(t2, t1)
     
    13771376    callSlowPath(_llint_slow_path_get_by_id)
    13781377    dispatch()
     1378
     1379# osr return point
     1380    getterSetterOSRExitReturnPoint(op_get_by_id, size)
     1381    metadata(t2, t3)
     1382    valueProfile(OpGetById, t2, r0)
     1383    return(r0)
     1384
    13791385end)
    13801386
     
    14491455    callSlowPath(_llint_slow_path_put_by_id)
    14501456    dispatch()
     1457
     1458# osr return point
     1459    getterSetterOSRExitReturnPoint(op_put_by_id, size)
     1460    dispatch()
     1461
    14511462end)
    14521463
     
    16201631    callSlowPath(_llint_slow_path_get_by_val)
    16211632    dispatch()
    1622 end)
    1623 
    1624 
    1625 macro putByValOp(opcodeName, opcodeStruct)
     1633
     1634# osr return point
     1635    getterSetterOSRExitReturnPoint(op_get_by_val, size)
     1636    metadata(t5, t2)
     1637    valueProfile(OpGetByVal, t5, r0)
     1638    return(r0)
     1639
     1640end)
     1641
     1642
     1643macro putByValOp(opcodeName, opcodeStruct, osrExitPoint)
    16261644    llintOpWithMetadata(op_%opcodeName%, opcodeStruct, macro (size, get, dispatch, metadata, return)
    16271645        macro contiguousPutByVal(storeCallback)
     
    17111729        callSlowPath(_llint_slow_path_%opcodeName%)
    17121730        dispatch()
     1731
     1732        osrExitPoint(size, dispatch)
     1733       
    17131734    end)
    17141735end
    17151736
    1716 putByValOp(put_by_val, OpPutByVal)
    1717 
    1718 putByValOp(put_by_val_direct, OpPutByValDirect)
     1737putByValOp(put_by_val, OpPutByVal, macro (size, dispatch)
     1738    # osr return point
     1739    getterSetterOSRExitReturnPoint(op_put_by_val, size)
     1740    dispatch()
     1741end)
     1742
     1743putByValOp(put_by_val_direct, OpPutByValDirect, macro (a, b) end)
    17191744
    17201745
     
    20052030        move t3, sp
    20062031        prepareCall(%opcodeStruct%::Metadata::m_callLinkInfo.m_machineCodeTarget[t5], t2, t3, t4, JSEntryPtrTag)
    2007         callTargetFunction(size, opcodeStruct, dispatch, %opcodeStruct%::Metadata::m_callLinkInfo.m_machineCodeTarget[t5], JSEntryPtrTag)
     2032        callTargetFunction(opcodeName, size, opcodeStruct, dispatch, %opcodeStruct%::Metadata::m_callLinkInfo.m_machineCodeTarget[t5], JSEntryPtrTag)
    20082033
    20092034    .opCallSlow:
    2010         slowPathForCall(size, opcodeStruct, dispatch, slowPath, prepareCall)
     2035        slowPathForCall(opcodeName, size, opcodeStruct, dispatch, slowPath, prepareCall)
    20112036    end)
    20122037end
  • trunk/Source/JavaScriptCore/offlineasm/asm.rb

    r245906 r250750  
    215215    def putsLabel(labelName, isGlobal)
    216216        raise unless @state == :asm
    217         @deferredNextLabelActions.each {
    218             | action |
    219             action.call()
    220         }
     217        unless isGlobal
     218            @deferredNextLabelActions.each {
     219                | action |
     220                action.call()
     221            }
     222        end
    221223        @deferredNextLabelActions = []
    222224        @numGlobalLabels += 1
     
    402404            lowLevelAST.validate
    403405            emitCodeInConfiguration(concreteSettings, lowLevelAST, backend) {
    404                  $currentSettings = concreteSettings
     406                $currentSettings = concreteSettings
    405407                $asm.inAsm {
    406408                    lowLevelAST.lower(backend)
  • trunk/Source/JavaScriptCore/offlineasm/transform.rb

    r237547 r250750  
    260260                end
    261261            }
    262             Label.forName(codeOrigin, name, @definedInFile)
     262            result = Label.forName(codeOrigin, name, @definedInFile)
     263            result.setGlobal() if @global
     264            result
    263265        else
    264266            self
     
    273275                mapping[var].name
    274276            }
    275             Label.forName(codeOrigin, name, @definedInFile)
     277            result = Label.forName(codeOrigin, name, @definedInFile)
     278            result.setGlobal() if @global
     279            result
    276280        else
    277281            self
  • trunk/Source/JavaScriptCore/runtime/OptionsList.h

    r250559 r250750  
    465465    v(Double, dumpJITMemoryFlushInterval, 10, Restricted, "Maximum time in between flushes of the JIT memory dump in seconds.") \
    466466    v(Bool, useUnlinkedCodeBlockJettisoning, false, Normal, "If true, UnlinkedCodeBlock can be jettisoned.") \
     467    v(Bool, forceOSRExitToLLInt, false, Normal, "If true, we always exit to the LLInt. If false, we exit to whatever is most convenient.") \
    467468
    468469enum OptionEquivalence {
  • trunk/Tools/ChangeLog

    r250746 r250750  
     12019-10-04  Saam Barati  <[email protected]>
     2
     3        Allow OSR exit to the LLInt
     4        https://bugs.webkit.org/show_bug.cgi?id=197993
     5
     6        Reviewed by Tadeu Zagallo.
     7
     8        * Scripts/run-jsc-stress-tests:
     9
    1102019-10-04  Matt Lewis  <[email protected]>
    211
  • trunk/Tools/Scripts/run-jsc-stress-tests

    r250559 r250750  
    496496FTL_OPTIONS = ["--useFTLJIT=true"]
    497497PROBE_OSR_EXIT_OPTION = ["--useProbeOSRExit=true"]
     498FORCE_LLINT_EXIT_OPTIONS = ["--forceOSRExitToLLInt=true"]
    498499
    499500require_relative "webkitruby/jsc-stress-test-writer-#{$testWriter}"
     
    709710
    710711def runFTLNoCJITB3O0(*optionalTestSpecificOptions)
    711     run("ftl-no-cjit-b3o0", "--useArrayAllocationProfiling=false", "--forcePolyProto=true", *(FTL_OPTIONS + NO_CJIT_OPTIONS + B3O0_OPTIONS + optionalTestSpecificOptions))
     712    run("ftl-no-cjit-b3o0", "--useArrayAllocationProfiling=false", "--forcePolyProto=true", *(FTL_OPTIONS + NO_CJIT_OPTIONS + B3O0_OPTIONS + FORCE_LLINT_EXIT_OPTIONS + optionalTestSpecificOptions))
    712713end
    713714
     
    729730
    730731def runDFGEager(*optionalTestSpecificOptions)
    731     run("dfg-eager", *(EAGER_OPTIONS + COLLECT_CONTINUOUSLY_OPTIONS + PROBE_OSR_EXIT_OPTION + optionalTestSpecificOptions))
     732    run("dfg-eager", *(EAGER_OPTIONS + COLLECT_CONTINUOUSLY_OPTIONS + PROBE_OSR_EXIT_OPTION + FORCE_LLINT_EXIT_OPTIONS + optionalTestSpecificOptions))
    732733end
    733734
     
    746747
    747748def runFTLEagerNoCJITValidate(*optionalTestSpecificOptions)
    748     run("ftl-eager-no-cjit", "--validateGraph=true", "--airForceIRCAllocator=true", *(FTL_OPTIONS + NO_CJIT_OPTIONS + EAGER_OPTIONS + COLLECT_CONTINUOUSLY_OPTIONS + optionalTestSpecificOptions))
     749    run("ftl-eager-no-cjit", "--validateGraph=true", "--airForceIRCAllocator=true", *(FTL_OPTIONS + NO_CJIT_OPTIONS + EAGER_OPTIONS + COLLECT_CONTINUOUSLY_OPTIONS + FORCE_LLINT_EXIT_OPTIONS + optionalTestSpecificOptions))
    749750end
    750751
Note: See TracChangeset for help on using the changeset viewer.