mirror of
https://github.com/servo/servo.git
synced 2025-08-06 06:00:15 +01:00
Add timeline markers for HTTP requests, JS evaluation, and HTML parsing.
This commit is contained in:
parent
36df00ae96
commit
9e8cf19e51
19 changed files with 126 additions and 30 deletions
|
@ -20,7 +20,7 @@ use js::jsapi::{JSContext, JSObject, JS_GetClass, MutableHandleValue};
|
|||
use js::{JSCLASS_IS_DOMJSCLASS, JSCLASS_IS_GLOBAL};
|
||||
use msg::constellation_msg::{ConstellationChan, PipelineId};
|
||||
use net_traits::ResourceThread;
|
||||
use profile_traits::mem;
|
||||
use profile_traits::{mem, time};
|
||||
use script_runtime::{CommonScriptMsg, ScriptChan, ScriptPort};
|
||||
use script_thread::{MainThreadScriptChan, ScriptThread};
|
||||
use script_traits::{MsDuration, ScriptMsg as ConstellationMsg, TimerEventRequest};
|
||||
|
@ -81,6 +81,14 @@ impl<'a> GlobalRef<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
/// Get a `time::ProfilerChan` to send messages to the time profiler thread.
|
||||
pub fn time_profiler_chan(&self) -> &time::ProfilerChan {
|
||||
match *self {
|
||||
GlobalRef::Window(window) => window.time_profiler_chan(),
|
||||
GlobalRef::Worker(worker) => worker.time_profiler_chan(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Get a `ConstellationChan` to send messages to the constellation channel when available.
|
||||
pub fn constellation_chan(&self) -> &ConstellationChan<ConstellationMsg> {
|
||||
match *self {
|
||||
|
|
|
@ -28,6 +28,8 @@ use msg::constellation_msg::{PipelineId, SubpageId};
|
|||
use net_traits::{AsyncResponseListener, Metadata, NetworkError};
|
||||
use network_listener::PreInvoke;
|
||||
use parse::{TrustedParser, ParserRef, Parser};
|
||||
use profile_traits::time::ProfilerCategory;
|
||||
use profile_traits::time::{profile, TimerMetadata, TimerMetadataReflowType, TimerMetadataFrameType};
|
||||
use script_thread::ScriptThread;
|
||||
use std::cell::Cell;
|
||||
use std::default::Default;
|
||||
|
@ -315,6 +317,18 @@ impl ServoHTMLParser {
|
|||
|
||||
impl ServoHTMLParser {
|
||||
pub fn parse_sync(&self) {
|
||||
let metadata = TimerMetadata {
|
||||
url: self.document.url().as_str().into(),
|
||||
iframe: TimerMetadataFrameType::RootWindow,
|
||||
incremental: TimerMetadataReflowType::FirstReflow,
|
||||
};
|
||||
profile(ProfilerCategory::ScriptParseHTML,
|
||||
Some(metadata),
|
||||
self.document.window().time_profiler_chan().clone(),
|
||||
|| self.do_parse_sync())
|
||||
}
|
||||
|
||||
fn do_parse_sync(&self) {
|
||||
// This parser will continue to parse while there is either pending input or
|
||||
// the parser remains unsuspended.
|
||||
loop {
|
||||
|
|
|
@ -51,6 +51,8 @@ use net_traits::image_cache_thread::{ImageCacheChan, ImageCacheThread};
|
|||
use net_traits::storage_thread::{StorageThread, StorageType};
|
||||
use num_traits::ToPrimitive;
|
||||
use profile_traits::mem;
|
||||
use profile_traits::time::{ProfilerCategory, TimerMetadata, TimerMetadataFrameType};
|
||||
use profile_traits::time::{ProfilerChan, TimerMetadataReflowType, profile};
|
||||
use reporter::CSSErrorReporter;
|
||||
use rustc_serialize::base64::{FromBase64, STANDARD, ToBase64};
|
||||
use script_runtime::{ScriptChan, ScriptPort};
|
||||
|
@ -165,6 +167,10 @@ pub struct Window {
|
|||
#[ignore_heap_size_of = "channels are hard"]
|
||||
mem_profiler_chan: mem::ProfilerChan,
|
||||
|
||||
/// For sending messages to the memory profiler.
|
||||
#[ignore_heap_size_of = "channels are hard"]
|
||||
time_profiler_chan: ProfilerChan,
|
||||
|
||||
/// For providing instructions to an optional devtools server.
|
||||
#[ignore_heap_size_of = "channels are hard"]
|
||||
devtools_chan: Option<IpcSender<ScriptToDevtoolsControlMsg>>,
|
||||
|
@ -841,21 +847,37 @@ impl<'a, T: Reflectable> ScriptHelpers for &'a T {
|
|||
fn evaluate_script_on_global_with_result(self, code: &str, filename: &str,
|
||||
rval: MutableHandleValue) {
|
||||
let global = self.global();
|
||||
let cx = global.r().get_cx();
|
||||
let globalhandle = global.r().reflector().get_jsobject();
|
||||
let code: Vec<u16> = code.encode_utf16().collect();
|
||||
let filename = CString::new(filename).unwrap();
|
||||
let metadata = TimerMetadata {
|
||||
url: if filename.is_empty() {
|
||||
global.r().get_url().as_str().into()
|
||||
} else {
|
||||
filename.into()
|
||||
},
|
||||
iframe: TimerMetadataFrameType::RootWindow,
|
||||
incremental: TimerMetadataReflowType::FirstReflow,
|
||||
};
|
||||
profile(
|
||||
ProfilerCategory::ScriptEvaluate,
|
||||
Some(metadata),
|
||||
global.r().time_profiler_chan().clone(),
|
||||
|| {
|
||||
let cx = global.r().get_cx();
|
||||
let globalhandle = global.r().reflector().get_jsobject();
|
||||
let code: Vec<u16> = code.encode_utf16().collect();
|
||||
let filename = CString::new(filename).unwrap();
|
||||
|
||||
let _ac = JSAutoCompartment::new(cx, globalhandle.get());
|
||||
let options = CompileOptionsWrapper::new(cx, filename.as_ptr(), 0);
|
||||
unsafe {
|
||||
if !Evaluate2(cx, options.ptr, code.as_ptr(),
|
||||
code.len() as libc::size_t,
|
||||
rval) {
|
||||
debug!("error evaluating JS string");
|
||||
report_pending_exception(cx, globalhandle.get());
|
||||
let _ac = JSAutoCompartment::new(cx, globalhandle.get());
|
||||
let options = CompileOptionsWrapper::new(cx, filename.as_ptr(), 0);
|
||||
unsafe {
|
||||
if !Evaluate2(cx, options.ptr, code.as_ptr(),
|
||||
code.len() as libc::size_t,
|
||||
rval) {
|
||||
debug!("error evaluating JS string");
|
||||
report_pending_exception(cx, globalhandle.get());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1259,6 +1281,10 @@ impl Window {
|
|||
&self.mem_profiler_chan
|
||||
}
|
||||
|
||||
pub fn time_profiler_chan(&self) -> &ProfilerChan {
|
||||
&self.time_profiler_chan
|
||||
}
|
||||
|
||||
pub fn devtools_chan(&self) -> Option<IpcSender<ScriptToDevtoolsControlMsg>> {
|
||||
self.devtools_chan.clone()
|
||||
}
|
||||
|
@ -1424,6 +1450,7 @@ impl Window {
|
|||
bluetooth_thread: IpcSender<BluetoothMethodMsg>,
|
||||
storage_thread: StorageThread,
|
||||
mem_profiler_chan: mem::ProfilerChan,
|
||||
time_profiler_chan: ProfilerChan,
|
||||
devtools_chan: Option<IpcSender<ScriptToDevtoolsControlMsg>>,
|
||||
constellation_chan: ConstellationChan<ConstellationMsg>,
|
||||
control_chan: IpcSender<ConstellationControlMsg>,
|
||||
|
@ -1460,6 +1487,7 @@ impl Window {
|
|||
navigator: Default::default(),
|
||||
image_cache_thread: image_cache_thread,
|
||||
mem_profiler_chan: mem_profiler_chan,
|
||||
time_profiler_chan: time_profiler_chan,
|
||||
devtools_chan: devtools_chan,
|
||||
browsing_context: Default::default(),
|
||||
performance: Default::default(),
|
||||
|
|
|
@ -102,6 +102,7 @@ impl Worker {
|
|||
let init = WorkerGlobalScopeInit {
|
||||
resource_thread: resource_thread,
|
||||
mem_profiler_chan: global.mem_profiler_chan().clone(),
|
||||
time_profiler_chan: global.time_profiler_chan().clone(),
|
||||
to_devtools_sender: global.devtools_chan(),
|
||||
from_devtools_sender: optional_sender,
|
||||
constellation_chan: constellation_chan,
|
||||
|
|
|
@ -23,7 +23,7 @@ use js::jsval::UndefinedValue;
|
|||
use js::rust::Runtime;
|
||||
use msg::constellation_msg::{ConstellationChan, PipelineId};
|
||||
use net_traits::{LoadContext, ResourceThread, load_whole_resource};
|
||||
use profile_traits::mem;
|
||||
use profile_traits::{mem, time};
|
||||
use script_runtime::{CommonScriptMsg, ScriptChan, ScriptPort};
|
||||
use script_traits::ScriptMsg as ConstellationMsg;
|
||||
use script_traits::{MsDuration, TimerEvent, TimerEventId, TimerEventRequest, TimerSource};
|
||||
|
@ -45,6 +45,7 @@ pub enum WorkerGlobalScopeTypeId {
|
|||
pub struct WorkerGlobalScopeInit {
|
||||
pub resource_thread: ResourceThread,
|
||||
pub mem_profiler_chan: mem::ProfilerChan,
|
||||
pub time_profiler_chan: time::ProfilerChan,
|
||||
pub to_devtools_sender: Option<IpcSender<ScriptToDevtoolsControlMsg>>,
|
||||
pub from_devtools_sender: Option<IpcSender<DevtoolScriptControlMsg>>,
|
||||
pub constellation_chan: ConstellationChan<ConstellationMsg>,
|
||||
|
@ -72,6 +73,8 @@ pub struct WorkerGlobalScope {
|
|||
timers: OneshotTimers,
|
||||
#[ignore_heap_size_of = "Defined in std"]
|
||||
mem_profiler_chan: mem::ProfilerChan,
|
||||
#[ignore_heap_size_of = "Defined in std"]
|
||||
time_profiler_chan: time::ProfilerChan,
|
||||
#[ignore_heap_size_of = "Defined in ipc-channel"]
|
||||
to_devtools_sender: Option<IpcSender<ScriptToDevtoolsControlMsg>>,
|
||||
|
||||
|
@ -118,6 +121,7 @@ impl WorkerGlobalScope {
|
|||
crypto: Default::default(),
|
||||
timers: OneshotTimers::new(timer_event_chan, init.scheduler_chan.clone()),
|
||||
mem_profiler_chan: init.mem_profiler_chan,
|
||||
time_profiler_chan: init.time_profiler_chan,
|
||||
to_devtools_sender: init.to_devtools_sender,
|
||||
from_devtools_sender: init.from_devtools_sender,
|
||||
from_devtools_receiver: from_devtools_receiver,
|
||||
|
@ -131,6 +135,10 @@ impl WorkerGlobalScope {
|
|||
&self.mem_profiler_chan
|
||||
}
|
||||
|
||||
pub fn time_profiler_chan(&self) -> &time::ProfilerChan {
|
||||
&self.time_profiler_chan
|
||||
}
|
||||
|
||||
pub fn devtools_chan(&self) -> Option<IpcSender<ScriptToDevtoolsControlMsg>> {
|
||||
self.to_devtools_sender.clone()
|
||||
}
|
||||
|
|
|
@ -1446,6 +1446,7 @@ impl ScriptThread {
|
|||
self.bluetooth_thread.clone(),
|
||||
self.storage_thread.clone(),
|
||||
self.mem_profiler_chan.clone(),
|
||||
self.time_profiler_chan.clone(),
|
||||
self.devtools_chan.clone(),
|
||||
self.constellation_chan.clone(),
|
||||
self.control_chan.clone(),
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue