Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Start-up clean-up #74122

Merged
merged 4 commits into from
Jul 11, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 8 additions & 8 deletions src/librustc_interface/interface.rs
Original file line number Diff line number Diff line change
Expand Up @@ -159,10 +159,7 @@ pub struct Config {
pub registry: Registry,
}

pub fn run_compiler_in_existing_thread_pool<R>(
config: Config,
f: impl FnOnce(&Compiler) -> R,
) -> R {
pub fn create_compiler_and_run<R>(config: Config, f: impl FnOnce(&Compiler) -> R) -> R {
let registry = &config.registry;
let (sess, codegen_backend) = util::create_session(
config.opts,
Expand Down Expand Up @@ -204,17 +201,20 @@ pub fn run_compiler_in_existing_thread_pool<R>(
pub fn run_compiler<R: Send>(mut config: Config, f: impl FnOnce(&Compiler) -> R + Send) -> R {
log::trace!("run_compiler");
let stderr = config.stderr.take();
util::spawn_thread_pool(
util::setup_callbacks_and_run_in_thread_pool_with_globals(
config.opts.edition,
config.opts.debugging_opts.threads,
&stderr,
|| run_compiler_in_existing_thread_pool(config, f),
|| create_compiler_and_run(config, f),
)
}

pub fn default_thread_pool<R: Send>(edition: edition::Edition, f: impl FnOnce() -> R + Send) -> R {
pub fn setup_callbacks_and_run_in_default_thread_pool_with_globals<R: Send>(
edition: edition::Edition,
f: impl FnOnce() -> R + Send,
) -> R {
// the 1 here is duplicating code in config.opts.debugging_opts.threads
// which also defaults to 1; it ultimately doesn't matter as the default
// isn't threaded, and just ignores this parameter
util::spawn_thread_pool(edition, 1, &None, f)
util::setup_callbacks_and_run_in_thread_pool_with_globals(edition, 1, &None, f)
}
31 changes: 17 additions & 14 deletions src/librustc_interface/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,8 @@ impl Write for Sink {
}
}

/// Like a `thread::Builder::spawn` followed by a `join()`, but avoids the need
/// for `'static` bounds.
#[cfg(not(parallel_compiler))]
pub fn scoped_thread<F: FnOnce() -> R + Send, R: Send>(cfg: thread::Builder, f: F) -> R {
struct Ptr(*mut ());
Expand All @@ -126,7 +128,7 @@ pub fn scoped_thread<F: FnOnce() -> R + Send, R: Send>(cfg: thread::Builder, f:
}

#[cfg(not(parallel_compiler))]
pub fn spawn_thread_pool<F: FnOnce() -> R + Send, R: Send>(
pub fn setup_callbacks_and_run_in_thread_pool_with_globals<F: FnOnce() -> R + Send, R: Send>(
edition: Edition,
_threads: usize,
stderr: &Option<Arc<Mutex<Vec<u8>>>>,
Expand All @@ -140,7 +142,7 @@ pub fn spawn_thread_pool<F: FnOnce() -> R + Send, R: Send>(

crate::callbacks::setup_callbacks();

scoped_thread(cfg, || {
let main_handler = move || {
rustc_ast::with_session_globals(edition, || {
ty::tls::GCX_PTR.set(&Lock::new(0), || {
if let Some(stderr) = stderr {
Expand All @@ -149,22 +151,21 @@ pub fn spawn_thread_pool<F: FnOnce() -> R + Send, R: Send>(
f()
})
})
})
};

scoped_thread(cfg, main_handler)
}

#[cfg(parallel_compiler)]
pub fn spawn_thread_pool<F: FnOnce() -> R + Send, R: Send>(
pub fn setup_callbacks_and_run_in_thread_pool_with_globals<F: FnOnce() -> R + Send, R: Send>(
edition: Edition,
threads: usize,
stderr: &Option<Arc<Mutex<Vec<u8>>>>,
f: F,
) -> R {
use rayon::{ThreadBuilder, ThreadPool, ThreadPoolBuilder};

let gcx_ptr = &Lock::new(0);
crate::callbacks::setup_callbacks();

let mut config = ThreadPoolBuilder::new()
let mut config = rayon::ThreadPoolBuilder::new()
.thread_name(|_| "rustc".to_string())
.acquire_thread_handler(jobserver::acquire_thread)
.release_thread_handler(jobserver::release_thread)
Expand All @@ -175,7 +176,7 @@ pub fn spawn_thread_pool<F: FnOnce() -> R + Send, R: Send>(
config = config.stack_size(size);
}

let with_pool = move |pool: &ThreadPool| pool.install(move || f());
let with_pool = move |pool: &rayon::ThreadPool| pool.install(move || f());

rustc_ast::with_session_globals(edition, || {
rustc_ast::SESSION_GLOBALS.with(|ast_session_globals| {
Expand All @@ -185,13 +186,15 @@ pub fn spawn_thread_pool<F: FnOnce() -> R + Send, R: Send>(
// span_session_globals are captured and set on the new
// threads. ty::tls::with_thread_locals sets up thread local
// callbacks from librustc_ast.
let main_handler = move |thread: ThreadBuilder| {
let main_handler = move |thread: rayon::ThreadBuilder| {
rustc_ast::SESSION_GLOBALS.set(ast_session_globals, || {
rustc_span::SESSION_GLOBALS.set(span_session_globals, || {
if let Some(stderr) = stderr {
io::set_panic(Some(box Sink(stderr.clone())));
}
ty::tls::GCX_PTR.set(gcx_ptr, || thread.run())
ty::tls::GCX_PTR.set(&Lock::new(0), || {
if let Some(stderr) = stderr {
io::set_panic(Some(box Sink(stderr.clone())));
}
thread.run()
})
})
})
};
Expand Down
2 changes: 1 addition & 1 deletion src/librustdoc/core.rs
Original file line number Diff line number Diff line change
Expand Up @@ -376,7 +376,7 @@ pub fn run_core(options: RustdocOptions) -> (clean::Crate, RenderInfo, RenderOpt
registry: rustc_driver::diagnostics_registry(),
};

interface::run_compiler_in_existing_thread_pool(config, |compiler| {
interface::create_compiler_and_run(config, |compiler| {
compiler.enter(|queries| {
let sess = compiler.session();

Expand Down
59 changes: 27 additions & 32 deletions src/librustdoc/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -437,7 +437,10 @@ fn main_args(args: &[String]) -> i32 {
Ok(opts) => opts,
Err(code) => return code,
};
rustc_interface::interface::default_thread_pool(options.edition, move || main_options(options))
rustc_interface::interface::setup_callbacks_and_run_in_default_thread_pool_with_globals(
options.edition,
move || main_options(options),
)
}

fn wrap_return(diag: &rustc_errors::Handler, res: Result<(), String>) -> i32 {
Expand Down Expand Up @@ -471,7 +474,29 @@ fn main_options(options: config::Options) -> i32 {
// but we can't crates the Handler ahead of time because it's not Send
let diag_opts = (options.error_format, options.edition, options.debugging_options.clone());
let show_coverage = options.show_coverage;
rust_input(options, move |out| {

// First, parse the crate and extract all relevant information.
info!("starting to run rustc");

// Interpret the input file as a rust source file, passing it through the
// compiler all the way through the analysis passes. The rustdoc output is
// then generated from the cleaned AST of the crate. This runs all the
// plug/cleaning passes.
let result = rustc_driver::catch_fatal_errors(move || {
let crate_name = options.crate_name.clone();
let crate_version = options.crate_version.clone();
let (mut krate, renderinfo, renderopts) = core::run_core(options);

info!("finished with rustc");

if let Some(name) = crate_name {
krate.name = name
}

krate.version = crate_version;

let out = Output { krate, renderinfo, renderopts };

if show_coverage {
// if we ran coverage, bail early, we don't need to also generate docs at this point
// (also we didn't load in any of the useful passes)
Expand All @@ -491,36 +516,6 @@ fn main_options(options: config::Options) -> i32 {
rustc_driver::EXIT_FAILURE
}
}
})
}

/// Interprets the input file as a rust source file, passing it through the
/// compiler all the way through the analysis passes. The rustdoc output is then
/// generated from the cleaned AST of the crate.
///
/// This form of input will run all of the plug/cleaning passes
fn rust_input<R, F>(options: config::Options, f: F) -> R
where
R: 'static + Send,
F: 'static + Send + FnOnce(Output) -> R,
{
// First, parse the crate and extract all relevant information.
info!("starting to run rustc");

let result = rustc_driver::catch_fatal_errors(move || {
let crate_name = options.crate_name.clone();
let crate_version = options.crate_version.clone();
let (mut krate, renderinfo, renderopts) = core::run_core(options);

info!("finished with rustc");

if let Some(name) = crate_name {
krate.name = name
}

krate.version = crate_version;

f(Output { krate, renderinfo, renderopts })
});

match result {
Expand Down