Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Measure SmallVecs in SelectorMap and InvalidationMap. #18387

Merged
merged 1 commit into from Sep 6, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
18 changes: 14 additions & 4 deletions components/style/invalidation/element/invalidation_map.rs
Expand Up @@ -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.
Expand Down Expand Up @@ -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);
for (_, val) in self.class_to_selector.iter() {
n += val.malloc_shallow_size_of_vec(malloc_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_enclosing_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
}
}
Expand Down
25 changes: 20 additions & 5 deletions components/style/selector_map.rs
Expand Up @@ -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
Expand Down Expand Up @@ -149,16 +149,31 @@ impl<T: 'static> SelectorMap<T> {

/// 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.
// 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.

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);
}

// We may measure other fields in the future if DMD says it's worth it.
n += self.other.malloc_shallow_size_of_vec(malloc_size_of);

n
}
Expand Down
11 changes: 11 additions & 0 deletions components/style/stylesheets/memory.rs
Expand Up @@ -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;
Expand Down Expand Up @@ -155,6 +156,16 @@ impl<T> MallocSizeOfVec for Vec<T> {
}
}

impl<A: Array> MallocSizeOfVec for SmallVec<A> {
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 --
Expand Down
9 changes: 5 additions & 4 deletions components/style/stylist.rs
Expand Up @@ -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)
}
}

Expand All @@ -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);
Expand Down