Ignore:
Timestamp:
Sep 21, 2011, 4:36:35 PM (14 years ago)
Author:
[email protected]
Message:

DFG should support continuous optimization
https://bugs.webkit.org/show_bug.cgi?id=68329

Reviewed by Geoffrey Garen.

This adds the ability to reoptimize a code block if speculation
failures happen frequently. 6% speed-up on Kraken, 1% slow-down
on V8, neutral on SunSpider.

(JSC::CodeBlock::CodeBlock):
(JSC::ProgramCodeBlock::jettison):
(JSC::EvalCodeBlock::jettison):
(JSC::FunctionCodeBlock::jettison):
(JSC::CodeBlock::shouldOptimizeNow):
(JSC::CodeBlock::dumpValueProfiles):

  • bytecode/CodeBlock.h:
  • dfg/DFGByteCodeParser.cpp:

(JSC::DFG::ByteCodeParser::getStrongPrediction):

  • dfg/DFGJITCompiler.cpp:

(JSC::DFG::JITCompiler::exitSpeculativeWithOSR):
(JSC::DFG::JITCompiler::compileEntry):
(JSC::DFG::JITCompiler::compileBody):

  • dfg/DFGJITCompiler.h:

(JSC::DFG::JITCompiler::noticeOSREntry):

  • dfg/DFGOSREntry.cpp:

(JSC::DFG::prepareOSREntry):

  • dfg/DFGOSREntry.h:

(JSC::DFG::getOSREntryDataBytecodeIndex):

  • dfg/DFGSpeculativeJIT.cpp:

(JSC::DFG::SpeculativeJIT::compile):

  • heap/ConservativeRoots.cpp:

(JSC::ConservativeRoots::ConservativeRoots):
(JSC::ConservativeRoots::~ConservativeRoots):
(JSC::DummyMarkHook::mark):
(JSC::ConservativeRoots::genericAddPointer):
(JSC::ConservativeRoots::genericAddSpan):
(JSC::ConservativeRoots::add):

  • heap/ConservativeRoots.h:
  • heap/Heap.cpp:

(JSC::Heap::addJettisonCodeBlock):
(JSC::Heap::markRoots):

  • heap/Heap.h:
  • heap/JettisonedCodeBlocks.cpp: Added.

(JSC::JettisonedCodeBlocks::JettisonedCodeBlocks):
(JSC::JettisonedCodeBlocks::~JettisonedCodeBlocks):
(JSC::JettisonedCodeBlocks::addCodeBlock):
(JSC::JettisonedCodeBlocks::clearMarks):
(JSC::JettisonedCodeBlocks::deleteUnmarkedCodeBlocks):
(JSC::JettisonedCodeBlocks::traceCodeBlocks):

  • heap/JettisonedCodeBlocks.h: Added.

(JSC::JettisonedCodeBlocks::mark):

  • interpreter/RegisterFile.cpp:

(JSC::RegisterFile::gatherConservativeRoots):

  • interpreter/RegisterFile.h:
  • jit/JITStubs.cpp:

(JSC::DEFINE_STUB_FUNCTION):

  • runtime/Executable.cpp:

(JSC::jettisonCodeBlock):
(JSC::EvalExecutable::jettisonOptimizedCode):
(JSC::ProgramExecutable::jettisonOptimizedCode):
(JSC::FunctionExecutable::jettisonOptimizedCodeForCall):
(JSC::FunctionExecutable::jettisonOptimizedCodeForConstruct):

  • runtime/Executable.h:

(JSC::FunctionExecutable::jettisonOptimizedCodeFor):

  • wtf/BitVector.h: Added.

(WTF::BitVector::BitVector):
(WTF::BitVector::~BitVector):
(WTF::BitVector::operator=):
(WTF::BitVector::size):
(WTF::BitVector::ensureSize):
(WTF::BitVector::resize):
(WTF::BitVector::clearAll):
(WTF::BitVector::get):
(WTF::BitVector::set):
(WTF::BitVector::clear):
(WTF::BitVector::bitsInPointer):
(WTF::BitVector::maxInlineBits):
(WTF::BitVector::byteCount):
(WTF::BitVector::makeInlineBits):
(WTF::BitVector::OutOfLineBits::numBits):
(WTF::BitVector::OutOfLineBits::numWords):
(WTF::BitVector::OutOfLineBits::bits):
(WTF::BitVector::OutOfLineBits::create):
(WTF::BitVector::OutOfLineBits::destroy):
(WTF::BitVector::OutOfLineBits::OutOfLineBits):
(WTF::BitVector::isInline):
(WTF::BitVector::outOfLineBits):
(WTF::BitVector::resizeOutOfLine):
(WTF::BitVector::bits):

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/jit/JITStubs.cpp

    r95666 r95681  
    19151915    unsigned bytecodeIndex = stackFrame.args[0].int32();
    19161916
    1917     if (!codeBlock->hasOptimizedReplacement()) {
     1917#if ENABLE(JIT_VERBOSE_OSR)
     1918    printf("Entered optimize_from_loop with executeCounter = %d, reoptimizationRetryCounter = %u, optimizationDelayCounter = %u\n", codeBlock->executeCounter(), codeBlock->reoptimizationRetryCounter(), codeBlock->optimizationDelayCounter());
     1919#endif
     1920
     1921    if (codeBlock->hasOptimizedReplacement()) {
     1922#if ENABLE(JIT_VERBOSE_OSR)
     1923        printf("Considering loop OSR into %p(%p) with success/fail %u/%u.\n", codeBlock, codeBlock->replacement(), codeBlock->replacement()->speculativeSuccessCounter(), codeBlock->replacement()->speculativeFailCounter());
     1924#endif
     1925        if (codeBlock->replacement()->shouldReoptimizeFromLoopNow()) {
     1926#if ENABLE(JIT_VERBOSE_OSR)
     1927            printf("Triggering reoptimization of %p(%p) (in loop).\n", codeBlock, codeBlock->replacement());
     1928#endif
     1929            codeBlock->reoptimize(callFrame->globalData());
     1930            return;
     1931        }
     1932    } else {
    19181933        if (!codeBlock->shouldOptimizeNow()) {
    19191934#if ENABLE(JIT_VERBOSE_OSR)
     
    19531968
    19541969        codeBlock->optimizeSoon();
     1970        optimizedCodeBlock->countSpeculationSuccess();
    19551971        STUB_SET_RETURN_ADDRESS(address);
    19561972        return;
     
    19611977#endif
    19621978
     1979    // Count the OSR failure as a speculation failure. If this happens a lot, then
     1980    // reoptimize.
     1981    optimizedCodeBlock->countSpeculationFailure();
     1982   
     1983#if ENABLE(JIT_VERBOSE_OSR)
     1984    printf("Encountered loop OSR failure into %p(%p) with success/fail %u/%u.\n", codeBlock, codeBlock->replacement(), codeBlock->replacement()->speculativeSuccessCounter(), codeBlock->replacement()->speculativeFailCounter());
     1985#endif
     1986
     1987    // We are a lot more conservative about triggering reoptimization after OSR failure than
     1988    // before it. If we enter the optimize_from_loop trigger with a bucket full of fail
     1989    // already, then we really would like to reoptimize immediately. But this case covers
     1990    // something else: there weren't many (or any) speculation failures before, but we just
     1991    // failed to enter the speculative code because some variable had the wrong value or
     1992    // because the OSR code decided for any spurious reason that it did not want to OSR
     1993    // right now. So, we only trigger reoptimization only upon the more conservative (non-loop)
     1994    // reoptimization trigger.
     1995    if (optimizedCodeBlock->shouldReoptimizeNow()) {
     1996#if ENABLE(JIT_VERBOSE_OSR)
     1997        printf("Triggering reoptimization of %p(%p) (in loop after OSR fail).\n", codeBlock, codeBlock->replacement());
     1998#endif
     1999        codeBlock->reoptimize(callFrame->globalData());
     2000        return;
     2001    }
     2002
    19632003    // OSR failed this time, but it might succeed next time! Let the code run a bit
    19642004    // longer and then try again.
     
    19732013    CodeBlock* codeBlock = callFrame->codeBlock();
    19742014   
    1975     if (codeBlock->hasOptimizedReplacement())
     2015#if ENABLE(JIT_VERBOSE_OSR)
     2016    printf("Entered optimize_from_ret with executeCounter = %d, reoptimizationRetryCounter = %u, optimizationDelayCounter = %u\n", codeBlock->executeCounter(), codeBlock->reoptimizationRetryCounter(), codeBlock->optimizationDelayCounter());
     2017#endif
     2018
     2019    if (codeBlock->hasOptimizedReplacement()) {
     2020#if ENABLE(JIT_VERBOSE_OSR)
     2021        printf("Returning from old JIT call frame with optimized replacement %p(%p), with success/fail %u/%u.\n", codeBlock, codeBlock->replacement(), codeBlock->replacement()->speculativeSuccessCounter(), codeBlock->replacement()->speculativeFailCounter());
     2022#endif
     2023        if (codeBlock->replacement()->shouldReoptimizeNow()) {
     2024#if ENABLE(JIT_VERBOSE_OSR)
     2025            printf("Triggering reoptimization of %p(%p) (in return).\n", codeBlock, codeBlock->replacement());
     2026#endif
     2027            codeBlock->reoptimize(callFrame->globalData());
     2028        }
     2029
    19762030        return;
     2031    }
    19772032   
    19782033    if (!codeBlock->shouldOptimizeNow()) {
Note: See TracChangeset for help on using the changeset viewer.