1
Fork 0

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. //! Runtime calls emitted by the compiler.
use cast::transmute; 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 managed::raw::BoxRepr;
use str; use str;
use sys; 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: // Local Variables:
// mode: rust; // mode: rust;
// fill-column: 78; // fill-column: 78;

View file

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

View file

@ -276,10 +276,9 @@ fn trans_lit_str(bcx: block,
fn trans_uniq_or_managed_vstore(bcx: block, fn trans_uniq_or_managed_vstore(bcx: block,
heap: heap, heap: heap,
vstore_expr: @ast::expr, vstore_expr: @ast::expr,
content_expr: @ast::expr) -> DatumBlock content_expr: @ast::expr) -> DatumBlock {
{
//! //!
// //
// @[...] or ~[...] (also @"..." or ~"...") allocate boxes in the // @[...] 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); bcx.expr_to_str(vstore_expr), heap);
let _indenter = indenter(); 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 vt = vec_types_from_expr(bcx, vstore_expr);
let count = elements_required(bcx, content_expr); let count = elements_required(bcx, content_expr);