diff options
author | bors-servo <lbergstrom+bors@mozilla.com> | 2019-03-26 16:36:19 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-03-26 16:36:19 -0400 |
commit | 2e0191b8394a318cd88e4660cf09fe6c8d88552b (patch) | |
tree | 4ee54d356017cc613a4db9d117dff94ab0e88477 /components/servo/lib.rs | |
parent | 7b8a898ac2ffef5ced8202dfd8bb40e37b972334 (diff) | |
parent | aee2974c330ed955958e90764f9a985c32fbc863 (diff) | |
download | servo-2e0191b8394a318cd88e4660cf09fe6c8d88552b.tar.gz servo-2e0191b8394a318cd88e4660cf09fe6c8d88552b.zip |
Auto merge of #23080 - jdm:sampling-profiler, r=gterzian
Add a sampling profiler
This uses the code already built for the background hang monitor and adds the ability to repeatedly sample all monitored threads. This sampling allows us to generate profiles that we can translate into the format used by https://perf-html.io/, allowing us to benefit from modern Gecko performance tooling.
You can run Servo with `PROFILE_OUTPUT=foo.json` and `SAMPLING_RATE=50` (for example), otherwise these values will default to `samples.json` and 10ms, respectively. To activate the profiler, press cmd+p, and to stop profiling, press cmd+p again. This will the captured samples to be symbolicated, which will take a very long time, and eventually there will be a new JSON profile in the output location.
To create a profile for use by Gecko's tools, run `python etc/profilicate.py path/to/profile.json >gecko_profile.json`, and load `gecko_profile.json` in the https://perf-html.io/ to see something like [this](https://profiler.firefox.com/public/8137e2b11fbb92afb80090bc534fd83015c87ee6/calltree/?globalTrackOrder=0-1&thread=1&v=3);
---
- [x] `./mach build -d` does not report any errors
- [x] `./mach test-tidy` does not report any errors
- [x] These changes fix #13103
- [x] These changes do not require tests because way too many pieces to automate
<!-- Reviewable:start -->
---
This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/23080)
<!-- Reviewable:end -->
Diffstat (limited to 'components/servo/lib.rs')
-rw-r--r-- | components/servo/lib.rs | 24 |
1 files changed, 17 insertions, 7 deletions
diff --git a/components/servo/lib.rs b/components/servo/lib.rs index 44eb62e51fc..71848f165a0 100644 --- a/components/servo/lib.rs +++ b/components/servo/lib.rs @@ -60,7 +60,6 @@ fn webdriver(port: u16, constellation: Sender<ConstellationMsg>) { #[cfg(not(feature = "webdriver"))] fn webdriver(_port: u16, _constellation: Sender<ConstellationMsg>) {} -use background_hang_monitor::HangMonitorRegister; use bluetooth::BluetoothThreadFactory; use bluetooth_traits::BluetoothRequest; use canvas::gl_context::GLContextFactory; @@ -133,6 +132,7 @@ pub struct Servo<Window: WindowMethods + 'static> { constellation_chan: Sender<ConstellationMsg>, embedder_receiver: EmbedderReceiver, embedder_events: Vec<(Option<BrowserId>, EmbedderMsg)>, + profiler_enabled: bool, } #[derive(Clone)] @@ -319,6 +319,7 @@ where constellation_chan: constellation_chan, embedder_receiver: embedder_receiver, embedder_events: Vec::new(), + profiler_enabled: false, } } @@ -407,6 +408,18 @@ where } }, + WindowEvent::ToggleSamplingProfiler(rate) => { + self.profiler_enabled = !self.profiler_enabled; + let msg = if self.profiler_enabled { + ConstellationMsg::EnableProfiler(rate) + } else { + ConstellationMsg::DisableProfiler + }; + if let Err(e) = self.constellation_chan.send(msg) { + warn!("Sending profiler toggle to constellation failed ({:?}).", e); + } + }, + WindowEvent::ToggleWebRenderDebug(option) => { self.compositor.toggle_webrender_debug(option); }, @@ -711,7 +724,7 @@ pub fn run_content_process(token: String) { .send(unprivileged_content_sender) .unwrap(); - let unprivileged_content = unprivileged_content_receiver.recv().unwrap(); + let mut unprivileged_content = unprivileged_content_receiver.recv().unwrap(); opts::set_options(unprivileged_content.opts()); prefs::pref_map() .set_all(unprivileged_content.prefs()) @@ -723,11 +736,8 @@ pub fn run_content_process(token: String) { create_sandbox(); } - let background_hang_monitor_register = HangMonitorRegister::init( - unprivileged_content - .background_hang_monitor_to_constellation_chan() - .clone(), - ); + let background_hang_monitor_register = + unprivileged_content.register_with_background_hang_monitor(); // send the required channels to the service worker manager let sw_senders = unprivileged_content.swmanager_senders(); |