DFG should be able to emit effectful structure checks
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
The shadow element is not reprojected to a nested ShadowRoot.
https://bugs.webkit.org/show_bug.cgi?id=99228

Reviewed by Dimitri Glazkov.

Source/WebCore:

We support shadow reprojection; elements distributed to <shadow> element can be reprojected to <content> now.

First, we have a distribution vector for each InsertionPoint, even if InsertionPoint is a shadow insertion point.
And we update a node-distribution map. Basically We're creating a map from node to InsertionPoint in ElementShadow.
If a node can be distributed to several InsertionPoint (e.g. in case reprojection happens),
the InsertionPoint in older ShadowDOM is chosen.

We also fix ComposedShadowTreeWalker to consider shadow reprojection.

Tests: fast/dom/shadow/composed-shadow-tree-walker-shadow-reprojection.html
       fast/dom/shadow/shadow-reprojection-click.html
       fast/dom/shadow/shadow-reprojection-dynamic.html
       fast/dom/shadow/shadow-reprojection-fallback.html
       fast/dom/shadow/shadow-reprojection.html
       fast/dom/shadow/shadow-reprojection2.html

* css/StyleResolver.cpp:
(WebCore::shouldResetStyleInheritance): Now context.insertionPoint() returns the final insertion point where
a node is distributed. So we don't have to trace shadow insertion point anymore here.
(WebCore::StyleResolver::styleForElement): Since a direct child of ShadowRoot can be distributed now. In that case,
we don't have any parentElement. The parent node is a ShadowRoot in that case.
* dom/ComposedShadowTreeWalker.cpp:
(WebCore::nodeCanBeDistributed): If a node can be distributed, returns true.
(WebCore):
(WebCore::resolveReprojection): Resolves content-reprojection and shadow-reprojection both.
(WebCore::ComposedShadowTreeWalker::traverseSiblingOrBackToInsertionPoint):
(WebCore::ComposedShadowTreeWalker::traverseParent):
(WebCore::ComposedShadowTreeWalker::traverseParentBackToYoungerShadowRootOrHost): A case ShadowRoot is assigned
to some InsertionPoint should be handled with in traverseSiblingOrBackToInsertionPoint. So we remove it.
(WebCore::AncestorChainWalker::parent): Now we have a case that a direct child of ShadowRoot can be distributed.
In that case, we should not update m_distributedNode.
* dom/ElementShadow.cpp:
(WebCore::ElementShadow::insertionPointFor): Since we have a distribution vector for each InsertionPoint,
we don't have a special case that a ShadowRoot is assigned to some InsertionPoint. Actually the existing code
is not correct now due to shadow reprojection.
* html/shadow/ContentDistributor.cpp:
(WebCore::ContentDistributor::populate): Populate a POOL. If a node is InsertionPoint, we fill it with the
distributed nodes.
(WebCore):
(WebCore::ContentDistributor::distribute): Since we want to make a distribution vector for each InsertionPoint,
we have to resolve a shadow InsertionPoint
(WebCore::ContentDistributor::distributeNodeChildrenTo):
* html/shadow/ContentDistributor.h:
(ContentDistributor):
* html/shadow/HTMLShadowElement.h:
(WebCore::toHTMLShadowElement):
(WebCore):
* html/shadow/InsertionPoint.h:
(WebCore::parentNodeForDistribution):
(WebCore::parentElementForDistribution):
(WebCore):

LayoutTests:

* fast/dom/shadow/composed-shadow-tree-walker-shadow-reprojection-expected.txt: Added.
* fast/dom/shadow/composed-shadow-tree-walker-shadow-reprojection.html: Added. A walker test case for elements distributed
to shadow element are reprojected.
* fast/dom/shadow/composed-shadow-tree-walker.html:
* fast/dom/shadow/content-reprojection-complex.html:
* fast/dom/shadow/content-reprojection-fallback-expected.html:
* fast/dom/shadow/content-reprojection-fallback-reprojection-expected.html:
* fast/dom/shadow/shadow-reprojection-click-expected.txt: Added.
* fast/dom/shadow/shadow-reprojection-click.html: Added. Does some interactive with a shadow-reprojected node.
* fast/dom/shadow/shadow-reprojection-dynamic-expected.html: Added.
* fast/dom/shadow/shadow-reprojection-dynamic.html: Added. Adds dynamically elements shadow-reprojected.
* fast/dom/shadow/shadow-reprojection-expected.html: Added.
* fast/dom/shadow/shadow-reprojection-fallback-expected.html: Added.
* fast/dom/shadow/shadow-reprojection-fallback.html: Added. A test case for fallback elements of a shadow element
are reprojected.
* fast/dom/shadow/shadow-reprojection-prohibited-expected.html: Removed.
* fast/dom/shadow/shadow-reprojection-prohibited.html: Removed.
* fast/dom/shadow/shadow-reprojection.html: Added. A basic test case.
* fast/dom/shadow/shadow-reprojection2-expected.html: Added.
* fast/dom/shadow/shadow-reprojection2.html: Added. Another basic test case.


git-svn-id: http://svn.webkit.org/repository/webkit/trunk@132760 268f45cc-cd09-0410-ab3c-d52691b4dbfc