mirror of
https://github.com/servo/servo.git
synced 2025-08-02 20:20:14 +01:00
Auto merge of #11239 - jdm:time-profile, r=nox
Add timeline markers for HTTP requests, JS evaluation, and HTML parsing. Thank you for contributing to Servo! Please replace each `[ ]` by `[X]` when the step is complete, and replace `__` with appropriate data: - [ ] `./mach build -d` does not report any errors (didn't try to compile past a rustc upgrade on airplane wifi) - [X] `./mach test-tidy --faster` does not report any errors - [X] These changes fix #11218 (github issue number if applicable). Either: - [ ] There are tests for these changes OR - [X] These changes do not require tests because we don't have testing infrastructure for profiling. Pull requests that do not address these steps are welcome, but they will require additional verification as part of the review process. <!-- Reviewable:start --> --- This change is [<img src="https://reviewable.io/review_button.svg" height="35" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/11239) <!-- Reviewable:end -->
This commit is contained in:
commit
96a86bd952
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, PanicMsg, 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>>,
|
||||
|
@ -844,21 +850,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());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1262,6 +1284,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()
|
||||
}
|
||||
|
@ -1431,6 +1457,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>,
|
||||
|
@ -1468,6 +1495,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, PanicMsg, 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>,
|
||||
|
@ -73,6 +74,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>>,
|
||||
|
||||
|
@ -122,6 +125,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,
|
||||
|
@ -136,6 +140,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()
|
||||
}
|
||||
|
|
|
@ -1449,6 +1449,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