tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

commit a59aa956ea3465e55a123e96729e1fdbb6b8bf8a
parent 6f16921de968c5da990eeabdd43fb1eb2c4d0339
Author: David Shin <dshin@mozilla.com>
Date:   Mon, 15 Dec 2025 20:14:05 +0000

Bug 2002747: Early-reject relative selector invalidation that doesn't match local name. r=firefox-style-system-reviewers,perftest-reviewers,emilio,sparky

Differential Revision: https://phabricator.services.mozilla.com/D276266

Diffstat:
Mservo/components/selectors/matching.rs | 31+++++++++++++++++++++++++++++++
Mservo/components/style/invalidation/element/relative_selector.rs | 13++++++++++---
Atesting/talos/talos/tests/perf-reftest-singletons/has-reject-by-local-name.html | 31+++++++++++++++++++++++++++++++
Mtesting/talos/talos/tests/perf-reftest-singletons/perf_reftest_singletons.manifest | 1+
4 files changed, 73 insertions(+), 3 deletions(-)

diff --git a/servo/components/selectors/matching.rs b/servo/components/selectors/matching.rs @@ -318,6 +318,37 @@ pub enum CompoundSelectorMatchingResult { NotMatched, } +fn complex_selector_early_reject_by_local_name<E: Element>( + list: &SelectorList<E::Impl>, + element: &E, +) -> bool { + list.slice() + .iter() + .all(|s| early_reject_by_local_name(s, 0, element)) +} + +/// Returns true if this compound would not match the given element by due +/// to a local name selector (If one exists). +pub fn early_reject_by_local_name<E: Element>( + selector: &Selector<E::Impl>, + from_offset: usize, + element: &E, +) -> bool { + let iter = selector.iter_from(from_offset); + for component in iter { + if match component { + Component::LocalName(name) => !matches_local_name(element, name), + Component::Is(list) | Component::Where(list) => { + complex_selector_early_reject_by_local_name(list, element) + }, + _ => continue, + } { + return true; + } + } + false +} + /// Matches a compound selector belonging to `selector`, starting at offset /// `from_offset`, matching left to right. /// diff --git a/servo/components/style/invalidation/element/relative_selector.rs b/servo/components/style/invalidation/element/relative_selector.rs @@ -30,9 +30,9 @@ use crate::stylist::{CascadeData, Stylist}; use dom::ElementState; use rustc_hash::FxHashMap; use selectors::matching::{ - matches_selector, ElementSelectorFlags, IncludeStartingStyle, MatchingContext, - MatchingForInvalidation, MatchingMode, NeedsSelectorFlags, QuirksMode, SelectorCaches, - VisitedHandlingMode, + early_reject_by_local_name, matches_selector, ElementSelectorFlags, + IncludeStartingStyle, MatchingContext, MatchingForInvalidation, MatchingMode, + NeedsSelectorFlags, QuirksMode, SelectorCaches, VisitedHandlingMode, }; use selectors::parser::SelectorKey; use selectors::OpaqueElement; @@ -497,6 +497,13 @@ where { return; } + if early_reject_by_local_name( + &dependency.selector, + dependency.selector_offset, + &element, + ) { + return; + } self.insert_invalidation(element, dependency, host); }, }; diff --git a/testing/talos/talos/tests/perf-reftest-singletons/has-reject-by-local-name.html b/testing/talos/talos/tests/perf-reftest-singletons/has-reject-by-local-name.html @@ -0,0 +1,31 @@ +<!DOCTYPE html> +<style> +#anchor:has(section[class*=nonexistent].bar .item) { + color: green; +} +</style> +<script src="util.js"></script> +<script> +window.onload = function() { + function create_tree(depth, width) { + const d = document.createElement("div"); + if (depth != 0) { + for (let i = 0; i < width; i++) { + d.appendChild(create_tree(depth - 1, width)); + } + } else { + d.classList.add("item"); + } + return d; + } + anchor.appendChild(create_tree(4, 30)); + flush_layout(); + perf_start(); + for (const d of anchor.children[0].children) { + d.classList.add("bar"); + } + flush_layout(); + perf_finish(); +}; +</script> +<div id=anchor></div> diff --git a/testing/talos/talos/tests/perf-reftest-singletons/perf_reftest_singletons.manifest b/testing/talos/talos/tests/perf-reftest-singletons/perf_reftest_singletons.manifest @@ -49,4 +49,5 @@ % http://localhost/tests/perf-reftest-singletons/deeply-nested-grid-2.html % http://localhost/tests/perf-reftest-singletons/insert-subtree-not-nth-edge-has-pseudo.html % http://localhost/tests/perf-reftest-singletons/remove-tons-of-table-rows.html +% http://localhost/tests/perf-reftest-singletons/has-reject-by-local-name.html # When modifying this list, please also update build/pgo/index.html (If relevant to profile-guided optimzation).