use cstore::{self, CrateMetadata, MetadataBlob, NativeLibrary};
use schema::*;
+use rustc_data_structures::sync::Lrc;
use rustc::hir::map::{DefKey, DefPath, DefPathData, DefPathHash};
use rustc::hir;
use rustc::middle::cstore::{LinkagePreference, ExternConstBody,
ExternBodyNestedBodies};
+use rustc::middle::exported_symbols::{ExportedSymbol, SymbolExportLevel};
use rustc::hir::def::{self, Def, CtorKind};
use rustc::hir::def_id::{CrateNum, DefId, DefIndex,
- CRATE_DEF_INDEX, LOCAL_CRATE};
+ CRATE_DEF_INDEX, LOCAL_CRATE, LocalDefId};
use rustc::ich::Fingerprint;
use rustc::middle::lang_items;
-use rustc::mir;
+use rustc::mir::{self, interpret};
use rustc::session::Session;
use rustc::ty::{self, Ty, TyCtxt};
use rustc::ty::codec::TyDecoder;
-use rustc::util::nodemap::DefIdSet;
use rustc::mir::Mir;
+use rustc::util::nodemap::FxHashMap;
use std::cell::Ref;
use std::collections::BTreeMap;
use std::io;
use std::mem;
-use std::rc::Rc;
use std::u32;
use rustc_serialize::{Decodable, Decoder, SpecializedDecoder, opaque};
last_filemap_index: usize,
lazy_state: LazyState,
+
+ // interpreter allocation cache
+ interpret_alloc_cache: FxHashMap<usize, interpret::AllocId>,
}
/// Abstract over the various ways one can create metadata decoders.
tcx,
last_filemap_index: 0,
lazy_state: LazyState::NoNode,
+ interpret_alloc_cache: FxHashMap::default(),
}
}
}
}
}
+impl<'a, 'tcx> SpecializedDecoder<LocalDefId> for DecodeContext<'a, 'tcx> {
+ #[inline]
+ fn specialized_decode(&mut self) -> Result<LocalDefId, Self::Error> {
+ self.specialized_decode().map(|i| LocalDefId::from_def_id(i))
+ }
+}
+
+impl<'a, 'tcx> SpecializedDecoder<interpret::AllocId> for DecodeContext<'a, 'tcx> {
+ fn specialized_decode(&mut self) -> Result<interpret::AllocId, Self::Error> {
+ const MAX1: usize = usize::max_value() - 1;
+ let tcx = self.tcx;
+ let interpret_interner = || tcx.unwrap().interpret_interner.borrow_mut();
+ let pos = self.position();
+ match usize::decode(self)? {
+ ::std::usize::MAX => {
+ let alloc_id = interpret_interner().reserve();
+ trace!("creating alloc id {:?} at {}", alloc_id, pos);
+ // insert early to allow recursive allocs
+ self.interpret_alloc_cache.insert(pos, alloc_id);
+
+ let allocation = interpret::Allocation::decode(self)?;
+ trace!("decoded alloc {:?} {:#?}", alloc_id, allocation);
+ let allocation = self.tcx.unwrap().intern_const_alloc(allocation);
+ interpret_interner().intern_at_reserved(alloc_id, allocation);
+
+ let num = usize::decode(self)?;
+ for _ in 0..num {
+ let glob = interpret::GlobalId::decode(self)?;
+ interpret_interner().cache(glob, alloc_id);
+ }
+
+ Ok(alloc_id)
+ },
+ MAX1 => {
+ trace!("creating fn alloc id at {}", pos);
+ let instance = ty::Instance::decode(self)?;
+ trace!("decoded fn alloc instance: {:?}", instance);
+ let id = interpret_interner().create_fn_alloc(instance);
+ trace!("created fn alloc id: {:?}", id);
+ self.interpret_alloc_cache.insert(pos, id);
+ Ok(id)
+ },
+ shorthand => {
+ trace!("loading shorthand {}", shorthand);
+ if let Some(&alloc_id) = self.interpret_alloc_cache.get(&shorthand) {
+ return Ok(alloc_id);
+ }
+ trace!("shorthand {} not cached, loading entire allocation", shorthand);
+ // need to load allocation
+ self.with_position(shorthand, |this| interpret::AllocId::decode(this))
+ },
+ }
+ }
+}
+
impl<'a, 'tcx> SpecializedDecoder<Span> for DecodeContext<'a, 'tcx> {
fn specialized_decode(&mut self) -> Result<Span, Self::Error> {
let tag = u8::decode(self)?;
.map(|body| (body.id(), body))
.collect();
ExternBodyNestedBodies {
- nested_bodies: Rc::new(nested_bodies),
+ nested_bodies: Lrc::new(nested_bodies),
fingerprint: ast.stable_bodies_hash,
}
} else {
ExternBodyNestedBodies {
- nested_bodies: Rc::new(BTreeMap::new()),
+ nested_bodies: Lrc::new(BTreeMap::new()),
fingerprint: Fingerprint::ZERO,
}
}
}
}
- pub fn get_item_attrs(&self, node_id: DefIndex, sess: &Session) -> Rc<[ast::Attribute]> {
+ pub fn get_item_attrs(&self, node_id: DefIndex, sess: &Session) -> Lrc<[ast::Attribute]> {
let (node_as, node_index) =
(node_id.address_space().index(), node_id.as_array_index());
if self.is_proc_macro(node_id) {
- return Rc::new([]);
+ return Lrc::new([]);
}
if let Some(&Some(ref val)) =
if def_key.disambiguated_data.data == DefPathData::StructCtor {
item = self.entry(def_key.parent.unwrap());
}
- let result: Rc<[ast::Attribute]> = Rc::from(self.get_attributes(&item, sess));
+ let result: Lrc<[ast::Attribute]> = Lrc::from(self.get_attributes(&item, sess));
let vec_ = &mut self.attribute_cache.borrow_mut()[node_as];
if vec_.len() < node_index + 1 {
vec_.resize(node_index + 1, None);
arg_names.decode(self).collect()
}
- pub fn get_exported_symbols(&self) -> DefIdSet {
- self.exported_symbols
- .iter()
- .map(|&index| self.local_def_id(index))
+ pub fn exported_symbols(&self) -> Vec<(ExportedSymbol, SymbolExportLevel)> {
+ self.root
+ .exported_symbols
+ .decode(self)
.collect()
}