mirror of
https://github.com/servo/servo.git
synced 2025-08-07 06:25:32 +01:00
Introduce an NthIndexCache type and pipe it from ThreadLocalStyleContext to MatchingContext.
Some future refactoring here to pass fewer things as parameters would be nice.
This commit is contained in:
parent
05c03d5104
commit
48466bf876
11 changed files with 83 additions and 24 deletions
|
@ -23,6 +23,7 @@ use properties::ComputedValues;
|
|||
use rule_cache::RuleCache;
|
||||
use rule_tree::StrongRuleNode;
|
||||
use selector_parser::{EAGER_PSEUDO_COUNT, SnapshotMap};
|
||||
use selectors::context::NthIndexCache;
|
||||
use selectors::matching::ElementSelectorFlags;
|
||||
use servo_arc::Arc;
|
||||
#[cfg(feature = "servo")] use servo_atoms::Atom;
|
||||
|
@ -719,6 +720,8 @@ pub struct ThreadLocalStyleContext<E: TElement> {
|
|||
/// A checker used to ensure that parallel.rs does not recurse indefinitely
|
||||
/// even on arbitrarily deep trees. See Gecko bug 1376883.
|
||||
pub stack_limit_checker: StackLimitChecker,
|
||||
/// A cache for nth-index-like selectors.
|
||||
pub nth_index_cache: NthIndexCache,
|
||||
}
|
||||
|
||||
impl<E: TElement> ThreadLocalStyleContext<E> {
|
||||
|
@ -737,6 +740,7 @@ impl<E: TElement> ThreadLocalStyleContext<E> {
|
|||
font_metrics_provider: E::FontMetricsProvider::create_from(shared),
|
||||
stack_limit_checker: StackLimitChecker::new(
|
||||
(STYLE_THREAD_STACK_SIZE_KB - STACK_SAFETY_MARGIN_KB) * 1024),
|
||||
nth_index_cache: NthIndexCache::default(),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -754,6 +758,7 @@ impl<E: TElement> ThreadLocalStyleContext<E> {
|
|||
font_metrics_provider: E::FontMetricsProvider::create_from(shared),
|
||||
stack_limit_checker: StackLimitChecker::new(
|
||||
(STYLE_THREAD_STACK_SIZE_KB - STACK_SAFETY_MARGIN_KB) * 1024),
|
||||
nth_index_cache: NthIndexCache::default(),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -633,10 +633,12 @@ impl<'a, 'b: 'a, E> TreeStyleInvalidator<'a, 'b, E>
|
|||
debug!("TreeStyleInvalidator::process_invalidation({:?}, {:?}, {:?})",
|
||||
self.element, invalidation, invalidation_kind);
|
||||
|
||||
// FIXME(bholley): Consider passing an nth-index cache here.
|
||||
let mut context =
|
||||
MatchingContext::new_for_visited(
|
||||
MatchingMode::Normal,
|
||||
None,
|
||||
None,
|
||||
VisitedHandlingMode::AllLinksVisitedAndUnvisited,
|
||||
self.shared_context.quirks_mode(),
|
||||
);
|
||||
|
@ -946,12 +948,14 @@ impl<'a, 'b: 'a, E> InvalidationCollector<'a, 'b, E>
|
|||
// whether any parent had a snapshot, and whether those snapshots were
|
||||
// taken due to an element class/id change, but it's not clear it'd be
|
||||
// worth it.
|
||||
//
|
||||
// FIXME(bholley): Consider passing an nth-index cache here.
|
||||
let mut now_context =
|
||||
MatchingContext::new_for_visited(MatchingMode::Normal, None,
|
||||
MatchingContext::new_for_visited(MatchingMode::Normal, None, None,
|
||||
VisitedHandlingMode::AllLinksUnvisited,
|
||||
self.shared_context.quirks_mode());
|
||||
let mut then_context =
|
||||
MatchingContext::new_for_visited(MatchingMode::Normal, None,
|
||||
MatchingContext::new_for_visited(MatchingMode::Normal, None, None,
|
||||
VisitedHandlingMode::AllLinksUnvisited,
|
||||
self.shared_context.quirks_mode());
|
||||
|
||||
|
|
|
@ -10,6 +10,7 @@ use Atom;
|
|||
use bloom::StyleBloom;
|
||||
use context::{SelectorFlagsMap, SharedStyleContext};
|
||||
use dom::TElement;
|
||||
use selectors::context::NthIndexCache;
|
||||
use sharing::{StyleSharingCandidate, StyleSharingTarget};
|
||||
|
||||
/// Determines whether a target and a candidate have compatible parents for sharing.
|
||||
|
@ -99,16 +100,25 @@ pub fn revalidate<E>(target: &mut StyleSharingTarget<E>,
|
|||
candidate: &mut StyleSharingCandidate<E>,
|
||||
shared_context: &SharedStyleContext,
|
||||
bloom: &StyleBloom<E>,
|
||||
nth_index_cache: &mut NthIndexCache,
|
||||
selector_flags_map: &mut SelectorFlagsMap<E>)
|
||||
-> bool
|
||||
where E: TElement,
|
||||
{
|
||||
let stylist = &shared_context.stylist;
|
||||
|
||||
let for_element =
|
||||
target.revalidation_match_results(stylist, bloom, selector_flags_map);
|
||||
let for_element = target.revalidation_match_results(
|
||||
stylist,
|
||||
bloom,
|
||||
nth_index_cache,
|
||||
selector_flags_map,
|
||||
);
|
||||
|
||||
let for_candidate = candidate.revalidation_match_results(stylist, bloom);
|
||||
let for_candidate = candidate.revalidation_match_results(
|
||||
stylist,
|
||||
bloom,
|
||||
nth_index_cache,
|
||||
);
|
||||
|
||||
// This assert "ensures", to some extent, that the two candidates have
|
||||
// matched the same rulehash buckets, and as such, that the bits we're
|
||||
|
|
|
@ -75,6 +75,7 @@ use matching::MatchMethods;
|
|||
use owning_ref::OwningHandle;
|
||||
use properties::ComputedValues;
|
||||
use rule_tree::StrongRuleNode;
|
||||
use selectors::context::NthIndexCache;
|
||||
use selectors::matching::{ElementSelectorFlags, VisitedHandlingMode};
|
||||
use servo_arc::{Arc, NonZeroPtrMut};
|
||||
use smallbitvec::SmallBitVec;
|
||||
|
@ -203,6 +204,7 @@ impl ValidationData {
|
|||
element: E,
|
||||
stylist: &Stylist,
|
||||
bloom: &StyleBloom<E>,
|
||||
nth_index_cache: &mut NthIndexCache,
|
||||
bloom_known_valid: bool,
|
||||
flags_setter: &mut F
|
||||
) -> &SmallBitVec
|
||||
|
@ -230,6 +232,7 @@ impl ValidationData {
|
|||
self.revalidation_match_results =
|
||||
Some(stylist.match_revalidation_selectors(&element,
|
||||
bloom_to_use,
|
||||
nth_index_cache,
|
||||
flags_setter));
|
||||
}
|
||||
|
||||
|
@ -289,11 +292,13 @@ impl<E: TElement> StyleSharingCandidate<E> {
|
|||
&mut self,
|
||||
stylist: &Stylist,
|
||||
bloom: &StyleBloom<E>,
|
||||
nth_index_cache: &mut NthIndexCache,
|
||||
) -> &SmallBitVec {
|
||||
self.validation_data.revalidation_match_results(
|
||||
self.element,
|
||||
stylist,
|
||||
bloom,
|
||||
nth_index_cache,
|
||||
/* bloom_known_valid = */ false,
|
||||
&mut |_, _| {})
|
||||
}
|
||||
|
@ -346,6 +351,7 @@ impl<E: TElement> StyleSharingTarget<E> {
|
|||
&mut self,
|
||||
stylist: &Stylist,
|
||||
bloom: &StyleBloom<E>,
|
||||
nth_index_cache: &mut NthIndexCache,
|
||||
selector_flags_map: &mut SelectorFlagsMap<E>
|
||||
) -> &SmallBitVec {
|
||||
// It's important to set the selector flags. Otherwise, if we succeed in
|
||||
|
@ -372,6 +378,7 @@ impl<E: TElement> StyleSharingTarget<E> {
|
|||
self.element,
|
||||
stylist,
|
||||
bloom,
|
||||
nth_index_cache,
|
||||
/* bloom_known_valid = */ true,
|
||||
&mut set_selector_flags)
|
||||
}
|
||||
|
@ -385,6 +392,7 @@ impl<E: TElement> StyleSharingTarget<E> {
|
|||
let shared_context = &context.shared;
|
||||
let selector_flags_map = &mut context.thread_local.selector_flags;
|
||||
let bloom_filter = &context.thread_local.bloom_filter;
|
||||
let nth_index_cache = &mut context.thread_local.nth_index_cache;
|
||||
|
||||
if cache.dom_depth != bloom_filter.matching_depth() {
|
||||
debug!("Can't share style, because DOM depth changed from {:?} to {:?}, element: {:?}",
|
||||
|
@ -398,6 +406,7 @@ impl<E: TElement> StyleSharingTarget<E> {
|
|||
shared_context,
|
||||
selector_flags_map,
|
||||
bloom_filter,
|
||||
nth_index_cache,
|
||||
self
|
||||
)
|
||||
}
|
||||
|
@ -596,6 +605,7 @@ impl<E: TElement> StyleSharingCache<E> {
|
|||
shared_context: &SharedStyleContext,
|
||||
selector_flags_map: &mut SelectorFlagsMap<E>,
|
||||
bloom_filter: &StyleBloom<E>,
|
||||
nth_index_cache: &mut NthIndexCache,
|
||||
target: &mut StyleSharingTarget<E>,
|
||||
) -> Option<ResolvedElementStyles> {
|
||||
if shared_context.options.disable_style_sharing_cache {
|
||||
|
@ -621,6 +631,7 @@ impl<E: TElement> StyleSharingCache<E> {
|
|||
candidate,
|
||||
&shared_context,
|
||||
bloom_filter,
|
||||
nth_index_cache,
|
||||
selector_flags_map
|
||||
)
|
||||
})
|
||||
|
@ -631,6 +642,7 @@ impl<E: TElement> StyleSharingCache<E> {
|
|||
candidate: &mut StyleSharingCandidate<E>,
|
||||
shared: &SharedStyleContext,
|
||||
bloom: &StyleBloom<E>,
|
||||
nth_index_cache: &mut NthIndexCache,
|
||||
selector_flags_map: &mut SelectorFlagsMap<E>
|
||||
) -> Option<ResolvedElementStyles> {
|
||||
// Check that we have the same parent, or at least that the parents
|
||||
|
@ -705,7 +717,7 @@ impl<E: TElement> StyleSharingCache<E> {
|
|||
}
|
||||
|
||||
if !checks::revalidate(target, candidate, shared, bloom,
|
||||
selector_flags_map) {
|
||||
nth_index_cache, selector_flags_map) {
|
||||
trace!("Miss: Revalidation");
|
||||
return None;
|
||||
}
|
||||
|
|
|
@ -413,10 +413,12 @@ where
|
|||
|
||||
let map = &mut self.context.thread_local.selector_flags;
|
||||
let bloom_filter = self.context.thread_local.bloom_filter.filter();
|
||||
let nth_index_cache = &mut self.context.thread_local.nth_index_cache;
|
||||
let mut matching_context =
|
||||
MatchingContext::new_for_visited(
|
||||
MatchingMode::Normal,
|
||||
Some(bloom_filter),
|
||||
Some(nth_index_cache),
|
||||
visited_handling,
|
||||
self.context.shared.quirks_mode(),
|
||||
);
|
||||
|
@ -486,11 +488,13 @@ where
|
|||
}
|
||||
|
||||
let bloom_filter = self.context.thread_local.bloom_filter.filter();
|
||||
let nth_index_cache = &mut self.context.thread_local.nth_index_cache;
|
||||
|
||||
let mut matching_context =
|
||||
MatchingContext::new_for_visited(
|
||||
MatchingMode::ForStatelessPseudoElement,
|
||||
Some(bloom_filter),
|
||||
Some(nth_index_cache),
|
||||
visited_handling,
|
||||
self.context.shared.quirks_mode(),
|
||||
);
|
||||
|
|
|
@ -30,7 +30,7 @@ use selector_map::{PrecomputedHashMap, SelectorMap, SelectorMapEntry};
|
|||
use selector_parser::{SelectorImpl, PerPseudoElementMap, PseudoElement};
|
||||
use selectors::attr::NamespaceConstraint;
|
||||
use selectors::bloom::{BloomFilter, NonCountingBloomFilter};
|
||||
use selectors::matching::{ElementSelectorFlags, matches_selector, MatchingContext, MatchingMode};
|
||||
use selectors::matching::{ElementSelectorFlags, matches_selector, MatchingContext, MatchingMode, NthIndexCache};
|
||||
use selectors::matching::VisitedHandlingMode;
|
||||
use selectors::parser::{AncestorHashes, Combinator, Component, Selector};
|
||||
use selectors::parser::{SelectorIter, SelectorMethods};
|
||||
|
@ -1027,6 +1027,7 @@ impl Stylist {
|
|||
let mut declarations = ApplicableDeclarationList::new();
|
||||
let mut matching_context =
|
||||
MatchingContext::new(MatchingMode::ForStatelessPseudoElement,
|
||||
None,
|
||||
None,
|
||||
self.quirks_mode);
|
||||
|
||||
|
@ -1061,6 +1062,7 @@ impl Stylist {
|
|||
MatchingContext::new_for_visited(
|
||||
MatchingMode::ForStatelessPseudoElement,
|
||||
None,
|
||||
None,
|
||||
VisitedHandlingMode::RelevantLinkVisited,
|
||||
self.quirks_mode,
|
||||
);
|
||||
|
@ -1203,7 +1205,7 @@ impl Stylist {
|
|||
V: Push<ApplicableDeclarationBlock> + VecLike<ApplicableDeclarationBlock>,
|
||||
{
|
||||
let mut matching_context =
|
||||
MatchingContext::new(MatchingMode::Normal, None, self.quirks_mode);
|
||||
MatchingContext::new(MatchingMode::Normal, None, None, self.quirks_mode);
|
||||
let mut dummy_flag_setter = |_: &E, _: ElementSelectorFlags| {};
|
||||
|
||||
let rule_hash_target = element.rule_hash_target();
|
||||
|
@ -1427,6 +1429,7 @@ impl Stylist {
|
|||
&self,
|
||||
element: &E,
|
||||
bloom: Option<&BloomFilter>,
|
||||
nth_index_cache: &mut NthIndexCache,
|
||||
flags_setter: &mut F
|
||||
) -> SmallBitVec
|
||||
where
|
||||
|
@ -1435,8 +1438,12 @@ impl Stylist {
|
|||
{
|
||||
// NB: `MatchingMode` doesn't really matter, given we don't share style
|
||||
// between pseudos.
|
||||
let mut matching_context =
|
||||
MatchingContext::new(MatchingMode::Normal, bloom, self.quirks_mode);
|
||||
let mut matching_context = MatchingContext::new(
|
||||
MatchingMode::Normal,
|
||||
bloom,
|
||||
Some(nth_index_cache),
|
||||
self.quirks_mode
|
||||
);
|
||||
|
||||
// Note that, by the time we're revalidating, we're guaranteed that the
|
||||
// candidate and the entry have the same id, classes, and local name.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue