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 context::{SharedStyleContext, StyleContext, ThreadLocalStyleContext};
use data::{ElementData, ElementStyles, RestyleKind, StoredRestyleHint};
use data::{ElementData, ElementStyles, StoredRestyleHint};
use dom::{NodeInfo, TElement, TNode};
use matching::{MatchMethods, StyleSharingResult};
use matching::MatchMethods;
use restyle_hints::{RESTYLE_DESCENDANTS, RESTYLE_SELF};
use selector_parser::RestyleDamage;
use servo_config::opts;
@ -483,77 +483,77 @@ fn compute_style<E, D>(_traversal: &D,
where E: TElement,
D: DomTraversal<E>,
{
use data::RestyleKind::*;
use matching::StyleSharingResult::*;
context.thread_local.statistics.elements_styled += 1;
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
// we don't need to run selector matching.
let cascade_input = match data.restyle_kind() {
RestyleKind::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)
};
let match_results = match kind {
MatchAndCascade => {
// Ensure the bloom filter is up to date.
let dom_depth =
context.thread_local.bloom_filter
.insert_parents_recovering(element,
traversal_data.current_dom_depth);
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.
let dom_depth =
context.thread_local.bloom_filter
.insert_parents_recovering(element,
traversal_data.current_dom_depth);
// Update the dom depth with the up-to-date dom depth.
//
// Note that this is always the same than the pre-existing depth,
// but it can change from unknown to known at this step.
traversal_data.current_dom_depth = Some(dom_depth);
// Update the dom depth with the up-to-date dom depth.
//
// Note that this is always the same than the pre-existing depth,
// but it can change from unknown to known at this step.
traversal_data.current_dom_depth = Some(dom_depth);
context.thread_local.bloom_filter.assert_complete(element);
context.thread_local.bloom_filter.assert_complete(element);
// Perform the CSS selector matching.
context.thread_local.statistics.elements_matched += 1;
// Perform the CSS selector matching.
context.thread_local.statistics.elements_matched += 1;
Some(element.match_element(context))
}
}
element.match_element(context)
}
RestyleKind::CascadeWithReplacements(hint) => {
Some(element.cascade_with_replacements(hint, context, &mut data))
CascadeWithReplacements(hint) => {
element.cascade_with_replacements(hint, context, &mut data)
}
RestyleKind::CascadeOnly => {
CascadeOnly => {
// TODO(emilio): Stop doing this work, and teach cascade_node about
// 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.
let shareable = match_results.primary_is_shareable();
unsafe {
element.cascade_node(context, &mut data,
element.parent_element(),
match_results.primary,
match_results.per_pseudo,
shareable);
}
// Perform the CSS cascade.
let shareable = match_results.primary_is_shareable();
unsafe {
element.cascade_node(context, &mut data,
element.parent_element(),
match_results.primary,
match_results.per_pseudo,
shareable);
}
if shareable {
// Add ourselves to the LRU cache.
context.thread_local
.style_sharing_candidate_cache
.insert_if_possible(&element,
&data.styles().primary.values,
match_results.relations);
}
if shareable {
// Add ourselves to the LRU cache.
context.thread_local
.style_sharing_candidate_cache
.insert_if_possible(&element,
&data.styles().primary.values,
match_results.relations);
}
}