mirror of
https://github.com/servo/servo.git
synced 2025-08-02 20:20:14 +01:00
profile: Make the time and memory profilers run over IPC.
Uses the `Router` abstraction inside `ipc-channel` to avoid spawning new threads.
This commit is contained in:
parent
ed1b6a3513
commit
f10c076180
19 changed files with 212 additions and 168 deletions
|
@ -29,11 +29,13 @@ use msg::constellation_msg::PipelineId;
|
|||
use devtools_traits::DevtoolsControlChan;
|
||||
|
||||
use net_traits::{load_whole_resource, ResourceTask};
|
||||
use profile_traits::mem::{self, Reporter, ReportsChan};
|
||||
use profile_traits::mem::{self, Reporter, ReporterRequest};
|
||||
use util::task::spawn_named;
|
||||
use util::task_state;
|
||||
use util::task_state::{SCRIPT, IN_WORKER};
|
||||
|
||||
use ipc_channel::ipc;
|
||||
use ipc_channel::router::ROUTER;
|
||||
use js::jsapi::{JSContext, RootedValue, HandleValue};
|
||||
use js::jsapi::{JSAutoRequest, JSAutoCompartment};
|
||||
use js::jsval::UndefinedValue;
|
||||
|
@ -66,13 +68,6 @@ impl ScriptChan for SendableWorkerScriptChan {
|
|||
}
|
||||
}
|
||||
|
||||
impl Reporter for SendableWorkerScriptChan {
|
||||
// Just injects an appropriate event into the worker task's queue.
|
||||
fn collect_reports(&self, reports_chan: ReportsChan) -> bool {
|
||||
self.send(ScriptMsg::CollectReports(reports_chan)).is_ok()
|
||||
}
|
||||
}
|
||||
|
||||
/// Set the `worker` field of a related DedicatedWorkerGlobalScope object to a particular
|
||||
/// value for the duration of this object's lifetime. This ensures that the related Worker
|
||||
/// object only lives as long as necessary (ie. while events are being executed), while
|
||||
|
@ -182,6 +177,7 @@ impl DedicatedWorkerGlobalScope {
|
|||
|
||||
let runtime = Rc::new(ScriptTask::new_rt_and_cx());
|
||||
let serialized_url = url.serialize();
|
||||
let parent_sender_for_reporter = parent_sender.clone();
|
||||
let global = DedicatedWorkerGlobalScope::new(
|
||||
url, id, mem_profiler_chan.clone(), devtools_chan, runtime.clone(), resource_task,
|
||||
parent_sender, own_sender, receiver);
|
||||
|
@ -206,9 +202,16 @@ impl DedicatedWorkerGlobalScope {
|
|||
|
||||
// Register this task as a memory reporter. This needs to be done within the
|
||||
// scope of `_ar` otherwise script_chan_as_reporter() will panic.
|
||||
let reporter = global.script_chan_as_reporter();
|
||||
let msg = mem::ProfilerMsg::RegisterReporter(reporter_name.clone(), reporter);
|
||||
mem_profiler_chan.send(msg);
|
||||
let (reporter_sender, reporter_receiver) = ipc::channel().unwrap();
|
||||
ROUTER.add_route(reporter_receiver.to_opaque(), box move |reporter_request| {
|
||||
// Just injects an appropriate event into the worker task's queue.
|
||||
let reporter_request: ReporterRequest = reporter_request.to().unwrap();
|
||||
parent_sender_for_reporter.send(ScriptMsg::CollectReports(
|
||||
reporter_request.reports_channel)).unwrap()
|
||||
});
|
||||
mem_profiler_chan.send(mem::ProfilerMsg::RegisterReporter(
|
||||
reporter_name.clone(),
|
||||
Reporter(reporter_sender)));
|
||||
}
|
||||
|
||||
loop {
|
||||
|
@ -230,7 +233,6 @@ impl DedicatedWorkerGlobalScope {
|
|||
|
||||
pub trait DedicatedWorkerGlobalScopeHelpers {
|
||||
fn script_chan(self) -> Box<ScriptChan+Send>;
|
||||
fn script_chan_as_reporter(self) -> Box<Reporter+Send>;
|
||||
fn pipeline(self) -> PipelineId;
|
||||
fn new_script_pair(self) -> (Box<ScriptChan+Send>, Box<ScriptPort+Send>);
|
||||
fn process_event(self, msg: ScriptMsg);
|
||||
|
@ -244,14 +246,6 @@ impl<'a> DedicatedWorkerGlobalScopeHelpers for &'a DedicatedWorkerGlobalScope {
|
|||
}
|
||||
}
|
||||
|
||||
fn script_chan_as_reporter(self) -> Box<Reporter+Send> {
|
||||
box SendableWorkerScriptChan {
|
||||
sender: self.own_sender.clone(),
|
||||
worker: self.worker.borrow().as_ref().unwrap().clone(),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fn pipeline(self) -> PipelineId {
|
||||
self.id
|
||||
}
|
||||
|
|
|
@ -18,7 +18,7 @@ use msg::constellation_msg::{WindowSizeData};
|
|||
use msg::compositor_msg::Epoch;
|
||||
use net_traits::image_cache_task::ImageCacheTask;
|
||||
use net_traits::PendingAsyncLoad;
|
||||
use profile_traits::mem::{Reporter, ReportsChan};
|
||||
use profile_traits::mem::ReportsChan;
|
||||
use script_traits::{ConstellationControlMsg, LayoutControlMsg, ScriptControlChan};
|
||||
use script_traits::{OpaqueScriptLayoutChannel, StylesheetLoadResponder, UntrustedNodeAddress};
|
||||
use std::any::Any;
|
||||
|
@ -159,14 +159,6 @@ impl LayoutChan {
|
|||
}
|
||||
}
|
||||
|
||||
impl Reporter for LayoutChan {
|
||||
// Just injects an appropriate event into the layout task's queue.
|
||||
fn collect_reports(&self, reports_chan: ReportsChan) -> bool {
|
||||
let LayoutChan(ref c) = *self;
|
||||
c.send(Msg::CollectReports(reports_chan)).is_ok()
|
||||
}
|
||||
}
|
||||
|
||||
/// A trait to manage opaque references to script<->layout channels without needing
|
||||
/// to expose the message type to crates that don't need to know about them.
|
||||
pub trait ScriptLayoutChan {
|
||||
|
|
|
@ -70,7 +70,7 @@ use net_traits::{ResourceTask, LoadConsumer, ControlMsg, Metadata};
|
|||
use net_traits::LoadData as NetLoadData;
|
||||
use net_traits::image_cache_task::{ImageCacheChan, ImageCacheTask, ImageCacheResult};
|
||||
use net_traits::storage_task::StorageTask;
|
||||
use profile_traits::mem::{self, Report, Reporter, ReportsChan};
|
||||
use profile_traits::mem::{self, Report, Reporter, ReporterRequest, ReportsChan};
|
||||
use string_cache::Atom;
|
||||
use util::str::DOMString;
|
||||
use util::task::spawn_named_with_send_on_failure;
|
||||
|
@ -79,6 +79,8 @@ use util::task_state;
|
|||
use euclid::Rect;
|
||||
use euclid::point::Point2D;
|
||||
use hyper::header::{LastModified, Headers};
|
||||
use ipc_channel::ipc;
|
||||
use ipc_channel::router::ROUTER;
|
||||
use js::glue::CollectServoSizes;
|
||||
use js::jsapi::{JS_SetWrapObjectCallbacks, JS_AddExtraGCRootsTracer, DisableIncrementalGC};
|
||||
use js::jsapi::{JSContext, JSRuntime, JSTracer};
|
||||
|
@ -252,18 +254,6 @@ impl NonWorkerScriptChan {
|
|||
let (chan, port) = channel();
|
||||
(port, box NonWorkerScriptChan(chan))
|
||||
}
|
||||
|
||||
fn clone_as_reporter(&self) -> Box<Reporter+Send> {
|
||||
let NonWorkerScriptChan(ref chan) = *self;
|
||||
box NonWorkerScriptChan((*chan).clone())
|
||||
}
|
||||
}
|
||||
|
||||
impl Reporter for NonWorkerScriptChan {
|
||||
// Just injects an appropriate event into the script task's queue.
|
||||
fn collect_reports(&self, reports_chan: ReportsChan) -> bool {
|
||||
self.send(ScriptMsg::CollectReports(reports_chan)).is_ok()
|
||||
}
|
||||
}
|
||||
|
||||
pub struct StackRootTLS;
|
||||
|
@ -420,7 +410,7 @@ impl ScriptTaskFactory for ScriptTask {
|
|||
let roots = RootCollection::new();
|
||||
let _stack_roots_tls = StackRootTLS::new(&roots);
|
||||
let chan = NonWorkerScriptChan(script_chan);
|
||||
let reporter = chan.clone_as_reporter();
|
||||
let channel_for_reporter = chan.clone();
|
||||
let script_task = ScriptTask::new(compositor,
|
||||
script_port,
|
||||
chan,
|
||||
|
@ -445,6 +435,14 @@ impl ScriptTaskFactory for ScriptTask {
|
|||
|
||||
// Register this task as a memory reporter.
|
||||
let reporter_name = format!("script-reporter-{}", id.0);
|
||||
let (reporter_sender, reporter_receiver) = ipc::channel().unwrap();
|
||||
ROUTER.add_route(reporter_receiver.to_opaque(), box move |reporter_request| {
|
||||
// Just injects an appropriate event into the worker task's queue.
|
||||
let reporter_request: ReporterRequest = reporter_request.to().unwrap();
|
||||
channel_for_reporter.send(ScriptMsg::CollectReports(
|
||||
reporter_request.reports_channel)).unwrap()
|
||||
});
|
||||
let reporter = Reporter(reporter_sender);
|
||||
let msg = mem::ProfilerMsg::RegisterReporter(reporter_name.clone(), reporter);
|
||||
mem_profiler_chan.send(msg);
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue