Auto merge of #18387 - nnethercote:measure-smallvec, r=heycam

Measure SmallVecs in SelectorMap and InvalidationMap.

<!-- Please describe your changes on the following line: -->

This is another ~300 KiB on the Obama wikipedia page.

---
<!-- Thank you for contributing to Servo! Please replace each `[ ]` by `[X]` when the step is complete, and replace `__` with appropriate data: -->
- [X] `./mach build -d` does not report any errors
- [X] `./mach test-tidy` does not report any errors
- [ ] These changes fix #__ (github issue number if applicable).

<!-- Either: -->
- [ ] There are tests for these changes OR
- [X] These changes do not require tests because testing is on the Gecko side.

<!-- Also, please make sure that "Allow edits from maintainers" checkbox is checked, so that we can help you if you get stuck somewhere along the way.-->

<!-- Pull requests that do not address these steps are welcome, but they will require additional verification as part of the review process. -->

r? @heycam

<!-- Reviewable:start -->
---
This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/18387)
<!-- Reviewable:end -->
This commit is contained in:
bors-servo 2017-09-06 01:39:35 -05:00 committed by GitHub
commit 6051e5ed02
4 changed files with 55 additions and 18 deletions

View file

@ -15,7 +15,7 @@ use selectors::parser::{Selector, SelectorIter, SelectorMethods};
use selectors::visitor::SelectorVisitor; use selectors::visitor::SelectorVisitor;
use smallvec::SmallVec; use smallvec::SmallVec;
#[cfg(feature = "gecko")] #[cfg(feature = "gecko")]
use stylesheets::{MallocEnclosingSizeOfFn, MallocSizeOfHash}; use stylesheets::{MallocEnclosingSizeOfFn, MallocSizeOfFn, MallocSizeOfHash, MallocSizeOfVec};
#[cfg(feature = "gecko")] #[cfg(feature = "gecko")]
/// Gets the element state relevant to the given `:dir` pseudo-class selector. /// Gets the element state relevant to the given `:dir` pseudo-class selector.
@ -292,19 +292,29 @@ impl InvalidationMap {
/// Measures heap usage. /// Measures heap usage.
#[cfg(feature = "gecko")] #[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 { -> usize {
// Currently we measure the HashMap storage, but not things pointed to // Currently we measure the HashMap storage, but not things pointed to
// by keys and values. // by keys and values.
let mut n = 0; let mut n = 0;
n += self.class_to_selector.malloc_shallow_size_of_hash(malloc_enclosing_size_of); 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( n += self.other_attribute_affecting_selectors.malloc_size_of_children(
malloc_enclosing_size_of); malloc_size_of, malloc_enclosing_size_of);
n n
} }
} }

View file

@ -20,7 +20,7 @@ use selectors::parser::{Component, Combinator, SelectorIter};
use smallvec::{SmallVec, VecLike}; use smallvec::{SmallVec, VecLike};
use std::hash::{BuildHasherDefault, Hash, Hasher}; use std::hash::{BuildHasherDefault, Hash, Hasher};
#[cfg(feature = "gecko")] #[cfg(feature = "gecko")]
use stylesheets::{MallocEnclosingSizeOfFn, MallocSizeOfHash}; use stylesheets::{MallocEnclosingSizeOfFn, MallocSizeOfFn, MallocSizeOfHash, MallocSizeOfVec};
use stylist::Rule; use stylist::Rule;
/// A hasher implementation that doesn't hash anything, because it expects its /// A hasher implementation that doesn't hash anything, because it expects its
@ -149,16 +149,31 @@ impl<T: 'static> SelectorMap<T> {
/// Measures heap usage. /// Measures heap usage.
#[cfg(feature = "gecko")] #[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 { -> usize {
// Currently we measure the HashMap storage, but not things pointed to // Currently we measure the storage used by the HashMaps, and any
// by keys and values. // heap-allocated SmallVec values, but not things pointed to by the T
let mut n = 0; // elements within the SmallVec values.
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);
// 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 n
} }

View file

@ -13,6 +13,7 @@ use hash::HashMap;
#[cfg(feature = "gecko")] #[cfg(feature = "gecko")]
use servo_arc::Arc; use servo_arc::Arc;
use shared_lock::SharedRwLockReadGuard; use shared_lock::SharedRwLockReadGuard;
use smallvec::{Array, SmallVec};
use std::collections::HashSet; use std::collections::HashSet;
use std::hash::{BuildHasher, Hash}; use std::hash::{BuildHasher, Hash};
use std::os::raw::c_void; use std::os::raw::c_void;
@ -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. /// Trait for measuring the heap usage of a hash table.
pub trait MallocSizeOfHash { pub trait MallocSizeOfHash {
/// Measure shallowly the size of the memory used within a hash table -- /// Measure shallowly the size of the memory used within a hash table --

View file

@ -1956,13 +1956,13 @@ impl CascadeData {
malloc_enclosing_size_of: MallocEnclosingSizeOfFn, malloc_enclosing_size_of: MallocEnclosingSizeOfFn,
sizes: &mut ServoStyleSetSizes) { sizes: &mut ServoStyleSetSizes) {
sizes.mStylistElementAndPseudosMaps += 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() { for elem in self.pseudos_map.iter() {
if let Some(ref elem) = *elem { if let Some(ref elem) = *elem {
sizes.mStylistElementAndPseudosMaps += sizes.mStylistElementAndPseudosMaps +=
elem.malloc_shallow_size_of_box(malloc_size_of) + 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 += 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 += 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 += sizes.mStylistOther +=
self.effective_media_query_results.malloc_size_of_children(malloc_enclosing_size_of); self.effective_media_query_results.malloc_size_of_children(malloc_enclosing_size_of);