Auto merge of #17713 - emilio:less-code-is-lovely, r=heycam

style: Kill some style sharing code.

It's trivial to do so after #17688.

<!-- Reviewable:start -->
---
This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/17713)
<!-- Reviewable:end -->
This commit is contained in:
bors-servo 2017-07-14 00:25:37 -07:00 committed by GitHub
commit 1c85c55d02
5 changed files with 53 additions and 204 deletions

View file

@ -21,7 +21,7 @@ use rule_tree::StrongRuleNode;
use selector_parser::{EAGER_PSEUDO_COUNT, SnapshotMap};
use selectors::matching::ElementSelectorFlags;
use shared_lock::StylesheetGuards;
use sharing::{ValidationData, StyleSharingCandidateCache};
use sharing::StyleSharingCandidateCache;
use std::fmt;
use std::ops::Add;
#[cfg(feature = "servo")] use std::sync::Mutex;
@ -269,8 +269,6 @@ pub struct CurrentElementInfo {
element: OpaqueNode,
/// Whether the element is being styled for the first time.
is_initial_style: bool,
/// Lazy cache of the different data used for style sharing.
pub validation_data: ValidationData,
/// A Vec of possibly expired animations. Used only by Servo.
#[allow(dead_code)]
pub possibly_expired_animations: Vec<PropertyAnimation>,
@ -575,7 +573,6 @@ impl<E: TElement> ThreadLocalStyleContext<E> {
self.current_element_info = Some(CurrentElementInfo {
element: element.as_node().opaque(),
is_initial_style: !data.has_styles(),
validation_data: ValidationData::default(),
possibly_expired_animations: Vec::new(),
});
}

View file

@ -4,7 +4,6 @@
//! Per-node data used in style calculation.
use arrayvec::ArrayVec;
use context::SharedStyleContext;
use dom::TElement;
use invalidation::element::restyle_hints::RestyleHint;
@ -157,20 +156,6 @@ impl EagerPseudoStyles {
self.0.as_ref().and_then(|p| p[pseudo.eager_index()].as_ref())
}
/// Returns a mutable reference to the style for a given eager pseudo, if it exists.
pub fn get_mut(&mut self, pseudo: &PseudoElement) -> Option<&mut Arc<ComputedValues>> {
debug_assert!(pseudo.is_eager());
match self.0 {
None => return None,
Some(ref mut arc) => Arc::make_mut(arc)[pseudo.eager_index()].as_mut(),
}
}
/// Returns true if the EagerPseudoStyles has the style for |pseudo|.
pub fn has(&self, pseudo: &PseudoElement) -> bool {
self.get(pseudo).is_some()
}
/// Sets the style for the eager pseudo.
pub fn set(&mut self, pseudo: &PseudoElement, value: Arc<ComputedValues>) {
if self.0.is_none() {
@ -179,57 +164,6 @@ impl EagerPseudoStyles {
let arr = Arc::make_mut(self.0.as_mut().unwrap());
arr[pseudo.eager_index()] = Some(value);
}
/// Inserts a pseudo-element. The pseudo-element must not already exist.
pub fn insert(&mut self, pseudo: &PseudoElement, value: Arc<ComputedValues>) {
debug_assert!(!self.has(pseudo));
self.set(pseudo, value);
}
/// Removes a pseudo-element style if it exists, and returns it.
pub fn take(&mut self, pseudo: &PseudoElement) -> Option<Arc<ComputedValues>> {
let result = match self.0 {
None => return None,
Some(ref mut arc) => Arc::make_mut(arc)[pseudo.eager_index()].take(),
};
let empty = self.0.as_ref().unwrap().iter().all(|x| x.is_none());
if empty {
self.0 = None;
}
result
}
/// Returns a list of the pseudo-elements.
pub fn keys(&self) -> ArrayVec<[PseudoElement; EAGER_PSEUDO_COUNT]> {
let mut v = ArrayVec::new();
if let Some(ref arr) = self.0 {
for i in 0..EAGER_PSEUDO_COUNT {
if arr[i].is_some() {
v.push(PseudoElement::from_eager_index(i));
}
}
}
v
}
/// Returns whether this map has the same set of pseudos as the given one.
pub fn has_same_pseudos_as(&self, other: &Self) -> bool {
// We could probably just compare self.keys() to other.keys(), but that
// seems like it'll involve a bunch more moving stuff around and
// whatnot.
match (&self.0, &other.0) {
(&Some(ref our_arr), &Some(ref other_arr)) => {
for i in 0..EAGER_PSEUDO_COUNT {
if our_arr[i].is_some() != other_arr[i].is_some() {
return false
}
}
true
},
(&None, &None) => true,
_ => false,
}
}
}
/// The styles associated with a node, including the styles for any
@ -248,11 +182,6 @@ impl ElementStyles {
self.primary.as_ref()
}
/// Returns the mutable primary style.
pub fn get_primary_mut(&mut self) -> Option<&mut Arc<ComputedValues>> {
self.primary.as_mut()
}
/// Returns the primary style. Panic if no style available.
pub fn primary(&self) -> &Arc<ComputedValues> {
self.primary.as_ref().unwrap()

View file

@ -70,11 +70,10 @@ use bit_vec::BitVec;
use bloom::StyleBloom;
use cache::{LRUCache, LRUCacheMutIterator};
use context::{SelectorFlagsMap, SharedStyleContext, StyleContext};
use data::{ElementData, ElementStyles};
use data::ElementStyles;
use dom::{TElement, SendElement};
use matching::{ChildCascadeRequirement, MatchMethods};
use matching::MatchMethods;
use properties::ComputedValues;
use selector_parser::RestyleDamage;
use selectors::matching::{ElementSelectorFlags, VisitedHandlingMode};
use smallvec::SmallVec;
use std::mem;
@ -329,11 +328,9 @@ impl<E: TElement> StyleSharingTarget<E> {
/// Attempts to share a style with another node.
pub fn share_style_if_possible(
mut self,
&mut self,
context: &mut StyleContext<E>,
data: &mut ElementData)
-> StyleSharingResult
{
) -> StyleSharingResult {
let cache = &mut context.thread_local.style_sharing_candidate_cache;
let shared_context = &context.shared;
let selector_flags_map = &mut context.thread_local.selector_flags;
@ -347,70 +344,17 @@ impl<E: TElement> StyleSharingTarget<E> {
debug_assert_eq!(bloom_filter.current_parent(),
self.element.traversal_parent());
let result = cache
.share_style_if_possible(shared_context,
selector_flags_map,
bloom_filter,
&mut self,
data);
context.thread_local.current_element_info.as_mut().unwrap().validation_data =
self.validation_data.take();
result
cache.share_style_if_possible(
shared_context,
selector_flags_map,
bloom_filter,
self
)
}
fn accumulate_damage_when_sharing(&self,
shared_context: &SharedStyleContext,
shared_styles: &ElementStyles,
data: &mut ElementData) -> ChildCascadeRequirement {
// Accumulate restyle damage for the case when our sharing
// target managed to share style. This can come from several
// sources:
//
// 1) We matched a different set of eager pseudos (which
// should cause a reconstruct).
// 2) We have restyle damage from the eager pseudo computed
// styles.
// 3) We have restyle damage from our own computed styles.
if data.has_styles() {
// We used to have pseudos (because we had styles).
// Check for damage from the set of pseudos changing or
// pseudos being restyled.
let (styles, mut restyle_data) = data.styles_and_restyle_mut();
let old_pseudos = &styles.pseudos;
let new_pseudos = &shared_styles.pseudos;
if !old_pseudos.has_same_pseudos_as(new_pseudos) {
restyle_data.damage |= RestyleDamage::reconstruct();
} else {
// It's a bit unfortunate that we have to keep
// mapping PseudoElements back to indices
// here....
for pseudo in old_pseudos.keys() {
let old_values =
old_pseudos.get(&pseudo).map(|v| &**v);
let new_values =
new_pseudos.get(&pseudo).unwrap();
self.element.accumulate_damage(
&shared_context,
restyle_data,
old_values,
new_values,
Some(&pseudo)
);
}
}
}
let old_values = data.styles.primary.take();
self.element.accumulate_damage(
&shared_context,
&mut data.restyle,
old_values.as_ref().map(|v| &**v),
shared_styles.primary(),
None
)
/// Gets the validation data used to match against this target, if any.
pub fn take_validation_data(&mut self) -> ValidationData {
self.validation_data.take()
}
}
@ -451,10 +395,8 @@ pub enum StyleSharingResult {
/// We didn't find anybody to share the style with.
CannotShare,
/// The node's style can be shared. The integer specifies the index in the
/// LRU cache that was hit and the damage that was done. The
/// `ChildCascadeRequirement` indicates whether style changes due to using
/// the shared style mean we need to recascade to children.
StyleWasShared(usize, ChildCascadeRequirement),
/// LRU cache that was hit and the damage that was done.
StyleWasShared(usize, ElementStyles),
}
/// An LRU cache of the last few nodes seen, so that we can aggressively try to
@ -553,7 +495,6 @@ impl<E: TElement> StyleSharingCandidateCache<E> {
selector_flags_map: &mut SelectorFlagsMap<E>,
bloom_filter: &StyleBloom<E>,
target: &mut StyleSharingTarget<E>,
data: &mut ElementData
) -> StyleSharingResult {
if shared_context.options.disable_style_sharing_cache {
debug!("{:?} Cannot share style: style sharing cache disabled",
@ -584,14 +525,7 @@ impl<E: TElement> StyleSharingCandidateCache<E> {
match sharing_result {
Ok(shared_styles) => {
// Yay, cache hit. Share the style.
let child_cascade_requirement =
target.accumulate_damage_when_sharing(shared_context,
&shared_styles,
data);
data.styles = shared_styles;
return StyleSharingResult::StyleWasShared(i, child_cascade_requirement)
return StyleSharingResult::StyleWasShared(i, shared_styles)
}
Err(miss) => {
debug!("Cache miss: {:?}", miss);
@ -605,12 +539,13 @@ impl<E: TElement> StyleSharingCandidateCache<E> {
StyleSharingResult::CannotShare
}
fn test_candidate(target: &mut StyleSharingTarget<E>,
candidate: &mut StyleSharingCandidate<E>,
shared: &SharedStyleContext,
bloom: &StyleBloom<E>,
selector_flags_map: &mut SelectorFlagsMap<E>)
-> Result<ElementStyles, CacheMiss> {
fn test_candidate(
target: &mut StyleSharingTarget<E>,
candidate: &mut StyleSharingCandidate<E>,
shared: &SharedStyleContext,
bloom: &StyleBloom<E>,
selector_flags_map: &mut SelectorFlagsMap<E>
) -> Result<ElementStyles, CacheMiss> {
macro_rules! miss {
($miss: ident) => {
return Err(CacheMiss::$miss);

View file

@ -771,50 +771,38 @@ where
context.thread_local.bloom_filter.assert_complete(element);
// Now that our bloom filter is set up, try the style sharing
// cache. If we get a match we can skip the rest of the work.
let target = StyleSharingTarget::new(element);
let sharing_result = target.share_style_if_possible(context, data);
if let StyleWasShared(index, had_damage) = sharing_result {
context.thread_local.statistics.styles_shared += 1;
context.thread_local.style_sharing_candidate_cache.touch(index);
return had_damage;
}
context.thread_local.statistics.elements_matched += 1;
// This is only relevant for animations as of right now.
important_rules_changed = true;
// Perform the matching and cascading.
let new_styles =
StyleResolverForElement::new(element, context, RuleInclusion::All)
.resolve_style_with_default_parents();
let mut target = StyleSharingTarget::new(element);
// If we previously tried to match this element against the cache,
// the revalidation match results will already be cached. Otherwise
// we'll have None, and compute them later on-demand.
//
// If we do have the results, grab them here to satisfy the borrow
// checker.
let validation_data =
context.thread_local
.current_element_info
.as_mut().unwrap()
.validation_data
.take();
// Now that our bloom filter is set up, try the style sharing
// cache.
match target.share_style_if_possible(context) {
StyleWasShared(index, styles) => {
context.thread_local.statistics.styles_shared += 1;
context.thread_local.style_sharing_candidate_cache.touch(index);
styles
}
CannotShare => {
context.thread_local.statistics.elements_matched += 1;
// Perform the matching and cascading.
let new_styles =
StyleResolverForElement::new(element, context, RuleInclusion::All)
.resolve_style_with_default_parents();
let dom_depth = context.thread_local.bloom_filter.matching_depth();
context.thread_local
.style_sharing_candidate_cache
.insert_if_possible(
&element,
new_styles.primary(),
validation_data,
dom_depth
);
context.thread_local
.style_sharing_candidate_cache
.insert_if_possible(
&element,
new_styles.primary(),
target.take_validation_data(),
context.thread_local.bloom_filter.matching_depth(),
);
new_styles
new_styles
}
}
}
CascadeWithReplacements(flags) => {
// Skipping full matching, load cascade inputs from previous values.