Ignore:
Timestamp:
Apr 28, 2014, 12:01:07 PM (11 years ago)
Author:
[email protected]
Message:

GC should be able to remove things from the DFG worklist and cancel on-going compilations if it knows that the compilation would already be invalidated
https://bugs.webkit.org/show_bug.cgi?id=132166

Reviewed by Oliver Hunt and Mark Hahnenberg.

The GC can aid type inference by removing structures that are dead and jettisoning
code that relies on those structures. This can dramatically accelerate type inference
for some tricky programs.

Unfortunately, we previously pinned any structures that enqueued compilations depended
on. This means that if you're on a machine that only runs a single compilation thread
and where compilations are relatively slow, you have a high chance of large numbers of
structures being pinned during any GC since the compilation queue is likely to be full
of random stuff.

This comprehensively fixes this issue by allowing the GC to remove compilation plans
if the things they depend on are dead, and to even cancel safepointed compilations.

  • bytecode/CodeBlock.cpp:

(JSC::CodeBlock::shouldImmediatelyAssumeLivenessDuringScan):
(JSC::CodeBlock::isKnownToBeLiveDuringGC):
(JSC::CodeBlock::finalizeUnconditionally):

  • bytecode/CodeBlock.h:

(JSC::CodeBlock::shouldImmediatelyAssumeLivenessDuringScan): Deleted.

  • dfg/DFGDesiredIdentifiers.cpp:

(JSC::DFG::DesiredIdentifiers::DesiredIdentifiers):

  • dfg/DFGDesiredIdentifiers.h:
  • dfg/DFGDesiredWatchpoints.h:
  • dfg/DFGDesiredWeakReferences.cpp:

(JSC::DFG::DesiredWeakReferences::DesiredWeakReferences):

  • dfg/DFGDesiredWeakReferences.h:
  • dfg/DFGGraphSafepoint.cpp:

(JSC::DFG::GraphSafepoint::GraphSafepoint):

  • dfg/DFGGraphSafepoint.h:
  • dfg/DFGPlan.cpp:

(JSC::DFG::Plan::Plan):
(JSC::DFG::Plan::compileInThread):
(JSC::DFG::Plan::compileInThreadImpl):
(JSC::DFG::Plan::notifyCompiling):
(JSC::DFG::Plan::notifyCompiled):
(JSC::DFG::Plan::notifyReady):
(JSC::DFG::Plan::checkLivenessAndVisitChildren):
(JSC::DFG::Plan::isKnownToBeLiveDuringGC):
(JSC::DFG::Plan::cancel):
(JSC::DFG::Plan::visitChildren): Deleted.

  • dfg/DFGPlan.h:
  • dfg/DFGSafepoint.cpp:

(JSC::DFG::Safepoint::Result::~Result):
(JSC::DFG::Safepoint::Result::didGetCancelled):
(JSC::DFG::Safepoint::Safepoint):
(JSC::DFG::Safepoint::~Safepoint):
(JSC::DFG::Safepoint::checkLivenessAndVisitChildren):
(JSC::DFG::Safepoint::isKnownToBeLiveDuringGC):
(JSC::DFG::Safepoint::cancel):
(JSC::DFG::Safepoint::visitChildren): Deleted.

  • dfg/DFGSafepoint.h:

(JSC::DFG::Safepoint::Result::Result):

  • dfg/DFGWorklist.cpp:

(JSC::DFG::Worklist::compilationState):
(JSC::DFG::Worklist::waitUntilAllPlansForVMAreReady):
(JSC::DFG::Worklist::removeAllReadyPlansForVM):
(JSC::DFG::Worklist::completeAllReadyPlansForVM):
(JSC::DFG::Worklist::visitWeakReferences):
(JSC::DFG::Worklist::removeDeadPlans):
(JSC::DFG::Worklist::runThread):
(JSC::DFG::Worklist::visitChildren): Deleted.

  • dfg/DFGWorklist.h:
  • ftl/FTLCompile.cpp:

(JSC::FTL::compile):

  • ftl/FTLCompile.h:
  • heap/CodeBlockSet.cpp:

(JSC::CodeBlockSet::rememberCurrentlyExecutingCodeBlocks):

  • heap/Heap.cpp:

(JSC::Heap::markRoots):
(JSC::Heap::visitCompilerWorklistWeakReferences):
(JSC::Heap::removeDeadCompilerWorklistEntries):
(JSC::Heap::visitWeakHandles):
(JSC::Heap::collect):
(JSC::Heap::visitCompilerWorklists): Deleted.

  • heap/Heap.h:
File:
1 edited

Legend:

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

    r167325 r167897  
    19711971    RELEASE_ASSERT_NOT_REACHED();
    19721972#endif // ENABLE(DFG_JIT)
     1973}
     1974
     1975bool CodeBlock::shouldImmediatelyAssumeLivenessDuringScan()
     1976{
     1977#if ENABLE(DFG_JIT)
     1978    // Interpreter and Baseline JIT CodeBlocks don't need to be jettisoned when
     1979    // their weak references go stale. So if a basline JIT CodeBlock gets
     1980    // scanned, we can assume that this means that it's live.
     1981    if (!JITCode::isOptimizingJIT(jitType()))
     1982        return true;
     1983
     1984    // For simplicity, we don't attempt to jettison code blocks during GC if
     1985    // they are executing. Instead we strongly mark their weak references to
     1986    // allow them to continue to execute soundly.
     1987    if (m_mayBeExecuting)
     1988        return true;
     1989
     1990    if (Options::forceDFGCodeBlockLiveness())
     1991        return true;
     1992
     1993    return false;
     1994#else
     1995    return true;
     1996#endif
     1997}
     1998
     1999bool CodeBlock::isKnownToBeLiveDuringGC()
     2000{
     2001#if ENABLE(DFG_JIT)
     2002    // This should return true for:
     2003    // - Code blocks that behave like normal objects - i.e. if they are referenced then they
     2004    //   are live.
     2005    // - Code blocks that were running on the stack.
     2006    // - Code blocks that survived the last GC if the current GC is an Eden GC. This is
     2007    //   because either livenessHasBeenProved would have survived as true or m_mayBeExecuting
     2008    //   would survive as true.
     2009    // - Code blocks that don't have any dead weak references.
     2010   
     2011    return shouldImmediatelyAssumeLivenessDuringScan()
     2012        || m_jitCode->dfgCommon()->livenessHasBeenProved;
     2013#else
     2014    return true;
     2015#endif
    19732016}
    19742017
     
    22162259#if ENABLE(DFG_JIT)
    22172260    // Check if we're not live. If we are, then jettison.
    2218     if (!(shouldImmediatelyAssumeLivenessDuringScan() || m_jitCode->dfgCommon()->livenessHasBeenProved)) {
     2261    if (!isKnownToBeLiveDuringGC()) {
    22192262        if (Options::verboseOSR())
    22202263            dataLog(*this, " has dead weak references, jettisoning during GC.\n");
Note: See TracChangeset for help on using the changeset viewer.