Send the start and end half of a TimelineMarker to the devtools PullTimelineMarkers thread together.

This commit is contained in:
Ms2ger 2015-08-28 19:45:32 +02:00
parent 72125f070d
commit cf55d3191d
4 changed files with 47 additions and 99 deletions

View file

@ -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,
} }
} }

View file

@ -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,
} }
} }
} }

View file

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

View file

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