Skip to content

Commit dd98d10

Browse files
committed
---
yaml --- r: 103594 b: refs/heads/try c: 760ddb3 h: refs/heads/master v: v3
1 parent b739200 commit dd98d10

File tree

4 files changed

+44
-7
lines changed

4 files changed

+44
-7
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
refs/heads/master: 62f1d68439dcfd509eaca29887afa97f22938373
33
refs/heads/snap-stage1: e33de59e47c5076a89eadeb38f4934f58a3618a6
44
refs/heads/snap-stage3: 6e7f170fedd3c526a643c0b2d13863acd982be02
5-
refs/heads/try: e81ab4198c15ef53a61c38196fad55add291fc58
5+
refs/heads/try: 760ddb3081acb038ff3c6bcc918bfa293dfc5acd
66
refs/tags/release-0.1: 1f5c5126e96c79d22cb7862f75304136e204f105
77
refs/heads/ndm: f3868061cd7988080c30d6d5bf352a5a5fe2460b
88
refs/heads/try2: 147ecfdd8221e4a4d4e090486829a06da1e0ca3c

branches/try/src/libstd/macros.rs

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,18 @@ macro_rules! fail(
4848
::std::rt::begin_unwind($msg, file!(), line!())
4949
);
5050
($fmt:expr, $($arg:tt)*) => (
51-
::std::rt::begin_unwind(format!($fmt, $($arg)*), file!(), line!())
52-
)
51+
{
52+
// a closure can't have return type !, so we need a full
53+
// function to pass to format_args!, *and* we need the
54+
// file and line numbers right here; so an inner bare fn
55+
// is our only choice.
56+
#[inline]
57+
fn run_fmt(fmt: &::std::fmt::Arguments) -> ! {
58+
::std::rt::begin_unwind_fmt(fmt, file!(), line!())
59+
}
60+
format_args!(run_fmt, $fmt, $($arg)*)
61+
}
62+
)
5363
)
5464

5565
#[macro_export]

branches/try/src/libstd/rt/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ use self::task::{Task, BlockedTask};
6969
pub use self::util::default_sched_threads;
7070

7171
// Export unwinding facilities used by the failure macros
72-
pub use self::unwind::{begin_unwind, begin_unwind_raw};
72+
pub use self::unwind::{begin_unwind, begin_unwind_raw, begin_unwind_fmt};
7373

7474
// FIXME: these probably shouldn't be public...
7575
#[doc(hidden)]

branches/try/src/libstd/rt/unwind.rs

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@
5858
use any::{Any, AnyRefExt};
5959
use c_str::CString;
6060
use cast;
61+
use fmt;
6162
use kinds::Send;
6263
use option::{Some, None, Option};
6364
use prelude::drop;
@@ -382,17 +383,43 @@ pub fn begin_unwind_raw(msg: *u8, file: *u8, line: uint) -> ! {
382383
begin_unwind(msg, file, line as uint)
383384
}
384385

386+
/// The entry point for unwinding with a formatted message.
387+
///
388+
/// This is designed to reduce the amount of code required at the call
389+
/// site as much as possible (so that `fail!()` has as low an implact
390+
/// on (e.g.) the inlining of other functions as possible), by moving
391+
/// the actual formatting into this shared place.
392+
#[inline(never)] #[cold]
393+
pub fn begin_unwind_fmt(msg: &fmt::Arguments, file: &'static str, line: uint) -> ! {
394+
begin_unwind_inner(~fmt::format(msg), file, line)
395+
}
396+
385397
/// This is the entry point of unwinding for fail!() and assert!().
386-
#[inline(never)] #[cold] // this is the slow path, please never inline this
398+
#[inline(never)] #[cold] // avoid code bloat at the call sites as much as possible
387399
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.
400+
// Note that this should be the only allocation performed in this code path.
389401
// Currently this means that fail!() on OOM will invoke this code path,
390402
// but then again we're not really ready for failing on OOM anyway. If
391403
// we do start doing this, then we should propagate this allocation to
392404
// be performed in the parent of this task instead of the task that's
393405
// failing.
394-
let msg = ~msg as ~Any;
395406

407+
// see below for why we do the `Any` coercion here.
408+
begin_unwind_inner(~msg, file, line)
409+
}
410+
411+
412+
/// The core of the unwinding.
413+
///
414+
/// This is non-generic to avoid instantiation bloat in other crates
415+
/// (which makes compilation of small crates noticably slower). (Note:
416+
/// we need the `Any` object anyway, we're not just creating it to
417+
/// avoid being generic.)
418+
///
419+
/// Do this split took the LLVM IR line counts of `fn main() { fail!()
420+
/// }` from ~1900/3700 (-O/no opts) to 180/590.
421+
#[inline(never)] #[cold] // this is the slow path, please never inline this
422+
fn begin_unwind_inner(msg: ~Any, file: &'static str, line: uint) -> ! {
396423
let mut task;
397424
{
398425
let msg_s = match msg.as_ref::<&'static str>() {

0 commit comments

Comments
 (0)