Skip to content

Reduce text size for fail invocations #15983

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Jul 28, 2014
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions src/libcore/failure.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ use intrinsics;
#[lang="fail_"]
fn fail_(expr: &'static str, file: &'static str, line: uint) -> ! {
format_args!(|args| -> () {
begin_unwind(args, file, line);
begin_unwind(args, &(file, line));
}, "{}", expr);

unsafe { intrinsics::abort() }
Expand All @@ -48,18 +48,20 @@ fn fail_(expr: &'static str, file: &'static str, line: uint) -> ! {
fn fail_bounds_check(file: &'static str, line: uint,
index: uint, len: uint) -> ! {
format_args!(|args| -> () {
begin_unwind(args, file, line);
begin_unwind(args, &(file, line));
}, "index out of bounds: the len is {} but the index is {}", len, index);
unsafe { intrinsics::abort() }
}

#[cold]
pub fn begin_unwind(fmt: &fmt::Arguments, file: &'static str, line: uint) -> ! {
pub fn begin_unwind(fmt: &fmt::Arguments, file_line: &(&'static str, uint)) -> ! {
#[allow(ctypes)]
extern {
#[lang = "begin_unwind"]
fn begin_unwind(fmt: &fmt::Arguments, file: &'static str,
line: uint) -> !;
}
let (file, line) = *file_line;
unsafe { begin_unwind(fmt, file, line) }
}

3 changes: 2 additions & 1 deletion src/libcore/macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@ macro_rules! fail(
// up with the number of calls to fail!()
#[inline(always)]
fn run_fmt(fmt: &::std::fmt::Arguments) -> ! {
::core::failure::begin_unwind(fmt, file!(), line!())
static FILE_LINE: (&'static str, uint) = (file!(), line!());
::core::failure::begin_unwind(fmt, &FILE_LINE)
}
format_args!(run_fmt, $fmt, $($arg)*)
});
Expand Down
2 changes: 1 addition & 1 deletion src/librustrt/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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, begin_unwind_no_time_to_explain};
pub use self::unwind::{begin_unwind, begin_unwind_fmt};

use core::prelude::*;

Expand Down
21 changes: 7 additions & 14 deletions src/librustrt/unwind.rs
Original file line number Diff line number Diff line change
Expand Up @@ -384,7 +384,7 @@ pub mod eabi {
#[lang = "begin_unwind"]
pub extern fn rust_begin_unwind(msg: &fmt::Arguments,
file: &'static str, line: uint) -> ! {
begin_unwind_fmt(msg, file, line)
begin_unwind_fmt(msg, &(file, line))
}

/// The entry point for unwinding with a formatted message.
Expand All @@ -394,8 +394,7 @@ pub extern fn rust_begin_unwind(msg: &fmt::Arguments,
/// 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) -> ! {
pub fn begin_unwind_fmt(msg: &fmt::Arguments, file_line: &(&'static str, uint)) -> ! {
use core::fmt::FormatWriter;

// We do two allocations here, unfortunately. But (a) they're
Expand All @@ -415,9 +414,10 @@ pub fn begin_unwind_fmt(msg: &fmt::Arguments, file: &'static str,
let mut v = Vec::new();
let _ = write!(&mut VecWriter { v: &mut v }, "{}", msg);

begin_unwind_inner(box String::from_utf8(v).unwrap(), file, line)
begin_unwind_inner(box String::from_utf8(v).unwrap(), file_line)
}

// FIXME: Need to change expr_fail in AstBuilder to change this to &(str, uint)
/// 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) -> ! {
Expand All @@ -429,13 +429,7 @@ pub fn begin_unwind<M: Any + Send>(msg: M, file: &'static str, line: uint) -> !
// failing.

// see below for why we do the `Any` coercion here.
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)
begin_unwind_inner(box msg, &(file, line))
}

/// The core of the unwinding.
Expand All @@ -448,9 +442,7 @@ pub fn begin_unwind_no_time_to_explain(file: &'static str, line: uint) -> ! {
/// 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: Box<Any + Send>,
file: &'static str,
line: uint) -> ! {
fn begin_unwind_inner(msg: Box<Any + Send>, file_line: &(&'static str, uint)) -> ! {
// First, invoke call the user-defined callbacks triggered on task failure.
//
// By the time that we see a callback has been registered (by reading
Expand All @@ -467,6 +459,7 @@ fn begin_unwind_inner(msg: Box<Any + Send>,
0 => {}
n => {
let f: Callback = unsafe { mem::transmute(n) };
let (file, line) = *file_line;
f(msg, file, line);
}
}
Expand Down
18 changes: 11 additions & 7 deletions src/libstd/macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,15 @@
/// ```
#[macro_export]
macro_rules! fail(
() => (
::std::rt::begin_unwind_no_time_to_explain(file!(), line!())
);
($msg:expr) => (
::std::rt::begin_unwind($msg, file!(), line!())
);
() => ({
fail!("explicit failure")
});
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd personally prefer to remove the special case of 0 arguments, I think that this change has much more impact than not moving the message into place for this fairly uncommon case of fail!()

($msg:expr) => ({
// static requires less code at runtime, more constant data
static FILE_LINE: (&'static str, uint) = (file!(), line!());
let (file, line) = FILE_LINE;
::std::rt::begin_unwind($msg, file, line)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems a little odd to have a static with the two together, but then it's immediately destructed? Is that because changing begin_unwind would involve changing the ast builder?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, and I'm going to do a followup to make that change.

});
($fmt:expr, $($arg:tt)*) => ({
// a closure can't have return type !, so we need a full
// function to pass to format_args!, *and* we need the
Expand All @@ -58,7 +61,8 @@ macro_rules! fail(
// up with the number of calls to fail!()
#[inline(always)]
fn run_fmt(fmt: &::std::fmt::Arguments) -> ! {
::std::rt::begin_unwind_fmt(fmt, file!(), line!())
static FILE_LINE: (&'static str, uint) = (file!(), line!());
::std::rt::begin_unwind_fmt(fmt, &FILE_LINE)
}
format_args!(run_fmt, $fmt, $($arg)*)
});
Expand Down
3 changes: 1 addition & 2 deletions src/libstd/rt/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,7 @@ 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};
pub use rustrt::{begin_unwind, begin_unwind_fmt, begin_unwind_no_time_to_explain};
pub use rustrt::{Stdio, Stdout, Stderr, begin_unwind, begin_unwind_fmt};
pub use rustrt::{bookkeeping, at_exit, unwind, DEFAULT_ERROR_CODE, Runtime};

// Simple backtrace functionality (to print on failure)
Expand Down