mirror of
https://github.com/servo/servo.git
synced 2025-06-06 16:45:39 +00: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 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,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue