mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-22 23:04:33 +00:00
Modify failure lang items to take less pointers.
Divide-by-zero before: ``` leaq "str\"str\"(1762)"(%rip), %rax movq %rax, 16(%rsp) movq $27, 24(%rsp) leaq "str\"str\"(1542)"(%rip), %rax movq %rax, (%rsp) movq $19, 8(%rsp) leaq 16(%rsp), %rdi leaq (%rsp), %rsi movl $32, %edx callq _ZN7failure5fail_20hc04408f955ce60aaqWjE@PLT ``` After: ``` leaq .Lconst(%rip), %rdi callq _ZN7failure5fail_20haf918a97c8f7f2bfqWjE@PLT ``` Bounds check before: ``` leaq "str\"str\"(1542)"(%rip), %rax movq %rax, 8(%rsp) movq $19, 16(%rsp) leaq 8(%rsp), %rdi movl $38, %esi movl $1, %edx movl $1, %ecx callq _ZN7failure17fail_bounds_check20hf4bc3c69e96caf41RXjE@PLT ``` Bounds check after: ``` leaq .Lconst2(%rip), %rdi movl $1, %esi movl $1, %edx callq _ZN7failure17fail_bounds_check20h5267276a537a7de22XjE@PLT ``` Size before: 21277995 librustc-4e7c5e5c.s ``` text data 12554881 6089335 ``` Size after: 21247617 librustc-4e7c5e5c.so ``` text data 12518497 6095748 ```
This commit is contained in:
parent
134946d06e
commit
4db68e644e
@ -33,6 +33,7 @@
|
||||
use fmt;
|
||||
use intrinsics;
|
||||
|
||||
#[cfg(stage0)]
|
||||
#[cold] #[inline(never)] // this is the slow path, always
|
||||
#[lang="fail_"]
|
||||
fn fail_(expr: &'static str, file: &'static str, line: uint) -> ! {
|
||||
@ -43,6 +44,7 @@ fn fail_(expr: &'static str, file: &'static str, line: uint) -> ! {
|
||||
unsafe { intrinsics::abort() }
|
||||
}
|
||||
|
||||
#[cfg(stage0)]
|
||||
#[cold]
|
||||
#[lang="fail_bounds_check"]
|
||||
fn fail_bounds_check(file: &'static str, line: uint,
|
||||
@ -53,6 +55,30 @@ fn fail_bounds_check(file: &'static str, line: uint,
|
||||
unsafe { intrinsics::abort() }
|
||||
}
|
||||
|
||||
#[cfg(not(stage0))]
|
||||
#[cold] #[inline(never)] // this is the slow path, always
|
||||
#[lang="fail_"]
|
||||
fn fail_(expr_file_line: &(&'static str, &'static str, uint)) -> ! {
|
||||
let (expr, file, line) = *expr_file_line;
|
||||
let ref file_line = (file, line);
|
||||
format_args!(|args| -> () {
|
||||
begin_unwind(args, file_line);
|
||||
}, "{}", expr);
|
||||
|
||||
unsafe { intrinsics::abort() }
|
||||
}
|
||||
|
||||
#[cfg(not(stage0))]
|
||||
#[cold]
|
||||
#[lang="fail_bounds_check"]
|
||||
fn fail_bounds_check(file_line: &(&'static str, uint),
|
||||
index: uint, len: uint) -> ! {
|
||||
format_args!(|args| -> () {
|
||||
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_line: &(&'static str, uint)) -> ! {
|
||||
#[allow(ctypes)]
|
||||
|
@ -109,7 +109,7 @@ fn const_vec(cx: &CrateContext, e: &ast::Expr,
|
||||
(v, llunitty, inlineable.iter().fold(true, |a, &b| a && b))
|
||||
}
|
||||
|
||||
fn const_addr_of(cx: &CrateContext, cv: ValueRef) -> ValueRef {
|
||||
pub fn const_addr_of(cx: &CrateContext, cv: ValueRef) -> ValueRef {
|
||||
unsafe {
|
||||
let gv = "const".with_c_str(|name| {
|
||||
llvm::LLVMAddGlobal(cx.llmod, val_ty(cv).to_ref(), name)
|
||||
|
@ -20,6 +20,7 @@ use middle::trans::callee;
|
||||
use middle::trans::cleanup::CleanupMethods;
|
||||
use middle::trans::cleanup;
|
||||
use middle::trans::common::*;
|
||||
use middle::trans::consts;
|
||||
use middle::trans::datum;
|
||||
use middle::trans::debuginfo;
|
||||
use middle::trans::expr;
|
||||
@ -477,14 +478,6 @@ pub fn trans_ret<'a>(bcx: &'a Block<'a>,
|
||||
return bcx;
|
||||
}
|
||||
|
||||
fn str_slice_arg<'a>(bcx: &'a Block<'a>, s: InternedString) -> ValueRef {
|
||||
let ccx = bcx.ccx();
|
||||
let s = C_str_slice(ccx, s);
|
||||
let slot = alloca(bcx, val_ty(s), "__temp");
|
||||
Store(bcx, s, slot);
|
||||
slot
|
||||
}
|
||||
|
||||
pub fn trans_fail<'a>(
|
||||
bcx: &'a Block<'a>,
|
||||
sp: Span,
|
||||
@ -493,12 +486,14 @@ pub fn trans_fail<'a>(
|
||||
let ccx = bcx.ccx();
|
||||
let _icx = push_ctxt("trans_fail_value");
|
||||
|
||||
let v_str = str_slice_arg(bcx, fail_str);
|
||||
let v_str = C_str_slice(ccx, fail_str);
|
||||
let loc = bcx.sess().codemap().lookup_char_pos(sp.lo);
|
||||
let filename = token::intern_and_get_ident(loc.file.name.as_slice());
|
||||
let v_filename = str_slice_arg(bcx, filename);
|
||||
let v_line = loc.line as int;
|
||||
let args = vec!(v_str, v_filename, C_int(ccx, v_line));
|
||||
let filename = C_str_slice(ccx, filename);
|
||||
let line = C_int(ccx, loc.line as int);
|
||||
let expr_file_line_const = C_struct(ccx, &[v_str, filename, line], false);
|
||||
let expr_file_line = consts::const_addr_of(ccx, expr_file_line_const);
|
||||
let args = vec!(expr_file_line);
|
||||
let did = langcall(bcx, Some(sp), "", FailFnLangItem);
|
||||
let bcx = callee::trans_lang_call(bcx,
|
||||
did,
|
||||
@ -514,6 +509,7 @@ pub fn trans_fail_bounds_check<'a>(
|
||||
index: ValueRef,
|
||||
len: ValueRef)
|
||||
-> &'a Block<'a> {
|
||||
let ccx = bcx.ccx();
|
||||
let _icx = push_ctxt("trans_fail_bounds_check");
|
||||
|
||||
// Extract the file/line from the span
|
||||
@ -521,9 +517,11 @@ pub fn trans_fail_bounds_check<'a>(
|
||||
let filename = token::intern_and_get_ident(loc.file.name.as_slice());
|
||||
|
||||
// Invoke the lang item
|
||||
let filename = str_slice_arg(bcx, filename);
|
||||
let line = C_int(bcx.ccx(), loc.line as int);
|
||||
let args = vec!(filename, line, index, len);
|
||||
let filename = C_str_slice(ccx, filename);
|
||||
let line = C_int(ccx, loc.line as int);
|
||||
let file_line_const = C_struct(ccx, &[filename, line], false);
|
||||
let file_line = consts::const_addr_of(ccx, file_line_const);
|
||||
let args = vec!(file_line, index, len);
|
||||
let did = langcall(bcx, Some(sp), "", FailBoundsCheckFnLangItem);
|
||||
let bcx = callee::trans_lang_call(bcx,
|
||||
did,
|
||||
|
Loading…
Reference in New Issue
Block a user