From a46f0c3b24d141ced34055f6e6fb70da85fa313c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Thu, 11 Aug 2016 16:44:21 -0700 Subject: [PATCH] Lazily compute common style affecting attribute info. --- components/style/cache.rs | 8 ++++++-- components/style/matching.rs | 34 ++++++++++++++++++++-------------- 2 files changed, 26 insertions(+), 16 deletions(-) diff --git a/components/style/cache.rs b/components/style/cache.rs index e15c99eea2c..9fb3f5b27f6 100644 --- a/components/style/cache.rs +++ b/components/style/cache.rs @@ -7,7 +7,7 @@ use rand; use rand::Rng; use std::hash::{Hash, Hasher, SipHasher}; -use std::slice::Iter; +use std::slice::{Iter, IterMut}; pub struct LRUCache { entries: Vec<(K, V)>, @@ -17,7 +17,7 @@ pub struct LRUCache { impl LRUCache { pub fn new(size: usize) -> LRUCache { LRUCache { - entries: vec!(), + entries: vec![], cache_size: size, } } @@ -36,6 +36,10 @@ impl LRUCache { self.entries.iter() } + pub fn iter_mut(&mut self) -> IterMut<(K, V)> { + self.entries.iter_mut() + } + pub fn insert(&mut self, key: K, val: V) { if self.entries.len() == self.cache_size { self.entries.remove(0); diff --git a/components/style/matching.rs b/components/style/matching.rs index ae1253a94bf..cb1f70602ad 100644 --- a/components/style/matching.rs +++ b/components/style/matching.rs @@ -24,7 +24,7 @@ use sink::ForgetfulSink; use smallvec::SmallVec; use std::collections::HashMap; use std::hash::{BuildHasherDefault, Hash, Hasher}; -use std::slice::Iter; +use std::slice::IterMut; use std::sync::Arc; use string_cache::Atom; use traversal::RestyleResult; @@ -188,7 +188,7 @@ struct StyleSharingCandidate { /// The cached computed style, here for convenience. style: Arc, /// The cached common style affecting attribute info. - common_style_affecting_attributes: CommonStyleAffectingAttributes, + common_style_affecting_attributes: Option, } impl PartialEq for StyleSharingCandidate { @@ -230,7 +230,7 @@ pub enum CacheMiss { } fn element_matches_candidate(element: &E, - candidate: &StyleSharingCandidate, + candidate: &mut StyleSharingCandidate, candidate_element: &E, shared_context: &SharedStyleContext) -> Result, CacheMiss> { @@ -272,7 +272,9 @@ fn element_matches_candidate(element: &E, miss!(Class) } - if !have_same_common_style_affecting_attributes(element, candidate) { + if !have_same_common_style_affecting_attributes(element, + candidate, + candidate_element) { miss!(CommonStyleAffectingAttributes) } @@ -296,11 +298,14 @@ fn element_matches_candidate(element: &E, } fn have_same_common_style_affecting_attributes(element: &E, - candidate: &StyleSharingCandidate) -> bool { - // XXX probably could do something smarter. Also, the cache should - // precompute this for the parent. Just experimenting now though. + candidate: &mut StyleSharingCandidate, + candidate_element: &E) -> bool { + if candidate.common_style_affecting_attributes.is_none() { + candidate.common_style_affecting_attributes = + Some(create_common_style_affecting_attributes_from_element(candidate_element)) + } create_common_style_affecting_attributes_from_element(element) == - candidate.common_style_affecting_attributes + candidate.common_style_affecting_attributes.unwrap() } fn have_same_presentational_hints(element: &E, candidate: &E) -> bool { @@ -406,8 +411,8 @@ impl StyleSharingCandidateCache { } } - fn iter(&self) -> Iter<(StyleSharingCandidate, ())> { - self.cache.iter() + fn iter_mut(&mut self) -> IterMut<(StyleSharingCandidate, ())> { + self.cache.iter_mut() } pub fn insert_if_possible(&mut self, @@ -451,8 +456,7 @@ impl StyleSharingCandidateCache { self.cache.insert(StyleSharingCandidate { node: node.to_unsafe(), style: style.clone(), - common_style_affecting_attributes: - create_common_style_affecting_attributes_from_element(element), + common_style_affecting_attributes: None, }, ()); } @@ -620,7 +624,7 @@ trait PrivateElementMatchMethods: TElement { fn share_style_with_candidate_if_possible(&self, parent_node: Self::ConcreteNode, shared_context: &SharedStyleContext, - candidate: &StyleSharingCandidate) + candidate: &mut StyleSharingCandidate) -> Result, CacheMiss> { debug_assert!(parent_node.is_element()); @@ -697,7 +701,7 @@ pub trait ElementMatchMethods : TElement { _ => return StyleSharingResult::CannotShare, }; - for (i, &(ref candidate, ())) in style_sharing_candidate_cache.iter().enumerate() { + for (i, &mut (ref mut candidate, ())) in style_sharing_candidate_cache.iter_mut().enumerate() { let sharing_result = self.share_style_with_candidate_if_possible(parent, shared_context, candidate); @@ -734,6 +738,8 @@ pub trait ElementMatchMethods : TElement { return StyleSharingResult::StyleWasShared(i, damage, restyle_result) } Err(miss) => { + debug!("Cache miss: {:?}", miss); + // Cache miss, let's see what kind of failure to decide // whether we keep trying or not. match miss {