Ignore:
Timestamp:
Oct 4, 2017, 1:00:01 PM (8 years ago)
Author:
[email protected]
Message:

Add support for using Probe DFG OSR Exit behind a runtime flag.
https://bugs.webkit.org/show_bug.cgi?id=177844
<rdar://problem/34801425>

Reviewed by Saam Barati.

Source/JavaScriptCore:

This is based on the code originally posted in https://bugs.webkit.org/show_bug.cgi?id=175144
(in r221774 and r221832) with some optimizations and bug fixes added. The probe
based DFG OSR Exit is only enabled if Options::useProbeOSRExit() is true. We're
landing this behind an option switch to make it easier to tune performance using
the probe based OSR exit.

  • JavaScriptCore.xcodeproj/project.pbxproj:
  • assembler/MacroAssembler.cpp:

(JSC::stdFunctionCallback):

  • assembler/MacroAssemblerPrinter.cpp:

(JSC::Printer::printCallback):

  • assembler/ProbeContext.cpp:

(JSC::Probe::executeProbe):
(JSC::Probe::flushDirtyStackPages):

  • assembler/ProbeContext.h:

(JSC::Probe::Context::Context):
(JSC::Probe::Context::arg):

  • assembler/ProbeFrame.h: Added.

(JSC::Probe::Frame::Frame):
(JSC::Probe::Frame::argument):
(JSC::Probe::Frame::operand):
(JSC::Probe::Frame::setArgument):
(JSC::Probe::Frame::setOperand):
(JSC::Probe::Frame::get):
(JSC::Probe::Frame::set):

  • assembler/ProbeStack.cpp:

(JSC::Probe::Page::lowWatermarkFromVisitingDirtyChunks):
(JSC::Probe::Stack::Stack):
(JSC::Probe::Stack::lowWatermarkFromVisitingDirtyPages):

  • assembler/ProbeStack.h:

(JSC::Probe::Stack::Stack):
(JSC::Probe::Stack::lowWatermark):
(JSC::Probe::Stack::set):
(JSC::Probe::Stack::savedStackPointer const):
(JSC::Probe::Stack::setSavedStackPointer):
(JSC::Probe::Stack::newStackPointer const): Deleted.
(JSC::Probe::Stack::setNewStackPointer): Deleted.

  • bytecode/ArrayProfile.h:

(JSC::ArrayProfile::observeArrayMode):

  • bytecode/CodeBlock.cpp:

(JSC::CodeBlock::updateOSRExitCounterAndCheckIfNeedToReoptimize):

  • bytecode/CodeBlock.h:

(JSC::CodeBlock::addressOfOSRExitCounter): Deleted.

  • bytecode/ExecutionCounter.h:

(JSC::ExecutionCounter::hasCrossedThreshold const):
(JSC::ExecutionCounter::setNewThresholdForOSRExit):

  • bytecode/MethodOfGettingAValueProfile.cpp:

(JSC::MethodOfGettingAValueProfile::reportValue):

  • bytecode/MethodOfGettingAValueProfile.h:
  • dfg/DFGDriver.cpp:

(JSC::DFG::compileImpl):

  • dfg/DFGJITCompiler.cpp:

(JSC::DFG::JITCompiler::linkOSRExits):
(JSC::DFG::JITCompiler::link):

  • dfg/DFGOSRExit.cpp:

(JSC::DFG::jsValueFor):
(JSC::DFG::restoreCalleeSavesFor):
(JSC::DFG::saveCalleeSavesFor):
(JSC::DFG::restoreCalleeSavesFromVMEntryFrameCalleeSavesBuffer):
(JSC::DFG::copyCalleeSavesToVMEntryFrameCalleeSavesBuffer):
(JSC::DFG::saveOrCopyCalleeSavesFor):
(JSC::DFG::createDirectArgumentsDuringExit):
(JSC::DFG::createClonedArgumentsDuringExit):
(JSC::DFG::emitRestoreArguments):
(JSC::DFG::OSRExit::executeOSRExit):
(JSC::DFG::reifyInlinedCallFrames):
(JSC::DFG::adjustAndJumpToTarget):
(JSC::DFG::printOSRExit):

  • dfg/DFGOSRExit.h:

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

  • dfg/DFGThunks.cpp:

(JSC::DFG::osrExitThunkGenerator):

  • dfg/DFGThunks.h:
  • dfg/DFGVariableEventStream.cpp:

(JSC::DFG::tryToSetConstantRecovery):
(JSC::DFG::VariableEventStream::reconstruct const):
(JSC::DFG::VariableEventStream::tryToSetConstantRecovery const): Deleted.

  • dfg/DFGVariableEventStream.h:
  • profiler/ProfilerOSRExit.h:

(JSC::Profiler::OSRExit::incCount):

  • runtime/JSCJSValue.h:
  • runtime/JSCJSValueInlines.h:
  • runtime/Options.h:

Tools:

Enable --useProbeOSrExit=true for dfg-eager and ftl-no-cjit-validate-sampling-profiler
test configurations.

  • Scripts/run-jsc-stress-tests:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp

    r222827 r222871  
    23212321}
    23222322
     2323auto CodeBlock::updateOSRExitCounterAndCheckIfNeedToReoptimize(DFG::OSRExitState& exitState) -> OptimizeAction
     2324{
     2325    DFG::OSRExitBase& exit = exitState.exit;
     2326    if (!exitKindMayJettison(exit.m_kind)) {
     2327        // FIXME: We may want to notice that we're frequently exiting
     2328        // at an op_catch that we didn't compile an entrypoint for, and
     2329        // then trigger a reoptimization of this CodeBlock:
     2330        // https://bugs.webkit.org/show_bug.cgi?id=175842
     2331        return OptimizeAction::None;
     2332    }
     2333
     2334    exit.m_count++;
     2335    m_osrExitCounter++;
     2336
     2337    CodeBlock* baselineCodeBlock = exitState.baselineCodeBlock;
     2338    ASSERT(baselineCodeBlock == baselineAlternative());
     2339    if (UNLIKELY(baselineCodeBlock->jitExecuteCounter().hasCrossedThreshold()))
     2340        return OptimizeAction::ReoptimizeNow;
     2341
     2342    // We want to figure out if there's a possibility that we're in a loop. For the outermost
     2343    // code block in the inline stack, we handle this appropriately by having the loop OSR trigger
     2344    // check the exit count of the replacement of the CodeBlock from which we are OSRing. The
     2345    // problem is the inlined functions, which might also have loops, but whose baseline versions
     2346    // don't know where to look for the exit count. Figure out if those loops are severe enough
     2347    // that we had tried to OSR enter. If so, then we should use the loop reoptimization trigger.
     2348    // Otherwise, we should use the normal reoptimization trigger.
     2349
     2350    bool didTryToEnterInLoop = false;
     2351    for (InlineCallFrame* inlineCallFrame = exit.m_codeOrigin.inlineCallFrame; inlineCallFrame; inlineCallFrame = inlineCallFrame->directCaller.inlineCallFrame) {
     2352        if (inlineCallFrame->baselineCodeBlock->ownerScriptExecutable()->didTryToEnterInLoop()) {
     2353            didTryToEnterInLoop = true;
     2354            break;
     2355        }
     2356    }
     2357
     2358    uint32_t exitCountThreshold = didTryToEnterInLoop
     2359        ? exitCountThresholdForReoptimizationFromLoop()
     2360        : exitCountThresholdForReoptimization();
     2361
     2362    if (m_osrExitCounter > exitCountThreshold)
     2363        return OptimizeAction::ReoptimizeNow;
     2364
     2365    // Too few fails. Adjust the execution counter such that the target is to only optimize after a while.
     2366    baselineCodeBlock->m_jitExecuteCounter.setNewThresholdForOSRExit(exitState.activeThreshold, exitState.memoryUsageAdjustedThreshold);
     2367    return OptimizeAction::None;
     2368}
     2369
    23232370void CodeBlock::optimizeNextInvocation()
    23242371{
Note: See TracChangeset for help on using the changeset viewer.