From 1a40101d2f96552a9d883a50fb0074b366288603 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Mon, 14 Aug 2017 10:49:48 +1000 Subject: [PATCH] Overhaul ComputedValues measurement, and add style structs measurement. --- components/style/data.rs | 36 ++++++-------- components/style/gecko/generated/bindings.rs | 21 ++++++-- components/style/properties/gecko.mako.rs | 13 ----- ports/geckolib/glue.rs | 51 +++++++++++++++++--- 4 files changed, 77 insertions(+), 44 deletions(-) diff --git a/components/style/data.rs b/components/style/data.rs index 38099cb6eb6..096f09f00de 100644 --- a/components/style/data.rs +++ b/components/style/data.rs @@ -16,7 +16,7 @@ use shared_lock::StylesheetGuards; use std::fmt; use std::ops::{Deref, DerefMut}; #[cfg(feature = "gecko")] -use stylesheets::{MallocSizeOfWithRepeats, SizeOfState}; +use stylesheets::SizeOfState; bitflags! { flags RestyleFlags: u8 { @@ -261,6 +261,17 @@ impl ElementStyles { pub fn is_display_none(&self) -> bool { self.primary().get_box().clone_display() == display::T::none } + + #[cfg(feature = "gecko")] + fn malloc_size_of_children_excluding_cvs(&self, _state: &mut SizeOfState) -> usize { + // As the method name suggests, we don't measures the ComputedValues + // here, because they are measured on the C++ side. + + // XXX: measure the EagerPseudoArray itself, but not the ComputedValues + // within it. + + 0 + } } // We manually implement Debug for ElementStyles so that we can avoid the @@ -273,20 +284,6 @@ impl fmt::Debug for ElementStyles { } } -#[cfg(feature = "gecko")] -impl MallocSizeOfWithRepeats for ElementStyles { - fn malloc_size_of_children(&self, state: &mut SizeOfState) -> usize { - let mut n = 0; - if let Some(ref primary) = self.primary { - n += primary.malloc_size_of_children(state) - }; - - // We may measure more fields in the future if DMD says it's worth it. - - n - } -} - /// Style system data associated with an Element. /// /// In Gecko, this hangs directly off the Element. Servo, this is embedded @@ -436,12 +433,11 @@ impl ElementData { pub fn clear_restyle_flags_and_damage(&mut self) { self.restyle.clear_restyle_flags_and_damage(); } -} -#[cfg(feature = "gecko")] -impl MallocSizeOfWithRepeats for ElementData { - fn malloc_size_of_children(&self, state: &mut SizeOfState) -> usize { - let n = self.styles.malloc_size_of_children(state); + /// Measures memory usage. + #[cfg(feature = "gecko")] + pub fn malloc_size_of_children_excluding_cvs(&self, state: &mut SizeOfState) -> usize { + let n = self.styles.malloc_size_of_children_excluding_cvs(state); // We may measure more fields in the future if DMD says it's worth it. diff --git a/components/style/gecko/generated/bindings.rs b/components/style/gecko/generated/bindings.rs index 0d6dbabb502..ecf25e3a622 100644 --- a/components/style/gecko/generated/bindings.rs +++ b/components/style/gecko/generated/bindings.rs @@ -1915,11 +1915,26 @@ extern "C" { pub fn Servo_Element_ClearData(node: RawGeckoElementBorrowed); } extern "C" { - pub fn Servo_Element_SizeOfExcludingThis(arg1: MallocSizeOf, - seen_ptrs: *mut SeenPtrs, - node: RawGeckoElementBorrowed) + pub fn Servo_Element_SizeOfExcludingThisAndCVs(malloc_size_of: MallocSizeOf, + seen_ptrs: *mut SeenPtrs, + node: RawGeckoElementBorrowed) -> usize; } +extern "C" { + pub fn Servo_Element_HasPrimaryComputedValues(element: RawGeckoElementBorrowed) -> bool; +} +extern "C" { + pub fn Servo_Element_GetPrimaryComputedValues(element: RawGeckoElementBorrowed) + -> ServoStyleContextStrong; +} +extern "C" { + pub fn Servo_Element_HasPseudoComputedValues(element: RawGeckoElementBorrowed, index: usize) + -> bool; +} +extern "C" { + pub fn Servo_Element_GetPseudoComputedValues(element: RawGeckoElementBorrowed, index: usize) + -> ServoStyleContextStrong; +} extern "C" { pub fn Servo_StyleSheet_FromUTF8Bytes(loader: *mut Loader, gecko_stylesheet: diff --git a/components/style/properties/gecko.mako.rs b/components/style/properties/gecko.mako.rs index a62d00be52f..74a7b157aea 100644 --- a/components/style/properties/gecko.mako.rs +++ b/components/style/properties/gecko.mako.rs @@ -60,7 +60,6 @@ use selector_parser::PseudoElement; use servo_arc::{Arc, RawOffsetArc}; use std::mem::{forget, uninitialized, transmute, zeroed}; use std::{cmp, ops, ptr}; -use stylesheets::{MallocSizeOfWithRepeats, SizeOfState}; use values::{self, Auto, CustomIdent, Either, KeyframesName}; use values::computed::{NonNegativeAu, ToComputedValue, Percentage}; use values::computed::effects::{BoxShadow, Filter, SimpleShadow}; @@ -369,18 +368,6 @@ impl ComputedValuesInner { } } -impl MallocSizeOfWithRepeats for ComputedValues { - fn malloc_size_of_children(&self, state: &mut SizeOfState) -> usize { - let mut n = 0; - if let Some(ref raw_offset_arc) = *self.get_raw_visited_style() { - n += raw_offset_arc.with_arc(|a: &Arc| { - a.malloc_size_of_children(state) - }) - } - n - } -} - <%def name="declare_style_struct(style_struct)"> pub use ::gecko_bindings::structs::mozilla::Gecko${style_struct.gecko_name} as ${style_struct.gecko_struct_name}; impl ${style_struct.gecko_struct_name} { diff --git a/ports/geckolib/glue.rs b/ports/geckolib/glue.rs index cdf76aa1407..ec1f610403e 100644 --- a/ports/geckolib/glue.rs +++ b/ports/geckolib/glue.rs @@ -115,10 +115,8 @@ use style::string_cache::Atom; use style::style_adjuster::StyleAdjuster; use style::stylesheets::{CssRule, CssRules, CssRuleType, CssRulesHelpers, DocumentRule}; use style::stylesheets::{FontFeatureValuesRule, ImportRule, KeyframesRule, MallocSizeOfWithGuard}; -use style::stylesheets::{MallocSizeOfWithRepeats, MediaRule}; -use style::stylesheets::{NamespaceRule, Origin, PageRule, SizeOfState, StyleRule, SupportsRule}; -use style::stylesheets::StylesheetContents; -use style::stylesheets::StylesheetInDocument; +use style::stylesheets::{MediaRule, NamespaceRule, Origin, PageRule, SizeOfState, StyleRule}; +use style::stylesheets::{StylesheetContents, StylesheetInDocument, SupportsRule}; use style::stylesheets::StylesheetLoader as StyleStylesheetLoader; use style::stylesheets::keyframes_rule::{Keyframe, KeyframeSelector, KeyframesStepValue}; use style::stylesheets::supports_rule::parse_condition_or_declaration; @@ -759,9 +757,9 @@ pub extern "C" fn Servo_Element_ClearData(element: RawGeckoElementBorrowed) { } #[no_mangle] -pub extern "C" fn Servo_Element_SizeOfExcludingThis(malloc_size_of: MallocSizeOf, - seen_ptrs: *mut SeenPtrs, - element: RawGeckoElementBorrowed) -> usize { +pub extern "C" fn Servo_Element_SizeOfExcludingThisAndCVs(malloc_size_of: MallocSizeOf, + seen_ptrs: *mut SeenPtrs, + element: RawGeckoElementBorrowed) -> usize { let malloc_size_of = malloc_size_of.unwrap(); let element = GeckoElement(element); let borrow = element.borrow_data(); @@ -770,12 +768,49 @@ pub extern "C" fn Servo_Element_SizeOfExcludingThis(malloc_size_of: MallocSizeOf malloc_size_of: malloc_size_of, seen_ptrs: seen_ptrs, }; - (*data).malloc_size_of_children(&mut state) + (*data).malloc_size_of_children_excluding_cvs(&mut state) } else { 0 } } +#[no_mangle] +pub extern "C" fn Servo_Element_HasPrimaryComputedValues(element: RawGeckoElementBorrowed) -> bool +{ + let element = GeckoElement(element); + let data = element.borrow_data().expect("Looking for CVs on unstyled element"); + data.has_styles() +} + +#[no_mangle] +pub extern "C" fn Servo_Element_GetPrimaryComputedValues(element: RawGeckoElementBorrowed) + -> ServoStyleContextStrong +{ + let element = GeckoElement(element); + let data = element.borrow_data().expect("Getting CVs on unstyled element"); + assert!(data.has_styles(), "Getting CVs on unstyled element"); + data.styles.primary().clone().into() +} + +#[no_mangle] +pub extern "C" fn Servo_Element_HasPseudoComputedValues(element: RawGeckoElementBorrowed, + index: usize) -> bool +{ + let element = GeckoElement(element); + let data = element.borrow_data().expect("Looking for CVs on unstyled element"); + data.styles.pseudos.as_array()[index].is_some() +} + +#[no_mangle] +pub extern "C" fn Servo_Element_GetPseudoComputedValues(element: RawGeckoElementBorrowed, + index: usize) -> ServoStyleContextStrong +{ + let element = GeckoElement(element); + let data = element.borrow_data().expect("Getting CVs that aren't present"); + data.styles.pseudos.as_array()[index].as_ref().expect("Getting CVs that aren't present") + .clone().into() +} + #[no_mangle] pub extern "C" fn Servo_StyleSheet_Empty(mode: SheetParsingMode) -> RawServoStyleSheetContentsStrong { let global_style_data = &*GLOBAL_STYLE_DATA;