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

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

Powered by Google App Engine
This is Rietveld 408576698