Skip to content

Commit

Permalink
Auto merge of #17713 - emilio:less-code-is-lovely, r=heycam
Browse files Browse the repository at this point in the history
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 -->
  • Loading branch information
bors-servo committed Jul 14, 2017
2 parents 59f00f5 + bd10081 commit 1c85c55
Show file tree
Hide file tree
Showing 5 changed files with 55 additions and 206 deletions.
4 changes: 2 additions & 2 deletions components/script_layout_interface/wrapper_traits.rs
Expand Up @@ -346,7 +346,7 @@ pub trait ThreadSafeLayoutElement: Clone + Copy + Sized + Debug +

#[inline]
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)))
} else {
None
Expand All @@ -355,7 +355,7 @@ pub trait ThreadSafeLayoutElement: Clone + Copy + Sized + Debug +

#[inline]
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)))
} else {
None
Expand Down
5 changes: 1 addition & 4 deletions components/style/context.rs
Expand Up @@ -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;
Expand Down Expand Up @@ -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>,
Expand Down Expand Up @@ -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(),
});
}
Expand Down
71 changes: 0 additions & 71 deletions components/style/data.rs
Expand Up @@ -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;
Expand Down Expand Up @@ -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() {
Expand All @@ -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
Expand All @@ -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()
Expand Down
111 changes: 23 additions & 88 deletions components/style/sharing/mod.rs
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand All @@ -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()
}
}

Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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",
Expand Down Expand Up @@ -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);
Expand All @@ -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);
Expand Down
70 changes: 29 additions & 41 deletions components/style/traversal.rs
Expand Up @@ -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();

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
);

new_styles
// 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();

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
}
}
}
CascadeWithReplacements(flags) => {
// Skipping full matching, load cascade inputs from previous values.
Expand Down

0 comments on commit 1c85c55

Please sign in to comment.