diff --git a/components/selectors/parser.rs b/components/selectors/parser.rs index 45ff70df416..c17e8af1a71 100644 --- a/components/selectors/parser.rs +++ b/components/selectors/parser.rs @@ -423,7 +423,6 @@ impl Selector { )) } - /// Returns an iterator over this selector in matching order (right-to-left). /// When a combinator is reached, the iterator will return None, and /// next_sequence() may be called to continue to the next sequence. @@ -494,6 +493,11 @@ impl Selector { pub fn len(&self) -> usize { self.0.slice.len() } + + /// Returns the address on the heap of the ThinArc for memory reporting. + pub fn thin_arc_heap_ptr(&self) -> *const ::std::os::raw::c_void { + self.0.heap_ptr() + } } #[derive(Clone)] diff --git a/components/servo_arc/lib.rs b/components/servo_arc/lib.rs index 2d0dbd8236c..5cac8c9b9bb 100644 --- a/components/servo_arc/lib.rs +++ b/components/servo_arc/lib.rs @@ -676,6 +676,12 @@ impl ThinArc { // Forward the result. result } + + /// Returns the address on the heap of the ThinArc itself -- not the T + /// within it -- for memory reporting. + pub fn heap_ptr(&self) -> *const c_void { + self.ptr as *const ArcInner as *const c_void + } } impl Deref for ThinArc { diff --git a/components/style/stylesheets/document_rule.rs b/components/style/stylesheets/document_rule.rs index 5465a4b9759..327994ad3ae 100644 --- a/components/style/stylesheets/document_rule.rs +++ b/components/style/stylesheets/document_rule.rs @@ -13,7 +13,7 @@ use servo_arc::Arc; use shared_lock::{DeepCloneParams, DeepCloneWithLock, Locked, SharedRwLock, SharedRwLockReadGuard, ToCssWithGuard}; use std::fmt; use style_traits::{ToCss, ParseError, StyleParseError}; -use stylesheets::CssRules; +use stylesheets::{CssRules, MallocSizeOfFn, MallocSizeOfWithGuard}; use values::specified::url::SpecifiedUrl; #[derive(Debug)] @@ -27,6 +27,15 @@ pub struct DocumentRule { pub source_location: SourceLocation, } +impl DocumentRule { + /// Measure heap usage. + pub fn malloc_size_of_children(&self, guard: &SharedRwLockReadGuard, + malloc_size_of: MallocSizeOfFn) -> usize { + // Measurement of other fields may be added later. + self.rules.read_with(guard).malloc_size_of_children(guard, malloc_size_of) + } +} + impl ToCssWithGuard for DocumentRule { fn to_css(&self, guard: &SharedRwLockReadGuard, dest: &mut W) -> fmt::Result where W: fmt::Write { diff --git a/components/style/stylesheets/media_rule.rs b/components/style/stylesheets/media_rule.rs index 4eb68999113..f336dc12d89 100644 --- a/components/style/stylesheets/media_rule.rs +++ b/components/style/stylesheets/media_rule.rs @@ -12,7 +12,7 @@ use servo_arc::Arc; use shared_lock::{DeepCloneParams, DeepCloneWithLock, Locked, SharedRwLock, SharedRwLockReadGuard, ToCssWithGuard}; use std::fmt; use style_traits::ToCss; -use stylesheets::CssRules; +use stylesheets::{CssRules, MallocSizeOfFn, MallocSizeOfWithGuard}; /// An [`@media`][media] urle. /// @@ -27,6 +27,15 @@ pub struct MediaRule { pub source_location: SourceLocation, } +impl MediaRule { + /// Measure heap usage. + pub fn malloc_size_of_children(&self, guard: &SharedRwLockReadGuard, + malloc_size_of: MallocSizeOfFn) -> usize { + // Measurement of other fields may be added later. + self.rules.read_with(guard).malloc_size_of_children(guard, malloc_size_of) + } +} + impl ToCssWithGuard for MediaRule { // Serialization of MediaRule is not specced. // https://drafts.csswg.org/cssom/#serialize-a-css-rule CSSMediaRule diff --git a/components/style/stylesheets/mod.rs b/components/style/stylesheets/mod.rs index 78c4e6d2dfb..87ee2b413c0 100644 --- a/components/style/stylesheets/mod.rs +++ b/components/style/stylesheets/mod.rs @@ -116,21 +116,40 @@ impl MallocSizeOfWithGuard for CssRule { malloc_size_of: MallocSizeOfFn ) -> usize { match *self { + // Not all fields are currently fully measured. Extra measurement + // may be added later. + + CssRule::Namespace(_) => 0, + + // We don't need to measure ImportRule::stylesheet because we measure + // it on the C++ side in the child list of the ServoStyleSheet. + CssRule::Import(_) => 0, + CssRule::Style(ref lock) => { lock.read_with(guard).malloc_size_of_children(guard, malloc_size_of) }, - // Measurement of these fields may be added later. - CssRule::Import(_) => 0, - CssRule::Media(_) => 0, + + CssRule::Media(ref lock) => { + lock.read_with(guard).malloc_size_of_children(guard, malloc_size_of) + }, + CssRule::FontFace(_) => 0, CssRule::FontFeatureValues(_) => 0, CssRule::CounterStyle(_) => 0, - CssRule::Keyframes(_) => 0, - CssRule::Namespace(_) => 0, CssRule::Viewport(_) => 0, - CssRule::Supports(_) => 0, - CssRule::Page(_) => 0, - CssRule::Document(_) => 0, + CssRule::Keyframes(_) => 0, + + CssRule::Supports(ref lock) => { + lock.read_with(guard).malloc_size_of_children(guard, malloc_size_of) + }, + + CssRule::Page(ref lock) => { + lock.read_with(guard).malloc_size_of_children(guard, malloc_size_of) + }, + + CssRule::Document(ref lock) => { + lock.read_with(guard).malloc_size_of_children(guard, malloc_size_of) + }, } } } diff --git a/components/style/stylesheets/page_rule.rs b/components/style/stylesheets/page_rule.rs index f47c1316a50..c334df44042 100644 --- a/components/style/stylesheets/page_rule.rs +++ b/components/style/stylesheets/page_rule.rs @@ -12,6 +12,7 @@ use servo_arc::Arc; use shared_lock::{DeepCloneParams, DeepCloneWithLock, Locked, SharedRwLock, SharedRwLockReadGuard, ToCssWithGuard}; use std::fmt; use style_traits::ToCss; +use stylesheets::{MallocSizeOf, MallocSizeOfFn}; /// A [`@page`][page] rule. /// @@ -30,6 +31,15 @@ pub struct PageRule { pub source_location: SourceLocation, } +impl PageRule { + /// Measure heap usage. + pub fn malloc_size_of_children(&self, guard: &SharedRwLockReadGuard, + malloc_size_of: MallocSizeOfFn) -> usize { + // Measurement of other fields may be added later. + self.block.read_with(guard).malloc_size_of_children(malloc_size_of) + } +} + impl ToCssWithGuard for PageRule { /// Serialization of PageRule is not specced, adapted from steps for /// StyleRule. diff --git a/components/style/stylesheets/style_rule.rs b/components/style/stylesheets/style_rule.rs index a66ad7eb5e8..72dbbed0548 100644 --- a/components/style/stylesheets/style_rule.rs +++ b/components/style/stylesheets/style_rule.rs @@ -12,7 +12,7 @@ use servo_arc::Arc; use shared_lock::{DeepCloneParams, DeepCloneWithLock, Locked, SharedRwLock, SharedRwLockReadGuard, ToCssWithGuard}; use std::fmt; use style_traits::ToCss; -use stylesheets::{MallocSizeOf, MallocSizeOfFn, MallocSizeOfWithGuard}; +use stylesheets::{MallocSizeOf, MallocSizeOfFn, MallocSizeOfVec, MallocSizeOfWithGuard}; /// A style rule, with selectors and declarations. #[derive(Debug)] @@ -47,8 +47,22 @@ impl MallocSizeOfWithGuard for StyleRule { guard: &SharedRwLockReadGuard, malloc_size_of: MallocSizeOfFn ) -> usize { - // Measurement of other fields may be added later. - self.block.read_with(guard).malloc_size_of_children(malloc_size_of) + let mut n = 0; + + // We may add measurement of things hanging off the embedded Components + // later. + n += self.selectors.0.malloc_shallow_size_of_vec(malloc_size_of); + 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.) + let ptr = selector.thin_arc_heap_ptr(); + n += unsafe { (malloc_size_of.0)(ptr) }; + } + + n += self.block.read_with(guard).malloc_size_of_children(malloc_size_of); + + n } } diff --git a/components/style/stylesheets/supports_rule.rs b/components/style/stylesheets/supports_rule.rs index 96c7e7b6cc3..ee5e7516642 100644 --- a/components/style/stylesheets/supports_rule.rs +++ b/components/style/stylesheets/supports_rule.rs @@ -13,7 +13,7 @@ use servo_arc::Arc; use shared_lock::{DeepCloneParams, DeepCloneWithLock, Locked, SharedRwLock, SharedRwLockReadGuard, ToCssWithGuard}; use std::fmt; use style_traits::{ToCss, ParseError, StyleParseError}; -use stylesheets::{CssRuleType, CssRules}; +use stylesheets::{CssRuleType, CssRules, MallocSizeOfFn, MallocSizeOfWithGuard}; /// An [`@supports`][supports] rule. /// @@ -30,6 +30,15 @@ pub struct SupportsRule { pub source_location: SourceLocation, } +impl SupportsRule { + /// Measure heap usage. + pub fn malloc_size_of_children(&self, guard: &SharedRwLockReadGuard, + malloc_size_of: MallocSizeOfFn) -> usize { + // Measurement of other fields may be added later. + self.rules.read_with(guard).malloc_size_of_children(guard, malloc_size_of) + } +} + impl ToCssWithGuard for SupportsRule { fn to_css(&self, guard: &SharedRwLockReadGuard, dest: &mut W) -> fmt::Result where W: fmt::Write {