style: Shrink maps if needed after stylist rebuilds

Hashbrown grows a lot sometimes making us waste a lot of memory. Shrink
some of these maps after CascadeData rebuild / stylesheet collection
invalidation.

Differential Revision: https://phabricator.services.mozilla.com/D134716
This commit is contained in:
Emilio Cobos Álvarez 2023-06-06 23:27:20 +02:00 committed by Oriol Brufau
parent f9610e5898
commit fcc55f2156
6 changed files with 122 additions and 17 deletions

View file

@ -12,7 +12,7 @@ use crate::rule_tree::CascadeLevel;
use crate::selector_parser::SelectorImpl;
use crate::stylist::{CascadeData, Rule};
use crate::AllocErr;
use crate::{Atom, LocalName, Namespace, WeakAtom};
use crate::{Atom, LocalName, Namespace, ShrinkIfNeeded, WeakAtom};
use precomputed_hash::PrecomputedHash;
use selectors::matching::{matches_selector, ElementSelectorFlags, MatchingContext};
use selectors::parser::{Combinator, Component, SelectorIter};
@ -122,10 +122,7 @@ impl<T: 'static> Default for SelectorMap<T> {
}
}
// FIXME(Manishearth) the 'static bound can be removed when
// our HashMap fork (hashglobe) is able to use NonZero,
// or when stdlib gets fallible collections
impl<T: 'static> SelectorMap<T> {
impl<T> SelectorMap<T> {
/// Trivially constructs an empty `SelectorMap`.
pub fn new() -> Self {
SelectorMap {
@ -152,6 +149,15 @@ impl<T: 'static> SelectorMap<T> {
ret
}
/// Shrink the capacity of the map if needed.
pub fn shrink_if_needed(&mut self) {
self.id_hash.shrink_if_needed();
self.class_hash.shrink_if_needed();
self.attribute_hash.shrink_if_needed();
self.local_name_hash.shrink_if_needed();
self.namespace_hash.shrink_if_needed();
}
/// Clears the hashmap retaining storage.
pub fn clear(&mut self) {
self.root.clear();
@ -715,26 +721,28 @@ fn find_bucket<'a>(
/// Wrapper for PrecomputedHashMap that does ASCII-case-insensitive lookup in quirks mode.
#[derive(Clone, Debug, MallocSizeOf)]
pub struct MaybeCaseInsensitiveHashMap<K: PrecomputedHash + Hash + Eq, V: 'static>(
pub struct MaybeCaseInsensitiveHashMap<K: PrecomputedHash + Hash + Eq, V>(
PrecomputedHashMap<K, V>,
);
impl<V: 'static> Default for MaybeCaseInsensitiveHashMap<Atom, V> {
impl<V> Default for MaybeCaseInsensitiveHashMap<Atom, V> {
#[inline]
fn default() -> Self {
MaybeCaseInsensitiveHashMap(PrecomputedHashMap::default())
}
}
// FIXME(Manishearth) the 'static bound can be removed when
// our HashMap fork (hashglobe) is able to use NonZero,
// or when stdlib gets fallible collections
impl<V: 'static> MaybeCaseInsensitiveHashMap<Atom, V> {
impl<V> MaybeCaseInsensitiveHashMap<Atom, V> {
/// Empty map
pub fn new() -> Self {
Self::default()
}
/// Shrink the capacity of the map if needed.
pub fn shrink_if_needed(&mut self) {
self.0.shrink_if_needed()
}
/// HashMap::try_entry
pub fn try_entry(
&mut self,