From e8cd2193b5b3f1c42bb26c38a535095c073aa59c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Mon, 23 Sep 2019 19:08:22 +0000 Subject: [PATCH] Bug 1579585 - Use fallible allocation for stylesheet invalidation. r=jwatt If the sets get too big we cannot allocate anything else, we'll just empty them and invalidate the whole document. Differential Revision: https://phabricator.services.mozilla.com/D46828 --HG-- extra : moz-landing-system : lando --- servo/components/hashglobe/src/hash_set.rs | 8 +++++ .../style/invalidation/stylesheets.rs | 29 ++++++++++++------- 2 files changed, 27 insertions(+), 10 deletions(-) diff --git a/servo/components/hashglobe/src/hash_set.rs b/servo/components/hashglobe/src/hash_set.rs index 694e01c46eb8..ef373ae37106 100644 --- a/servo/components/hashglobe/src/hash_set.rs +++ b/servo/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/servo/components/style/invalidation/stylesheets.rs b/servo/components/style/invalidation/stylesheets.rs index 1359cce60541..244366af21db 100644 --- a/servo/components/style/invalidation/stylesheets.rs +++ b/servo/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.