mirror of
https://github.com/servo/servo.git
synced 2025-08-03 12:40:06 +01:00
Add telemetry probe for fraction of restyles that are parallel
This commit is contained in:
parent
0fa605d243
commit
d573081fe5
3 changed files with 42 additions and 2 deletions
|
@ -25,11 +25,13 @@ use traversal::{DomTraversal, PerLevelTraversalData, PreTraverseToken};
|
||||||
/// processing, until we arrive at a wide enough level in the DOM that the
|
/// processing, until we arrive at a wide enough level in the DOM that the
|
||||||
/// parallel traversal would parallelize it. If a thread pool is provided, we
|
/// parallel traversal would parallelize it. If a thread pool is provided, we
|
||||||
/// then transfer control over to the parallel traversal.
|
/// then transfer control over to the parallel traversal.
|
||||||
|
///
|
||||||
|
/// Returns true if the traversal was parallel
|
||||||
pub fn traverse_dom<E, D>(
|
pub fn traverse_dom<E, D>(
|
||||||
traversal: &D,
|
traversal: &D,
|
||||||
token: PreTraverseToken<E>,
|
token: PreTraverseToken<E>,
|
||||||
pool: Option<&rayon::ThreadPool>
|
pool: Option<&rayon::ThreadPool>
|
||||||
)
|
) -> bool
|
||||||
where
|
where
|
||||||
E: TElement,
|
E: TElement,
|
||||||
D: DomTraversal<E>,
|
D: DomTraversal<E>,
|
||||||
|
@ -38,6 +40,7 @@ where
|
||||||
token.traversal_root().expect("Should've ensured we needed to traverse");
|
token.traversal_root().expect("Should've ensured we needed to traverse");
|
||||||
|
|
||||||
let dump_stats = traversal.shared_context().options.dump_style_statistics;
|
let dump_stats = traversal.shared_context().options.dump_style_statistics;
|
||||||
|
let mut used_parallel = false;
|
||||||
let start_time = if dump_stats { Some(time::precise_time_s()) } else { None };
|
let start_time = if dump_stats { Some(time::precise_time_s()) } else { None };
|
||||||
|
|
||||||
// Declare the main-thread context, as well as the worker-thread contexts,
|
// Declare the main-thread context, as well as the worker-thread contexts,
|
||||||
|
@ -84,6 +87,7 @@ where
|
||||||
// moving to the next level in the dom so that we can pass the same
|
// moving to the next level in the dom so that we can pass the same
|
||||||
// depth for all the children.
|
// depth for all the children.
|
||||||
if pool.is_some() && discovered.len() > WORK_UNIT_MAX {
|
if pool.is_some() && discovered.len() > WORK_UNIT_MAX {
|
||||||
|
used_parallel = true;
|
||||||
let pool = pool.unwrap();
|
let pool = pool.unwrap();
|
||||||
maybe_tls = Some(ScopedTLS::<ThreadLocalStyleContext<E>>::new(pool));
|
maybe_tls = Some(ScopedTLS::<ThreadLocalStyleContext<E>>::new(pool));
|
||||||
let root_opaque = root.as_node().opaque();
|
let root_opaque = root.as_node().opaque();
|
||||||
|
@ -128,4 +132,6 @@ where
|
||||||
println!("{}", aggregate);
|
println!("{}", aggregate);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
used_parallel
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,6 +16,7 @@ use media_queries::{Device, MediaList};
|
||||||
use properties::ComputedValues;
|
use properties::ComputedValues;
|
||||||
use servo_arc::Arc;
|
use servo_arc::Arc;
|
||||||
use shared_lock::{Locked, StylesheetGuards, SharedRwLockReadGuard};
|
use shared_lock::{Locked, StylesheetGuards, SharedRwLockReadGuard};
|
||||||
|
use std::sync::atomic::{AtomicUsize, Ordering};
|
||||||
use stylesheets::{StylesheetContents, StylesheetInDocument};
|
use stylesheets::{StylesheetContents, StylesheetInDocument};
|
||||||
use stylist::Stylist;
|
use stylist::Stylist;
|
||||||
|
|
||||||
|
@ -112,6 +113,10 @@ impl StylesheetInDocument for GeckoStyleSheet {
|
||||||
pub struct PerDocumentStyleDataImpl {
|
pub struct PerDocumentStyleDataImpl {
|
||||||
/// Rule processor.
|
/// Rule processor.
|
||||||
pub stylist: Stylist,
|
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,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The data itself is an `AtomicRefCell`, which guarantees the proper semantics
|
/// The data itself is an `AtomicRefCell`, which guarantees the proper semantics
|
||||||
|
@ -133,6 +138,8 @@ impl PerDocumentStyleData {
|
||||||
|
|
||||||
PerDocumentStyleData(AtomicRefCell::new(PerDocumentStyleDataImpl {
|
PerDocumentStyleData(AtomicRefCell::new(PerDocumentStyleDataImpl {
|
||||||
stylist: Stylist::new(device, quirks_mode.into()),
|
stylist: Stylist::new(device, quirks_mode.into()),
|
||||||
|
total_traversal_count: Default::default(),
|
||||||
|
parallel_traversal_count: Default::default(),
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -147,6 +154,14 @@ 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) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl PerDocumentStyleDataImpl {
|
impl PerDocumentStyleDataImpl {
|
||||||
/// Recreate the style data if the stylesheets have changed.
|
/// Recreate the style data if the stylesheets have changed.
|
||||||
pub fn flush_stylesheets<E>(
|
pub fn flush_stylesheets<E>(
|
||||||
|
@ -209,6 +224,14 @@ impl PerDocumentStyleDataImpl {
|
||||||
pub fn add_size_of(&self, ops: &mut MallocSizeOfOps, sizes: &mut ServoStyleSetSizes) {
|
pub fn add_size_of(&self, ops: &mut MallocSizeOfOps, sizes: &mut ServoStyleSetSizes) {
|
||||||
self.stylist.add_size_of(ops, sizes);
|
self.stylist.add_size_of(ops, sizes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe impl HasFFI for PerDocumentStyleData {
|
unsafe impl HasFFI for PerDocumentStyleData {
|
||||||
|
|
|
@ -267,8 +267,19 @@ fn traverse_subtree(
|
||||||
None
|
None
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let is_restyle = element.get_data().is_some();
|
||||||
|
|
||||||
let traversal = RecalcStyleOnly::new(shared_style_context);
|
let traversal = RecalcStyleOnly::new(shared_style_context);
|
||||||
driver::traverse_dom(&traversal, token, thread_pool);
|
let used_parallel = driver::traverse_dom(&traversal, token, thread_pool);
|
||||||
|
|
||||||
|
if traversal_flags.contains(TraversalFlags::ParallelTraversal) &&
|
||||||
|
!traversal_flags.contains(TraversalFlags::AnimationOnly) &&
|
||||||
|
is_restyle && !element.is_native_anonymous() {
|
||||||
|
// 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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Traverses the subtree rooted at `root` for restyling.
|
/// Traverses the subtree rooted at `root` for restyling.
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue