Auto merge of #18568 - nnethercote:bug-1400078, r=emilio

Measure the UA cache.

This is the Servo PR for https://bugzilla.mozilla.org/show_bug.cgi?id=1400078

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

---
<!-- 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
- [X] These changes fix https://bugzilla.mozilla.org/show_bug.cgi?id=1400078

<!-- Either: -->
- [ ] There are tests for these changes OR
- [X] These changes do not require tests because tested on 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. -->

<!-- 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/18568)
<!-- Reviewable:end -->
This commit is contained in:
bors-servo 2017-09-19 18:46:49 -05:00 committed by GitHub
commit ad4f50270d
7 changed files with 114 additions and 84 deletions

View file

@ -36,6 +36,7 @@ const SOURCE_ORDER_MASK: u32 = (1 << SOURCE_ORDER_BITS) - 1;
const SOURCE_ORDER_MAX: u32 = SOURCE_ORDER_MASK;
/// Stores the source order of a block and the cascade level it belongs to.
#[cfg_attr(feature = "gecko", derive(MallocSizeOf))]
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
#[derive(Clone, Copy, Eq, PartialEq)]
struct SourceOrderAndCascadeLevel(u32);
@ -75,10 +76,12 @@ impl Debug for SourceOrderAndCascadeLevel {
///
/// This represents the declarations in a given declaration block for a given
/// importance.
#[cfg_attr(feature = "gecko", derive(MallocSizeOf))]
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
#[derive(Clone, Debug, PartialEq)]
pub struct ApplicableDeclarationBlock {
/// The style source, either a style rule, or a property declaration block.
#[cfg_attr(feature = "gecko", ignore_malloc_size_of = "contains Arcs")]
#[cfg_attr(feature = "servo", ignore_heap_size_of = "Arc")]
pub source: StyleSource,
/// The source order of the block, and the cascade level it belongs to.

View file

@ -2089,6 +2089,11 @@ extern "C" {
set:
RawServoStyleSetBorrowed);
}
extern "C" {
pub fn Servo_UACache_AddSizeOf(malloc_size_of: MallocSizeOf,
malloc_enclosing_size_of: MallocSizeOf,
sizes: *mut ServoStyleSetSizes);
}
extern "C" {
pub fn Servo_StyleContext_AddRef(ctx: ServoStyleContextBorrowed);
}

View file

@ -4947,17 +4947,16 @@ pub mod root {
#[repr(C)]
#[derive(Debug, Copy)]
pub struct ServoStyleSetSizes {
pub mStylistRuleTree: usize,
pub mStylistPrecomputedPseudos: usize,
pub mStylistElementAndPseudosMaps: usize,
pub mStylistInvalidationMap: usize,
pub mStylistRevalidationSelectors: usize,
pub mStylistOther: usize,
pub mRuleTree: usize,
pub mPrecomputedPseudos: usize,
pub mElementAndPseudosMaps: usize,
pub mInvalidationMap: usize,
pub mRevalidationSelectors: usize,
pub mOther: usize,
}
#[test]
fn bindgen_test_layout_ServoStyleSetSizes() {
assert_eq!(::std::mem::size_of::<ServoStyleSetSizes>() , 56usize ,
assert_eq!(::std::mem::size_of::<ServoStyleSetSizes>() , 48usize ,
concat ! (
"Size of: " , stringify ! ( ServoStyleSetSizes ) ));
assert_eq! (::std::mem::align_of::<ServoStyleSetSizes>() , 8usize
@ -4966,49 +4965,42 @@ pub mod root {
));
assert_eq! (unsafe {
& ( * ( 0 as * const ServoStyleSetSizes ) ) .
mStylistRuleTree as * const _ as usize } , 0usize ,
mRuleTree as * const _ as usize } , 0usize , concat !
(
"Alignment of field: " , stringify ! (
ServoStyleSetSizes ) , "::" , stringify ! ( mRuleTree
) ));
assert_eq! (unsafe {
& ( * ( 0 as * const ServoStyleSetSizes ) ) .
mPrecomputedPseudos as * const _ as usize } , 8usize ,
concat ! (
"Alignment of field: " , stringify ! (
ServoStyleSetSizes ) , "::" , stringify ! (
mStylistRuleTree ) ));
mPrecomputedPseudos ) ));
assert_eq! (unsafe {
& ( * ( 0 as * const ServoStyleSetSizes ) ) .
mStylistPrecomputedPseudos as * const _ as usize } ,
8usize , concat ! (
mElementAndPseudosMaps as * const _ as usize } ,
16usize , concat ! (
"Alignment of field: " , stringify ! (
ServoStyleSetSizes ) , "::" , stringify ! (
mStylistPrecomputedPseudos ) ));
mElementAndPseudosMaps ) ));
assert_eq! (unsafe {
& ( * ( 0 as * const ServoStyleSetSizes ) ) .
mStylistElementAndPseudosMaps as * const _ as usize }
, 16usize , concat ! (
"Alignment of field: " , stringify ! (
ServoStyleSetSizes ) , "::" , stringify ! (
mStylistElementAndPseudosMaps ) ));
assert_eq! (unsafe {
& ( * ( 0 as * const ServoStyleSetSizes ) ) .
mStylistInvalidationMap as * const _ as usize } ,
24usize , concat ! (
"Alignment of field: " , stringify ! (
ServoStyleSetSizes ) , "::" , stringify ! (
mStylistInvalidationMap ) ));
assert_eq! (unsafe {
& ( * ( 0 as * const ServoStyleSetSizes ) ) .
mStylistRevalidationSelectors as * const _ as usize }
, 32usize , concat ! (
"Alignment of field: " , stringify ! (
ServoStyleSetSizes ) , "::" , stringify ! (
mStylistRevalidationSelectors ) ));
assert_eq! (unsafe {
& ( * ( 0 as * const ServoStyleSetSizes ) ) .
mStylistOther as * const _ as usize } , 40usize ,
mInvalidationMap as * const _ as usize } , 24usize ,
concat ! (
"Alignment of field: " , stringify ! (
ServoStyleSetSizes ) , "::" , stringify ! (
mStylistOther ) ));
mInvalidationMap ) ));
assert_eq! (unsafe {
& ( * ( 0 as * const ServoStyleSetSizes ) ) .
mRevalidationSelectors as * const _ as usize } ,
32usize , concat ! (
"Alignment of field: " , stringify ! (
ServoStyleSetSizes ) , "::" , stringify ! (
mRevalidationSelectors ) ));
assert_eq! (unsafe {
& ( * ( 0 as * const ServoStyleSetSizes ) ) . mOther
as * const _ as usize } , 48usize , concat ! (
as * const _ as usize } , 40usize , concat ! (
"Alignment of field: " , stringify ! (
ServoStyleSetSizes ) , "::" , stringify ! ( mOther )
));

View file

@ -4867,17 +4867,16 @@ pub mod root {
#[repr(C)]
#[derive(Debug, Copy)]
pub struct ServoStyleSetSizes {
pub mStylistRuleTree: usize,
pub mStylistPrecomputedPseudos: usize,
pub mStylistElementAndPseudosMaps: usize,
pub mStylistInvalidationMap: usize,
pub mStylistRevalidationSelectors: usize,
pub mStylistOther: usize,
pub mRuleTree: usize,
pub mPrecomputedPseudos: usize,
pub mElementAndPseudosMaps: usize,
pub mInvalidationMap: usize,
pub mRevalidationSelectors: usize,
pub mOther: usize,
}
#[test]
fn bindgen_test_layout_ServoStyleSetSizes() {
assert_eq!(::std::mem::size_of::<ServoStyleSetSizes>() , 56usize ,
assert_eq!(::std::mem::size_of::<ServoStyleSetSizes>() , 48usize ,
concat ! (
"Size of: " , stringify ! ( ServoStyleSetSizes ) ));
assert_eq! (::std::mem::align_of::<ServoStyleSetSizes>() , 8usize
@ -4886,49 +4885,42 @@ pub mod root {
));
assert_eq! (unsafe {
& ( * ( 0 as * const ServoStyleSetSizes ) ) .
mStylistRuleTree as * const _ as usize } , 0usize ,
mRuleTree as * const _ as usize } , 0usize , concat !
(
"Alignment of field: " , stringify ! (
ServoStyleSetSizes ) , "::" , stringify ! ( mRuleTree
) ));
assert_eq! (unsafe {
& ( * ( 0 as * const ServoStyleSetSizes ) ) .
mPrecomputedPseudos as * const _ as usize } , 8usize ,
concat ! (
"Alignment of field: " , stringify ! (
ServoStyleSetSizes ) , "::" , stringify ! (
mStylistRuleTree ) ));
mPrecomputedPseudos ) ));
assert_eq! (unsafe {
& ( * ( 0 as * const ServoStyleSetSizes ) ) .
mStylistPrecomputedPseudos as * const _ as usize } ,
8usize , concat ! (
mElementAndPseudosMaps as * const _ as usize } ,
16usize , concat ! (
"Alignment of field: " , stringify ! (
ServoStyleSetSizes ) , "::" , stringify ! (
mStylistPrecomputedPseudos ) ));
mElementAndPseudosMaps ) ));
assert_eq! (unsafe {
& ( * ( 0 as * const ServoStyleSetSizes ) ) .
mStylistElementAndPseudosMaps as * const _ as usize }
, 16usize , concat ! (
"Alignment of field: " , stringify ! (
ServoStyleSetSizes ) , "::" , stringify ! (
mStylistElementAndPseudosMaps ) ));
assert_eq! (unsafe {
& ( * ( 0 as * const ServoStyleSetSizes ) ) .
mStylistInvalidationMap as * const _ as usize } ,
24usize , concat ! (
"Alignment of field: " , stringify ! (
ServoStyleSetSizes ) , "::" , stringify ! (
mStylistInvalidationMap ) ));
assert_eq! (unsafe {
& ( * ( 0 as * const ServoStyleSetSizes ) ) .
mStylistRevalidationSelectors as * const _ as usize }
, 32usize , concat ! (
"Alignment of field: " , stringify ! (
ServoStyleSetSizes ) , "::" , stringify ! (
mStylistRevalidationSelectors ) ));
assert_eq! (unsafe {
& ( * ( 0 as * const ServoStyleSetSizes ) ) .
mStylistOther as * const _ as usize } , 40usize ,
mInvalidationMap as * const _ as usize } , 24usize ,
concat ! (
"Alignment of field: " , stringify ! (
ServoStyleSetSizes ) , "::" , stringify ! (
mStylistOther ) ));
mInvalidationMap ) ));
assert_eq! (unsafe {
& ( * ( 0 as * const ServoStyleSetSizes ) ) .
mRevalidationSelectors as * const _ as usize } ,
32usize , concat ! (
"Alignment of field: " , stringify ! (
ServoStyleSetSizes ) , "::" , stringify ! (
mRevalidationSelectors ) ));
assert_eq! (unsafe {
& ( * ( 0 as * const ServoStyleSetSizes ) ) . mOther
as * const _ as usize } , 48usize , concat ! (
as * const _ as usize } , 40usize , concat ! (
"Alignment of field: " , stringify ! (
ServoStyleSetSizes ) , "::" , stringify ! ( mOther )
));

View file

@ -112,6 +112,7 @@ pub trait ElementExt: Element<Impl=SelectorImpl> + Debug {
}
/// A per-functional-pseudo map, from a given pseudo to a `T`.
#[cfg_attr(feature = "gecko", derive(MallocSizeOf))]
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
pub struct PerPseudoElementMap<T> {
entries: [Option<T>; SIMPLE_PSEUDO_COUNT],

View file

@ -17,6 +17,8 @@ use invalidation::element::invalidation_map::InvalidationMap;
use invalidation::media_queries::{EffectiveMediaQueryResults, ToMediaListKey};
#[cfg(feature = "gecko")]
use malloc_size_of::{MallocShallowSizeOf, MallocSizeOf, MallocSizeOfOps};
#[cfg(feature = "gecko")]
use malloc_size_of::MallocUnconditionalShallowSizeOf;
use media_queries::Device;
use properties::{self, CascadeFlags, ComputedValues};
use properties::{AnimationRules, PropertyDeclarationBlock};
@ -133,6 +135,23 @@ impl UserAgentCascadeDataCache {
fn clear(&mut self) {
self.entries.clear();
}
#[cfg(feature = "gecko")]
pub fn add_size_of(&self, ops: &mut MallocSizeOfOps, sizes: &mut ServoStyleSetSizes) {
sizes.mOther += self.entries.shallow_size_of(ops);
for arc in self.entries.iter() {
// These are primary Arc references that can be measured
// unconditionally.
sizes.mOther += arc.unconditional_shallow_size_of(ops);
arc.add_size_of(ops, sizes);
}
}
}
/// Measure heap usage of UA_CASCADE_DATA_CACHE.
#[cfg(feature = "gecko")]
pub fn add_size_of_ua_cache(ops: &mut MallocSizeOfOps, sizes: &mut ServoStyleSetSizes) {
UA_CASCADE_DATA_CACHE.lock().unwrap().add_size_of(ops, sizes);
}
type PrecomputedPseudoElementDeclarations =
@ -151,6 +170,14 @@ struct UserAgentCascadeData {
precomputed_pseudo_element_decls: PrecomputedPseudoElementDeclarations,
}
impl UserAgentCascadeData {
#[cfg(feature = "gecko")]
fn add_size_of(&self, ops: &mut MallocSizeOfOps, sizes: &mut ServoStyleSetSizes) {
self.cascade_data.add_size_of_children(ops, sizes);
sizes.mPrecomputedPseudos += self.precomputed_pseudo_element_decls.size_of(ops);
}
}
/// All the computed information for a stylesheet.
#[derive(Default)]
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
@ -304,9 +331,6 @@ impl DocumentCascadeData {
pub fn add_size_of_children(&self, ops: &mut MallocSizeOfOps, sizes: &mut ServoStyleSetSizes) {
self.user.add_size_of_children(ops, sizes);
self.author.add_size_of_children(ops, sizes);
// FIXME(emilio): UA_CASCADE_DATA_CACHE is shared, we should do whatever
// we do for RuleProcessorCache in Gecko.
}
}
@ -1500,7 +1524,7 @@ impl Stylist {
#[cfg(feature = "gecko")]
pub fn add_size_of_children(&self, ops: &mut MallocSizeOfOps, sizes: &mut ServoStyleSetSizes) {
self.cascade_data.add_size_of_children(ops, sizes);
sizes.mStylistRuleTree += self.rule_tree.size_of(ops);
sizes.mRuleTree += self.rule_tree.size_of(ops);
// We may measure other fields in the future if DMD says it's worth it.
}
@ -2194,22 +2218,22 @@ impl CascadeData {
/// Measures heap usage.
#[cfg(feature = "gecko")]
pub fn add_size_of_children(&self, ops: &mut MallocSizeOfOps, sizes: &mut ServoStyleSetSizes) {
sizes.mStylistElementAndPseudosMaps += self.element_map.size_of(ops);
sizes.mElementAndPseudosMaps += self.element_map.size_of(ops);
for elem in self.pseudos_map.iter() {
if let Some(ref elem) = *elem {
sizes.mStylistElementAndPseudosMaps += <Box<_> as MallocSizeOf>::size_of(elem, ops);
sizes.mElementAndPseudosMaps += <Box<_> as MallocSizeOf>::size_of(elem, ops);
}
}
sizes.mStylistOther += self.animations.size_of(ops);
sizes.mOther += self.animations.size_of(ops);
sizes.mStylistInvalidationMap += self.invalidation_map.size_of(ops);
sizes.mInvalidationMap += self.invalidation_map.size_of(ops);
sizes.mStylistRevalidationSelectors += self.selectors_for_cache_revalidation.size_of(ops);
sizes.mRevalidationSelectors += self.selectors_for_cache_revalidation.size_of(ops);
sizes.mStylistOther += self.effective_media_query_results.size_of(ops);
sizes.mStylistOther += self.extra_data.size_of(ops);
sizes.mOther += self.effective_media_query_results.size_of(ops);
sizes.mOther += self.extra_data.size_of(ops);
}
}

View file

@ -131,7 +131,7 @@ use style::stylesheets::{StylesheetContents, SupportsRule};
use style::stylesheets::StylesheetLoader as StyleStylesheetLoader;
use style::stylesheets::keyframes_rule::{Keyframe, KeyframeSelector, KeyframesStepValue};
use style::stylesheets::supports_rule::parse_condition_or_declaration;
use style::stylist::{RuleInclusion, Stylist};
use style::stylist::{add_size_of_ua_cache, RuleInclusion, Stylist};
use style::thread_state;
use style::timer::Timer;
use style::traversal::DomTraversal;
@ -3768,6 +3768,19 @@ pub extern "C" fn Servo_StyleSet_AddSizeOfExcludingThis(
data.add_size_of_children(&mut ops, sizes);
}
#[no_mangle]
pub extern "C" fn Servo_UACache_AddSizeOf(
malloc_size_of: GeckoMallocSizeOf,
malloc_enclosing_size_of: GeckoMallocSizeOf,
sizes: *mut ServoStyleSetSizes
) {
let mut ops = MallocSizeOfOps::new(malloc_size_of.unwrap(),
malloc_enclosing_size_of.unwrap(),
None);
let sizes = unsafe { sizes.as_mut() }.unwrap();
add_size_of_ua_cache(&mut ops, sizes);
}
#[no_mangle]
pub extern "C" fn Servo_StyleSet_MightHaveAttributeDependency(
raw_data: RawServoStyleSetBorrowed,