Ignore:
Timestamp:
Oct 5, 2015, 6:33:39 PM (10 years ago)
Author:
[email protected]
Message:

GC shouldn't cancel every FTL compilation
https://bugs.webkit.org/show_bug.cgi?id=149821

Reviewed by Saam Barati.

During one of the CodeBlock GC refactorings, we messed up the GC's compilation cancellation
code. The GC should be able to cancel compilation plans if it determines that the plan will
be DOA. But, prior to this fix, that code was killing every FTL compilation. This happened
because the meaning of CodeBlock::isKnownToBeLiveDuringGC() changed.

It's funny that this didn't show up as a bigger slow-down. Basically, those benchmarks that
GC a lot usually don't rely on good compilation, while those benchmarks that do rely on good
compilation usually don't GC a lot. That's probably why this wasn't super obvious when we
broke it.

This change just changes the cancellation logic so that it only cancels plans if the owning
executable is dead. This is safe; in fact the relevant method would be correct even if it
always returned true. It would also be correct if it always returned false. So, compared to
what we had before we changed isKnownToBeLiveDuringGC(), this new code will cancel fewer
compilations. But, that's better than cancelling every compilation. I've filed a bug and
written a FIXME for investigating ways to resurrect the old behavior:
https://bugs.webkit.org/show_bug.cgi?id=149823

Nonetheless, this change looks like it might be a 1% speed-up on Octane. It improves earley
and gbemu.

  • dfg/DFGPlan.cpp:

(JSC::DFG::Plan::isKnownToBeLiveDuringGC):

File:
1 edited

Legend:

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

    r190589 r190599  
    642642    if (stage == Cancelled)
    643643        return false;
     644
     645    // NOTE: From here on, this method can return anything and still be sound. It's sound to return
     646    // false because then we'll just cancel the compilation. It's always sound to do that. It's sound
     647    // to return true because then we'll just keep alive everything that the compilation needs to
     648    // have live. The only thing you have to worry about is performance. The goal of returning false
     649    // is to try to minimize the likelihood that we expend effort compiling something that will be
     650    // DOA - that is, the code being compiled is only reachable from the compilation worklist itself
     651    // or the code being compiled is going to have weak references to things that are otherwise dead.
     652    // If you return false too often, then you'll regress performance because you might be killing a
     653    // compilation that wouldn't have been DOA, and so you're losing opportunities to run faster
     654    // code. If you return true too often, then you'll regress performance because you might expend
     655    // too much effort compiling something that will be DOA.
     656   
    644657    if (!Heap::isMarked(codeBlock->ownerExecutable()))
    645658        return false;
    646     if (!codeBlock->alternative()->isKnownToBeLiveDuringGC())
    647         return false;
    648     if (!!profiledDFGCodeBlock && !profiledDFGCodeBlock->isKnownToBeLiveDuringGC())
    649         return false;
     659
     660    // FIXME: We could detect if the alternate CodeBlock or the profiled DFG CodeBlock have
     661    // experienced troubles and may be jettisoned.
     662    // https://bugs.webkit.org/show_bug.cgi?id=149823
     663
    650664    return true;
    651665}
Note: See TracChangeset for help on using the changeset viewer.