Changeset 196031 in webkit


Ignore:
Timestamp:
Feb 2, 2016 2:34:45 PM (8 years ago)
Author:
Antti Koivisto
Message:

Factor style sharing code out of StyleResolver
https://bugs.webkit.org/show_bug.cgi?id=153768

Reviewed by Darin Adler.

Move the code to a new class, Style::SharingResolver.

When resolving document style we query the sharing resolver first before using the regular style resolver.
Other paths that call style resolver were mostly already disabling it with DisallowStyleSharing flag.

  • WebCore.xcodeproj/project.pbxproj:
  • css/ElementRuleCollector.cpp:

(WebCore::MatchRequest::MatchRequest):
(WebCore::ElementRuleCollector::matchAllRules):
(WebCore::ElementRuleCollector::hasAnyMatchingRules):

More const.

  • css/ElementRuleCollector.h:

(WebCore::ElementRuleCollector::setRegionForStyling):
(WebCore::ElementRuleCollector::setMedium):

  • css/MediaQueryMatcher.cpp:

(WebCore::MediaQueryMatcher::prepareEvaluator):

  • css/StyleMedia.cpp:

(WebCore::StyleMedia::matchMedium):

  • css/StyleResolver.cpp:

(WebCore::StyleResolver::State::cacheBorderAndBackground):
(WebCore::StyleResolver::StyleResolver):
(WebCore::StyleResolver::sweepMatchedPropertiesCache):
(WebCore::StyleResolver::State::State):
(WebCore::StyleResolver::State::setStyle):
(WebCore::isAtShadowBoundary):
(WebCore::StyleResolver::styleForElement):
(WebCore::StyleResolver::classNamesAffectedByRules): Deleted.
(WebCore::parentElementPreventsSharing): Deleted.
(WebCore::StyleResolver::locateCousinList): Deleted.
(WebCore::StyleResolver::styleSharingCandidateMatchesRuleSet): Deleted.
(WebCore::StyleResolver::canShareStyleWithControl): Deleted.
(WebCore::elementHasDirectionAuto): Deleted.
(WebCore::StyleResolver::sharingCandidateHasIdenticalStyleAffectingAttributes): Deleted.
(WebCore::StyleResolver::canShareStyleWithElement): Deleted.
(WebCore::StyleResolver::findSiblingForStyleSharing): Deleted.
(WebCore::StyleResolver::locateSharedStyle): Deleted.

Style sharing code moves to SharingResolver.

  • css/StyleResolver.h:

(WebCore::StyleResolver::mediaQueryEvaluator):
(WebCore::StyleResolver::State::regionForStyling):
(WebCore::StyleResolver::State::elementLinkState):
(WebCore::StyleResolver::State::setApplyPropertyToRegularStyle):
(WebCore::StyleResolver::State::setApplyPropertyToVisitedLinkStyle):
(WebCore::StyleResolver::state):
(WebCore::StyleResolver::setTextOrientation):
(WebCore::StyleResolver::State::setElementAffectedByClassRules): Deleted.
(WebCore::StyleResolver::State::elementAffectedByClassRules): Deleted.
(WebCore::StyleResolver::styleNotYetAvailable): Deleted.

Placeholder code moves to TreeResolver.

  • dom/VisitedLinkState.cpp:

(WebCore::linkAttribute):
(WebCore::VisitedLinkState::invalidateStyleForAllLinks):
(WebCore::linkHashForElement):
(WebCore::VisitedLinkState::invalidateStyleForLink):
(WebCore::VisitedLinkState::determineLinkStateSlowCase):

  • dom/VisitedLinkState.h:

(WebCore::VisitedLinkState::determineLinkState):

  • html/HTMLFormControlElement.h:
  • rendering/RenderElement.cpp:

(WebCore::RenderElement::getUncachedPseudoStyle):

  • rendering/RenderNamedFlowFragment.cpp:

(WebCore::RenderNamedFlowFragment::computeStyleInRegion):

  • rendering/style/RenderStyle.cpp:

(WebCore::RenderStyle::isStyleAvailable):
(WebCore::RenderStyle::hasUniquePseudoStyle):

  • style/StyleSharingResolver.cpp: Added.

(WebCore::Style::SharingResolver::SharingResolver):
(WebCore::Style::parentElementPreventsSharing):
(WebCore::Style::elementHasDirectionAuto):
(WebCore::Style::SharingResolver::searchSimilar):
(WebCore::Style::SharingResolver::findSibling):
(WebCore::Style::SharingResolver::locateCousinList):
(WebCore::Style::canShareStyleWithControl):
(WebCore::Style::SharingResolver::canShareStyleWithElement):
(WebCore::Style::SharingResolver::styleSharingCandidateMatchesRuleSet):
(WebCore::Style::SharingResolver::sharingCandidateHasIdenticalStyleAffectingAttributes):
(WebCore::Style::SharingResolver::classNamesAffectedByRules):

  • style/StyleSharingResolver.h: Added.
  • style/StyleTreeResolver.cpp:

(WebCore::Style::ensurePlaceholderStyle):
(WebCore::Style::TreeResolver::TreeResolver):
(WebCore::Style::TreeResolver::styleForElement):

Try to use SharingResolver first.
Also move placeholder style handling here, it is only relevant when resolving document style.

(WebCore::Style::postResolutionCallbacksAreSuspended):
(WebCore::Style::isPlaceholderStyle):

  • style/StyleTreeResolver.h:
  • svg/SVGElement.cpp:

(WebCore::SVGElement::customStyleForRenderer):

  • svg/SVGElementRareData.h:

(WebCore::SVGElementRareData::overrideComputedStyle):

Location:
trunk/Source/WebCore
Files:
2 added
20 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/CMakeLists.txt

    r195999 r196031  
    26402640    style/StyleFontSizeFunctions.cpp
    26412641    style/StyleResolveForDocument.cpp
     2642    style/StyleSharingResolver.cpp
    26422643    style/StyleTreeResolver.cpp
    26432644
  • trunk/Source/WebCore/ChangeLog

    r196028 r196031  
     12016-02-02  Antti Koivisto  <antti@apple.com>
     2
     3        Factor style sharing code out of StyleResolver
     4        https://bugs.webkit.org/show_bug.cgi?id=153768
     5
     6        Reviewed by Darin Adler.
     7
     8        Move the code to a new class, Style::SharingResolver.
     9
     10        When resolving document style we query the sharing resolver first before using the regular style resolver.
     11        Other paths that call style resolver were mostly already disabling it with DisallowStyleSharing flag.
     12
     13        * WebCore.xcodeproj/project.pbxproj:
     14        * css/ElementRuleCollector.cpp:
     15        (WebCore::MatchRequest::MatchRequest):
     16        (WebCore::ElementRuleCollector::matchAllRules):
     17        (WebCore::ElementRuleCollector::hasAnyMatchingRules):
     18
     19            More const.
     20
     21        * css/ElementRuleCollector.h:
     22        (WebCore::ElementRuleCollector::setRegionForStyling):
     23        (WebCore::ElementRuleCollector::setMedium):
     24        * css/MediaQueryMatcher.cpp:
     25        (WebCore::MediaQueryMatcher::prepareEvaluator):
     26        * css/StyleMedia.cpp:
     27        (WebCore::StyleMedia::matchMedium):
     28        * css/StyleResolver.cpp:
     29        (WebCore::StyleResolver::State::cacheBorderAndBackground):
     30        (WebCore::StyleResolver::StyleResolver):
     31        (WebCore::StyleResolver::sweepMatchedPropertiesCache):
     32        (WebCore::StyleResolver::State::State):
     33        (WebCore::StyleResolver::State::setStyle):
     34        (WebCore::isAtShadowBoundary):
     35        (WebCore::StyleResolver::styleForElement):
     36        (WebCore::StyleResolver::classNamesAffectedByRules): Deleted.
     37        (WebCore::parentElementPreventsSharing): Deleted.
     38        (WebCore::StyleResolver::locateCousinList): Deleted.
     39        (WebCore::StyleResolver::styleSharingCandidateMatchesRuleSet): Deleted.
     40        (WebCore::StyleResolver::canShareStyleWithControl): Deleted.
     41        (WebCore::elementHasDirectionAuto): Deleted.
     42        (WebCore::StyleResolver::sharingCandidateHasIdenticalStyleAffectingAttributes): Deleted.
     43        (WebCore::StyleResolver::canShareStyleWithElement): Deleted.
     44        (WebCore::StyleResolver::findSiblingForStyleSharing): Deleted.
     45        (WebCore::StyleResolver::locateSharedStyle): Deleted.
     46
     47            Style sharing code moves to SharingResolver.
     48
     49        * css/StyleResolver.h:
     50        (WebCore::StyleResolver::mediaQueryEvaluator):
     51        (WebCore::StyleResolver::State::regionForStyling):
     52        (WebCore::StyleResolver::State::elementLinkState):
     53        (WebCore::StyleResolver::State::setApplyPropertyToRegularStyle):
     54        (WebCore::StyleResolver::State::setApplyPropertyToVisitedLinkStyle):
     55        (WebCore::StyleResolver::state):
     56        (WebCore::StyleResolver::setTextOrientation):
     57        (WebCore::StyleResolver::State::setElementAffectedByClassRules): Deleted.
     58        (WebCore::StyleResolver::State::elementAffectedByClassRules): Deleted.
     59        (WebCore::StyleResolver::styleNotYetAvailable): Deleted.
     60
     61            Placeholder code moves to TreeResolver.
     62
     63        * dom/VisitedLinkState.cpp:
     64        (WebCore::linkAttribute):
     65        (WebCore::VisitedLinkState::invalidateStyleForAllLinks):
     66        (WebCore::linkHashForElement):
     67        (WebCore::VisitedLinkState::invalidateStyleForLink):
     68        (WebCore::VisitedLinkState::determineLinkStateSlowCase):
     69        * dom/VisitedLinkState.h:
     70        (WebCore::VisitedLinkState::determineLinkState):
     71        * html/HTMLFormControlElement.h:
     72        * rendering/RenderElement.cpp:
     73        (WebCore::RenderElement::getUncachedPseudoStyle):
     74        * rendering/RenderNamedFlowFragment.cpp:
     75        (WebCore::RenderNamedFlowFragment::computeStyleInRegion):
     76        * rendering/style/RenderStyle.cpp:
     77        (WebCore::RenderStyle::isStyleAvailable):
     78        (WebCore::RenderStyle::hasUniquePseudoStyle):
     79        * style/StyleSharingResolver.cpp: Added.
     80        (WebCore::Style::SharingResolver::SharingResolver):
     81        (WebCore::Style::parentElementPreventsSharing):
     82        (WebCore::Style::elementHasDirectionAuto):
     83        (WebCore::Style::SharingResolver::searchSimilar):
     84        (WebCore::Style::SharingResolver::findSibling):
     85        (WebCore::Style::SharingResolver::locateCousinList):
     86        (WebCore::Style::canShareStyleWithControl):
     87        (WebCore::Style::SharingResolver::canShareStyleWithElement):
     88        (WebCore::Style::SharingResolver::styleSharingCandidateMatchesRuleSet):
     89        (WebCore::Style::SharingResolver::sharingCandidateHasIdenticalStyleAffectingAttributes):
     90        (WebCore::Style::SharingResolver::classNamesAffectedByRules):
     91        * style/StyleSharingResolver.h: Added.
     92        * style/StyleTreeResolver.cpp:
     93        (WebCore::Style::ensurePlaceholderStyle):
     94        (WebCore::Style::TreeResolver::TreeResolver):
     95        (WebCore::Style::TreeResolver::styleForElement):
     96
     97            Try to use SharingResolver first.
     98            Also move placeholder style handling here, it is only relevant when resolving document style.
     99
     100        (WebCore::Style::postResolutionCallbacksAreSuspended):
     101        (WebCore::Style::isPlaceholderStyle):
     102        * style/StyleTreeResolver.h:
     103        * svg/SVGElement.cpp:
     104        (WebCore::SVGElement::customStyleForRenderer):
     105        * svg/SVGElementRareData.h:
     106        (WebCore::SVGElementRareData::overrideComputedStyle):
     107
    11082016-02-02  Tim Horton  <timothy_horton@apple.com>
    2109
  • trunk/Source/WebCore/WebCore.vcxproj/WebCore.vcxproj

    r195948 r196031  
    1924619246    <ClCompile Include="..\style\StyleFontSizeFunctions.cpp" />
    1924719247    <ClCompile Include="..\style\StyleResolveForDocument.cpp" />
     19248    <ClCompile Include="..\style\StyleSharingResolver.cpp" />
    1924819249    <ClCompile Include="..\style\StyleTreeResolver.cpp" />
    1924919250    <ClCompile Include="..\bridge\jsc\BridgeJSC.cpp" />
     
    2281322814    <ClInclude Include="..\style\StyleFontSizeFunctions.h" />
    2281422815    <ClInclude Include="..\style\StyleResolveForDocument.h" />
     22816    <ClInclude Include="..\style\StyleSharingResolver.h" />
    2281522817    <ClInclude Include="..\style\StyleTreeResolver.h" />
    2281622818    <ClInclude Include="..\bridge\Bridge.h" />
  • trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj

    r195999 r196031  
    65896589                E4778B7F115A581A00B5D372 /* JSCustomEvent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E4778B7D115A581A00B5D372 /* JSCustomEvent.cpp */; };
    65906590                E4778B80115A581A00B5D372 /* JSCustomEvent.h in Headers */ = {isa = PBXBuildFile; fileRef = E4778B7E115A581A00B5D372 /* JSCustomEvent.h */; };
     6591                E47A3AC31C5EABBE00CCBFA7 /* StyleSharingResolver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E47A3AC21C5EABBE00CCBFA7 /* StyleSharingResolver.cpp */; };
     6592                E47A3AC61C5EAC9D00CCBFA7 /* StyleSharingResolver.h in Headers */ = {isa = PBXBuildFile; fileRef = E47A3AC41C5EAC7900CCBFA7 /* StyleSharingResolver.h */; };
    65916593                E47B4BE80E71241600038854 /* CachedResourceHandle.h in Headers */ = {isa = PBXBuildFile; fileRef = E47B4BE60E71241600038854 /* CachedResourceHandle.h */; settings = {ATTRIBUTES = (Private, ); }; };
    65926594                E47B4BE90E71241600038854 /* CachedResourceHandle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E47B4BE70E71241600038854 /* CachedResourceHandle.cpp */; };
     
    1455414556                E4778B7D115A581A00B5D372 /* JSCustomEvent.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSCustomEvent.cpp; sourceTree = "<group>"; };
    1455514557                E4778B7E115A581A00B5D372 /* JSCustomEvent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSCustomEvent.h; sourceTree = "<group>"; };
     14558                E47A3AC21C5EABBE00CCBFA7 /* StyleSharingResolver.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = StyleSharingResolver.cpp; sourceTree = "<group>"; };
     14559                E47A3AC41C5EAC7900CCBFA7 /* StyleSharingResolver.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StyleSharingResolver.h; sourceTree = "<group>"; };
    1455614560                E47A97CE163059FC005DCD99 /* StyleInvalidationAnalysis.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = StyleInvalidationAnalysis.cpp; sourceTree = "<group>"; };
    1455714561                E47A97CF163059FC005DCD99 /* StyleInvalidationAnalysis.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StyleInvalidationAnalysis.h; sourceTree = "<group>"; };
     
    2334323347                                E4DEAA1517A93DC3000E0430 /* StyleTreeResolver.cpp */,
    2334423348                                E4DEAA1617A93DC3000E0430 /* StyleTreeResolver.h */,
     23349                                E47A3AC21C5EABBE00CCBFA7 /* StyleSharingResolver.cpp */,
     23350                                E47A3AC41C5EAC7900CCBFA7 /* StyleSharingResolver.h */,
    2334523351                        );
    2334623352                        path = style;
     
    2689726903                                439046E012DA25E17BAF80A2 /* MathMLOperatorDictionary.h in Headers */,
    2689826904                                FA654A6C1108ABED002615E0 /* MathMLTextElement.h in Headers */,
     26905                                E47A3AC61C5EAC9D00CCBFA7 /* StyleSharingResolver.h in Headers */,
    2689926906                                49D5DC2C0F423A73008F20FD /* Matrix3DTransformOperation.h in Headers */,
    2690026907                                49E911C70EF86D47009D0CAF /* MatrixTransformOperation.h in Headers */,
     
    3009230099                                448A29C00A46D9CB0030759F /* JSHTMLOptionsCollection.cpp in Sources */,
    3009330100                                448AD27C0A48137A0023D179 /* JSHTMLOptionsCollectionCustom.cpp in Sources */,
     30101                                E47A3AC31C5EABBE00CCBFA7 /* StyleSharingResolver.cpp in Sources */,
    3009430102                                4AD0173C127E82860015035F /* JSHTMLOutputElement.cpp in Sources */,
    3009530103                                1AE2ABA60A1CE90500B42B25 /* JSHTMLParagraphElement.cpp in Sources */,
  • trunk/Source/WebCore/css/ElementRuleCollector.cpp

    r195311 r196031  
    6969class MatchRequest {
    7070public:
    71     MatchRequest(RuleSet* ruleSet, bool includeEmptyRules = false)
     71    MatchRequest(const RuleSet* ruleSet, bool includeEmptyRules = false)
    7272        : ruleSet(ruleSet)
    7373        , includeEmptyRules(includeEmptyRules)
     
    530530}
    531531
    532 bool ElementRuleCollector::hasAnyMatchingRules(RuleSet* ruleSet)
     532bool ElementRuleCollector::hasAnyMatchingRules(const RuleSet* ruleSet)
    533533{
    534534    clearMatchedRules();
  • trunk/Source/WebCore/css/ElementRuleCollector.h

    r195293 r196031  
    5959    void setMedium(const MediaQueryEvaluator* medium) { m_isPrintStyle = medium->mediaTypeMatchSpecific("print"); }
    6060
    61     bool hasAnyMatchingRules(RuleSet*);
     61    bool hasAnyMatchingRules(const RuleSet*);
    6262
    6363    StyleResolver::MatchResult& matchedResult();
  • trunk/Source/WebCore/css/MediaQueryMatcher.cpp

    r195465 r196031  
    8686        return nullptr;
    8787
    88     RefPtr<RenderStyle> rootStyle = m_document->ensureStyleResolver().styleForElement(*documentElement, m_document->renderStyle(), DisallowStyleSharing, MatchOnlyUserAgentRules);
     88    RefPtr<RenderStyle> rootStyle = m_document->ensureStyleResolver().styleForElement(*documentElement, m_document->renderStyle(), MatchOnlyUserAgentRules);
    8989
    9090    return std::make_unique<MediaQueryEvaluator>(mediaType(), m_document->frame(), rootStyle.get());
  • trunk/Source/WebCore/css/StyleMedia.cpp

    r195465 r196031  
    6262        return false;
    6363
    64     RefPtr<RenderStyle> rootStyle = document->ensureStyleResolver().styleForElement(*documentElement, document->renderStyle(), DisallowStyleSharing, MatchOnlyUserAgentRules);
     64    RefPtr<RenderStyle> rootStyle = document->ensureStyleResolver().styleForElement(*documentElement, document->renderStyle(), MatchOnlyUserAgentRules);
    6565
    6666    RefPtr<MediaQuerySet> media = MediaQuerySet::create();
  • trunk/Source/WebCore/css/StyleResolver.cpp

    r195560 r196031  
    177177static void extractDirectionAndWritingMode(const RenderStyle&, const StyleResolver::MatchResult&, TextDirection&, WritingMode&);
    178178
    179 RenderStyle* StyleResolver::s_styleNotYetAvailable;
    180 
    181179inline void StyleResolver::State::cacheBorderAndBackground()
    182180{
     
    265263
    266264    if (root)
    267         m_rootDefaultStyle = styleForElement(*root, m_document.renderStyle(), DisallowStyleSharing, MatchOnlyUserAgentRules);
     265        m_rootDefaultStyle = styleForElement(*root, m_document.renderStyle(), MatchOnlyUserAgentRules);
    268266
    269267    if (m_rootDefaultStyle && view)
     
    333331}
    334332
    335 bool StyleResolver::classNamesAffectedByRules(const SpaceSplitString& classNames) const
    336 {
    337     for (unsigned i = 0; i < classNames.size(); ++i) {
    338         if (m_ruleSets.features().classesInRules.contains(classNames[i].impl()))
    339             return true;
    340     }
    341     return false;
    342 }
    343 
    344333StyleResolver::State::State(Element& element, RenderStyle* parentStyle, const RenderRegion* regionForStyling, const SelectorFilter* selectorFilter)
    345334    : m_element(&element)
     
    370359    updateConversionData();
    371360}
    372 
    373 static const unsigned cStyleSearchThreshold = 10;
    374 static const unsigned cStyleSearchLevelThreshold = 10;
    375 
    376 static inline bool parentElementPreventsSharing(const Element* parentElement)
    377 {
    378     if (!parentElement)
    379         return false;
    380     return parentElement->hasFlagsSetDuringStylingOfChildren();
    381 }
    382 
    383 Node* StyleResolver::locateCousinList(Element* parent, unsigned& visitedNodeCount) const
    384 {
    385     if (visitedNodeCount >= cStyleSearchThreshold * cStyleSearchLevelThreshold)
    386         return nullptr;
    387     if (!is<StyledElement>(parent))
    388         return nullptr;
    389     StyledElement* styledParent = downcast<StyledElement>(parent);
    390     if (styledParent->inlineStyle())
    391         return nullptr;
    392     if (is<SVGElement>(*styledParent) && downcast<SVGElement>(*styledParent).animatedSMILStyleProperties())
    393         return nullptr;
    394     if (styledParent->hasID() && m_ruleSets.features().idsInRules.contains(styledParent->idForStyleResolution().impl()))
    395         return nullptr;
    396 
    397     RenderStyle* parentStyle = styledParent->renderStyle();
    398     unsigned subcount = 0;
    399     Node* thisCousin = styledParent;
    400     Node* currentNode = styledParent->previousSibling();
    401 
    402     // Reserve the tries for this level. This effectively makes sure that the algorithm
    403     // will never go deeper than cStyleSearchLevelThreshold levels into recursion.
    404     visitedNodeCount += cStyleSearchThreshold;
    405     while (thisCousin) {
    406         while (currentNode) {
    407             ++subcount;
    408             if (currentNode->renderStyle() == parentStyle && currentNode->lastChild()
    409                 && is<Element>(*currentNode) && !parentElementPreventsSharing(downcast<Element>(currentNode))
    410                 ) {
    411                 // Adjust for unused reserved tries.
    412                 visitedNodeCount -= cStyleSearchThreshold - subcount;
    413                 return currentNode->lastChild();
    414             }
    415             if (subcount >= cStyleSearchThreshold)
    416                 return nullptr;
    417             currentNode = currentNode->previousSibling();
    418         }
    419         currentNode = locateCousinList(thisCousin->parentElement(), visitedNodeCount);
    420         thisCousin = currentNode;
    421     }
    422 
    423     return nullptr;
    424 }
    425 
    426 bool StyleResolver::styleSharingCandidateMatchesRuleSet(RuleSet* ruleSet)
    427 {
    428     if (!ruleSet)
    429         return false;
    430 
    431     ElementRuleCollector collector(*m_state.element(), m_state.style(), m_ruleSets, m_state.selectorFilter());
    432     return collector.hasAnyMatchingRules(ruleSet);
    433 }
    434 
    435 bool StyleResolver::canShareStyleWithControl(StyledElement& element) const
    436 {
    437     const State& state = m_state;
    438     if (!is<HTMLInputElement>(element) || !is<HTMLInputElement>(*state.element()))
    439         return false;
    440 
    441     auto& thisInputElement = downcast<HTMLInputElement>(element);
    442     auto& otherInputElement = downcast<HTMLInputElement>(*state.element());
    443 
    444     if (thisInputElement.isAutoFilled() != otherInputElement.isAutoFilled())
    445         return false;
    446     if (thisInputElement.shouldAppearChecked() != otherInputElement.shouldAppearChecked())
    447         return false;
    448     if (thisInputElement.shouldAppearIndeterminate() != otherInputElement.shouldAppearIndeterminate())
    449         return false;
    450     if (thisInputElement.isRequired() != otherInputElement.isRequired())
    451         return false;
    452 
    453     if (element.isDisabledFormControl() != state.element()->isDisabledFormControl())
    454         return false;
    455 
    456     if (element.isDefaultButtonForForm() != state.element()->isDefaultButtonForForm())
    457         return false;
    458 
    459     if (element.isInRange() != state.element()->isInRange())
    460         return false;
    461 
    462     if (element.isOutOfRange() != state.element()->isOutOfRange())
    463         return false;
    464 
    465     return true;
    466 }
    467 
    468 static inline bool elementHasDirectionAuto(Element& element)
    469 {
    470     // FIXME: This line is surprisingly hot, we may wish to inline hasDirectionAuto into StyleResolver.
    471     return is<HTMLElement>(element) && downcast<HTMLElement>(element).hasDirectionAuto();
    472 }
    473 
    474 bool StyleResolver::sharingCandidateHasIdenticalStyleAffectingAttributes(StyledElement& sharingCandidate) const
    475 {
    476     const State& state = m_state;
    477     if (state.element()->elementData() == sharingCandidate.elementData())
    478         return true;
    479     if (state.element()->fastGetAttribute(XMLNames::langAttr) != sharingCandidate.fastGetAttribute(XMLNames::langAttr))
    480         return false;
    481     if (state.element()->fastGetAttribute(langAttr) != sharingCandidate.fastGetAttribute(langAttr))
    482         return false;
    483 
    484     if (!state.elementAffectedByClassRules()) {
    485         if (sharingCandidate.hasClass() && classNamesAffectedByRules(sharingCandidate.classNames()))
    486             return false;
    487     } else if (sharingCandidate.hasClass()) {
    488         // SVG elements require a (slow!) getAttribute comparision because "class" is an animatable attribute for SVG.
    489         if (state.element()->isSVGElement()) {
    490             if (state.element()->getAttribute(classAttr) != sharingCandidate.getAttribute(classAttr))
    491                 return false;
    492         } else {
    493             if (state.element()->classNames() != sharingCandidate.classNames())
    494                 return false;
    495         }
    496     } else
    497         return false;
    498 
    499     if (downcast<StyledElement>(*state.element()).presentationAttributeStyle() != sharingCandidate.presentationAttributeStyle())
    500         return false;
    501 
    502     if (state.element()->hasTagName(progressTag)) {
    503         if (state.element()->shouldAppearIndeterminate() != sharingCandidate.shouldAppearIndeterminate())
    504             return false;
    505     }
    506 
    507     return true;
    508 }
    509 
    510 bool StyleResolver::canShareStyleWithElement(StyledElement& element) const
    511 {
    512     auto* style = element.renderStyle();
    513     const State& state = m_state;
    514 
    515     if (!style)
    516         return false;
    517     if (style->unique())
    518         return false;
    519     if (style->hasUniquePseudoStyle())
    520         return false;
    521     if (element.tagQName() != state.element()->tagQName())
    522         return false;
    523     if (element.inlineStyle())
    524         return false;
    525     if (element.needsStyleRecalc())
    526         return false;
    527     if (element.isSVGElement() && downcast<SVGElement>(element).animatedSMILStyleProperties())
    528         return false;
    529     if (element.isLink() != state.element()->isLink())
    530         return false;
    531     if (element.hovered() != state.element()->hovered())
    532         return false;
    533     if (element.active() != state.element()->active())
    534         return false;
    535     if (element.focused() != state.element()->focused())
    536         return false;
    537     if (element.shadowPseudoId() != state.element()->shadowPseudoId())
    538         return false;
    539     if (&element == element.document().cssTarget())
    540         return false;
    541     if (!sharingCandidateHasIdenticalStyleAffectingAttributes(element))
    542         return false;
    543     if (element.additionalPresentationAttributeStyle() != downcast<StyledElement>(*state.element()).additionalPresentationAttributeStyle())
    544         return false;
    545     if (element.affectsNextSiblingElementStyle() || element.styleIsAffectedByPreviousSibling())
    546         return false;
    547 
    548     if (element.hasID() && m_ruleSets.features().idsInRules.contains(element.idForStyleResolution().impl()))
    549         return false;
    550 
    551     bool isControl = is<HTMLFormControlElement>(element);
    552 
    553     if (isControl != is<HTMLFormControlElement>(*state.element()))
    554         return false;
    555 
    556     if (isControl && !canShareStyleWithControl(element))
    557         return false;
    558 
    559     if (style->transitions() || style->animations())
    560         return false;
    561 
    562     // Turn off style sharing for elements that can gain layers for reasons outside of the style system.
    563     // See comments in RenderObject::setStyle().
    564     if (element.hasTagName(iframeTag) || element.hasTagName(frameTag) || element.hasTagName(embedTag) || element.hasTagName(objectTag) || element.hasTagName(appletTag) || element.hasTagName(canvasTag))
    565         return false;
    566 
    567     if (elementHasDirectionAuto(element))
    568         return false;
    569 
    570     if (element.isLink() && state.elementLinkState() != style->insideLink())
    571         return false;
    572 
    573     if (element.elementData() != state.element()->elementData()) {
    574         if (element.fastGetAttribute(readonlyAttr) != state.element()->fastGetAttribute(readonlyAttr))
    575             return false;
    576         if (element.isSVGElement()) {
    577             if (element.getAttribute(typeAttr) != state.element()->getAttribute(typeAttr))
    578                 return false;
    579         } else {
    580             if (element.fastGetAttribute(typeAttr) != state.element()->fastGetAttribute(typeAttr))
    581                 return false;
    582         }
    583     }
    584 
    585     if (element.matchesValidPseudoClass() != state.element()->matchesValidPseudoClass())
    586         return false;
    587 
    588     if (element.matchesInvalidPseudoClass() != state.element()->matchesValidPseudoClass())
    589         return false;
    590 
    591 #if ENABLE(VIDEO_TRACK)
    592     // Deny sharing styles between WebVTT and non-WebVTT nodes.
    593     if (is<WebVTTElement>(*state.element()))
    594         return false;
    595 #endif
    596 
    597 #if ENABLE(FULLSCREEN_API)
    598     if (&element == element.document().webkitCurrentFullScreenElement() || state.element() == state.document().webkitCurrentFullScreenElement())
    599         return false;
    600 #endif
    601     return true;
    602 }
    603 
    604 inline StyledElement* StyleResolver::findSiblingForStyleSharing(Node* node, unsigned& count) const
    605 {
    606     for (; node; node = node->previousSibling()) {
    607         if (!is<StyledElement>(*node))
    608             continue;
    609         if (canShareStyleWithElement(downcast<StyledElement>(*node)))
    610             break;
    611         if (count++ == cStyleSearchThreshold)
    612             return nullptr;
    613     }
    614     return downcast<StyledElement>(node);
    615 }
    616 
    617 RenderStyle* StyleResolver::locateSharedStyle()
    618 {
    619     State& state = m_state;
    620     if (!is<StyledElement>(state.element()) || !state.parentStyle())
    621         return nullptr;
    622     auto& styledElement = downcast<StyledElement>(*state.element());
    623 
    624     // If the element has inline style it is probably unique.
    625     if (styledElement.inlineStyle())
    626         return nullptr;
    627     if (styledElement.isSVGElement() && downcast<SVGElement>(styledElement).animatedSMILStyleProperties())
    628         return nullptr;
    629     // Ids stop style sharing if they show up in the stylesheets.
    630     if (styledElement.hasID() && m_ruleSets.features().idsInRules.contains(styledElement.idForStyleResolution().impl()))
    631         return nullptr;
    632     if (parentElementPreventsSharing(styledElement.parentElement()))
    633         return nullptr;
    634     if (state.element() == state.document().cssTarget())
    635         return nullptr;
    636     if (elementHasDirectionAuto(*state.element()))
    637         return nullptr;
    638 
    639     // Cache whether state.element is affected by any known class selectors.
    640     // FIXME: This shouldn't be a member variable. The style sharing code could be factored out of StyleResolver.
    641     state.setElementAffectedByClassRules(state.element() && state.element()->hasClass() && classNamesAffectedByRules(state.element()->classNames()));
    642 
    643     // Check previous siblings and their cousins.
    644     unsigned count = 0;
    645     unsigned visitedNodeCount = 0;
    646     StyledElement* shareElement = nullptr;
    647     Node* cousinList = styledElement.previousSibling();
    648     while (cousinList) {
    649         shareElement = findSiblingForStyleSharing(cousinList, count);
    650         if (shareElement)
    651             break;
    652         cousinList = locateCousinList(cousinList->parentElement(), visitedNodeCount);
    653     }
    654 
    655     // If we have exhausted all our budget or our cousins.
    656     if (!shareElement)
    657         return nullptr;
    658 
    659     // Can't share if sibling rules apply. This is checked at the end as it should rarely fail.
    660     if (styleSharingCandidateMatchesRuleSet(m_ruleSets.sibling()))
    661         return nullptr;
    662     // Can't share if attribute rules apply.
    663     if (styleSharingCandidateMatchesRuleSet(m_ruleSets.uncommonAttribute()))
    664         return nullptr;
    665     // Tracking child index requires unique style for each node. This may get set by the sibling rule match above.
    666     if (parentElementPreventsSharing(styledElement.parentElement()))
    667         return nullptr;
    668     return shareElement->renderStyle();
    669 }
    670 
    671361static inline bool isAtShadowBoundary(const Element* element)
    672362{
     
    677367}
    678368
    679 Ref<RenderStyle> StyleResolver::styleForElement(Element& element, RenderStyle* parentStyle,
    680     StyleSharingBehavior sharingBehavior, RuleMatchingBehavior matchingBehavior, const RenderRegion* regionForStyling, const SelectorFilter* selectorFilter)
     369Ref<RenderStyle> StyleResolver::styleForElement(Element& element, RenderStyle* parentStyle, RuleMatchingBehavior matchingBehavior, const RenderRegion* regionForStyling, const SelectorFilter* selectorFilter)
    681370{
    682371    RELEASE_ASSERT(!m_inLoadPendingImages);
    683 
    684     // Once an element has a renderer, we don't try to destroy it, since otherwise the renderer
    685     // will vanish if a style recalc happens during loading.
    686     if (sharingBehavior == AllowStyleSharing && !m_document.haveStylesheetsLoaded() && !element.renderer()) {
    687         if (!s_styleNotYetAvailable) {
    688             s_styleNotYetAvailable = &RenderStyle::create().leakRef();
    689             s_styleNotYetAvailable->setDisplay(NONE);
    690             s_styleNotYetAvailable->fontCascade().update(&m_document.fontSelector());
    691         }
    692         m_document.setHasNodesWithPlaceholderStyle();
    693         return *s_styleNotYetAvailable;
    694     }
    695372
    696373    m_state = State(element, parentStyle, regionForStyling, selectorFilter);
    697374    State& state = m_state;
    698 
    699     if (sharingBehavior == AllowStyleSharing) {
    700         if (RenderStyle* sharedStyle = locateSharedStyle()) {
    701             state.clear();
    702             return *sharedStyle;
    703         }
    704     }
    705375
    706376    if (state.parentStyle()) {
  • trunk/Source/WebCore/css/StyleResolver.h

    r195465 r196031  
    9494struct ResourceLoaderOptions;
    9595
    96 enum StyleSharingBehavior {
    97     AllowStyleSharing,
    98     DisallowStyleSharing,
    99 };
    100 
    10196// MatchOnlyUserAgentRules is used in media queries, where relative units
    10297// are interpreted according to the document root element style, and styled only
     
    136131    ~StyleResolver();
    137132
    138     Ref<RenderStyle> styleForElement(Element&, RenderStyle* parentStyle, StyleSharingBehavior = AllowStyleSharing,
    139         RuleMatchingBehavior = MatchAllRules, const RenderRegion* regionForStyling = nullptr, const SelectorFilter* = nullptr);
     133    Ref<RenderStyle> styleForElement(Element&, RenderStyle* parentStyle, RuleMatchingBehavior = MatchAllRules, const RenderRegion* regionForStyling = nullptr, const SelectorFilter* = nullptr);
    140134
    141135    void keyframeStylesForAnimation(Element&, const RenderStyle*, KeyframeList&);
     
    161155
    162156private:
    163     RenderStyle* locateSharedStyle();
    164     bool styleSharingCandidateMatchesRuleSet(RuleSet*);
    165     Node* locateCousinList(Element* parent, unsigned& visitedNodeCount) const;
    166     StyledElement* findSiblingForStyleSharing(Node*, unsigned& count) const;
    167     bool canShareStyleWithElement(StyledElement&) const;
    168 
    169157    Ref<RenderStyle> styleForKeyframe(const RenderStyle*, const StyleKeyframe*, KeyframeValue&);
    170158
     
    379367        const RenderRegion* regionForStyling() const { return m_regionForStyling; }
    380368        EInsideLink elementLinkState() const { return m_elementLinkState; }
    381         void setElementAffectedByClassRules(bool isAffected) { m_elementAffectedByClassRules = isAffected; }
    382         bool elementAffectedByClassRules() const { return m_elementAffectedByClassRules; }
    383369
    384370        void setApplyPropertyToRegularStyle(bool isApply) { m_applyPropertyToRegularStyle = isApply; }
     
    436422        EInsideLink m_elementLinkState { NotInsideLink };
    437423
    438         bool m_elementAffectedByClassRules { false };
    439424        bool m_applyPropertyToRegularStyle { true };
    440425        bool m_applyPropertyToVisitedLinkStyle { false };
     
    459444
    460445    State& state() { return m_state; }
    461 
    462     static RenderStyle* styleNotYetAvailable() { return s_styleNotYetAvailable; }
    463446
    464447    PassRefPtr<StyleImage> styleImage(CSSPropertyID, CSSValue&);
     
    489472
    490473private:
    491     static RenderStyle* s_styleNotYetAvailable;
    492 
    493474    void cacheBorderAndBackground();
    494 
    495     bool canShareStyleWithControl(StyledElement&) const;
    496475
    497476    void applyProperty(CSSPropertyID, CSSValue*, SelectorChecker::LinkMatchMask = SelectorChecker::MatchDefault, const MatchResult* = nullptr);
     
    520499    // the last reference to a style declaration are garbage collected.
    521500    void sweepMatchedPropertiesCache();
    522 
    523     bool classNamesAffectedByRules(const SpaceSplitString&) const;
    524     bool sharingCandidateHasIdenticalStyleAffectingAttributes(StyledElement&) const;
    525501
    526502    unsigned m_matchedPropertiesCacheAdditionsSinceLastSweep;
  • trunk/Source/WebCore/dom/VisitedLinkState.cpp

    r173980 r196031  
    4242using namespace HTMLNames;
    4343
    44 inline static const AtomicString* linkAttribute(Element& element)
     44inline static const AtomicString* linkAttribute(const Element& element)
    4545{
    4646    if (!element.isLink())
     
    6868}
    6969
    70 inline static LinkHash linkHashForElement(Document& document, Element& element)
     70inline static LinkHash linkHashForElement(Document& document, const Element& element)
    7171{
    7272    if (is<HTMLAnchorElement>(element))
     
    8787}
    8888
    89 EInsideLink VisitedLinkState::determineLinkStateSlowCase(Element& element)
     89EInsideLink VisitedLinkState::determineLinkStateSlowCase(const Element& element)
    9090{
    9191    ASSERT(element.isLink());
  • trunk/Source/WebCore/dom/VisitedLinkState.h

    r171752 r196031  
    4646    void invalidateStyleForAllLinks();
    4747    void invalidateStyleForLink(LinkHash);
    48     EInsideLink determineLinkState(Element&);
     48    EInsideLink determineLinkState(const Element&);
    4949
    5050private:
    51     EInsideLink determineLinkStateSlowCase(Element&);
     51    EInsideLink determineLinkStateSlowCase(const Element&);
    5252
    5353    Document& m_document;
     
    5555};
    5656
    57 inline EInsideLink VisitedLinkState::determineLinkState(Element& element)
     57inline EInsideLink VisitedLinkState::determineLinkState(const Element& element)
    5858{
    5959    if (!element.isLink())
  • trunk/Source/WebCore/html/HTMLFormControlElement.h

    r194999 r196031  
    7272
    7373    virtual bool isDisabledFormControl() const override;
     74    virtual bool isDefaultButtonForForm() const override;
    7475
    7576    virtual bool isFocusable() const override;
     
    169170
    170171    virtual HTMLFormElement* virtualForm() const override;
    171     virtual bool isDefaultButtonForForm() const override;
    172172    bool isValidFormControlElement() const;
    173173
  • trunk/Source/WebCore/rendering/RenderElement.cpp

    r195465 r196031  
    15911591
    15921592    if (pseudoStyleRequest.pseudoId == FIRST_LINE_INHERITED) {
    1593         RefPtr<RenderStyle> result = styleResolver.styleForElement(*element(), parentStyle, DisallowStyleSharing);
     1593        RefPtr<RenderStyle> result = styleResolver.styleForElement(*element(), parentStyle);
    15941594        result->setStyleType(FIRST_LINE_INHERITED);
    15951595        return result.release();
  • trunk/Source/WebCore/rendering/RenderNamedFlowFragment.cpp

    r195465 r196031  
    353353
    354354    // FIXME: Region styling fails for pseudo-elements because the renderers don't have a node.
    355     RefPtr<RenderStyle> renderObjectRegionStyle = renderer.element()->styleResolver().styleForElement(*renderer.element(), &parentStyle, DisallowStyleSharing, MatchAllRules, this);
     355    RefPtr<RenderStyle> renderObjectRegionStyle = renderer.element()->styleResolver().styleForElement(*renderer.element(), &parentStyle, MatchAllRules, this);
    356356
    357357    return renderObjectRegionStyle.release();
  • trunk/Source/WebCore/rendering/style/RenderStyle.cpp

    r195928 r196031  
    4343#include "StyleScrollSnapPoints.h"
    4444#include "StyleSelfAlignmentData.h"
     45#include "StyleTreeResolver.h"
    4546#include "WillChangeData.h"
    4647#include <wtf/MathExtras.h>
     
    294295bool RenderStyle::isStyleAvailable() const
    295296{
    296     return this != StyleResolver::styleNotYetAvailable();
     297    return !Style::isPlaceholderStyle(*this);
    297298}
    298299
  • trunk/Source/WebCore/style/StyleTreeResolver.cpp

    r195465 r196031  
    9797};
    9898
     99
     100static RenderStyle* placeholderStyle;
     101
     102static void ensurePlaceholderStyle(Document& document)
     103{
     104    if (placeholderStyle)
     105        return;
     106    placeholderStyle = &RenderStyle::create().leakRef();
     107    placeholderStyle->setDisplay(NONE);
     108    placeholderStyle->fontCascade().update(&document.fontSelector());
     109}
     110
    99111TreeResolver::TreeResolver(Document& document)
    100112    : m_document(document)
    101113    , m_styleResolver(document.ensureStyleResolver())
    102 {
     114    , m_sharingResolver(document, m_styleResolver.ruleSets(), m_selectorFilter)
     115{
     116    ensurePlaceholderStyle(document);
    103117}
    104118
     
    108122    , m_shadowRoot(&shadowRoot)
    109123    , m_shadowHostTreeResolver(&shadowHostTreeResolver)
     124    , m_sharingResolver(m_document, m_styleResolver.ruleSets(), m_selectorFilter)
    110125{
    111126}
     
    124139Ref<RenderStyle> TreeResolver::styleForElement(Element& element, RenderStyle& inheritedStyle)
    125140{
     141    if (!m_document.haveStylesheetsLoaded() && !element.renderer()) {
     142        m_document.setHasNodesWithPlaceholderStyle();
     143        return *placeholderStyle;
     144    }
     145
    126146    if (element.hasCustomStyleResolveCallbacks()) {
    127147        if (RefPtr<RenderStyle> style = element.customStyleForRenderer(inheritedStyle))
    128148            return style.releaseNonNull();
    129149    }
    130     return m_styleResolver.styleForElement(element, &inheritedStyle, AllowStyleSharing, MatchAllRules, nullptr, &m_selectorFilter);
     150
     151    if (auto* sharingElement = m_sharingResolver.resolve(element))
     152        return *sharingElement->renderStyle();
     153
     154    return m_styleResolver.styleForElement(element, &inheritedStyle, MatchAllRules, nullptr, &m_selectorFilter);
    131155}
    132156
     
    949973}
    950974
    951 }
    952 }
     975bool isPlaceholderStyle(const RenderStyle& style)
     976{
     977    return &style == placeholderStyle;
     978}
     979
     980}
     981}
  • trunk/Source/WebCore/style/StyleTreeResolver.h

    r194762 r196031  
    3030#include "SelectorFilter.h"
    3131#include "StyleChange.h"
     32#include "StyleSharingResolver.h"
    3233#include <functional>
    3334#include <wtf/RefPtr.h>
     
    8687
    8788    SelectorFilter m_selectorFilter;
     89    SharingResolver m_sharingResolver;
    8890};
    8991
     
    9597void queuePostResolutionCallback(std::function<void ()>);
    9698bool postResolutionCallbacksAreSuspended();
     99
     100bool isPlaceholderStyle(const RenderStyle&);
    97101
    98102class PostResolutionCallbackDisabler {
  • trunk/Source/WebCore/svg/SVGElement.cpp

    r195465 r196031  
    794794    // If the element is in a <use> tree we get the style from the definition tree.
    795795    if (auto* styleElement = this->correspondingElement())
    796         return styleElement->styleResolver().styleForElement(*styleElement, &parentStyle, DisallowStyleSharing);
     796        return styleElement->styleResolver().styleForElement(*styleElement, &parentStyle);
    797797
    798798    return resolveStyle(&parentStyle);
  • trunk/Source/WebCore/svg/SVGElementRareData.h

    r195465 r196031  
    7272        if (!m_overrideComputedStyle || m_needsOverrideComputedStyleUpdate) {
    7373            // The style computed here contains no CSS Animations/Transitions or SMIL induced rules - this is needed to compute the "base value" for the SMIL animation sandwhich model.
    74             m_overrideComputedStyle = element.styleResolver().styleForElement(element, parentStyle, DisallowStyleSharing, MatchAllRulesExcludingSMIL);
     74            m_overrideComputedStyle = element.styleResolver().styleForElement(element, parentStyle, MatchAllRulesExcludingSMIL);
    7575            m_needsOverrideComputedStyleUpdate = false;
    7676        }
Note: See TracChangeset for help on using the changeset viewer.