From c61f9763e2e03afbe62445877ceb3ed15e22e123 Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Mon, 21 Jul 2014 13:48:19 -0700 Subject: [PATCH] Use fewer instructions for `fail!` Adds a special-case fail function, rustrt::unwind::begin_unwind_no_time_to_explain, that encapsulates the printing of the words "explicit failure". The before/after optimized assembly: ``` leaq "str\"str\"(1369)"(%rip), %rax movq %rax, 8(%rsp) movq $19, 16(%rsp) leaq 8(%rsp), %rdi movl $11, %esi callq _ZN6unwind31begin_unwind_no_time_to_explain20hd1c720cdde6a116480dE@PLT ``` ``` leaq "str\"str\"(1412)"(%rip), %rax movq %rax, 24(%rsp) movq $16, 32(%rsp) leaq "str\"str\"(1413)"(%rip), %rax movq %rax, 8(%rsp) movq $19, 16(%rsp) leaq 24(%rsp), %rdi leaq 8(%rsp), %rsi movl $11, %edx callq _ZN6unwind12begin_unwind21h15836560661922107792E ``` Before/after filesizes: rwxrwxr-x 1 brian brian 21479503 Jul 20 22:09 stage2-old/lib/librustc-4e7c5e5c.so rwxrwxr-x 1 brian brian 21475415 Jul 20 22:30 x86_64-unknown-linux-gnu/stage2/lib/librustc-4e7c5e5c.so --- src/librustrt/lib.rs | 2 +- src/librustrt/unwind.rs | 5 +++++ src/libstd/macros.rs | 2 +- src/libstd/rt/mod.rs | 3 ++- 4 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/librustrt/lib.rs b/src/librustrt/lib.rs index a150408ac2e..2fe0c32153a 100644 --- a/src/librustrt/lib.rs +++ b/src/librustrt/lib.rs @@ -33,7 +33,7 @@ extern crate collections; #[cfg(test)] #[phase(plugin, link)] extern crate std; pub use self::util::{Stdio, Stdout, Stderr}; -pub use self::unwind::{begin_unwind, begin_unwind_fmt}; +pub use self::unwind::{begin_unwind, begin_unwind_fmt, begin_unwind_no_time_to_explain}; use core::prelude::*; diff --git a/src/librustrt/unwind.rs b/src/librustrt/unwind.rs index f26cccdd3ed..cb1b6f46afe 100644 --- a/src/librustrt/unwind.rs +++ b/src/librustrt/unwind.rs @@ -432,6 +432,11 @@ pub fn begin_unwind(msg: M, file: &'static str, line: uint) -> ! begin_unwind_inner(box msg, file, line) } +/// Unwinding for `fail!()`. Saves passing a string. +#[inline(never)] #[cold] #[experimental] +pub fn begin_unwind_no_time_to_explain(file: &'static str, line: uint) -> ! { + begin_unwind_inner(box () ("explicit failure"), file, line) +} /// The core of the unwinding. /// diff --git a/src/libstd/macros.rs b/src/libstd/macros.rs index 8b79af8c931..3c6c860f516 100644 --- a/src/libstd/macros.rs +++ b/src/libstd/macros.rs @@ -39,7 +39,7 @@ #[macro_export] macro_rules! fail( () => ( - fail!("explicit failure") + ::std::rt::begin_unwind_no_time_to_explain(file!(), line!()) ); ($msg:expr) => ( ::std::rt::begin_unwind($msg, file!(), line!()) diff --git a/src/libstd/rt/mod.rs b/src/libstd/rt/mod.rs index 4490977bde6..023a30de027 100644 --- a/src/libstd/rt/mod.rs +++ b/src/libstd/rt/mod.rs @@ -66,7 +66,8 @@ pub use self::util::{default_sched_threads, min_stack, running_on_valgrind}; // standard library which work together to create the entire runtime. pub use alloc::{heap, libc_heap}; pub use rustrt::{task, local, mutex, exclusive, stack, args, rtio, thread}; -pub use rustrt::{Stdio, Stdout, Stderr, begin_unwind, begin_unwind_fmt}; +pub use rustrt::{Stdio, Stdout, Stderr}; +pub use rustrt::{begin_unwind, begin_unwind_fmt, begin_unwind_no_time_to_explain}; pub use rustrt::{bookkeeping, at_exit, unwind, DEFAULT_ERROR_CODE, Runtime}; // Simple backtrace functionality (to print on failure)