Skip to content

Commit 878a9b9

Browse files
committed
auto merge of #7004 : dotdash/rust/allocs, r=thestinger
This removes some unnecessary allocations in the lexer, the typechecker and the metadata decoder. Reduces the time spent in the parsing and typechecking passes by about 10% for me.
2 parents 4aa7719 + 2096d79 commit 878a9b9

File tree

7 files changed

+199
-192
lines changed

7 files changed

+199
-192
lines changed

src/libextra/ebml.rs

+12-7
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,14 @@ pub mod reader {
9393
pub fn get(&self, tag: uint) -> Doc {
9494
get_doc(*self, tag)
9595
}
96+
97+
pub fn as_str_slice<'a>(&'a self) -> &'a str {
98+
str::from_bytes_slice(self.data.slice(self.start, self.end))
99+
}
100+
101+
pub fn as_str(&self) -> ~str {
102+
self.as_str_slice().to_owned()
103+
}
96104
}
97105

98106
struct Res {
@@ -239,15 +247,10 @@ pub mod reader {
239247
return true;
240248
}
241249

242-
pub fn doc_data(d: Doc) -> ~[u8] {
243-
vec::slice::<u8>(*d.data, d.start, d.end).to_vec()
244-
}
245-
246250
pub fn with_doc_data<T>(d: Doc, f: &fn(x: &[u8]) -> T) -> T {
247251
f(vec::slice(*d.data, d.start, d.end))
248252
}
249253

250-
pub fn doc_as_str(d: Doc) -> ~str { str::from_bytes(doc_data(d)) }
251254

252255
pub fn doc_as_u8(d: Doc) -> u8 {
253256
assert_eq!(d.end, d.start + 1u);
@@ -294,7 +297,7 @@ pub mod reader {
294297

295298
if r_tag == (EsLabel as uint) {
296299
self.pos = r_doc.end;
297-
let str = doc_as_str(r_doc);
300+
let str = r_doc.as_str_slice();
298301
if lbl != str {
299302
fail!("Expected label %s but found %s", lbl, str);
300303
}
@@ -415,7 +418,9 @@ pub mod reader {
415418
fn read_char(&mut self) -> char {
416419
doc_as_u32(self.next_doc(EsChar)) as char
417420
}
418-
fn read_str(&mut self) -> ~str { doc_as_str(self.next_doc(EsStr)) }
421+
fn read_str(&mut self) -> ~str {
422+
self.next_doc(EsStr).as_str()
423+
}
419424

420425
// Compound types:
421426
fn read_enum<T>(&mut self,

src/librustc/metadata/decoder.rs

+42-53
Original file line numberDiff line numberDiff line change
@@ -162,19 +162,18 @@ fn item_visibility(item: ebml::Doc) -> ast::visibility {
162162

163163
fn item_method_sort(item: ebml::Doc) -> char {
164164
for reader::tagged_docs(item, tag_item_trait_method_sort) |doc| {
165-
return str::from_bytes(reader::doc_data(doc))[0] as char;
165+
return doc.as_str_slice()[0] as char;
166166
}
167167
return 'r';
168168
}
169169

170170
fn item_symbol(item: ebml::Doc) -> ~str {
171-
let sym = reader::get_doc(item, tag_items_data_item_symbol);
172-
return str::from_bytes(reader::doc_data(sym));
171+
reader::get_doc(item, tag_items_data_item_symbol).as_str()
173172
}
174173

175174
fn item_parent_item(d: ebml::Doc) -> Option<ast::def_id> {
176175
for reader::tagged_docs(d, tag_items_data_parent_item) |did| {
177-
return Some(reader::with_doc_data(did, |d| parse_def_id(d)));
176+
return Some(reader::with_doc_data(did, parse_def_id));
178177
}
179178
None
180179
}
@@ -195,8 +194,7 @@ fn item_reqd_and_translated_parent_item(cnum: ast::crate_num,
195194

196195
fn item_def_id(d: ebml::Doc, cdata: cmd) -> ast::def_id {
197196
let tagdoc = reader::get_doc(d, tag_def_id);
198-
return translate_def_id(cdata, reader::with_doc_data(tagdoc,
199-
|d| parse_def_id(d)));
197+
return translate_def_id(cdata, reader::with_doc_data(tagdoc, parse_def_id));
200198
}
201199

202200
fn each_reexport(d: ebml::Doc, f: &fn(ebml::Doc) -> bool) -> bool {
@@ -210,19 +208,19 @@ fn each_reexport(d: ebml::Doc, f: &fn(ebml::Doc) -> bool) -> bool {
210208

211209
fn variant_disr_val(d: ebml::Doc) -> Option<int> {
212210
do reader::maybe_get_doc(d, tag_disr_val).chain |val_doc| {
213-
int::parse_bytes(reader::doc_data(val_doc), 10u)
211+
do reader::with_doc_data(val_doc) |data| { int::parse_bytes(data, 10u) }
214212
}
215213
}
216214

217215
fn doc_type(doc: ebml::Doc, tcx: ty::ctxt, cdata: cmd) -> ty::t {
218216
let tp = reader::get_doc(doc, tag_items_data_item_type);
219-
parse_ty_data(tp.data, cdata.cnum, tp.start, tcx,
217+
parse_ty_data(*tp.data, cdata.cnum, tp.start, tcx,
220218
|_, did| translate_def_id(cdata, did))
221219
}
222220

223221
fn doc_method_fty(doc: ebml::Doc, tcx: ty::ctxt, cdata: cmd) -> ty::BareFnTy {
224222
let tp = reader::get_doc(doc, tag_item_method_fty);
225-
parse_bare_fn_ty_data(tp.data, cdata.cnum, tp.start, tcx,
223+
parse_bare_fn_ty_data(*tp.data, cdata.cnum, tp.start, tcx,
226224
|_, did| translate_def_id(cdata, did))
227225
}
228226

@@ -231,7 +229,7 @@ fn doc_transformed_self_ty(doc: ebml::Doc,
231229
cdata: cmd) -> Option<ty::t>
232230
{
233231
do reader::maybe_get_doc(doc, tag_item_method_transformed_self_ty).map |tp| {
234-
parse_ty_data(tp.data, cdata.cnum, tp.start, tcx,
232+
parse_ty_data(*tp.data, cdata.cnum, tp.start, tcx,
235233
|_, did| translate_def_id(cdata, did))
236234
}
237235
}
@@ -242,7 +240,7 @@ pub fn item_type(_item_id: ast::def_id, item: ebml::Doc,
242240
}
243241

244242
fn doc_trait_ref(doc: ebml::Doc, tcx: ty::ctxt, cdata: cmd) -> ty::TraitRef {
245-
parse_trait_ref_data(doc.data, cdata.cnum, doc.start, tcx,
243+
parse_trait_ref_data(*doc.data, cdata.cnum, doc.start, tcx,
246244
|_, did| translate_def_id(cdata, did))
247245
}
248246

@@ -257,7 +255,7 @@ fn item_ty_param_defs(item: ebml::Doc, tcx: ty::ctxt, cdata: cmd,
257255
let mut bounds = ~[];
258256
for reader::tagged_docs(item, tag) |p| {
259257
let bd = parse_type_param_def_data(
260-
p.data, p.start, cdata.cnum, tcx,
258+
*p.data, p.start, cdata.cnum, tcx,
261259
|_, did| translate_def_id(cdata, did));
262260
bounds.push(bd);
263261
}
@@ -282,7 +280,7 @@ fn enum_variant_ids(item: ebml::Doc, cdata: cmd) -> ~[ast::def_id] {
282280
let mut ids: ~[ast::def_id] = ~[];
283281
let v = tag_items_data_item_variant;
284282
for reader::tagged_docs(item, v) |p| {
285-
let ext = reader::with_doc_data(p, |d| parse_def_id(d));
283+
let ext = reader::with_doc_data(p, parse_def_id);
286284
ids.push(ast::def_id { crate: cdata.cnum, node: ext.node });
287285
};
288286
return ids;
@@ -297,10 +295,10 @@ fn item_path(item_doc: ebml::Doc) -> ast_map::path {
297295
let mut result = vec::with_capacity(len);
298296
for reader::docs(path_doc) |tag, elt_doc| {
299297
if tag == tag_path_elt_mod {
300-
let str = reader::doc_as_str(elt_doc);
298+
let str = elt_doc.as_str_slice();
301299
result.push(ast_map::path_mod(token::str_to_ident(str)));
302300
} else if tag == tag_path_elt_name {
303-
let str = reader::doc_as_str(elt_doc);
301+
let str = elt_doc.as_str_slice();
304302
result.push(ast_map::path_name(token::str_to_ident(str)));
305303
} else {
306304
// ignore tag_path_len element
@@ -312,12 +310,10 @@ fn item_path(item_doc: ebml::Doc) -> ast_map::path {
312310

313311
fn item_name(intr: @ident_interner, item: ebml::Doc) -> ast::ident {
314312
let name = reader::get_doc(item, tag_paths_data_name);
315-
do reader::with_doc_data(name) |data| {
316-
let string = str::from_bytes_slice(data);
317-
match intr.find_equiv(&StringRef(string)) {
318-
None => token::str_to_ident(string),
319-
Some(val) => ast::new_ident(val),
320-
}
313+
let string = name.as_str_slice();
314+
match intr.find_equiv(&StringRef(string)) {
315+
None => token::str_to_ident(string),
316+
Some(val) => ast::new_ident(val),
321317
}
322318
}
323319

@@ -413,15 +409,9 @@ pub fn get_impl_trait(cdata: cmd,
413409
tcx: ty::ctxt) -> Option<@ty::TraitRef>
414410
{
415411
let item_doc = lookup_item(id, cdata.data);
416-
let mut result = None;
417-
for reader::tagged_docs(item_doc, tag_item_trait_ref) |tp| {
418-
let trait_ref =
419-
@parse_trait_ref_data(tp.data, cdata.cnum, tp.start, tcx,
420-
|_, did| translate_def_id(cdata, did));
421-
result = Some(trait_ref);
422-
break;
423-
};
424-
result
412+
do reader::maybe_get_doc(item_doc, tag_item_trait_ref).map |&tp| {
413+
@doc_trait_ref(tp, tcx, cdata)
414+
}
425415
}
426416

427417
pub fn get_impl_method(intr: @ident_interner, cdata: cmd, id: ast::node_id,
@@ -430,7 +420,7 @@ pub fn get_impl_method(intr: @ident_interner, cdata: cmd, id: ast::node_id,
430420
let mut found = None;
431421
for reader::tagged_docs(find_item(id, items), tag_item_impl_method)
432422
|mid| {
433-
let m_did = reader::with_doc_data(mid, |d| parse_def_id(d));
423+
let m_did = reader::with_doc_data(mid, parse_def_id);
434424
if item_name(intr, find_item(m_did.node, items)) == name {
435425
found = Some(translate_def_id(cdata, m_did));
436426
}
@@ -513,19 +503,17 @@ pub fn each_path(intr: @ident_interner,
513503
let def_id_doc =
514504
reader::get_doc(reexport_doc,
515505
tag_items_data_item_reexport_def_id);
516-
let def_id =
517-
reader::with_doc_data(def_id_doc,
518-
|d| parse_def_id(d));
506+
let def_id = reader::with_doc_data(def_id_doc, parse_def_id);
519507
let def_id = translate_def_id(cdata, def_id);
520508

521509
let reexport_name_doc =
522510
reader::get_doc(reexport_doc,
523511
tag_items_data_item_reexport_name);
524-
let reexport_name = reader::doc_as_str(reexport_name_doc);
512+
let reexport_name = reexport_name_doc.as_str_slice();
525513

526514
let reexport_path;
527515
if path_is_empty {
528-
reexport_path = reexport_name;
516+
reexport_path = reexport_name.to_owned();
529517
} else {
530518
reexport_path = path + "::" + reexport_name;
531519
}
@@ -646,7 +634,7 @@ fn get_explicit_self(item: ebml::Doc) -> ast::explicit_self_ {
646634
}
647635

648636
let explicit_self_doc = reader::get_doc(item, tag_item_trait_method_explicit_self);
649-
let string = reader::doc_as_str(explicit_self_doc);
637+
let string = explicit_self_doc.as_str_slice();
650638

651639
let explicit_self_kind = string[0];
652640
match explicit_self_kind as char {
@@ -668,7 +656,7 @@ fn item_impl_methods(intr: @ident_interner, cdata: cmd, item: ebml::Doc,
668656
base_tps: uint) -> ~[@resolve::MethodInfo] {
669657
let mut rslt = ~[];
670658
for reader::tagged_docs(item, tag_item_impl_method) |doc| {
671-
let m_did = reader::with_doc_data(doc, |d| parse_def_id(d));
659+
let m_did = reader::with_doc_data(doc, parse_def_id);
672660
let mth_item = lookup_item(m_did.node, cdata.data);
673661
let explicit_self = get_explicit_self(mth_item);
674662
rslt.push(@resolve::MethodInfo {
@@ -690,7 +678,7 @@ pub fn get_impls_for_mod(intr: @ident_interner,
690678
let mod_item = lookup_item(m_id, data);
691679
let mut result = ~[];
692680
for reader::tagged_docs(mod_item, tag_mod_impl) |doc| {
693-
let did = reader::with_doc_data(doc, |d| parse_def_id(d));
681+
let did = reader::with_doc_data(doc, parse_def_id);
694682
let local_did = translate_def_id(cdata, did);
695683
debug!("(get impls for mod) getting did %? for '%?'",
696684
local_did, name);
@@ -831,7 +819,7 @@ pub fn get_type_name_if_impl(cdata: cmd,
831819
}
832820

833821
for reader::tagged_docs(item, tag_item_impl_type_basename) |doc| {
834-
return Some(token::str_to_ident(str::from_bytes(reader::doc_data(doc))));
822+
return Some(token::str_to_ident(doc.as_str_slice()));
835823
}
836824

837825
return None;
@@ -853,7 +841,7 @@ pub fn get_static_methods_if_impl(intr: @ident_interner,
853841

854842
let mut impl_method_ids = ~[];
855843
for reader::tagged_docs(item, tag_item_impl_method) |impl_method_doc| {
856-
impl_method_ids.push(parse_def_id(reader::doc_data(impl_method_doc)));
844+
impl_method_ids.push(reader::with_doc_data(impl_method_doc, parse_def_id));
857845
}
858846

859847
let mut static_impl_methods = ~[];
@@ -950,12 +938,13 @@ fn family_names_type(fam: Family) -> bool {
950938
}
951939

952940
fn read_path(d: ebml::Doc) -> (~str, uint) {
953-
let desc = reader::doc_data(d);
954-
let pos = io::u64_from_be_bytes(desc, 0u, 4u) as uint;
955-
let pathbytes = vec::slice::<u8>(desc, 4u, vec::len::<u8>(desc));
956-
let path = str::from_bytes(pathbytes);
941+
do reader::with_doc_data(d) |desc| {
942+
let pos = io::u64_from_be_bytes(desc, 0u, 4u) as uint;
943+
let pathbytes = desc.slice(4u, desc.len());
944+
let path = str::from_bytes(pathbytes);
957945

958-
(path, pos)
946+
(path, pos)
947+
}
959948
}
960949

961950
fn describe_def(items: ebml::Doc, id: ast::def_id) -> ~str {
@@ -996,21 +985,21 @@ fn get_meta_items(md: ebml::Doc) -> ~[@ast::meta_item] {
996985
let mut items: ~[@ast::meta_item] = ~[];
997986
for reader::tagged_docs(md, tag_meta_item_word) |meta_item_doc| {
998987
let nd = reader::get_doc(meta_item_doc, tag_meta_item_name);
999-
let n = str::from_bytes(reader::doc_data(nd));
988+
let n = nd.as_str();
1000989
items.push(attr::mk_word_item(@n));
1001990
};
1002991
for reader::tagged_docs(md, tag_meta_item_name_value) |meta_item_doc| {
1003992
let nd = reader::get_doc(meta_item_doc, tag_meta_item_name);
1004993
let vd = reader::get_doc(meta_item_doc, tag_meta_item_value);
1005-
let n = str::from_bytes(reader::doc_data(nd));
1006-
let v = str::from_bytes(reader::doc_data(vd));
994+
let n = nd.as_str();
995+
let v = vd.as_str();
1007996
// FIXME (#623): Should be able to decode meta_name_value variants,
1008997
// but currently the encoder just drops them
1009998
items.push(attr::mk_name_value_item_str(@n, @v));
1010999
};
10111000
for reader::tagged_docs(md, tag_meta_item_list) |meta_item_doc| {
10121001
let nd = reader::get_doc(meta_item_doc, tag_meta_item_name);
1013-
let n = str::from_bytes(reader::doc_data(nd));
1002+
let n = nd.as_str();
10141003
let subitems = get_meta_items(meta_item_doc);
10151004
items.push(attr::mk_list_item(@n, subitems));
10161005
};
@@ -1079,7 +1068,7 @@ pub fn get_crate_deps(data: @~[u8]) -> ~[crate_dep] {
10791068
let depsdoc = reader::get_doc(cratedoc, tag_crate_deps);
10801069
let mut crate_num = 1;
10811070
fn docstr(doc: ebml::Doc, tag_: uint) -> ~str {
1082-
str::from_bytes(reader::doc_data(reader::get_doc(doc, tag_)))
1071+
reader::get_doc(doc, tag_).as_str()
10831072
}
10841073
for reader::tagged_docs(depsdoc, tag_crate_dep) |depdoc| {
10851074
deps.push(crate_dep {cnum: crate_num,
@@ -1106,7 +1095,7 @@ fn list_crate_deps(data: @~[u8], out: @io::Writer) {
11061095
pub fn get_crate_hash(data: @~[u8]) -> @~str {
11071096
let cratedoc = reader::Doc(data);
11081097
let hashdoc = reader::get_doc(cratedoc, tag_crate_hash);
1109-
@str::from_bytes(reader::doc_data(hashdoc))
1098+
@hashdoc.as_str()
11101099
}
11111100

11121101
pub fn get_crate_vers(data: @~[u8]) -> @~str {
@@ -1161,7 +1150,7 @@ pub fn get_link_args_for_crate(cdata: cmd) -> ~[~str] {
11611150
let link_args = reader::get_doc(reader::Doc(cdata.data), tag_link_args);
11621151
let mut result = ~[];
11631152
for reader::tagged_docs(link_args, tag_link_args_arg) |arg_doc| {
1164-
result.push(reader::doc_as_str(arg_doc));
1153+
result.push(arg_doc.as_str());
11651154
}
11661155
result
11671156
}

0 commit comments

Comments
 (0)