Ignore:
Timestamp:
Sep 18, 2012, 6:20:52 PM (13 years ago)
Author:
[email protected]
Message:

DFG should not call out to C++ every time that it tries to put to an object that doesn't yet have array storage
https://bugs.webkit.org/show_bug.cgi?id=96983

Reviewed by Oliver Hunt.

Introduce more polymorphism into the DFG's array mode support. Use that to
introduce the notion of effectul array modes, where the check for the mode
will perform actions necessary to ensure that we have the mode we want, if
the object is not already in that mode. Also added profiling support for
checking if an object is of a type that would not allow us to create array
storage (like a typed array or a string for example).

This is a ~2x speed-up on loops that transform an object that did not have
indexed storage into one that does.

  • JSCTypedArrayStubs.h:

(JSC):

  • bytecode/ArrayProfile.cpp:

(JSC::ArrayProfile::computeUpdatedPrediction):

  • bytecode/ArrayProfile.h:

(JSC::ArrayProfile::ArrayProfile):
(JSC::ArrayProfile::mayInterceptIndexedAccesses):
(ArrayProfile):

  • dfg/DFGAbstractState.cpp:

(JSC::DFG::AbstractState::execute):

  • dfg/DFGArrayMode.cpp:

(JSC::DFG::fromObserved):
(DFG):
(JSC::DFG::modeAlreadyChecked):
(JSC::DFG::modeToString):

  • dfg/DFGArrayMode.h:

(DFG):
(JSC::DFG::modeUsesButterfly):
(JSC::DFG::isSlowPutAccess):
(JSC::DFG::benefitsFromStructureCheck):
(JSC::DFG::isEffectful):

  • dfg/DFGByteCodeParser.cpp:

(JSC::DFG::ByteCodeParser::getArrayMode):
(JSC::DFG::ByteCodeParser::getArrayModeAndEmitChecks):
(JSC::DFG::ByteCodeParser::parseBlock):

  • dfg/DFGCSEPhase.cpp:

(JSC::DFG::CSEPhase::getPropertyStorageLoadElimination):

  • dfg/DFGFixupPhase.cpp:

(JSC::DFG::FixupPhase::fixupNode):
(JSC::DFG::FixupPhase::checkArray):

  • dfg/DFGGraph.h:

(JSC::DFG::Graph::byValIsPure):

  • dfg/DFGNode.h:

(JSC::DFG::Node::hasArrayMode):

  • dfg/DFGNodeType.h:

(DFG):

  • dfg/DFGOperations.cpp:
  • dfg/DFGOperations.h:
  • dfg/DFGPredictionPropagationPhase.cpp:

(JSC::DFG::PredictionPropagationPhase::propagate):

  • dfg/DFGSpeculativeJIT.cpp:

(JSC::DFG::SpeculativeJIT::checkArray):
(JSC::DFG::SpeculativeJIT::arrayify):
(DFG):

  • dfg/DFGSpeculativeJIT.h:

(SpeculativeJIT):

  • dfg/DFGSpeculativeJIT32_64.cpp:

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

  • dfg/DFGSpeculativeJIT64.cpp:

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

  • runtime/Arguments.h:

(Arguments):

  • runtime/JSNotAnObject.h:

(JSNotAnObject):

  • runtime/JSObject.h:

(JSObject):
(JSC::JSObject::ensureArrayStorage):

  • runtime/JSString.h:

(JSC::JSString::createStructure):

File:
1 edited

Legend:

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

    r128544 r128957  
    829829    {
    830830        profile->computeUpdatedPrediction();
    831         return fromObserved(profile->observedArrayModes(), false);
    832     }
    833    
    834     Array::Mode getArrayModeAndEmitChecks(ArrayProfile* profile, NodeIndex base)
     831        return fromObserved(profile, Array::Read, false);
     832    }
     833   
     834    Array::Mode getArrayModeAndEmitChecks(ArrayProfile* profile, Array::Action action, NodeIndex base)
    835835    {
    836836        profile->computeUpdatedPrediction();
    837         if (profile->hasDefiniteStructure())
    838             addToGraph(CheckStructure, OpInfo(m_graph.addStructureSet(profile->expectedStructure())), base);
    839837       
    840838#if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
    841839        if (m_inlineStackTop->m_profiledBlock->numberOfRareCaseProfiles())
    842840            dataLog("Slow case profile for bc#%u: %u\n", m_currentIndex, m_inlineStackTop->m_profiledBlock->rareCaseProfileForBytecodeOffset(m_currentIndex)->m_counter);
    843         dataLog("Array profile for bc#%u: %p%s, %u\n", m_currentIndex, profile->expectedStructure(), profile->structureIsPolymorphic() ? " (polymorphic)" : "", profile->observedArrayModes());
     841        dataLog("Array profile for bc#%u: %p%s%s, %u\n", m_currentIndex, profile->expectedStructure(), profile->structureIsPolymorphic() ? " (polymorphic)" : "", profile->mayInterceptIndexedAccesses() ? " (may intercept)" : "", profile->observedArrayModes());
    844842#endif
    845843       
     
    848846            || m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, OutOfBounds);
    849847       
    850         return fromObserved(profile->observedArrayModes(), makeSafe);
     848        Array::Mode result = fromObserved(profile, action, makeSafe);
     849       
     850        if (profile->hasDefiniteStructure() && benefitsFromStructureCheck(result))
     851            addToGraph(CheckStructure, OpInfo(m_graph.addStructureSet(profile->expectedStructure())), base);
     852       
     853        return result;
    851854    }
    852855   
     
    21892192           
    21902193            NodeIndex base = get(currentInstruction[2].u.operand);
    2191             Array::Mode arrayMode = getArrayModeAndEmitChecks(currentInstruction[4].u.arrayProfile, base);
     2194            Array::Mode arrayMode = getArrayModeAndEmitChecks(currentInstruction[4].u.arrayProfile, Array::Read, base);
    21922195            NodeIndex property = get(currentInstruction[3].u.operand);
    21932196            NodeIndex getByVal = addToGraph(GetByVal, OpInfo(arrayMode), OpInfo(prediction), base, property);
     
    22002203            NodeIndex base = get(currentInstruction[1].u.operand);
    22012204
    2202             Array::Mode arrayMode = getArrayModeAndEmitChecks(currentInstruction[4].u.arrayProfile, base);
     2205            Array::Mode arrayMode = getArrayModeAndEmitChecks(currentInstruction[4].u.arrayProfile, Array::Write, base);
    22032206           
    22042207            NodeIndex property = get(currentInstruction[2].u.operand);
Note: See TracChangeset for help on using the changeset viewer.