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

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

Issue 2235723002: Use invalidation sets for nth invalidations. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 4 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 333 matching lines...) Expand 10 before | Expand all | Expand 10 after
344 case CSSSelector::PseudoIndeterminate: 344 case CSSSelector::PseudoIndeterminate:
345 case CSSSelector::PseudoTarget: 345 case CSSSelector::PseudoTarget:
346 case CSSSelector::PseudoLang: 346 case CSSSelector::PseudoLang:
347 case CSSSelector::PseudoFullScreen: 347 case CSSSelector::PseudoFullScreen:
348 case CSSSelector::PseudoFullScreenAncestor: 348 case CSSSelector::PseudoFullScreenAncestor:
349 case CSSSelector::PseudoInRange: 349 case CSSSelector::PseudoInRange:
350 case CSSSelector::PseudoOutOfRange: 350 case CSSSelector::PseudoOutOfRange:
351 case CSSSelector::PseudoUnresolved: 351 case CSSSelector::PseudoUnresolved:
352 case CSSSelector::PseudoDefined: 352 case CSSSelector::PseudoDefined:
353 return &ensurePseudoInvalidationSet(selector.getPseudoType(), type); 353 return &ensurePseudoInvalidationSet(selector.getPseudoType(), type);
354 case CSSSelector::PseudoFirstOfType:
355 case CSSSelector::PseudoLastOfType:
356 case CSSSelector::PseudoOnlyOfType:
357 case CSSSelector::PseudoNthChild:
358 case CSSSelector::PseudoNthOfType:
359 case CSSSelector::PseudoNthLastChild:
360 case CSSSelector::PseudoNthLastOfType:
361 return &ensureNthInvalidationSet();
354 default: 362 default:
355 break; 363 break;
356 } 364 }
357 } 365 }
358 return nullptr; 366 return nullptr;
359 } 367 }
360 368
361 // Given a rule, update the descendant invalidation sets for the features found 369 // Given a rule, update the descendant invalidation sets for the features found
362 // in its selector. The first step is to extract the features from the rightmost 370 // in its selector. The first step is to extract the features from the rightmost
363 // compound selector (extractInvalidationSetFeatures). Secondly, add those featu res 371 // compound selector (extractInvalidationSetFeatures). Secondly, add those featu res
364 // to the invalidation sets for the features found in the other compound selecto rs 372 // to the invalidation sets for the features found in the other compound selecto rs
365 // (addFeaturesToInvalidationSets). If we find a feature in the right-most compo und 373 // (addFeaturesToInvalidationSets). If we find a feature in the right-most compo und
366 // selector that requires a subtree recalc, we addFeaturesToInvalidationSets for the 374 // selector that requires a subtree recalc, we addFeaturesToInvalidationSets for the
367 // rightmost compound selector as well. 375 // rightmost compound selector as well.
368 376
369 void RuleFeatureSet::updateInvalidationSets(const RuleData& ruleData) 377 void RuleFeatureSet::updateInvalidationSets(const RuleData& ruleData)
370 { 378 {
371 InvalidationSetFeatures features; 379 InvalidationSetFeatures features;
372 auto result = extractInvalidationSetFeatures(ruleData.selector(), features, Subject); 380 auto result = extractInvalidationSetFeatures(ruleData.selector(), features, Subject);
373 381
382 features.forceSubtree = result.second == ForceSubtree;
374 if (result.first) { 383 if (result.first) {
375 features.forceSubtree = result.second == ForceSubtree;
376 addFeaturesToInvalidationSets(result.first, features.adjacent ? &feature s : nullptr, features); 384 addFeaturesToInvalidationSets(result.first, features.adjacent ? &feature s : nullptr, features);
385 } else if (features.hasNthPseudo) {
386 DCHECK(m_nthInvalidationSet);
387 addFeaturesToInvalidationSet(*m_nthInvalidationSet, features);
377 } 388 }
378 389
379 // If any ::before and ::after rules specify 'content: attr(...)', we 390 // If any ::before and ::after rules specify 'content: attr(...)', we
380 // need to create invalidation sets for those attributes. 391 // need to create invalidation sets for those attributes.
381 if (features.hasBeforeOrAfter) 392 if (features.hasBeforeOrAfter)
382 updateInvalidationSetsForContentAttribute(ruleData); 393 updateInvalidationSetsForContentAttribute(ruleData);
383 } 394 }
384 395
385 void RuleFeatureSet::updateInvalidationSetsForContentAttribute(const RuleData& r uleData) 396 void RuleFeatureSet::updateInvalidationSetsForContentAttribute(const RuleData& r uleData)
386 { 397 {
(...skipping 22 matching lines...) Expand all
409 420
410 std::pair<const CSSSelector*, RuleFeatureSet::UseFeaturesType> 421 std::pair<const CSSSelector*, RuleFeatureSet::UseFeaturesType>
411 RuleFeatureSet::extractInvalidationSetFeatures(const CSSSelector& selector, Inva lidationSetFeatures& features, PositionType position, CSSSelector::PseudoType ps eudo) 422 RuleFeatureSet::extractInvalidationSetFeatures(const CSSSelector& selector, Inva lidationSetFeatures& features, PositionType position, CSSSelector::PseudoType ps eudo)
412 { 423 {
413 bool foundFeatures = false; 424 bool foundFeatures = false;
414 for (const CSSSelector* current = &selector; current; current = current->tag History()) { 425 for (const CSSSelector* current = &selector; current; current = current->tag History()) {
415 if (pseudo != CSSSelector::PseudoNot) 426 if (pseudo != CSSSelector::PseudoNot)
416 foundFeatures |= extractInvalidationSetFeature(*current, features); 427 foundFeatures |= extractInvalidationSetFeature(*current, features);
417 // Initialize the entry in the invalidation set map, if supported. 428 // Initialize the entry in the invalidation set map, if supported.
418 if (InvalidationSet* invalidationSet = invalidationSetForSelector(*curre nt, InvalidateDescendants)) { 429 if (InvalidationSet* invalidationSet = invalidationSetForSelector(*curre nt, InvalidateDescendants)) {
419 if (position == Subject) 430 if (position == Subject) {
420 invalidationSet->setInvalidatesSelf(); 431 if (invalidationSet == m_nthInvalidationSet)
432 features.hasNthPseudo = true;
433 else
434 invalidationSet->setInvalidatesSelf();
435 }
421 } else { 436 } else {
422 if (requiresSubtreeInvalidation(*current)) { 437 if (requiresSubtreeInvalidation(*current)) {
423 // Fall back to use subtree invalidations, even for features in the 438 // Fall back to use subtree invalidations, even for features in the
424 // rightmost compound selector. Returning the start &selector he re 439 // rightmost compound selector. Returning the start &selector he re
425 // will make addFeaturesToInvalidationSets start marking invalid ation 440 // will make addFeaturesToInvalidationSets start marking invalid ation
426 // sets for subtree recalc for features in the rightmost compoun d 441 // sets for subtree recalc for features in the rightmost compoun d
427 // selector. 442 // selector.
428 return std::make_pair(&selector, ForceSubtree); 443 return std::make_pair(&selector, ForceSubtree);
429 } 444 }
430 if (const CSSSelectorList* selectorList = current->selectorList()) { 445 if (const CSSSelectorList* selectorList = current->selectorList()) {
(...skipping 14 matching lines...) Expand all
445 } 460 }
446 allSubSelectorsHaveFeatures &= result.second == UseFeatures; 461 allSubSelectorsHaveFeatures &= result.second == UseFeatures;
447 } 462 }
448 foundFeatures |= allSubSelectorsHaveFeatures; 463 foundFeatures |= allSubSelectorsHaveFeatures;
449 } 464 }
450 } 465 }
451 466
452 if (current->relation() == CSSSelector::SubSelector) 467 if (current->relation() == CSSSelector::SubSelector)
453 continue; 468 continue;
454 469
470 if (features.hasNthPseudo && position == Subject) {
471 DCHECK(m_nthInvalidationSet);
472 addFeaturesToInvalidationSet(*m_nthInvalidationSet, features);
473 if (!foundFeatures)
474 m_nthInvalidationSet->setWholeSubtreeInvalid();
esprehn 2016/08/11 10:32:55 If we're going to mark it for the whole subtree wh
rune 2016/08/12 11:03:14 Will fix.
475 }
476
455 features.treeBoundaryCrossing = current->isShadowSelector(); 477 features.treeBoundaryCrossing = current->isShadowSelector();
456 if (current->relationIsAffectedByPseudoContent()) { 478 if (current->relationIsAffectedByPseudoContent()) {
457 features.contentPseudoCrossing = true; 479 features.contentPseudoCrossing = true;
458 features.insertionPointCrossing = true; 480 features.insertionPointCrossing = true;
459 } 481 }
460 features.adjacent = current->isAdjacentSelector(); 482 features.adjacent = current->isAdjacentSelector();
461 if (current->relation() == CSSSelector::DirectAdjacent) 483 if (current->relation() == CSSSelector::DirectAdjacent)
462 features.maxDirectAdjacentSelectors = 1; 484 features.maxDirectAdjacentSelectors = 1;
463 return std::make_pair(current->tagHistory(), foundFeatures ? UseFeatures : ForceSubtree); 485 return std::make_pair(current->tagHistory(), foundFeatures ? UseFeatures : ForceSubtree);
464 } 486 }
465 return std::make_pair(nullptr, foundFeatures ? UseFeatures : ForceSubtree); 487 return std::make_pair(nullptr, foundFeatures ? UseFeatures : ForceSubtree);
466 } 488 }
467 489
468 // Add features extracted from the rightmost compound selector to descendant inv alidation 490 // Add features extracted from the rightmost compound selector to descendant inv alidation
469 // sets for features found in other compound selectors. 491 // sets for features found in other compound selectors.
470 // 492 //
471 // We use descendant invalidation for descendants, sibling invalidation for sibl ings and their subtrees. 493 // We use descendant invalidation for descendants, sibling invalidation for sibl ings and their subtrees.
472 // 494 //
473 // As we encounter a descendant type of combinator, the features only need to be checked 495 // As we encounter a descendant type of combinator, the features only need to be checked
474 // against descendants in the same subtree only. features.adjacent is set to fal se, and 496 // against descendants in the same subtree only. features.adjacent is set to fal se, and
475 // we start adding features to the descendant invalidation set. 497 // we start adding features to the descendant invalidation set.
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
509 // We set siblingFeatures to &localFeatures if we find a rightmost sibling c ombinator. 531 // We set siblingFeatures to &localFeatures if we find a rightmost sibling c ombinator.
510 InvalidationSetFeatures localFeatures; 532 InvalidationSetFeatures localFeatures;
511 533
512 bool universalCompound = true; 534 bool universalCompound = true;
513 535
514 for (const CSSSelector* current = selector; current; current = current->tagH istory()) { 536 for (const CSSSelector* current = selector; current; current = current->tagH istory()) {
515 InvalidationType type = siblingFeatures ? InvalidateSiblings : Invalidat eDescendants; 537 InvalidationType type = siblingFeatures ? InvalidateSiblings : Invalidat eDescendants;
516 if (InvalidationSet* invalidationSet = invalidationSetForSelector(*curre nt, type)) { 538 if (InvalidationSet* invalidationSet = invalidationSetForSelector(*curre nt, type)) {
517 if (current->match() != CSSSelector::PseudoClass) 539 if (current->match() != CSSSelector::PseudoClass)
518 universalCompound = false; 540 universalCompound = false;
519 if (siblingFeatures) { 541 if (siblingFeatures && invalidationSet != m_nthInvalidationSet) {
520 SiblingInvalidationSet* siblingInvalidationSet = toSiblingInvali dationSet(invalidationSet); 542 SiblingInvalidationSet* siblingInvalidationSet = toSiblingInvali dationSet(invalidationSet);
521 siblingInvalidationSet->updateMaxDirectAdjacentSelectors(sibling Features->maxDirectAdjacentSelectors); 543 siblingInvalidationSet->updateMaxDirectAdjacentSelectors(sibling Features->maxDirectAdjacentSelectors);
522 544
523 addFeaturesToInvalidationSet(*invalidationSet, *siblingFeatures) ; 545 addFeaturesToInvalidationSet(*invalidationSet, *siblingFeatures) ;
524 if (siblingFeatures == &descendantFeatures) 546 if (siblingFeatures == &descendantFeatures)
525 siblingInvalidationSet->setInvalidatesSelf(); 547 siblingInvalidationSet->setInvalidatesSelf();
526 else 548 else
527 addFeaturesToInvalidationSet(siblingInvalidationSet->ensureS iblingDescendants(), descendantFeatures); 549 addFeaturesToInvalidationSet(siblingInvalidationSet->ensureS iblingDescendants(), descendantFeatures);
528 } else { 550 } else {
529 addFeaturesToInvalidationSet(*invalidationSet, descendantFeature s); 551 addFeaturesToInvalidationSet(*invalidationSet, descendantFeature s);
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after
691 for (const auto& entry : other.m_classInvalidationSets) 713 for (const auto& entry : other.m_classInvalidationSets)
692 ensureInvalidationSet(m_classInvalidationSets, entry.key, entry.value->t ype()).combine(*entry.value); 714 ensureInvalidationSet(m_classInvalidationSets, entry.key, entry.value->t ype()).combine(*entry.value);
693 for (const auto& entry : other.m_attributeInvalidationSets) 715 for (const auto& entry : other.m_attributeInvalidationSets)
694 ensureInvalidationSet(m_attributeInvalidationSets, entry.key, entry.valu e->type()).combine(*entry.value); 716 ensureInvalidationSet(m_attributeInvalidationSets, entry.key, entry.valu e->type()).combine(*entry.value);
695 for (const auto& entry : other.m_idInvalidationSets) 717 for (const auto& entry : other.m_idInvalidationSets)
696 ensureInvalidationSet(m_idInvalidationSets, entry.key, entry.value->type ()).combine(*entry.value); 718 ensureInvalidationSet(m_idInvalidationSets, entry.key, entry.value->type ()).combine(*entry.value);
697 for (const auto& entry : other.m_pseudoInvalidationSets) 719 for (const auto& entry : other.m_pseudoInvalidationSets)
698 ensureInvalidationSet(m_pseudoInvalidationSets, static_cast<CSSSelector: :PseudoType>(entry.key), entry.value->type()).combine(*entry.value); 720 ensureInvalidationSet(m_pseudoInvalidationSets, static_cast<CSSSelector: :PseudoType>(entry.key), entry.value->type()).combine(*entry.value);
699 if (other.m_universalSiblingInvalidationSet) 721 if (other.m_universalSiblingInvalidationSet)
700 ensureUniversalSiblingInvalidationSet().combine(*other.m_universalSiblin gInvalidationSet); 722 ensureUniversalSiblingInvalidationSet().combine(*other.m_universalSiblin gInvalidationSet);
723 if (other.m_nthInvalidationSet)
724 ensureNthInvalidationSet().combine(*other.m_nthInvalidationSet);
701 725
702 m_metadata.add(other.m_metadata); 726 m_metadata.add(other.m_metadata);
703 727
704 siblingRules.appendVector(other.siblingRules); 728 siblingRules.appendVector(other.siblingRules);
705 uncommonAttributeRules.appendVector(other.uncommonAttributeRules); 729 uncommonAttributeRules.appendVector(other.uncommonAttributeRules);
706 } 730 }
707 731
708 void RuleFeatureSet::clear() 732 void RuleFeatureSet::clear()
709 { 733 {
710 siblingRules.clear(); 734 siblingRules.clear();
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after
860 invalidationLists.siblings.append(m_universalSiblingInvalidationSet); 884 invalidationLists.siblings.append(m_universalSiblingInvalidationSet);
861 } 885 }
862 886
863 SiblingInvalidationSet& RuleFeatureSet::ensureUniversalSiblingInvalidationSet() 887 SiblingInvalidationSet& RuleFeatureSet::ensureUniversalSiblingInvalidationSet()
864 { 888 {
865 if (!m_universalSiblingInvalidationSet) 889 if (!m_universalSiblingInvalidationSet)
866 m_universalSiblingInvalidationSet = SiblingInvalidationSet::create(nullp tr); 890 m_universalSiblingInvalidationSet = SiblingInvalidationSet::create(nullp tr);
867 return *m_universalSiblingInvalidationSet; 891 return *m_universalSiblingInvalidationSet;
868 } 892 }
869 893
894 void RuleFeatureSet::collectNthInvalidationSet(InvalidationLists& invalidationLi sts) const
895 {
896 if (m_nthInvalidationSet)
897 invalidationLists.descendants.append(m_nthInvalidationSet);
898 }
899
900 DescendantInvalidationSet& RuleFeatureSet::ensureNthInvalidationSet()
901 {
902 if (!m_nthInvalidationSet)
903 m_nthInvalidationSet = DescendantInvalidationSet::create();
904 return *m_nthInvalidationSet;
905 }
906
870 void RuleFeatureSet::addFeaturesToUniversalSiblingInvalidationSet(const Invalida tionSetFeatures& siblingFeatures, const InvalidationSetFeatures& descendantFeatu res) 907 void RuleFeatureSet::addFeaturesToUniversalSiblingInvalidationSet(const Invalida tionSetFeatures& siblingFeatures, const InvalidationSetFeatures& descendantFeatu res)
871 { 908 {
872 SiblingInvalidationSet& universalSet = ensureUniversalSiblingInvalidationSet (); 909 SiblingInvalidationSet& universalSet = ensureUniversalSiblingInvalidationSet ();
873 addFeaturesToInvalidationSet(universalSet, siblingFeatures); 910 addFeaturesToInvalidationSet(universalSet, siblingFeatures);
874 universalSet.updateMaxDirectAdjacentSelectors(siblingFeatures.maxDirectAdjac entSelectors); 911 universalSet.updateMaxDirectAdjacentSelectors(siblingFeatures.maxDirectAdjac entSelectors);
875 912
876 if (&siblingFeatures == &descendantFeatures) 913 if (&siblingFeatures == &descendantFeatures)
877 universalSet.setInvalidatesSelf(); 914 universalSet.setInvalidatesSelf();
878 else 915 else
879 addFeaturesToInvalidationSet(universalSet.ensureSiblingDescendants(), de scendantFeatures); 916 addFeaturesToInvalidationSet(universalSet.ensureSiblingDescendants(), de scendantFeatures);
880 } 917 }
881 918
882 DEFINE_TRACE(RuleFeatureSet) 919 DEFINE_TRACE(RuleFeatureSet)
883 { 920 {
884 visitor->trace(siblingRules); 921 visitor->trace(siblingRules);
885 visitor->trace(uncommonAttributeRules); 922 visitor->trace(uncommonAttributeRules);
886 } 923 }
887 924
888 } // namespace blink 925 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698