diff --git a/components/hashglobe/src/hash_set.rs b/components/hashglobe/src/hash_set.rs index 694e01c46eb..ef373ae3710 100644 --- a/components/hashglobe/src/hash_set.rs +++ b/components/hashglobe/src/hash_set.rs @@ -17,6 +17,8 @@ use std::ops::{BitAnd, BitOr, BitXor, Sub}; use super::hash_map::{self, HashMap, Keys, RandomState}; use super::Recover; +use crate::FailedAllocationError; + // Future Optimization (FIXME!) // ============================= // @@ -589,6 +591,12 @@ where self.map.insert(value, ()).is_none() } + /// Fallible version of `insert`. + #[inline] + pub fn try_insert(&mut self, value: T) -> Result { + Ok(self.map.try_insert(value, ())?.is_none()) + } + /// Adds a value to the set, replacing the existing value, if any, that is equal to the given /// one. Returns the replaced value. pub fn replace(&mut self, value: T) -> Option { diff --git a/components/style/invalidation/stylesheets.rs b/components/style/invalidation/stylesheets.rs index 1359cce6054..244366af21d 100644 --- a/components/style/invalidation/stylesheets.rs +++ b/components/style/invalidation/stylesheets.rs @@ -8,6 +8,7 @@ #![deny(unsafe_code)] use crate::dom::{TDocument, TElement, TNode}; +use crate::hash::HashSet; use crate::invalidation::element::element_wrapper::{ElementSnapshot, ElementWrapper}; use crate::invalidation::element::restyle_hints::RestyleHint; use crate::media_queries::Device; @@ -17,9 +18,12 @@ use crate::stylesheets::{CssRule, StylesheetInDocument}; use crate::Atom; use crate::CaseSensitivityExt; use crate::LocalName as SelectorLocalName; -use fxhash::FxHashSet; +use fxhash::FxHasher; use selectors::attr::CaseSensitivity; use selectors::parser::{Component, LocalName, Selector}; +use std::hash::BuildHasherDefault; + +type FxHashSet = HashSet>; /// A style sheet invalidation represents a kind of element or subtree that may /// need to be restyled. Whether it represents a whole subtree or just a single @@ -400,16 +404,21 @@ impl StylesheetInvalidationSet { if let Some(s) = subtree_invalidation { debug!(" > Found subtree invalidation: {:?}", s); - self.invalid_scopes.insert(s); - } else if let Some(s) = element_invalidation { - debug!(" > Found element invalidation: {:?}", s); - self.invalid_elements.insert(s); - } else { - // The selector was of a form that we can't handle. Any element - // could match it, so let's just bail out. - debug!(" > Can't handle selector, marking fully invalid"); - self.fully_invalid = true; + if self.invalid_scopes.try_insert(s).is_ok() { + return; + } } + if let Some(s) = element_invalidation { + debug!(" > Found element invalidation: {:?}", s); + if self.invalid_elements.try_insert(s).is_ok() { + return; + } + } + + // The selector was of a form that we can't handle. Any element could + // match it, so let's just bail out. + debug!(" > Can't handle selector or OOMd, marking fully invalid"); + self.fully_invalid = true; } /// Collects invalidations for a given CSS rule.