mirror of
https://github.com/servo/servo.git
synced 2025-06-06 16:45:39 +00:00
Lazily compute common style affecting attribute info.
This commit is contained in:
parent
51b6568273
commit
a46f0c3b24
2 changed files with 26 additions and 16 deletions
|
@ -7,7 +7,7 @@
|
||||||
use rand;
|
use rand;
|
||||||
use rand::Rng;
|
use rand::Rng;
|
||||||
use std::hash::{Hash, Hasher, SipHasher};
|
use std::hash::{Hash, Hasher, SipHasher};
|
||||||
use std::slice::Iter;
|
use std::slice::{Iter, IterMut};
|
||||||
|
|
||||||
pub struct LRUCache<K, V> {
|
pub struct LRUCache<K, V> {
|
||||||
entries: Vec<(K, V)>,
|
entries: Vec<(K, V)>,
|
||||||
|
@ -17,7 +17,7 @@ pub struct LRUCache<K, V> {
|
||||||
impl<K: PartialEq, V: Clone> LRUCache<K, V> {
|
impl<K: PartialEq, V: Clone> LRUCache<K, V> {
|
||||||
pub fn new(size: usize) -> LRUCache<K, V> {
|
pub fn new(size: usize) -> LRUCache<K, V> {
|
||||||
LRUCache {
|
LRUCache {
|
||||||
entries: vec!(),
|
entries: vec![],
|
||||||
cache_size: size,
|
cache_size: size,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -36,6 +36,10 @@ impl<K: PartialEq, V: Clone> LRUCache<K, V> {
|
||||||
self.entries.iter()
|
self.entries.iter()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn iter_mut(&mut self) -> IterMut<(K, V)> {
|
||||||
|
self.entries.iter_mut()
|
||||||
|
}
|
||||||
|
|
||||||
pub fn insert(&mut self, key: K, val: V) {
|
pub fn insert(&mut self, key: K, val: V) {
|
||||||
if self.entries.len() == self.cache_size {
|
if self.entries.len() == self.cache_size {
|
||||||
self.entries.remove(0);
|
self.entries.remove(0);
|
||||||
|
|
|
@ -24,7 +24,7 @@ use sink::ForgetfulSink;
|
||||||
use smallvec::SmallVec;
|
use smallvec::SmallVec;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::hash::{BuildHasherDefault, Hash, Hasher};
|
use std::hash::{BuildHasherDefault, Hash, Hasher};
|
||||||
use std::slice::Iter;
|
use std::slice::IterMut;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use string_cache::Atom;
|
use string_cache::Atom;
|
||||||
use traversal::RestyleResult;
|
use traversal::RestyleResult;
|
||||||
|
@ -188,7 +188,7 @@ struct StyleSharingCandidate {
|
||||||
/// The cached computed style, here for convenience.
|
/// The cached computed style, here for convenience.
|
||||||
style: Arc<ComputedValues>,
|
style: Arc<ComputedValues>,
|
||||||
/// The cached common style affecting attribute info.
|
/// The cached common style affecting attribute info.
|
||||||
common_style_affecting_attributes: CommonStyleAffectingAttributes,
|
common_style_affecting_attributes: Option<CommonStyleAffectingAttributes>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PartialEq<StyleSharingCandidate> for StyleSharingCandidate {
|
impl PartialEq<StyleSharingCandidate> for StyleSharingCandidate {
|
||||||
|
@ -230,7 +230,7 @@ pub enum CacheMiss {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn element_matches_candidate<E: TElement>(element: &E,
|
fn element_matches_candidate<E: TElement>(element: &E,
|
||||||
candidate: &StyleSharingCandidate,
|
candidate: &mut StyleSharingCandidate,
|
||||||
candidate_element: &E,
|
candidate_element: &E,
|
||||||
shared_context: &SharedStyleContext)
|
shared_context: &SharedStyleContext)
|
||||||
-> Result<Arc<ComputedValues>, CacheMiss> {
|
-> Result<Arc<ComputedValues>, CacheMiss> {
|
||||||
|
@ -272,7 +272,9 @@ fn element_matches_candidate<E: TElement>(element: &E,
|
||||||
miss!(Class)
|
miss!(Class)
|
||||||
}
|
}
|
||||||
|
|
||||||
if !have_same_common_style_affecting_attributes(element, candidate) {
|
if !have_same_common_style_affecting_attributes(element,
|
||||||
|
candidate,
|
||||||
|
candidate_element) {
|
||||||
miss!(CommonStyleAffectingAttributes)
|
miss!(CommonStyleAffectingAttributes)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -296,11 +298,14 @@ fn element_matches_candidate<E: TElement>(element: &E,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn have_same_common_style_affecting_attributes<E: TElement>(element: &E,
|
fn have_same_common_style_affecting_attributes<E: TElement>(element: &E,
|
||||||
candidate: &StyleSharingCandidate) -> bool {
|
candidate: &mut StyleSharingCandidate,
|
||||||
// XXX probably could do something smarter. Also, the cache should
|
candidate_element: &E) -> bool {
|
||||||
// precompute this for the parent. Just experimenting now though.
|
if candidate.common_style_affecting_attributes.is_none() {
|
||||||
|
candidate.common_style_affecting_attributes =
|
||||||
|
Some(create_common_style_affecting_attributes_from_element(candidate_element))
|
||||||
|
}
|
||||||
create_common_style_affecting_attributes_from_element(element) ==
|
create_common_style_affecting_attributes_from_element(element) ==
|
||||||
candidate.common_style_affecting_attributes
|
candidate.common_style_affecting_attributes.unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn have_same_presentational_hints<E: TElement>(element: &E, candidate: &E) -> bool {
|
fn have_same_presentational_hints<E: TElement>(element: &E, candidate: &E) -> bool {
|
||||||
|
@ -406,8 +411,8 @@ impl StyleSharingCandidateCache {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn iter(&self) -> Iter<(StyleSharingCandidate, ())> {
|
fn iter_mut(&mut self) -> IterMut<(StyleSharingCandidate, ())> {
|
||||||
self.cache.iter()
|
self.cache.iter_mut()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn insert_if_possible<E: TElement>(&mut self,
|
pub fn insert_if_possible<E: TElement>(&mut self,
|
||||||
|
@ -451,8 +456,7 @@ impl StyleSharingCandidateCache {
|
||||||
self.cache.insert(StyleSharingCandidate {
|
self.cache.insert(StyleSharingCandidate {
|
||||||
node: node.to_unsafe(),
|
node: node.to_unsafe(),
|
||||||
style: style.clone(),
|
style: style.clone(),
|
||||||
common_style_affecting_attributes:
|
common_style_affecting_attributes: None,
|
||||||
create_common_style_affecting_attributes_from_element(element),
|
|
||||||
}, ());
|
}, ());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -620,7 +624,7 @@ trait PrivateElementMatchMethods: TElement {
|
||||||
fn share_style_with_candidate_if_possible(&self,
|
fn share_style_with_candidate_if_possible(&self,
|
||||||
parent_node: Self::ConcreteNode,
|
parent_node: Self::ConcreteNode,
|
||||||
shared_context: &SharedStyleContext,
|
shared_context: &SharedStyleContext,
|
||||||
candidate: &StyleSharingCandidate)
|
candidate: &mut StyleSharingCandidate)
|
||||||
-> Result<Arc<ComputedValues>, CacheMiss> {
|
-> Result<Arc<ComputedValues>, CacheMiss> {
|
||||||
debug_assert!(parent_node.is_element());
|
debug_assert!(parent_node.is_element());
|
||||||
|
|
||||||
|
@ -697,7 +701,7 @@ pub trait ElementMatchMethods : TElement {
|
||||||
_ => return StyleSharingResult::CannotShare,
|
_ => return StyleSharingResult::CannotShare,
|
||||||
};
|
};
|
||||||
|
|
||||||
for (i, &(ref candidate, ())) in style_sharing_candidate_cache.iter().enumerate() {
|
for (i, &mut (ref mut candidate, ())) in style_sharing_candidate_cache.iter_mut().enumerate() {
|
||||||
let sharing_result = self.share_style_with_candidate_if_possible(parent,
|
let sharing_result = self.share_style_with_candidate_if_possible(parent,
|
||||||
shared_context,
|
shared_context,
|
||||||
candidate);
|
candidate);
|
||||||
|
@ -734,6 +738,8 @@ pub trait ElementMatchMethods : TElement {
|
||||||
return StyleSharingResult::StyleWasShared(i, damage, restyle_result)
|
return StyleSharingResult::StyleWasShared(i, damage, restyle_result)
|
||||||
}
|
}
|
||||||
Err(miss) => {
|
Err(miss) => {
|
||||||
|
debug!("Cache miss: {:?}", miss);
|
||||||
|
|
||||||
// Cache miss, let's see what kind of failure to decide
|
// Cache miss, let's see what kind of failure to decide
|
||||||
// whether we keep trying or not.
|
// whether we keep trying or not.
|
||||||
match miss {
|
match miss {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue