From a41127152b333d7f59554d630e5bfee64d7cfd73 Mon Sep 17 00:00:00 2001 From: Cameron McCormack Date: Thu, 12 Jul 2018 19:44:00 +1000 Subject: [PATCH] style: Measure heap allocations hanging off selector components. Bug: 1475191 Reviewed-by: emilio MozReview-Commit-ID: D7vZQ7v8owS --- components/malloc_size_of/lib.rs | 84 +++++++++++++++++++ .../gecko/pseudo_element_definition.mako.rs | 2 +- components/style/gecko/selector_parser.rs | 2 +- components/style/selector_parser.rs | 2 +- components/style/stylesheets/style_rule.rs | 15 +--- 5 files changed, 89 insertions(+), 16 deletions(-) diff --git a/components/malloc_size_of/lib.rs b/components/malloc_size_of/lib.rs index eaec2cb20dc..641d276483e 100644 --- a/components/malloc_size_of/lib.rs +++ b/components/malloc_size_of/lib.rs @@ -693,6 +693,90 @@ impl MallocSizeOf for selectors::parser::AncestorHashes { } } +impl MallocSizeOf + for selectors::parser::Selector +where + Impl::NonTSPseudoClass: MallocSizeOf, + Impl::PseudoElement: MallocSizeOf, +{ + fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize { + let mut n = 0; + + // It's OK to measure this ThinArc directly because it's the + // "primary" reference. (The secondary references are on the + // Stylist.) + n += unsafe { ops.malloc_size_of(self.thin_arc_heap_ptr()) }; + for component in self.iter_raw_match_order() { + n += component.size_of(ops); + } + + n + } +} + +impl MallocSizeOf + for selectors::parser::Component +where + Impl::NonTSPseudoClass: MallocSizeOf, + Impl::PseudoElement: MallocSizeOf, +{ + fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize { + use selectors::parser::Component; + + match self { + Component::AttributeOther(ref attr_selector) => { + attr_selector.size_of(ops) + } + Component::Negation(ref components) => { + components.size_of(ops) + } + Component::NonTSPseudoClass(ref pseudo) => { + (*pseudo).size_of(ops) + } + Component::Slotted(ref selector) | + Component::Host(Some(ref selector)) => { + selector.size_of(ops) + } + Component::PseudoElement(ref pseudo) => { + (*pseudo).size_of(ops) + } + Component::Combinator(..) | + Component::ExplicitAnyNamespace | + Component::ExplicitNoNamespace | + Component::DefaultNamespace(..) | + Component::Namespace(..) | + Component::ExplicitUniversalType | + Component::LocalName(..) | + Component::ID(..) | + Component::Class(..) | + Component::AttributeInNoNamespaceExists { .. } | + Component::AttributeInNoNamespace { .. } | + Component::FirstChild | + Component::LastChild | + Component::OnlyChild | + Component::Root | + Component::Empty | + Component::Scope | + Component::NthChild(..) | + Component::NthLastChild(..) | + Component::NthOfType(..) | + Component::NthLastOfType(..) | + Component::FirstOfType | + Component::LastOfType | + Component::OnlyOfType | + Component::Host(None) => 0, + } + } +} + +impl MallocSizeOf + for selectors::attr::AttrSelectorWithNamespace +{ + fn size_of(&self, _ops: &mut MallocSizeOfOps) -> usize { + 0 + } +} + impl MallocSizeOf for Void { #[inline] fn size_of(&self, _ops: &mut MallocSizeOfOps) -> usize { diff --git a/components/style/gecko/pseudo_element_definition.mako.rs b/components/style/gecko/pseudo_element_definition.mako.rs index caaeeac629d..216650c9295 100644 --- a/components/style/gecko/pseudo_element_definition.mako.rs +++ b/components/style/gecko/pseudo_element_definition.mako.rs @@ -3,7 +3,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /// Gecko's pseudo-element definition. -#[derive(Clone, Debug, Eq, Hash, PartialEq)] +#[derive(Clone, Debug, Eq, Hash, MallocSizeOf, PartialEq)] pub enum PseudoElement { % for pseudo in PSEUDOS: /// ${pseudo.value} diff --git a/components/style/gecko/selector_parser.rs b/components/style/gecko/selector_parser.rs index 7dfc9aa1bbc..45f42acc09d 100644 --- a/components/style/gecko/selector_parser.rs +++ b/components/style/gecko/selector_parser.rs @@ -40,7 +40,7 @@ macro_rules! pseudo_class_name { (bare: [$(($css:expr, $name:ident, $gecko_type:tt, $state:tt, $flags:tt),)*], string: [$(($s_css:expr, $s_name:ident, $s_gecko_type:tt, $s_state:tt, $s_flags:tt),)*]) => { /// Our representation of a non tree-structural pseudo-class. - #[derive(Clone, Debug, Eq, PartialEq)] + #[derive(Clone, Debug, Eq, MallocSizeOf, PartialEq)] pub enum NonTSPseudoClass { $( #[doc = $css] diff --git a/components/style/selector_parser.rs b/components/style/selector_parser.rs index e93085af141..7250502b1ad 100644 --- a/components/style/selector_parser.rs +++ b/components/style/selector_parser.rs @@ -172,7 +172,7 @@ impl PerPseudoElementMap { } /// Values for the :dir() pseudo class -#[derive(Clone, Debug, Eq, PartialEq)] +#[derive(Clone, Debug, Eq, MallocSizeOf, PartialEq)] pub enum Direction { /// left-to-right semantic directionality Ltr, diff --git a/components/style/stylesheets/style_rule.rs b/components/style/stylesheets/style_rule.rs index 9a34c203818..c161cc43ee2 100644 --- a/components/style/stylesheets/style_rule.rs +++ b/components/style/stylesheets/style_rule.rs @@ -6,7 +6,7 @@ use cssparser::SourceLocation; #[cfg(feature = "gecko")] -use malloc_size_of::{MallocShallowSizeOf, MallocSizeOf, MallocSizeOfOps}; +use malloc_size_of::{MallocSizeOf, MallocSizeOfOps}; #[cfg(feature = "gecko")] use malloc_size_of::MallocUnconditionalShallowSizeOf; use properties::PropertyDeclarationBlock; @@ -50,20 +50,9 @@ impl StyleRule { #[cfg(feature = "gecko")] pub fn size_of(&self, guard: &SharedRwLockReadGuard, ops: &mut MallocSizeOfOps) -> usize { let mut n = 0; - - // We may add measurement of things hanging off the embedded Components - // later. - n += self.selectors.0.shallow_size_of(ops); - for selector in self.selectors.0.iter() { - // It's safe to measure this ThinArc directly because it's the - // "primary" reference. (The secondary references are on the - // Stylist.) - n += unsafe { ops.malloc_size_of(selector.thin_arc_heap_ptr()) }; - } - + n += self.selectors.0.size_of(ops); n += self.block.unconditional_shallow_size_of(ops) + self.block.read_with(guard).size_of(ops); - n } }