mirror of
https://github.com/servo/servo.git
synced 2025-08-03 20:50:07 +01:00
style: Add a CachedStyleSharingData to hold the candidate class list and revalidation results.
This commit is contained in:
parent
fb6339bbf9
commit
abcc9b301c
2 changed files with 78 additions and 24 deletions
|
@ -72,13 +72,7 @@ pub fn have_same_class<E>(element: E,
|
||||||
let mut element_class_attributes = vec![];
|
let mut element_class_attributes = vec![];
|
||||||
element.each_class(|c| element_class_attributes.push(c.clone()));
|
element.each_class(|c| element_class_attributes.push(c.clone()));
|
||||||
|
|
||||||
if candidate.class_attributes.is_none() {
|
element_class_attributes == candidate.class_list()
|
||||||
let mut attrs = vec![];
|
|
||||||
candidate.element.each_class(|c| attrs.push(c.clone()));
|
|
||||||
candidate.class_attributes = Some(attrs)
|
|
||||||
}
|
|
||||||
|
|
||||||
element_class_attributes == *candidate.class_attributes.as_ref().unwrap()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Compare element and candidate state, but ignore visitedness. Styles don't
|
/// Compare element and candidate state, but ignore visitedness. Styles don't
|
||||||
|
@ -137,15 +131,8 @@ pub fn revalidate<E>(element: E,
|
||||||
&mut set_selector_flags));
|
&mut set_selector_flags));
|
||||||
}
|
}
|
||||||
|
|
||||||
if candidate.revalidation_match_results.is_none() {
|
|
||||||
let results =
|
|
||||||
stylist.match_revalidation_selectors(&*candidate.element, bloom,
|
|
||||||
&mut |_, _| {});
|
|
||||||
candidate.revalidation_match_results = Some(results);
|
|
||||||
}
|
|
||||||
|
|
||||||
let for_element = info.revalidation_match_results.as_ref().unwrap();
|
let for_element = info.revalidation_match_results.as_ref().unwrap();
|
||||||
let for_candidate = candidate.revalidation_match_results.as_ref().unwrap();
|
let for_candidate = candidate.revalidation_match_results(stylist, bloom);
|
||||||
|
|
||||||
// This assert "ensures", to some extent, that the two candidates have
|
// This assert "ensures", to some extent, that the two candidates have
|
||||||
// matched the same rulehash buckets, and as such, that the bits we're
|
// matched the same rulehash buckets, and as such, that the bits we're
|
||||||
|
|
|
@ -14,8 +14,10 @@ use dom::{TElement, SendElement};
|
||||||
use matching::{ChildCascadeRequirement, MatchMethods};
|
use matching::{ChildCascadeRequirement, MatchMethods};
|
||||||
use properties::ComputedValues;
|
use properties::ComputedValues;
|
||||||
use selectors::bloom::BloomFilter;
|
use selectors::bloom::BloomFilter;
|
||||||
use selectors::matching::StyleRelations;
|
use selectors::matching::{ElementSelectorFlags, StyleRelations};
|
||||||
use sink::ForgetfulSink;
|
use sink::ForgetfulSink;
|
||||||
|
use smallvec::SmallVec;
|
||||||
|
use stylist::Stylist;
|
||||||
|
|
||||||
mod checks;
|
mod checks;
|
||||||
|
|
||||||
|
@ -32,23 +34,86 @@ pub enum StyleSharingBehavior {
|
||||||
Disallow,
|
Disallow,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Some data we want to avoid recomputing all the time while trying to share
|
||||||
|
/// style.
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct CachedStyleSharingData {
|
||||||
|
/// The class list of this element.
|
||||||
|
///
|
||||||
|
/// TODO(emilio): See if it's worth to sort them, or doing something else in
|
||||||
|
/// a similar fashion as what Boris is doing for the ID attribute.
|
||||||
|
class_list: Option<SmallVec<[Atom; 5]>>,
|
||||||
|
|
||||||
|
/// The cached result of matching this entry against the revalidation
|
||||||
|
/// selectors.
|
||||||
|
revalidation_match_results: Option<BitVec>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl CachedStyleSharingData {
|
||||||
|
/// Get or compute the class-list associated with this element.
|
||||||
|
pub fn class_list<E>(&mut self, element: E) -> &[Atom]
|
||||||
|
where E: TElement,
|
||||||
|
{
|
||||||
|
if self.class_list.is_none() {
|
||||||
|
let mut class_list = SmallVec::new();
|
||||||
|
element.each_class(|c| class_list.push(c.clone()));
|
||||||
|
self.class_list = Some(class_list);
|
||||||
|
}
|
||||||
|
&*self.class_list.as_ref().unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Computes the revalidation results if needed, and returns it.
|
||||||
|
fn revalidation_match_results<E, F>(
|
||||||
|
&mut self,
|
||||||
|
element: E,
|
||||||
|
stylist: &Stylist,
|
||||||
|
bloom: &BloomFilter,
|
||||||
|
flags_setter: &mut F
|
||||||
|
) -> &BitVec
|
||||||
|
where E: TElement,
|
||||||
|
F: FnMut(&E, ElementSelectorFlags),
|
||||||
|
{
|
||||||
|
if self.revalidation_match_results.is_none() {
|
||||||
|
self.revalidation_match_results =
|
||||||
|
Some(stylist.match_revalidation_selectors(&element, bloom,
|
||||||
|
flags_setter));
|
||||||
|
}
|
||||||
|
|
||||||
|
self.revalidation_match_results.as_ref().unwrap()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Information regarding a style sharing candidate, that is, an entry in the
|
/// Information regarding a style sharing candidate, that is, an entry in the
|
||||||
/// style sharing cache.
|
/// style sharing cache.
|
||||||
///
|
///
|
||||||
/// Note that this information is stored in TLS and cleared after the traversal,
|
/// Note that this information is stored in TLS and cleared after the traversal,
|
||||||
/// and once here, the style information of the element is immutable, so it's
|
/// and once here, the style information of the element is immutable, so it's
|
||||||
/// safe to access.
|
/// safe to access.
|
||||||
///
|
|
||||||
/// TODO: We can stick a lot more info here.
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct StyleSharingCandidate<E: TElement> {
|
pub struct StyleSharingCandidate<E: TElement> {
|
||||||
/// The element. We use SendElement here so that the cache may live in
|
/// The element. We use SendElement here so that the cache may live in
|
||||||
/// ScopedTLS.
|
/// ScopedTLS.
|
||||||
element: SendElement<E>,
|
element: SendElement<E>,
|
||||||
/// The cached class names.
|
cache: CachedStyleSharingData,
|
||||||
class_attributes: Option<Vec<Atom>>,
|
}
|
||||||
/// The cached result of matching this entry against the revalidation selectors.
|
|
||||||
revalidation_match_results: Option<BitVec>,
|
impl<E: TElement> StyleSharingCandidate<E> {
|
||||||
|
/// Get the classlist of this candidate.
|
||||||
|
fn class_list(&mut self) -> &[Atom] {
|
||||||
|
self.cache.class_list(*self.element)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get the classlist of this candidate.
|
||||||
|
fn revalidation_match_results(
|
||||||
|
&mut self,
|
||||||
|
stylist: &Stylist,
|
||||||
|
bloom: &BloomFilter,
|
||||||
|
) -> &BitVec {
|
||||||
|
self.cache.revalidation_match_results(*self.element,
|
||||||
|
stylist,
|
||||||
|
bloom,
|
||||||
|
&mut |_, _| {})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<E: TElement> PartialEq<StyleSharingCandidate<E>> for StyleSharingCandidate<E> {
|
impl<E: TElement> PartialEq<StyleSharingCandidate<E>> for StyleSharingCandidate<E> {
|
||||||
|
@ -177,8 +242,10 @@ impl<E: TElement> StyleSharingCandidateCache<E> {
|
||||||
|
|
||||||
self.cache.insert(StyleSharingCandidate {
|
self.cache.insert(StyleSharingCandidate {
|
||||||
element: unsafe { SendElement::new(*element) },
|
element: unsafe { SendElement::new(*element) },
|
||||||
class_attributes: None,
|
cache: CachedStyleSharingData {
|
||||||
|
class_list: None,
|
||||||
revalidation_match_results: revalidation_match_results,
|
revalidation_match_results: revalidation_match_results,
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue