Skip to content

Commit

Permalink
Add telemetry probe for fraction of restyles that are parallel
Browse files Browse the repository at this point in the history
  • Loading branch information
Manishearth committed Dec 12, 2017
1 parent 0fa605d commit d573081
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 2 deletions.
8 changes: 7 additions & 1 deletion components/style/driver.rs
Expand Up @@ -25,11 +25,13 @@ use traversal::{DomTraversal, PerLevelTraversalData, PreTraverseToken};
/// 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
/// then transfer control over to the parallel traversal.
///
/// Returns true if the traversal was parallel
pub fn traverse_dom<E, D>(
traversal: &D,
token: PreTraverseToken<E>,
pool: Option<&rayon::ThreadPool>
)
) -> bool
where
E: TElement,
D: DomTraversal<E>,
Expand All @@ -38,6 +40,7 @@ where
token.traversal_root().expect("Should've ensured we needed to traverse");

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 };

// Declare the main-thread context, as well as the worker-thread contexts,
Expand Down Expand Up @@ -84,6 +87,7 @@ where
// moving to the next level in the dom so that we can pass the same
// depth for all the children.
if pool.is_some() && discovered.len() > WORK_UNIT_MAX {
used_parallel = true;
let pool = pool.unwrap();
maybe_tls = Some(ScopedTLS::<ThreadLocalStyleContext<E>>::new(pool));
let root_opaque = root.as_node().opaque();
Expand Down Expand Up @@ -128,4 +132,6 @@ where
println!("{}", aggregate);
}
}

used_parallel
}
23 changes: 23 additions & 0 deletions components/style/gecko/data.rs
Expand Up @@ -16,6 +16,7 @@ use media_queries::{Device, MediaList};
use properties::ComputedValues;
use servo_arc::Arc;
use shared_lock::{Locked, StylesheetGuards, SharedRwLockReadGuard};
use std::sync::atomic::{AtomicUsize, Ordering};
use stylesheets::{StylesheetContents, StylesheetInDocument};
use stylist::Stylist;

Expand Down Expand Up @@ -112,6 +113,10 @@ impl StylesheetInDocument for GeckoStyleSheet {
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,
}

/// The data itself is an `AtomicRefCell`, which guarantees the proper semantics
Expand All @@ -133,6 +138,8 @@ impl PerDocumentStyleData {

PerDocumentStyleData(AtomicRefCell::new(PerDocumentStyleDataImpl {
stylist: Stylist::new(device, quirks_mode.into()),
total_traversal_count: Default::default(),
parallel_traversal_count: Default::default(),
}))
}

Expand All @@ -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 {
/// Recreate the style data if the stylesheets have changed.
pub fn flush_stylesheets<E>(
Expand Down Expand Up @@ -209,6 +224,14 @@ impl PerDocumentStyleDataImpl {
pub fn add_size_of(&self, ops: &mut MallocSizeOfOps, sizes: &mut ServoStyleSetSizes) {
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 {
Expand Down
13 changes: 12 additions & 1 deletion ports/geckolib/glue.rs
Expand Up @@ -267,8 +267,19 @@ fn traverse_subtree(
None
};

let is_restyle = element.get_data().is_some();

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.
Expand Down

0 comments on commit d573081

Please sign in to comment.