From 2096d79626029bfbfd7d42668be4705390a2c4ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Steinbrink?= Date: Sat, 8 Jun 2013 02:37:17 +0200 Subject: [PATCH] Avoid unnecessary allocations in the metadata decoder --- src/libextra/ebml.rs | 19 ++++++---- src/librustc/metadata/decoder.rs | 60 +++++++++++++++----------------- 2 files changed, 40 insertions(+), 39 deletions(-) diff --git a/src/libextra/ebml.rs b/src/libextra/ebml.rs index 47b0b4f6c97..09e6a849f98 100644 --- a/src/libextra/ebml.rs +++ b/src/libextra/ebml.rs @@ -93,6 +93,14 @@ pub mod reader { pub fn get(&self, tag: uint) -> Doc { get_doc(*self, tag) } + + pub fn as_str_slice<'a>(&'a self) -> &'a str { + str::from_bytes_slice(self.data.slice(self.start, self.end)) + } + + pub fn as_str(&self) -> ~str { + self.as_str_slice().to_owned() + } } struct Res { @@ -239,15 +247,10 @@ pub mod reader { return true; } - pub fn doc_data(d: Doc) -> ~[u8] { - vec::slice::(*d.data, d.start, d.end).to_vec() - } - pub fn with_doc_data(d: Doc, f: &fn(x: &[u8]) -> T) -> T { f(vec::slice(*d.data, d.start, d.end)) } - pub fn doc_as_str(d: Doc) -> ~str { str::from_bytes(doc_data(d)) } pub fn doc_as_u8(d: Doc) -> u8 { assert_eq!(d.end, d.start + 1u); @@ -294,7 +297,7 @@ pub mod reader { if r_tag == (EsLabel as uint) { self.pos = r_doc.end; - let str = doc_as_str(r_doc); + let str = r_doc.as_str_slice(); if lbl != str { fail!("Expected label %s but found %s", lbl, str); } @@ -415,7 +418,9 @@ pub mod reader { fn read_char(&mut self) -> char { doc_as_u32(self.next_doc(EsChar)) as char } - fn read_str(&mut self) -> ~str { doc_as_str(self.next_doc(EsStr)) } + fn read_str(&mut self) -> ~str { + self.next_doc(EsStr).as_str() + } // Compound types: fn read_enum(&mut self, diff --git a/src/librustc/metadata/decoder.rs b/src/librustc/metadata/decoder.rs index b544b94d1c2..81c1560f18b 100644 --- a/src/librustc/metadata/decoder.rs +++ b/src/librustc/metadata/decoder.rs @@ -162,14 +162,13 @@ fn item_visibility(item: ebml::Doc) -> ast::visibility { fn item_method_sort(item: ebml::Doc) -> char { for reader::tagged_docs(item, tag_item_trait_method_sort) |doc| { - return str::from_bytes(reader::doc_data(doc))[0] as char; + return doc.as_str_slice()[0] as char; } return 'r'; } fn item_symbol(item: ebml::Doc) -> ~str { - let sym = reader::get_doc(item, tag_items_data_item_symbol); - return str::from_bytes(reader::doc_data(sym)); + reader::get_doc(item, tag_items_data_item_symbol).as_str() } fn item_parent_item(d: ebml::Doc) -> Option { @@ -209,7 +208,7 @@ fn each_reexport(d: ebml::Doc, f: &fn(ebml::Doc) -> bool) -> bool { fn variant_disr_val(d: ebml::Doc) -> Option { do reader::maybe_get_doc(d, tag_disr_val).chain |val_doc| { - int::parse_bytes(reader::doc_data(val_doc), 10u) + do reader::with_doc_data(val_doc) |data| { int::parse_bytes(data, 10u) } } } @@ -296,10 +295,10 @@ fn item_path(item_doc: ebml::Doc) -> ast_map::path { let mut result = vec::with_capacity(len); for reader::docs(path_doc) |tag, elt_doc| { if tag == tag_path_elt_mod { - let str = reader::doc_as_str(elt_doc); + let str = elt_doc.as_str_slice(); result.push(ast_map::path_mod(token::str_to_ident(str))); } else if tag == tag_path_elt_name { - let str = reader::doc_as_str(elt_doc); + let str = elt_doc.as_str_slice(); result.push(ast_map::path_name(token::str_to_ident(str))); } else { // ignore tag_path_len element @@ -311,12 +310,10 @@ fn item_path(item_doc: ebml::Doc) -> ast_map::path { fn item_name(intr: @ident_interner, item: ebml::Doc) -> ast::ident { let name = reader::get_doc(item, tag_paths_data_name); - do reader::with_doc_data(name) |data| { - let string = str::from_bytes_slice(data); - match intr.find_equiv(&StringRef(string)) { - None => token::str_to_ident(string), - Some(val) => ast::new_ident(val), - } + let string = name.as_str_slice(); + match intr.find_equiv(&StringRef(string)) { + None => token::str_to_ident(string), + Some(val) => ast::new_ident(val), } } @@ -506,19 +503,17 @@ pub fn each_path(intr: @ident_interner, let def_id_doc = reader::get_doc(reexport_doc, tag_items_data_item_reexport_def_id); - let def_id = - reader::with_doc_data(def_id_doc, - |d| parse_def_id(d)); + let def_id = reader::with_doc_data(def_id_doc, parse_def_id); let def_id = translate_def_id(cdata, def_id); let reexport_name_doc = reader::get_doc(reexport_doc, tag_items_data_item_reexport_name); - let reexport_name = reader::doc_as_str(reexport_name_doc); + let reexport_name = reexport_name_doc.as_str_slice(); let reexport_path; if path_is_empty { - reexport_path = reexport_name; + reexport_path = reexport_name.to_owned(); } else { reexport_path = path + "::" + reexport_name; } @@ -639,7 +634,7 @@ fn get_explicit_self(item: ebml::Doc) -> ast::explicit_self_ { } let explicit_self_doc = reader::get_doc(item, tag_item_trait_method_explicit_self); - let string = reader::doc_as_str(explicit_self_doc); + let string = explicit_self_doc.as_str_slice(); let explicit_self_kind = string[0]; match explicit_self_kind as char { @@ -824,7 +819,7 @@ pub fn get_type_name_if_impl(cdata: cmd, } for reader::tagged_docs(item, tag_item_impl_type_basename) |doc| { - return Some(token::str_to_ident(str::from_bytes(reader::doc_data(doc)))); + return Some(token::str_to_ident(doc.as_str_slice())); } return None; @@ -846,7 +841,7 @@ pub fn get_static_methods_if_impl(intr: @ident_interner, let mut impl_method_ids = ~[]; for reader::tagged_docs(item, tag_item_impl_method) |impl_method_doc| { - impl_method_ids.push(parse_def_id(reader::doc_data(impl_method_doc))); + impl_method_ids.push(reader::with_doc_data(impl_method_doc, parse_def_id)); } let mut static_impl_methods = ~[]; @@ -943,12 +938,13 @@ fn family_names_type(fam: Family) -> bool { } fn read_path(d: ebml::Doc) -> (~str, uint) { - let desc = reader::doc_data(d); - let pos = io::u64_from_be_bytes(desc, 0u, 4u) as uint; - let pathbytes = vec::slice::(desc, 4u, vec::len::(desc)); - let path = str::from_bytes(pathbytes); + do reader::with_doc_data(d) |desc| { + let pos = io::u64_from_be_bytes(desc, 0u, 4u) as uint; + let pathbytes = desc.slice(4u, desc.len()); + let path = str::from_bytes(pathbytes); - (path, pos) + (path, pos) + } } 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] { let mut items: ~[@ast::meta_item] = ~[]; for reader::tagged_docs(md, tag_meta_item_word) |meta_item_doc| { let nd = reader::get_doc(meta_item_doc, tag_meta_item_name); - let n = str::from_bytes(reader::doc_data(nd)); + let n = nd.as_str(); items.push(attr::mk_word_item(@n)); }; for reader::tagged_docs(md, tag_meta_item_name_value) |meta_item_doc| { let nd = reader::get_doc(meta_item_doc, tag_meta_item_name); let vd = reader::get_doc(meta_item_doc, tag_meta_item_value); - let n = str::from_bytes(reader::doc_data(nd)); - let v = str::from_bytes(reader::doc_data(vd)); + let n = nd.as_str(); + let v = vd.as_str(); // FIXME (#623): Should be able to decode meta_name_value variants, // but currently the encoder just drops them items.push(attr::mk_name_value_item_str(@n, @v)); }; for reader::tagged_docs(md, tag_meta_item_list) |meta_item_doc| { let nd = reader::get_doc(meta_item_doc, tag_meta_item_name); - let n = str::from_bytes(reader::doc_data(nd)); + let n = nd.as_str(); let subitems = get_meta_items(meta_item_doc); items.push(attr::mk_list_item(@n, subitems)); }; @@ -1072,7 +1068,7 @@ pub fn get_crate_deps(data: @~[u8]) -> ~[crate_dep] { let depsdoc = reader::get_doc(cratedoc, tag_crate_deps); let mut crate_num = 1; fn docstr(doc: ebml::Doc, tag_: uint) -> ~str { - str::from_bytes(reader::doc_data(reader::get_doc(doc, tag_))) + reader::get_doc(doc, tag_).as_str() } for reader::tagged_docs(depsdoc, tag_crate_dep) |depdoc| { deps.push(crate_dep {cnum: crate_num, @@ -1099,7 +1095,7 @@ fn list_crate_deps(data: @~[u8], out: @io::Writer) { pub fn get_crate_hash(data: @~[u8]) -> @~str { let cratedoc = reader::Doc(data); let hashdoc = reader::get_doc(cratedoc, tag_crate_hash); - @str::from_bytes(reader::doc_data(hashdoc)) + @hashdoc.as_str() } pub fn get_crate_vers(data: @~[u8]) -> @~str { @@ -1154,7 +1150,7 @@ pub fn get_link_args_for_crate(cdata: cmd) -> ~[~str] { let link_args = reader::get_doc(reader::Doc(cdata.data), tag_link_args); let mut result = ~[]; for reader::tagged_docs(link_args, tag_link_args_arg) |arg_doc| { - result.push(reader::doc_as_str(arg_doc)); + result.push(arg_doc.as_str()); } result }