summary refs log tree commit diff
path: root/src/libstd/rt
diff options
context:
space:
mode:
authorHuon Wilson <dbau.pp+github@gmail.com>2014-01-27 22:37:55 +1100
committerHuon Wilson <dbau.pp+github@gmail.com>2014-01-27 23:58:03 +1100
commitb4bb8c0f4ee1234e9d84aa7cb1a9ad691a509212 (patch)
tree9fb5bc2209efd91a825d791caa029b8184c167e2 /src/libstd/rt
parente5abe669831a59c48faa85e88ed8859b6dc63f49 (diff)
downloadrust-b4bb8c0f4ee1234e9d84aa7cb1a9ad691a509212.tar.gz
rust-b4bb8c0f4ee1234e9d84aa7cb1a9ad691a509212.zip
std: add begin_unwind_fmt that reduces codesize for formatted fail!().
This ends up saving a single `call` instruction in the optimised code,
but saves a few hundred lines of non-optimised IR for `fn main() {
fail!("foo {}", "bar"); }` (comparing against the minimal generic
baseline from the parent commit).
Diffstat (limited to 'src/libstd/rt')
-rw-r--r--src/libstd/rt/mod.rs2
-rw-r--r--src/libstd/rt/unwind.rs12
2 files changed, 13 insertions, 1 deletions
diff --git a/src/libstd/rt/mod.rs b/src/libstd/rt/mod.rs
index 56f6c8f8e6c..0e30f3e2efd 100644
--- a/src/libstd/rt/mod.rs
+++ b/src/libstd/rt/mod.rs
@@ -69,7 +69,7 @@ use self::task::{Task, BlockedTask};
 pub use self::util::default_sched_threads;
 
 // Export unwinding facilities used by the failure macros
-pub use self::unwind::{begin_unwind, begin_unwind_raw};
+pub use self::unwind::{begin_unwind, begin_unwind_raw, begin_unwind_fmt};
 
 // FIXME: these probably shouldn't be public...
 #[doc(hidden)]
diff --git a/src/libstd/rt/unwind.rs b/src/libstd/rt/unwind.rs
index b8b004b1c3b..25a92148e96 100644
--- a/src/libstd/rt/unwind.rs
+++ b/src/libstd/rt/unwind.rs
@@ -58,6 +58,7 @@
 use any::{Any, AnyRefExt};
 use c_str::CString;
 use cast;
+use fmt;
 use kinds::Send;
 use option::{Some, None, Option};
 use prelude::drop;
@@ -382,6 +383,17 @@ pub fn begin_unwind_raw(msg: *u8, file: *u8, line: uint) -> ! {
     begin_unwind(msg, file, line as uint)
 }
 
+/// The entry point for unwinding with a formatted message.
+///
+/// This is designed to reduce the amount of code required at the call
+/// site as much as possible (so that `fail!()` has as low an implact
+/// on (e.g.) the inlining of other functions as possible), by moving
+/// the actual formatting into this shared place.
+#[inline(never)] #[cold]
+pub fn begin_unwind_fmt(msg: &fmt::Arguments, file: &'static str, line: uint) -> ! {
+    begin_unwind_inner(~fmt::format(msg), file, line)
+}
+
 /// This is the entry point of unwinding for fail!() and assert!().
 #[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) -> ! {