Ignore:
Timestamp:
Mar 16, 2016, 1:12:27 PM (9 years ago)
Author:
[email protected]
Message:

ASSERTION FAILED: !edge->isPhantomAllocation() in regress/script-tests/sink-huge-activation.js.ftl-eager in debug mode
https://bugs.webkit.org/show_bug.cgi?id=153805

Reviewed by Mark Lam.

The object allocation sinking phase uses InferredValue::isStillValid() in the opposite
way from most clients: it will do an *extra* optimization if it returns false. The
phase will first compute sink candidates and then it will compute materialization
points. If something is a sink candidate then it is not a materialization point. A
NewFunction node may appear as not being a sink candidate during the first pass, so it's
not added to the set of things that will turn into PhantomNewFunction. But on the second
pass where we add materializations, we check isStillValid() again. Now this may become
false, so that second pass thinks that NewFunction is a sink candidate (even though it's
not in the sink candidates set) and so is not a materialization point.

This manifests as the NewFunction referring to a PhantomCreateActivation or whatever.

The solution is to have the phase cache results of calls to isStillValid(). It's OK if
we just remember the result of the first call and assume that it's not a sink candidate.
That's the worst that can happen.

No new tests since this is a super hard race and sink-huge-activation seemed to already
be catching it.

  • dfg/DFGObjectAllocationSinkingPhase.cpp:
File:
1 edited

Legend:

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

    r194496 r198296  
    839839        case NewArrowFunction:
    840840        case NewGeneratorFunction: {
    841             if (node->castOperand<FunctionExecutable*>()->singletonFunction()->isStillValid()) {
     841            if (isStillValid(node->castOperand<FunctionExecutable*>()->singletonFunction())) {
    842842                m_heap.escape(node->child1().node());
    843843                break;
     
    856856
    857857        case CreateActivation: {
    858             if (node->castOperand<SymbolTable*>()->singletonScope()->isStillValid()) {
     858            if (isStillValid(node->castOperand<SymbolTable*>()->singletonScope())) {
    859859                m_heap.escape(node->child1().node());
    860860                break;
     
    21742174    }
    21752175
     2176    // This is a great way of asking value->isStillValid() without having to worry about getting
     2177    // different answers. It turns out that this analysis works OK regardless of what this
     2178    // returns but breaks badly if this changes its mind for any particular InferredValue. This
     2179    // method protects us from that.
     2180    bool isStillValid(InferredValue* value)
     2181    {
     2182        return m_validInferredValues.add(value, value->isStillValid()).iterator->value;
     2183    }
     2184
    21762185    SSACalculator m_pointerSSA;
    21772186    SSACalculator m_allocationSSA;
     
    21842193    CombinedLiveness m_combinedLiveness;
    21852194
     2195    HashMap<InferredValue*, bool> m_validInferredValues;
     2196
    21862197    HashMap<Node*, Node*> m_materializationToEscapee;
    21872198    HashMap<Node*, Vector<Node*>> m_materializationSiteToMaterializations;
Note: See TracChangeset for help on using the changeset viewer.