style: Tweak recursion in add_rule to only cause a function call per recursion level

This code is really hot, and we've had perf regressions in the past for
introducing function calls in the hot path.

After the previous patch, add_rule is recursive and thus it can't be
inlined, causing a function call for each CSS rule.

This reduces the overhead by making the function take a rule list
instead, causing a function call per rule _list_, which should be
unnoticeable in practice.

Depends on D124335

Differential Revision: https://phabricator.services.mozilla.com/D124336
This commit is contained in:
Emilio Cobos Álvarez 2023-05-27 06:03:48 +02:00 committed by Oriol Brufau
parent 8705e3f39f
commit 1f62a7144d

View file

@ -2134,10 +2134,9 @@ impl CascadeData {
}
}
#[inline]
fn add_rule<S>(
fn add_rule_list<S>(
&mut self,
rule: &CssRule,
rules: std::slice::Iter<'_, CssRule>,
device: &Device,
quirks_mode: QuirksMode,
stylesheet: &S,
@ -2149,8 +2148,9 @@ impl CascadeData {
where
S: StylesheetInDocument + 'static,
{
// Handle leaf rules first, as those are by far the most common ones,
// and are always effective, so we can skip some checks.
for rule in rules {
// Handle leaf rules first, as those are by far the most common
// ones, and are always effective, so we can skip some checks.
let mut handled = true;
match *rule {
CssRule::Style(ref locked) => {
@ -2310,7 +2310,7 @@ impl CascadeData {
debug_assert!(children.is_none());
debug_assert!(effective);
}
return Ok(());
continue;
}
let mut effective = false;
@ -2323,7 +2323,7 @@ impl CascadeData {
);
if !effective {
return Ok(());
continue;
}
let mut layer_names_to_pop = 0;
@ -2381,9 +2381,8 @@ impl CascadeData {
}
if let Some(children) = children {
for child in children {
self.add_rule(
child,
self.add_rule_list(
children,
device,
quirks_mode,
stylesheet,
@ -2393,11 +2392,11 @@ impl CascadeData {
precomputed_pseudo_element_decls.as_deref_mut(),
)?;
}
}
for _ in 0..layer_names_to_pop {
current_layer.0.pop();
}
}
Ok(())
}
@ -2426,10 +2425,8 @@ impl CascadeData {
}
let mut current_layer = LayerName::new_empty();
for rule in contents.rules(guard).iter() {
self.add_rule(
rule,
self.add_rule_list(
contents.rules(guard).iter(),
device,
quirks_mode,
stylesheet,
@ -2438,7 +2435,6 @@ impl CascadeData {
&mut current_layer,
precomputed_pseudo_element_decls.as_deref_mut(),
)?;
}
Ok(())
}