Bug 1420741 - style: Require an nth-index cache for invalidation. r=xidorn, a=gchang DEVEDITION_58_0b9_RELEASE FENNEC_58_0b9_BUILD1 FENNEC_58_0b9_RELEASE FIREFOX_58_0b9_BUILD1 FIREFOX_58_0b9_RELEASE
authorEmilio Cobos Álvarez <emilio@crisal.io>
Wed, 29 Nov 2017 16:36:48 -0600
changeset 709871 671706994162518e80a4b9f8125ff8e8c1bc3b1f
parent 709870 8340a945b6e35291dcf308bc4488596a58152d31
child 709872 f37b9d1303f0dec7a3255ede430aa28277dd0efe
push id92737
push userbmo:csadilek@mozilla.com
push dateFri, 08 Dec 2017 17:39:52 +0000
reviewersxidorn, gchang
bugs1420741
milestone58.0
Bug 1420741 - style: Require an nth-index cache for invalidation. r=xidorn, a=gchang Source-Repo: https://github.com/servo/servo Source-Revision: 95aac490a5150fd1a354f25c61b01ee0406a1e84
servo/components/style/data.rs
servo/components/style/invalidation/element/collector.rs
servo/components/style/traversal.rs
servo/ports/geckolib/glue.rs
--- a/servo/components/style/data.rs
+++ b/servo/components/style/data.rs
@@ -233,17 +233,17 @@ impl ElementData {
     /// Invalidates style for this element, its descendants, and later siblings,
     /// based on the snapshot of the element that we took when attributes or
     /// state changed.
     pub fn invalidate_style_if_needed<'a, E: TElement>(
         &mut self,
         element: E,
         shared_context: &SharedStyleContext,
         stack_limit_checker: Option<&StackLimitChecker>,
-        nth_index_cache: Option<&mut NthIndexCache>,
+        nth_index_cache: &mut NthIndexCache,
     ) -> InvalidationResult {
         // In animation-only restyle we shouldn't touch snapshot at all.
         if shared_context.traversal_flags.for_animation_only() {
             return InvalidationResult::empty();
         }
 
         use invalidation::element::collector::StateAndAttrInvalidationProcessor;
         use invalidation::element::invalidator::TreeStyleInvalidator;
--- a/servo/components/style/invalidation/element/collector.rs
+++ b/servo/components/style/invalidation/element/collector.rs
@@ -66,22 +66,22 @@ pub struct StateAndAttrInvalidationProce
 impl<'a, 'b: 'a, E: TElement> StateAndAttrInvalidationProcessor<'a, 'b, E> {
     /// Creates a new StateAndAttrInvalidationProcessor.
     pub fn new(
         shared_context: &'a SharedStyleContext<'b>,
         xbl_stylists: &'a [AtomicRef<'b, Stylist>],
         cut_off_inheritance: bool,
         element: E,
         data: &'a mut ElementData,
-        nth_index_cache: Option<&'a mut NthIndexCache>,
+        nth_index_cache: &'a mut NthIndexCache,
     ) -> Self {
         let matching_context = MatchingContext::new_for_visited(
             MatchingMode::Normal,
             None,
-            nth_index_cache,
+            Some(nth_index_cache),
             VisitedHandlingMode::AllLinksVisitedAndUnvisited,
             shared_context.quirks_mode(),
         );
 
         Self {
             shared_context,
             xbl_stylists,
             cut_off_inheritance,
--- a/servo/components/style/traversal.rs
+++ b/servo/components/style/traversal.rs
@@ -5,16 +5,17 @@
 //! Traversing the DOM tree; the bloom filter.
 
 use context::{ElementCascadeInputs, StyleContext, SharedStyleContext};
 use data::{ElementData, ElementStyles};
 use dom::{NodeInfo, OpaqueNode, TElement, TNode};
 use invalidation::element::restyle_hints::RestyleHint;
 use matching::{ChildCascadeRequirement, MatchMethods};
 use selector_parser::PseudoElement;
+use selectors::NthIndexCache;
 use sharing::StyleSharingTarget;
 use smallvec::SmallVec;
 use style_resolver::{PseudoElementResolution, StyleResolverForElement};
 use stylist::RuleInclusion;
 use traversal_flags::TraversalFlags;
 
 /// A per-traversal-level chunk of data. This is sent down by the traversal, and
 /// currently only holds the dom depth for the bloom filter.
@@ -164,21 +165,22 @@ pub trait DomTraversal<E: TElement> : Sy
             //
             // From the perspective of this traversal, the root cannot have
             // reconstructed ancestors.
             data.set_reconstructed_ancestor(false);
 
             if !traversal_flags.for_animation_only() {
                 // Invalidate our style, and that of our siblings and
                 // descendants as needed.
-                //
-                // FIXME(emilio): an nth-index cache could be worth here, even
-                // if temporary?
-                let invalidation_result =
-                    data.invalidate_style_if_needed(root, shared_context, None, None);
+                let invalidation_result = data.invalidate_style_if_needed(
+                    root,
+                    shared_context,
+                    None,
+                    &mut NthIndexCache::default(),
+                );
 
                 if invalidation_result.has_invalidated_siblings() {
                     let actual_root =
                         parent.expect("How in the world can you invalidate \
                                        siblings without a parent?");
                     unsafe { actual_root.set_dirty_descendants() }
                     return PreTraverseToken(Some(actual_root));
                 }
@@ -892,17 +894,17 @@ where
             // Handle element snapshots and invalidation of descendants and siblings
             // as needed.
             //
             // NB: This will be a no-op if there's no snapshot.
             child_data.invalidate_style_if_needed(
                 child,
                 &context.shared,
                 Some(&context.thread_local.stack_limit_checker),
-                Some(&mut context.thread_local.nth_index_cache)
+                &mut context.thread_local.nth_index_cache,
             );
         }
 
         if D::element_needs_traversal(child, flags, child_data.map(|d| &*d), Some(data)) {
             note_child(child_node);
 
             // Set the dirty descendants bit on the parent as needed, so that we
             // can find elements during the post-traversal.
--- a/servo/ports/geckolib/glue.rs
+++ b/servo/ports/geckolib/glue.rs
@@ -1,17 +1,17 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 use cssparser::{Parser, ParserInput};
 use cssparser::ToCss as ParserToCss;
 use env_logger::LogBuilder;
 use malloc_size_of::MallocSizeOfOps;
-use selectors::Element;
+use selectors::{Element, NthIndexCache};
 use selectors::matching::{MatchingContext, MatchingMode, matches_selector};
 use servo_arc::{Arc, ArcBorrow, RawOffsetArc};
 use std::cell::RefCell;
 use std::env;
 use std::fmt::Write;
 use std::iter;
 use std::mem;
 use std::ptr;
@@ -4451,25 +4451,23 @@ pub extern "C" fn Servo_ProcessInvalidat
     let shared_style_context = create_shared_context(&global_style_data,
                                                      &guard,
                                                      &per_doc_data,
                                                      TraversalFlags::empty(),
                                                      unsafe { &*snapshots });
     let mut data = data.as_mut().map(|d| &mut **d);
 
     if let Some(ref mut data) = data {
-        // FIXME(emilio): an nth-index cache could be worth here, even
-        // if temporary?
-        //
-        // Also, ideally we could share them across all the elements?
+        // FIXME(emilio): Ideally we could share the nth-index-cache across all
+        // the elements?
         let result = data.invalidate_style_if_needed(
             element,
             &shared_style_context,
             None,
-            None,
+            &mut NthIndexCache::default(),
         );
 
         if result.has_invalidated_siblings() {
             let parent = element.traversal_parent().expect("How could we invalidate siblings without a common parent?");
             unsafe {
                 parent.set_dirty_descendants();
                 bindings::Gecko_NoteDirtySubtreeForInvalidation(parent.0);
             }