rustrt: Make begin_unwind take a single file/line pointer

Smaller text size.
This commit is contained in:
Brian Anderson 2014-07-28 21:26:21 -07:00 committed by Alex Crichton
parent 571f6cf29a
commit 134946d06e
3 changed files with 57 additions and 6 deletions

View File

@ -417,8 +417,8 @@ pub fn begin_unwind_fmt(msg: &fmt::Arguments, file_line: &(&'static str, uint))
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!().
#[cfg(stage0)]
#[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) -> ! {
// Note that this should be the only allocation performed in this code path.
@ -432,6 +432,21 @@ pub fn begin_unwind<M: Any + Send>(msg: M, file: &'static str, line: uint) -> !
begin_unwind_inner(box msg, &(file, line))
}
/// This is the entry point of unwinding for fail!() and assert!().
#[cfg(not(stage0))]
#[inline(never)] #[cold] // avoid code bloat at the call sites as much as possible
pub fn begin_unwind<M: Any + Send>(msg: M, file_line: &(&'static str, uint)) -> ! {
// Note that this should be the only allocation performed in this code path.
// Currently this means that fail!() on OOM will invoke this code path,
// but then again we're not really ready for failing on OOM anyway. If
// we do start doing this, then we should propagate this allocation to
// be performed in the parent of this task instead of the task that's
// failing.
// see below for why we do the `Any` coercion here.
begin_unwind_inner(box msg, file_line)
}
/// The core of the unwinding.
///
/// This is non-generic to avoid instantiation bloat in other crates

View File

@ -37,6 +37,39 @@
/// fail!("this is a {} {message}", "fancy", message = "message");
/// ```
#[macro_export]
#[cfg(not(stage0))]
macro_rules! fail(
() => ({
fail!("explicit failure")
});
($msg:expr) => ({
// static requires less code at runtime, more constant data
static FILE_LINE: (&'static str, uint) = (file!(), line!());
::std::rt::begin_unwind($msg, &FILE_LINE)
});
($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
// file and line numbers right here; so an inner bare fn
// is our only choice.
//
// LLVM doesn't tend to inline this, presumably because begin_unwind_fmt
// is #[cold] and #[inline(never)] and because this is flagged as cold
// as returning !. We really do want this to be inlined, however,
// because it's just a tiny wrapper. Small wins (156K to 149K in size)
// were seen when forcing this to be inlined, and that number just goes
// up with the number of calls to fail!()
#[inline(always)]
fn run_fmt(fmt: &::std::fmt::Arguments) -> ! {
static FILE_LINE: (&'static str, uint) = (file!(), line!());
::std::rt::begin_unwind_fmt(fmt, &FILE_LINE)
}
format_args!(run_fmt, $fmt, $($arg)*)
});
)
#[macro_export]
#[cfg(stage0)]
macro_rules! fail(
() => ({
fail!("explicit failure")

View File

@ -690,6 +690,13 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
fn expr_fail(&self, span: Span, msg: InternedString) -> Gc<ast::Expr> {
let loc = self.codemap().lookup_char_pos(span.lo);
let expr_file = self.expr_str(span,
token::intern_and_get_ident(loc.file
.name
.as_slice()));
let expr_line = self.expr_uint(span, loc.line);
let expr_file_line_tuple = self.expr_tuple(span, vec!(expr_file, expr_line));
let expr_file_line_ptr = self.expr_addr_of(span, expr_file_line_tuple);
self.expr_call_global(
span,
vec!(
@ -698,11 +705,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
self.ident_of("begin_unwind")),
vec!(
self.expr_str(span, msg),
self.expr_str(span,
token::intern_and_get_ident(loc.file
.name
.as_slice())),
self.expr_uint(span, loc.line)))
expr_file_line_ptr))
}
fn expr_unreachable(&self, span: Span) -> Gc<ast::Expr> {