зеркало из https://github.com/mozilla/gecko-dev.git
servo: Merge #13519 - profile: Integrate the time profiler with the macOS signpost infrastructure (from pcwalton:signpost); r=larsbergstrom
With this change, if you supply the `-Z signpost` flag, Instruments.app can display Servo events overlaid with callstack data. Even better, you can get call stack profiling for individual Servo events (one layout, one network request, one style recalculation, etc.) This adds a dependency on the `signpost` crate. On unsupported OS's, this crate is an no-op. Screenshot: http://i.imgur.com/agLyzOU.png r? @larsbergstrom Source-Repo: https://github.com/servo/servo Source-Revision: 7f84982de2fe8283d1df37d704842e037432087e
This commit is contained in:
Родитель
e880e27bef
Коммит
a2cdb30f64
|
@ -19,4 +19,7 @@ energy-monitor = {version = "0.2.0", optional = true}
|
|||
plugins = {path = "../plugins"}
|
||||
serde = "0.8"
|
||||
serde_macros = "0.8"
|
||||
signpost = {git = "https://github.com/pcwalton/signpost.git"}
|
||||
time = "0.1.12"
|
||||
util = {path = "../util"}
|
||||
|
||||
|
|
|
@ -14,6 +14,8 @@
|
|||
|
||||
extern crate ipc_channel;
|
||||
extern crate serde;
|
||||
extern crate signpost;
|
||||
extern crate util;
|
||||
|
||||
pub mod energy;
|
||||
pub mod mem;
|
||||
|
|
|
@ -7,6 +7,8 @@ extern crate time as std_time;
|
|||
use energy::read_energy_uj;
|
||||
use ipc_channel::ipc::IpcSender;
|
||||
use self::std_time::precise_time_ns;
|
||||
use signpost;
|
||||
use util::opts;
|
||||
|
||||
#[derive(PartialEq, Clone, PartialOrd, Eq, Ord, Debug, Deserialize, Serialize)]
|
||||
pub struct TimerMetadata {
|
||||
|
@ -37,51 +39,51 @@ pub enum ProfilerMsg {
|
|||
#[repr(u32)]
|
||||
#[derive(PartialEq, Clone, Copy, PartialOrd, Eq, Ord, Deserialize, Serialize, Debug, Hash)]
|
||||
pub enum ProfilerCategory {
|
||||
Compositing,
|
||||
LayoutPerform,
|
||||
LayoutStyleRecalc,
|
||||
LayoutTextShaping,
|
||||
LayoutRestyleDamagePropagation,
|
||||
LayoutNonIncrementalReset,
|
||||
LayoutSelectorMatch,
|
||||
LayoutTreeBuilder,
|
||||
LayoutDamagePropagate,
|
||||
LayoutGeneratedContent,
|
||||
LayoutDisplayListSorting,
|
||||
LayoutFloatPlacementSpeculation,
|
||||
LayoutMain,
|
||||
LayoutStoreOverflow,
|
||||
LayoutParallelWarmup,
|
||||
LayoutDispListBuild,
|
||||
NetHTTPRequestResponse,
|
||||
PaintingPerTile,
|
||||
PaintingPrepBuff,
|
||||
Painting,
|
||||
ImageDecoding,
|
||||
ImageSaving,
|
||||
ScriptAttachLayout,
|
||||
ScriptConstellationMsg,
|
||||
ScriptDevtoolsMsg,
|
||||
ScriptDocumentEvent,
|
||||
ScriptDomEvent,
|
||||
ScriptEvaluate,
|
||||
ScriptEvent,
|
||||
ScriptFileRead,
|
||||
ScriptImageCacheMsg,
|
||||
ScriptInputEvent,
|
||||
ScriptNetworkEvent,
|
||||
ScriptParseHTML,
|
||||
ScriptPlannedNavigation,
|
||||
ScriptResize,
|
||||
ScriptSetScrollState,
|
||||
ScriptSetViewport,
|
||||
ScriptTimerEvent,
|
||||
ScriptStylesheetLoad,
|
||||
ScriptUpdateReplacedElement,
|
||||
ScriptWebSocketEvent,
|
||||
ScriptWorkerEvent,
|
||||
ScriptServiceWorkerEvent,
|
||||
ApplicationHeartbeat,
|
||||
Compositing = 0x00,
|
||||
LayoutPerform = 0x10,
|
||||
LayoutStyleRecalc = 0x11,
|
||||
LayoutTextShaping = 0x12,
|
||||
LayoutRestyleDamagePropagation = 0x13,
|
||||
LayoutNonIncrementalReset = 0x14,
|
||||
LayoutSelectorMatch = 0x15,
|
||||
LayoutTreeBuilder = 0x16,
|
||||
LayoutDamagePropagate = 0x17,
|
||||
LayoutGeneratedContent = 0x18,
|
||||
LayoutDisplayListSorting = 0x19,
|
||||
LayoutFloatPlacementSpeculation = 0x1a,
|
||||
LayoutMain = 0x1b,
|
||||
LayoutStoreOverflow = 0x1c,
|
||||
LayoutParallelWarmup = 0x1d,
|
||||
LayoutDispListBuild = 0x1e,
|
||||
NetHTTPRequestResponse = 0x30,
|
||||
PaintingPerTile = 0x41,
|
||||
PaintingPrepBuff = 0x42,
|
||||
Painting = 0x43,
|
||||
ImageDecoding = 0x50,
|
||||
ImageSaving = 0x51,
|
||||
ScriptAttachLayout = 0x60,
|
||||
ScriptConstellationMsg = 0x61,
|
||||
ScriptDevtoolsMsg = 0x62,
|
||||
ScriptDocumentEvent = 0x63,
|
||||
ScriptDomEvent = 0x64,
|
||||
ScriptEvaluate = 0x65,
|
||||
ScriptEvent = 0x66,
|
||||
ScriptFileRead = 0x67,
|
||||
ScriptImageCacheMsg = 0x68,
|
||||
ScriptInputEvent = 0x69,
|
||||
ScriptNetworkEvent = 0x6a,
|
||||
ScriptParseHTML = 0x6b,
|
||||
ScriptPlannedNavigation = 0x6c,
|
||||
ScriptResize = 0x6d,
|
||||
ScriptSetScrollState = 0x6e,
|
||||
ScriptSetViewport = 0x6f,
|
||||
ScriptTimerEvent = 0x70,
|
||||
ScriptStylesheetLoad = 0x71,
|
||||
ScriptUpdateReplacedElement = 0x72,
|
||||
ScriptWebSocketEvent = 0x73,
|
||||
ScriptWorkerEvent = 0x74,
|
||||
ScriptServiceWorkerEvent = 0x75,
|
||||
ApplicationHeartbeat = 0x90,
|
||||
}
|
||||
|
||||
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Deserialize, Serialize)]
|
||||
|
@ -103,11 +105,20 @@ pub fn profile<T, F>(category: ProfilerCategory,
|
|||
-> T
|
||||
where F: FnOnce() -> T
|
||||
{
|
||||
if opts::get().signpost {
|
||||
signpost::start(category as u32, &[0, 0, 0, (category as usize) >> 4]);
|
||||
}
|
||||
let start_energy = read_energy_uj();
|
||||
let start_time = precise_time_ns();
|
||||
|
||||
let val = callback();
|
||||
|
||||
let end_time = precise_time_ns();
|
||||
let end_energy = read_energy_uj();
|
||||
if opts::get().signpost {
|
||||
signpost::end(category as u32, &[0, 0, 0, (category as usize) >> 4]);
|
||||
}
|
||||
|
||||
send_profile_data(category,
|
||||
meta,
|
||||
profiler_chan,
|
||||
|
|
|
@ -1846,7 +1846,9 @@ dependencies = [
|
|||
"plugins 0.0.1",
|
||||
"serde 0.8.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_macros 0.8.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"signpost 0.1.0 (git+https://github.com/pcwalton/signpost.git)",
|
||||
"time 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"util 0.0.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -2250,6 +2252,11 @@ name = "sig"
|
|||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "signpost"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/pcwalton/signpost.git#636f31b996ebec3f9d98e4d3973423a5d779666e"
|
||||
|
||||
[[package]]
|
||||
name = "simd"
|
||||
version = "0.1.1"
|
||||
|
@ -2967,6 +2974,7 @@ dependencies = [
|
|||
"checksum shared_library 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "fb04126b6fcfd2710fb5b6d18f4207b6c535f2850a7e1a43bcd526d44f30a79a"
|
||||
"checksum shell32-sys 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "72f20b8f3c060374edb8046591ba28f62448c369ccbdc7b02075103fb3a9e38d"
|
||||
"checksum sig 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c6649e43c1a1e68d29ed56d0dc3b5b6cf3b901da77cf107c4066b9e3da036df5"
|
||||
"checksum signpost 0.1.0 (git+https://github.com/pcwalton/signpost.git)" = "<none>"
|
||||
"checksum simd 0.1.1 (git+https://github.com/huonw/simd)" = "<none>"
|
||||
"checksum smallvec 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "fcc8d19212aacecf95e4a7a2179b26f7aeb9732a915cf01f05b0d3e044865410"
|
||||
"checksum solicit 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "172382bac9424588d7840732b250faeeef88942e37b6e35317dce98cafdd75b2"
|
||||
|
|
|
@ -217,6 +217,10 @@ pub struct Opts {
|
|||
// don't skip any backtraces on panic
|
||||
pub full_backtraces: bool,
|
||||
|
||||
/// True to use OS native signposting facilities. This makes profiling events (script activity,
|
||||
/// reflow, compositing, etc.) appear in Instruments.app on macOS.
|
||||
pub signpost: bool,
|
||||
|
||||
/// Print the version and exit.
|
||||
pub is_printing_version: bool,
|
||||
}
|
||||
|
@ -322,6 +326,10 @@ pub struct DebugOptions {
|
|||
/// useful when modifying the shaders, to ensure they all compile
|
||||
/// after each change is made.
|
||||
pub precache_shaders: bool,
|
||||
|
||||
/// True to use OS native signposting facilities. This makes profiling events (script activity,
|
||||
/// reflow, compositing, etc.) appear in Instruments.app on macOS.
|
||||
pub signpost: bool,
|
||||
}
|
||||
|
||||
|
||||
|
@ -361,6 +369,7 @@ impl DebugOptions {
|
|||
"msaa" => debug_options.use_msaa = true,
|
||||
"full-backtraces" => debug_options.full_backtraces = true,
|
||||
"precache-shaders" => debug_options.precache_shaders = true,
|
||||
"signpost" => debug_options.signpost = true,
|
||||
"" => {},
|
||||
_ => return Err(option)
|
||||
};
|
||||
|
@ -411,6 +420,7 @@ pub fn print_debug_usage(app: &str) -> ! {
|
|||
print_option("full-backtraces", "Print full backtraces for all errors");
|
||||
print_option("wr-debug", "Display webrender tile borders. Must be used with -w option.");
|
||||
print_option("precache-shaders", "Compile all shaders during init. Must be used with -w option.");
|
||||
print_option("signpost", "Emit native OS signposts for profile events (currently macOS only)");
|
||||
|
||||
println!("");
|
||||
|
||||
|
@ -549,6 +559,7 @@ pub fn default_opts() -> Opts {
|
|||
is_printing_version: false,
|
||||
webrender_debug: false,
|
||||
precache_shaders: false,
|
||||
signpost: false,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -860,6 +871,7 @@ pub fn from_cmdline_args(args: &[String]) -> ArgumentParsingResult {
|
|||
is_printing_version: is_printing_version,
|
||||
webrender_debug: debug_options.webrender_debug,
|
||||
precache_shaders: debug_options.precache_shaders,
|
||||
signpost: debug_options.signpost,
|
||||
};
|
||||
|
||||
set_defaults(opts);
|
||||
|
|
|
@ -0,0 +1,108 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
# Copyright 2013 The Servo Project Developers. See the COPYRIGHT
|
||||
# file at the top-level directory of this distribution.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
# http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
# <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
# option. This file may not be copied, modified, or distributed
|
||||
# except according to those terms.
|
||||
|
||||
import re
|
||||
import subprocess
|
||||
import sys
|
||||
from xml.etree import ElementTree
|
||||
from xml.etree.ElementTree import Element
|
||||
|
||||
if len(sys.argv) < 3:
|
||||
sys.stderr.write("""usage: patch-trace-template.py components/profile_traits/time.rs path/to/my.tracetemplate
|
||||
|
||||
`time.rs` is usually located in `components/profile_traits/time.rs`.
|
||||
Trace templates are typically located in `~/Library/Application Support/Instruments/Templates`.
|
||||
The supplied trace template must contain the "Points of Interest" instrument.
|
||||
Output is written to standard output and should typically be piped to a new `.tracetemplate` file.
|
||||
|
||||
Example:
|
||||
patch-trace-template.py \\
|
||||
components/profile_traits/time.rs \\
|
||||
~/Library/Application\\ Support/Instruments/Templates/MyTemplate.tracetemplate > \\
|
||||
~/Library/Application\\ Support/Instruments/Templates/MyServoTemplate.tracetemplate
|
||||
""")
|
||||
sys.exit(0)
|
||||
|
||||
rust_source = open(sys.argv[1], 'r')
|
||||
lines = iter(rust_source)
|
||||
for line in lines:
|
||||
if line.lstrip().startswith("pub enum ProfilerCategory"):
|
||||
break
|
||||
|
||||
code_pairs = []
|
||||
regex = re.compile(r"\s*(\w+)\s*=\s*([0-9]+|0x[a-fA-F0-9]+),?\s*$")
|
||||
for line in lines:
|
||||
if line.lstrip().startswith("}"):
|
||||
break
|
||||
|
||||
match = regex.match(line)
|
||||
if match is None:
|
||||
continue
|
||||
code_pairs.append((match.group(2), match.group(1)))
|
||||
|
||||
xml = subprocess.check_output(["plutil", "-convert", "xml1", "-o", "-", sys.argv[2]])
|
||||
plist = ElementTree.ElementTree(ElementTree.fromstring(xml))
|
||||
|
||||
elems = iter(plist.findall("./dict/*"))
|
||||
for elem in elems:
|
||||
if elem.tag != 'key' or elem.text != '$objects':
|
||||
continue
|
||||
array = elems.next()
|
||||
break
|
||||
|
||||
elems = iter(array.findall("./*"))
|
||||
for elem in elems:
|
||||
if elem.tag != 'string' or elem.text != 'kdebugIntervalRule':
|
||||
continue
|
||||
dictionary = elems.next()
|
||||
break
|
||||
|
||||
elems = iter(dictionary.findall("./*"))
|
||||
for elem in elems:
|
||||
if elem.tag != 'key' or elem.text != 'NS.objects':
|
||||
continue
|
||||
objects_array = elems.next()
|
||||
break
|
||||
|
||||
child_count = sum(1 for _ in iter(array.findall("./*")))
|
||||
|
||||
for code_pair in code_pairs:
|
||||
number_index = child_count
|
||||
integer = Element('integer')
|
||||
integer.text = str(int(code_pair[0], 0))
|
||||
array.append(integer)
|
||||
child_count += 1
|
||||
|
||||
string_index = child_count
|
||||
string = Element('string')
|
||||
string.text = code_pair[1]
|
||||
array.append(string)
|
||||
child_count += 1
|
||||
|
||||
dictionary = Element('dict')
|
||||
key = Element('key')
|
||||
key.text = "CF$UID"
|
||||
dictionary.append(key)
|
||||
integer = Element('integer')
|
||||
integer.text = str(number_index)
|
||||
dictionary.append(integer)
|
||||
objects_array.append(dictionary)
|
||||
|
||||
dictionary = Element('dict')
|
||||
key = Element('key')
|
||||
key.text = "CF$UID"
|
||||
dictionary.append(key)
|
||||
integer = Element('integer')
|
||||
integer.text = str(string_index)
|
||||
dictionary.append(integer)
|
||||
objects_array.append(dictionary)
|
||||
|
||||
plist.write(sys.stdout, encoding='utf-8', xml_declaration=True)
|
|
@ -1697,7 +1697,9 @@ dependencies = [
|
|||
"plugins 0.0.1",
|
||||
"serde 0.8.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_macros 0.8.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"signpost 0.1.0 (git+https://github.com/pcwalton/signpost.git)",
|
||||
"time 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"util 0.0.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -2133,6 +2135,11 @@ name = "sig"
|
|||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "signpost"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/pcwalton/signpost.git#81803b4d09af51a3a1133a62ef8dbb3cf0595de9"
|
||||
|
||||
[[package]]
|
||||
name = "simd"
|
||||
version = "0.1.1"
|
||||
|
@ -2821,6 +2828,7 @@ dependencies = [
|
|||
"checksum shared_library 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "fb04126b6fcfd2710fb5b6d18f4207b6c535f2850a7e1a43bcd526d44f30a79a"
|
||||
"checksum shell32-sys 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "72f20b8f3c060374edb8046591ba28f62448c369ccbdc7b02075103fb3a9e38d"
|
||||
"checksum sig 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c6649e43c1a1e68d29ed56d0dc3b5b6cf3b901da77cf107c4066b9e3da036df5"
|
||||
"checksum signpost 0.1.0 (git+https://github.com/pcwalton/signpost.git)" = "<none>"
|
||||
"checksum simd 0.1.1 (git+https://github.com/huonw/simd)" = "<none>"
|
||||
"checksum smallvec 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "fcc8d19212aacecf95e4a7a2179b26f7aeb9732a915cf01f05b0d3e044865410"
|
||||
"checksum solicit 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "172382bac9424588d7840732b250faeeef88942e37b6e35317dce98cafdd75b2"
|
||||
|
|
Загрузка…
Ссылка в новой задаче