From 67e60bf283fbfb4b6b93b41e3e45e9fba835386c Mon Sep 17 00:00:00 2001 From: Ariel Ben-Yehuda Date: Thu, 17 Sep 2015 12:30:04 +0300 Subject: [PATCH 01/10] remove unneeded tags from metadata stage1 release rlib sizes: 580890 liballoc-bb943c5a.rlib 1425558 liballoc_jemalloc-bb943c5a.rlib 10514 liballoc_system-bb943c5a.rlib 157192 libarena-bb943c5a.rlib 4316234 libcollections-bb943c5a.rlib 19580128 libcore-bb943c5a.rlib 199498 libflate-bb943c5a.rlib 249328 libfmt_macros-bb943c5a.rlib 560406 libgetopts-bb943c5a.rlib 233620 libgraphviz-bb943c5a.rlib 442964 liblibc-bb943c5a.rlib 190178 liblog-bb943c5a.rlib 778488 librand-bb943c5a.rlib 621972 librbml-bb943c5a.rlib 1415040 librustc_back-bb943c5a.rlib 38849082 librustc-bb943c5a.rlib 12862 librustc_bitflags-bb943c5a.rlib 2331690 librustc_borrowck-bb943c5a.rlib 616880 librustc_data_structures-bb943c5a.rlib 9386582 librustc_driver-bb943c5a.rlib 9600440 librustc_front-bb943c5a.rlib 1615058 librustc_lint-bb943c5a.rlib 79218480 librustc_llvm-bb943c5a.rlib 5020974 librustc_mir-bb943c5a.rlib 3535448 librustc_platform_intrinsics-bb943c5a.rlib 603640 librustc_privacy-bb943c5a.rlib 3163628 librustc_resolve-bb943c5a.rlib 14326646 librustc_trans-bb943c5a.rlib 12033174 librustc_typeck-bb943c5a.rlib 1838202 librustc_unicode-bb943c5a.rlib 15611582 librustdoc-bb943c5a.rlib 3056280 libserialize-bb943c5a.rlib 8954312 libstd-bb943c5a.rlib 30906736 libsyntax-bb943c5a.rlib 925480 libterm-bb943c5a.rlib 1377952 libtest-bb943c5a.rlib --- src/librustc/metadata/common.rs | 26 +++++++---------------- src/librustc/metadata/csearch.rs | 6 ------ src/librustc/metadata/decoder.rs | 12 ----------- src/librustc/metadata/encoder.rs | 36 ++++---------------------------- 4 files changed, 11 insertions(+), 69 deletions(-) diff --git a/src/librustc/metadata/common.rs b/src/librustc/metadata/common.rs index a6cbb4ec50490..5523c2840987a 100644 --- a/src/librustc/metadata/common.rs +++ b/src/librustc/metadata/common.rs @@ -74,8 +74,6 @@ pub const tag_crate_dep_crate_name: usize = 0x36; pub const tag_crate_dep_hash: usize = 0x37; pub const tag_crate_dep_explicitly_linked: usize = 0x38; // top-level only -pub const tag_mod_impl: usize = 0x39; - pub const tag_item_trait_item: usize = 0x3a; pub const tag_item_trait_ref: usize = 0x3b; @@ -89,7 +87,6 @@ pub const tag_path_len: usize = 0x3e; pub const tag_path_elem_mod: usize = 0x3f; pub const tag_path_elem_name: usize = 0x40; pub const tag_item_field: usize = 0x41; -pub const tag_item_field_origin: usize = 0x42; pub const tag_item_variances: usize = 0x43; /* @@ -119,8 +116,7 @@ enum_from_u32! { tag_tree = 0x51, - tag_id_range = 0x52, - + // GAP 0x52 tag_table = 0x53, // GAP 0x54, 0x55 tag_table_def = 0x56, @@ -129,19 +125,15 @@ enum_from_u32! { tag_table_freevars = 0x59, tag_table_tcache = 0x5a, tag_table_param_defs = 0x5b, - tag_table_mutbl = 0x5c, - tag_table_last_use = 0x5d, - tag_table_spill = 0x5e, + // GAP 0x5c, 0x5d, 0x5e tag_table_method_map = 0x5f, - tag_table_vtable_map = 0x60, + // GAP 0x60 tag_table_adjustments = 0x61, - tag_table_moves_map = 0x62, - tag_table_capture_map = 0x63, + // GAP 0x62, 0x63 tag_table_closure_tys = 0x64, tag_table_closure_kinds = 0x65, tag_table_upvar_capture_map = 0x66, - tag_table_capture_modes = 0x67, - // GAP 0x68 + // GAP 0x67, 0x68 tag_table_const_qualif = 0x69, tag_table_cast_kinds = 0x6a, } @@ -149,10 +141,6 @@ enum_from_u32! { pub const tag_item_trait_item_sort: usize = 0x70; -pub const tag_item_trait_parent_sort: usize = 0x71; - -pub const tag_item_impl_type_basename: usize = 0x72; - pub const tag_crate_triple: usize = 0x105; // top-level only pub const tag_dylib_dependency_formats: usize = 0x106; // top-level only @@ -173,7 +161,7 @@ pub const tag_lang_items_missing: usize = 0x76; pub const tag_item_unnamed_field: usize = 0x77; pub const tag_items_data_item_visibility: usize = 0x78; -pub const tag_item_method_tps: usize = 0x79; +// GAP 0x79 pub const tag_item_method_fty: usize = 0x7a; pub const tag_mod_child: usize = 0x7b; @@ -181,7 +169,7 @@ pub const tag_misc_info: usize = 0x108; // top-level only pub const tag_misc_info_crate_items: usize = 0x7c; // GAP 0x7d -pub const tag_item_impl_vtables: usize = 0x7e; +// GAP 0x7e pub const tag_impls: usize = 0x109; // top-level only pub const tag_impls_impl: usize = 0x7f; diff --git a/src/librustc/metadata/csearch.rs b/src/librustc/metadata/csearch.rs index 88d73b3feb390..dd6250d92aa62 100644 --- a/src/librustc/metadata/csearch.rs +++ b/src/librustc/metadata/csearch.rs @@ -171,12 +171,6 @@ pub fn get_associated_consts<'tcx>(tcx: &ty::ctxt<'tcx>, def: DefId) decoder::get_associated_consts(cstore.intr.clone(), &*cdata, def.node, tcx) } -pub fn get_type_name_if_impl(cstore: &cstore::CStore, def: DefId) - -> Option { - let cdata = cstore.get_crate_data(def.krate); - decoder::get_type_name_if_impl(&*cdata, def.node) -} - pub fn get_methods_if_impl(cstore: &cstore::CStore, def: DefId) -> Option > { diff --git a/src/librustc/metadata/decoder.rs b/src/librustc/metadata/decoder.rs index 77863ee3c87a2..be2fe7ddf7cd2 100644 --- a/src/librustc/metadata/decoder.rs +++ b/src/librustc/metadata/decoder.rs @@ -979,18 +979,6 @@ pub fn get_associated_consts<'tcx>(intr: Rc, }).collect() } -pub fn get_type_name_if_impl(cdata: Cmd, - node_id: ast::NodeId) -> Option { - let item = cdata.lookup_item(node_id); - if item_family(item) != Impl { - return None; - } - - reader::tagged_docs(item, tag_item_impl_type_basename).nth(0).map(|doc| { - token::intern(doc.as_str_slice()) - }) -} - pub fn get_methods_if_impl(intr: Rc, cdata: Cmd, node_id: ast::NodeId) diff --git a/src/librustc/metadata/encoder.rs b/src/librustc/metadata/encoder.rs index 0d83103e0bb49..4da94213a30ed 100644 --- a/src/librustc/metadata/encoder.rs +++ b/src/librustc/metadata/encoder.rs @@ -78,10 +78,6 @@ fn encode_name(rbml_w: &mut Encoder, name: Name) { rbml_w.wr_tagged_str(tag_paths_data_name, &name.as_str()); } -fn encode_impl_type_basename(rbml_w: &mut Encoder, name: Name) { - rbml_w.wr_tagged_str(tag_item_impl_type_basename, &name.as_str()); -} - fn encode_def_id(rbml_w: &mut Encoder, id: DefId) { rbml_w.wr_tagged_u64(tag_def_id, def_to_u64(id)); } @@ -253,8 +249,7 @@ fn encode_parent_item(rbml_w: &mut Encoder, id: DefId) { } fn encode_struct_fields(rbml_w: &mut Encoder, - variant: ty::VariantDef, - origin: DefId) { + variant: ty::VariantDef) { for f in &variant.fields { if f.name == special_idents::unnamed_field.name { rbml_w.start_tag(tag_item_unnamed_field); @@ -264,7 +259,6 @@ fn encode_struct_fields(rbml_w: &mut Encoder, } encode_struct_field_family(rbml_w, f.vis); encode_def_id(rbml_w, f.did); - rbml_w.wr_tagged_u64(tag_item_field_origin, def_to_u64(origin)); rbml_w.end_tag(); } } @@ -311,7 +305,7 @@ fn encode_enum_variant_info(ecx: &EncodeContext, let stab = stability::lookup(ecx.tcx, vid); encode_stability(rbml_w, stab); - encode_struct_fields(rbml_w, variant, vid); + encode_struct_fields(rbml_w, variant); let specified_disr_val = variant.disr_val; if specified_disr_val != disr_val { @@ -518,15 +512,6 @@ fn encode_info_for_mod(ecx: &EncodeContext, def_to_u64(DefId::local(auxiliary_node_id))); true }); - - if let hir::ItemImpl(..) = item.node { - let (name, did) = (item.name, item.id); - debug!("(encoding info for module) ... encoding impl {} ({}/{})", - name, - did, ecx.tcx.map.node_to_string(did)); - - rbml_w.wr_tagged_u64(tag_mod_impl, def_to_u64(DefId::local(did))); - } } encode_path(rbml_w, path.clone()); @@ -605,10 +590,6 @@ fn encode_item_sort(rbml_w: &mut Encoder, sort: char) { rbml_w.wr_tagged_u8(tag_item_trait_item_sort, sort as u8); } -fn encode_parent_sort(rbml_w: &mut Encoder, sort: char) { - rbml_w.wr_tagged_u8(tag_item_trait_parent_sort, sort as u8); -} - fn encode_field<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>, rbml_w: &mut Encoder, field: ty::FieldDef<'tcx>, @@ -1147,7 +1128,7 @@ fn encode_info_for_item(ecx: &EncodeContext, /* Encode def_ids for each field and method for methods, write all the stuff get_trait_method needs to know*/ - encode_struct_fields(rbml_w, variant, def_id); + encode_struct_fields(rbml_w, variant); encode_inlined_item(ecx, rbml_w, InlinedItemRef::Item(item)); @@ -1177,7 +1158,7 @@ fn encode_info_for_item(ecx: &EncodeContext, encode_trait_ref(rbml_w, ecx, trait_ref, tag_item_trait_ref); rbml_w.end_tag(); } - hir::ItemImpl(unsafety, polarity, _, _, ref ty, ref ast_items) => { + hir::ItemImpl(unsafety, polarity, _, _, _, ref ast_items) => { // We need to encode information about the default methods we // have inherited, so we drive this based on the impl structure. let impl_items = tcx.impl_items.borrow(); @@ -1202,13 +1183,6 @@ fn encode_info_for_item(ecx: &EncodeContext, None => {} } - match ty.node { - hir::TyPath(None, ref path) if path.segments.len() == 1 => { - let name = path.segments.last().unwrap().identifier.name; - encode_impl_type_basename(rbml_w, name); - } - _ => {} - } for &item_def_id in items { rbml_w.start_tag(tag_item_impl_item); match item_def_id { @@ -1412,8 +1386,6 @@ fn encode_info_for_item(ecx: &EncodeContext, } } - encode_parent_sort(rbml_w, 't'); - let trait_item = &*ms[i]; encode_attributes(rbml_w, &trait_item.attrs); match trait_item.node { From d98165941d85de37007a0851d268c13169c3fa45 Mon Sep 17 00:00:00 2001 From: Ariel Ben-Yehuda Date: Thu, 17 Sep 2015 16:04:18 +0300 Subject: [PATCH 02/10] add a cross-reference index it still does not *do* anything --- src/librustc/metadata/common.rs | 6 +- src/librustc/metadata/creader.rs | 1 + src/librustc/metadata/cstore.rs | 2 + src/librustc/metadata/decoder.rs | 5 + src/librustc/metadata/encoder.rs | 203 ++++++++++++++++--------------- src/librustc/metadata/index.rs | 37 +++++- 6 files changed, 149 insertions(+), 105 deletions(-) diff --git a/src/librustc/metadata/common.rs b/src/librustc/metadata/common.rs index 5523c2840987a..30f0485d7d174 100644 --- a/src/librustc/metadata/common.rs +++ b/src/librustc/metadata/common.rs @@ -43,9 +43,11 @@ pub const tag_items_data_parent_item: usize = 0x28; pub const tag_items_data_item_is_tuple_struct_ctor: usize = 0x29; -pub const tag_index: usize = 0x2a; +pub const tag_index: usize = 0x110; // top-level only +pub const tag_xref_index: usize = 0x111; // top-level only +pub const tag_xref_data: usize = 0x112; // top-level only -// GAP 0x2b, 0x2c, 0x2d, 0x2e +// GAP 0x2a, 0x2b, 0x2c, 0x2d, 0x2e pub const tag_meta_item_name_value: usize = 0x2f; diff --git a/src/librustc/metadata/creader.rs b/src/librustc/metadata/creader.rs index 04f164c296d2e..c40eb56917d24 100644 --- a/src/librustc/metadata/creader.rs +++ b/src/librustc/metadata/creader.rs @@ -326,6 +326,7 @@ impl<'a> CrateReader<'a> { name: name.to_string(), local_path: RefCell::new(SmallVector::zero()), index: decoder::load_index(metadata.as_slice()), + xref_index: decoder::load_xrefs(metadata.as_slice()), data: metadata, cnum_map: RefCell::new(cnum_map), cnum: cnum, diff --git a/src/librustc/metadata/cstore.rs b/src/librustc/metadata/cstore.rs index 5f60fa8ff40e3..9ffe8cd1d111d 100644 --- a/src/librustc/metadata/cstore.rs +++ b/src/librustc/metadata/cstore.rs @@ -65,7 +65,9 @@ pub struct crate_metadata { pub codemap_import_info: RefCell>, pub span: codemap::Span, pub staged_api: bool, + pub index: index::Index, + pub xref_index: index::DenseIndex, /// Flag if this crate is required by an rlib version of this crate, or in /// other words whether it was explicitly linked to. An example of a crate diff --git a/src/librustc/metadata/decoder.rs b/src/librustc/metadata/decoder.rs index be2fe7ddf7cd2..64858d99b7e8a 100644 --- a/src/librustc/metadata/decoder.rs +++ b/src/librustc/metadata/decoder.rs @@ -82,6 +82,11 @@ pub fn crate_rustc_version(data: &[u8]) -> Option { reader::maybe_get_doc(doc, tag_rustc_version).map(|s| s.as_str()) } +pub fn load_xrefs(data: &[u8]) -> index::DenseIndex { + let index = reader::get_doc(rbml::Doc::new(data), tag_xref_index); + index::DenseIndex::from_buf(index.data, index.start, index.end) +} + #[derive(Debug, PartialEq)] enum Family { ImmStatic, // c diff --git a/src/librustc/metadata/encoder.rs b/src/librustc/metadata/encoder.rs index 4da94213a30ed..d5ef8b962c846 100644 --- a/src/librustc/metadata/encoder.rs +++ b/src/librustc/metadata/encoder.rs @@ -74,6 +74,24 @@ pub struct EncodeContext<'a, 'tcx: 'a> { pub reachable: &'a NodeSet, } +/// "interned" entries referenced by id +#[derive(PartialEq, Eq, Hash)] +pub enum XRef<'tcx> { Unused(&'tcx ()) } + +struct CrateIndex<'tcx> { + items: Vec, + xrefs: FnvHashMap, u32>, // sequentially-assigned +} + +impl<'tcx> CrateIndex<'tcx> { + fn index_item(&mut self, rbml_w: &mut Encoder, id: NodeId) { + self.items.push(IndexEntry { + node: id, + pos: rbml_w.mark_stable_position(), + }); + } +} + fn encode_name(rbml_w: &mut Encoder, name: Name) { rbml_w.wr_tagged_str(tag_paths_data_name, &name.as_str()); } @@ -263,11 +281,11 @@ fn encode_struct_fields(rbml_w: &mut Encoder, } } -fn encode_enum_variant_info(ecx: &EncodeContext, - rbml_w: &mut Encoder, - id: NodeId, - vis: hir::Visibility, - index: &mut Vec) { +fn encode_enum_variant_info<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>, + rbml_w: &mut Encoder, + id: NodeId, + vis: hir::Visibility, + index: &mut CrateIndex<'tcx>) { debug!("encode_enum_variant_info(id={})", id); let mut disr_val = 0; @@ -284,10 +302,7 @@ fn encode_enum_variant_info(ecx: &EncodeContext, } } - index.push(IndexEntry { - node: vid.node, - pos: rbml_w.mark_stable_position(), - }); + index.index_item(rbml_w, vid.node); rbml_w.start_tag(tag_items_data_item); encode_def_id(rbml_w, vid); encode_family(rbml_w, match variant.kind() { @@ -593,15 +608,11 @@ fn encode_item_sort(rbml_w: &mut Encoder, sort: char) { fn encode_field<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>, rbml_w: &mut Encoder, field: ty::FieldDef<'tcx>, - global_index: &mut Vec) { + index: &mut CrateIndex<'tcx>) { let nm = field.name; let id = field.did.node; - let pos = rbml_w.mark_stable_position(); - global_index.push(IndexEntry { - node: id, - pos: pos, - }); + index.index_item(rbml_w, id); rbml_w.start_tag(tag_items_data_item); debug!("encode_field: encoding {} {}", nm, id); encode_struct_field_family(rbml_w, field.vis); @@ -615,17 +626,13 @@ fn encode_field<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>, rbml_w.end_tag(); } -fn encode_info_for_struct_ctor(ecx: &EncodeContext, - rbml_w: &mut Encoder, - name: Name, - ctor_id: NodeId, - index: &mut Vec, - struct_id: NodeId) { - index.push(IndexEntry { - node: ctor_id, - pos: rbml_w.mark_stable_position(), - }); - +fn encode_info_for_struct_ctor<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>, + rbml_w: &mut Encoder, + name: Name, + ctor_id: NodeId, + index: &mut CrateIndex<'tcx>, + struct_id: NodeId) { + index.index_item(rbml_w, ctor_id); rbml_w.start_tag(tag_items_data_item); encode_def_id(rbml_w, DefId::local(ctor_id)); encode_family(rbml_w, 'o'); @@ -952,21 +959,24 @@ fn encode_stability(rbml_w: &mut Encoder, stab_opt: Option<&attr::Stability>) { }); } -fn encode_info_for_item(ecx: &EncodeContext, - rbml_w: &mut Encoder, - item: &hir::Item, - index: &mut Vec, - path: PathElems, - vis: hir::Visibility) { - let tcx = ecx.tcx; +fn encode_xrefs<'a, 'tcx>(_ecx: &EncodeContext<'a, 'tcx>, + rbml_w: &mut Encoder, + _xrefs: FnvHashMap, u32>) +{ + rbml_w.start_tag(tag_xref_data); + rbml_w.end_tag(); - fn add_to_index(item: &hir::Item, rbml_w: &mut Encoder, - index: &mut Vec) { - index.push(IndexEntry { - node: item.id, - pos: rbml_w.mark_stable_position(), - }); - } + rbml_w.start_tag(tag_xref_index); + rbml_w.end_tag(); +} + +fn encode_info_for_item<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>, + rbml_w: &mut Encoder, + item: &hir::Item, + index: &mut CrateIndex<'tcx>, + path: PathElems, + vis: hir::Visibility) { + let tcx = ecx.tcx; debug!("encoding info for item at {}", tcx.sess.codemap().span_to_string(item.span)); @@ -976,7 +986,7 @@ fn encode_info_for_item(ecx: &EncodeContext, match item.node { hir::ItemStatic(_, m, _) => { - add_to_index(item, rbml_w, index); + index.index_item(rbml_w, item.id); rbml_w.start_tag(tag_items_data_item); encode_def_id(rbml_w, def_id); if m == hir::MutMutable { @@ -994,7 +1004,7 @@ fn encode_info_for_item(ecx: &EncodeContext, rbml_w.end_tag(); } hir::ItemConst(_, _) => { - add_to_index(item, rbml_w, index); + index.index_item(rbml_w, item.id); rbml_w.start_tag(tag_items_data_item); encode_def_id(rbml_w, def_id); encode_family(rbml_w, 'C'); @@ -1008,7 +1018,7 @@ fn encode_info_for_item(ecx: &EncodeContext, rbml_w.end_tag(); } hir::ItemFn(ref decl, _, constness, _, ref generics, _) => { - add_to_index(item, rbml_w, index); + index.index_item(rbml_w, item.id); rbml_w.start_tag(tag_items_data_item); encode_def_id(rbml_w, def_id); encode_family(rbml_w, FN_FAMILY); @@ -1031,7 +1041,7 @@ fn encode_info_for_item(ecx: &EncodeContext, rbml_w.end_tag(); } hir::ItemMod(ref m) => { - add_to_index(item, rbml_w, index); + index.index_item(rbml_w, item.id); encode_info_for_mod(ecx, rbml_w, m, @@ -1042,7 +1052,7 @@ fn encode_info_for_item(ecx: &EncodeContext, item.vis); } hir::ItemForeignMod(ref fm) => { - add_to_index(item, rbml_w, index); + index.index_item(rbml_w, item.id); rbml_w.start_tag(tag_items_data_item); encode_def_id(rbml_w, def_id); encode_family(rbml_w, 'n'); @@ -1059,7 +1069,7 @@ fn encode_info_for_item(ecx: &EncodeContext, rbml_w.end_tag(); } hir::ItemTy(..) => { - add_to_index(item, rbml_w, index); + index.index_item(rbml_w, item.id); rbml_w.start_tag(tag_items_data_item); encode_def_id(rbml_w, def_id); encode_family(rbml_w, 'y'); @@ -1071,7 +1081,7 @@ fn encode_info_for_item(ecx: &EncodeContext, rbml_w.end_tag(); } hir::ItemEnum(ref enum_definition, _) => { - add_to_index(item, rbml_w, index); + index.index_item(rbml_w, item.id); rbml_w.start_tag(tag_items_data_item); encode_def_id(rbml_w, def_id); @@ -1104,12 +1114,8 @@ fn encode_info_for_item(ecx: &EncodeContext, let def = ecx.tcx.lookup_adt_def(def_id); let variant = def.struct_variant(); - for field in &variant.fields { - encode_field(ecx, rbml_w, field, index); - } - /* Index the class*/ - add_to_index(item, rbml_w, index); + index.index_item(rbml_w, item.id); /* Now, make an item for the class itself */ rbml_w.start_tag(tag_items_data_item); @@ -1137,6 +1143,10 @@ fn encode_info_for_item(ecx: &EncodeContext, rbml_w.end_tag(); + for field in &variant.fields { + encode_field(ecx, rbml_w, field, index); + } + // If this is a tuple-like struct, encode the type of the constructor. match struct_def.ctor_id { Some(ctor_id) => { @@ -1147,7 +1157,7 @@ fn encode_info_for_item(ecx: &EncodeContext, } } hir::ItemDefaultImpl(unsafety, _) => { - add_to_index(item, rbml_w, index); + index.index_item(rbml_w, item.id); rbml_w.start_tag(tag_items_data_item); encode_def_id(rbml_w, def_id); encode_family(rbml_w, 'd'); @@ -1164,7 +1174,7 @@ fn encode_info_for_item(ecx: &EncodeContext, let impl_items = tcx.impl_items.borrow(); let items = impl_items.get(&def_id).unwrap(); - add_to_index(item, rbml_w, index); + index.index_item(rbml_w, item.id); rbml_w.start_tag(tag_items_data_item); encode_def_id(rbml_w, def_id); encode_family(rbml_w, 'i'); @@ -1220,11 +1230,7 @@ fn encode_info_for_item(ecx: &EncodeContext, None }; - index.push(IndexEntry { - node: trait_item_def_id.def_id().node, - pos: rbml_w.mark_stable_position(), - }); - + index.index_item(rbml_w, trait_item_def_id.def_id().node); match tcx.impl_or_trait_item(trait_item_def_id.def_id()) { ty::ConstTraitItem(ref associated_const) => { encode_info_for_associated_const(ecx, @@ -1255,7 +1261,7 @@ fn encode_info_for_item(ecx: &EncodeContext, } } hir::ItemTrait(_, _, _, ref ms) => { - add_to_index(item, rbml_w, index); + index.index_item(rbml_w, item.id); rbml_w.start_tag(tag_items_data_item); encode_def_id(rbml_w, def_id); encode_family(rbml_w, 'I'); @@ -1311,11 +1317,7 @@ fn encode_info_for_item(ecx: &EncodeContext, for (i, &item_def_id) in r.iter().enumerate() { assert_eq!(item_def_id.def_id().krate, LOCAL_CRATE); - index.push(IndexEntry { - node: item_def_id.def_id().node, - pos: rbml_w.mark_stable_position(), - }); - + index.index_item(rbml_w, item_def_id.def_id().node); rbml_w.start_tag(tag_items_data_item); encode_parent_item(rbml_w, def_id); @@ -1431,17 +1433,13 @@ fn encode_info_for_item(ecx: &EncodeContext, } } -fn encode_info_for_foreign_item(ecx: &EncodeContext, - rbml_w: &mut Encoder, - nitem: &hir::ForeignItem, - index: &mut Vec, - path: PathElems, - abi: abi::Abi) { - index.push(IndexEntry { - node: nitem.id, - pos: rbml_w.mark_stable_position(), - }); - +fn encode_info_for_foreign_item<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>, + rbml_w: &mut Encoder, + nitem: &hir::ForeignItem, + index: &mut CrateIndex<'tcx>, + path: PathElems, + abi: abi::Abi) { + index.index_item(rbml_w, nitem.id); rbml_w.start_tag(tag_items_data_item); encode_def_id(rbml_w, DefId::local(nitem.id)); encode_visibility(rbml_w, nitem.vis); @@ -1479,19 +1477,19 @@ fn encode_info_for_foreign_item(ecx: &EncodeContext, fn my_visit_expr(_e: &hir::Expr) { } -fn my_visit_item(i: &hir::Item, - rbml_w: &mut Encoder, - ecx: &EncodeContext, - index: &mut Vec) { +fn my_visit_item<'a, 'tcx>(i: &hir::Item, + rbml_w: &mut Encoder, + ecx: &EncodeContext<'a, 'tcx>, + index: &mut CrateIndex<'tcx>) { ecx.tcx.map.with_path(i.id, |path| { encode_info_for_item(ecx, rbml_w, i, index, path, i.vis); }); } -fn my_visit_foreign_item(ni: &hir::ForeignItem, - rbml_w: &mut Encoder, - ecx: &EncodeContext, - index: &mut Vec) { +fn my_visit_foreign_item<'a, 'tcx>(ni: &hir::ForeignItem, + rbml_w: &mut Encoder, + ecx: &EncodeContext<'a, 'tcx>, + index: &mut CrateIndex<'tcx>) { debug!("writing foreign item {}::{}", ecx.tcx.map.path_to_string(ni.id), ni.name); @@ -1507,7 +1505,7 @@ fn my_visit_foreign_item(ni: &hir::ForeignItem, struct EncodeVisitor<'a, 'b:'a, 'c:'a, 'tcx:'c> { rbml_w_for_visit_item: &'a mut Encoder<'b>, ecx: &'a EncodeContext<'c,'tcx>, - index: &'a mut Vec, + index: &'a mut CrateIndex<'tcx>, } impl<'a, 'b, 'c, 'tcx, 'v> Visitor<'v> for EncodeVisitor<'a, 'b, 'c, 'tcx> { @@ -1531,16 +1529,17 @@ impl<'a, 'b, 'c, 'tcx, 'v> Visitor<'v> for EncodeVisitor<'a, 'b, 'c, 'tcx> { } } -fn encode_info_for_items(ecx: &EncodeContext, - rbml_w: &mut Encoder, - krate: &hir::Crate) - -> Vec { - let mut index = Vec::new(); +fn encode_info_for_items<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>, + rbml_w: &mut Encoder, + krate: &hir::Crate) + -> CrateIndex<'tcx> { + let mut index = CrateIndex { + items: Vec::new(), + xrefs: FnvHashMap() + }; rbml_w.start_tag(tag_items_data); - index.push(IndexEntry { - node: CRATE_NODE_ID, - pos: rbml_w.mark_stable_position(), - }); + + index.index_item(rbml_w, CRATE_NODE_ID); encode_info_for_mod(ecx, rbml_w, &krate.module, @@ -1560,10 +1559,7 @@ fn encode_info_for_items(ecx: &EncodeContext, index } - - - -fn encode_index(rbml_w: &mut Encoder, index: Vec) +fn encode_item_index(rbml_w: &mut Encoder, index: Vec) { rbml_w.start_tag(tag_index); index::write_index(index, rbml_w.writer); @@ -1978,6 +1974,7 @@ fn encode_metadata_inner(wr: &mut Cursor>, misc_bytes: u64, item_bytes: u64, index_bytes: u64, + xref_bytes: u64, zero_bytes: u64, total_bytes: u64, } @@ -1993,6 +1990,7 @@ fn encode_metadata_inner(wr: &mut Cursor>, misc_bytes: 0, item_bytes: 0, index_bytes: 0, + xref_bytes: 0, zero_bytes: 0, total_bytes: 0, }; @@ -2074,14 +2072,18 @@ fn encode_metadata_inner(wr: &mut Cursor>, // Encode and index the items. rbml_w.start_tag(tag_items); i = rbml_w.writer.seek(SeekFrom::Current(0)).unwrap(); - let items_index = encode_info_for_items(&ecx, &mut rbml_w, krate); + let index = encode_info_for_items(&ecx, &mut rbml_w, krate); stats.item_bytes = rbml_w.writer.seek(SeekFrom::Current(0)).unwrap() - i; rbml_w.end_tag(); i = rbml_w.writer.seek(SeekFrom::Current(0)).unwrap(); - encode_index(&mut rbml_w, items_index); + encode_item_index(&mut rbml_w, index.items); stats.index_bytes = rbml_w.writer.seek(SeekFrom::Current(0)).unwrap() - i; + i = rbml_w.writer.seek(SeekFrom::Current(0)).unwrap(); + encode_xrefs(&ecx, &mut rbml_w, index.xrefs); + stats.xref_bytes = rbml_w.writer.seek(SeekFrom::Current(0)).unwrap() - i; + encode_struct_field_attrs(&mut rbml_w, krate); stats.total_bytes = rbml_w.writer.seek(SeekFrom::Current(0)).unwrap(); @@ -2105,6 +2107,7 @@ fn encode_metadata_inner(wr: &mut Cursor>, println!(" misc bytes: {}", stats.misc_bytes); println!(" item bytes: {}", stats.item_bytes); println!(" index bytes: {}", stats.index_bytes); + println!(" xref bytes: {}", stats.xref_bytes); println!(" zero bytes: {}", stats.zero_bytes); println!(" total bytes: {}", stats.total_bytes); } diff --git a/src/librustc/metadata/index.rs b/src/librustc/metadata/index.rs index b02a9022a7a6e..1cfb201023bc4 100644 --- a/src/librustc/metadata/index.rs +++ b/src/librustc/metadata/index.rs @@ -33,8 +33,8 @@ impl IndexArrayEntry { fn decode_from(b: &[u32]) -> Self { IndexArrayEntry { - bits: b[0].to_be(), - first_pos: b[1].to_be() + bits: u32::from_be(b[0]), + first_pos: u32::from_be(b[1]) } } } @@ -106,7 +106,7 @@ impl Index { } fn item_from_pos(&self, positions: &[u32], pos: u32) -> u32 { - positions[pos as usize].to_be() + u32::from_be(positions[pos as usize]) } #[inline(never)] @@ -149,6 +149,37 @@ impl Index { } } +/// A dense index with integer keys +pub struct DenseIndex { + start: usize, + end: usize +} + +impl DenseIndex { + pub fn lookup(&self, buf: &[u8], ix: u32) -> Option { + let data = bytes_to_words(&buf[self.start..self.end]); + data.get(ix as usize).map(|d| u32::from_be(*d)) + } + pub fn from_buf(buf: &[u8], start: usize, end: usize) -> Self { + assert!((end-start)%4 == 0 && start <= end && end <= buf.len()); + DenseIndex { + start: start, + end: end + } + } +} + +pub fn write_dense_index(entries: Vec, buf: &mut Cursor>) { + let elen = entries.len(); + assert!(elen < u32::MAX as usize); + + for entry in entries { + write_be_u32(buf, entry); + } + + info!("write_dense_index: {} entries", elen); +} + fn write_be_u32(w: &mut W, u: u32) { let _ = w.write_all(&[ (u >> 24) as u8, From 38cd6d40d2370b9bc0ab3bd6dae389c61d171c9e Mon Sep 17 00:00:00 2001 From: Ariel Ben-Yehuda Date: Thu, 17 Sep 2015 18:05:30 +0300 Subject: [PATCH 03/10] share stored predicates while most of the duplication in predicates was caused by stubs, this is still a 5% win on libcore. 567924 liballoc-bb943c5a.rlib 1425564 liballoc_jemalloc-bb943c5a.rlib 10520 liballoc_system-bb943c5a.rlib 154842 libarena-bb943c5a.rlib 4113790 libcollections-bb943c5a.rlib 18513674 libcore-bb943c5a.rlib 199466 libflate-bb943c5a.rlib 249548 libfmt_macros-bb943c5a.rlib 560488 libgetopts-bb943c5a.rlib 226772 libgraphviz-bb943c5a.rlib 442966 liblibc-bb943c5a.rlib 189884 liblog-bb943c5a.rlib 736764 librand-bb943c5a.rlib 609874 librbml-bb943c5a.rlib 1411678 librustc_back-bb943c5a.rlib 38770354 librustc-bb943c5a.rlib 12868 librustc_bitflags-bb943c5a.rlib 2327196 librustc_borrowck-bb943c5a.rlib 582178 librustc_data_structures-bb943c5a.rlib 9379344 librustc_driver-bb943c5a.rlib 9540324 librustc_front-bb943c5a.rlib 1614996 librustc_lint-bb943c5a.rlib 79217876 librustc_llvm-bb943c5a.rlib 4833518 librustc_mir-bb943c5a.rlib 3535794 librustc_platform_intrinsics-bb943c5a.rlib 603190 librustc_privacy-bb943c5a.rlib 3158032 librustc_resolve-bb943c5a.rlib 14300126 librustc_trans-bb943c5a.rlib 12024054 librustc_typeck-bb943c5a.rlib 1834852 librustc_unicode-bb943c5a.rlib 15611582 librustdoc-bb943c5a.rlib 2926594 libserialize-bb943c5a.rlib 8780060 libstd-bb943c5a.rlib 30772000 libsyntax-bb943c5a.rlib 917984 libterm-bb943c5a.rlib 1369754 libtest-bb943c5a.rlib --- src/librustc/metadata/common.rs | 6 +- src/librustc/metadata/decoder.rs | 35 +++++--- src/librustc/metadata/encoder.rs | 140 +++++++++++++++++++------------ 3 files changed, 115 insertions(+), 66 deletions(-) diff --git a/src/librustc/metadata/common.rs b/src/librustc/metadata/common.rs index 30f0485d7d174..bf099a7e52c06 100644 --- a/src/librustc/metadata/common.rs +++ b/src/librustc/metadata/common.rs @@ -222,9 +222,9 @@ pub const tag_type_param_def: usize = 0x94; pub const tag_item_generics: usize = 0x95; pub const tag_method_ty_generics: usize = 0x96; -pub const tag_predicate: usize = 0x97; -pub const tag_predicate_space: usize = 0x98; -pub const tag_predicate_data: usize = 0x99; +pub const tag_type_predicate: usize = 0x97; +pub const tag_self_predicate: usize = 0x98; +pub const tag_fn_predicate: usize = 0x99; pub const tag_unsafety: usize = 0x9a; diff --git a/src/librustc/metadata/decoder.rs b/src/librustc/metadata/decoder.rs index 64858d99b7e8a..565ec2414f41d 100644 --- a/src/librustc/metadata/decoder.rs +++ b/src/librustc/metadata/decoder.rs @@ -1473,6 +1473,19 @@ fn doc_generics<'tcx>(base_doc: rbml::Doc, ty::Generics { types: types, regions: regions } } +fn doc_predicate<'tcx>(cdata: Cmd, + doc: rbml::Doc, + tcx: &ty::ctxt<'tcx>) + -> ty::Predicate<'tcx> +{ + let predicate_pos = cdata.xref_index.lookup( + cdata.data(), reader::doc_as_u32(doc)).unwrap() as usize; + TyDecoder::new( + cdata.data(), cdata.cnum, predicate_pos, tcx, + &mut |_, did| translate_def_id(cdata, did) + ).parse_predicate() +} + fn doc_predicates<'tcx>(base_doc: rbml::Doc, tcx: &ty::ctxt<'tcx>, cdata: Cmd, @@ -1482,17 +1495,17 @@ fn doc_predicates<'tcx>(base_doc: rbml::Doc, let doc = reader::get_doc(base_doc, tag); let mut predicates = subst::VecPerParamSpace::empty(); - for predicate_doc in reader::tagged_docs(doc, tag_predicate) { - let space_doc = reader::get_doc(predicate_doc, tag_predicate_space); - let space = subst::ParamSpace::from_uint(reader::doc_as_u8(space_doc) as usize); - - let data_doc = reader::get_doc(predicate_doc, tag_predicate_data); - let data = - TyDecoder::with_doc(tcx, cdata.cnum, data_doc, - &mut |_, did| translate_def_id(cdata, did)) - .parse_predicate(); - - predicates.push(space, data); + for predicate_doc in reader::tagged_docs(doc, tag_type_predicate) { + predicates.push(subst::TypeSpace, + doc_predicate(cdata, predicate_doc, tcx)); + } + for predicate_doc in reader::tagged_docs(doc, tag_self_predicate) { + predicates.push(subst::SelfSpace, + doc_predicate(cdata, predicate_doc, tcx)); + } + for predicate_doc in reader::tagged_docs(doc, tag_fn_predicate) { + predicates.push(subst::FnSpace, + doc_predicate(cdata, predicate_doc, tcx)); } ty::GenericPredicates { predicates: predicates } diff --git a/src/librustc/metadata/encoder.rs b/src/librustc/metadata/encoder.rs index d5ef8b962c846..fd10639fbc7a1 100644 --- a/src/librustc/metadata/encoder.rs +++ b/src/librustc/metadata/encoder.rs @@ -25,6 +25,7 @@ use middle::def; use middle::def_id::{DefId, LOCAL_CRATE}; use middle::dependency_format::Linkage; use middle::stability; +use middle::subst; use middle::ty::{self, Ty}; use util::nodemap::{FnvHashMap, NodeMap, NodeSet}; @@ -76,7 +77,7 @@ pub struct EncodeContext<'a, 'tcx: 'a> { /// "interned" entries referenced by id #[derive(PartialEq, Eq, Hash)] -pub enum XRef<'tcx> { Unused(&'tcx ()) } +pub enum XRef<'tcx> { Predicate(ty::Predicate<'tcx>) } struct CrateIndex<'tcx> { items: Vec, @@ -90,6 +91,11 @@ impl<'tcx> CrateIndex<'tcx> { pos: rbml_w.mark_stable_position(), }); } + + fn add_xref(&mut self, xref: XRef<'tcx>) -> u32 { + let old_len = self.xrefs.len() as u32; + *self.xrefs.entry(xref).or_insert(old_len) + } } fn encode_name(rbml_w: &mut Encoder, name: Name) { @@ -140,18 +146,22 @@ fn encode_item_variances(rbml_w: &mut Encoder, fn encode_bounds_and_type_for_item<'a, 'tcx>(rbml_w: &mut Encoder, ecx: &EncodeContext<'a, 'tcx>, + index: &mut CrateIndex<'tcx>, id: NodeId) { encode_bounds_and_type(rbml_w, ecx, + index, &ecx.tcx.lookup_item_type(DefId::local(id)), &ecx.tcx.lookup_predicates(DefId::local(id))); } fn encode_bounds_and_type<'a, 'tcx>(rbml_w: &mut Encoder, ecx: &EncodeContext<'a, 'tcx>, + index: &mut CrateIndex<'tcx>, scheme: &ty::TypeScheme<'tcx>, predicates: &ty::GenericPredicates<'tcx>) { - encode_generics(rbml_w, ecx, &scheme.generics, &predicates, tag_item_generics); + encode_generics(rbml_w, ecx, index, + &scheme.generics, &predicates, tag_item_generics); encode_type(ecx, rbml_w, scheme.ty); } @@ -327,7 +337,7 @@ fn encode_enum_variant_info<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>, encode_disr_val(ecx, rbml_w, specified_disr_val); disr_val = specified_disr_val; } - encode_bounds_and_type_for_item(rbml_w, ecx, vid.node); + encode_bounds_and_type_for_item(rbml_w, ecx, index, vid.node); ecx.tcx.map.with_path(vid.node, |path| encode_path(rbml_w, path)); rbml_w.end_tag(); @@ -617,7 +627,7 @@ fn encode_field<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>, debug!("encode_field: encoding {} {}", nm, id); encode_struct_field_family(rbml_w, field.vis); encode_name(rbml_w, nm); - encode_bounds_and_type_for_item(rbml_w, ecx, id); + encode_bounds_and_type_for_item(rbml_w, ecx, index, id); encode_def_id(rbml_w, DefId::local(id)); let stab = stability::lookup(ecx.tcx, field.did); @@ -636,7 +646,7 @@ fn encode_info_for_struct_ctor<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>, rbml_w.start_tag(tag_items_data_item); encode_def_id(rbml_w, DefId::local(ctor_id)); encode_family(rbml_w, 'o'); - encode_bounds_and_type_for_item(rbml_w, ecx, ctor_id); + encode_bounds_and_type_for_item(rbml_w, ecx, index, ctor_id); encode_name(rbml_w, name); ecx.tcx.map.with_path(ctor_id, |path| encode_path(rbml_w, path)); encode_parent_item(rbml_w, DefId::local(struct_id)); @@ -658,6 +668,7 @@ fn encode_info_for_struct_ctor<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>, fn encode_generics<'a, 'tcx>(rbml_w: &mut Encoder, ecx: &EncodeContext<'a, 'tcx>, + index: &mut CrateIndex<'tcx>, generics: &ty::Generics<'tcx>, predicates: &ty::GenericPredicates<'tcx>, tag: usize) @@ -702,51 +713,47 @@ fn encode_generics<'a, 'tcx>(rbml_w: &mut Encoder, rbml_w.end_tag(); } - encode_predicates_in_current_doc(rbml_w, ecx, predicates); + encode_predicates_in_current_doc(rbml_w, ecx, index, predicates); rbml_w.end_tag(); } fn encode_predicates_in_current_doc<'a,'tcx>(rbml_w: &mut Encoder, - ecx: &EncodeContext<'a,'tcx>, + _ecx: &EncodeContext<'a,'tcx>, + index: &mut CrateIndex<'tcx>, predicates: &ty::GenericPredicates<'tcx>) { - let ty_str_ctxt = &tyencode::ctxt { - diag: ecx.diag, - ds: def_to_string, - tcx: ecx.tcx, - abbrevs: &ecx.type_abbrevs - }; - for (space, _, predicate) in predicates.predicates.iter_enumerated() { - rbml_w.start_tag(tag_predicate); - - rbml_w.wr_tagged_u8(tag_predicate_space, space as u8); - - rbml_w.start_tag(tag_predicate_data); - tyencode::enc_predicate(rbml_w, ty_str_ctxt, predicate); - rbml_w.end_tag(); + let tag = match space { + subst::TypeSpace => tag_type_predicate, + subst::SelfSpace => tag_self_predicate, + subst::FnSpace => tag_fn_predicate + }; - rbml_w.end_tag(); + rbml_w.wr_tagged_u32(tag, + index.add_xref(XRef::Predicate(predicate.clone()))); } } fn encode_predicates<'a,'tcx>(rbml_w: &mut Encoder, ecx: &EncodeContext<'a,'tcx>, + index: &mut CrateIndex<'tcx>, predicates: &ty::GenericPredicates<'tcx>, tag: usize) { rbml_w.start_tag(tag); - encode_predicates_in_current_doc(rbml_w, ecx, predicates); + encode_predicates_in_current_doc(rbml_w, ecx, index, predicates); rbml_w.end_tag(); } fn encode_method_ty_fields<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>, rbml_w: &mut Encoder, + index: &mut CrateIndex<'tcx>, method_ty: &ty::Method<'tcx>) { encode_def_id(rbml_w, method_ty.def_id); encode_name(rbml_w, method_ty.name); - encode_generics(rbml_w, ecx, &method_ty.generics, &method_ty.predicates, + encode_generics(rbml_w, ecx, index, + &method_ty.generics, &method_ty.predicates, tag_method_ty_generics); encode_method_fty(ecx, rbml_w, &method_ty.fty); encode_visibility(rbml_w, method_ty.vis); @@ -759,16 +766,18 @@ fn encode_method_ty_fields<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>, } } -fn encode_info_for_associated_const(ecx: &EncodeContext, - rbml_w: &mut Encoder, - associated_const: &ty::AssociatedConst, - impl_path: PathElems, - parent_id: NodeId, - impl_item_opt: Option<&hir::ImplItem>) { +fn encode_info_for_associated_const<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>, + rbml_w: &mut Encoder, + index: &mut CrateIndex<'tcx>, + associated_const: &ty::AssociatedConst, + impl_path: PathElems, + parent_id: NodeId, + impl_item_opt: Option<&hir::ImplItem>) { debug!("encode_info_for_associated_const({:?},{:?})", associated_const.def_id, associated_const.name); + index.index_item(rbml_w, associated_const.def_id.node); rbml_w.start_tag(tag_items_data_item); encode_def_id(rbml_w, associated_const.def_id); @@ -779,7 +788,8 @@ fn encode_info_for_associated_const(ecx: &EncodeContext, encode_parent_item(rbml_w, DefId::local(parent_id)); encode_item_sort(rbml_w, 'C'); - encode_bounds_and_type_for_item(rbml_w, ecx, associated_const.def_id.local_id()); + encode_bounds_and_type_for_item(rbml_w, ecx, index, + associated_const.def_id.local_id()); let stab = stability::lookup(ecx.tcx, associated_const.def_id); encode_stability(rbml_w, stab); @@ -797,6 +807,7 @@ fn encode_info_for_associated_const(ecx: &EncodeContext, fn encode_info_for_method<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>, rbml_w: &mut Encoder, + index: &mut CrateIndex<'tcx>, m: &ty::Method<'tcx>, impl_path: PathElems, is_default_impl: bool, @@ -805,9 +816,10 @@ fn encode_info_for_method<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>, debug!("encode_info_for_method: {:?} {:?}", m.def_id, m.name); + index.index_item(rbml_w, m.def_id.node); rbml_w.start_tag(tag_items_data_item); - encode_method_ty_fields(ecx, rbml_w, m); + encode_method_ty_fields(ecx, rbml_w, index, m); encode_parent_item(rbml_w, DefId::local(parent_id)); encode_item_sort(rbml_w, 'r'); @@ -815,7 +827,7 @@ fn encode_info_for_method<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>, encode_stability(rbml_w, stab); // The type for methods gets encoded twice, which is unfortunate. - encode_bounds_and_type_for_item(rbml_w, ecx, m.def_id.local_id()); + encode_bounds_and_type_for_item(rbml_w, ecx, index, m.def_id.local_id()); let elem = ast_map::PathName(m.name); encode_path(rbml_w, impl_path.chain(Some(elem))); @@ -843,6 +855,7 @@ fn encode_info_for_method<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>, fn encode_info_for_associated_type<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>, rbml_w: &mut Encoder, + index: &mut CrateIndex<'tcx>, associated_type: &ty::AssociatedType<'tcx>, impl_path: PathElems, parent_id: NodeId, @@ -851,6 +864,7 @@ fn encode_info_for_associated_type<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>, associated_type.def_id, associated_type.name); + index.index_item(rbml_w, associated_type.def_id.node); rbml_w.start_tag(tag_items_data_item); encode_def_id(rbml_w, associated_type.def_id); @@ -869,7 +883,7 @@ fn encode_info_for_associated_type<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>, if let Some(ii) = impl_item_opt { encode_attributes(rbml_w, &ii.attrs); } else { - encode_predicates(rbml_w, ecx, + encode_predicates(rbml_w, ecx, index, &ecx.tcx.lookup_predicates(associated_type.def_id), tag_item_generics); } @@ -959,14 +973,31 @@ fn encode_stability(rbml_w: &mut Encoder, stab_opt: Option<&attr::Stability>) { }); } -fn encode_xrefs<'a, 'tcx>(_ecx: &EncodeContext<'a, 'tcx>, +fn encode_xrefs<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>, rbml_w: &mut Encoder, - _xrefs: FnvHashMap, u32>) + xrefs: FnvHashMap, u32>) { + let ty_str_ctxt = &tyencode::ctxt { + diag: ecx.diag, + ds: def_to_string, + tcx: ecx.tcx, + abbrevs: &ecx.type_abbrevs + }; + + let mut xref_positions = vec![0; xrefs.len()]; rbml_w.start_tag(tag_xref_data); + for (xref, id) in xrefs.into_iter() { + xref_positions[id as usize] = rbml_w.mark_stable_position() as u32; + match xref { + XRef::Predicate(p) => { + tyencode::enc_predicate(rbml_w, ty_str_ctxt, &p) + } + } + } rbml_w.end_tag(); rbml_w.start_tag(tag_xref_index); + index::write_dense_index(xref_positions, rbml_w.writer); rbml_w.end_tag(); } @@ -994,7 +1025,7 @@ fn encode_info_for_item<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>, } else { encode_family(rbml_w, 'c'); } - encode_bounds_and_type_for_item(rbml_w, ecx, item.id); + encode_bounds_and_type_for_item(rbml_w, ecx, index, item.id); encode_symbol(ecx, rbml_w, item.id); encode_name(rbml_w, item.name); encode_path(rbml_w, path); @@ -1008,7 +1039,7 @@ fn encode_info_for_item<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>, rbml_w.start_tag(tag_items_data_item); encode_def_id(rbml_w, def_id); encode_family(rbml_w, 'C'); - encode_bounds_and_type_for_item(rbml_w, ecx, item.id); + encode_bounds_and_type_for_item(rbml_w, ecx, index, item.id); encode_name(rbml_w, item.name); encode_path(rbml_w, path); encode_attributes(rbml_w, &item.attrs); @@ -1023,7 +1054,7 @@ fn encode_info_for_item<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>, encode_def_id(rbml_w, def_id); encode_family(rbml_w, FN_FAMILY); let tps_len = generics.ty_params.len(); - encode_bounds_and_type_for_item(rbml_w, ecx, item.id); + encode_bounds_and_type_for_item(rbml_w, ecx, index, item.id); encode_name(rbml_w, item.name); encode_path(rbml_w, path); encode_attributes(rbml_w, &item.attrs); @@ -1073,7 +1104,7 @@ fn encode_info_for_item<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>, rbml_w.start_tag(tag_items_data_item); encode_def_id(rbml_w, def_id); encode_family(rbml_w, 'y'); - encode_bounds_and_type_for_item(rbml_w, ecx, item.id); + encode_bounds_and_type_for_item(rbml_w, ecx, index, item.id); encode_name(rbml_w, item.name); encode_path(rbml_w, path); encode_visibility(rbml_w, vis); @@ -1087,7 +1118,7 @@ fn encode_info_for_item<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>, encode_def_id(rbml_w, def_id); encode_family(rbml_w, 't'); encode_item_variances(rbml_w, ecx, item.id); - encode_bounds_and_type_for_item(rbml_w, ecx, item.id); + encode_bounds_and_type_for_item(rbml_w, ecx, index, item.id); encode_name(rbml_w, item.name); encode_attributes(rbml_w, &item.attrs); encode_repr_attrs(rbml_w, ecx, &item.attrs); @@ -1121,7 +1152,7 @@ fn encode_info_for_item<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>, rbml_w.start_tag(tag_items_data_item); encode_def_id(rbml_w, def_id); encode_family(rbml_w, 'S'); - encode_bounds_and_type_for_item(rbml_w, ecx, item.id); + encode_bounds_and_type_for_item(rbml_w, ecx, index, item.id); encode_item_variances(rbml_w, ecx, item.id); encode_name(rbml_w, item.name); @@ -1178,7 +1209,7 @@ fn encode_info_for_item<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>, rbml_w.start_tag(tag_items_data_item); encode_def_id(rbml_w, def_id); encode_family(rbml_w, 'i'); - encode_bounds_and_type_for_item(rbml_w, ecx, item.id); + encode_bounds_and_type_for_item(rbml_w, ecx, index, item.id); encode_name(rbml_w, item.name); encode_attributes(rbml_w, &item.attrs); encode_unsafety(rbml_w, unsafety); @@ -1230,11 +1261,11 @@ fn encode_info_for_item<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>, None }; - index.index_item(rbml_w, trait_item_def_id.def_id().node); match tcx.impl_or_trait_item(trait_item_def_id.def_id()) { ty::ConstTraitItem(ref associated_const) => { encode_info_for_associated_const(ecx, rbml_w, + index, &*associated_const, path.clone(), item.id, @@ -1243,6 +1274,7 @@ fn encode_info_for_item<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>, ty::MethodTraitItem(ref method_type) => { encode_info_for_method(ecx, rbml_w, + index, &**method_type, path.clone(), false, @@ -1252,6 +1284,7 @@ fn encode_info_for_item<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>, ty::TypeTraitItem(ref associated_type) => { encode_info_for_associated_type(ecx, rbml_w, + index, &**associated_type, path.clone(), item.id, @@ -1272,9 +1305,11 @@ fn encode_info_for_item<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>, encode_paren_sugar(rbml_w, trait_def.paren_sugar); encode_defaulted(rbml_w, tcx.trait_has_default_impl(def_id)); encode_associated_type_names(rbml_w, &trait_def.associated_type_names); - encode_generics(rbml_w, ecx, &trait_def.generics, &trait_predicates, + encode_generics(rbml_w, ecx, index, + &trait_def.generics, &trait_predicates, tag_item_generics); - encode_predicates(rbml_w, ecx, &tcx.lookup_super_predicates(def_id), + encode_predicates(rbml_w, ecx, index, + &tcx.lookup_super_predicates(def_id), tag_item_super_predicates); encode_trait_ref(rbml_w, ecx, trait_def.trait_ref, tag_item_trait_ref); encode_name(rbml_w, item.name); @@ -1340,7 +1375,7 @@ fn encode_info_for_item<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>, encode_family(rbml_w, 'C'); - encode_bounds_and_type_for_item(rbml_w, ecx, + encode_bounds_and_type_for_item(rbml_w, ecx, index, associated_const.def_id.local_id()); is_nonstatic_method = false; @@ -1348,7 +1383,7 @@ fn encode_info_for_item<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>, ty::MethodTraitItem(method_ty) => { let method_def_id = item_def_id.def_id(); - encode_method_ty_fields(ecx, rbml_w, &*method_ty); + encode_method_ty_fields(ecx, rbml_w, index, &*method_ty); let elem = ast_map::PathName(method_ty.name); encode_path(rbml_w, @@ -1364,7 +1399,8 @@ fn encode_info_for_item<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>, METHOD_FAMILY); } } - encode_bounds_and_type_for_item(rbml_w, ecx, method_def_id.local_id()); + encode_bounds_and_type_for_item(rbml_w, ecx, index, + method_def_id.local_id()); is_nonstatic_method = method_ty.explicit_self != ty::StaticExplicitSelfCategory; @@ -1407,7 +1443,7 @@ fn encode_info_for_item<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>, if is_nonstatic_method { // FIXME: I feel like there is something funny // going on. - encode_bounds_and_type_for_item(rbml_w, ecx, + encode_bounds_and_type_for_item(rbml_w, ecx, index, item_def_id.def_id().local_id()); } @@ -1446,7 +1482,7 @@ fn encode_info_for_foreign_item<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>, match nitem.node { hir::ForeignItemFn(ref fndecl, _) => { encode_family(rbml_w, FN_FAMILY); - encode_bounds_and_type_for_item(rbml_w, ecx, nitem.id); + encode_bounds_and_type_for_item(rbml_w, ecx, index, nitem.id); encode_name(rbml_w, nitem.name); if abi == abi::RustIntrinsic || abi == abi::PlatformIntrinsic { encode_inlined_item(ecx, rbml_w, InlinedItemRef::Foreign(nitem)); @@ -1463,7 +1499,7 @@ fn encode_info_for_foreign_item<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>, } else { encode_family(rbml_w, 'c'); } - encode_bounds_and_type_for_item(rbml_w, ecx, nitem.id); + encode_bounds_and_type_for_item(rbml_w, ecx, index, nitem.id); encode_attributes(rbml_w, &*nitem.attrs); let stab = stability::lookup(ecx.tcx, DefId::local(nitem.id)); encode_stability(rbml_w, stab); From 7aed441ac8ef9da3f12c0606a93a55bd998f2d4f Mon Sep 17 00:00:00 2001 From: Ariel Ben-Yehuda Date: Thu, 17 Sep 2015 19:55:43 +0300 Subject: [PATCH 04/10] don't emit leading zeros in tagged integers we *already* need a length, so might as well use it this saves 3% in libcore 559870 liballoc-bb943c5a.rlib 1425170 liballoc_jemalloc-bb943c5a.rlib 10120 liballoc_system-bb943c5a.rlib 152398 libarena-bb943c5a.rlib 4023670 libcollections-bb943c5a.rlib 18042746 libcore-bb943c5a.rlib 198202 libflate-bb943c5a.rlib 244412 libfmt_macros-bb943c5a.rlib 555750 libgetopts-bb943c5a.rlib 222462 libgraphviz-bb943c5a.rlib 417824 liblibc-bb943c5a.rlib 187804 liblog-bb943c5a.rlib 722742 librand-bb943c5a.rlib 604846 librbml-bb943c5a.rlib 1397814 librustc_back-bb943c5a.rlib 38382616 librustc-bb943c5a.rlib 12826 librustc_bitflags-bb943c5a.rlib 2298772 librustc_borrowck-bb943c5a.rlib 570822 librustc_data_structures-bb943c5a.rlib 9361826 librustc_driver-bb943c5a.rlib 9479914 librustc_front-bb943c5a.rlib 1604576 librustc_lint-bb943c5a.rlib 79190586 librustc_llvm-bb943c5a.rlib 4783104 librustc_mir-bb943c5a.rlib 3534332 librustc_platform_intrinsics-bb943c5a.rlib 592710 librustc_privacy-bb943c5a.rlib 3123792 librustc_resolve-bb943c5a.rlib 14183434 librustc_trans-bb943c5a.rlib 11937016 librustc_typeck-bb943c5a.rlib 1830988 librustc_unicode-bb943c5a.rlib 15611582 librustdoc-bb943c5a.rlib 2892482 libserialize-bb943c5a.rlib 8642922 libstd-bb943c5a.rlib 30590774 libsyntax-bb943c5a.rlib 912678 libterm-bb943c5a.rlib 1369754 libtest-bb943c5a.rlib --- src/librbml/lib.rs | 73 ++++++++++++++++++++++++++++------------------ 1 file changed, 44 insertions(+), 29 deletions(-) diff --git a/src/librbml/lib.rs b/src/librbml/lib.rs index af36d45ab573d..dbd6ba700fa1d 100644 --- a/src/librbml/lib.rs +++ b/src/librbml/lib.rs @@ -467,37 +467,44 @@ pub mod reader { f(&d.data[d.start..d.end]) } - pub fn doc_as_u8(d: Doc) -> u8 { assert_eq!(d.end, d.start + 1); d.data[d.start] } - pub fn doc_as_u16(d: Doc) -> u16 { - assert_eq!(d.end, d.start + 2); - let mut b = [0; 2]; - bytes::copy_memory(&d.data[d.start..d.end], &mut b); - unsafe { (*(b.as_ptr() as *const u16)).to_be() } - } - - pub fn doc_as_u32(d: Doc) -> u32 { - assert_eq!(d.end, d.start + 4); - let mut b = [0; 4]; - bytes::copy_memory(&d.data[d.start..d.end], &mut b); - unsafe { (*(b.as_ptr() as *const u32)).to_be() } - } - pub fn doc_as_u64(d: Doc) -> u64 { - assert_eq!(d.end, d.start + 8); - let mut b = [0; 8]; - bytes::copy_memory(&d.data[d.start..d.end], &mut b); - unsafe { (*(b.as_ptr() as *const u64)).to_be() } + if d.end >= 8 { + // For performance, we read 8 big-endian bytes, + // and mask off the junk if there is any. This + // obviously won't work on the first 8 bytes + // of a file - we will fall of the start + // of the page and segfault. + + let mut b = [0; 8]; + bytes::copy_memory(&d.data[d.end-8..d.end], &mut b); + let data = unsafe { (*(b.as_ptr() as *const u64)).to_be() }; + let len = d.end - d.start; + if len < 8 { + data & ((1<<(len*8))-1) + } else { + data + } + } else { + let mut result = 0; + for b in &d.data[d.start..d.end] { + result = (result<<8) + (*b as u64); + } + result + } } - pub fn doc_as_i8(d: Doc) -> i8 { doc_as_u8(d) as i8 } - pub fn doc_as_i16(d: Doc) -> i16 { doc_as_u16(d) as i16 } - pub fn doc_as_i32(d: Doc) -> i32 { doc_as_u32(d) as i32 } - pub fn doc_as_i64(d: Doc) -> i64 { doc_as_u64(d) as i64 } + #[inline] pub fn doc_as_u16(d: Doc) -> u16 { doc_as_u64(d) as u16 } + #[inline] pub fn doc_as_u32(d: Doc) -> u32 { doc_as_u64(d) as u32 } + + #[inline] pub fn doc_as_i8(d: Doc) -> i8 { doc_as_u8(d) as i8 } + #[inline] pub fn doc_as_i16(d: Doc) -> i16 { doc_as_u16(d) as i16 } + #[inline] pub fn doc_as_i32(d: Doc) -> i32 { doc_as_u32(d) as i32 } + #[inline] pub fn doc_as_i64(d: Doc) -> i64 { doc_as_u64(d) as i64 } pub struct Decoder<'a> { parent: Doc<'a>, @@ -996,35 +1003,43 @@ pub mod writer { pub fn wr_tagged_u64(&mut self, tag_id: usize, v: u64) -> EncodeResult { let bytes: [u8; 8] = unsafe { mem::transmute(v.to_be()) }; - self.wr_tagged_bytes(tag_id, &bytes) + // tagged integers are emitted in big-endian, with no + // leading zeros. + let leading_zero_bytes = v.leading_zeros()/8; + self.wr_tagged_bytes(tag_id, &bytes[leading_zero_bytes as usize..]) } - pub fn wr_tagged_u32(&mut self, tag_id: usize, v: u32) -> EncodeResult{ - let bytes: [u8; 4] = unsafe { mem::transmute(v.to_be()) }; - self.wr_tagged_bytes(tag_id, &bytes) + #[inline] + pub fn wr_tagged_u32(&mut self, tag_id: usize, v: u32) -> EncodeResult { + self.wr_tagged_u64(tag_id, v as u64) } + #[inline] pub fn wr_tagged_u16(&mut self, tag_id: usize, v: u16) -> EncodeResult { - let bytes: [u8; 2] = unsafe { mem::transmute(v.to_be()) }; - self.wr_tagged_bytes(tag_id, &bytes) + self.wr_tagged_u64(tag_id, v as u64) } + #[inline] pub fn wr_tagged_u8(&mut self, tag_id: usize, v: u8) -> EncodeResult { self.wr_tagged_bytes(tag_id, &[v]) } + #[inline] pub fn wr_tagged_i64(&mut self, tag_id: usize, v: i64) -> EncodeResult { self.wr_tagged_u64(tag_id, v as u64) } + #[inline] pub fn wr_tagged_i32(&mut self, tag_id: usize, v: i32) -> EncodeResult { self.wr_tagged_u32(tag_id, v as u32) } + #[inline] pub fn wr_tagged_i16(&mut self, tag_id: usize, v: i16) -> EncodeResult { self.wr_tagged_u16(tag_id, v as u16) } + #[inline] pub fn wr_tagged_i8(&mut self, tag_id: usize, v: i8) -> EncodeResult { self.wr_tagged_bytes(tag_id, &[v as u8]) } From ce02aa494283fa238aa9ce435e8e82a52088fd20 Mon Sep 17 00:00:00 2001 From: Ariel Ben-Yehuda Date: Thu, 17 Sep 2015 20:50:27 +0300 Subject: [PATCH 05/10] don't mark_stable_position needlessly in tyencode another 1% improvement in libcore size - also 1% in librustc 550076 liballoc-bb943c5a.rlib 1425150 liballoc_jemalloc-bb943c5a.rlib 10100 liballoc_system-bb943c5a.rlib 149372 libarena-bb943c5a.rlib 3964144 libcollections-bb943c5a.rlib 17744342 libcore-bb943c5a.rlib 197420 libflate-bb943c5a.rlib 241582 libfmt_macros-bb943c5a.rlib 550560 libgetopts-bb943c5a.rlib 219444 libgraphviz-bb943c5a.rlib 402668 liblibc-bb943c5a.rlib 187158 liblog-bb943c5a.rlib 704588 librand-bb943c5a.rlib 594522 librbml-bb943c5a.rlib 1392516 librustc_back-bb943c5a.rlib 38196500 librustc-bb943c5a.rlib 12826 librustc_bitflags-bb943c5a.rlib 2286918 librustc_borrowck-bb943c5a.rlib 561714 librustc_data_structures-bb943c5a.rlib 9356400 librustc_driver-bb943c5a.rlib 9378650 librustc_front-bb943c5a.rlib 1603680 librustc_lint-bb943c5a.rlib 79184908 librustc_llvm-bb943c5a.rlib 4746824 librustc_mir-bb943c5a.rlib 3532474 librustc_platform_intrinsics-bb943c5a.rlib 592664 librustc_privacy-bb943c5a.rlib 3114986 librustc_resolve-bb943c5a.rlib 14153174 librustc_trans-bb943c5a.rlib 11918356 librustc_typeck-bb943c5a.rlib 1669986 librustc_unicode-bb943c5a.rlib 15611582 librustdoc-bb943c5a.rlib 2836912 libserialize-bb943c5a.rlib 8549994 libstd-bb943c5a.rlib 30399156 libsyntax-bb943c5a.rlib 907058 libterm-bb943c5a.rlib --- src/librustc/metadata/tyencode.rs | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/src/librustc/metadata/tyencode.rs b/src/librustc/metadata/tyencode.rs index 3176f5c9cc42f..489d213879c9a 100644 --- a/src/librustc/metadata/tyencode.rs +++ b/src/librustc/metadata/tyencode.rs @@ -14,6 +14,7 @@ #![allow(non_camel_case_types)] use std::cell::RefCell; +use std::str; use std::io::prelude::*; use middle::def_id::DefId; @@ -173,12 +174,18 @@ pub fn enc_ty<'a, 'tcx>(w: &mut Encoder, cx: &ctxt<'a, 'tcx>, t: Ty<'tcx>) { return len; } let abbrev_len = 3 + estimate_sz(pos) + estimate_sz(len); - if abbrev_len < len { - // I.e. it's actually an abbreviation. - cx.abbrevs.borrow_mut().insert(t, ty_abbrev { - s: format!("#{:x}:{:x}#", pos, len) - }); - } + cx.abbrevs.borrow_mut().insert(t, ty_abbrev { + s: if abbrev_len < len { + format!("#{:x}:{:x}#", pos, len) + } else { + // if the abbreviation is longer than the real type, + // don't use #-notation. However, insert it here so + // other won't have to `mark_stable_position` + str::from_utf8( + &w.writer.get_ref()[pos as usize..end as usize] + ).unwrap().to_owned() + } + }); } fn enc_mutability(w: &mut Encoder, mt: hir::Mutability) { From b74219964c1e86129cffc952a5e2ed3c03f052c1 Mon Sep 17 00:00:00 2001 From: Ariel Ben-Yehuda Date: Thu, 17 Sep 2015 22:12:39 +0300 Subject: [PATCH 06/10] improve the tyencode abbrev format 3% win on libcore 528828 liballoc-bb943c5a.rlib 1425126 liballoc_jemalloc-bb943c5a.rlib 10090 liballoc_system-bb943c5a.rlib 144904 libarena-bb943c5a.rlib 3773896 libcollections-bb943c5a.rlib 17075242 libcore-bb943c5a.rlib 195770 libflate-bb943c5a.rlib 234702 libfmt_macros-bb943c5a.rlib 536342 libgetopts-bb943c5a.rlib 212028 libgraphviz-bb943c5a.rlib 397068 liblibc-bb943c5a.rlib 185038 liblog-bb943c5a.rlib 680782 librand-bb943c5a.rlib 577574 librbml-bb943c5a.rlib 1381992 librustc_back-bb943c5a.rlib 37554736 librustc-bb943c5a.rlib 12826 librustc_bitflags-bb943c5a.rlib 2257392 librustc_borrowck-bb943c5a.rlib 533858 librustc_data_structures-bb943c5a.rlib 9338878 librustc_driver-bb943c5a.rlib 8960016 librustc_front-bb943c5a.rlib 1594212 librustc_lint-bb943c5a.rlib 79159342 librustc_llvm-bb943c5a.rlib 4590656 librustc_mir-bb943c5a.rlib 3529292 librustc_platform_intrinsics-bb943c5a.rlib 590688 librustc_privacy-bb943c5a.rlib 3084134 librustc_resolve-bb943c5a.rlib 14032890 librustc_trans-bb943c5a.rlib 11833852 librustc_typeck-bb943c5a.rlib 1641496 librustc_unicode-bb943c5a.rlib 15611582 librustdoc-bb943c5a.rlib 2693764 libserialize-bb943c5a.rlib 8266920 libstd-bb943c5a.rlib 29573790 libsyntax-bb943c5a.rlib 895484 libterm-bb943c5a.rlib --- src/librbml/lib.rs | 2 +- src/librustc/metadata/encoder.rs | 4 ++-- src/librustc/metadata/tydecode.rs | 26 ++++++++------------------ src/librustc/metadata/tyencode.rs | 29 +++++++++++++---------------- src/librustc/middle/ty/mod.rs | 1 - src/librustc_trans/back/link.rs | 2 +- 6 files changed, 25 insertions(+), 39 deletions(-) diff --git a/src/librbml/lib.rs b/src/librbml/lib.rs index dbd6ba700fa1d..4f7bbe9e02725 100644 --- a/src/librbml/lib.rs +++ b/src/librbml/lib.rs @@ -914,7 +914,7 @@ pub mod writer { } } - fn write_vuint(w: &mut W, n: usize) -> EncodeResult { + pub fn write_vuint(w: &mut W, n: usize) -> EncodeResult { if n < 0x7f { return write_sized_vuint(w, n, 1); } if n < 0x4000 { return write_sized_vuint(w, n, 2); } if n < 0x200000 { return write_sized_vuint(w, n, 3); } diff --git a/src/librustc/metadata/encoder.rs b/src/librustc/metadata/encoder.rs index fd10639fbc7a1..822887a9c12a2 100644 --- a/src/librustc/metadata/encoder.rs +++ b/src/librustc/metadata/encoder.rs @@ -2150,7 +2150,7 @@ fn encode_metadata_inner(wr: &mut Cursor>, } // Get the encoded string for a type -pub fn encoded_ty<'tcx>(tcx: &ty::ctxt<'tcx>, t: Ty<'tcx>) -> String { +pub fn encoded_ty<'tcx>(tcx: &ty::ctxt<'tcx>, t: Ty<'tcx>) -> Vec { let mut wr = Cursor::new(Vec::new()); tyencode::enc_ty(&mut Encoder::new(&mut wr), &tyencode::ctxt { diag: tcx.sess.diagnostic(), @@ -2158,5 +2158,5 @@ pub fn encoded_ty<'tcx>(tcx: &ty::ctxt<'tcx>, t: Ty<'tcx>) -> String { tcx: tcx, abbrevs: &RefCell::new(FnvHashMap()) }, t); - String::from_utf8(wr.into_inner()).unwrap() + wr.into_inner() } diff --git a/src/librustc/metadata/tydecode.rs b/src/librustc/metadata/tydecode.rs index abc0429e7d297..8e5b09b81c7ac 100644 --- a/src/librustc/metadata/tydecode.rs +++ b/src/librustc/metadata/tydecode.rs @@ -125,6 +125,12 @@ impl<'a,'tcx> TyDecoder<'a,'tcx> { return &self.data[start_pos..end_pos]; } + fn parse_vuint(&mut self) -> usize { + let res = rbml::reader::vuint_at(self.data, self.pos).unwrap(); + self.pos = res.next; + res.val + } + fn parse_name(&mut self, last: char) -> ast::Name { fn is_last(b: char, c: char) -> bool { return c == b; } let bytes = self.scan(|a| is_last(last, a)); @@ -405,11 +411,8 @@ impl<'a,'tcx> TyDecoder<'a,'tcx> { // we return it (modulo closure types, see below). But if not, then we // jump to offset 123 and read the type from there. - let pos = self.parse_hex(); - assert_eq!(self.next(), ':'); - let len = self.parse_hex(); - assert_eq!(self.next(), '#'); - let key = ty::CReaderCacheKey {cnum: self.krate, pos: pos, len: len }; + let pos = self.parse_vuint(); + let key = ty::CReaderCacheKey { cnum: self.krate, pos: pos }; match tcx.rcache.borrow().get(&key).cloned() { Some(tt) => { // If there is a closure buried in the type some where, then we @@ -508,19 +511,6 @@ impl<'a,'tcx> TyDecoder<'a,'tcx> { subst::ParamSpace::from_uint(self.parse_uint()) } - fn parse_hex(&mut self) -> usize { - let mut n = 0; - loop { - let cur = self.peek(); - if (cur < '0' || cur > '9') && (cur < 'a' || cur > 'f') { return n; } - self.pos = self.pos + 1; - n *= 16; - if '0' <= cur && cur <= '9' { - n += (cur as usize) - ('0' as usize); - } else { n += 10 + (cur as usize) - ('a' as usize); } - }; - } - fn parse_abi_set(&mut self) -> abi::Abi { assert_eq!(self.next(), '['); let bytes = self.scan(|c| c == ']'); diff --git a/src/librustc/metadata/tyencode.rs b/src/librustc/metadata/tyencode.rs index 489d213879c9a..4a9257b60c48a 100644 --- a/src/librustc/metadata/tyencode.rs +++ b/src/librustc/metadata/tyencode.rs @@ -14,7 +14,7 @@ #![allow(non_camel_case_types)] use std::cell::RefCell; -use std::str; +use std::io::Cursor; use std::io::prelude::*; use middle::def_id::DefId; @@ -31,7 +31,7 @@ use syntax::abi::Abi; use syntax::ast; use syntax::diagnostic::SpanHandler; -use rbml::writer::Encoder; +use rbml::writer::{self, Encoder}; macro_rules! mywrite { ($w:expr, $($arg:tt)*) => ({ write!($w.writer, $($arg)*); }) } @@ -48,14 +48,14 @@ pub struct ctxt<'a, 'tcx: 'a> { // Extra parameters are for converting to/from def_ids in the string rep. // Whatever format you choose should not contain pipe characters. pub struct ty_abbrev { - s: String + s: Vec } pub type abbrev_map<'tcx> = RefCell, ty_abbrev>>; pub fn enc_ty<'a, 'tcx>(w: &mut Encoder, cx: &ctxt<'a, 'tcx>, t: Ty<'tcx>) { match cx.abbrevs.borrow_mut().get(&t) { - Some(a) => { w.writer.write_all(a.s.as_bytes()); return; } + Some(a) => { w.writer.write_all(&a.s); return; } None => {} } @@ -167,23 +167,20 @@ pub fn enc_ty<'a, 'tcx>(w: &mut Encoder, cx: &ctxt<'a, 'tcx>, t: Ty<'tcx>) { let end = w.mark_stable_position(); let len = end - pos; - fn estimate_sz(u: u64) -> u64 { - let mut n = u; - let mut len = 0; - while n != 0 { len += 1; n = n >> 4; } - return len; - } - let abbrev_len = 3 + estimate_sz(pos) + estimate_sz(len); + + let buf: &mut [u8] = &mut [0; 16]; // vuint < 15 bytes + let mut abbrev = Cursor::new(buf); + abbrev.write_all(b"#"); + writer::write_vuint(&mut abbrev, pos as usize); + cx.abbrevs.borrow_mut().insert(t, ty_abbrev { - s: if abbrev_len < len { - format!("#{:x}:{:x}#", pos, len) + s: if abbrev.position() < len { + abbrev.get_ref()[..abbrev.position() as usize].to_owned() } else { // if the abbreviation is longer than the real type, // don't use #-notation. However, insert it here so // other won't have to `mark_stable_position` - str::from_utf8( - &w.writer.get_ref()[pos as usize..end as usize] - ).unwrap().to_owned() + w.writer.get_ref()[pos as usize..end as usize].to_owned() } }); } diff --git a/src/librustc/middle/ty/mod.rs b/src/librustc/middle/ty/mod.rs index 7ec39619d9cfd..45522c4e457e1 100644 --- a/src/librustc/middle/ty/mod.rs +++ b/src/librustc/middle/ty/mod.rs @@ -366,7 +366,6 @@ pub type MethodMap<'tcx> = FnvHashMap>; pub struct CReaderCacheKey { pub cnum: CrateNum, pub pos: usize, - pub len: usize } /// A restriction that certain types must be the same size. The use of diff --git a/src/librustc_trans/back/link.rs b/src/librustc_trans/back/link.rs index 2e18b50a45cfe..3a98df0bdfd74 100644 --- a/src/librustc_trans/back/link.rs +++ b/src/librustc_trans/back/link.rs @@ -214,7 +214,7 @@ fn symbol_hash<'tcx>(tcx: &ty::ctxt<'tcx>, symbol_hasher.input_str(&meta[..]); } symbol_hasher.input_str("-"); - symbol_hasher.input_str(&encoder::encoded_ty(tcx, t)); + symbol_hasher.input(&encoder::encoded_ty(tcx, t)); // Prefix with 'h' so that it never blends into adjacent digits let mut hash = String::from("h"); hash.push_str(&truncated_hash_result(symbol_hasher)); From a1c921e8a5797d5e770a633d53116a24deab8067 Mon Sep 17 00:00:00 2001 From: Ariel Ben-Yehuda Date: Sat, 19 Sep 2015 23:28:21 +0300 Subject: [PATCH 07/10] don't duplicate item types between encoder <-> astencode a 5% win on libcore 512576 liballoc-bb943c5a.rlib 1425106 liballoc_jemalloc-bb943c5a.rlib 10070 liballoc_system-bb943c5a.rlib 141332 libarena-bb943c5a.rlib 3611586 libcollections-bb943c5a.rlib 16293400 libcore-bb943c5a.rlib 195018 libflate-bb943c5a.rlib 231940 libfmt_macros-bb943c5a.rlib 532704 libgetopts-bb943c5a.rlib 208094 libgraphviz-bb943c5a.rlib 383522 liblibc-bb943c5a.rlib 183786 liblog-bb943c5a.rlib 658332 librand-bb943c5a.rlib 567676 librbml-bb943c5a.rlib 1376114 librustc_back-bb943c5a.rlib 37134688 librustc-bb943c5a.rlib 12826 librustc_bitflags-bb943c5a.rlib 2241942 librustc_borrowck-bb943c5a.rlib 513598 librustc_data_structures-bb943c5a.rlib 9340348 librustc_driver-bb943c5a.rlib 8880472 librustc_front-bb943c5a.rlib 1590548 librustc_lint-bb943c5a.rlib 79149202 librustc_llvm-bb943c5a.rlib 4536740 librustc_mir-bb943c5a.rlib 3528866 librustc_platform_intrinsics-bb943c5a.rlib 588514 librustc_privacy-bb943c5a.rlib 3068562 librustc_resolve-bb943c5a.rlib 13982508 librustc_trans-bb943c5a.rlib 11799790 librustc_typeck-bb943c5a.rlib 1637532 librustc_unicode-bb943c5a.rlib 15611582 librustdoc-bb943c5a.rlib 2649520 libserialize-bb943c5a.rlib 8095050 libstd-bb943c5a.rlib 29391260 libsyntax-bb943c5a.rlib 891210 libterm-bb943c5a.rlib --- src/librustc/metadata/common.rs | 2 +- src/librustc/middle/astencode.rs | 169 ++++++++++--------------------- 2 files changed, 52 insertions(+), 119 deletions(-) diff --git a/src/librustc/metadata/common.rs b/src/librustc/metadata/common.rs index bf099a7e52c06..e27178b32f9e2 100644 --- a/src/librustc/metadata/common.rs +++ b/src/librustc/metadata/common.rs @@ -125,7 +125,7 @@ enum_from_u32! { tag_table_node_type = 0x57, tag_table_item_subst = 0x58, tag_table_freevars = 0x59, - tag_table_tcache = 0x5a, + // GAP 0x5a tag_table_param_defs = 0x5b, // GAP 0x5c, 0x5d, 0x5e tag_table_method_map = 0x5f, diff --git a/src/librustc/middle/astencode.rs b/src/librustc/middle/astencode.rs index 270734a21e239..a6a048710369b 100644 --- a/src/librustc/middle/astencode.rs +++ b/src/librustc/middle/astencode.rs @@ -35,7 +35,6 @@ use middle::def_id::{DefId, LOCAL_CRATE}; use middle::privacy::{AllPublic, LastMod}; use middle::region; use middle::subst; -use middle::subst::VecPerParamSpace; use middle::ty::{self, Ty}; use syntax::{ast, ast_util, codemap}; @@ -167,6 +166,7 @@ pub fn decode_inlined_item<'tcx>(cdata: &cstore::crate_metadata, name); region::resolve_inlined_item(&tcx.sess, &tcx.region_maps, ii); decode_side_tables(dcx, ast_doc); + copy_item_types(dcx, ii); match *ii { InlinedItem::Item(ref i) => { debug!(">>> DECODED ITEM >>>\n{}\n<<< DECODED ITEM <<<", @@ -205,6 +205,17 @@ impl<'a, 'b, 'tcx> DecodeContext<'a, 'b, 'tcx> { (id.wrapping_sub(self.from_id_range.min).wrapping_add(self.to_id_range.min)) } + /// Gets the original crate's DefId from a translated internal + /// def-id. + pub fn reverse_tr_id(&self, id: ast::NodeId) -> DefId { + // from_id_range should be non-empty + assert!(!self.from_id_range.empty()); + // Use wrapping arithmetic because otherwise it introduces control flow. + // Maybe we should just have the control flow? -- aatch + let node = id.wrapping_sub(self.to_id_range.min).wrapping_add(self.from_id_range.min); + DefId { krate: self.cdata.cnum, node: node } + } + /// Translates an EXTERNAL def-id, converting the crate number from the one used in the encoded /// data to the current crate numbers.. By external, I mean that it be translated to a /// reference to the item in its original crate, as opposed to being translated to a reference @@ -576,36 +587,6 @@ pub fn encode_cast_kind(ebml_w: &mut Encoder, kind: cast::CastKind) { kind.encode(ebml_w).unwrap(); } -pub trait vtable_decoder_helpers<'tcx> { - fn read_vec_per_param_space(&mut self, f: F) -> VecPerParamSpace where - F: FnMut(&mut Self) -> T; -} - -impl<'tcx, 'a> vtable_decoder_helpers<'tcx> for reader::Decoder<'a> { - fn read_vec_per_param_space(&mut self, mut f: F) -> VecPerParamSpace where - F: FnMut(&mut reader::Decoder<'a>) -> T, - { - let types = self.read_to_vec(|this| Ok(f(this))).unwrap(); - let selfs = self.read_to_vec(|this| Ok(f(this))).unwrap(); - let fns = self.read_to_vec(|this| Ok(f(this))).unwrap(); - VecPerParamSpace::new(types, selfs, fns) - } -} - -// ___________________________________________________________________________ -// - -fn encode_vec_per_param_space(rbml_w: &mut Encoder, - v: &subst::VecPerParamSpace, - mut f: F) where - F: FnMut(&mut Encoder, &T), -{ - for &space in &subst::ParamSpace::all() { - rbml_w.emit_from_vec(v.get_slice(space), - |rbml_w, n| Ok(f(rbml_w, n))).unwrap(); - } -} - // ______________________________________________________________________ // Encoding and decoding the side tables @@ -632,14 +613,10 @@ trait rbml_writer_helpers<'tcx> { fn emit_tys<'a>(&mut self, ecx: &e::EncodeContext<'a, 'tcx>, tys: &[Ty<'tcx>]); fn emit_type_param_def<'a>(&mut self, ecx: &e::EncodeContext<'a, 'tcx>, type_param_def: &ty::TypeParameterDef<'tcx>); - fn emit_region_param_def(&mut self, ecx: &e::EncodeContext, - region_param_def: &ty::RegionParameterDef); fn emit_predicate<'a>(&mut self, ecx: &e::EncodeContext<'a, 'tcx>, predicate: &ty::Predicate<'tcx>); fn emit_trait_ref<'a>(&mut self, ecx: &e::EncodeContext<'a, 'tcx>, ty: &ty::TraitRef<'tcx>); - fn emit_type_scheme<'a>(&mut self, ecx: &e::EncodeContext<'a, 'tcx>, - type_scheme: ty::TypeScheme<'tcx>); fn emit_substs<'a>(&mut self, ecx: &e::EncodeContext<'a, 'tcx>, substs: &subst::Substs<'tcx>); fn emit_existential_bounds<'b>(&mut self, ecx: &e::EncodeContext<'b,'tcx>, @@ -688,14 +665,7 @@ impl<'a, 'tcx> rbml_writer_helpers<'tcx> for Encoder<'a> { type_param_def)) }); } - fn emit_region_param_def(&mut self, ecx: &e::EncodeContext, - region_param_def: &ty::RegionParameterDef) { - self.emit_opaque(|this| { - Ok(tyencode::enc_region_param_def(this, - &ecx.ty_str_ctxt(), - region_param_def)) - }); - } + fn emit_predicate<'b>(&mut self, ecx: &e::EncodeContext<'b, 'tcx>, predicate: &ty::Predicate<'tcx>) { self.emit_opaque(|this| { @@ -705,32 +675,6 @@ impl<'a, 'tcx> rbml_writer_helpers<'tcx> for Encoder<'a> { }); } - fn emit_type_scheme<'b>(&mut self, - ecx: &e::EncodeContext<'b, 'tcx>, - type_scheme: ty::TypeScheme<'tcx>) { - use serialize::Encoder; - - self.emit_struct("TypeScheme", 2, |this| { - this.emit_struct_field("generics", 0, |this| { - this.emit_struct("Generics", 2, |this| { - this.emit_struct_field("types", 0, |this| { - Ok(encode_vec_per_param_space( - this, &type_scheme.generics.types, - |this, def| this.emit_type_param_def(ecx, def))) - }); - this.emit_struct_field("regions", 1, |this| { - Ok(encode_vec_per_param_space( - this, &type_scheme.generics.regions, - |this, def| this.emit_region_param_def(ecx, def))) - }) - }) - }); - this.emit_struct_field("ty", 1, |this| { - Ok(this.emit_ty(ecx, type_scheme.ty)) - }) - }); - } - fn emit_existential_bounds<'b>(&mut self, ecx: &e::EncodeContext<'b,'tcx>, bounds: &ty::ExistentialBounds<'tcx>) { self.emit_opaque(|this| Ok(tyencode::enc_existential_bounds(this, @@ -950,14 +894,6 @@ fn encode_side_tables_for_id(ecx: &e::EncodeContext, } } - let lid = DefId { krate: LOCAL_CRATE, node: id }; - if let Some(type_scheme) = tcx.tcache.borrow().get(&lid) { - rbml_w.tag(c::tag_table_tcache, |rbml_w| { - rbml_w.id(id); - rbml_w.emit_type_scheme(ecx, type_scheme.clone()); - }) - } - if let Some(type_param_def) = tcx.ty_param_defs.borrow().get(&id) { rbml_w.tag(c::tag_table_param_defs, |rbml_w| { rbml_w.id(id); @@ -1051,12 +987,8 @@ trait rbml_decoder_decoder_helpers<'tcx> { -> ty::PolyTraitRef<'tcx>; fn read_type_param_def<'a, 'b>(&mut self, dcx: &DecodeContext<'a, 'b, 'tcx>) -> ty::TypeParameterDef<'tcx>; - fn read_region_param_def(&mut self, dcx: &DecodeContext) - -> ty::RegionParameterDef; fn read_predicate<'a, 'b>(&mut self, dcx: &DecodeContext<'a, 'b, 'tcx>) -> ty::Predicate<'tcx>; - fn read_type_scheme<'a, 'b>(&mut self, dcx: &DecodeContext<'a, 'b, 'tcx>) - -> ty::TypeScheme<'tcx>; fn read_existential_bounds<'a, 'b>(&mut self, dcx: &DecodeContext<'a, 'b, 'tcx>) -> ty::ExistentialBounds<'tcx>; fn read_substs<'a, 'b>(&mut self, dcx: &DecodeContext<'a, 'b, 'tcx>) @@ -1177,44 +1109,13 @@ impl<'a, 'tcx> rbml_decoder_decoder_helpers<'tcx> for reader::Decoder<'a> { -> ty::TypeParameterDef<'tcx> { self.read_ty_encoded(dcx, |decoder| decoder.parse_type_param_def()) } - fn read_region_param_def(&mut self, dcx: &DecodeContext) - -> ty::RegionParameterDef { - self.read_ty_encoded(dcx, |decoder| decoder.parse_region_param_def()) - } + fn read_predicate<'b, 'c>(&mut self, dcx: &DecodeContext<'b, 'c, 'tcx>) -> ty::Predicate<'tcx> { self.read_ty_encoded(dcx, |decoder| decoder.parse_predicate()) } - fn read_type_scheme<'b, 'c>(&mut self, dcx: &DecodeContext<'b, 'c, 'tcx>) - -> ty::TypeScheme<'tcx> { - self.read_struct("TypeScheme", 3, |this| { - Ok(ty::TypeScheme { - generics: this.read_struct_field("generics", 0, |this| { - this.read_struct("Generics", 2, |this| { - Ok(ty::Generics { - types: - this.read_struct_field("types", 0, |this| { - Ok(this.read_vec_per_param_space( - |this| this.read_type_param_def(dcx))) - }).unwrap(), - - regions: - this.read_struct_field("regions", 1, |this| { - Ok(this.read_vec_per_param_space( - |this| this.read_region_param_def(dcx))) - }).unwrap(), - }) - }) - }).unwrap(), - ty: this.read_struct_field("ty", 1, |this| { - Ok(this.read_ty(dcx)) - }).unwrap() - }) - }).unwrap() - } - fn read_existential_bounds<'b, 'c>(&mut self, dcx: &DecodeContext<'b, 'c, 'tcx>) -> ty::ExistentialBounds<'tcx> { @@ -1450,11 +1351,6 @@ fn decode_side_tables(dcx: &DecodeContext, let ub = val_dsr.read_upvar_capture(dcx); dcx.tcx.tables.borrow_mut().upvar_capture_map.insert(upvar_id, ub); } - c::tag_table_tcache => { - let type_scheme = val_dsr.read_type_scheme(dcx); - let lid = DefId { krate: LOCAL_CRATE, node: id }; - dcx.tcx.register_item_type(lid, type_scheme); - } c::tag_table_param_defs => { let bounds = val_dsr.read_type_param_def(dcx); dcx.tcx.ty_param_defs.borrow_mut().insert(id, bounds); @@ -1506,6 +1402,43 @@ fn decode_side_tables(dcx: &DecodeContext, } } +// copy the tcache entries from the original item to the new +// inlined item +fn copy_item_types(dcx: &DecodeContext, ii: &InlinedItem) { + fn copy_item_type(dcx: &DecodeContext, inlined_node: ast::NodeId) { + let inlined_did = DefId::local(inlined_node); + let remote_did = dcx.reverse_tr_id(inlined_node); + dcx.tcx.register_item_type(inlined_did, + dcx.tcx.lookup_item_type(remote_did)); + + } + // copy the entry for the item itself + let item_node_id = match ii { + &InlinedItem::Item(ref i) => i.id, + &InlinedItem::TraitItem(_, ref ti) => ti.id, + &InlinedItem::ImplItem(_, ref ii) => ii.id, + &InlinedItem::Foreign(ref fi) => fi.id + }; + copy_item_type(dcx, item_node_id); + + // copy the entries of inner items + if let &InlinedItem::Item(ref item) = ii { + match item.node { + hir::ItemEnum(ref def, _) => { + for variant in &def.variants { + copy_item_type(dcx, variant.node.id); + } + } + hir::ItemStruct(ref def, _) => { + if let Some(ctor_id) = def.ctor_id { + copy_item_type(dcx, ctor_id); + } + } + _ => {} + } + } +} + // ______________________________________________________________________ // Testing of astencode_gen From 8557cb47cba1f343563f92b14151661425573270 Mon Sep 17 00:00:00 2001 From: Ariel Ben-Yehuda Date: Sun, 20 Sep 2015 14:15:21 +0300 Subject: [PATCH 08/10] don't store method_fty It is redundant with the item type. This is not much of a win, as there are really not *that* many methods, but it makes the code uglier. --- src/librustc/metadata/common.rs | 3 +-- src/librustc/metadata/decoder.rs | 16 +++++++--------- src/librustc/metadata/encoder.rs | 18 ------------------ 3 files changed, 8 insertions(+), 29 deletions(-) diff --git a/src/librustc/metadata/common.rs b/src/librustc/metadata/common.rs index e27178b32f9e2..c436963f6ad8d 100644 --- a/src/librustc/metadata/common.rs +++ b/src/librustc/metadata/common.rs @@ -163,8 +163,7 @@ pub const tag_lang_items_missing: usize = 0x76; pub const tag_item_unnamed_field: usize = 0x77; pub const tag_items_data_item_visibility: usize = 0x78; -// GAP 0x79 -pub const tag_item_method_fty: usize = 0x7a; +// GAP 0x79, 0x7a pub const tag_mod_child: usize = 0x7b; pub const tag_misc_info: usize = 0x108; // top-level only diff --git a/src/librustc/metadata/decoder.rs b/src/librustc/metadata/decoder.rs index 565ec2414f41d..69d3e55835f5b 100644 --- a/src/librustc/metadata/decoder.rs +++ b/src/librustc/metadata/decoder.rs @@ -219,14 +219,6 @@ fn maybe_doc_type<'tcx>(doc: rbml::Doc, tcx: &ty::ctxt<'tcx>, cdata: Cmd) -> Opt }) } -fn doc_method_fty<'tcx>(doc: rbml::Doc, tcx: &ty::ctxt<'tcx>, - cdata: Cmd) -> ty::BareFnTy<'tcx> { - let tp = reader::get_doc(doc, tag_item_method_fty); - TyDecoder::with_doc(tcx, cdata.cnum, tp, - &mut |_, did| translate_def_id(cdata, did)) - .parse_bare_fn_ty() -} - pub fn item_type<'tcx>(_item_id: DefId, item: rbml::Doc, tcx: &ty::ctxt<'tcx>, cdata: Cmd) -> Ty<'tcx> { doc_type(item, tcx, cdata) @@ -880,7 +872,13 @@ pub fn get_impl_or_trait_item<'tcx>(intr: Rc, Some('r') | Some('p') => { let generics = doc_generics(item_doc, tcx, cdata, tag_method_ty_generics); let predicates = doc_predicates(item_doc, tcx, cdata, tag_method_ty_generics); - let fty = doc_method_fty(item_doc, tcx, cdata); + let ity = tcx.lookup_item_type(def_id).ty; + let fty = match ity.sty { + ty::TyBareFn(_, fty) => fty.clone(), + _ => tcx.sess.bug(&format!( + "the type {:?} of the method {:?} is not a function?", + ity, name)) + }; let explicit_self = get_explicit_self(item_doc); ty::MethodTraitItem(Rc::new(ty::Method::new(name, diff --git a/src/librustc/metadata/encoder.rs b/src/librustc/metadata/encoder.rs index 822887a9c12a2..dd23584994b9a 100644 --- a/src/librustc/metadata/encoder.rs +++ b/src/librustc/metadata/encoder.rs @@ -235,22 +235,6 @@ fn encode_region(ecx: &EncodeContext, rbml_w.end_tag(); } -fn encode_method_fty<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>, - rbml_w: &mut Encoder, - typ: &ty::BareFnTy<'tcx>) { - rbml_w.start_tag(tag_item_method_fty); - - let ty_str_ctxt = &tyencode::ctxt { - diag: ecx.diag, - ds: def_to_string, - tcx: ecx.tcx, - abbrevs: &ecx.type_abbrevs - }; - tyencode::enc_bare_fn_ty(rbml_w, ty_str_ctxt, typ); - - rbml_w.end_tag(); -} - fn encode_symbol(ecx: &EncodeContext, rbml_w: &mut Encoder, id: NodeId) { @@ -755,7 +739,6 @@ fn encode_method_ty_fields<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>, encode_generics(rbml_w, ecx, index, &method_ty.generics, &method_ty.predicates, tag_method_ty_generics); - encode_method_fty(ecx, rbml_w, &method_ty.fty); encode_visibility(rbml_w, method_ty.vis); encode_explicit_self(rbml_w, &method_ty.explicit_self); match method_ty.explicit_self { @@ -826,7 +809,6 @@ fn encode_info_for_method<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>, let stab = stability::lookup(ecx.tcx, m.def_id); encode_stability(rbml_w, stab); - // The type for methods gets encoded twice, which is unfortunate. encode_bounds_and_type_for_item(rbml_w, ecx, index, m.def_id.local_id()); let elem = ast_map::PathName(m.name); From db817ceda4fe204261c9d1773dc137830e58e225 Mon Sep 17 00:00:00 2001 From: Ariel Ben-Yehuda Date: Tue, 29 Sep 2015 23:51:55 +0300 Subject: [PATCH 09/10] remove the code that encodes type parameter defs there are no type parameter defs in the relevant range --- src/librustc/metadata/common.rs | 4 +--- src/librustc/middle/astencode.rs | 29 ----------------------------- 2 files changed, 1 insertion(+), 32 deletions(-) diff --git a/src/librustc/metadata/common.rs b/src/librustc/metadata/common.rs index c436963f6ad8d..2ffccd2d9a585 100644 --- a/src/librustc/metadata/common.rs +++ b/src/librustc/metadata/common.rs @@ -125,9 +125,7 @@ enum_from_u32! { tag_table_node_type = 0x57, tag_table_item_subst = 0x58, tag_table_freevars = 0x59, - // GAP 0x5a - tag_table_param_defs = 0x5b, - // GAP 0x5c, 0x5d, 0x5e + // GAP 0x5a, 0x5b, 0x5c, 0x5d, 0x5e tag_table_method_map = 0x5f, // GAP 0x60 tag_table_adjustments = 0x61, diff --git a/src/librustc/middle/astencode.rs b/src/librustc/middle/astencode.rs index a6a048710369b..75826c690364e 100644 --- a/src/librustc/middle/astencode.rs +++ b/src/librustc/middle/astencode.rs @@ -611,8 +611,6 @@ trait rbml_writer_helpers<'tcx> { fn emit_region(&mut self, ecx: &e::EncodeContext, r: ty::Region); fn emit_ty<'a>(&mut self, ecx: &e::EncodeContext<'a, 'tcx>, ty: Ty<'tcx>); fn emit_tys<'a>(&mut self, ecx: &e::EncodeContext<'a, 'tcx>, tys: &[Ty<'tcx>]); - fn emit_type_param_def<'a>(&mut self, ecx: &e::EncodeContext<'a, 'tcx>, - type_param_def: &ty::TypeParameterDef<'tcx>); fn emit_predicate<'a>(&mut self, ecx: &e::EncodeContext<'a, 'tcx>, predicate: &ty::Predicate<'tcx>); fn emit_trait_ref<'a>(&mut self, ecx: &e::EncodeContext<'a, 'tcx>, @@ -657,15 +655,6 @@ impl<'a, 'tcx> rbml_writer_helpers<'tcx> for Encoder<'a> { self.emit_opaque(|this| Ok(e::write_trait_ref(ecx, this, trait_ref))); } - fn emit_type_param_def<'b>(&mut self, ecx: &e::EncodeContext<'b, 'tcx>, - type_param_def: &ty::TypeParameterDef<'tcx>) { - self.emit_opaque(|this| { - Ok(tyencode::enc_type_param_def(this, - &ecx.ty_str_ctxt(), - type_param_def)) - }); - } - fn emit_predicate<'b>(&mut self, ecx: &e::EncodeContext<'b, 'tcx>, predicate: &ty::Predicate<'tcx>) { self.emit_opaque(|this| { @@ -894,13 +883,6 @@ fn encode_side_tables_for_id(ecx: &e::EncodeContext, } } - if let Some(type_param_def) = tcx.ty_param_defs.borrow().get(&id) { - rbml_w.tag(c::tag_table_param_defs, |rbml_w| { - rbml_w.id(id); - rbml_w.emit_type_param_def(ecx, type_param_def) - }) - } - let method_call = ty::MethodCall::expr(id); if let Some(method) = tcx.tables.borrow().method_map.get(&method_call) { rbml_w.tag(c::tag_table_method_map, |rbml_w| { @@ -985,8 +967,6 @@ trait rbml_decoder_decoder_helpers<'tcx> { -> ty::TraitRef<'tcx>; fn read_poly_trait_ref<'a, 'b>(&mut self, dcx: &DecodeContext<'a, 'b, 'tcx>) -> ty::PolyTraitRef<'tcx>; - fn read_type_param_def<'a, 'b>(&mut self, dcx: &DecodeContext<'a, 'b, 'tcx>) - -> ty::TypeParameterDef<'tcx>; fn read_predicate<'a, 'b>(&mut self, dcx: &DecodeContext<'a, 'b, 'tcx>) -> ty::Predicate<'tcx>; fn read_existential_bounds<'a, 'b>(&mut self, dcx: &DecodeContext<'a, 'b, 'tcx>) @@ -1105,11 +1085,6 @@ impl<'a, 'tcx> rbml_decoder_decoder_helpers<'tcx> for reader::Decoder<'a> { ty::Binder(self.read_ty_encoded(dcx, |decoder| decoder.parse_trait_ref())) } - fn read_type_param_def<'b, 'c>(&mut self, dcx: &DecodeContext<'b, 'c, 'tcx>) - -> ty::TypeParameterDef<'tcx> { - self.read_ty_encoded(dcx, |decoder| decoder.parse_type_param_def()) - } - fn read_predicate<'b, 'c>(&mut self, dcx: &DecodeContext<'b, 'c, 'tcx>) -> ty::Predicate<'tcx> { @@ -1351,10 +1326,6 @@ fn decode_side_tables(dcx: &DecodeContext, let ub = val_dsr.read_upvar_capture(dcx); dcx.tcx.tables.borrow_mut().upvar_capture_map.insert(upvar_id, ub); } - c::tag_table_param_defs => { - let bounds = val_dsr.read_type_param_def(dcx); - dcx.tcx.ty_param_defs.borrow_mut().insert(id, bounds); - } c::tag_table_method_map => { let (autoderef, method) = val_dsr.read_method_callee(dcx); let method_call = ty::MethodCall { From eae41d3078562aef1cd4fc8a26f859c168ca4c4a Mon Sep 17 00:00:00 2001 From: Ariel Ben-Yehuda Date: Fri, 2 Oct 2015 16:44:26 +0300 Subject: [PATCH 10/10] unify the 2 impl indexes --- src/librustc/metadata/common.rs | 20 +++------ src/librustc/metadata/decoder.rs | 19 +++----- src/librustc/metadata/encoder.rs | 74 +++++++++++--------------------- src/librustc/middle/astencode.rs | 2 +- 4 files changed, 39 insertions(+), 76 deletions(-) diff --git a/src/librustc/metadata/common.rs b/src/librustc/metadata/common.rs index 85d589242426a..a4fee5b7aa805 100644 --- a/src/librustc/metadata/common.rs +++ b/src/librustc/metadata/common.rs @@ -133,8 +133,7 @@ enum_from_u32! { tag_table_method_map = 0x5f, // GAP 0x60 tag_table_adjustments = 0x61, - // GAP 0x62, 0x63 - // GAP 0x64, 0x65 + // GAP 0x62, 0x63, 0x64, 0x65 tag_table_upvar_capture_map = 0x66, // GAP 0x67, 0x68 tag_table_const_qualif = 0x69, @@ -163,22 +162,17 @@ pub const tag_lang_items_missing: usize = 0x76; pub const tag_item_unnamed_field: usize = 0x77; pub const tag_items_data_item_visibility: usize = 0x78; - -// GAP 0x79, 0x7a - +pub const tag_items_data_item_inherent_impl: usize = 0x79; +// GAP 0x7a pub const tag_mod_child: usize = 0x7b; pub const tag_misc_info: usize = 0x108; // top-level only pub const tag_misc_info_crate_items: usize = 0x7c; -// GAP 0x7d -// GAP 0x7e - pub const tag_impls: usize = 0x109; // top-level only -pub const tag_impls_impl: usize = 0x7f; -pub const tag_impls_impl_trait_def_id: usize = 0x8d; +pub const tag_impls_trait: usize = 0x7d; +pub const tag_impls_trait_impl: usize = 0x7e; -pub const tag_items_data_item_inherent_impl: usize = 0x80; -pub const tag_items_data_item_extension_impl: usize = 0x81; +// GAP 0x7f, 0x80, 0x81 pub const tag_native_libraries: usize = 0x10a; // top-level only pub const tag_native_libraries_lib: usize = 0x82; @@ -208,7 +202,7 @@ pub const tag_struct_field: usize = 0x8a; pub const tag_items_data_item_struct_ctor: usize = 0x8b; pub const tag_attribute_is_sugared_doc: usize = 0x8c; - +// GAP 0x8d pub const tag_items_data_region: usize = 0x8e; pub const tag_region_param_def: usize = 0x8f; diff --git a/src/librustc/metadata/decoder.rs b/src/librustc/metadata/decoder.rs index 28d801bb8c98b..8eea5b3553adf 100644 --- a/src/librustc/metadata/decoder.rs +++ b/src/librustc/metadata/decoder.rs @@ -1284,24 +1284,19 @@ pub fn each_implementation_for_trait(cdata: Cmd, mut callback: F) where F: FnMut(DefId), { - if cdata.cnum == def_id.krate { - let item_doc = cdata.lookup_item(def_id.index); - for impl_doc in reader::tagged_docs(item_doc, tag_items_data_item_extension_impl) { - callback(item_def_id(impl_doc, cdata)); - } - return; - } - // Do a reverse lookup beforehand to avoid touching the crate_num // hash map in the loop below. if let Some(crate_local_did) = reverse_translate_def_id(cdata, def_id) { let def_id_u64 = def_to_u64(crate_local_did); let impls_doc = reader::get_doc(rbml::Doc::new(cdata.data()), tag_impls); - for impl_doc in reader::tagged_docs(impls_doc, tag_impls_impl) { - let impl_trait = reader::get_doc(impl_doc, tag_impls_impl_trait_def_id); - if reader::doc_as_u64(impl_trait) == def_id_u64 { - callback(item_def_id(impl_doc, cdata)); + for trait_doc in reader::tagged_docs(impls_doc, tag_impls_trait) { + let trait_def_id = reader::get_doc(trait_doc, tag_def_id); + if reader::doc_as_u64(trait_def_id) != def_id_u64 { + continue; + } + for impl_doc in reader::tagged_docs(trait_doc, tag_impls_trait_impl) { + callback(translated_def_id(cdata, impl_doc)); } } } diff --git a/src/librustc/metadata/encoder.rs b/src/librustc/metadata/encoder.rs index caccdbd338269..9d2b1548f29d8 100644 --- a/src/librustc/metadata/encoder.rs +++ b/src/librustc/metadata/encoder.rs @@ -865,20 +865,6 @@ fn encode_inherent_implementations(ecx: &EncodeContext, } } -// Encodes the implementations of a trait defined in this crate. -fn encode_extension_implementations(ecx: &EncodeContext, - rbml_w: &mut Encoder, - trait_def_id: DefId) { - assert!(trait_def_id.is_local()); - let def = ecx.tcx.lookup_trait_def(trait_def_id); - - def.for_each_impl(ecx.tcx, |impl_def_id| { - rbml_w.start_tag(tag_items_data_item_extension_impl); - encode_def_id(rbml_w, impl_def_id); - rbml_w.end_tag(); - }); -} - fn encode_stability(rbml_w: &mut Encoder, stab_opt: Option<&attr::Stability>) { stab_opt.map(|stab| { rbml_w.start_tag(tag_items_data_item_stability); @@ -1256,9 +1242,6 @@ fn encode_info_for_item<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>, } encode_path(rbml_w, path.clone()); - // Encode the implementations of this trait. - encode_extension_implementations(ecx, rbml_w, def_id); - // Encode inherent implementations for this trait. encode_inherent_implementations(ecx, rbml_w, def_id); @@ -1763,53 +1746,44 @@ fn encode_struct_field_attrs(ecx: &EncodeContext, -struct ImplVisitor<'a, 'b:'a, 'c:'a, 'tcx:'b> { - ecx: &'a EncodeContext<'b, 'tcx>, - rbml_w: &'a mut Encoder<'c>, +struct ImplVisitor<'a, 'tcx:'a> { + tcx: &'a ty::ctxt<'tcx>, + impls: FnvHashMap> } -impl<'a, 'b, 'c, 'tcx, 'v> Visitor<'v> for ImplVisitor<'a, 'b, 'c, 'tcx> { +impl<'a, 'tcx, 'v> Visitor<'v> for ImplVisitor<'a, 'tcx> { fn visit_item(&mut self, item: &hir::Item) { - if let hir::ItemImpl(_, _, _, Some(ref trait_ref), _, _) = item.node { - let def_id = self.ecx.tcx.def_map.borrow().get(&trait_ref.ref_id).unwrap().def_id(); - - // Load eagerly if this is an implementation of the Drop trait - // or if the trait is not defined in this crate. - if Some(def_id) == self.ecx.tcx.lang_items.drop_trait() || - def_id.krate != LOCAL_CRATE { - self.rbml_w.start_tag(tag_impls_impl); - encode_def_id(self.rbml_w, self.ecx.tcx.map.local_def_id(item.id)); - self.rbml_w.wr_tagged_u64(tag_impls_impl_trait_def_id, def_to_u64(def_id)); - self.rbml_w.end_tag(); + if let hir::ItemImpl(..) = item.node { + let impl_id = self.tcx.map.local_def_id(item.id); + if let Some(trait_ref) = self.tcx.impl_trait_ref(impl_id) { + self.impls.entry(trait_ref.def_id) + .or_insert(vec![]) + .push(impl_id); } } visit::walk_item(self, item); } } -/// Encodes implementations that are eagerly loaded. -/// -/// None of this is necessary in theory; we can load all implementations -/// lazily. However, in two cases the optimizations to lazily load -/// implementations are not yet implemented. These two cases, which require us -/// to load implementations eagerly, are: -/// -/// * Destructors (implementations of the Drop trait). -/// -/// * Implementations of traits not defined in this crate. +/// Encodes an index, mapping each trait to its (local) implementations. fn encode_impls<'a>(ecx: &'a EncodeContext, krate: &hir::Crate, rbml_w: &'a mut Encoder) { - rbml_w.start_tag(tag_impls); + let mut visitor = ImplVisitor { + tcx: ecx.tcx, + impls: FnvHashMap() + }; + visit::walk_crate(&mut visitor, krate); - { - let mut visitor = ImplVisitor { - ecx: ecx, - rbml_w: rbml_w, - }; - visit::walk_crate(&mut visitor, krate); + rbml_w.start_tag(tag_impls); + for (trait_, trait_impls) in visitor.impls { + rbml_w.start_tag(tag_impls_trait); + encode_def_id(rbml_w, trait_); + for impl_ in trait_impls { + rbml_w.wr_tagged_u64(tag_impls_trait_impl, def_to_u64(impl_)); + } + rbml_w.end_tag(); } - rbml_w.end_tag(); } diff --git a/src/librustc/middle/astencode.rs b/src/librustc/middle/astencode.rs index 40e89b390888f..6c23307c67776 100644 --- a/src/librustc/middle/astencode.rs +++ b/src/librustc/middle/astencode.rs @@ -1319,7 +1319,7 @@ fn copy_item_types(dcx: &DecodeContext, ii: &InlinedItem, orig_did: DefId) { if let Some(ctor_id) = def.ctor_id { let ctor_did = dcx.tcx.lookup_adt_def(orig_did) .struct_variant().ctor_id; - println!("copying ctor {:?}", ctor_did); + debug!("copying ctor {:?}", ctor_did); copy_item_type(dcx, ctor_id, ctor_did); } }