std: reduce the generic code instantiated by fail!().
This splits the vast majority of the code path taken by `fail!()` (`begin_unwind`) into a separate non-generic inline(never) function, so that uses of `fail!()` only monomorphise a small amount of code, reducing code bloat and making very small crates compile faster.
This commit is contained in:
parent
0119e46204
commit
e5abe66983
1 changed files with 18 additions and 3 deletions
|
@ -383,16 +383,31 @@ pub fn begin_unwind_raw(msg: *u8, file: *u8, line: uint) -> ! {
|
|||
}
|
||||
|
||||
/// This is the entry point of unwinding for fail!() and assert!().
|
||||
#[inline(never)] #[cold] // this is the slow path, please never inline this
|
||||
#[inline(never)] #[cold] // avoid code bloat at the call sites as much as possible
|
||||
pub fn begin_unwind<M: Any + Send>(msg: M, file: &'static str, line: uint) -> ! {
|
||||
// Note that this should be the only allocation performed in this block.
|
||||
// Note that this should be the only allocation performed in this code path.
|
||||
// Currently this means that fail!() on OOM will invoke this code path,
|
||||
// but then again we're not really ready for failing on OOM anyway. If
|
||||
// we do start doing this, then we should propagate this allocation to
|
||||
// be performed in the parent of this task instead of the task that's
|
||||
// failing.
|
||||
let msg = ~msg as ~Any;
|
||||
|
||||
// see below for why we do the `Any` coercion here.
|
||||
begin_unwind_inner(~msg, file, line)
|
||||
}
|
||||
|
||||
|
||||
/// The core of the unwinding.
|
||||
///
|
||||
/// This is non-generic to avoid instantiation bloat in other crates
|
||||
/// (which makes compilation of small crates noticably slower). (Note:
|
||||
/// we need the `Any` object anyway, we're not just creating it to
|
||||
/// avoid being generic.)
|
||||
///
|
||||
/// Do this split took the LLVM IR line counts of `fn main() { fail!()
|
||||
/// }` from ~1900/3700 (-O/no opts) to 180/590.
|
||||
#[inline(never)] #[cold] // this is the slow path, please never inline this
|
||||
fn begin_unwind_inner(msg: ~Any, file: &'static str, line: uint) -> ! {
|
||||
let mut task;
|
||||
{
|
||||
let msg_s = match msg.as_ref::<&'static str>() {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue