Changeset 229372 in webkit
- Timestamp:
- Mar 7, 2018 12:29:17 PM (6 years ago)
- Location:
- trunk/Source/WebCore
- Files:
-
- 8 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r229368 r229372 1 2018-03-07 Antti Koivisto <antti@apple.com> 2 3 Don't invalidate descendants for sibling combinators unless needed 4 https://bugs.webkit.org/show_bug.cgi?id=183410 5 <rdar://problem/38227297> 6 7 Reviewed by Zalan Bujtas. 8 9 If we know the matched sibling combinator doesn't affect descendants we shouldn't invalidate them. 10 11 * css/SelectorChecker.cpp: 12 (WebCore::SelectorChecker::matchRecursively const): 13 14 Use different bit for the descendant case. 15 16 * cssjit/SelectorCompiler.cpp: 17 (WebCore::SelectorCompiler::fragmentMatchesTheRightmostElement): 18 19 Remove unneeded context assert. 20 21 (WebCore::SelectorCompiler::SelectorCodeGenerator::generateSelectorChecker): 22 23 Use different bit for the descendant case. 24 25 (WebCore::SelectorCompiler::SelectorCodeGenerator::generateSelectorCheckerExcludingPseudoElements): 26 (WebCore::SelectorCompiler::SelectorCodeGenerator::generateElementHasPseudoElement): 27 (WebCore::SelectorCompiler::SelectorCodeGenerator::generateRequestedPseudoElementEqualsToSelectorPseudoElement): 28 * dom/Element.cpp: 29 (WebCore::invalidateForSiblingCombinators): 30 31 Invalidate the target sibling or all descendants based on the bits. 32 33 * dom/Element.h: 34 (WebCore::Element::descendantsAffectedByPreviousSibling const): 35 (WebCore::Element::setDescendantsAffectedByPreviousSibling const): 36 * dom/Node.h: 37 * style/StyleRelations.cpp: 38 (WebCore::Style::commitRelationsToRenderStyle): 39 (WebCore::Style::commitRelations): 40 * style/StyleRelations.h: 41 42 Add DescendantsAffectedByPreviousSibling bit. AffectedByPreviousSibling is now just about the target element. 43 1 44 2018-03-07 Antti Koivisto <antti@apple.com> 2 45 -
trunk/Source/WebCore/css/SelectorChecker.cpp
r229368 r229372 363 363 case CSSSelector::DirectAdjacent: 364 364 { 365 addStyleRelation(checkingContext, *context.element, Style::Relation::AffectedByPreviousSibling); 365 auto relation = context.isMatchElement ? Style::Relation::AffectedByPreviousSibling : Style::Relation::DescendantsAffectedByPreviousSibling; 366 addStyleRelation(checkingContext, *context.element, relation); 366 367 367 368 Element* previousElement = context.element->previousElementSibling(); … … 383 384 return MatchResult::updateWithMatchType(result, matchType); 384 385 } 385 case CSSSelector::IndirectAdjacent: 386 addStyleRelation(checkingContext, *context.element, Style::Relation::AffectedByPreviousSibling); 386 case CSSSelector::IndirectAdjacent: { 387 auto relation = context.isMatchElement ? Style::Relation::AffectedByPreviousSibling : Style::Relation::DescendantsAffectedByPreviousSibling; 388 addStyleRelation(checkingContext, *context.element, relation); 387 389 388 390 nextContext.element = context.element->previousElementSibling(); … … 403 405 }; 404 406 return MatchResult::fails(Match::SelectorFailsAllSiblings); 405 407 } 406 408 case CSSSelector::Subselector: 407 409 { -
trunk/Source/WebCore/cssjit/SelectorCompiler.cpp
r229307 r229372 423 423 } 424 424 425 static inline bool fragmentMatchesTheRightmostElement(SelectorContext selectorContext, const SelectorFragment& fragment) 426 { 427 // Return true if the position of this fragment is Rightmost in the root fragments. 428 // In this case, we should use the RenderStyle stored in the CheckingContext. 429 ASSERT_UNUSED(selectorContext, selectorContext != SelectorContext::QuerySelector); 425 static inline bool fragmentMatchesTheRightmostElement(const SelectorFragment& fragment) 426 { 430 427 return fragment.relationToRightFragment == FragmentRelation::Rightmost && fragment.positionInRootFragments == FragmentPositionInRootFragments::Rightmost; 431 428 } … … 1735 1732 // Test selector's pseudo element equals to requested PseudoId. 1736 1733 if (m_selectorContext != SelectorContext::QuerySelector && m_functionType == FunctionType::SelectorCheckerWithCheckingContext) { 1737 ASSERT_WITH_MESSAGE(fragmentMatchesTheRightmostElement(m_selector Context, m_selectorFragments.first()), "Matching pseudo elements only make sense for the rightmost fragment.");1734 ASSERT_WITH_MESSAGE(fragmentMatchesTheRightmostElement(m_selectorFragments.first()), "Matching pseudo elements only make sense for the rightmost fragment."); 1738 1735 generateRequestedPseudoElementEqualsToSelectorPseudoElement(failureOnFunctionEntry, m_selectorFragments.first(), checkingContextRegister); 1739 1736 } … … 1896 1893 break; 1897 1894 } 1898 if (shouldMarkStyleIsAffectedByPreviousSibling(fragment)) 1899 generateAddStyleRelationIfResolvingStyle(elementAddressRegister, Style::Relation::AffectedByPreviousSibling); 1895 if (shouldMarkStyleIsAffectedByPreviousSibling(fragment)) { 1896 if (fragmentMatchesTheRightmostElement(fragment)) 1897 generateAddStyleRelationIfResolvingStyle(elementAddressRegister, Style::Relation::AffectedByPreviousSibling); 1898 else 1899 generateAddStyleRelationIfResolvingStyle(elementAddressRegister, Style::Relation::DescendantsAffectedByPreviousSibling); 1900 } 1900 1901 generateBacktrackingTailsIfNeeded(failureCases, fragment); 1901 1902 } … … 3732 3733 ASSERT_UNUSED(fragment, fragment.pseudoElementSelector); 3733 3734 ASSERT_WITH_MESSAGE(m_selectorContext != SelectorContext::QuerySelector, "When the fragment has pseudo element, the selector becomes CannotMatchAnything for QuerySelector and this test function is not called."); 3734 ASSERT_WITH_MESSAGE_UNUSED(fragment, fragmentMatchesTheRightmostElement( m_selectorContext,fragment), "Virtual pseudo elements handling is only effective in the rightmost fragment. If the current fragment is not rightmost fragment, CSS JIT compiler makes it CannotMatchAnything in fragment construction phase, so never reach here.");3735 ASSERT_WITH_MESSAGE_UNUSED(fragment, fragmentMatchesTheRightmostElement(fragment), "Virtual pseudo elements handling is only effective in the rightmost fragment. If the current fragment is not rightmost fragment, CSS JIT compiler makes it CannotMatchAnything in fragment construction phase, so never reach here."); 3735 3736 } 3736 3737 … … 3742 3743 // If the rightmost fragment doesn't have a pseudo element, the requested pseudoId need to be NOPSEUDO to succeed the matching. 3743 3744 // Otherwise, if the requested pseudoId is not NOPSEUDO, the requested pseudoId need to equal to the pseudo element of the rightmost fragment. 3744 if (fragmentMatchesTheRightmostElement( m_selectorContext,fragment)) {3745 if (fragmentMatchesTheRightmostElement(fragment)) { 3745 3746 if (!fragment.pseudoElementSelector) 3746 3747 failureCases.append(m_assembler.branch8(Assembler::NotEqual, Assembler::Address(checkingContext, OBJECT_OFFSETOF(SelectorChecker::CheckingContext, pseudoId)), Assembler::TrustedImm32(NOPSEUDO))); -
trunk/Source/WebCore/dom/Element.cpp
r229368 r229372 1485 1485 for (; sibling; sibling = sibling->nextElementSibling()) { 1486 1486 if (sibling->styleIsAffectedByPreviousSibling()) 1487 sibling->invalidateStyleForSubtreeInternal(); 1487 sibling->invalidateStyleInternal(); 1488 if (sibling->descendantsAffectedByPreviousSibling()) { 1489 for (auto* siblingChild = sibling->firstElementChild(); siblingChild; siblingChild = siblingChild->nextElementSibling()) 1490 siblingChild->invalidateStyleForSubtreeInternal(); 1491 } 1488 1492 if (!sibling->affectsNextSiblingElementStyle()) 1489 1493 return; -
trunk/Source/WebCore/dom/Element.h
r229307 r229372 328 328 bool styleAffectedByEmpty() const { return hasRareData() && rareDataStyleAffectedByEmpty(); } 329 329 bool styleAffectedByFocusWithin() const { return hasRareData() && rareDataStyleAffectedByFocusWithin(); } 330 bool descendantsAffectedByPreviousSibling() const { return getFlag(DescendantsAffectedByPreviousSiblingFlag); } 330 331 bool childrenAffectedByHover() const { return getFlag(ChildrenAffectedByHoverRulesFlag); } 331 332 bool childrenAffectedByDrag() const { return hasRareData() && rareDataChildrenAffectedByDrag(); } … … 342 343 void setStyleAffectedByEmpty(); 343 344 void setStyleAffectedByFocusWithin(); 345 void setDescendantsAffectedByPreviousSibling() const { return setFlag(DescendantsAffectedByPreviousSiblingFlag); } 344 346 void setChildrenAffectedByHover() { setFlag(ChildrenAffectedByHoverRulesFlag); } 345 347 void setStyleAffectedByActive(); -
trunk/Source/WebCore/dom/Node.h
r224740 r229372 570 570 IsHTMLFlag = 1 << 4, 571 571 IsSVGFlag = 1 << 5, 572 // One free bit left.572 DescendantsAffectedByPreviousSiblingFlag = 1 << 6, 573 573 ChildNeedsStyleRecalcFlag = 1 << 7, 574 574 IsConnectedFlag = 1 << 8, -
trunk/Source/WebCore/style/StyleRelations.cpp
r229307 r229372 76 76 case Relation::AffectedByFocusWithin: 77 77 case Relation::AffectedByPreviousSibling: 78 case Relation::DescendantsAffectedByPreviousSibling: 78 79 case Relation::AffectsNextSibling: 79 80 case Relation::ChildrenAffectedByForwardPositionalRules: … … 114 115 case Relation::AffectedByPreviousSibling: 115 116 element.setStyleIsAffectedByPreviousSibling(); 117 break; 118 case Relation::DescendantsAffectedByPreviousSibling: 119 element.setDescendantsAffectedByPreviousSibling(); 116 120 break; 117 121 case Relation::AffectsNextSibling: { -
trunk/Source/WebCore/style/StyleRelations.h
r229307 r229372 45 45 AffectedByHover, 46 46 AffectedByPreviousSibling, 47 DescendantsAffectedByPreviousSibling, 47 48 // For AffectsNextSibling 'value' tells how many element siblings to mark starting with 'element'. 48 49 AffectsNextSibling,
Note: See TracChangeset
for help on using the changeset viewer.