Skip to content

Commit e5abe66

Browse files
committed
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.
1 parent 0119e46 commit e5abe66

File tree

1 file changed

+18
-3
lines changed

1 file changed

+18
-3
lines changed

src/libstd/rt/unwind.rs

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -383,16 +383,31 @@ pub fn begin_unwind_raw(msg: *u8, file: *u8, line: uint) -> ! {
383383
}
384384

385385
/// This is the entry point of unwinding for fail!() and assert!().
386-
#[inline(never)] #[cold] // this is the slow path, please never inline this
386+
#[inline(never)] #[cold] // avoid code bloat at the call sites as much as possible
387387
pub fn begin_unwind<M: Any + Send>(msg: M, file: &'static str, line: uint) -> ! {
388-
// Note that this should be the only allocation performed in this block.
388+
// Note that this should be the only allocation performed in this code path.
389389
// Currently this means that fail!() on OOM will invoke this code path,
390390
// but then again we're not really ready for failing on OOM anyway. If
391391
// we do start doing this, then we should propagate this allocation to
392392
// be performed in the parent of this task instead of the task that's
393393
// failing.
394-
let msg = ~msg as ~Any;
395394

395+
// see below for why we do the `Any` coercion here.
396+
begin_unwind_inner(~msg, file, line)
397+
}
398+
399+
400+
/// The core of the unwinding.
401+
///
402+
/// This is non-generic to avoid instantiation bloat in other crates
403+
/// (which makes compilation of small crates noticably slower). (Note:
404+
/// we need the `Any` object anyway, we're not just creating it to
405+
/// avoid being generic.)
406+
///
407+
/// Do this split took the LLVM IR line counts of `fn main() { fail!()
408+
/// }` from ~1900/3700 (-O/no opts) to 180/590.
409+
#[inline(never)] #[cold] // this is the slow path, please never inline this
410+
fn begin_unwind_inner(msg: ~Any, file: &'static str, line: uint) -> ! {
396411
let mut task;
397412
{
398413
let msg_s = match msg.as_ref::<&'static str>() {

0 commit comments

Comments
 (0)