Ignore:
Timestamp:
Jun 22, 2012, 4:32:59 PM (13 years ago)
Author:
[email protected]
Message:

DFG tier-up should happen in prologues, not epilogues
https://bugs.webkit.org/show_bug.cgi?id=89752

Reviewed by Geoffrey Garen.

This change has two outcomes:

1) Slightly reduces the likelihood that a function will be optimized both
standalone and via inlining. Previously, if you had a call sequence like foo()
calls bar() exactly once, and nobody else calls bar(), then bar() would get
optimized first (because it returns first) and then foo() gets optimized. If foo()
can inline bar() then that means that bar() gets optimized twice. But now, if we
optimize in prologues, then foo() will be optimized first. If it inlines bar(),
that means that there will no longer be any calls to bar().

2) It lets us kill some code in JITStubs. Epilogue tier-up was very different from
loop tier-up, since epilogue tier-up should not attempt OSR. But prologue tier-up
requires OSR (albeit really easy OSR since it's the top of the compilation unit),
so it becomes just like loop tier-up. As a result, we now have one optimization
hook (cti_optimize) instead of two (cti_optimize_from_loop and
cti_optimize_from_ret).

As a consequence of not having an optimization check in epilogues, the OSR exit
code must now trigger reoptimization itself instead of just signaling the epilogue
check to fire.

This also adds the ability to count the number of DFG compilations, which was
useful for debugging this patch and might be useful for other things in the future.

  • bytecode/CodeBlock.cpp:

(JSC::CodeBlock::reoptimize):
(JSC):

  • bytecode/CodeBlock.h:

(CodeBlock):

  • dfg/DFGByteCodeParser.cpp:

(JSC::DFG::ByteCodeParser::parseCodeBlock):

  • dfg/DFGDriver.cpp:

(DFG):
(JSC::DFG::getNumCompilations):
(JSC::DFG::compile):

  • dfg/DFGDriver.h:

(DFG):

  • dfg/DFGOSRExitCompiler.cpp:

(JSC::DFG::OSRExitCompiler::handleExitCounts):

  • dfg/DFGOperations.cpp:
  • dfg/DFGOperations.h:
  • jit/JIT.cpp:

(JSC::JIT::emitOptimizationCheck):

  • jit/JIT.h:
  • jit/JITCall32_64.cpp:

(JSC::JIT::emit_op_ret):
(JSC::JIT::emit_op_ret_object_or_this):

  • jit/JITOpcodes.cpp:

(JSC::JIT::emit_op_ret):
(JSC::JIT::emit_op_ret_object_or_this):
(JSC::JIT::emit_op_enter):

  • jit/JITOpcodes32_64.cpp:

(JSC::JIT::emit_op_enter):

  • jit/JITStubs.cpp:

(JSC::DEFINE_STUB_FUNCTION):

  • jit/JITStubs.h:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/dfg/DFGOSRExitCompiler.cpp

    r120786 r121073  
    116116        m_jit.store32(GPRInfo::regT1, AssemblyHelpers::Address(GPRInfo::regT0, CodeBlock::offsetOfSpeculativeSuccessCounter()));
    117117       
     118        m_jit.move(AssemblyHelpers::TrustedImmPtr(m_jit.baselineCodeBlock()), GPRInfo::regT0);
     119
    118120        tooFewFails.append(m_jit.branch32(AssemblyHelpers::BelowOrEqual, GPRInfo::regT2, AssemblyHelpers::TrustedImm32(Options::forcedOSRExitCountForReoptimization)));
     121
    119122    } else {
    120123        // Proceed based on the assumption that we can handle these exits so long as they
     
    137140
    138141    // Reoptimize as soon as possible.
    139     m_jit.store32(AssemblyHelpers::TrustedImm32(0), AssemblyHelpers::Address(GPRInfo::regT0, CodeBlock::offsetOfJITExecuteCounter()));
    140     m_jit.store32(AssemblyHelpers::TrustedImm32(0), AssemblyHelpers::Address(GPRInfo::regT0, CodeBlock::offsetOfJITExecutionActiveThreshold()));
     142#if !NUMBER_OF_ARGUMENT_REGISTERS
     143    m_jit.poke(GPRInfo::regT0);
     144#else
     145    m_jit.move(GPRInfo::regT0, GPRInfo::argumentGPR0);
     146    ASSERT(GPRInfo::argumentGPR0 != GPRInfo::regT1);
     147#endif
     148    m_jit.move(AssemblyHelpers::TrustedImmPtr(bitwise_cast<void*>(triggerReoptimizationNow)), GPRInfo::regT1);
     149    m_jit.call(GPRInfo::regT1);
    141150    AssemblyHelpers::Jump doneAdjusting = m_jit.jump();
    142151   
Note: See TracChangeset for help on using the changeset viewer.