diff --git a/components/style/invalidation/element/invalidation_map.rs b/components/style/invalidation/element/invalidation_map.rs index 4a1a092a2aa..58d612af122 100644 --- a/components/style/invalidation/element/invalidation_map.rs +++ b/components/style/invalidation/element/invalidation_map.rs @@ -15,7 +15,7 @@ use selectors::parser::{Selector, SelectorIter, SelectorMethods}; use selectors::visitor::SelectorVisitor; use smallvec::SmallVec; #[cfg(feature = "gecko")] -use stylesheets::{MallocEnclosingSizeOfFn, MallocSizeOfHash}; +use stylesheets::{MallocEnclosingSizeOfFn, MallocSizeOfFn, MallocSizeOfHash, MallocSizeOfVec}; #[cfg(feature = "gecko")] /// Gets the element state relevant to the given `:dir` pseudo-class selector. @@ -292,19 +292,29 @@ impl InvalidationMap { /// Measures heap usage. #[cfg(feature = "gecko")] - pub fn malloc_size_of_children(&self, malloc_enclosing_size_of: MallocEnclosingSizeOfFn) + pub fn malloc_size_of_children(&self, malloc_size_of: MallocSizeOfFn, + malloc_enclosing_size_of: MallocEnclosingSizeOfFn) -> usize { // Currently we measure the HashMap storage, but not things pointed to // by keys and values. let mut n = 0; n += self.class_to_selector.malloc_shallow_size_of_hash(malloc_enclosing_size_of); - n += self.id_to_selector.malloc_shallow_size_of_hash(malloc_enclosing_size_of); + for (_, val) in self.class_to_selector.iter() { + n += val.malloc_shallow_size_of_vec(malloc_size_of); + } - n += self.state_affecting_selectors.malloc_size_of_children(malloc_enclosing_size_of); + n += self.id_to_selector.malloc_shallow_size_of_hash(malloc_enclosing_size_of); + for (_, val) in self.id_to_selector.iter() { + n += val.malloc_shallow_size_of_vec(malloc_size_of); + } + + n += self.state_affecting_selectors.malloc_size_of_children(malloc_size_of, + malloc_enclosing_size_of); n += self.other_attribute_affecting_selectors.malloc_size_of_children( - malloc_enclosing_size_of); + malloc_size_of, malloc_enclosing_size_of); + n } } diff --git a/components/style/selector_map.rs b/components/style/selector_map.rs index 284b1a0a55f..cd96aa736d8 100644 --- a/components/style/selector_map.rs +++ b/components/style/selector_map.rs @@ -20,7 +20,7 @@ use selectors::parser::{Component, Combinator, SelectorIter}; use smallvec::{SmallVec, VecLike}; use std::hash::{BuildHasherDefault, Hash, Hasher}; #[cfg(feature = "gecko")] -use stylesheets::{MallocEnclosingSizeOfFn, MallocSizeOfHash}; +use stylesheets::{MallocEnclosingSizeOfFn, MallocSizeOfFn, MallocSizeOfHash, MallocSizeOfVec}; use stylist::Rule; /// A hasher implementation that doesn't hash anything, because it expects its @@ -149,16 +149,31 @@ impl SelectorMap { /// Measures heap usage. #[cfg(feature = "gecko")] - pub fn malloc_size_of_children(&self, malloc_enclosing_size_of: MallocEnclosingSizeOfFn) + pub fn malloc_size_of_children(&self, malloc_size_of: MallocSizeOfFn, + malloc_enclosing_size_of: MallocEnclosingSizeOfFn) -> usize { - // Currently we measure the HashMap storage, but not things pointed to - // by keys and values. - let mut n = 0; - n += self.id_hash.malloc_shallow_size_of_hash(malloc_enclosing_size_of); - n += self.class_hash.malloc_shallow_size_of_hash(malloc_enclosing_size_of); - n += self.local_name_hash.malloc_shallow_size_of_hash(malloc_enclosing_size_of); + // Currently we measure the storage used by the HashMaps, and any + // heap-allocated SmallVec values, but not things pointed to by the T + // elements within the SmallVec values. - // We may measure other fields in the future if DMD says it's worth it. + let mut n = 0; + + n += self.id_hash.malloc_shallow_size_of_hash(malloc_enclosing_size_of); + for (_, val) in self.id_hash.iter() { + n += val.malloc_shallow_size_of_vec(malloc_size_of); + } + + n += self.class_hash.malloc_shallow_size_of_hash(malloc_enclosing_size_of); + for (_, val) in self.class_hash.iter() { + n += val.malloc_shallow_size_of_vec(malloc_size_of); + } + + n += self.local_name_hash.malloc_shallow_size_of_hash(malloc_enclosing_size_of); + for (_, val) in self.local_name_hash.iter() { + n += val.malloc_shallow_size_of_vec(malloc_size_of); + } + + n += self.other.malloc_shallow_size_of_vec(malloc_size_of); n } diff --git a/components/style/stylesheets/memory.rs b/components/style/stylesheets/memory.rs index be77a7b5cbd..b9f4f438fe5 100644 --- a/components/style/stylesheets/memory.rs +++ b/components/style/stylesheets/memory.rs @@ -13,6 +13,7 @@ use hash::HashMap; #[cfg(feature = "gecko")] use servo_arc::Arc; use shared_lock::SharedRwLockReadGuard; +use smallvec::{Array, SmallVec}; use std::collections::HashSet; use std::hash::{BuildHasher, Hash}; use std::os::raw::c_void; @@ -155,6 +156,16 @@ impl MallocSizeOfVec for Vec { } } +impl MallocSizeOfVec for SmallVec { + fn malloc_shallow_size_of_vec(&self, malloc_size_of: MallocSizeOfFn) -> usize { + if self.spilled() { + unsafe { do_malloc_size_of(malloc_size_of, self.as_ptr()) } + } else { + 0 + } + } +} + /// Trait for measuring the heap usage of a hash table. pub trait MallocSizeOfHash { /// Measure shallowly the size of the memory used within a hash table -- diff --git a/components/style/stylist.rs b/components/style/stylist.rs index 46747c182b9..c9211d8267c 100644 --- a/components/style/stylist.rs +++ b/components/style/stylist.rs @@ -1956,13 +1956,13 @@ impl CascadeData { malloc_enclosing_size_of: MallocEnclosingSizeOfFn, sizes: &mut ServoStyleSetSizes) { sizes.mStylistElementAndPseudosMaps += - self.element_map.malloc_size_of_children(malloc_enclosing_size_of); + self.element_map.malloc_size_of_children(malloc_size_of, malloc_enclosing_size_of); for elem in self.pseudos_map.iter() { if let Some(ref elem) = *elem { sizes.mStylistElementAndPseudosMaps += elem.malloc_shallow_size_of_box(malloc_size_of) + - elem.malloc_size_of_children(malloc_enclosing_size_of) + elem.malloc_size_of_children(malloc_size_of, malloc_enclosing_size_of) } } @@ -1973,10 +1973,11 @@ impl CascadeData { } sizes.mStylistInvalidationMap += - self.invalidation_map.malloc_size_of_children(malloc_enclosing_size_of); + self.invalidation_map.malloc_size_of_children(malloc_size_of, malloc_enclosing_size_of); sizes.mStylistRevalidationSelectors += - self.selectors_for_cache_revalidation.malloc_size_of_children(malloc_enclosing_size_of); + self.selectors_for_cache_revalidation.malloc_size_of_children(malloc_size_of, + malloc_enclosing_size_of); sizes.mStylistOther += self.effective_media_query_results.malloc_size_of_children(malloc_enclosing_size_of);