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

@ -346,7 +346,7 @@ pub trait ThreadSafeLayoutElement: Clone + Copy + Sized + Debug +
#[inline] #[inline]
fn get_before_pseudo(&self) -> Option<Self> { fn get_before_pseudo(&self) -> Option<Self> {
if self.style_data().styles.pseudos.has(&PseudoElement::Before) { if self.style_data().styles.pseudos.get(&PseudoElement::Before).is_some() {
Some(self.with_pseudo(PseudoElementType::Before(None))) Some(self.with_pseudo(PseudoElementType::Before(None)))
} else { } else {
None None
@ -355,7 +355,7 @@ pub trait ThreadSafeLayoutElement: Clone + Copy + Sized + Debug +
#[inline] #[inline]
fn get_after_pseudo(&self) -> Option<Self> { fn get_after_pseudo(&self) -> Option<Self> {
if self.style_data().styles.pseudos.has(&PseudoElement::After) { if self.style_data().styles.pseudos.get(&PseudoElement::After).is_some() {
Some(self.with_pseudo(PseudoElementType::After(None))) Some(self.with_pseudo(PseudoElementType::After(None)))
} else { } else {
None None

View file

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

View file

@ -4,7 +4,6 @@
//! Per-node data used in style calculation. //! Per-node data used in style calculation.
use arrayvec::ArrayVec;
use context::SharedStyleContext; use context::SharedStyleContext;
use dom::TElement; use dom::TElement;
use invalidation::element::restyle_hints::RestyleHint; 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()) 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. /// Sets the style for the eager pseudo.
pub fn set(&mut self, pseudo: &PseudoElement, value: Arc<ComputedValues>) { pub fn set(&mut self, pseudo: &PseudoElement, value: Arc<ComputedValues>) {
if self.0.is_none() { if self.0.is_none() {
@ -179,57 +164,6 @@ impl EagerPseudoStyles {
let arr = Arc::make_mut(self.0.as_mut().unwrap()); let arr = Arc::make_mut(self.0.as_mut().unwrap());
arr[pseudo.eager_index()] = Some(value); 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 /// The styles associated with a node, including the styles for any
@ -248,11 +182,6 @@ impl ElementStyles {
self.primary.as_ref() 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. /// Returns the primary style. Panic if no style available.
pub fn primary(&self) -> &Arc<ComputedValues> { pub fn primary(&self) -> &Arc<ComputedValues> {
self.primary.as_ref().unwrap() self.primary.as_ref().unwrap()

View file

@ -70,11 +70,10 @@ use bit_vec::BitVec;
use bloom::StyleBloom; use bloom::StyleBloom;
use cache::{LRUCache, LRUCacheMutIterator}; use cache::{LRUCache, LRUCacheMutIterator};
use context::{SelectorFlagsMap, SharedStyleContext, StyleContext}; use context::{SelectorFlagsMap, SharedStyleContext, StyleContext};
use data::{ElementData, ElementStyles}; use data::ElementStyles;
use dom::{TElement, SendElement}; use dom::{TElement, SendElement};
use matching::{ChildCascadeRequirement, MatchMethods}; use matching::MatchMethods;
use properties::ComputedValues; use properties::ComputedValues;
use selector_parser::RestyleDamage;
use selectors::matching::{ElementSelectorFlags, VisitedHandlingMode}; use selectors::matching::{ElementSelectorFlags, VisitedHandlingMode};
use smallvec::SmallVec; use smallvec::SmallVec;
use std::mem; use std::mem;
@ -329,11 +328,9 @@ impl<E: TElement> StyleSharingTarget<E> {
/// Attempts to share a style with another node. /// Attempts to share a style with another node.
pub fn share_style_if_possible( pub fn share_style_if_possible(
mut self, &mut self,
context: &mut StyleContext<E>, context: &mut StyleContext<E>,
data: &mut ElementData) ) -> StyleSharingResult {
-> StyleSharingResult
{
let cache = &mut context.thread_local.style_sharing_candidate_cache; let cache = &mut context.thread_local.style_sharing_candidate_cache;
let shared_context = &context.shared; let shared_context = &context.shared;
let selector_flags_map = &mut context.thread_local.selector_flags; 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(), debug_assert_eq!(bloom_filter.current_parent(),
self.element.traversal_parent()); self.element.traversal_parent());
let result = cache cache.share_style_if_possible(
.share_style_if_possible(shared_context, shared_context,
selector_flags_map, selector_flags_map,
bloom_filter, bloom_filter,
&mut self, self
data); )
context.thread_local.current_element_info.as_mut().unwrap().validation_data =
self.validation_data.take();
result
} }
fn accumulate_damage_when_sharing(&self, /// Gets the validation data used to match against this target, if any.
shared_context: &SharedStyleContext, pub fn take_validation_data(&mut self) -> ValidationData {
shared_styles: &ElementStyles, self.validation_data.take()
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
)
} }
} }
@ -451,10 +395,8 @@ pub enum StyleSharingResult {
/// We didn't find anybody to share the style with. /// We didn't find anybody to share the style with.
CannotShare, CannotShare,
/// The node's style can be shared. The integer specifies the index in the /// 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 /// LRU cache that was hit and the damage that was done.
/// `ChildCascadeRequirement` indicates whether style changes due to using StyleWasShared(usize, ElementStyles),
/// the shared style mean we need to recascade to children.
StyleWasShared(usize, ChildCascadeRequirement),
} }
/// An LRU cache of the last few nodes seen, so that we can aggressively try to /// 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>, selector_flags_map: &mut SelectorFlagsMap<E>,
bloom_filter: &StyleBloom<E>, bloom_filter: &StyleBloom<E>,
target: &mut StyleSharingTarget<E>, target: &mut StyleSharingTarget<E>,
data: &mut ElementData
) -> StyleSharingResult { ) -> StyleSharingResult {
if shared_context.options.disable_style_sharing_cache { if shared_context.options.disable_style_sharing_cache {
debug!("{:?} Cannot share style: style sharing cache disabled", debug!("{:?} Cannot share style: style sharing cache disabled",
@ -584,14 +525,7 @@ impl<E: TElement> StyleSharingCandidateCache<E> {
match sharing_result { match sharing_result {
Ok(shared_styles) => { Ok(shared_styles) => {
// Yay, cache hit. Share the style. return StyleSharingResult::StyleWasShared(i, shared_styles)
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)
} }
Err(miss) => { Err(miss) => {
debug!("Cache miss: {:?}", miss); debug!("Cache miss: {:?}", miss);
@ -605,12 +539,13 @@ impl<E: TElement> StyleSharingCandidateCache<E> {
StyleSharingResult::CannotShare StyleSharingResult::CannotShare
} }
fn test_candidate(target: &mut StyleSharingTarget<E>, fn test_candidate(
candidate: &mut StyleSharingCandidate<E>, target: &mut StyleSharingTarget<E>,
shared: &SharedStyleContext, candidate: &mut StyleSharingCandidate<E>,
bloom: &StyleBloom<E>, shared: &SharedStyleContext,
selector_flags_map: &mut SelectorFlagsMap<E>) bloom: &StyleBloom<E>,
-> Result<ElementStyles, CacheMiss> { selector_flags_map: &mut SelectorFlagsMap<E>
) -> Result<ElementStyles, CacheMiss> {
macro_rules! miss { macro_rules! miss {
($miss: ident) => { ($miss: ident) => {
return Err(CacheMiss::$miss); return Err(CacheMiss::$miss);

View file

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