Auto merge of #20248 - emilio:invalidation-selectors-faster, r=bholley

style: Change the order we match selectors on invalidation to match normal order.

This changes the order to match the normal selector-matching order, which is
usually faster.

That is, when matching div:nth-child(2), for example, before this patch we'd
first try to match :nth-child(2), and only then div.

This patch makes us walk until the end or the next combinator, and only then
match backwards, matching first div, then :nth-child.

Bug: 1443814
Reviewed-by: bholley

<!-- 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/20248)
<!-- Reviewable:end -->
This commit is contained in:
bors-servo 2018-03-08 18:44:29 -05:00 committed by GitHub
commit 8e52f8a523
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -249,23 +249,52 @@ where
matches_hover_and_active_quirk: MatchesHoverAndActiveQuirk::No,
};
// Find the end of the selector or the next combinator, then match
// backwards, so that we match in the same order as
// matches_complex_selector, which is usually faster.
let start_offset = from_offset;
for component in selector.iter_raw_parse_order_from(from_offset) {
if matches!(*component, Component::Combinator(..)) {
debug_assert_ne!(from_offset, 0, "Selector started with a combinator?");
return CompoundSelectorMatchingResult::Matched {
next_combinator_offset: from_offset,
}
break;
}
from_offset += 1;
}
debug_assert!(from_offset >= 1);
debug_assert!(from_offset <= selector.len());
let iter = selector.iter_from(selector.len() - from_offset);
debug_assert!(
iter.clone().next().is_some() || (
from_offset != selector.len() && matches!(
selector.combinator_at_parse_order(from_offset),
Combinator::SlotAssignment | Combinator::PseudoElement
)
),
"Got the math wrong: {:?} | {:?} | {} {}",
selector,
selector.iter_raw_match_order().as_slice(),
from_offset,
start_offset
);
for component in iter {
if !matches_simple_selector(
component,
element,
&mut local_context,
&mut |_, _| {}) {
&mut |_, _| {}
) {
return CompoundSelectorMatchingResult::NotMatched;
}
}
from_offset += 1;
if from_offset != selector.len() {
return CompoundSelectorMatchingResult::Matched {
next_combinator_offset: from_offset,
}
}
CompoundSelectorMatchingResult::FullyMatched