Wrap the self-profiler in an `Arc<Mutex<>>`

This will allow us to send it across threads and measure things like
LLVM time.
This commit is contained in:
Wesley Wiser 2019-02-10 17:23:00 -05:00
parent c0086b9e89
commit 25b8c614f0
7 changed files with 60 additions and 32 deletions

View File

@ -2625,6 +2625,7 @@ dependencies = [
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
"memmap 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
"num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
"parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc 0.0.0",
"rustc-demangle 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc_allocator 0.0.0",

View File

@ -44,7 +44,9 @@ use std::fmt;
use std::io::Write;
use std::path::PathBuf;
use std::time::Duration;
use std::sync::mpsc;
use std::sync::{Arc, mpsc};
use parking_lot::Mutex as PlMutex;
mod code_stats;
pub mod config;
@ -127,11 +129,8 @@ pub struct Session {
/// Used by `-Z profile-queries` in `util::common`.
pub profile_channel: Lock<Option<mpsc::Sender<ProfileQueriesMsg>>>,
/// Used by `-Z self-profile`.
pub self_profiling_active: bool,
/// Used by `-Z self-profile`.
pub self_profiling: Lock<SelfProfiler>,
/// Used by -Z self-profile
pub self_profiling: Option<Arc<PlMutex<SelfProfiler>>>,
/// Some measurements that are being gathered during compilation.
pub perf_stats: PerfStats,
@ -834,27 +833,23 @@ impl Session {
#[inline(never)]
#[cold]
fn profiler_active<F: FnOnce(&mut SelfProfiler) -> ()>(&self, f: F) {
let mut profiler = self.self_profiling.borrow_mut();
f(&mut profiler);
match &self.self_profiling {
None => bug!("profiler_active() called but there was no profiler active"),
Some(profiler) => {
let mut p = profiler.lock();
f(&mut p);
}
}
}
#[inline(always)]
pub fn profiler<F: FnOnce(&mut SelfProfiler) -> ()>(&self, f: F) {
if unlikely!(self.self_profiling_active) {
if unlikely!(self.self_profiling.is_some()) {
self.profiler_active(f)
}
}
pub fn print_profiler_results(&self) {
let mut profiler = self.self_profiling.borrow_mut();
profiler.print_results(&self.opts);
}
pub fn save_json_results(&self) {
let profiler = self.self_profiling.borrow();
profiler.save_results(&self.opts);
}
pub fn print_perf_stats(&self) {
println!(
"Total time spent computing symbol hashes: {}",
@ -1136,6 +1131,13 @@ pub fn build_session_(
source_map: Lrc<source_map::SourceMap>,
driver_lint_caps: FxHashMap<lint::LintId, lint::Level>,
) -> Session {
let self_profiling_active = sopts.debugging_opts.self_profile ||
sopts.debugging_opts.profile_json;
let self_profiler =
if self_profiling_active { Some(Arc::new(PlMutex::new(SelfProfiler::new()))) }
else { None };
let host_triple = TargetTriple::from_triple(config::host_triple());
let host = Target::search(&host_triple).unwrap_or_else(|e|
span_diagnostic
@ -1185,9 +1187,6 @@ pub fn build_session_(
CguReuseTracker::new_disabled()
};
let self_profiling_active = sopts.debugging_opts.self_profile ||
sopts.debugging_opts.profile_json;
let sess = Session {
target: target_cfg,
host,
@ -1216,8 +1215,7 @@ pub fn build_session_(
imported_macro_spans: OneThread::new(RefCell::new(FxHashMap::default())),
incr_comp_session: OneThread::new(RefCell::new(IncrCompSession::NotInitialized)),
cgu_reuse_tracker,
self_profiling_active,
self_profiling: Lock::new(SelfProfiler::new()),
self_profiling: self_profiler,
profile_channel: Lock::new(None),
perf_stats: PerfStats {
symbol_hash_time: Lock::new(Duration::from_secs(0)),

View File

@ -19,6 +19,7 @@ memmap = "0.6"
log = "0.4.5"
libc = "0.2.44"
jobserver = "0.1.11"
parking_lot = "0.7"
serialize = { path = "../libserialize" }
syntax = { path = "../libsyntax" }

View File

@ -19,6 +19,7 @@ use rustc::util::time_graph::{self, TimeGraph, Timeline};
use rustc::hir::def_id::{CrateNum, LOCAL_CRATE};
use rustc::ty::TyCtxt;
use rustc::util::common::{time_depth, set_time_depth, print_time_passes_entry};
use rustc::util::profiling::SelfProfiler;
use rustc_fs_util::link_or_copy;
use rustc_data_structures::svh::Svh;
use rustc_errors::{Handler, Level, DiagnosticBuilder, FatalError, DiagnosticId};
@ -29,6 +30,7 @@ use syntax::ext::hygiene::Mark;
use syntax_pos::MultiSpan;
use syntax_pos::symbol::Symbol;
use jobserver::{Client, Acquired};
use parking_lot::Mutex as PlMutex;
use std::any::Any;
use std::fs;
@ -201,6 +203,7 @@ pub struct CodegenContext<B: WriteBackendMethods> {
// Resources needed when running LTO
pub backend: B,
pub time_passes: bool,
pub profiler: Option<Arc<PlMutex<SelfProfiler>>>,
pub lto: Lto,
pub no_landing_pads: bool,
pub save_temps: bool,
@ -254,6 +257,26 @@ impl<B: WriteBackendMethods> CodegenContext<B> {
ModuleKind::Allocator => &self.allocator_module_config,
}
}
#[inline(never)]
#[cold]
fn profiler_active<F: FnOnce(&mut SelfProfiler) -> ()>(&self, f: F) {
match &self.profiler {
None => bug!("profiler_active() called but there was no profiler active"),
Some(profiler) => {
let mut p = profiler.lock();
f(&mut p);
}
}
}
#[inline(always)]
pub fn profile<F: FnOnce(&mut SelfProfiler) -> ()>(&self, f: F) {
if unlikely!(self.profiler.is_some()) {
self.profiler_active(f)
}
}
}
fn generate_lto_work<B: ExtraBackendMethods>(
@ -1033,6 +1056,7 @@ fn start_executing_work<B: ExtraBackendMethods>(
save_temps: sess.opts.cg.save_temps,
opts: Arc::new(sess.opts.clone()),
time_passes: sess.time_passes(),
profiler: sess.self_profiling.clone(),
exported_symbols,
plugin_passes: sess.plugin_llvm_passes.borrow().clone(),
remark: sess.opts.cg.remark.clone(),

View File

@ -2,9 +2,11 @@
#![feature(box_patterns)]
#![feature(box_syntax)]
#![feature(core_intrinsics)]
#![feature(custom_attribute)]
#![feature(libc)]
#![feature(rustc_diagnostic_macros)]
#![feature(stmt_expr_attributes)]
#![feature(in_band_lifetimes)]
#![feature(nll)]
#![allow(unused_attributes)]
@ -20,6 +22,7 @@
#[macro_use] extern crate log;
#[macro_use] extern crate rustc;
#[macro_use] extern crate rustc_data_structures;
#[macro_use] extern crate syntax;
use std::path::PathBuf;

View File

@ -349,14 +349,6 @@ pub fn compile_input(
sess.print_perf_stats();
}
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!(
compilation_done,
sess,

View File

@ -276,6 +276,15 @@ fn run_compiler_with_pool<'a>(
&control)
};
if sess.opts.debugging_opts.self_profile {
sess.profiler(|p| p.print_results(&sess.opts));
}
if sess.opts.debugging_opts.profile_json {
sess.profiler(|p| p.save_results(&sess.opts));
}
(result, Some(sess))
}