Bug 1505908 - Add Gecko profiler labels for when the style threads are doing work. r=emilio

Differential Revision: https://phabricator.services.mozilla.com/D30869

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Cameron McCormack 2019-05-14 05:00:45 +00:00
Родитель e510881888
Коммит 4b20fc81c7
12 изменённых файлов: 139 добавлений и 1 удалений

Просмотреть файл

@ -2170,6 +2170,20 @@ void Gecko_RegisterProfilerThread(const char* name) {
void Gecko_UnregisterProfilerThread() { PROFILER_UNREGISTER_THREAD(); }
#ifdef MOZ_GECKO_PROFILER
void Gecko_Construct_AutoProfilerLabel(AutoProfilerLabel* aAutoLabel,
JS::ProfilingCategoryPair aCatPair) {
new (aAutoLabel) AutoProfilerLabel(
"", nullptr, aCatPair,
uint32_t(
js::ProfilingStackFrame::Flags::LABEL_DETERMINED_BY_CATEGORY_PAIR));
}
void Gecko_Destroy_AutoProfilerLabel(AutoProfilerLabel* aAutoLabel) {
aAutoLabel->~AutoProfilerLabel();
}
#endif
bool Gecko_DocumentRule_UseForPresentation(
const Document* aDocument, const nsACString* aPattern,
DocumentMatchingFunction aMatchingFunction) {

Просмотреть файл

@ -735,6 +735,12 @@ void Gecko_AddPropertyToSet(nsCSSPropertyIDSet*, nsCSSPropertyID);
void Gecko_RegisterProfilerThread(const char* name);
void Gecko_UnregisterProfilerThread();
#ifdef MOZ_GECKO_PROFILER
void Gecko_Construct_AutoProfilerLabel(mozilla::AutoProfilerLabel*,
JS::ProfilingCategoryPair);
void Gecko_Destroy_AutoProfilerLabel(mozilla::AutoProfilerLabel*);
#endif
bool Gecko_DocumentRule_UseForPresentation(
const mozilla::dom::Document*, const nsACString* aPattern,
mozilla::css::DocumentMatchingFunction);

Просмотреть файл

@ -35,6 +35,7 @@ headers = [
"nsNameSpaceManager.h",
"nsMediaFeatures.h",
"nsXBLBinding.h",
"GeckoProfiler.h",
]
raw-lines = [
# FIXME(emilio): Incrementally remove these "pub use"s. Probably
@ -159,6 +160,7 @@ whitelist-vars = [
"GECKO_IS_NIGHTLY",
"mozilla::detail::gGkAtoms",
"mozilla::detail::kGkAtomsArrayOffset",
"mozilla::profiler::detail::RacyFeatures::sActiveAndFeatures",
]
# TODO(emilio): A bunch of types here can go away once we generate bindings and
# structs together.
@ -328,6 +330,7 @@ whitelist-types = [
"mozilla::dom::MediaList",
"mozilla::StyleRuleInclusion",
"nsStyleTransformMatrix::MatrixTransformOperator",
"mozilla::profiler::detail::RacyFeatures",
]
opaque-types = [
"mozilla::StyleThinArc", # https://github.com/rust-lang/rust-bindgen/issues/1557

Просмотреть файл

@ -22,6 +22,7 @@ servo = ["serde", "style_traits/servo", "servo_atoms", "servo_config", "html5eve
"cssparser/serde", "encoding_rs", "malloc_size_of/servo", "arrayvec/use_union",
"servo_url", "string_cache", "crossbeam-channel", "to_shmem/servo", "servo_arc/servo"]
gecko_debug = []
gecko_profiler = []
[dependencies]
app_units = "0.7"

Просмотреть файл

@ -134,6 +134,7 @@ pub fn traverse_dom<E, D>(
let drain = discovered.drain(..);
pool.install(|| {
rayon::scope(|scope| {
profiler_label!(Style);
parallel::traverse_nodes(
drain,
DispatchMode::TailCall,

Просмотреть файл

@ -13,6 +13,8 @@ pub mod conversions;
pub mod data;
pub mod media_features;
pub mod media_queries;
#[cfg(feature = "gecko_profiler")]
pub mod profiler;
pub mod pseudo_element;
pub mod restyle_damage;
pub mod rules;

Просмотреть файл

@ -0,0 +1,76 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
//! Gecko profiler support.
//!
//! Use the `profiler_label!` macro from macros.rs.
use crate::gecko_bindings::structs;
/// A label describing a category of work that style threads can perform.
pub enum ProfilerLabel {
/// Style computation.
Style,
/// Style sheet parsing.
Parse,
}
/// RAII object that constructs and destroys a C++ AutoProfilerLabel object
/// pointed to be the specified reference.
#[cfg(feature = "gecko_profiler")]
pub struct AutoProfilerLabel<'a>(&'a mut structs::AutoProfilerLabel);
#[cfg(feature = "gecko_profiler")]
impl<'a> AutoProfilerLabel<'a> {
/// Creates a new AutoProfilerLabel with the specified label type.
///
/// unsafe since the caller must ensure that `label` is allocated on the
/// stack.
#[inline]
pub unsafe fn new(
label: &mut structs::AutoProfilerLabel,
label_type: ProfilerLabel,
) -> AutoProfilerLabel {
let category_pair = match label_type {
ProfilerLabel::Style => structs::JS::ProfilingCategoryPair_LAYOUT_StyleComputation,
ProfilerLabel::Parse => structs::JS::ProfilingCategoryPair_LAYOUT_CSSParsing,
};
structs::Gecko_Construct_AutoProfilerLabel(label, category_pair);
AutoProfilerLabel(label)
}
}
#[cfg(feature = "gecko_profiler")]
impl<'a> Drop for AutoProfilerLabel<'a> {
#[inline]
fn drop(&mut self) {
unsafe {
structs::Gecko_Destroy_AutoProfilerLabel(self.0);
}
}
}
/// Whether the Gecko profiler is currently active.
///
/// This implementation must be kept in sync with
/// `mozilla::profiler::detail::RacyFeatures::IsActive`.
#[cfg(feature = "gecko_profiler")]
#[inline]
pub fn profiler_is_active() -> bool {
use self::structs::profiler::detail;
use std::mem;
use std::sync::atomic::{AtomicU32, Ordering};
let active_and_features: &AtomicU32 = unsafe {
mem::transmute(&detail::RacyFeatures_sActiveAndFeatures)
};
(active_and_features.load(Ordering::Relaxed) & detail::RacyFeatures_Active) != 0
}
/// Always false when the Gecko profiler is disabled.
#[cfg(not(feature = "gecko_profiler"))]
#[inline]
pub fn profiler_is_active() -> bool {
false
}

Просмотреть файл

@ -104,3 +104,33 @@ macro_rules! define_keyword_type {
}
};
}
/// Place a Gecko profiler label on the stack.
///
/// The `label_type` argument must be the name of a variant of `ProfilerLabel`.
#[cfg(feature = "gecko_profiler")]
#[macro_export]
macro_rules! profiler_label {
($label_type:ident) => {
let mut _profiler_label: $crate::gecko_bindings::structs::AutoProfilerLabel = unsafe {
::std::mem::uninitialized()
};
let _profiler_label = if $crate::gecko::profiler::profiler_is_active() {
unsafe {
Some($crate::gecko::profiler::AutoProfilerLabel::new(
&mut _profiler_label,
$crate::gecko::profiler::ProfilerLabel::$label_type,
))
}
} else {
None
};
}
}
/// No-op when the Gecko profiler is not available.
#[cfg(not(feature = "gecko_profiler"))]
#[macro_export]
macro_rules! profiler_label {
($label_type:ident) => {}
}

Просмотреть файл

@ -277,6 +277,7 @@ pub fn traverse_nodes<'a, 'scope, E, D, I>(
top_down_dom(&work, root, traversal_data, scope, pool, traversal, tls);
} else {
scope.spawn(move |scope| {
profiler_label!(Style);
let work = work;
top_down_dom(&work, root, traversal_data, scope, pool, traversal, tls);
});
@ -286,6 +287,7 @@ pub fn traverse_nodes<'a, 'scope, E, D, I>(
let nodes: WorkUnit<E::ConcreteNode> = chunk.collect();
let traversal_data_copy = traversal_data.clone();
scope.spawn(move |scope| {
profiler_label!(Style);
let n = nodes;
top_down_dom(&*n, root, traversal_data_copy, scope, pool, traversal, tls)
});

Просмотреть файл

@ -11,6 +11,7 @@ path = "lib.rs"
[features]
bindgen = ["style/use_bindgen"]
gecko_debug = ["style/gecko_debug", "nsstring/gecko_debug"]
gecko_profiler = ["style/gecko_profiler"]
[dependencies]
atomic_refcell = "0.1"

Просмотреть файл

@ -18,6 +18,7 @@ use std::fmt::Write;
use std::iter;
use std::os::raw::c_void;
use std::ptr;
use style::profiler_label;
use style::applicable_declarations::ApplicableDeclarationBlock;
use style::author_styles::AuthorStyles;
use style::context::ThreadLocalStyleContext;
@ -1411,6 +1412,7 @@ pub unsafe extern "C" fn Servo_StyleSheet_FromUTF8BytesAsync(
if let Some(thread_pool) = STYLE_THREAD_POOL.style_thread_pool.as_ref() {
thread_pool.spawn(|| {
profiler_label!(Parse);
async_parser.parse();
});
} else {

Просмотреть файл

@ -59,7 +59,7 @@ cranelift_x86 = ["jsrust_shared/cranelift_x86"]
cranelift_arm32 = ["jsrust_shared/cranelift_arm32"]
cranelift_arm64 = ["jsrust_shared/cranelift_arm64"]
cranelift_none = ["jsrust_shared/cranelift_none"]
gecko_profiler = ["profiler_helper"]
gecko_profiler = ["profiler_helper", "geckoservo/gecko_profiler"]
gecko_profiler_parse_elf = ["profiler_helper/parse_elf"]
new_xulstore = ["xulstore"]
new_cert_storage = ["cert_storage"]