mirror of
https://github.com/servo/servo.git
synced 2025-08-03 04:30:10 +01:00
Send the start and end half of a TimelineMarker to the devtools PullTimelineMarkers thread together.
This commit is contained in:
parent
72125f070d
commit
cf55d3191d
4 changed files with 47 additions and 99 deletions
|
@ -6,7 +6,6 @@ use ipc_channel::ipc::{self, IpcReceiver, IpcSender};
|
||||||
use msg::constellation_msg::PipelineId;
|
use msg::constellation_msg::PipelineId;
|
||||||
use rustc_serialize::{json, Encoder, Encodable};
|
use rustc_serialize::{json, Encoder, Encodable};
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
use std::collections::{HashMap, VecDeque};
|
|
||||||
use std::net::TcpStream;
|
use std::net::TcpStream;
|
||||||
use std::sync::mpsc::channel;
|
use std::sync::mpsc::channel;
|
||||||
use std::sync::{Arc, Mutex};
|
use std::sync::{Arc, Mutex};
|
||||||
|
@ -17,7 +16,7 @@ use actors::framerate::FramerateActor;
|
||||||
use actors::memory::{MemoryActor, TimelineMemoryReply};
|
use actors::memory::{MemoryActor, TimelineMemoryReply};
|
||||||
use devtools_traits::DevtoolScriptControlMsg;
|
use devtools_traits::DevtoolScriptControlMsg;
|
||||||
use devtools_traits::DevtoolScriptControlMsg::{SetTimelineMarkers, DropTimelineMarkers};
|
use devtools_traits::DevtoolScriptControlMsg::{SetTimelineMarkers, DropTimelineMarkers};
|
||||||
use devtools_traits::{PreciseTime, TimelineMarker, TracingMetadata, TimelineMarkerType};
|
use devtools_traits::{PreciseTime, TimelineMarker, TimelineMarkerType};
|
||||||
use protocol::JsonPacketStream;
|
use protocol::JsonPacketStream;
|
||||||
use util::task;
|
use util::task;
|
||||||
|
|
||||||
|
@ -148,72 +147,15 @@ impl TimelineActor {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Select root(with depth 0) TimelineMarker pair (IntervalStart + IntervalEnd)
|
|
||||||
/// from queue and add marker to emitter
|
|
||||||
/// Return true if closed (IntervalStart + IntervalEnd) pair was founded
|
|
||||||
fn group(queue: &mut VecDeque<TimelineMarker>, depth: usize,
|
|
||||||
start_payload: Option<TimelineMarker>, emitter: &Emitter,
|
|
||||||
markers: &mut Vec<TimelineMarkerReply>) -> bool {
|
|
||||||
|
|
||||||
if let Some(start_payload) = start_payload {
|
|
||||||
if start_payload.metadata != TracingMetadata::IntervalStart {
|
|
||||||
panic!("Start payload doesn't have metadata IntervalStart");
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Some(end_payload) = queue.pop_front() {
|
|
||||||
match end_payload.metadata {
|
|
||||||
TracingMetadata::IntervalEnd => {
|
|
||||||
if depth == 0 {
|
|
||||||
// Emit TimelineMarkerReply, pair was found
|
|
||||||
markers.push(emitter.marker(start_payload, end_payload));
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
TracingMetadata::IntervalStart => {
|
|
||||||
if group(queue, depth + 1, Some(end_payload), emitter, markers) {
|
|
||||||
return group(queue, depth, Some(start_payload), emitter, markers);
|
|
||||||
} else {
|
|
||||||
queue.push_front(start_payload);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_ => panic!("Unknown tracingMetadata")
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
queue.push_front(start_payload);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
false
|
|
||||||
}
|
|
||||||
|
|
||||||
task::spawn_named("PullTimelineMarkers".to_string(), move || {
|
task::spawn_named("PullTimelineMarkers".to_string(), move || {
|
||||||
let mut queues = HashMap::new();
|
|
||||||
queues.insert("Reflow".to_string(), VecDeque::new());
|
|
||||||
queues.insert("DOMEvent".to_string(), VecDeque::new());
|
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
if !*is_recording.lock().unwrap() {
|
if !*is_recording.lock().unwrap() {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Creating queues by marker.name
|
|
||||||
loop {
|
|
||||||
match receiver.try_recv() {
|
|
||||||
Ok(marker) => {
|
|
||||||
if let Some(list) = queues.get_mut(&marker.name) {
|
|
||||||
list.push_back(marker);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Err(_) => break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Emit all markers
|
|
||||||
let mut markers = vec![];
|
let mut markers = vec![];
|
||||||
for (_, queue) in &mut queues {
|
while let Ok(marker) = receiver.try_recv() {
|
||||||
let start_payload = queue.pop_front();
|
markers.push(emitter.marker(marker));
|
||||||
group(queue, 0, start_payload, &emitter, &mut markers);
|
|
||||||
}
|
}
|
||||||
emitter.send(markers);
|
emitter.send(markers);
|
||||||
|
|
||||||
|
@ -336,14 +278,13 @@ impl Emitter {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn marker(&self, start_payload: TimelineMarker, end_payload: TimelineMarker)
|
fn marker(&self, payload: TimelineMarker) -> TimelineMarkerReply {
|
||||||
-> TimelineMarkerReply {
|
|
||||||
TimelineMarkerReply {
|
TimelineMarkerReply {
|
||||||
name: start_payload.name,
|
name: payload.name,
|
||||||
start: HighResolutionStamp::new(self.start_stamp, start_payload.time),
|
start: HighResolutionStamp::new(self.start_stamp, payload.start_time),
|
||||||
end: HighResolutionStamp::new(self.start_stamp, end_payload.time),
|
end: HighResolutionStamp::new(self.start_stamp, payload.end_time),
|
||||||
stack: start_payload.stack,
|
stack: payload.start_stack,
|
||||||
endStack: end_payload.stack,
|
endStack: payload.end_stack,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -124,21 +124,19 @@ pub struct NodeInfo {
|
||||||
pub incompleteValue: bool,
|
pub incompleteValue: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(PartialEq, Eq, Deserialize, Serialize)]
|
pub struct StartedTimelineMarker {
|
||||||
pub enum TracingMetadata {
|
name: String,
|
||||||
Default,
|
start_time: PreciseTime,
|
||||||
IntervalStart,
|
start_stack: Option<Vec<()>>,
|
||||||
IntervalEnd,
|
|
||||||
Event,
|
|
||||||
EventBacktrace,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Deserialize, Serialize)]
|
#[derive(Deserialize, Serialize)]
|
||||||
pub struct TimelineMarker {
|
pub struct TimelineMarker {
|
||||||
pub name: String,
|
pub name: String,
|
||||||
pub metadata: TracingMetadata,
|
pub start_time: PreciseTime,
|
||||||
pub time: PreciseTime,
|
pub start_stack: Option<Vec<()>>,
|
||||||
pub stack: Option<Vec<()>>,
|
pub end_time: PreciseTime,
|
||||||
|
pub end_stack: Option<Vec<()>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(PartialEq, Eq, Hash, Clone, Deserialize, Serialize)]
|
#[derive(PartialEq, Eq, Hash, Clone, Deserialize, Serialize)]
|
||||||
|
@ -270,12 +268,23 @@ pub enum NetworkEvent {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TimelineMarker {
|
impl TimelineMarker {
|
||||||
pub fn new(name: String, metadata: TracingMetadata) -> TimelineMarker {
|
pub fn start(name: String) -> StartedTimelineMarker {
|
||||||
TimelineMarker {
|
StartedTimelineMarker {
|
||||||
name: name,
|
name: name,
|
||||||
metadata: metadata,
|
start_time: PreciseTime::now(),
|
||||||
time: PreciseTime::now(),
|
start_stack: None,
|
||||||
stack: None,
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl StartedTimelineMarker {
|
||||||
|
pub fn end(self) -> TimelineMarker {
|
||||||
|
TimelineMarker {
|
||||||
|
name: self.name,
|
||||||
|
start_time: self.start_time,
|
||||||
|
start_stack: self.start_stack,
|
||||||
|
end_time: PreciseTime::now(),
|
||||||
|
end_stack: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,7 +40,6 @@ use timers::{IsInterval, TimerId, TimerManager, TimerCallback};
|
||||||
use webdriver_handlers::jsval_to_webdriver;
|
use webdriver_handlers::jsval_to_webdriver;
|
||||||
|
|
||||||
use devtools_traits::{ScriptToDevtoolsControlMsg, TimelineMarker, TimelineMarkerType};
|
use devtools_traits::{ScriptToDevtoolsControlMsg, TimelineMarker, TimelineMarkerType};
|
||||||
use devtools_traits::{TracingMetadata};
|
|
||||||
use msg::compositor_msg::ScriptToCompositorMsg;
|
use msg::compositor_msg::ScriptToCompositorMsg;
|
||||||
use msg::constellation_msg::{LoadData, PipelineId, SubpageId, ConstellationChan, WindowSizeData, WorkerId};
|
use msg::constellation_msg::{LoadData, PipelineId, SubpageId, ConstellationChan, WindowSizeData, WorkerId};
|
||||||
use msg::webdriver_msg::{WebDriverJSError, WebDriverJSResult};
|
use msg::webdriver_msg::{WebDriverJSError, WebDriverJSResult};
|
||||||
|
@ -681,10 +680,11 @@ impl Window {
|
||||||
|
|
||||||
debug!("script: performing reflow for goal {:?} reason {:?}", goal, reason);
|
debug!("script: performing reflow for goal {:?} reason {:?}", goal, reason);
|
||||||
|
|
||||||
if self.need_emit_timeline_marker(TimelineMarkerType::Reflow) {
|
let marker = if self.need_emit_timeline_marker(TimelineMarkerType::Reflow) {
|
||||||
let marker = TimelineMarker::new("Reflow".to_owned(), TracingMetadata::IntervalStart);
|
Some(TimelineMarker::start("Reflow".to_owned()))
|
||||||
self.emit_timeline_marker(marker);
|
} else {
|
||||||
}
|
None
|
||||||
|
};
|
||||||
|
|
||||||
// Layout will let us know when it's done.
|
// Layout will let us know when it's done.
|
||||||
let (join_chan, join_port) = channel();
|
let (join_chan, join_port) = channel();
|
||||||
|
@ -725,9 +725,8 @@ impl Window {
|
||||||
|
|
||||||
self.pending_reflow_count.set(0);
|
self.pending_reflow_count.set(0);
|
||||||
|
|
||||||
if self.need_emit_timeline_marker(TimelineMarkerType::Reflow) {
|
if let Some(marker) = marker {
|
||||||
let marker = TimelineMarker::new("Reflow".to_owned(), TracingMetadata::IntervalEnd);
|
self.emit_timeline_marker(marker.end());
|
||||||
self.emit_timeline_marker(marker);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -52,8 +52,8 @@ use timers::TimerId;
|
||||||
use webdriver_handlers;
|
use webdriver_handlers;
|
||||||
|
|
||||||
use devtools_traits::{DevtoolsPageInfo, DevtoolScriptControlMsg};
|
use devtools_traits::{DevtoolsPageInfo, DevtoolScriptControlMsg};
|
||||||
use devtools_traits::{ScriptToDevtoolsControlMsg, TimelineMarker, TimelineMarkerType};
|
use devtools_traits::{ScriptToDevtoolsControlMsg, TimelineMarker};
|
||||||
use devtools_traits::{TracingMetadata};
|
use devtools_traits::{StartedTimelineMarker, TimelineMarkerType};
|
||||||
use msg::compositor_msg::{LayerId, ScriptToCompositorMsg};
|
use msg::compositor_msg::{LayerId, ScriptToCompositorMsg};
|
||||||
use msg::constellation_msg::Msg as ConstellationMsg;
|
use msg::constellation_msg::Msg as ConstellationMsg;
|
||||||
use msg::constellation_msg::{ConstellationChan, FocusType};
|
use msg::constellation_msg::{ConstellationChan, FocusType};
|
||||||
|
@ -2016,23 +2016,22 @@ impl Drop for ScriptTask {
|
||||||
}
|
}
|
||||||
|
|
||||||
struct AutoDOMEventMarker<'a> {
|
struct AutoDOMEventMarker<'a> {
|
||||||
script_task: &'a ScriptTask
|
script_task: &'a ScriptTask,
|
||||||
|
marker: Option<StartedTimelineMarker>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> AutoDOMEventMarker<'a> {
|
impl<'a> AutoDOMEventMarker<'a> {
|
||||||
fn new(script_task: &'a ScriptTask) -> AutoDOMEventMarker<'a> {
|
fn new(script_task: &'a ScriptTask) -> AutoDOMEventMarker<'a> {
|
||||||
let marker = TimelineMarker::new("DOMEvent".to_owned(), TracingMetadata::IntervalStart);
|
|
||||||
script_task.emit_timeline_marker(marker);
|
|
||||||
AutoDOMEventMarker {
|
AutoDOMEventMarker {
|
||||||
script_task: script_task
|
script_task: script_task,
|
||||||
|
marker: Some(TimelineMarker::start("DOMEvent".to_owned())),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Drop for AutoDOMEventMarker<'a> {
|
impl<'a> Drop for AutoDOMEventMarker<'a> {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
let marker = TimelineMarker::new("DOMEvent".to_owned(), TracingMetadata::IntervalEnd);
|
self.script_task.emit_timeline_marker(self.marker.take().unwrap().end());
|
||||||
self.script_task.emit_timeline_marker(marker);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue