mirror of
https://github.com/servo/servo.git
synced 2025-08-05 13:40:08 +01:00
Measure the UA cache.
ServoStyleSetSizes now has two uses, one for the Stylist, and one for the UA cache, and so the patch removes 'Stylist' from the field names. Example output from about:memory: > +----1,359,608 B (00.55%) -- layout > | +----756,488 B (00.31%) -- style-sheet-cache [2] > | +----393,968 B (00.16%) -- servo-ua-cache > | | +--234,496 B (00.10%) -- element-and-pseudos-maps > | | +---59,648 B (00.02%) -- revalidation-selectors > | | +---58,320 B (00.02%) -- invalidation-map > | | +---30,752 B (00.01%) -- other > | | +---10,752 B (00.00%) -- precomputed-pseudos
This commit is contained in:
parent
c6381c66a0
commit
f7023a120e
7 changed files with 114 additions and 84 deletions
|
@ -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.
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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 )
|
||||
));
|
||||
|
|
|
@ -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 )
|
||||
));
|
||||
|
|
|
@ -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],
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue