diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs index cc29bad9cb532..dda4a2d2418d7 100644 --- a/src/librustc/session/config.rs +++ b/src/librustc/session/config.rs @@ -1369,6 +1369,8 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options, "inject the given attribute in the crate"), self_profile: bool = (false, parse_bool, [UNTRACKED], "run the self profiler"), + profile_json: bool = (false, parse_bool, [UNTRACKED], + "output a json file with profiler results"), } pub fn default_lib_output() -> CrateType { diff --git a/src/librustc/session/mod.rs b/src/librustc/session/mod.rs index a321728f74989..8bb9f0b92679c 100644 --- a/src/librustc/session/mod.rs +++ b/src/librustc/session/mod.rs @@ -839,6 +839,11 @@ impl Session { profiler.print_results(&self.opts); } + pub fn save_json_results(&self) { + let profiler = self.self_profiling.borrow(); + profiler.save_results(); + } + pub fn print_perf_stats(&self) { println!( "Total time spent computing symbol hashes: {}", diff --git a/src/librustc/util/profiling.rs b/src/librustc/util/profiling.rs index ef4e233260470..73604d2a4371a 100644 --- a/src/librustc/util/profiling.rs +++ b/src/librustc/util/profiling.rs @@ -10,6 +10,7 @@ use session::config::Options; +use std::fs; use std::io::{self, StdoutLock, Write}; use std::time::Instant; @@ -119,6 +120,46 @@ impl CategoryData { p!("Linking", linking); p!("Other", other); } + + fn json(&self) -> String { + format!("[ + {{ + \"category\": \"Parsing\", + \"time_ms\": {} + }}, + {{ + \"category\": \"Expansion\", + \"time_ms\": {} + }}, + {{ + \"category\": \"TypeChecking\", + \"time_ms\": {} + }}, + {{ + \"category\": \"BorrowChecking\", + \"time_ms\": {} + }}, + {{ + \"category\": \"Codegen\", + \"time_ms\": {} + }}, + {{ + \"category\": \"Linking\", + \"time_ms\": {} + }}, + {{ + \"category\": \"Other\", + \"time_ms\": {} + }} + ]", + self.times.parsing / 1_000_000, + self.times.expansion / 1_000_000, + self.times.type_checking / 1_000_000, + self.times.borrow_checking / 1_000_000, + self.times.codegen / 1_000_000, + self.times.linking / 1_000_000, + self.times.other / 1_000_000) + } } pub struct SelfProfiler { @@ -235,6 +276,10 @@ impl SelfProfiler { writeln!(lock, "Incremental: {}", incremental).unwrap(); } + pub fn save_results(&self) { + fs::write("self_profiler_results.json", self.data.json()).unwrap(); + } + pub fn record_activity<'a>(&'a mut self, category: ProfileCategory) -> ProfilerActivity<'a> { self.start_activity(category); diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs index d862741cda54f..f178f847aa51e 100644 --- a/src/librustc_driver/driver.rs +++ b/src/librustc_driver/driver.rs @@ -355,6 +355,10 @@ pub fn compile_input( if sess.opts.debugging_opts.self_profile { sess.print_profiler_results(); + + if sess.opts.debugging_opts.profile_json { + sess.save_json_results(); + } } controller_entry_point!(