Merge style_affecting_attributes_selectors with selectors_for_cache_revalidation.

This commit is contained in:
Bobby Holley 2017-04-11 14:06:11 +08:00
parent 6515f78f6d
commit d51d95d0c7
3 changed files with 8 additions and 83 deletions

View file

@ -95,12 +95,9 @@ pub enum CacheMiss {
Class, Class,
/// The presentation hints didn't match. /// The presentation hints didn't match.
PresHints, PresHints,
/// The element and the candidate didn't match the same set of /// The element and the candidate didn't match the same set of revalidation
/// sibling-affecting rules. /// selectors.
SiblingRules, Revalidation,
/// The element and the candidate didn't match the same set of style
/// affecting attribute selectors.
AttrRules,
} }
fn element_matches_candidate<E: TElement>(element: &E, fn element_matches_candidate<E: TElement>(element: &E,
@ -155,13 +152,7 @@ fn element_matches_candidate<E: TElement>(element: &E,
} }
if !revalidate(element, candidate_element, shared_context) { if !revalidate(element, candidate_element, shared_context) {
miss!(SiblingRules) miss!(Revalidation)
}
if !match_same_style_affecting_attributes_rules(element,
candidate_element,
shared_context) {
miss!(AttrRules)
} }
let data = candidate_element.borrow_data().unwrap(); let data = candidate_element.borrow_data().unwrap();
@ -201,14 +192,6 @@ fn have_same_class<E: TElement>(element: &E,
element_class_attributes == *candidate.class_attributes.as_ref().unwrap() element_class_attributes == *candidate.class_attributes.as_ref().unwrap()
} }
// TODO: These re-match the candidate every time, which is suboptimal.
#[inline]
fn match_same_style_affecting_attributes_rules<E: TElement>(element: &E,
candidate: &E,
ctx: &SharedStyleContext) -> bool {
ctx.stylist.match_same_style_affecting_attributes_rules(element, candidate)
}
#[inline] #[inline]
fn revalidate<E: TElement>(element: &E, fn revalidate<E: TElement>(element: &E,
candidate: &E, candidate: &E,
@ -1031,8 +1014,7 @@ pub trait MatchMethods : TElement {
// Too expensive failure, give up, we don't want another // Too expensive failure, give up, we don't want another
// one of these. // one of these.
CacheMiss::PresHints | CacheMiss::PresHints |
CacheMiss::SiblingRules | CacheMiss::Revalidation => break,
CacheMiss::AttrRules => break,
_ => {} _ => {}
} }
} }

View file

@ -490,7 +490,6 @@ struct Dependency {
pub struct SelectorDependencyVisitor<'a> { pub struct SelectorDependencyVisitor<'a> {
dependency_set: &'a mut DependencySet, dependency_set: &'a mut DependencySet,
needs_cache_revalidation: bool, needs_cache_revalidation: bool,
affected_by_attribute: bool,
} }
impl<'a> SelectorDependencyVisitor<'a> { impl<'a> SelectorDependencyVisitor<'a> {
@ -499,7 +498,6 @@ impl<'a> SelectorDependencyVisitor<'a> {
SelectorDependencyVisitor { SelectorDependencyVisitor {
dependency_set: dependency_set, dependency_set: dependency_set,
needs_cache_revalidation: false, needs_cache_revalidation: false,
affected_by_attribute: false,
} }
} }
@ -508,12 +506,6 @@ impl<'a> SelectorDependencyVisitor<'a> {
pub fn needs_cache_revalidation(&self) -> bool { pub fn needs_cache_revalidation(&self) -> bool {
self.needs_cache_revalidation self.needs_cache_revalidation
} }
/// Returns whether this visitor has known of a attribute-dependent
/// selector.
pub fn affected_by_attribute(&self) -> bool {
self.affected_by_attribute
}
} }
impl<'a> SelectorVisitor for SelectorDependencyVisitor<'a> { impl<'a> SelectorVisitor for SelectorDependencyVisitor<'a> {
@ -537,7 +529,7 @@ impl<'a> SelectorVisitor for SelectorDependencyVisitor<'a> {
let hint = combinator_to_restyle_hint(combinator); let hint = combinator_to_restyle_hint(combinator);
self.affected_by_attribute |= sensitivities.attrs; self.needs_cache_revalidation |= sensitivities.attrs;
self.needs_cache_revalidation |= hint.intersects(RESTYLE_LATER_SIBLINGS); self.needs_cache_revalidation |= hint.intersects(RESTYLE_LATER_SIBLINGS);
if !sensitivities.is_empty() { if !sensitivities.is_empty() {

View file

@ -112,14 +112,10 @@ pub struct Stylist {
state_deps: DependencySet, state_deps: DependencySet,
/// Selectors that require explicit cache revalidation (i.e. which depend /// Selectors that require explicit cache revalidation (i.e. which depend
/// on state that is not otherwise visible to the cache, like child index). /// on state that is not otherwise visible to the cache, like attributes or
/// tree-structural state like child index and pseudos).
#[cfg_attr(feature = "servo", ignore_heap_size_of = "Arc")] #[cfg_attr(feature = "servo", ignore_heap_size_of = "Arc")]
selectors_for_cache_revalidation: Vec<Selector<SelectorImpl>>, selectors_for_cache_revalidation: Vec<Selector<SelectorImpl>>,
/// Selectors in the page matching elements with non-common style-affecting
/// attributes.
#[cfg_attr(feature = "servo", ignore_heap_size_of = "Arc")]
style_affecting_attributes_selectors: Vec<Selector<SelectorImpl>>,
} }
/// This struct holds data which user of Stylist may want to extract /// This struct holds data which user of Stylist may want to extract
@ -172,7 +168,6 @@ impl Stylist {
state_deps: DependencySet::new(), state_deps: DependencySet::new(),
selectors_for_cache_revalidation: vec![], selectors_for_cache_revalidation: vec![],
style_affecting_attributes_selectors: vec![]
}; };
SelectorImpl::each_eagerly_cascaded_pseudo_element(|pseudo| { SelectorImpl::each_eagerly_cascaded_pseudo_element(|pseudo| {
@ -227,7 +222,6 @@ impl Stylist {
self.animations.clear(); self.animations.clear();
self.selectors_for_cache_revalidation.clear(); self.selectors_for_cache_revalidation.clear();
self.style_affecting_attributes_selectors.clear();
extra_data.clear_font_faces(); extra_data.clear_font_faces();
@ -249,8 +243,6 @@ impl Stylist {
debug!("Stylist stats:"); debug!("Stylist stats:");
debug!(" - Got {} selectors for cache revalidation", debug!(" - Got {} selectors for cache revalidation",
self.selectors_for_cache_revalidation.len()); self.selectors_for_cache_revalidation.len());
debug!(" - Got {} non-common-style-attribute-affecting selectors",
self.style_affecting_attributes_selectors.len());
debug!(" - Got {} deps for style-hint calculation", debug!(" - Got {} deps for style-hint calculation",
self.state_deps.len()); self.state_deps.len());
@ -308,10 +300,6 @@ impl Stylist {
if visitor.needs_cache_revalidation() { if visitor.needs_cache_revalidation() {
self.selectors_for_cache_revalidation.push(selector.clone()); self.selectors_for_cache_revalidation.push(selector.clone());
} }
if visitor.affected_by_attribute() {
self.style_affecting_attributes_selectors.push(selector.clone());
}
} }
} }
CssRule::Import(ref import) => { CssRule::Import(ref import) => {
@ -771,43 +759,6 @@ impl Stylist {
&self.animations &self.animations
} }
/// Whether two elements match the same not-common style-affecting attribute
/// rules.
///
/// This is used to test elements and candidates in the style-sharing
/// candidate cache.
pub fn match_same_style_affecting_attributes_rules<E>(&self,
element: &E,
candidate: &E) -> bool
where E: TElement,
{
use selectors::matching::StyleRelations;
use selectors::matching::matches_complex_selector;
// TODO(emilio): we can probably do better, the candidate should already
// know what rules it matches. Also, we should only match until we find
// a descendant combinator, the rest should be ok, since the parent is
// the same.
//
// TODO(emilio): Use the bloom filter, since they contain the element's
// ancestor chain and it's correct for the candidate too.
for ref selector in self.style_affecting_attributes_selectors.iter() {
let element_matches =
matches_complex_selector(&selector.complex_selector, element,
None, &mut StyleRelations::empty(),
&mut |_, _| {});
let candidate_matches =
matches_complex_selector(&selector.complex_selector, candidate,
None, &mut StyleRelations::empty(),
&mut |_, _| {});
if element_matches != candidate_matches {
return false;
}
}
true
}
/// Returns the rule root node. /// Returns the rule root node.
#[inline] #[inline]
pub fn rule_tree_root(&self) -> StrongRuleNode { pub fn rule_tree_root(&self) -> StrongRuleNode {