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
This commit is contained in:
parent
b74219964c
commit
a1c921e8a5
|
@ -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,
|
||||
|
|
|
@ -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<T, F>(&mut self, f: F) -> VecPerParamSpace<T> where
|
||||
F: FnMut(&mut Self) -> T;
|
||||
}
|
||||
|
||||
impl<'tcx, 'a> vtable_decoder_helpers<'tcx> for reader::Decoder<'a> {
|
||||
fn read_vec_per_param_space<T, F>(&mut self, mut f: F) -> VecPerParamSpace<T> 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<T, F>(rbml_w: &mut Encoder,
|
||||
v: &subst::VecPerParamSpace<T>,
|
||||
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
|
||||
|
||||
|
|
Loading…
Reference in New Issue