diff options
| author | Brian Anderson <banderson@mozilla.com> | 2014-07-29 16:40:59 -0700 |
|---|---|---|
| committer | Alex Crichton <alex@alexcrichton.com> | 2014-07-31 07:30:17 -0700 |
| commit | 4db68e644e2e7bef55ed536ac77f87292260527c (patch) | |
| tree | f4f515bed4ef231d75f17fd49779816cfefbe006 | |
| parent | 134946d06e6926e087a792ac13c7f4421591afed (diff) | |
| download | rust-4db68e644e2e7bef55ed536ac77f87292260527c.tar.gz rust-4db68e644e2e7bef55ed536ac77f87292260527c.zip | |
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
```
| -rw-r--r-- | src/libcore/failure.rs | 26 | ||||
| -rw-r--r-- | src/librustc/middle/trans/consts.rs | 2 | ||||
| -rw-r--r-- | src/librustc/middle/trans/controlflow.rs | 28 |
3 files changed, 40 insertions, 16 deletions
diff --git a/src/libcore/failure.rs b/src/libcore/failure.rs index 5965603770b..6a638b5618c 100644 --- a/src/libcore/failure.rs +++ b/src/libcore/failure.rs @@ -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)] diff --git a/src/librustc/middle/trans/consts.rs b/src/librustc/middle/trans/consts.rs index 2fd468d8fda..7d546aac0cb 100644 --- a/src/librustc/middle/trans/consts.rs +++ b/src/librustc/middle/trans/consts.rs @@ -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) diff --git a/src/librustc/middle/trans/controlflow.rs b/src/librustc/middle/trans/controlflow.rs index dd8fe5e9303..2fd2e69cfc3 100644 --- a/src/librustc/middle/trans/controlflow.rs +++ b/src/librustc/middle/trans/controlflow.rs @@ -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, |
