Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(128)

Side by Side Diff: third_party/WebKit/Source/core/css/RuleFeature.cpp

Issue 2089063005: Schedule sibling invalidation sets for sibling insert/remove. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Corrected DCHECK Created 4 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) 2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
3 * (C) 2004-2005 Allan Sandfeld Jensen (kde@carewolf.com) 3 * (C) 2004-2005 Allan Sandfeld Jensen (kde@carewolf.com)
4 * Copyright (C) 2006, 2007 Nicholas Shanks (webkit@nickshanks.com) 4 * Copyright (C) 2006, 2007 Nicholas Shanks (webkit@nickshanks.com)
5 * Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 Apple Inc. All r ights reserved. 5 * Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 Apple Inc. All r ights reserved.
6 * Copyright (C) 2007 Alexey Proskuryakov <ap@webkit.org> 6 * Copyright (C) 2007 Alexey Proskuryakov <ap@webkit.org>
7 * Copyright (C) 2007, 2008 Eric Seidel <eric@webkit.org> 7 * Copyright (C) 2007, 2008 Eric Seidel <eric@webkit.org>
8 * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.t orchmobile.com/) 8 * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.t orchmobile.com/)
9 * Copyright (c) 2011, Code Aurora Forum. All rights reserved. 9 * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
10 * Copyright (C) Research In Motion Limited 2011. All rights reserved. 10 * Copyright (C) Research In Motion Limited 2011. All rights reserved.
(...skipping 488 matching lines...) Expand 10 before | Expand all | Expand 10 after
499 // selector is the selector immediately to the left of the rightmost combinator. 499 // selector is the selector immediately to the left of the rightmost combinator.
500 // siblingFeatures is null if selector is not immediately to the left of a sibli ng combinator. 500 // siblingFeatures is null if selector is not immediately to the left of a sibli ng combinator.
501 // descendantFeatures has the features of the rightmost compound selector. 501 // descendantFeatures has the features of the rightmost compound selector.
502 void RuleFeatureSet::addFeaturesToInvalidationSets(const CSSSelector* selector, InvalidationSetFeatures* siblingFeatures, InvalidationSetFeatures& descendantFea tures) 502 void RuleFeatureSet::addFeaturesToInvalidationSets(const CSSSelector* selector, InvalidationSetFeatures* siblingFeatures, InvalidationSetFeatures& descendantFea tures)
503 { 503 {
504 const CSSSelector* lastCompoundSelectorInAdjacentChain = selector; 504 const CSSSelector* lastCompoundSelectorInAdjacentChain = selector;
505 505
506 // We set siblingFeatures to &localFeatures if we find a rightmost sibling c ombinator. 506 // We set siblingFeatures to &localFeatures if we find a rightmost sibling c ombinator.
507 InvalidationSetFeatures localFeatures; 507 InvalidationSetFeatures localFeatures;
508 508
509 bool universalCompound = true;
510
509 for (const CSSSelector* current = selector; current; current = current->tagH istory()) { 511 for (const CSSSelector* current = selector; current; current = current->tagH istory()) {
510 InvalidationType type = siblingFeatures ? InvalidateSiblings : Invalidat eDescendants; 512 InvalidationType type = siblingFeatures ? InvalidateSiblings : Invalidat eDescendants;
511 if (InvalidationSet* invalidationSet = invalidationSetForSelector(*curre nt, type)) { 513 if (InvalidationSet* invalidationSet = invalidationSetForSelector(*curre nt, type)) {
514 if (current->match() != CSSSelector::PseudoClass)
515 universalCompound = false;
512 if (siblingFeatures) { 516 if (siblingFeatures) {
513 SiblingInvalidationSet* siblingInvalidationSet = toSiblingInvali dationSet(invalidationSet); 517 SiblingInvalidationSet* siblingInvalidationSet = toSiblingInvali dationSet(invalidationSet);
514 siblingInvalidationSet->updateMaxDirectAdjacentSelectors(sibling Features->maxDirectAdjacentSelectors); 518 siblingInvalidationSet->updateMaxDirectAdjacentSelectors(sibling Features->maxDirectAdjacentSelectors);
515 519
516 addFeaturesToInvalidationSet(*invalidationSet, *siblingFeatures) ; 520 addFeaturesToInvalidationSet(*invalidationSet, *siblingFeatures) ;
517 if (siblingFeatures == &descendantFeatures) 521 if (siblingFeatures == &descendantFeatures)
518 siblingInvalidationSet->setInvalidatesSelf(); 522 siblingInvalidationSet->setInvalidatesSelf();
519 else 523 else
520 addFeaturesToInvalidationSet(siblingInvalidationSet->ensureS iblingDescendants(), descendantFeatures); 524 addFeaturesToInvalidationSet(siblingInvalidationSet->ensureS iblingDescendants(), descendantFeatures);
521 } else { 525 } else {
522 addFeaturesToInvalidationSet(*invalidationSet, descendantFeature s); 526 addFeaturesToInvalidationSet(*invalidationSet, descendantFeature s);
523 } 527 }
524 } else { 528 } else {
525 if (current->isHostPseudoClass()) 529 if (current->isHostPseudoClass())
526 descendantFeatures.treeBoundaryCrossing = true; 530 descendantFeatures.treeBoundaryCrossing = true;
527 if (current->isInsertionPointCrossing()) 531 if (current->isInsertionPointCrossing())
528 descendantFeatures.insertionPointCrossing = true; 532 descendantFeatures.insertionPointCrossing = true;
529 if (const CSSSelectorList* selectorList = current->selectorList()) { 533 if (const CSSSelectorList* selectorList = current->selectorList()) {
530 ASSERT(supportsInvalidationWithSelectorList(current->getPseudoTy pe())); 534 ASSERT(supportsInvalidationWithSelectorList(current->getPseudoTy pe()));
531 for (const CSSSelector* subSelector = selectorList->first(); sub Selector; subSelector = CSSSelectorList::next(*subSelector)) 535 for (const CSSSelector* subSelector = selectorList->first(); sub Selector; subSelector = CSSSelectorList::next(*subSelector))
532 addFeaturesToInvalidationSets(subSelector, siblingFeatures, descendantFeatures); 536 addFeaturesToInvalidationSets(subSelector, siblingFeatures, descendantFeatures);
533 } 537 }
534 } 538 }
535 539
536 if (current->relation() == CSSSelector::SubSelector) 540 if (current->relation() == CSSSelector::SubSelector)
537 continue; 541 continue;
538 542
543 if (universalCompound && siblingFeatures)
544 addFeaturesToUniversalSiblingInvalidationSet(*siblingFeatures, desce ndantFeatures);
545 universalCompound = true;
546
539 if (current->relationIsAffectedByPseudoContent() || current->relation() == CSSSelector::ShadowSlot) { 547 if (current->relationIsAffectedByPseudoContent() || current->relation() == CSSSelector::ShadowSlot) {
540 descendantFeatures.insertionPointCrossing = true; 548 descendantFeatures.insertionPointCrossing = true;
541 descendantFeatures.contentPseudoCrossing = true; 549 descendantFeatures.contentPseudoCrossing = true;
542 } 550 }
543 if (current->isShadowSelector()) 551 if (current->isShadowSelector())
544 descendantFeatures.treeBoundaryCrossing = true; 552 descendantFeatures.treeBoundaryCrossing = true;
545 if (!current->isAdjacentSelector()) { 553 if (!current->isAdjacentSelector()) {
546 lastCompoundSelectorInAdjacentChain = current->tagHistory(); 554 lastCompoundSelectorInAdjacentChain = current->tagHistory();
547 siblingFeatures = nullptr; 555 siblingFeatures = nullptr;
548 continue; 556 continue;
549 } 557 }
550 558
551 if (siblingFeatures) { 559 if (siblingFeatures) {
552 if (siblingFeatures->maxDirectAdjacentSelectors == UINT_MAX) 560 if (siblingFeatures->maxDirectAdjacentSelectors == UINT_MAX)
553 continue; 561 continue;
554 562
555 if (current->relation() == CSSSelector::DirectAdjacent) 563 if (current->relation() == CSSSelector::DirectAdjacent)
556 siblingFeatures->maxDirectAdjacentSelectors++; 564 siblingFeatures->maxDirectAdjacentSelectors++;
557 else 565 else
558 siblingFeatures->maxDirectAdjacentSelectors = UINT_MAX; 566 siblingFeatures->maxDirectAdjacentSelectors = UINT_MAX;
559 continue; 567 continue;
560 } 568 }
561 569
562 localFeatures = InvalidationSetFeatures(); 570 localFeatures = InvalidationSetFeatures();
563 auto result = extractInvalidationSetFeatures(*lastCompoundSelectorInAdja centChain, localFeatures, Ancestor); 571 auto result = extractInvalidationSetFeatures(*lastCompoundSelectorInAdja centChain, localFeatures, Ancestor);
564 ASSERT(result.first); 572 ASSERT(result.first);
565 localFeatures.forceSubtree = result.second == ForceSubtree; 573 localFeatures.forceSubtree = result.second == ForceSubtree;
566 siblingFeatures = &localFeatures; 574 siblingFeatures = &localFeatures;
567 } 575 }
576
577 if (universalCompound && siblingFeatures)
578 addFeaturesToUniversalSiblingInvalidationSet(*siblingFeatures, descendan tFeatures);
568 } 579 }
569 580
570 RuleFeatureSet::SelectorPreMatch RuleFeatureSet::collectFeaturesFromRuleData(con st RuleData& ruleData) 581 RuleFeatureSet::SelectorPreMatch RuleFeatureSet::collectFeaturesFromRuleData(con st RuleData& ruleData)
571 { 582 {
572 FeatureMetadata metadata; 583 FeatureMetadata metadata;
573 if (collectFeaturesFromSelector(ruleData.selector(), metadata) == SelectorNe verMatches) 584 if (collectFeaturesFromSelector(ruleData.selector(), metadata) == SelectorNe verMatches)
574 return SelectorNeverMatches; 585 return SelectorNeverMatches;
575 586
576 m_metadata.add(metadata); 587 m_metadata.add(metadata);
577 588
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
675 void RuleFeatureSet::add(const RuleFeatureSet& other) 686 void RuleFeatureSet::add(const RuleFeatureSet& other)
676 { 687 {
677 for (const auto& entry : other.m_classInvalidationSets) 688 for (const auto& entry : other.m_classInvalidationSets)
678 ensureInvalidationSet(m_classInvalidationSets, entry.key, entry.value->t ype()).combine(*entry.value); 689 ensureInvalidationSet(m_classInvalidationSets, entry.key, entry.value->t ype()).combine(*entry.value);
679 for (const auto& entry : other.m_attributeInvalidationSets) 690 for (const auto& entry : other.m_attributeInvalidationSets)
680 ensureInvalidationSet(m_attributeInvalidationSets, entry.key, entry.valu e->type()).combine(*entry.value); 691 ensureInvalidationSet(m_attributeInvalidationSets, entry.key, entry.valu e->type()).combine(*entry.value);
681 for (const auto& entry : other.m_idInvalidationSets) 692 for (const auto& entry : other.m_idInvalidationSets)
682 ensureInvalidationSet(m_idInvalidationSets, entry.key, entry.value->type ()).combine(*entry.value); 693 ensureInvalidationSet(m_idInvalidationSets, entry.key, entry.value->type ()).combine(*entry.value);
683 for (const auto& entry : other.m_pseudoInvalidationSets) 694 for (const auto& entry : other.m_pseudoInvalidationSets)
684 ensureInvalidationSet(m_pseudoInvalidationSets, static_cast<CSSSelector: :PseudoType>(entry.key), entry.value->type()).combine(*entry.value); 695 ensureInvalidationSet(m_pseudoInvalidationSets, static_cast<CSSSelector: :PseudoType>(entry.key), entry.value->type()).combine(*entry.value);
696 if (other.m_universalSiblingInvalidationSet)
697 ensureUniversalSiblingInvalidationSet().combine(*other.m_universalSiblin gInvalidationSet);
685 698
686 m_metadata.add(other.m_metadata); 699 m_metadata.add(other.m_metadata);
687 700
688 siblingRules.appendVector(other.siblingRules); 701 siblingRules.appendVector(other.siblingRules);
689 uncommonAttributeRules.appendVector(other.uncommonAttributeRules); 702 uncommonAttributeRules.appendVector(other.uncommonAttributeRules);
690 } 703 }
691 704
692 void RuleFeatureSet::clear() 705 void RuleFeatureSet::clear()
693 { 706 {
694 siblingRules.clear(); 707 siblingRules.clear();
(...skipping 19 matching lines...) Expand all
714 TRACE_SCHEDULE_STYLE_INVALIDATION(element, *descendants, classChange, cl assName); 727 TRACE_SCHEDULE_STYLE_INVALIDATION(element, *descendants, classChange, cl assName);
715 invalidationLists.descendants.append(descendants); 728 invalidationLists.descendants.append(descendants);
716 } 729 }
717 730
718 if (siblings) { 731 if (siblings) {
719 TRACE_SCHEDULE_STYLE_INVALIDATION(element, *siblings, classChange, class Name); 732 TRACE_SCHEDULE_STYLE_INVALIDATION(element, *siblings, classChange, class Name);
720 invalidationLists.siblings.append(siblings); 733 invalidationLists.siblings.append(siblings);
721 } 734 }
722 } 735 }
723 736
737 void RuleFeatureSet::collectSiblingInvalidationSetForClass(InvalidationLists& in validationLists, Element& element, const AtomicString& className, unsigned minDi rectAdjacent) const
738 {
739 InvalidationSetMap::const_iterator it = m_classInvalidationSets.find(classNa me);
740 if (it == m_classInvalidationSets.end())
741 return;
742
743 InvalidationSet* invalidationSet = it->value.get();
744 if (invalidationSet->type() == InvalidateDescendants)
745 return;
746
747 SiblingInvalidationSet* siblingSet = toSiblingInvalidationSet(invalidationSe t);
748 if (siblingSet->maxDirectAdjacentSelectors() < minDirectAdjacent)
749 return;
750
751 TRACE_SCHEDULE_STYLE_INVALIDATION(element, *siblingSet, classChange, classNa me);
752 invalidationLists.siblings.append(siblingSet);
753 }
754
724 void RuleFeatureSet::collectInvalidationSetsForId(InvalidationLists& invalidatio nLists, Element& element, const AtomicString& id) const 755 void RuleFeatureSet::collectInvalidationSetsForId(InvalidationLists& invalidatio nLists, Element& element, const AtomicString& id) const
725 { 756 {
726 InvalidationSetMap::const_iterator it = m_idInvalidationSets.find(id); 757 InvalidationSetMap::const_iterator it = m_idInvalidationSets.find(id);
727 if (it == m_idInvalidationSets.end()) 758 if (it == m_idInvalidationSets.end())
728 return; 759 return;
729 760
730 DescendantInvalidationSet* descendants; 761 DescendantInvalidationSet* descendants;
731 SiblingInvalidationSet* siblings; 762 SiblingInvalidationSet* siblings;
732 extractInvalidationSets(it->value.get(), descendants, siblings); 763 extractInvalidationSets(it->value.get(), descendants, siblings);
733 764
734 if (descendants) { 765 if (descendants) {
735 TRACE_SCHEDULE_STYLE_INVALIDATION(element, *descendants, idChange, id); 766 TRACE_SCHEDULE_STYLE_INVALIDATION(element, *descendants, idChange, id);
736 invalidationLists.descendants.append(descendants); 767 invalidationLists.descendants.append(descendants);
737 } 768 }
738 769
739 if (siblings) { 770 if (siblings) {
740 TRACE_SCHEDULE_STYLE_INVALIDATION(element, *siblings, idChange, id); 771 TRACE_SCHEDULE_STYLE_INVALIDATION(element, *siblings, idChange, id);
741 invalidationLists.siblings.append(siblings); 772 invalidationLists.siblings.append(siblings);
742 } 773 }
743 } 774 }
744 775
776 void RuleFeatureSet::collectSiblingInvalidationSetForId(InvalidationLists& inval idationLists, Element& element, const AtomicString& id, unsigned minDirectAdjace nt) const
777 {
778 InvalidationSetMap::const_iterator it = m_idInvalidationSets.find(id);
779 if (it == m_idInvalidationSets.end())
780 return;
781
782 InvalidationSet* invalidationSet = it->value.get();
783 if (invalidationSet->type() == InvalidateDescendants)
784 return;
785
786 SiblingInvalidationSet* siblingSet = toSiblingInvalidationSet(invalidationSe t);
787 if (siblingSet->maxDirectAdjacentSelectors() < minDirectAdjacent)
788 return;
789
790 TRACE_SCHEDULE_STYLE_INVALIDATION(element, *siblingSet, idChange, id);
791 invalidationLists.siblings.append(siblingSet);
792 }
793
745 void RuleFeatureSet::collectInvalidationSetsForAttribute(InvalidationLists& inva lidationLists, Element& element, const QualifiedName& attributeName) const 794 void RuleFeatureSet::collectInvalidationSetsForAttribute(InvalidationLists& inva lidationLists, Element& element, const QualifiedName& attributeName) const
746 { 795 {
747 InvalidationSetMap::const_iterator it = m_attributeInvalidationSets.find(att ributeName.localName()); 796 InvalidationSetMap::const_iterator it = m_attributeInvalidationSets.find(att ributeName.localName());
748 if (it == m_attributeInvalidationSets.end()) 797 if (it == m_attributeInvalidationSets.end())
749 return; 798 return;
750 799
751 DescendantInvalidationSet* descendants; 800 DescendantInvalidationSet* descendants;
752 SiblingInvalidationSet* siblings; 801 SiblingInvalidationSet* siblings;
753 extractInvalidationSets(it->value.get(), descendants, siblings); 802 extractInvalidationSets(it->value.get(), descendants, siblings);
754 803
755 if (descendants) { 804 if (descendants) {
756 TRACE_SCHEDULE_STYLE_INVALIDATION(element, *descendants, attributeChange , attributeName); 805 TRACE_SCHEDULE_STYLE_INVALIDATION(element, *descendants, attributeChange , attributeName);
757 invalidationLists.descendants.append(descendants); 806 invalidationLists.descendants.append(descendants);
758 } 807 }
759 808
760 if (siblings) { 809 if (siblings) {
761 TRACE_SCHEDULE_STYLE_INVALIDATION(element, *siblings, attributeChange, a ttributeName); 810 TRACE_SCHEDULE_STYLE_INVALIDATION(element, *siblings, attributeChange, a ttributeName);
762 invalidationLists.siblings.append(siblings); 811 invalidationLists.siblings.append(siblings);
763 } 812 }
764 } 813 }
765 814
815 void RuleFeatureSet::collectSiblingInvalidationSetForAttribute(InvalidationLists & invalidationLists, Element& element, const QualifiedName& attributeName, unsig ned minDirectAdjacent) const
816 {
817 InvalidationSetMap::const_iterator it = m_attributeInvalidationSets.find(att ributeName.localName());
818 if (it == m_attributeInvalidationSets.end())
819 return;
820
821 InvalidationSet* invalidationSet = it->value.get();
822 if (invalidationSet->type() == InvalidateDescendants)
823 return;
824
825 SiblingInvalidationSet* siblingSet = toSiblingInvalidationSet(invalidationSe t);
826 if (siblingSet->maxDirectAdjacentSelectors() < minDirectAdjacent)
esprehn 2016/06/25 01:54:07 Can you explain why we can skip collecting the set
rune 2016/06/25 11:06:34 The min that is passed in is the distance from the
esprehn 2016/06/29 04:52:08 Interesting, I wonder if we should do that in a se
rune 2016/06/29 07:44:21 Yeah. I didn't add any tests for that either, so I
rune 2016/06/29 08:26:06 Done.
827 return;
828
829 TRACE_SCHEDULE_STYLE_INVALIDATION(element, *siblingSet, attributeChange, att ributeName);
830 invalidationLists.siblings.append(siblingSet);
831 }
832
766 void RuleFeatureSet::collectInvalidationSetsForPseudoClass(InvalidationLists& in validationLists, Element& element, CSSSelector::PseudoType pseudo) const 833 void RuleFeatureSet::collectInvalidationSetsForPseudoClass(InvalidationLists& in validationLists, Element& element, CSSSelector::PseudoType pseudo) const
767 { 834 {
768 PseudoTypeInvalidationSetMap::const_iterator it = m_pseudoInvalidationSets.f ind(pseudo); 835 PseudoTypeInvalidationSetMap::const_iterator it = m_pseudoInvalidationSets.f ind(pseudo);
769 if (it == m_pseudoInvalidationSets.end()) 836 if (it == m_pseudoInvalidationSets.end())
770 return; 837 return;
771 838
772 DescendantInvalidationSet* descendants; 839 DescendantInvalidationSet* descendants;
773 SiblingInvalidationSet* siblings; 840 SiblingInvalidationSet* siblings;
774 extractInvalidationSets(it->value.get(), descendants, siblings); 841 extractInvalidationSets(it->value.get(), descendants, siblings);
775 842
776 if (descendants) { 843 if (descendants) {
777 TRACE_SCHEDULE_STYLE_INVALIDATION(element, *descendants, pseudoChange, p seudo); 844 TRACE_SCHEDULE_STYLE_INVALIDATION(element, *descendants, pseudoChange, p seudo);
778 invalidationLists.descendants.append(descendants); 845 invalidationLists.descendants.append(descendants);
779 } 846 }
780 847
781 if (siblings) { 848 if (siblings) {
782 TRACE_SCHEDULE_STYLE_INVALIDATION(element, *siblings, pseudoChange, pseu do); 849 TRACE_SCHEDULE_STYLE_INVALIDATION(element, *siblings, pseudoChange, pseu do);
783 invalidationLists.siblings.append(siblings); 850 invalidationLists.siblings.append(siblings);
784 } 851 }
785 } 852 }
786 853
854 void RuleFeatureSet::collectUniversalSiblingInvalidationSet(InvalidationLists& i nvalidationLists, unsigned minDirectAdjacent) const
855 {
856 if (m_universalSiblingInvalidationSet && m_universalSiblingInvalidationSet-> maxDirectAdjacentSelectors() >= minDirectAdjacent)
857 invalidationLists.siblings.append(m_universalSiblingInvalidationSet);
858 }
859
860 SiblingInvalidationSet& RuleFeatureSet::ensureUniversalSiblingInvalidationSet()
861 {
862 if (!m_universalSiblingInvalidationSet)
863 m_universalSiblingInvalidationSet = SiblingInvalidationSet::create(nullp tr);
864 return *m_universalSiblingInvalidationSet;
865 }
866
867 void RuleFeatureSet::addFeaturesToUniversalSiblingInvalidationSet(const Invalida tionSetFeatures& siblingFeatures, const InvalidationSetFeatures& descendantFeatu res)
868 {
869 SiblingInvalidationSet& universalSet = ensureUniversalSiblingInvalidationSet ();
870 addFeaturesToInvalidationSet(universalSet, siblingFeatures);
871 universalSet.updateMaxDirectAdjacentSelectors(siblingFeatures.maxDirectAdjac entSelectors);
872
873 if (&siblingFeatures == &descendantFeatures)
874 universalSet.setInvalidatesSelf();
875 else
876 addFeaturesToInvalidationSet(universalSet.ensureSiblingDescendants(), de scendantFeatures);
877 }
878
787 DEFINE_TRACE(RuleFeatureSet) 879 DEFINE_TRACE(RuleFeatureSet)
788 { 880 {
789 visitor->trace(siblingRules); 881 visitor->trace(siblingRules);
790 visitor->trace(uncommonAttributeRules); 882 visitor->trace(uncommonAttributeRules);
791 } 883 }
792 884
793 } // namespace blink 885 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698