-
fpizlo@apple.com authored
https://bugs.webkit.org/show_bug.cgi?id=99260 Reviewed by Oliver Hunt. This change allows us to find out if an array access that has gone polymorphic is operating over known structures - i.e. the primordial array structures of the global object that the code block containing the array access belongs to. We term this state "OriginalArray" for short. The fact that the access has gone polymorphic means that the array profile will not be able to report the set of structures it had seen - but if it can tell us that all of the structures were primordial then it just so happens that we can deduce what the structure set would have been by just querying the code block's global object. This allows us to emit an ArrayifyToStructure instead of an Arrayify if we find that we need to do conversions. The fast path of an ArrayifyToStructure is exactly like the fast path of a CheckStructure and is mostly subject to the same optimizations. It also burns one fewer registers. Essentially the notion of OriginalArray is a super cheap way of getting the array profile to tell us a structure set instead of a singleton structure. Currently, the array profile can only tell us the structure seen at an array access if there was exactly one structure. If there were multiple structures, it won't tell us anything other than the array modes and other auxiliary profiling data (whether there were stores to holes, for example). With OriginalArray, we cheaply get a structure set if all of the structures were primordial for the code block's global object, since in that case the array mode set (ArrayModes) can directly tell us the structure set. In the future, we might consider adding complete structure sets to the array profiles, but I suspect that we would hit diminishing returns if we did so - it would only help if we have array accesses that are both polymorphic and are cross-global-object accesses (rare) or if the arrays had named properties or other structure transitions that are unrelated to indexing type (also rare). This also does away with Arrayify (and the new ArrayifyToStructure) returning the butterfly pointer. This turns out to be faster and easier to CSE. And, this also changes constant folding to be able to eliminate CheckStructure, ForwardCheckStructure, and ArrayifyToStructure in addition to being able to transform them into structure transition watchpoints. This is great for ArrayifyToStructure because then CSE and CFA know that there is no side effect. Converting CheckStructure and ForwardCheckStructure to also behave this way is just a matter of elegance. This has no performance impact right now. It's intended to alleviate some of the regressions seen in the early implementation of https://bugs.webkit.org/show_bug.cgi?id=98606. * bytecode/ArrayProfile.cpp: (JSC::ArrayProfile::computeUpdatedPrediction): * bytecode/ArrayProfile.h: (JSC): (JSC::ArrayProfile::ArrayProfile): (ArrayProfile): (JSC::ArrayProfile::usesOriginalArrayStructures): * bytecode/CodeBlock.cpp: (JSC::CodeBlock::updateAllPredictionsAndCountLiveness): * dfg/DFGAbstractState.cpp: (JSC::DFG::AbstractState::execute): * dfg/DFGArrayMode.cpp: (JSC::DFG::ArrayMode::fromObserved): (JSC::DFG::ArrayMode::alreadyChecked): (JSC::DFG::arrayClassToString): * dfg/DFGArrayMode.h: (JSC::DFG::ArrayMode::withProfile): (JSC::DFG::ArrayMode::isJSArray): (ArrayMode): (JSC::DFG::ArrayMode::isJSArrayWithOriginalStructure): (JSC::DFG::ArrayMode::supportsLength): (JSC::DFG::ArrayMode::arrayModesWithIndexingShape): * dfg/DFGByteCodeParser.cpp: (JSC::DFG::ByteCodeParser::getArrayMode): (JSC::DFG::ByteCodeParser::getArrayModeAndEmitChecks): (JSC::DFG::ByteCodeParser::handleGetByOffset): * dfg/DFGCSEPhase.cpp: (JSC::DFG::CSEPhase::checkStructureElimination): (JSC::DFG::CSEPhase::structureTransitionWatchpointElimination): (JSC::DFG::CSEPhase::getPropertyStorageLoadElimination): (JSC::DFG::CSEPhase::checkArrayElimination): (JSC::DFG::CSEPhase::getScopeRegistersLoadElimination): * dfg/DFGConstantFoldingPhase.cpp: (JSC::DFG::ConstantFoldingPhase::foldConstants): * dfg/DFGFixupPhase.cpp: (JSC::DFG::FixupPhase::fixupNode): (JSC::DFG::FixupPhase::checkArray): * dfg/DFGNode.h: (JSC::DFG::Node::hasStructure): (JSC::DFG::Node::hasArrayMode): (JSC::DFG::Node::arrayMode): * dfg/DFGNodeType.h: (DFG): * dfg/DFGPredictionPropagationPhase.cpp: (JSC::DFG::PredictionPropagationPhase::propagate): * dfg/DFGSpeculativeJIT.cpp: (JSC::DFG::SpeculativeJIT::jumpSlowForUnwantedArrayMode): (JSC::DFG::SpeculativeJIT::arrayify): * dfg/DFGSpeculativeJIT.h: (SpeculativeJIT): * dfg/DFGSpeculativeJIT32_64.cpp: (JSC::DFG::SpeculativeJIT::compile): * dfg/DFGSpeculativeJIT64.cpp: (JSC::DFG::SpeculativeJIT::compile): * runtime/JSGlobalObject.h: (JSC::JSGlobalObject::isOriginalArrayStructure): * runtime/Structure.cpp: (JSC::Structure::nonPropertyTransition): git-svn-id: http://svn.webkit.org/repository/webkit/trunk@132759 268f45cc-cd09-0410-ab3c-d52691b4dbfc
99f3762d