mirror of
https://github.com/servo/servo.git
synced 2025-06-06 16:45:39 +00:00
Plumb time profiler output into tracing (#34238)
* Plumb time profiler output into tracing Signed-off-by: Delan Azabani <dazabani@igalia.com> * Enter the span tightly around the callback Signed-off-by: Delan Azabani <dazabani@igalia.com> * Use `info_span!()` shorthand Signed-off-by: Delan Azabani <dazabani@igalia.com> --------- Signed-off-by: Delan Azabani <dazabani@igalia.com>
This commit is contained in:
parent
495cceb7de
commit
aa7116c75d
16 changed files with 279 additions and 82 deletions
4
Cargo.lock
generated
4
Cargo.lock
generated
|
@ -3832,6 +3832,7 @@ dependencies = [
|
||||||
"smallvec",
|
"smallvec",
|
||||||
"style",
|
"style",
|
||||||
"style_traits",
|
"style_traits",
|
||||||
|
"tracing",
|
||||||
"unicode-bidi",
|
"unicode-bidi",
|
||||||
"unicode-script",
|
"unicode-script",
|
||||||
"webrender_api",
|
"webrender_api",
|
||||||
|
@ -3919,6 +3920,7 @@ dependencies = [
|
||||||
"style",
|
"style",
|
||||||
"style_traits",
|
"style_traits",
|
||||||
"time 0.3.36",
|
"time 0.3.36",
|
||||||
|
"tracing",
|
||||||
"url",
|
"url",
|
||||||
"webrender_api",
|
"webrender_api",
|
||||||
"webrender_traits",
|
"webrender_traits",
|
||||||
|
@ -5564,6 +5566,7 @@ dependencies = [
|
||||||
"servo_config",
|
"servo_config",
|
||||||
"signpost",
|
"signpost",
|
||||||
"time 0.3.36",
|
"time 0.3.36",
|
||||||
|
"tracing",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -6074,6 +6077,7 @@ dependencies = [
|
||||||
"tempfile",
|
"tempfile",
|
||||||
"tendril",
|
"tendril",
|
||||||
"time 0.3.36",
|
"time 0.3.36",
|
||||||
|
"tracing",
|
||||||
"unicode-bidi",
|
"unicode-bidi",
|
||||||
"unicode-segmentation",
|
"unicode-segmentation",
|
||||||
"url",
|
"url",
|
||||||
|
|
|
@ -27,7 +27,8 @@ use ipc_channel::ipc::{self, IpcSharedMemory};
|
||||||
use libc::c_void;
|
use libc::c_void;
|
||||||
use log::{debug, error, info, trace, warn};
|
use log::{debug, error, info, trace, warn};
|
||||||
use pixels::{CorsStatus, Image, PixelFormat};
|
use pixels::{CorsStatus, Image, PixelFormat};
|
||||||
use profile_traits::time::{self as profile_time, profile, ProfilerCategory};
|
use profile_traits::time::{self as profile_time, ProfilerCategory};
|
||||||
|
use profile_traits::time_profile;
|
||||||
use script_traits::CompositorEvent::{MouseButtonEvent, MouseMoveEvent, TouchEvent, WheelEvent};
|
use script_traits::CompositorEvent::{MouseButtonEvent, MouseMoveEvent, TouchEvent, WheelEvent};
|
||||||
use script_traits::{
|
use script_traits::{
|
||||||
AnimationState, AnimationTickType, ConstellationControlMsg, MouseButton, MouseEventType,
|
AnimationState, AnimationTickType, ConstellationControlMsg, MouseButton, MouseEventType,
|
||||||
|
@ -2098,7 +2099,7 @@ impl<Window: WindowMethods + ?Sized> IOCompositor<Window> {
|
||||||
self.assert_gl_framebuffer_complete();
|
self.assert_gl_framebuffer_complete();
|
||||||
}
|
}
|
||||||
|
|
||||||
profile(
|
time_profile!(
|
||||||
ProfilerCategory::Compositing,
|
ProfilerCategory::Compositing,
|
||||||
None,
|
None,
|
||||||
self.time_profiler_chan.clone(),
|
self.time_profiler_chan.clone(),
|
||||||
|
@ -2214,7 +2215,7 @@ impl<Window: WindowMethods + ?Sized> IOCompositor<Window> {
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
CompositeTarget::PngFile(path) => {
|
CompositeTarget::PngFile(path) => {
|
||||||
profile(
|
time_profile!(
|
||||||
ProfilerCategory::ImageSaving,
|
ProfilerCategory::ImageSaving,
|
||||||
None,
|
None,
|
||||||
self.time_profiler_chan.clone(),
|
self.time_profiler_chan.clone(),
|
||||||
|
|
|
@ -13,6 +13,9 @@ path = "lib.rs"
|
||||||
test = true
|
test = true
|
||||||
doctest = false
|
doctest = false
|
||||||
|
|
||||||
|
[features]
|
||||||
|
tracing = ["dep:tracing"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
app_units = { workspace = true }
|
app_units = { workspace = true }
|
||||||
atomic_refcell = { workspace = true }
|
atomic_refcell = { workspace = true }
|
||||||
|
@ -47,6 +50,7 @@ servo_url = { path = "../url" }
|
||||||
smallvec = { workspace = true, features = ["union"] }
|
smallvec = { workspace = true, features = ["union"] }
|
||||||
style = { workspace = true }
|
style = { workspace = true }
|
||||||
style_traits = { workspace = true }
|
style_traits = { workspace = true }
|
||||||
|
tracing = { workspace = true, optional = true }
|
||||||
unicode-bidi = { workspace = true, features = ["with_serde"] }
|
unicode-bidi = { workspace = true, features = ["with_serde"] }
|
||||||
unicode-script = { workspace = true }
|
unicode-script = { workspace = true }
|
||||||
webrender_api = { workspace = true }
|
webrender_api = { workspace = true }
|
||||||
|
|
|
@ -11,7 +11,8 @@
|
||||||
use std::sync::atomic::{AtomicIsize, Ordering};
|
use std::sync::atomic::{AtomicIsize, Ordering};
|
||||||
use std::{mem, ptr};
|
use std::{mem, ptr};
|
||||||
|
|
||||||
use profile_traits::time::{self, profile, TimerMetadata};
|
use profile_traits::time::{self, TimerMetadata};
|
||||||
|
use profile_traits::time_profile;
|
||||||
use servo_config::opts;
|
use servo_config::opts;
|
||||||
use smallvec::SmallVec;
|
use smallvec::SmallVec;
|
||||||
|
|
||||||
|
@ -229,7 +230,7 @@ pub fn reflow(
|
||||||
|
|
||||||
queue.install(move || {
|
queue.install(move || {
|
||||||
rayon::scope_fifo(move |scope| {
|
rayon::scope_fifo(move |scope| {
|
||||||
profile(
|
time_profile!(
|
||||||
time::ProfilerCategory::LayoutParallelWarmup,
|
time::ProfilerCategory::LayoutParallelWarmup,
|
||||||
profiler_metadata,
|
profiler_metadata,
|
||||||
time_profiler_chan,
|
time_profiler_chan,
|
||||||
|
|
|
@ -11,6 +11,9 @@ rust-version.workspace = true
|
||||||
name = "layout_thread_2013"
|
name = "layout_thread_2013"
|
||||||
path = "lib.rs"
|
path = "lib.rs"
|
||||||
|
|
||||||
|
[features]
|
||||||
|
tracing = ["dep:tracing", "layout/tracing"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
app_units = { workspace = true }
|
app_units = { workspace = true }
|
||||||
base = { workspace = true }
|
base = { workspace = true }
|
||||||
|
@ -42,6 +45,7 @@ servo_url = { path = "../url" }
|
||||||
style = { workspace = true }
|
style = { workspace = true }
|
||||||
style_traits = { workspace = true }
|
style_traits = { workspace = true }
|
||||||
time_03 = { workspace = true }
|
time_03 = { workspace = true }
|
||||||
|
tracing = { workspace = true, optional = true }
|
||||||
url = { workspace = true }
|
url = { workspace = true }
|
||||||
webrender_api = { workspace = true }
|
webrender_api = { workspace = true }
|
||||||
webrender_traits = { workspace = true }
|
webrender_traits = { workspace = true }
|
||||||
|
|
|
@ -55,10 +55,10 @@ use net_traits::image_cache::{ImageCache, UsePlaceholder};
|
||||||
use net_traits::ResourceThreads;
|
use net_traits::ResourceThreads;
|
||||||
use parking_lot::RwLock;
|
use parking_lot::RwLock;
|
||||||
use profile_traits::mem::{Report, ReportKind};
|
use profile_traits::mem::{Report, ReportKind};
|
||||||
use profile_traits::path;
|
|
||||||
use profile_traits::time::{
|
use profile_traits::time::{
|
||||||
self as profile_time, profile, TimerMetadata, TimerMetadataFrameType, TimerMetadataReflowType,
|
self as profile_time, TimerMetadata, TimerMetadataFrameType, TimerMetadataReflowType,
|
||||||
};
|
};
|
||||||
|
use profile_traits::{path, time_profile};
|
||||||
use script::layout_dom::{ServoLayoutDocument, ServoLayoutElement, ServoLayoutNode};
|
use script::layout_dom::{ServoLayoutDocument, ServoLayoutElement, ServoLayoutNode};
|
||||||
use script_layout_interface::wrapper_traits::LayoutNode;
|
use script_layout_interface::wrapper_traits::LayoutNode;
|
||||||
use script_layout_interface::{
|
use script_layout_interface::{
|
||||||
|
@ -528,7 +528,7 @@ impl Layout for LayoutThread {
|
||||||
|
|
||||||
fn reflow(&mut self, script_reflow: script_layout_interface::ScriptReflow) {
|
fn reflow(&mut self, script_reflow: script_layout_interface::ScriptReflow) {
|
||||||
let mut result = ScriptReflowResult::new(script_reflow);
|
let mut result = ScriptReflowResult::new(script_reflow);
|
||||||
profile(
|
time_profile!(
|
||||||
profile_time::ProfilerCategory::LayoutPerform,
|
profile_time::ProfilerCategory::LayoutPerform,
|
||||||
self.profiler_metadata(),
|
self.profiler_metadata(),
|
||||||
self.time_profiler_chan.clone(),
|
self.time_profiler_chan.clone(),
|
||||||
|
@ -838,7 +838,7 @@ impl LayoutThread {
|
||||||
) {
|
) {
|
||||||
let writing_mode = layout_root.base().writing_mode;
|
let writing_mode = layout_root.base().writing_mode;
|
||||||
let (metadata, sender) = (self.profiler_metadata(), self.time_profiler_chan.clone());
|
let (metadata, sender) = (self.profiler_metadata(), self.time_profiler_chan.clone());
|
||||||
profile(
|
time_profile!(
|
||||||
profile_time::ProfilerCategory::LayoutDispListBuild,
|
profile_time::ProfilerCategory::LayoutDispListBuild,
|
||||||
metadata.clone(),
|
metadata.clone(),
|
||||||
sender.clone(),
|
sender.clone(),
|
||||||
|
@ -1103,7 +1103,7 @@ impl LayoutThread {
|
||||||
|
|
||||||
if token.should_traverse() {
|
if token.should_traverse() {
|
||||||
// Recalculate CSS styles and rebuild flows and fragments.
|
// Recalculate CSS styles and rebuild flows and fragments.
|
||||||
profile(
|
time_profile!(
|
||||||
profile_time::ProfilerCategory::LayoutStyleRecalc,
|
profile_time::ProfilerCategory::LayoutStyleRecalc,
|
||||||
self.profiler_metadata(),
|
self.profiler_metadata(),
|
||||||
self.time_profiler_chan.clone(),
|
self.time_profiler_chan.clone(),
|
||||||
|
@ -1248,7 +1248,7 @@ impl LayoutThread {
|
||||||
FlowRef::deref_mut(root_flow),
|
FlowRef::deref_mut(root_flow),
|
||||||
);
|
);
|
||||||
|
|
||||||
profile(
|
time_profile!(
|
||||||
profile_time::ProfilerCategory::LayoutRestyleDamagePropagation,
|
profile_time::ProfilerCategory::LayoutRestyleDamagePropagation,
|
||||||
self.profiler_metadata(),
|
self.profiler_metadata(),
|
||||||
self.time_profiler_chan.clone(),
|
self.time_profiler_chan.clone(),
|
||||||
|
@ -1270,7 +1270,7 @@ impl LayoutThread {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Resolve generated content.
|
// Resolve generated content.
|
||||||
profile(
|
time_profile!(
|
||||||
profile_time::ProfilerCategory::LayoutGeneratedContent,
|
profile_time::ProfilerCategory::LayoutGeneratedContent,
|
||||||
self.profiler_metadata(),
|
self.profiler_metadata(),
|
||||||
self.time_profiler_chan.clone(),
|
self.time_profiler_chan.clone(),
|
||||||
|
@ -1278,7 +1278,7 @@ impl LayoutThread {
|
||||||
);
|
);
|
||||||
|
|
||||||
// Guess float placement.
|
// Guess float placement.
|
||||||
profile(
|
time_profile!(
|
||||||
profile_time::ProfilerCategory::LayoutFloatPlacementSpeculation,
|
profile_time::ProfilerCategory::LayoutFloatPlacementSpeculation,
|
||||||
self.profiler_metadata(),
|
self.profiler_metadata(),
|
||||||
self.time_profiler_chan.clone(),
|
self.time_profiler_chan.clone(),
|
||||||
|
@ -1292,7 +1292,7 @@ impl LayoutThread {
|
||||||
.restyle_damage
|
.restyle_damage
|
||||||
.intersects(ServoRestyleDamage::REFLOW | ServoRestyleDamage::REFLOW_OUT_OF_FLOW)
|
.intersects(ServoRestyleDamage::REFLOW | ServoRestyleDamage::REFLOW_OUT_OF_FLOW)
|
||||||
{
|
{
|
||||||
profile(
|
time_profile!(
|
||||||
profile_time::ProfilerCategory::LayoutMain,
|
profile_time::ProfilerCategory::LayoutMain,
|
||||||
self.profiler_metadata(),
|
self.profiler_metadata(),
|
||||||
self.time_profiler_chan.clone(),
|
self.time_profiler_chan.clone(),
|
||||||
|
@ -1316,7 +1316,7 @@ impl LayoutThread {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
profile(
|
time_profile!(
|
||||||
profile_time::ProfilerCategory::LayoutStoreOverflow,
|
profile_time::ProfilerCategory::LayoutStoreOverflow,
|
||||||
self.profiler_metadata(),
|
self.profiler_metadata(),
|
||||||
self.time_profiler_chan.clone(),
|
self.time_profiler_chan.clone(),
|
||||||
|
|
|
@ -43,10 +43,10 @@ use net_traits::image_cache::{ImageCache, UsePlaceholder};
|
||||||
use net_traits::ResourceThreads;
|
use net_traits::ResourceThreads;
|
||||||
use parking_lot::{Mutex, RwLock};
|
use parking_lot::{Mutex, RwLock};
|
||||||
use profile_traits::mem::{Report, ReportKind};
|
use profile_traits::mem::{Report, ReportKind};
|
||||||
use profile_traits::path;
|
|
||||||
use profile_traits::time::{
|
use profile_traits::time::{
|
||||||
self as profile_time, profile, TimerMetadata, TimerMetadataFrameType, TimerMetadataReflowType,
|
self as profile_time, TimerMetadata, TimerMetadataFrameType, TimerMetadataReflowType,
|
||||||
};
|
};
|
||||||
|
use profile_traits::{path, time_profile};
|
||||||
use script::layout_dom::{ServoLayoutDocument, ServoLayoutElement, ServoLayoutNode};
|
use script::layout_dom::{ServoLayoutDocument, ServoLayoutElement, ServoLayoutNode};
|
||||||
use script_layout_interface::{
|
use script_layout_interface::{
|
||||||
Layout, LayoutConfig, LayoutFactory, NodesFromPointQueryType, OffsetParentResponse,
|
Layout, LayoutConfig, LayoutFactory, NodesFromPointQueryType, OffsetParentResponse,
|
||||||
|
@ -500,7 +500,7 @@ impl Layout for LayoutThread {
|
||||||
|
|
||||||
fn reflow(&mut self, script_reflow: ScriptReflow) {
|
fn reflow(&mut self, script_reflow: ScriptReflow) {
|
||||||
let mut result = ScriptReflowResult::new(script_reflow);
|
let mut result = ScriptReflowResult::new(script_reflow);
|
||||||
profile(
|
time_profile!(
|
||||||
profile_time::ProfilerCategory::LayoutPerform,
|
profile_time::ProfilerCategory::LayoutPerform,
|
||||||
self.profiler_metadata(),
|
self.profiler_metadata(),
|
||||||
self.time_profiler_chan.clone(),
|
self.time_profiler_chan.clone(),
|
||||||
|
|
|
@ -16,6 +16,7 @@ path = "lib.rs"
|
||||||
debugmozjs = ['js/debugmozjs']
|
debugmozjs = ['js/debugmozjs']
|
||||||
jitspew = ['js/jitspew']
|
jitspew = ['js/jitspew']
|
||||||
profilemozjs = ['js/profilemozjs']
|
profilemozjs = ['js/profilemozjs']
|
||||||
|
tracing = ["dep:tracing"]
|
||||||
webgl_backtrace = ["canvas_traits/webgl_backtrace"]
|
webgl_backtrace = ["canvas_traits/webgl_backtrace"]
|
||||||
js_backtrace = []
|
js_backtrace = []
|
||||||
refcell_backtrace = ["accountable-refcell"]
|
refcell_backtrace = ["accountable-refcell"]
|
||||||
|
@ -111,6 +112,7 @@ swapper = "0.1"
|
||||||
tempfile = "3"
|
tempfile = "3"
|
||||||
tendril = { version = "0.4.1", features = ["encoding_rs"] }
|
tendril = { version = "0.4.1", features = ["encoding_rs"] }
|
||||||
time_03 = { workspace = true }
|
time_03 = { workspace = true }
|
||||||
|
tracing = { workspace = true, optional = true }
|
||||||
unicode-bidi = { workspace = true }
|
unicode-bidi = { workspace = true }
|
||||||
unicode-segmentation = { workspace = true }
|
unicode-segmentation = { workspace = true }
|
||||||
url = { workspace = true }
|
url = { workspace = true }
|
||||||
|
|
|
@ -52,7 +52,7 @@ use net_traits::{
|
||||||
fetch_async, CoreResourceMsg, CoreResourceThread, FetchResponseListener, IpcSend,
|
fetch_async, CoreResourceMsg, CoreResourceThread, FetchResponseListener, IpcSend,
|
||||||
ReferrerPolicy, ResourceThreads,
|
ReferrerPolicy, ResourceThreads,
|
||||||
};
|
};
|
||||||
use profile_traits::{ipc as profile_ipc, mem as profile_mem, time as profile_time};
|
use profile_traits::{ipc as profile_ipc, mem as profile_mem, time as profile_time, time_profile};
|
||||||
use script_traits::serializable::{BlobData, BlobImpl, FileBlob};
|
use script_traits::serializable::{BlobData, BlobImpl, FileBlob};
|
||||||
use script_traits::transferable::MessagePortImpl;
|
use script_traits::transferable::MessagePortImpl;
|
||||||
use script_traits::{
|
use script_traits::{
|
||||||
|
@ -2686,7 +2686,7 @@ impl GlobalScope {
|
||||||
iframe: profile_time::TimerMetadataFrameType::RootWindow,
|
iframe: profile_time::TimerMetadataFrameType::RootWindow,
|
||||||
incremental: profile_time::TimerMetadataReflowType::FirstReflow,
|
incremental: profile_time::TimerMetadataReflowType::FirstReflow,
|
||||||
};
|
};
|
||||||
profile_time::profile(
|
time_profile!(
|
||||||
profile_time::ProfilerCategory::ScriptEvaluate,
|
profile_time::ProfilerCategory::ScriptEvaluate,
|
||||||
Some(metadata),
|
Some(metadata),
|
||||||
self.time_profiler_chan().clone(),
|
self.time_profiler_chan().clone(),
|
||||||
|
|
|
@ -27,8 +27,9 @@ use net_traits::{
|
||||||
ResourceTimingType,
|
ResourceTimingType,
|
||||||
};
|
};
|
||||||
use profile_traits::time::{
|
use profile_traits::time::{
|
||||||
profile, ProfilerCategory, TimerMetadata, TimerMetadataFrameType, TimerMetadataReflowType,
|
ProfilerCategory, TimerMetadata, TimerMetadataFrameType, TimerMetadataReflowType,
|
||||||
};
|
};
|
||||||
|
use profile_traits::time_profile;
|
||||||
use script_traits::DocumentActivity;
|
use script_traits::DocumentActivity;
|
||||||
use servo_config::pref;
|
use servo_config::pref;
|
||||||
use servo_url::ServoUrl;
|
use servo_url::ServoUrl;
|
||||||
|
@ -521,17 +522,32 @@ impl ServoParser {
|
||||||
iframe: TimerMetadataFrameType::RootWindow,
|
iframe: TimerMetadataFrameType::RootWindow,
|
||||||
incremental: TimerMetadataReflowType::FirstReflow,
|
incremental: TimerMetadataReflowType::FirstReflow,
|
||||||
};
|
};
|
||||||
let profiler_category = self.tokenizer.profiler_category();
|
let profiler_chan = self
|
||||||
profile(
|
.document
|
||||||
profiler_category,
|
.window()
|
||||||
Some(metadata),
|
.upcast::<GlobalScope>()
|
||||||
self.document
|
.time_profiler_chan()
|
||||||
.window()
|
.clone();
|
||||||
.upcast::<GlobalScope>()
|
match self.tokenizer {
|
||||||
.time_profiler_chan()
|
Tokenizer::Html(_) => time_profile!(
|
||||||
.clone(),
|
ProfilerCategory::ScriptParseHTML,
|
||||||
|| self.do_parse_sync(can_gc),
|
Some(metadata),
|
||||||
)
|
profiler_chan,
|
||||||
|
|| self.do_parse_sync(can_gc),
|
||||||
|
),
|
||||||
|
Tokenizer::AsyncHtml(_) => time_profile!(
|
||||||
|
ProfilerCategory::ScriptParseHTML,
|
||||||
|
Some(metadata),
|
||||||
|
profiler_chan,
|
||||||
|
|| self.do_parse_sync(can_gc),
|
||||||
|
),
|
||||||
|
Tokenizer::Xml(_) => time_profile!(
|
||||||
|
ProfilerCategory::ScriptParseXML,
|
||||||
|
Some(metadata),
|
||||||
|
profiler_chan,
|
||||||
|
|| self.do_parse_sync(can_gc),
|
||||||
|
),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn do_parse_sync(&self, can_gc: CanGc) {
|
fn do_parse_sync(&self, can_gc: CanGc) {
|
||||||
|
@ -720,14 +736,6 @@ impl Tokenizer {
|
||||||
Tokenizer::Xml(_) => unimplemented!(),
|
Tokenizer::Xml(_) => unimplemented!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn profiler_category(&self) -> ProfilerCategory {
|
|
||||||
match *self {
|
|
||||||
Tokenizer::Html(_) => ProfilerCategory::ScriptParseHTML,
|
|
||||||
Tokenizer::AsyncHtml(_) => ProfilerCategory::ScriptParseHTML,
|
|
||||||
Tokenizer::Xml(_) => ProfilerCategory::ScriptParseXML,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The context required for asynchronously fetching a document
|
/// The context required for asynchronously fetching a document
|
||||||
|
|
|
@ -74,7 +74,8 @@ use net_traits::{
|
||||||
};
|
};
|
||||||
use percent_encoding::percent_decode;
|
use percent_encoding::percent_decode;
|
||||||
use profile_traits::mem::{self as profile_mem, OpaqueSender, ReportsChan};
|
use profile_traits::mem::{self as profile_mem, OpaqueSender, ReportsChan};
|
||||||
use profile_traits::time::{self as profile_time, profile, ProfilerCategory};
|
use profile_traits::time::{self as profile_time, ProfilerCategory};
|
||||||
|
use profile_traits::time_profile;
|
||||||
use script_layout_interface::{
|
use script_layout_interface::{
|
||||||
node_id_from_scroll_id, LayoutConfig, LayoutFactory, ReflowGoal, ScriptThreadFactory,
|
node_id_from_scroll_id, LayoutConfig, LayoutFactory, ReflowGoal, ScriptThreadFactory,
|
||||||
};
|
};
|
||||||
|
@ -2165,48 +2166,126 @@ impl ScriptThread {
|
||||||
self.notify_activity_to_hang_monitor(&category);
|
self.notify_activity_to_hang_monitor(&category);
|
||||||
let start = Instant::now();
|
let start = Instant::now();
|
||||||
let value = if self.profile_script_events {
|
let value = if self.profile_script_events {
|
||||||
let profiler_cat = match category {
|
let profiler_chan = self.time_profiler_chan.clone();
|
||||||
ScriptThreadEventCategory::AttachLayout => ProfilerCategory::ScriptAttachLayout,
|
match category {
|
||||||
ScriptThreadEventCategory::ConstellationMsg => {
|
ScriptThreadEventCategory::AttachLayout => {
|
||||||
ProfilerCategory::ScriptConstellationMsg
|
time_profile!(ProfilerCategory::ScriptAttachLayout, None, profiler_chan, f)
|
||||||
},
|
},
|
||||||
ScriptThreadEventCategory::DevtoolsMsg => ProfilerCategory::ScriptDevtoolsMsg,
|
ScriptThreadEventCategory::ConstellationMsg => time_profile!(
|
||||||
ScriptThreadEventCategory::DocumentEvent => ProfilerCategory::ScriptDocumentEvent,
|
ProfilerCategory::ScriptConstellationMsg,
|
||||||
ScriptThreadEventCategory::DomEvent => ProfilerCategory::ScriptDomEvent,
|
None,
|
||||||
ScriptThreadEventCategory::FileRead => ProfilerCategory::ScriptFileRead,
|
profiler_chan,
|
||||||
ScriptThreadEventCategory::FormPlannedNavigation => {
|
f
|
||||||
ProfilerCategory::ScriptPlannedNavigation
|
),
|
||||||
|
ScriptThreadEventCategory::DevtoolsMsg => {
|
||||||
|
time_profile!(ProfilerCategory::ScriptDevtoolsMsg, None, profiler_chan, f)
|
||||||
},
|
},
|
||||||
ScriptThreadEventCategory::HistoryEvent => ProfilerCategory::ScriptHistoryEvent,
|
ScriptThreadEventCategory::DocumentEvent => time_profile!(
|
||||||
ScriptThreadEventCategory::ImageCacheMsg => ProfilerCategory::ScriptImageCacheMsg,
|
ProfilerCategory::ScriptDocumentEvent,
|
||||||
ScriptThreadEventCategory::InputEvent => ProfilerCategory::ScriptInputEvent,
|
None,
|
||||||
ScriptThreadEventCategory::NetworkEvent => ProfilerCategory::ScriptNetworkEvent,
|
profiler_chan,
|
||||||
ScriptThreadEventCategory::PortMessage => ProfilerCategory::ScriptPortMessage,
|
f
|
||||||
ScriptThreadEventCategory::Resize => ProfilerCategory::ScriptResize,
|
),
|
||||||
ScriptThreadEventCategory::ScriptEvent => ProfilerCategory::ScriptEvent,
|
ScriptThreadEventCategory::DomEvent => {
|
||||||
ScriptThreadEventCategory::SetScrollState => ProfilerCategory::ScriptSetScrollState,
|
time_profile!(ProfilerCategory::ScriptDomEvent, None, profiler_chan, f)
|
||||||
ScriptThreadEventCategory::UpdateReplacedElement => {
|
|
||||||
ProfilerCategory::ScriptUpdateReplacedElement
|
|
||||||
},
|
},
|
||||||
ScriptThreadEventCategory::StylesheetLoad => ProfilerCategory::ScriptStylesheetLoad,
|
ScriptThreadEventCategory::FileRead => {
|
||||||
ScriptThreadEventCategory::SetViewport => ProfilerCategory::ScriptSetViewport,
|
time_profile!(ProfilerCategory::ScriptFileRead, None, profiler_chan, f)
|
||||||
ScriptThreadEventCategory::TimerEvent => ProfilerCategory::ScriptTimerEvent,
|
|
||||||
ScriptThreadEventCategory::WebSocketEvent => ProfilerCategory::ScriptWebSocketEvent,
|
|
||||||
ScriptThreadEventCategory::WorkerEvent => ProfilerCategory::ScriptWorkerEvent,
|
|
||||||
ScriptThreadEventCategory::WorkletEvent => ProfilerCategory::ScriptWorkletEvent,
|
|
||||||
ScriptThreadEventCategory::ServiceWorkerEvent => {
|
|
||||||
ProfilerCategory::ScriptServiceWorkerEvent
|
|
||||||
},
|
},
|
||||||
ScriptThreadEventCategory::EnterFullscreen => {
|
ScriptThreadEventCategory::FormPlannedNavigation => time_profile!(
|
||||||
ProfilerCategory::ScriptEnterFullscreen
|
ProfilerCategory::ScriptPlannedNavigation,
|
||||||
|
None,
|
||||||
|
profiler_chan,
|
||||||
|
f
|
||||||
|
),
|
||||||
|
ScriptThreadEventCategory::HistoryEvent => {
|
||||||
|
time_profile!(ProfilerCategory::ScriptHistoryEvent, None, profiler_chan, f)
|
||||||
},
|
},
|
||||||
ScriptThreadEventCategory::ExitFullscreen => ProfilerCategory::ScriptExitFullscreen,
|
ScriptThreadEventCategory::ImageCacheMsg => time_profile!(
|
||||||
ScriptThreadEventCategory::PerformanceTimelineTask => {
|
ProfilerCategory::ScriptImageCacheMsg,
|
||||||
ProfilerCategory::ScriptPerformanceEvent
|
None,
|
||||||
|
profiler_chan,
|
||||||
|
f
|
||||||
|
),
|
||||||
|
ScriptThreadEventCategory::InputEvent => {
|
||||||
|
time_profile!(ProfilerCategory::ScriptInputEvent, None, profiler_chan, f)
|
||||||
},
|
},
|
||||||
ScriptThreadEventCategory::WebGPUMsg => ProfilerCategory::ScriptWebGPUMsg,
|
ScriptThreadEventCategory::NetworkEvent => {
|
||||||
};
|
time_profile!(ProfilerCategory::ScriptNetworkEvent, None, profiler_chan, f)
|
||||||
profile(profiler_cat, None, self.time_profiler_chan.clone(), f)
|
},
|
||||||
|
ScriptThreadEventCategory::PortMessage => {
|
||||||
|
time_profile!(ProfilerCategory::ScriptPortMessage, None, profiler_chan, f)
|
||||||
|
},
|
||||||
|
ScriptThreadEventCategory::Resize => {
|
||||||
|
time_profile!(ProfilerCategory::ScriptResize, None, profiler_chan, f)
|
||||||
|
},
|
||||||
|
ScriptThreadEventCategory::ScriptEvent => {
|
||||||
|
time_profile!(ProfilerCategory::ScriptEvent, None, profiler_chan, f)
|
||||||
|
},
|
||||||
|
ScriptThreadEventCategory::SetScrollState => time_profile!(
|
||||||
|
ProfilerCategory::ScriptSetScrollState,
|
||||||
|
None,
|
||||||
|
profiler_chan,
|
||||||
|
f
|
||||||
|
),
|
||||||
|
ScriptThreadEventCategory::UpdateReplacedElement => time_profile!(
|
||||||
|
ProfilerCategory::ScriptUpdateReplacedElement,
|
||||||
|
None,
|
||||||
|
profiler_chan,
|
||||||
|
f
|
||||||
|
),
|
||||||
|
ScriptThreadEventCategory::StylesheetLoad => time_profile!(
|
||||||
|
ProfilerCategory::ScriptStylesheetLoad,
|
||||||
|
None,
|
||||||
|
profiler_chan,
|
||||||
|
f
|
||||||
|
),
|
||||||
|
ScriptThreadEventCategory::SetViewport => {
|
||||||
|
time_profile!(ProfilerCategory::ScriptSetViewport, None, profiler_chan, f)
|
||||||
|
},
|
||||||
|
ScriptThreadEventCategory::TimerEvent => {
|
||||||
|
time_profile!(ProfilerCategory::ScriptTimerEvent, None, profiler_chan, f)
|
||||||
|
},
|
||||||
|
ScriptThreadEventCategory::WebSocketEvent => time_profile!(
|
||||||
|
ProfilerCategory::ScriptWebSocketEvent,
|
||||||
|
None,
|
||||||
|
profiler_chan,
|
||||||
|
f
|
||||||
|
),
|
||||||
|
ScriptThreadEventCategory::WorkerEvent => {
|
||||||
|
time_profile!(ProfilerCategory::ScriptWorkerEvent, None, profiler_chan, f)
|
||||||
|
},
|
||||||
|
ScriptThreadEventCategory::WorkletEvent => {
|
||||||
|
time_profile!(ProfilerCategory::ScriptWorkletEvent, None, profiler_chan, f)
|
||||||
|
},
|
||||||
|
ScriptThreadEventCategory::ServiceWorkerEvent => time_profile!(
|
||||||
|
ProfilerCategory::ScriptServiceWorkerEvent,
|
||||||
|
None,
|
||||||
|
profiler_chan,
|
||||||
|
f
|
||||||
|
),
|
||||||
|
ScriptThreadEventCategory::EnterFullscreen => time_profile!(
|
||||||
|
ProfilerCategory::ScriptEnterFullscreen,
|
||||||
|
None,
|
||||||
|
profiler_chan,
|
||||||
|
f
|
||||||
|
),
|
||||||
|
ScriptThreadEventCategory::ExitFullscreen => time_profile!(
|
||||||
|
ProfilerCategory::ScriptExitFullscreen,
|
||||||
|
None,
|
||||||
|
profiler_chan,
|
||||||
|
f
|
||||||
|
),
|
||||||
|
ScriptThreadEventCategory::PerformanceTimelineTask => time_profile!(
|
||||||
|
ProfilerCategory::ScriptPerformanceEvent,
|
||||||
|
None,
|
||||||
|
profiler_chan,
|
||||||
|
f
|
||||||
|
),
|
||||||
|
ScriptThreadEventCategory::WebGPUMsg => {
|
||||||
|
time_profile!(ProfilerCategory::ScriptWebGPUMsg, None, profiler_chan, f)
|
||||||
|
},
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
f()
|
f()
|
||||||
};
|
};
|
||||||
|
|
|
@ -24,7 +24,7 @@ no-wgl = ["mozangle/egl", "mozangle/build_dlls", "surfman/sm-angle-default"]
|
||||||
dynamic_freetype = ["webrender/dynamic_freetype"]
|
dynamic_freetype = ["webrender/dynamic_freetype"]
|
||||||
profilemozjs = ["script/profilemozjs"]
|
profilemozjs = ["script/profilemozjs"]
|
||||||
refcell_backtrace = ["script/refcell_backtrace"]
|
refcell_backtrace = ["script/refcell_backtrace"]
|
||||||
tracing = ["dep:tracing", "compositing/tracing", "constellation/tracing", "fonts/tracing", "layout_thread_2020/tracing"]
|
tracing = ["dep:tracing", "compositing/tracing", "constellation/tracing", "fonts/tracing", "layout_thread_2013/tracing", "layout_thread_2020/tracing", "profile_traits/tracing", "script/tracing"]
|
||||||
webdriver = ["webdriver_server"]
|
webdriver = ["webdriver_server"]
|
||||||
webgl_backtrace = [
|
webgl_backtrace = [
|
||||||
"script/webgl_backtrace",
|
"script/webgl_backtrace",
|
||||||
|
|
|
@ -11,6 +11,9 @@ rust-version.workspace = true
|
||||||
name = "profile_traits"
|
name = "profile_traits"
|
||||||
path = "lib.rs"
|
path = "lib.rs"
|
||||||
|
|
||||||
|
[features]
|
||||||
|
tracing = ["dep:tracing"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
base = { workspace = true }
|
base = { workspace = true }
|
||||||
crossbeam-channel = { workspace = true }
|
crossbeam-channel = { workspace = true }
|
||||||
|
@ -20,3 +23,4 @@ serde = { workspace = true }
|
||||||
servo_config = { path = "../../config" }
|
servo_config = { path = "../../config" }
|
||||||
signpost = { git = "https://github.com/pcwalton/signpost.git" }
|
signpost = { git = "https://github.com/pcwalton/signpost.git" }
|
||||||
time_03 = { workspace = true }
|
time_03 = { workspace = true }
|
||||||
|
tracing = { workspace = true, optional = true }
|
||||||
|
|
|
@ -7,8 +7,8 @@ use std::io::Error;
|
||||||
use ipc_channel::ipc;
|
use ipc_channel::ipc;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
use crate::time;
|
|
||||||
use crate::time::{ProfilerCategory, ProfilerChan};
|
use crate::time::{ProfilerCategory, ProfilerChan};
|
||||||
|
use crate::time_profile;
|
||||||
|
|
||||||
pub struct IpcReceiver<T>
|
pub struct IpcReceiver<T>
|
||||||
where
|
where
|
||||||
|
@ -23,7 +23,7 @@ where
|
||||||
T: for<'de> Deserialize<'de> + Serialize,
|
T: for<'de> Deserialize<'de> + Serialize,
|
||||||
{
|
{
|
||||||
pub fn recv(&self) -> Result<T, ipc::IpcError> {
|
pub fn recv(&self) -> Result<T, ipc::IpcError> {
|
||||||
time::profile(
|
time_profile!(
|
||||||
ProfilerCategory::IpcReceiver,
|
ProfilerCategory::IpcReceiver,
|
||||||
None,
|
None,
|
||||||
self.time_profile_chan.clone(),
|
self.time_profile_chan.clone(),
|
||||||
|
@ -61,7 +61,7 @@ pub struct IpcBytesReceiver {
|
||||||
|
|
||||||
impl IpcBytesReceiver {
|
impl IpcBytesReceiver {
|
||||||
pub fn recv(&self) -> Result<Vec<u8>, ipc::IpcError> {
|
pub fn recv(&self) -> Result<Vec<u8>, ipc::IpcError> {
|
||||||
time::profile(
|
time_profile!(
|
||||||
ProfilerCategory::IpcBytesReceiver,
|
ProfilerCategory::IpcBytesReceiver,
|
||||||
None,
|
None,
|
||||||
self.time_profile_chan.clone(),
|
self.time_profile_chan.clone(),
|
||||||
|
|
|
@ -11,3 +11,17 @@
|
||||||
pub mod ipc;
|
pub mod ipc;
|
||||||
pub mod mem;
|
pub mod mem;
|
||||||
pub mod time;
|
pub mod time;
|
||||||
|
|
||||||
|
/// Measure the given callback with the time profiler and (if enabled) tracing.
|
||||||
|
///
|
||||||
|
/// `$category` must be const, because we use it to derive the span name.
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! time_profile {
|
||||||
|
($category:expr, $meta:expr, $profiler_chan:expr, $($callback:tt)+) => {{
|
||||||
|
#[cfg(feature = "tracing")]
|
||||||
|
let span = tracing::info_span!($category.variant_name(), servo_profiling = true);
|
||||||
|
#[cfg(not(feature = "tracing"))]
|
||||||
|
let span = ();
|
||||||
|
$crate::time::profile($category, $meta, $profiler_chan, span, $($callback)+)
|
||||||
|
}};
|
||||||
|
}
|
||||||
|
|
|
@ -118,6 +118,71 @@ pub enum ProfilerCategory {
|
||||||
IpcBytesReceiver = 0x84,
|
IpcBytesReceiver = 0x84,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl ProfilerCategory {
|
||||||
|
pub const fn variant_name(&self) -> &'static str {
|
||||||
|
match self {
|
||||||
|
ProfilerCategory::Compositing => "Compositing",
|
||||||
|
ProfilerCategory::LayoutPerform => "LayoutPerform",
|
||||||
|
ProfilerCategory::LayoutStyleRecalc => "LayoutStyleRecalc",
|
||||||
|
ProfilerCategory::LayoutTextShaping => "LayoutTextShaping",
|
||||||
|
ProfilerCategory::LayoutRestyleDamagePropagation => "LayoutRestyleDamagePropagation",
|
||||||
|
ProfilerCategory::LayoutNonIncrementalReset => "LayoutNonIncrementalReset",
|
||||||
|
ProfilerCategory::LayoutSelectorMatch => "LayoutSelectorMatch",
|
||||||
|
ProfilerCategory::LayoutTreeBuilder => "LayoutTreeBuilder",
|
||||||
|
ProfilerCategory::LayoutDamagePropagate => "LayoutDamagePropagate",
|
||||||
|
ProfilerCategory::LayoutGeneratedContent => "LayoutGeneratedContent",
|
||||||
|
ProfilerCategory::LayoutDisplayListSorting => "LayoutDisplayListSorting",
|
||||||
|
ProfilerCategory::LayoutFloatPlacementSpeculation => "LayoutFloatPlacementSpeculation",
|
||||||
|
ProfilerCategory::LayoutMain => "LayoutMain",
|
||||||
|
ProfilerCategory::LayoutStoreOverflow => "LayoutStoreOverflow",
|
||||||
|
ProfilerCategory::LayoutParallelWarmup => "LayoutParallelWarmup",
|
||||||
|
ProfilerCategory::LayoutDispListBuild => "LayoutDispListBuild",
|
||||||
|
ProfilerCategory::NetHTTPRequestResponse => "NetHTTPRequestResponse",
|
||||||
|
ProfilerCategory::PaintingPerTile => "PaintingPerTile",
|
||||||
|
ProfilerCategory::PaintingPrepBuff => "PaintingPrepBuff",
|
||||||
|
ProfilerCategory::Painting => "Painting",
|
||||||
|
ProfilerCategory::ImageDecoding => "ImageDecoding",
|
||||||
|
ProfilerCategory::ImageSaving => "ImageSaving",
|
||||||
|
ProfilerCategory::ScriptAttachLayout => "ScriptAttachLayout",
|
||||||
|
ProfilerCategory::ScriptConstellationMsg => "ScriptConstellationMsg",
|
||||||
|
ProfilerCategory::ScriptDevtoolsMsg => "ScriptDevtoolsMsg",
|
||||||
|
ProfilerCategory::ScriptDocumentEvent => "ScriptDocumentEvent",
|
||||||
|
ProfilerCategory::ScriptDomEvent => "ScriptDomEvent",
|
||||||
|
ProfilerCategory::ScriptEvaluate => "ScriptEvaluate",
|
||||||
|
ProfilerCategory::ScriptEvent => "ScriptEvent",
|
||||||
|
ProfilerCategory::ScriptFileRead => "ScriptFileRead",
|
||||||
|
ProfilerCategory::ScriptImageCacheMsg => "ScriptImageCacheMsg",
|
||||||
|
ProfilerCategory::ScriptInputEvent => "ScriptInputEvent",
|
||||||
|
ProfilerCategory::ScriptNetworkEvent => "ScriptNetworkEvent",
|
||||||
|
ProfilerCategory::ScriptParseHTML => "ScriptParseHTML",
|
||||||
|
ProfilerCategory::ScriptPlannedNavigation => "ScriptPlannedNavigation",
|
||||||
|
ProfilerCategory::ScriptResize => "ScriptResize",
|
||||||
|
ProfilerCategory::ScriptSetScrollState => "ScriptSetScrollState",
|
||||||
|
ProfilerCategory::ScriptSetViewport => "ScriptSetViewport",
|
||||||
|
ProfilerCategory::ScriptTimerEvent => "ScriptTimerEvent",
|
||||||
|
ProfilerCategory::ScriptStylesheetLoad => "ScriptStylesheetLoad",
|
||||||
|
ProfilerCategory::ScriptUpdateReplacedElement => "ScriptUpdateReplacedElement",
|
||||||
|
ProfilerCategory::ScriptWebSocketEvent => "ScriptWebSocketEvent",
|
||||||
|
ProfilerCategory::ScriptWorkerEvent => "ScriptWorkerEvent",
|
||||||
|
ProfilerCategory::ScriptServiceWorkerEvent => "ScriptServiceWorkerEvent",
|
||||||
|
ProfilerCategory::ScriptParseXML => "ScriptParseXML",
|
||||||
|
ProfilerCategory::ScriptEnterFullscreen => "ScriptEnterFullscreen",
|
||||||
|
ProfilerCategory::ScriptExitFullscreen => "ScriptExitFullscreen",
|
||||||
|
ProfilerCategory::ScriptWebVREvent => "ScriptWebVREvent",
|
||||||
|
ProfilerCategory::ScriptWorkletEvent => "ScriptWorkletEvent",
|
||||||
|
ProfilerCategory::ScriptPerformanceEvent => "ScriptPerformanceEvent",
|
||||||
|
ProfilerCategory::ScriptHistoryEvent => "ScriptHistoryEvent",
|
||||||
|
ProfilerCategory::ScriptPortMessage => "ScriptPortMessage",
|
||||||
|
ProfilerCategory::ScriptWebGPUMsg => "ScriptWebGPUMsg",
|
||||||
|
ProfilerCategory::TimeToFirstPaint => "TimeToFirstPaint",
|
||||||
|
ProfilerCategory::TimeToFirstContentfulPaint => "TimeToFirstContentfulPaint",
|
||||||
|
ProfilerCategory::TimeToInteractive => "TimeToInteractive",
|
||||||
|
ProfilerCategory::IpcReceiver => "IpcReceiver",
|
||||||
|
ProfilerCategory::IpcBytesReceiver => "IpcBytesReceiver",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Deserialize, Eq, Ord, PartialEq, PartialOrd, Serialize)]
|
#[derive(Clone, Debug, Deserialize, Eq, Ord, PartialEq, PartialOrd, Serialize)]
|
||||||
pub enum TimerMetadataFrameType {
|
pub enum TimerMetadataFrameType {
|
||||||
RootWindow,
|
RootWindow,
|
||||||
|
@ -130,10 +195,17 @@ pub enum TimerMetadataReflowType {
|
||||||
FirstReflow,
|
FirstReflow,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "tracing")]
|
||||||
|
pub type Span = tracing::Span;
|
||||||
|
#[cfg(not(feature = "tracing"))]
|
||||||
|
pub type Span = ();
|
||||||
|
|
||||||
pub fn profile<T, F>(
|
pub fn profile<T, F>(
|
||||||
category: ProfilerCategory,
|
category: ProfilerCategory,
|
||||||
meta: Option<TimerMetadata>,
|
meta: Option<TimerMetadata>,
|
||||||
profiler_chan: ProfilerChan,
|
profiler_chan: ProfilerChan,
|
||||||
|
#[cfg(feature = "tracing")] span: Span,
|
||||||
|
#[cfg(not(feature = "tracing"))] _span: Span,
|
||||||
callback: F,
|
callback: F,
|
||||||
) -> T
|
) -> T
|
||||||
where
|
where
|
||||||
|
@ -143,7 +215,11 @@ where
|
||||||
signpost::start(category as u32, &[0, 0, 0, (category as usize) >> 4]);
|
signpost::start(category as u32, &[0, 0, 0, (category as usize) >> 4]);
|
||||||
}
|
}
|
||||||
let start_time = CrossProcessInstant::now();
|
let start_time = CrossProcessInstant::now();
|
||||||
let val = callback();
|
let val = {
|
||||||
|
#[cfg(feature = "tracing")]
|
||||||
|
let _enter = span.enter();
|
||||||
|
callback()
|
||||||
|
};
|
||||||
let end_time = CrossProcessInstant::now();
|
let end_time = CrossProcessInstant::now();
|
||||||
|
|
||||||
if opts::get().debug.signpost {
|
if opts::get().debug.signpost {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue