Hoist style sharing cache handling to the top of compute_style.

This commit is contained in:
Bobby Holley 2017-02-08 12:55:10 -08:00
parent 095265affe
commit 1c530f9279

View file

@ -8,9 +8,9 @@
use atomic_refcell::{AtomicRefCell, AtomicRefMut}; use atomic_refcell::{AtomicRefCell, AtomicRefMut};
use context::{SharedStyleContext, StyleContext, ThreadLocalStyleContext}; use context::{SharedStyleContext, StyleContext, ThreadLocalStyleContext};
use data::{ElementData, ElementStyles, RestyleKind, StoredRestyleHint}; use data::{ElementData, ElementStyles, StoredRestyleHint};
use dom::{NodeInfo, TElement, TNode}; use dom::{NodeInfo, TElement, TNode};
use matching::{MatchMethods, StyleSharingResult}; use matching::MatchMethods;
use restyle_hints::{RESTYLE_DESCENDANTS, RESTYLE_SELF}; use restyle_hints::{RESTYLE_DESCENDANTS, RESTYLE_SELF};
use selector_parser::RestyleDamage; use selector_parser::RestyleDamage;
use servo_config::opts; use servo_config::opts;
@ -483,27 +483,31 @@ fn compute_style<E, D>(_traversal: &D,
where E: TElement, where E: TElement,
D: DomTraversal<E>, D: DomTraversal<E>,
{ {
use data::RestyleKind::*;
use matching::StyleSharingResult::*;
context.thread_local.statistics.elements_styled += 1; context.thread_local.statistics.elements_styled += 1;
let shared_context = context.shared; let shared_context = context.shared;
let kind = data.restyle_kind();
// First, try the style sharing cache. If we get a match we can skip the rest
// of the work.
if let MatchAndCascade = kind {
let sharing_result = unsafe {
let cache = &mut context.thread_local.style_sharing_candidate_cache;
element.share_style_if_possible(cache, shared_context, &mut data)
};
if let StyleWasShared(index) = sharing_result {
context.thread_local.statistics.styles_shared += 1;
context.thread_local.style_sharing_candidate_cache.touch(index);
return;
}
}
// TODO(emilio): Make cascade_input less expensive to compute in the cases // TODO(emilio): Make cascade_input less expensive to compute in the cases
// we don't need to run selector matching. // we don't need to run selector matching.
let cascade_input = match data.restyle_kind() { let match_results = match kind {
RestyleKind::MatchAndCascade => { MatchAndCascade => {
// Check to see whether we can share a style with someone.
let sharing_result = unsafe {
element.share_style_if_possible(&mut context.thread_local.style_sharing_candidate_cache,
shared_context,
&mut data)
};
match sharing_result {
StyleSharingResult::StyleWasShared(index) => {
context.thread_local.statistics.styles_shared += 1;
context.thread_local.style_sharing_candidate_cache.touch(index);
None
}
StyleSharingResult::CannotShare => {
// Ensure the bloom filter is up to date. // Ensure the bloom filter is up to date.
let dom_depth = let dom_depth =
context.thread_local.bloom_filter context.thread_local.bloom_filter
@ -521,21 +525,18 @@ fn compute_style<E, D>(_traversal: &D,
// Perform the CSS selector matching. // Perform the CSS selector matching.
context.thread_local.statistics.elements_matched += 1; context.thread_local.statistics.elements_matched += 1;
Some(element.match_element(context)) element.match_element(context)
} }
CascadeWithReplacements(hint) => {
element.cascade_with_replacements(hint, context, &mut data)
} }
} CascadeOnly => {
RestyleKind::CascadeWithReplacements(hint) => {
Some(element.cascade_with_replacements(hint, context, &mut data))
}
RestyleKind::CascadeOnly => {
// TODO(emilio): Stop doing this work, and teach cascade_node about // TODO(emilio): Stop doing this work, and teach cascade_node about
// the current style instead. // the current style instead.
Some(element.match_results_from_current_style(&*data)) element.match_results_from_current_style(&*data)
} }
}; };
if let Some(match_results) = cascade_input {
// Perform the CSS cascade. // Perform the CSS cascade.
let shareable = match_results.primary_is_shareable(); let shareable = match_results.primary_is_shareable();
unsafe { unsafe {
@ -555,7 +556,6 @@ fn compute_style<E, D>(_traversal: &D,
match_results.relations); match_results.relations);
} }
} }
}
fn preprocess_children<E, D>(traversal: &D, fn preprocess_children<E, D>(traversal: &D,
element: E, element: E,