From 337e5288c20e94bfaebae8ea32eb13704fdc6b87 Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Tue, 28 Nov 2017 14:42:59 -0800 Subject: [PATCH] Add weighted telemetry probes for parallel restyles --- components/style/context.rs | 15 +++++ components/style/driver.rs | 26 +++++---- components/style/gecko/data.rs | 61 +++++++++++++++----- components/style/gecko/generated/bindings.rs | 2 + components/style/gecko/generated/structs.rs | 2 +- ports/geckolib/glue.rs | 4 +- 6 files changed, 84 insertions(+), 26 deletions(-) diff --git a/components/style/context.rs b/components/style/context.rs index 7b58bfa7d9f..6c9ba7b47f6 100644 --- a/components/style/context.rs +++ b/components/style/context.rs @@ -116,6 +116,21 @@ impl Default for StyleSystemOptions { } } +impl StyleSystemOptions { + #[cfg(feature = "servo")] + /// On Gecko's nightly build? + pub fn is_nightly(&self) -> bool { + false + } + + #[cfg(feature = "gecko")] + /// On Gecko's nightly build? + #[inline] + pub fn is_nightly(&self) -> bool { + structs::GECKO_IS_NIGHTLY + } +} + /// A shared style context. /// /// There's exactly one of these during a given restyle traversal, and it's diff --git a/components/style/driver.rs b/components/style/driver.rs index 6e214f8a50f..07beb6d40d2 100644 --- a/components/style/driver.rs +++ b/components/style/driver.rs @@ -7,7 +7,7 @@ #![deny(missing_docs)] -use context::{StyleContext, ThreadLocalStyleContext}; +use context::{StyleContext, ThreadLocalStyleContext, TraversalStatistics}; use dom::{SendNode, TElement, TNode}; use parallel; use parallel::{DispatchMode, WORK_UNIT_MAX}; @@ -26,12 +26,14 @@ use traversal::{DomTraversal, PerLevelTraversalData, PreTraverseToken}; /// parallel traversal would parallelize it. If a thread pool is provided, we /// then transfer control over to the parallel traversal. /// -/// Returns true if the traversal was parallel +/// Returns true if the traversal was parallel, and also returns the statistics +/// object containing information on nodes traversed (on nightly only). Not +/// all of its fields will be initialized since we don't call finish(). pub fn traverse_dom( traversal: &D, token: PreTraverseToken, pool: Option<&rayon::ThreadPool> -) -> bool +) -> (bool, Option) where E: TElement, D: DomTraversal, @@ -40,6 +42,7 @@ where token.traversal_root().expect("Should've ensured we needed to traverse"); let dump_stats = traversal.shared_context().options.dump_style_statistics; + let is_nightly = traversal.shared_context().options.is_nightly(); let mut used_parallel = false; let start_time = if dump_stats { Some(time::precise_time_s()) } else { None }; @@ -112,9 +115,9 @@ where nodes_remaining_at_current_depth = discovered.len(); } } - - // Dump statistics to stdout if requested. - if dump_stats { + let mut maybe_stats = None; + // Accumulate statistics + if dump_stats || is_nightly { let mut aggregate = mem::replace(&mut context.thread_local.statistics, Default::default()); let parallel = maybe_tls.is_some(); @@ -127,11 +130,14 @@ where } }); } - aggregate.finish(traversal, parallel, start_time.unwrap()); - if aggregate.is_large_traversal() { - println!("{}", aggregate); + + // dump to stdout if requested + if dump_stats && aggregate.is_large_traversal() { + aggregate.finish(traversal, parallel, start_time.unwrap()); + println!("{}", aggregate); } + maybe_stats = Some(aggregate); } - used_parallel + (used_parallel, maybe_stats) } diff --git a/components/style/gecko/data.rs b/components/style/gecko/data.rs index 481c555ba1d..d3f5e303f75 100644 --- a/components/style/gecko/data.rs +++ b/components/style/gecko/data.rs @@ -5,6 +5,7 @@ //! Data needed to style a Gecko document. use atomic_refcell::{AtomicRef, AtomicRefCell, AtomicRefMut}; +use context::TraversalStatistics; use dom::TElement; use gecko_bindings::bindings::{self, RawServoStyleSet}; use gecko_bindings::structs::{RawGeckoPresContextOwned, ServoStyleSetSizes, ServoStyleSheet}; @@ -108,15 +109,40 @@ impl StylesheetInDocument for GeckoStyleSheet { } } +#[derive(Default)] +/// Helper struct for counting traversals +pub struct TraversalCount { + /// Total number of events + pub total_count: AtomicUsize, + /// Number of events which were parallel + pub parallel_count: AtomicUsize +} + +impl TraversalCount { + fn record(&self, parallel: bool, count: u32) { + self.total_count.fetch_add(count as usize, Ordering::Relaxed); + if parallel { + self.parallel_count.fetch_add(count as usize, Ordering::Relaxed); + } + } + + fn get(&self) -> (u32, u32) { + (self.total_count.load(Ordering::Relaxed) as u32, + self.parallel_count.load(Ordering::Relaxed) as u32) + } +} + /// The container for data that a Servo-backed Gecko document needs to style /// itself. pub struct PerDocumentStyleDataImpl { /// Rule processor. pub stylist: Stylist, - /// Total number of traversals that could have been parallel, for telemetry - pub total_traversal_count: AtomicUsize, - /// Number of parallel traversals - pub parallel_traversal_count: AtomicUsize, + /// Counter for traversals that could have been parallel, for telemetry + pub traversal_count: TraversalCount, + /// Counter for traversals, weighted by elements traversed, + pub traversal_count_traversed: TraversalCount, + /// Counter for traversals, weighted by elements styled, + pub traversal_count_styled: TraversalCount, } /// The data itself is an `AtomicRefCell`, which guarantees the proper semantics @@ -138,8 +164,9 @@ impl PerDocumentStyleData { PerDocumentStyleData(AtomicRefCell::new(PerDocumentStyleDataImpl { stylist: Stylist::new(device, quirks_mode.into()), - total_traversal_count: Default::default(), - parallel_traversal_count: Default::default(), + traversal_count: Default::default(), + traversal_count_traversed: Default::default(), + traversal_count_styled: Default::default(), })) } @@ -156,9 +183,16 @@ impl PerDocumentStyleData { impl Drop for PerDocumentStyleDataImpl { fn drop(&mut self) { - let total = self.total_traversal_count.load(Ordering::Relaxed) as u32; - let parallel = self.parallel_traversal_count.load(Ordering::Relaxed) as u32; - unsafe { bindings::Gecko_RecordTraversalStatistics(total, parallel) } + if !structs::GECKO_IS_NIGHTLY { + return + } + let (total, parallel) = self.traversal_count.get(); + let (total_t, parallel_t) = self.traversal_count_traversed.get(); + let (total_s, parallel_s) = self.traversal_count_styled.get(); + + unsafe { bindings::Gecko_RecordTraversalStatistics(total, parallel, + total_t, parallel_t, + total_s, parallel_s) } } } @@ -226,10 +260,11 @@ impl PerDocumentStyleDataImpl { } /// Record that a traversal happened for later collection as telemetry - pub fn record_traversal(&self, was_parallel: bool) { - self.total_traversal_count.fetch_add(1, Ordering::Relaxed); - if was_parallel { - self.parallel_traversal_count.fetch_add(1, Ordering::Relaxed); + pub fn record_traversal(&self, was_parallel: bool, stats: Option) { + self.traversal_count.record(was_parallel, 1); + if let Some(stats) = stats { + self.traversal_count_traversed.record(was_parallel, stats.elements_traversed); + self.traversal_count_styled.record(was_parallel, stats.elements_styled); } } } diff --git a/components/style/gecko/generated/bindings.rs b/components/style/gecko/generated/bindings.rs index d4e2bf86851..090d2096d07 100644 --- a/components/style/gecko/generated/bindings.rs +++ b/components/style/gecko/generated/bindings.rs @@ -499,6 +499,8 @@ extern "C" { pub fn Servo_SelectorList_Drop ( ptr : RawServoSelectorListOwned , ) ; } extern "C" { pub fn Servo_SourceSizeList_Drop ( ptr : RawServoSourceSizeListOwned , ) ; +} extern "C" { + pub fn Gecko_RecordTraversalStatistics ( total : u32 , parallel : u32 , total_t : u32 , parallel_t : u32 , total_s : u32 , parallel_s : u32 , ) ; } extern "C" { pub fn Gecko_IsInDocument ( node : RawGeckoNodeBorrowed , ) -> bool ; } extern "C" { diff --git a/components/style/gecko/generated/structs.rs b/components/style/gecko/generated/structs.rs index a0cd5c5cbcd..2b89e95794c 100644 --- a/components/style/gecko/generated/structs.rs +++ b/components/style/gecko/generated/structs.rs @@ -1660,7 +1660,7 @@ pub type ServoStyleContextStrong = ::gecko_bindings::sugar::ownership::Strong<:: pub static mut nsDOMAttributeMap__cycleCollectorGlobal : root :: nsDOMAttributeMap_cycleCollection ; } # [ test ] fn bindgen_test_layout_nsDOMAttributeMap ( ) { assert_eq ! ( :: std :: mem :: size_of :: < nsDOMAttributeMap > ( ) , 80usize , concat ! ( "Size of: " , stringify ! ( nsDOMAttributeMap ) ) ) ; assert_eq ! ( :: std :: mem :: align_of :: < nsDOMAttributeMap > ( ) , 8usize , concat ! ( "Alignment of " , stringify ! ( nsDOMAttributeMap ) ) ) ; } # [ repr ( C ) ] pub struct nsISMILAttr__bindgen_vtable ( :: std :: os :: raw :: c_void ) ; /// - # [ repr ( C ) ] # [ derive ( Debug ) ] pub struct nsISMILAttr { pub vtable_ : * const nsISMILAttr__bindgen_vtable , } # [ test ] fn bindgen_test_layout_nsISMILAttr ( ) { assert_eq ! ( :: std :: mem :: size_of :: < nsISMILAttr > ( ) , 8usize , concat ! ( "Size of: " , stringify ! ( nsISMILAttr ) ) ) ; assert_eq ! ( :: std :: mem :: align_of :: < nsISMILAttr > ( ) , 8usize , concat ! ( "Alignment of " , stringify ! ( nsISMILAttr ) ) ) ; } pub const ELEMENT_SHARED_RESTYLE_BIT_1 : root :: _bindgen_ty_85 = 8388608 ; pub const ELEMENT_SHARED_RESTYLE_BIT_2 : root :: _bindgen_ty_85 = 16777216 ; pub const ELEMENT_SHARED_RESTYLE_BIT_3 : root :: _bindgen_ty_85 = 33554432 ; pub const ELEMENT_SHARED_RESTYLE_BIT_4 : root :: _bindgen_ty_85 = 67108864 ; pub const ELEMENT_SHARED_RESTYLE_BITS : root :: _bindgen_ty_85 = 125829120 ; pub const ELEMENT_HAS_DIRTY_DESCENDANTS_FOR_SERVO : root :: _bindgen_ty_85 = 8388608 ; pub const ELEMENT_HAS_ANIMATION_ONLY_DIRTY_DESCENDANTS_FOR_SERVO : root :: _bindgen_ty_85 = 16777216 ; pub const ELEMENT_HAS_SNAPSHOT : root :: _bindgen_ty_85 = 33554432 ; pub const ELEMENT_HANDLED_SNAPSHOT : root :: _bindgen_ty_85 = 67108864 ; pub const ELEMENT_HAS_PENDING_RESTYLE : root :: _bindgen_ty_85 = 8388608 ; pub const ELEMENT_IS_POTENTIAL_RESTYLE_ROOT : root :: _bindgen_ty_85 = 16777216 ; pub const ELEMENT_HAS_PENDING_ANIMATION_ONLY_RESTYLE : root :: _bindgen_ty_85 = 33554432 ; pub const ELEMENT_IS_POTENTIAL_ANIMATION_ONLY_RESTYLE_ROOT : root :: _bindgen_ty_85 = 67108864 ; pub const ELEMENT_IS_CONDITIONAL_RESTYLE_ANCESTOR : root :: _bindgen_ty_85 = 134217728 ; pub const ELEMENT_HAS_CHILD_WITH_LATER_SIBLINGS_HINT : root :: _bindgen_ty_85 = 268435456 ; pub const ELEMENT_PENDING_RESTYLE_FLAGS : root :: _bindgen_ty_85 = 41943040 ; pub const ELEMENT_POTENTIAL_RESTYLE_ROOT_FLAGS : root :: _bindgen_ty_85 = 83886080 ; pub const ELEMENT_ALL_RESTYLE_FLAGS : root :: _bindgen_ty_85 = 260046848 ; pub const ELEMENT_TYPE_SPECIFIC_BITS_OFFSET : root :: _bindgen_ty_85 = 27 ; pub type _bindgen_ty_85 = :: std :: os :: raw :: c_uint ; # [ repr ( C ) ] # [ derive ( Debug , Copy ) ] pub struct ServoBundledURI { pub mURLString : * const u8 , pub mURLStringLength : u32 , pub mExtraData : * mut root :: mozilla :: URLExtraData , } # [ test ] fn bindgen_test_layout_ServoBundledURI ( ) { assert_eq ! ( :: std :: mem :: size_of :: < ServoBundledURI > ( ) , 24usize , concat ! ( "Size of: " , stringify ! ( ServoBundledURI ) ) ) ; assert_eq ! ( :: std :: mem :: align_of :: < ServoBundledURI > ( ) , 8usize , concat ! ( "Alignment of " , stringify ! ( ServoBundledURI ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const ServoBundledURI ) ) . mURLString as * const _ as usize } , 0usize , concat ! ( "Alignment of field: " , stringify ! ( ServoBundledURI ) , "::" , stringify ! ( mURLString ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const ServoBundledURI ) ) . mURLStringLength as * const _ as usize } , 8usize , concat ! ( "Alignment of field: " , stringify ! ( ServoBundledURI ) , "::" , stringify ! ( mURLStringLength ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const ServoBundledURI ) ) . mExtraData as * const _ as usize } , 16usize , concat ! ( "Alignment of field: " , stringify ! ( ServoBundledURI ) , "::" , stringify ! ( mExtraData ) ) ) ; } impl Clone for ServoBundledURI { fn clone ( & self ) -> Self { * self } } # [ repr ( C ) ] # [ derive ( Debug , Copy ) ] pub struct FontSizePrefs { pub mDefaultVariableSize : root :: nscoord , pub mDefaultFixedSize : root :: nscoord , pub mDefaultSerifSize : root :: nscoord , pub mDefaultSansSerifSize : root :: nscoord , pub mDefaultMonospaceSize : root :: nscoord , pub mDefaultCursiveSize : root :: nscoord , pub mDefaultFantasySize : root :: nscoord , } # [ test ] fn bindgen_test_layout_FontSizePrefs ( ) { assert_eq ! ( :: std :: mem :: size_of :: < FontSizePrefs > ( ) , 28usize , concat ! ( "Size of: " , stringify ! ( FontSizePrefs ) ) ) ; assert_eq ! ( :: std :: mem :: align_of :: < FontSizePrefs > ( ) , 4usize , concat ! ( "Alignment of " , stringify ! ( FontSizePrefs ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const FontSizePrefs ) ) . mDefaultVariableSize as * const _ as usize } , 0usize , concat ! ( "Alignment of field: " , stringify ! ( FontSizePrefs ) , "::" , stringify ! ( mDefaultVariableSize ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const FontSizePrefs ) ) . mDefaultFixedSize as * const _ as usize } , 4usize , concat ! ( "Alignment of field: " , stringify ! ( FontSizePrefs ) , "::" , stringify ! ( mDefaultFixedSize ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const FontSizePrefs ) ) . mDefaultSerifSize as * const _ as usize } , 8usize , concat ! ( "Alignment of field: " , stringify ! ( FontSizePrefs ) , "::" , stringify ! ( mDefaultSerifSize ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const FontSizePrefs ) ) . mDefaultSansSerifSize as * const _ as usize } , 12usize , concat ! ( "Alignment of field: " , stringify ! ( FontSizePrefs ) , "::" , stringify ! ( mDefaultSansSerifSize ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const FontSizePrefs ) ) . mDefaultMonospaceSize as * const _ as usize } , 16usize , concat ! ( "Alignment of field: " , stringify ! ( FontSizePrefs ) , "::" , stringify ! ( mDefaultMonospaceSize ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const FontSizePrefs ) ) . mDefaultCursiveSize as * const _ as usize } , 20usize , concat ! ( "Alignment of field: " , stringify ! ( FontSizePrefs ) , "::" , stringify ! ( mDefaultCursiveSize ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const FontSizePrefs ) ) . mDefaultFantasySize as * const _ as usize } , 24usize , concat ! ( "Alignment of field: " , stringify ! ( FontSizePrefs ) , "::" , stringify ! ( mDefaultFantasySize ) ) ) ; } impl Clone for FontSizePrefs { fn clone ( & self ) -> Self { * self } } # [ repr ( C ) ] # [ derive ( Debug , Copy ) ] pub struct GeckoFontMetrics { pub mChSize : root :: nscoord , pub mXSize : root :: nscoord , } # [ test ] fn bindgen_test_layout_GeckoFontMetrics ( ) { assert_eq ! ( :: std :: mem :: size_of :: < GeckoFontMetrics > ( ) , 8usize , concat ! ( "Size of: " , stringify ! ( GeckoFontMetrics ) ) ) ; assert_eq ! ( :: std :: mem :: align_of :: < GeckoFontMetrics > ( ) , 4usize , concat ! ( "Alignment of " , stringify ! ( GeckoFontMetrics ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const GeckoFontMetrics ) ) . mChSize as * const _ as usize } , 0usize , concat ! ( "Alignment of field: " , stringify ! ( GeckoFontMetrics ) , "::" , stringify ! ( mChSize ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const GeckoFontMetrics ) ) . mXSize as * const _ as usize } , 4usize , concat ! ( "Alignment of field: " , stringify ! ( GeckoFontMetrics ) , "::" , stringify ! ( mXSize ) ) ) ; } impl Clone for GeckoFontMetrics { fn clone ( & self ) -> Self { * self } } pub const SERVO_CSS_PSEUDO_ELEMENT_FLAGS_after : u32 = 65 ; pub const SERVO_CSS_PSEUDO_ELEMENT_FLAGS_before : u32 = 65 ; pub const SERVO_CSS_PSEUDO_ELEMENT_FLAGS_backdrop : u32 = 0 ; pub const SERVO_CSS_PSEUDO_ELEMENT_FLAGS_cue : u32 = 36 ; pub const SERVO_CSS_PSEUDO_ELEMENT_FLAGS_firstLetter : u32 = 3 ; pub const SERVO_CSS_PSEUDO_ELEMENT_FLAGS_firstLine : u32 = 3 ; pub const SERVO_CSS_PSEUDO_ELEMENT_FLAGS_mozSelection : u32 = 2 ; pub const SERVO_CSS_PSEUDO_ELEMENT_FLAGS_mozFocusInner : u32 = 0 ; pub const SERVO_CSS_PSEUDO_ELEMENT_FLAGS_mozFocusOuter : u32 = 0 ; pub const SERVO_CSS_PSEUDO_ELEMENT_FLAGS_mozListBullet : u32 = 0 ; pub const SERVO_CSS_PSEUDO_ELEMENT_FLAGS_mozListNumber : u32 = 0 ; pub const SERVO_CSS_PSEUDO_ELEMENT_FLAGS_mozMathAnonymous : u32 = 0 ; pub const SERVO_CSS_PSEUDO_ELEMENT_FLAGS_mozNumberWrapper : u32 = 24 ; pub const SERVO_CSS_PSEUDO_ELEMENT_FLAGS_mozNumberText : u32 = 24 ; pub const SERVO_CSS_PSEUDO_ELEMENT_FLAGS_mozNumberSpinBox : u32 = 24 ; pub const SERVO_CSS_PSEUDO_ELEMENT_FLAGS_mozNumberSpinUp : u32 = 24 ; pub const SERVO_CSS_PSEUDO_ELEMENT_FLAGS_mozNumberSpinDown : u32 = 24 ; pub const SERVO_CSS_PSEUDO_ELEMENT_FLAGS_mozProgressBar : u32 = 8 ; pub const SERVO_CSS_PSEUDO_ELEMENT_FLAGS_mozRangeTrack : u32 = 8 ; pub const SERVO_CSS_PSEUDO_ELEMENT_FLAGS_mozRangeProgress : u32 = 8 ; pub const SERVO_CSS_PSEUDO_ELEMENT_FLAGS_mozRangeThumb : u32 = 8 ; pub const SERVO_CSS_PSEUDO_ELEMENT_FLAGS_mozMeterBar : u32 = 8 ; pub const SERVO_CSS_PSEUDO_ELEMENT_FLAGS_mozPlaceholder : u32 = 8 ; pub const SERVO_CSS_PSEUDO_ELEMENT_FLAGS_placeholder : u32 = 8 ; pub const SERVO_CSS_PSEUDO_ELEMENT_FLAGS_mozColorSwatch : u32 = 12 ; # [ repr ( C ) ] # [ derive ( Debug , Copy ) ] pub struct nsIDOMMediaList { pub _base : root :: nsISupports , } # [ repr ( C ) ] # [ derive ( Debug , Copy , Clone ) ] pub struct nsIDOMMediaList_COMTypeInfo { pub _address : u8 , } # [ test ] fn bindgen_test_layout_nsIDOMMediaList ( ) { assert_eq ! ( :: std :: mem :: size_of :: < nsIDOMMediaList > ( ) , 8usize , concat ! ( "Size of: " , stringify ! ( nsIDOMMediaList ) ) ) ; assert_eq ! ( :: std :: mem :: align_of :: < nsIDOMMediaList > ( ) , 8usize , concat ! ( "Alignment of " , stringify ! ( nsIDOMMediaList ) ) ) ; } impl Clone for nsIDOMMediaList { fn clone ( & self ) -> Self { * self } } pub type nsCSSAnonBoxes_NonInheritingBase = u8 ; pub const nsCSSAnonBoxes_NonInheriting_oofPlaceholder : root :: nsCSSAnonBoxes_NonInheriting = 0 ; pub const nsCSSAnonBoxes_NonInheriting_horizontalFramesetBorder : root :: nsCSSAnonBoxes_NonInheriting = 1 ; pub const nsCSSAnonBoxes_NonInheriting_verticalFramesetBorder : root :: nsCSSAnonBoxes_NonInheriting = 2 ; pub const nsCSSAnonBoxes_NonInheriting_framesetBlank : root :: nsCSSAnonBoxes_NonInheriting = 3 ; pub const nsCSSAnonBoxes_NonInheriting_tableColGroup : root :: nsCSSAnonBoxes_NonInheriting = 4 ; pub const nsCSSAnonBoxes_NonInheriting_tableCol : root :: nsCSSAnonBoxes_NonInheriting = 5 ; pub const nsCSSAnonBoxes_NonInheriting_pageBreak : root :: nsCSSAnonBoxes_NonInheriting = 6 ; pub const nsCSSAnonBoxes_NonInheriting__Count : root :: nsCSSAnonBoxes_NonInheriting = 7 ; pub type nsCSSAnonBoxes_NonInheriting = root :: nsCSSAnonBoxes_NonInheritingBase ; + # [ repr ( C ) ] # [ derive ( Debug ) ] pub struct nsISMILAttr { pub vtable_ : * const nsISMILAttr__bindgen_vtable , } # [ test ] fn bindgen_test_layout_nsISMILAttr ( ) { assert_eq ! ( :: std :: mem :: size_of :: < nsISMILAttr > ( ) , 8usize , concat ! ( "Size of: " , stringify ! ( nsISMILAttr ) ) ) ; assert_eq ! ( :: std :: mem :: align_of :: < nsISMILAttr > ( ) , 8usize , concat ! ( "Alignment of " , stringify ! ( nsISMILAttr ) ) ) ; } pub const ELEMENT_SHARED_RESTYLE_BIT_1 : root :: _bindgen_ty_85 = 8388608 ; pub const ELEMENT_SHARED_RESTYLE_BIT_2 : root :: _bindgen_ty_85 = 16777216 ; pub const ELEMENT_SHARED_RESTYLE_BIT_3 : root :: _bindgen_ty_85 = 33554432 ; pub const ELEMENT_SHARED_RESTYLE_BIT_4 : root :: _bindgen_ty_85 = 67108864 ; pub const ELEMENT_SHARED_RESTYLE_BITS : root :: _bindgen_ty_85 = 125829120 ; pub const ELEMENT_HAS_DIRTY_DESCENDANTS_FOR_SERVO : root :: _bindgen_ty_85 = 8388608 ; pub const ELEMENT_HAS_ANIMATION_ONLY_DIRTY_DESCENDANTS_FOR_SERVO : root :: _bindgen_ty_85 = 16777216 ; pub const ELEMENT_HAS_SNAPSHOT : root :: _bindgen_ty_85 = 33554432 ; pub const ELEMENT_HANDLED_SNAPSHOT : root :: _bindgen_ty_85 = 67108864 ; pub const ELEMENT_HAS_PENDING_RESTYLE : root :: _bindgen_ty_85 = 8388608 ; pub const ELEMENT_IS_POTENTIAL_RESTYLE_ROOT : root :: _bindgen_ty_85 = 16777216 ; pub const ELEMENT_HAS_PENDING_ANIMATION_ONLY_RESTYLE : root :: _bindgen_ty_85 = 33554432 ; pub const ELEMENT_IS_POTENTIAL_ANIMATION_ONLY_RESTYLE_ROOT : root :: _bindgen_ty_85 = 67108864 ; pub const ELEMENT_IS_CONDITIONAL_RESTYLE_ANCESTOR : root :: _bindgen_ty_85 = 134217728 ; pub const ELEMENT_HAS_CHILD_WITH_LATER_SIBLINGS_HINT : root :: _bindgen_ty_85 = 268435456 ; pub const ELEMENT_PENDING_RESTYLE_FLAGS : root :: _bindgen_ty_85 = 41943040 ; pub const ELEMENT_POTENTIAL_RESTYLE_ROOT_FLAGS : root :: _bindgen_ty_85 = 83886080 ; pub const ELEMENT_ALL_RESTYLE_FLAGS : root :: _bindgen_ty_85 = 260046848 ; pub const ELEMENT_TYPE_SPECIFIC_BITS_OFFSET : root :: _bindgen_ty_85 = 27 ; pub type _bindgen_ty_85 = :: std :: os :: raw :: c_uint ; pub const GECKO_IS_NIGHTLY : bool = true ; # [ repr ( C ) ] # [ derive ( Debug , Copy ) ] pub struct ServoBundledURI { pub mURLString : * const u8 , pub mURLStringLength : u32 , pub mExtraData : * mut root :: mozilla :: URLExtraData , } # [ test ] fn bindgen_test_layout_ServoBundledURI ( ) { assert_eq ! ( :: std :: mem :: size_of :: < ServoBundledURI > ( ) , 24usize , concat ! ( "Size of: " , stringify ! ( ServoBundledURI ) ) ) ; assert_eq ! ( :: std :: mem :: align_of :: < ServoBundledURI > ( ) , 8usize , concat ! ( "Alignment of " , stringify ! ( ServoBundledURI ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const ServoBundledURI ) ) . mURLString as * const _ as usize } , 0usize , concat ! ( "Alignment of field: " , stringify ! ( ServoBundledURI ) , "::" , stringify ! ( mURLString ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const ServoBundledURI ) ) . mURLStringLength as * const _ as usize } , 8usize , concat ! ( "Alignment of field: " , stringify ! ( ServoBundledURI ) , "::" , stringify ! ( mURLStringLength ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const ServoBundledURI ) ) . mExtraData as * const _ as usize } , 16usize , concat ! ( "Alignment of field: " , stringify ! ( ServoBundledURI ) , "::" , stringify ! ( mExtraData ) ) ) ; } impl Clone for ServoBundledURI { fn clone ( & self ) -> Self { * self } } # [ repr ( C ) ] # [ derive ( Debug , Copy ) ] pub struct FontSizePrefs { pub mDefaultVariableSize : root :: nscoord , pub mDefaultFixedSize : root :: nscoord , pub mDefaultSerifSize : root :: nscoord , pub mDefaultSansSerifSize : root :: nscoord , pub mDefaultMonospaceSize : root :: nscoord , pub mDefaultCursiveSize : root :: nscoord , pub mDefaultFantasySize : root :: nscoord , } # [ test ] fn bindgen_test_layout_FontSizePrefs ( ) { assert_eq ! ( :: std :: mem :: size_of :: < FontSizePrefs > ( ) , 28usize , concat ! ( "Size of: " , stringify ! ( FontSizePrefs ) ) ) ; assert_eq ! ( :: std :: mem :: align_of :: < FontSizePrefs > ( ) , 4usize , concat ! ( "Alignment of " , stringify ! ( FontSizePrefs ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const FontSizePrefs ) ) . mDefaultVariableSize as * const _ as usize } , 0usize , concat ! ( "Alignment of field: " , stringify ! ( FontSizePrefs ) , "::" , stringify ! ( mDefaultVariableSize ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const FontSizePrefs ) ) . mDefaultFixedSize as * const _ as usize } , 4usize , concat ! ( "Alignment of field: " , stringify ! ( FontSizePrefs ) , "::" , stringify ! ( mDefaultFixedSize ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const FontSizePrefs ) ) . mDefaultSerifSize as * const _ as usize } , 8usize , concat ! ( "Alignment of field: " , stringify ! ( FontSizePrefs ) , "::" , stringify ! ( mDefaultSerifSize ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const FontSizePrefs ) ) . mDefaultSansSerifSize as * const _ as usize } , 12usize , concat ! ( "Alignment of field: " , stringify ! ( FontSizePrefs ) , "::" , stringify ! ( mDefaultSansSerifSize ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const FontSizePrefs ) ) . mDefaultMonospaceSize as * const _ as usize } , 16usize , concat ! ( "Alignment of field: " , stringify ! ( FontSizePrefs ) , "::" , stringify ! ( mDefaultMonospaceSize ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const FontSizePrefs ) ) . mDefaultCursiveSize as * const _ as usize } , 20usize , concat ! ( "Alignment of field: " , stringify ! ( FontSizePrefs ) , "::" , stringify ! ( mDefaultCursiveSize ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const FontSizePrefs ) ) . mDefaultFantasySize as * const _ as usize } , 24usize , concat ! ( "Alignment of field: " , stringify ! ( FontSizePrefs ) , "::" , stringify ! ( mDefaultFantasySize ) ) ) ; } impl Clone for FontSizePrefs { fn clone ( & self ) -> Self { * self } } # [ repr ( C ) ] # [ derive ( Debug , Copy ) ] pub struct GeckoFontMetrics { pub mChSize : root :: nscoord , pub mXSize : root :: nscoord , } # [ test ] fn bindgen_test_layout_GeckoFontMetrics ( ) { assert_eq ! ( :: std :: mem :: size_of :: < GeckoFontMetrics > ( ) , 8usize , concat ! ( "Size of: " , stringify ! ( GeckoFontMetrics ) ) ) ; assert_eq ! ( :: std :: mem :: align_of :: < GeckoFontMetrics > ( ) , 4usize , concat ! ( "Alignment of " , stringify ! ( GeckoFontMetrics ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const GeckoFontMetrics ) ) . mChSize as * const _ as usize } , 0usize , concat ! ( "Alignment of field: " , stringify ! ( GeckoFontMetrics ) , "::" , stringify ! ( mChSize ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const GeckoFontMetrics ) ) . mXSize as * const _ as usize } , 4usize , concat ! ( "Alignment of field: " , stringify ! ( GeckoFontMetrics ) , "::" , stringify ! ( mXSize ) ) ) ; } impl Clone for GeckoFontMetrics { fn clone ( & self ) -> Self { * self } } pub const SERVO_CSS_PSEUDO_ELEMENT_FLAGS_after : u32 = 65 ; pub const SERVO_CSS_PSEUDO_ELEMENT_FLAGS_before : u32 = 65 ; pub const SERVO_CSS_PSEUDO_ELEMENT_FLAGS_backdrop : u32 = 0 ; pub const SERVO_CSS_PSEUDO_ELEMENT_FLAGS_cue : u32 = 36 ; pub const SERVO_CSS_PSEUDO_ELEMENT_FLAGS_firstLetter : u32 = 3 ; pub const SERVO_CSS_PSEUDO_ELEMENT_FLAGS_firstLine : u32 = 3 ; pub const SERVO_CSS_PSEUDO_ELEMENT_FLAGS_mozSelection : u32 = 2 ; pub const SERVO_CSS_PSEUDO_ELEMENT_FLAGS_mozFocusInner : u32 = 0 ; pub const SERVO_CSS_PSEUDO_ELEMENT_FLAGS_mozFocusOuter : u32 = 0 ; pub const SERVO_CSS_PSEUDO_ELEMENT_FLAGS_mozListBullet : u32 = 0 ; pub const SERVO_CSS_PSEUDO_ELEMENT_FLAGS_mozListNumber : u32 = 0 ; pub const SERVO_CSS_PSEUDO_ELEMENT_FLAGS_mozMathAnonymous : u32 = 0 ; pub const SERVO_CSS_PSEUDO_ELEMENT_FLAGS_mozNumberWrapper : u32 = 24 ; pub const SERVO_CSS_PSEUDO_ELEMENT_FLAGS_mozNumberText : u32 = 24 ; pub const SERVO_CSS_PSEUDO_ELEMENT_FLAGS_mozNumberSpinBox : u32 = 24 ; pub const SERVO_CSS_PSEUDO_ELEMENT_FLAGS_mozNumberSpinUp : u32 = 24 ; pub const SERVO_CSS_PSEUDO_ELEMENT_FLAGS_mozNumberSpinDown : u32 = 24 ; pub const SERVO_CSS_PSEUDO_ELEMENT_FLAGS_mozProgressBar : u32 = 8 ; pub const SERVO_CSS_PSEUDO_ELEMENT_FLAGS_mozRangeTrack : u32 = 8 ; pub const SERVO_CSS_PSEUDO_ELEMENT_FLAGS_mozRangeProgress : u32 = 8 ; pub const SERVO_CSS_PSEUDO_ELEMENT_FLAGS_mozRangeThumb : u32 = 8 ; pub const SERVO_CSS_PSEUDO_ELEMENT_FLAGS_mozMeterBar : u32 = 8 ; pub const SERVO_CSS_PSEUDO_ELEMENT_FLAGS_mozPlaceholder : u32 = 8 ; pub const SERVO_CSS_PSEUDO_ELEMENT_FLAGS_placeholder : u32 = 8 ; pub const SERVO_CSS_PSEUDO_ELEMENT_FLAGS_mozColorSwatch : u32 = 12 ; # [ repr ( C ) ] # [ derive ( Debug , Copy ) ] pub struct nsIDOMMediaList { pub _base : root :: nsISupports , } # [ repr ( C ) ] # [ derive ( Debug , Copy , Clone ) ] pub struct nsIDOMMediaList_COMTypeInfo { pub _address : u8 , } # [ test ] fn bindgen_test_layout_nsIDOMMediaList ( ) { assert_eq ! ( :: std :: mem :: size_of :: < nsIDOMMediaList > ( ) , 8usize , concat ! ( "Size of: " , stringify ! ( nsIDOMMediaList ) ) ) ; assert_eq ! ( :: std :: mem :: align_of :: < nsIDOMMediaList > ( ) , 8usize , concat ! ( "Alignment of " , stringify ! ( nsIDOMMediaList ) ) ) ; } impl Clone for nsIDOMMediaList { fn clone ( & self ) -> Self { * self } } pub type nsCSSAnonBoxes_NonInheritingBase = u8 ; pub const nsCSSAnonBoxes_NonInheriting_oofPlaceholder : root :: nsCSSAnonBoxes_NonInheriting = 0 ; pub const nsCSSAnonBoxes_NonInheriting_horizontalFramesetBorder : root :: nsCSSAnonBoxes_NonInheriting = 1 ; pub const nsCSSAnonBoxes_NonInheriting_verticalFramesetBorder : root :: nsCSSAnonBoxes_NonInheriting = 2 ; pub const nsCSSAnonBoxes_NonInheriting_framesetBlank : root :: nsCSSAnonBoxes_NonInheriting = 3 ; pub const nsCSSAnonBoxes_NonInheriting_tableColGroup : root :: nsCSSAnonBoxes_NonInheriting = 4 ; pub const nsCSSAnonBoxes_NonInheriting_tableCol : root :: nsCSSAnonBoxes_NonInheriting = 5 ; pub const nsCSSAnonBoxes_NonInheriting_pageBreak : root :: nsCSSAnonBoxes_NonInheriting = 6 ; pub const nsCSSAnonBoxes_NonInheriting__Count : root :: nsCSSAnonBoxes_NonInheriting = 7 ; pub type nsCSSAnonBoxes_NonInheriting = root :: nsCSSAnonBoxes_NonInheritingBase ; /// templated hashtable class maps keys to interface pointers. /// See nsBaseHashtable for complete declaration. /// @param KeyClass a wrapper-class for the hashtable key, see nsHashKeys.h diff --git a/ports/geckolib/glue.rs b/ports/geckolib/glue.rs index bed1bc48dbf..c3477348a80 100644 --- a/ports/geckolib/glue.rs +++ b/ports/geckolib/glue.rs @@ -270,7 +270,7 @@ fn traverse_subtree( let is_restyle = element.get_data().is_some(); let traversal = RecalcStyleOnly::new(shared_style_context); - let used_parallel = driver::traverse_dom(&traversal, token, thread_pool); + let (used_parallel, stats) = driver::traverse_dom(&traversal, token, thread_pool); if traversal_flags.contains(TraversalFlags::ParallelTraversal) && !traversal_flags.contains(TraversalFlags::AnimationOnly) && @@ -278,7 +278,7 @@ fn traverse_subtree( // We turn off parallel traversal for background tabs; this // shouldn't count in telemetry. We're also focusing on restyles so // we ensure that it's a restyle. - per_doc_data.record_traversal(used_parallel); + per_doc_data.record_traversal(used_parallel, stats); } }