Skip to content

Commit 2096d79

Browse files
committed
Avoid unnecessary allocations in the metadata decoder
1 parent 29e5aa0 commit 2096d79

File tree

2 files changed

+40
-39
lines changed

2 files changed

+40
-39
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

+28-32
Original file line numberDiff line numberDiff line change
@@ -162,14 +162,13 @@ 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> {
@@ -209,7 +208,7 @@ fn each_reexport(d: ebml::Doc, f: &fn(ebml::Doc) -> bool) -> bool {
209208

210209
fn variant_disr_val(d: ebml::Doc) -> Option<int> {
211210
do reader::maybe_get_doc(d, tag_disr_val).chain |val_doc| {
212-
int::parse_bytes(reader::doc_data(val_doc), 10u)
211+
do reader::with_doc_data(val_doc) |data| { int::parse_bytes(data, 10u) }
213212
}
214213
}
215214

@@ -296,10 +295,10 @@ fn item_path(item_doc: ebml::Doc) -> ast_map::path {
296295
let mut result = vec::with_capacity(len);
297296
for reader::docs(path_doc) |tag, elt_doc| {
298297
if tag == tag_path_elt_mod {
299-
let str = reader::doc_as_str(elt_doc);
298+
let str = elt_doc.as_str_slice();
300299
result.push(ast_map::path_mod(token::str_to_ident(str)));
301300
} else if tag == tag_path_elt_name {
302-
let str = reader::doc_as_str(elt_doc);
301+
let str = elt_doc.as_str_slice();
303302
result.push(ast_map::path_name(token::str_to_ident(str)));
304303
} else {
305304
// ignore tag_path_len element
@@ -311,12 +310,10 @@ fn item_path(item_doc: ebml::Doc) -> ast_map::path {
311310

312311
fn item_name(intr: @ident_interner, item: ebml::Doc) -> ast::ident {
313312
let name = reader::get_doc(item, tag_paths_data_name);
314-
do reader::with_doc_data(name) |data| {
315-
let string = str::from_bytes_slice(data);
316-
match intr.find_equiv(&StringRef(string)) {
317-
None => token::str_to_ident(string),
318-
Some(val) => ast::new_ident(val),
319-
}
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),
320317
}
321318
}
322319

@@ -506,19 +503,17 @@ pub fn each_path(intr: @ident_interner,
506503
let def_id_doc =
507504
reader::get_doc(reexport_doc,
508505
tag_items_data_item_reexport_def_id);
509-
let def_id =
510-
reader::with_doc_data(def_id_doc,
511-
|d| parse_def_id(d));
506+
let def_id = reader::with_doc_data(def_id_doc, parse_def_id);
512507
let def_id = translate_def_id(cdata, def_id);
513508

514509
let reexport_name_doc =
515510
reader::get_doc(reexport_doc,
516511
tag_items_data_item_reexport_name);
517-
let reexport_name = reader::doc_as_str(reexport_name_doc);
512+
let reexport_name = reexport_name_doc.as_str_slice();
518513

519514
let reexport_path;
520515
if path_is_empty {
521-
reexport_path = reexport_name;
516+
reexport_path = reexport_name.to_owned();
522517
} else {
523518
reexport_path = path + "::" + reexport_name;
524519
}
@@ -639,7 +634,7 @@ fn get_explicit_self(item: ebml::Doc) -> ast::explicit_self_ {
639634
}
640635

641636
let explicit_self_doc = reader::get_doc(item, tag_item_trait_method_explicit_self);
642-
let string = reader::doc_as_str(explicit_self_doc);
637+
let string = explicit_self_doc.as_str_slice();
643638

644639
let explicit_self_kind = string[0];
645640
match explicit_self_kind as char {
@@ -824,7 +819,7 @@ pub fn get_type_name_if_impl(cdata: cmd,
824819
}
825820

826821
for reader::tagged_docs(item, tag_item_impl_type_basename) |doc| {
827-
return Some(token::str_to_ident(str::from_bytes(reader::doc_data(doc))));
822+
return Some(token::str_to_ident(doc.as_str_slice()));
828823
}
829824

830825
return None;
@@ -846,7 +841,7 @@ pub fn get_static_methods_if_impl(intr: @ident_interner,
846841

847842
let mut impl_method_ids = ~[];
848843
for reader::tagged_docs(item, tag_item_impl_method) |impl_method_doc| {
849-
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));
850845
}
851846

852847
let mut static_impl_methods = ~[];
@@ -943,12 +938,13 @@ fn family_names_type(fam: Family) -> bool {
943938
}
944939

945940
fn read_path(d: ebml::Doc) -> (~str, uint) {
946-
let desc = reader::doc_data(d);
947-
let pos = io::u64_from_be_bytes(desc, 0u, 4u) as uint;
948-
let pathbytes = vec::slice::<u8>(desc, 4u, vec::len::<u8>(desc));
949-
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);
950945

951-
(path, pos)
946+
(path, pos)
947+
}
952948
}
953949

954950
fn describe_def(items: ebml::Doc, id: ast::def_id) -> ~str {
@@ -989,21 +985,21 @@ fn get_meta_items(md: ebml::Doc) -> ~[@ast::meta_item] {
989985
let mut items: ~[@ast::meta_item] = ~[];
990986
for reader::tagged_docs(md, tag_meta_item_word) |meta_item_doc| {
991987
let nd = reader::get_doc(meta_item_doc, tag_meta_item_name);
992-
let n = str::from_bytes(reader::doc_data(nd));
988+
let n = nd.as_str();
993989
items.push(attr::mk_word_item(@n));
994990
};
995991
for reader::tagged_docs(md, tag_meta_item_name_value) |meta_item_doc| {
996992
let nd = reader::get_doc(meta_item_doc, tag_meta_item_name);
997993
let vd = reader::get_doc(meta_item_doc, tag_meta_item_value);
998-
let n = str::from_bytes(reader::doc_data(nd));
999-
let v = str::from_bytes(reader::doc_data(vd));
994+
let n = nd.as_str();
995+
let v = vd.as_str();
1000996
// FIXME (#623): Should be able to decode meta_name_value variants,
1001997
// but currently the encoder just drops them
1002998
items.push(attr::mk_name_value_item_str(@n, @v));
1003999
};
10041000
for reader::tagged_docs(md, tag_meta_item_list) |meta_item_doc| {
10051001
let nd = reader::get_doc(meta_item_doc, tag_meta_item_name);
1006-
let n = str::from_bytes(reader::doc_data(nd));
1002+
let n = nd.as_str();
10071003
let subitems = get_meta_items(meta_item_doc);
10081004
items.push(attr::mk_list_item(@n, subitems));
10091005
};
@@ -1072,7 +1068,7 @@ pub fn get_crate_deps(data: @~[u8]) -> ~[crate_dep] {
10721068
let depsdoc = reader::get_doc(cratedoc, tag_crate_deps);
10731069
let mut crate_num = 1;
10741070
fn docstr(doc: ebml::Doc, tag_: uint) -> ~str {
1075-
str::from_bytes(reader::doc_data(reader::get_doc(doc, tag_)))
1071+
reader::get_doc(doc, tag_).as_str()
10761072
}
10771073
for reader::tagged_docs(depsdoc, tag_crate_dep) |depdoc| {
10781074
deps.push(crate_dep {cnum: crate_num,
@@ -1099,7 +1095,7 @@ fn list_crate_deps(data: @~[u8], out: @io::Writer) {
10991095
pub fn get_crate_hash(data: @~[u8]) -> @~str {
11001096
let cratedoc = reader::Doc(data);
11011097
let hashdoc = reader::get_doc(cratedoc, tag_crate_hash);
1102-
@str::from_bytes(reader::doc_data(hashdoc))
1098+
@hashdoc.as_str()
11031099
}
11041100

11051101
pub fn get_crate_vers(data: @~[u8]) -> @~str {
@@ -1154,7 +1150,7 @@ pub fn get_link_args_for_crate(cdata: cmd) -> ~[~str] {
11541150
let link_args = reader::get_doc(reader::Doc(cdata.data), tag_link_args);
11551151
let mut result = ~[];
11561152
for reader::tagged_docs(link_args, tag_link_args_arg) |arg_doc| {
1157-
result.push(reader::doc_as_str(arg_doc));
1153+
result.push(arg_doc.as_str());
11581154
}
11591155
result
11601156
}

0 commit comments

Comments
 (0)