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 rustc_serialize::{json, Encoder, Encodable};
use std::cell::RefCell;
use std::collections::{HashMap, VecDeque};
use std::net::TcpStream;
use std::sync::mpsc::channel;
use std::sync::{Arc, Mutex};
@ -17,7 +16,7 @@ use actors::framerate::FramerateActor;
use actors::memory::{MemoryActor, TimelineMemoryReply};
use devtools_traits::DevtoolScriptControlMsg;
use devtools_traits::DevtoolScriptControlMsg::{SetTimelineMarkers, DropTimelineMarkers};
use devtools_traits::{PreciseTime, TimelineMarker, TracingMetadata, TimelineMarkerType};
use devtools_traits::{PreciseTime, TimelineMarker, TimelineMarkerType};
use protocol::JsonPacketStream;
use util::task;
@ -148,72 +147,15 @@ impl TimelineActor {
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 || {
let mut queues = HashMap::new();
queues.insert("Reflow".to_string(), VecDeque::new());
queues.insert("DOMEvent".to_string(), VecDeque::new());
loop {
if !*is_recording.lock().unwrap() {
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![];
for (_, queue) in &mut queues {
let start_payload = queue.pop_front();
group(queue, 0, start_payload, &emitter, &mut markers);
while let Ok(marker) = receiver.try_recv() {
markers.push(emitter.marker(marker));
}
emitter.send(markers);
@ -336,14 +278,13 @@ impl Emitter {
}
}
fn marker(&self, start_payload: TimelineMarker, end_payload: TimelineMarker)
-> TimelineMarkerReply {
fn marker(&self, payload: TimelineMarker) -> TimelineMarkerReply {
TimelineMarkerReply {
name: start_payload.name,
start: HighResolutionStamp::new(self.start_stamp, start_payload.time),
end: HighResolutionStamp::new(self.start_stamp, end_payload.time),
stack: start_payload.stack,
endStack: end_payload.stack,
name: payload.name,
start: HighResolutionStamp::new(self.start_stamp, payload.start_time),
end: HighResolutionStamp::new(self.start_stamp, payload.end_time),
stack: payload.start_stack,
endStack: payload.end_stack,
}
}

View file

@ -124,21 +124,19 @@ pub struct NodeInfo {
pub incompleteValue: bool,
}
#[derive(PartialEq, Eq, Deserialize, Serialize)]
pub enum TracingMetadata {
Default,
IntervalStart,
IntervalEnd,
Event,
EventBacktrace,
pub struct StartedTimelineMarker {
name: String,
start_time: PreciseTime,
start_stack: Option<Vec<()>>,
}
#[derive(Deserialize, Serialize)]
pub struct TimelineMarker {
pub name: String,
pub metadata: TracingMetadata,
pub time: PreciseTime,
pub stack: Option<Vec<()>>,
pub start_time: PreciseTime,
pub start_stack: Option<Vec<()>>,
pub end_time: PreciseTime,
pub end_stack: Option<Vec<()>>,
}
#[derive(PartialEq, Eq, Hash, Clone, Deserialize, Serialize)]
@ -270,12 +268,23 @@ pub enum NetworkEvent {
}
impl TimelineMarker {
pub fn new(name: String, metadata: TracingMetadata) -> TimelineMarker {
TimelineMarker {
pub fn start(name: String) -> StartedTimelineMarker {
StartedTimelineMarker {
name: name,
metadata: metadata,
time: PreciseTime::now(),
stack: None,
start_time: PreciseTime::now(),
start_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 devtools_traits::{ScriptToDevtoolsControlMsg, TimelineMarker, TimelineMarkerType};
use devtools_traits::{TracingMetadata};
use msg::compositor_msg::ScriptToCompositorMsg;
use msg::constellation_msg::{LoadData, PipelineId, SubpageId, ConstellationChan, WindowSizeData, WorkerId};
use msg::webdriver_msg::{WebDriverJSError, WebDriverJSResult};
@ -681,10 +680,11 @@ impl Window {
debug!("script: performing reflow for goal {:?} reason {:?}", goal, reason);
if self.need_emit_timeline_marker(TimelineMarkerType::Reflow) {
let marker = TimelineMarker::new("Reflow".to_owned(), TracingMetadata::IntervalStart);
self.emit_timeline_marker(marker);
}
let marker = if self.need_emit_timeline_marker(TimelineMarkerType::Reflow) {
Some(TimelineMarker::start("Reflow".to_owned()))
} else {
None
};
// Layout will let us know when it's done.
let (join_chan, join_port) = channel();
@ -725,9 +725,8 @@ impl Window {
self.pending_reflow_count.set(0);
if self.need_emit_timeline_marker(TimelineMarkerType::Reflow) {
let marker = TimelineMarker::new("Reflow".to_owned(), TracingMetadata::IntervalEnd);
self.emit_timeline_marker(marker);
if let Some(marker) = marker {
self.emit_timeline_marker(marker.end());
}
}

View file

@ -52,8 +52,8 @@ use timers::TimerId;
use webdriver_handlers;
use devtools_traits::{DevtoolsPageInfo, DevtoolScriptControlMsg};
use devtools_traits::{ScriptToDevtoolsControlMsg, TimelineMarker, TimelineMarkerType};
use devtools_traits::{TracingMetadata};
use devtools_traits::{ScriptToDevtoolsControlMsg, TimelineMarker};
use devtools_traits::{StartedTimelineMarker, TimelineMarkerType};
use msg::compositor_msg::{LayerId, ScriptToCompositorMsg};
use msg::constellation_msg::Msg as ConstellationMsg;
use msg::constellation_msg::{ConstellationChan, FocusType};
@ -2016,23 +2016,22 @@ impl Drop for ScriptTask {
}
struct AutoDOMEventMarker<'a> {
script_task: &'a ScriptTask
script_task: &'a ScriptTask,
marker: Option<StartedTimelineMarker>,
}
impl<'a> 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 {
script_task: script_task
script_task: script_task,
marker: Some(TimelineMarker::start("DOMEvent".to_owned())),
}
}
}
impl<'a> Drop for AutoDOMEventMarker<'a> {
fn drop(&mut self) {
let marker = TimelineMarker::new("DOMEvent".to_owned(), TracingMetadata::IntervalEnd);
self.script_task.emit_timeline_marker(marker);
self.script_task.emit_timeline_marker(self.marker.take().unwrap().end());
}
}