From 16937ba7cd71fa3b7b184ff56a7598ca3e12a97d Mon Sep 17 00:00:00 2001 From: Cameron McCormack Date: Wed, 9 Aug 2017 10:43:07 +0800 Subject: [PATCH] style: Move invalidation map into PerOriginCascadeData. --- components/style/context.rs | 2 +- .../invalidation/element/invalidation_map.rs | 3 +- .../style/invalidation/element/invalidator.rs | 12 +++---- components/style/stylist.rs | 34 ++++++++++++++----- 4 files changed, 34 insertions(+), 17 deletions(-) diff --git a/components/style/context.rs b/components/style/context.rs index ee1057fc735..4ee4f3b3959 100644 --- a/components/style/context.rs +++ b/components/style/context.rs @@ -394,7 +394,7 @@ impl TraversalStatistics { self.traversal_time_ms = (time::precise_time_s() - start) * 1000.0; self.selectors = stylist.num_selectors() as u32; self.revalidation_selectors = stylist.num_revalidation_selectors() as u32; - self.dependency_selectors = stylist.invalidation_map().len() as u32; + self.dependency_selectors = stylist.num_invalidations() as u32; self.declarations = stylist.num_declarations() as u32; self.stylist_rebuilds = stylist.num_rebuilds() as u32; } diff --git a/components/style/invalidation/element/invalidation_map.rs b/components/style/invalidation/element/invalidation_map.rs index e5c6c63bfce..81f966a5df3 100644 --- a/components/style/invalidation/element/invalidation_map.rs +++ b/components/style/invalidation/element/invalidation_map.rs @@ -109,7 +109,7 @@ impl SelectorMapEntry for Dependency { /// The same, but for state selectors, which can track more exactly what state /// do they track. -#[derive(Clone)] +#[derive(Clone, Debug)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] pub struct StateDependency { /// The other dependency fields. @@ -132,6 +132,7 @@ impl SelectorMapEntry for StateDependency { /// In particular, we want to lookup as few things as possible to get the fewer /// selectors the better, so this looks up by id, class, or looks at the list of /// state/other attribute affecting selectors. +#[derive(Debug)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] pub struct InvalidationMap { /// A map from a given class name to all the selectors with that class diff --git a/components/style/invalidation/element/invalidator.rs b/components/style/invalidation/element/invalidator.rs index 055e3e6f3ac..46b1d53bc1d 100644 --- a/components/style/invalidation/element/invalidator.rs +++ b/components/style/invalidation/element/invalidator.rs @@ -213,9 +213,9 @@ impl<'a, 'b: 'a, E> TreeStyleInvalidator<'a, 'b, E> invalidates_self: false, }; - collector.collect_dependencies_in_invalidation_map( - shared_context.stylist.invalidation_map(), - ); + shared_context.stylist.each_invalidation_map(|invalidation_map| { + collector.collect_dependencies_in_invalidation_map(invalidation_map); + }); // TODO(emilio): Consider storing dependencies from the UA sheet in // a different map. If we do that, we can skip the stuff on the @@ -223,9 +223,9 @@ impl<'a, 'b: 'a, E> TreeStyleInvalidator<'a, 'b, E> // just at that map. let _cut_off_inheritance = self.element.each_xbl_stylist(|stylist| { - collector.collect_dependencies_in_invalidation_map( - stylist.invalidation_map(), - ); + stylist.each_invalidation_map(|invalidation_map| { + collector.collect_dependencies_in_invalidation_map(invalidation_map); + }); }); collector.invalidates_self diff --git a/components/style/stylist.rs b/components/style/stylist.rs index 9b3aaedc8f4..cf4df1f5a55 100644 --- a/components/style/stylist.rs +++ b/components/style/stylist.rs @@ -108,9 +108,6 @@ pub struct Stylist { /// style rule appears in a stylesheet, needed to sort them by source order. rules_source_order: u32, - /// The invalidation map for this document. - invalidation_map: InvalidationMap, - /// The attribute local names that appear in attribute selectors. Used /// to avoid taking element snapshots when an irrelevant attribute changes. /// (We don't bother storing the namespace, since namespaced attributes @@ -235,7 +232,6 @@ impl Stylist { precomputed_pseudo_element_decls: PerPseudoElementMap::default(), rules_source_order: 0, rule_tree: RuleTree::new(), - invalidation_map: InvalidationMap::new(), attribute_dependencies: NonCountingBloomFilter::new(), style_attribute_dependency: false, state_dependencies: ElementState::empty(), @@ -269,9 +265,23 @@ impl Stylist { self.selectors_for_cache_revalidation.len() } - /// Gets a reference to the invalidation map. - pub fn invalidation_map(&self) -> &InvalidationMap { - &self.invalidation_map + /// Returns the number of entries in invalidation maps. + pub fn num_invalidations(&self) -> usize { + self.cascade_data.iter_origins() + .map(|d| d.invalidation_map.len()).sum() + } + + /// Invokes `f` with the `InvalidationMap` for each origin. + /// + /// NOTE(heycam) This might be better as an `iter_invalidation_maps`, once + /// we have `impl trait` and can return that easily without bothering to + /// create a whole new iterator type. + pub fn each_invalidation_map(&self, mut f: F) + where F: FnMut(&InvalidationMap) + { + for origin_cascade_data in self.cascade_data.iter_origins() { + f(&origin_cascade_data.invalidation_map) + } } /// Clear the stylist's state, effectively resetting it to more or less @@ -302,7 +312,6 @@ impl Stylist { self.precomputed_pseudo_element_decls.clear(); self.rules_source_order = 0; // We want to keep rule_tree around across stylist rebuilds. - self.invalidation_map.clear(); self.attribute_dependencies.clear(); self.style_attribute_dependency = false; self.state_dependencies = ElementState::empty(); @@ -497,7 +506,9 @@ impl Stylist { map.insert(rule, self.quirks_mode); - self.invalidation_map.note_selector(selector, self.quirks_mode); + origin_cascade_data + .invalidation_map + .note_selector(selector, self.quirks_mode); let mut visitor = StylistSelectorVisitor { needs_revalidation: false, passed_rightmost_selector: false, @@ -1670,6 +1681,9 @@ struct PerOriginCascadeData { /// A map with all the animations at this `CascadeData`'s origin, indexed /// by name. animations: PrecomputedHashMap, + + /// The invalidation map for the rules at this origin. + invalidation_map: InvalidationMap, } impl PerOriginCascadeData { @@ -1678,6 +1692,7 @@ impl PerOriginCascadeData { element_map: SelectorMap::new(), pseudos_map: PerPseudoElementMap::default(), animations: Default::default(), + invalidation_map: InvalidationMap::new(), } } @@ -1693,6 +1708,7 @@ impl PerOriginCascadeData { self.element_map = SelectorMap::new(); self.pseudos_map = Default::default(); self.animations = Default::default(); + self.invalidation_map.clear(); } fn has_rules_for_pseudo(&self, pseudo: &PseudoElement) -> bool {