-
Notifications
You must be signed in to change notification settings - Fork 12.7k
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
rustc_driver: get rid of the extra thread #48575
Changes from 3 commits
e85c922
1bb89f1
a185b56
8c8a72f
2928c7a
9127990
d39b02c
8ecbec1
50ca86b
7db854b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -24,6 +24,7 @@ | |
#![feature(quote)] | ||
#![feature(rustc_diagnostic_macros)] | ||
#![feature(set_stdio)] | ||
#![feature(rustc_stack_internals)] | ||
|
||
extern crate arena; | ||
extern crate getopts; | ||
|
@@ -1461,16 +1462,56 @@ pub fn in_rustc_thread<F, R>(f: F) -> Result<R, Box<Any + Send>> | |
// Temporarily have stack size set to 16MB to deal with nom-using crates failing | ||
const STACK_SIZE: usize = 16 * 1024 * 1024; // 16MB | ||
|
||
let mut cfg = thread::Builder::new().name("rustc".to_string()); | ||
#[cfg(unix)] | ||
let spawn_thread = unsafe { | ||
// Fetch the current resource limits | ||
let mut rlim = libc::rlimit { | ||
rlim_cur: 0, | ||
rlim_max: 0, | ||
}; | ||
if libc::getrlimit(libc::RLIMIT_STACK, &mut rlim) != 0 { | ||
let err = io::Error::last_os_error(); | ||
error!("in_rustc_thread: error calling getrlimit: {}", err); | ||
true | ||
} else if rlim.rlim_max < STACK_SIZE as libc::rlim_t { | ||
true | ||
} else { | ||
std::rt::deinit_stack_guard(); | ||
rlim.rlim_cur = STACK_SIZE as libc::rlim_t; | ||
if libc::setrlimit(libc::RLIMIT_STACK, &mut rlim) != 0 { | ||
let err = io::Error::last_os_error(); | ||
// We have already deinited the stack. Further corruption is | ||
// not allowed. | ||
panic!("in_rustc_thread: error calling setrlimit: {}", err); | ||
} else { | ||
std::rt::update_stack_guard(); | ||
false | ||
} | ||
} | ||
}; | ||
|
||
// FIXME: Hacks on hacks. If the env is trying to override the stack size | ||
// then *don't* set it explicitly. | ||
if env::var_os("RUST_MIN_STACK").is_none() { | ||
cfg = cfg.stack_size(STACK_SIZE); | ||
} | ||
// We set the stack size at link time. See src/rustc/rustc.rs. | ||
#[cfg(windows)] | ||
let spawn_thread = false; | ||
|
||
#[cfg(not(any(windows,unix)))] | ||
let spawn_thread = true; | ||
|
||
let thread = cfg.spawn(f); | ||
thread.unwrap().join() | ||
// The or condition is added from backward compatibility. | ||
if spawn_thread || env::var_os("RUST_MIN_STACK").is_some() { | ||
let mut cfg = thread::Builder::new().name("rustc".to_string()); | ||
|
||
// FIXME: Hacks on hacks. If the env is trying to override the stack size | ||
// then *don't* set it explicitly. | ||
if env::var_os("RUST_MIN_STACK").is_none() { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Could this be checked earlier? If this env var is set I think we'll want to force spawning a thread. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I disagree: that environment variable only affects stack size of non-main thread. If we can extend the main thread stack, that's all what we need. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Without moving this check earlier it's breaking existing behavior. Today the stack size of the rustc thread can be controlled by configuring |
||
cfg = cfg.stack_size(STACK_SIZE); | ||
} | ||
|
||
let thread = cfg.spawn(f); | ||
thread.unwrap().join() | ||
} else { | ||
Ok(f()) | ||
} | ||
} | ||
|
||
/// Get a list of extra command-line flags provided by the user, as strings. | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -222,7 +222,7 @@ pub mod guard { | |
#[cfg_attr(test, allow(dead_code))] | ||
pub mod guard { | ||
use libc; | ||
use libc::mmap; | ||
use libc::{mmap, munmap}; | ||
use libc::{PROT_NONE, MAP_PRIVATE, MAP_ANON, MAP_FAILED, MAP_FIXED}; | ||
use ops::Range; | ||
use sys::os; | ||
|
@@ -336,6 +336,24 @@ pub mod guard { | |
} | ||
} | ||
|
||
pub unsafe fn deinit() { | ||
if !cfg!(target_os = "linux") { | ||
if let Some(mut stackaddr) = get_stack_start() { | ||
// Ensure address is aligned. Same as above. | ||
let remainder = (stackaddr as usize) % PAGE_SIZE; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This looks the same as the calculation above, could they be unified perhaps? |
||
if remainder != 0 { | ||
stackaddr = ((stackaddr as usize) + PAGE_SIZE - remainder) | ||
as *mut libc::c_void; | ||
} | ||
|
||
// Undo the guard page mapping. | ||
if munmap(stackaddr, PAGE_SIZE) != 0 { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It looks like on FreeBSD we map 2 pages? Could the logic above and here be shared? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We don't. It's just a wider guard address range, unrelated to what we memory map. |
||
panic!("unable to deallocate the guard page"); | ||
} | ||
} | ||
} | ||
} | ||
|
||
#[cfg(any(target_os = "macos", | ||
target_os = "bitrig", | ||
target_os = "openbsd", | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We could fall through and call
update_stack_guard
again here, right?