librustc: Strdup unique strings instead of copying in byte by byte. Shaves 2MB off librustc at -O0.

This commit is contained in:
Patrick Walton 2013-01-29 19:59:52 -08:00
parent a47fa9b32f
commit 1b613ff9fc
3 changed files with 45 additions and 7 deletions

View File

@ -14,7 +14,7 @@
//! Runtime calls emitted by the compiler.
use cast::transmute;
use libc::{c_char, c_void, size_t, uintptr_t};
use libc::{c_char, c_uchar, c_void, size_t, uintptr_t};
use managed::raw::BoxRepr;
use str;
use sys;
@ -123,6 +123,11 @@ pub unsafe fn check_not_borrowed(a: *u8) {
}
}
#[lang="strdup_uniq"]
pub unsafe fn strdup_uniq(ptr: *c_uchar, len: uint) -> ~str {
str::raw::from_buf_len(ptr, len)
}
// Local Variables:
// mode: rust;
// fill-column: 78;

View File

@ -74,16 +74,17 @@ pub enum LangItem {
BorrowAsImmFnLangItem, // 30
ReturnToMutFnLangItem, // 31
CheckNotBorrowedFnLangItem, // 32
StrDupUniqFnLangItem, // 33
}
struct LanguageItems {
items: [ Option<def_id> * 33 ]
items: [ Option<def_id> * 34 ]
}
impl LanguageItems {
static pub fn new() -> LanguageItems {
LanguageItems {
items: [ None, ..33 ]
items: [ None, ..34 ]
}
}
@ -133,6 +134,7 @@ impl LanguageItems {
30 => "borrow_as_imm",
31 => "return_to_mut",
32 => "check_not_borrowed",
33 => "strdup_uniq",
_ => "???"
}
@ -243,6 +245,9 @@ impl LanguageItems {
pub fn check_not_borrowed_fn(&const self) -> def_id {
self.items[CheckNotBorrowedFnLangItem as uint].get()
}
pub fn strdup_uniq_fn(&const self) -> def_id {
self.items[StrDupUniqFnLangItem as uint].get()
}
}
fn LanguageItemCollector(crate: @crate,
@ -289,6 +294,7 @@ fn LanguageItemCollector(crate: @crate,
item_refs.insert(~"return_to_mut", ReturnToMutFnLangItem as uint);
item_refs.insert(~"check_not_borrowed",
CheckNotBorrowedFnLangItem as uint);
item_refs.insert(~"strdup_uniq", StrDupUniqFnLangItem as uint);
LanguageItemCollector {
crate: crate,

View File

@ -276,10 +276,9 @@ fn trans_lit_str(bcx: block,
fn trans_uniq_or_managed_vstore(bcx: block,
heap: heap,
vstore_expr: @ast::expr,
content_expr: @ast::expr) -> DatumBlock
{
heap: heap,
vstore_expr: @ast::expr,
content_expr: @ast::expr) -> DatumBlock {
//!
//
// @[...] or ~[...] (also @"..." or ~"...") allocate boxes in the
@ -289,6 +288,34 @@ fn trans_uniq_or_managed_vstore(bcx: block,
bcx.expr_to_str(vstore_expr), heap);
let _indenter = indenter();
// Handle ~"".
match heap {
heap_exchange => {
match content_expr.node {
ast::expr_lit(@ast::spanned {
node: ast::lit_str(s), _
}) => {
let llptrval = C_cstr(bcx.ccx(), copy *s);
let llptrval = PointerCast(bcx, llptrval, T_ptr(T_i8()));
let llsizeval = C_uint(bcx.ccx(), s.len());
let typ = ty::mk_estr(bcx.tcx(), ty::vstore_uniq);
let lldestval = datum::scratch_datum(bcx, typ, false);
let bcx = callee::trans_rtcall_or_lang_call(
bcx,
bcx.tcx().lang_items.strdup_uniq_fn(),
~[ llptrval, llsizeval ],
expr::SaveIn(lldestval.to_ref_llval(bcx)));
return datum::DatumBlock {
bcx: bcx,
datum: lldestval
};
}
_ => {}
}
}
heap_shared => {}
}
let vt = vec_types_from_expr(bcx, vstore_expr);
let count = elements_required(bcx, content_expr);