diff options
| author | Eduard Burtescu <edy.burt@gmail.com> | 2016-09-01 11:04:21 +0300 |
|---|---|---|
| committer | Eduard Burtescu <edy.burt@gmail.com> | 2016-09-20 20:08:00 +0300 |
| commit | 2ce0e6d4e7a8150c4bb1019b7a8276d373c9a307 (patch) | |
| tree | 7a22cec92121029b15b0cb428ea344d1c1a898a6 | |
| parent | 02c4155d2cf0b17f526a126ad1f9dca944d9e85d (diff) | |
rustc_trans: use the TypeId hashing mechanism instead of metadata.
| -rw-r--r-- | src/librustc/middle/cstore.rs | 12 | ||||
| -rw-r--r-- | src/librustc/ty/util.rs | 28 | ||||
| -rw-r--r-- | src/librustc_metadata/csearch.rs | 8 | ||||
| -rw-r--r-- | src/librustc_metadata/encoder.rs | 17 | ||||
| -rw-r--r-- | src/librustc_trans/back/symbol_names.rs | 47 |
5 files changed, 45 insertions, 67 deletions
diff --git a/src/librustc/middle/cstore.rs b/src/librustc/middle/cstore.rs index 55a895b37ee..513fa30861a 100644 --- a/src/librustc/middle/cstore.rs +++ b/src/librustc/middle/cstore.rs @@ -258,11 +258,6 @@ pub trait CrateStore<'tcx> { // utility functions fn metadata_filename(&self) -> &str; fn metadata_section_name(&self, target: &Target) -> &str; - fn encode_type<'a>(&self, - tcx: TyCtxt<'a, 'tcx, 'tcx>, - ty: Ty<'tcx>, - def_id_to_string: for<'b> fn(TyCtxt<'b, 'tcx, 'tcx>, DefId) -> String) - -> Vec<u8>; fn used_crates(&self, prefer: LinkagePreference) -> Vec<(CrateNum, Option<PathBuf>)>; fn used_crate_source(&self, cnum: CrateNum) -> CrateSource; fn extern_mod_stmt_cnum(&self, emod_id: ast::NodeId) -> Option<CrateNum>; @@ -469,13 +464,6 @@ impl<'tcx> CrateStore<'tcx> for DummyCrateStore { // utility functions fn metadata_filename(&self) -> &str { bug!("metadata_filename") } fn metadata_section_name(&self, target: &Target) -> &str { bug!("metadata_section_name") } - fn encode_type<'a>(&self, - tcx: TyCtxt<'a, 'tcx, 'tcx>, - ty: Ty<'tcx>, - def_id_to_string: for<'b> fn(TyCtxt<'b, 'tcx, 'tcx>, DefId) -> String) - -> Vec<u8> { - bug!("encode_type") - } fn used_crates(&self, prefer: LinkagePreference) -> Vec<(CrateNum, Option<PathBuf>)> { vec![] } fn used_crate_source(&self, cnum: CrateNum) -> CrateSource { bug!("used_crate_source") } diff --git a/src/librustc/ty/util.rs b/src/librustc/ty/util.rs index 2090877fb3c..5c71f348b99 100644 --- a/src/librustc/ty/util.rs +++ b/src/librustc/ty/util.rs @@ -352,12 +352,9 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { /// Creates a hash of the type `Ty` which will be the same no matter what crate /// context it's calculated within. This is used by the `type_id` intrinsic. pub fn type_id_hash(self, ty: Ty<'tcx>) -> u64 { - let mut hasher = TypeIdHasher { - tcx: self, - state: SipHasher::new() - }; + let mut hasher = TypeIdHasher::new(self, SipHasher::new()); hasher.visit_ty(ty); - hasher.state.finish() + hasher.finish() } /// Returns true if this ADT is a dtorck type. @@ -391,16 +388,27 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { } } -struct TypeIdHasher<'a, 'gcx: 'a+'tcx, 'tcx: 'a> { +pub struct TypeIdHasher<'a, 'gcx: 'a+'tcx, 'tcx: 'a, H> { tcx: TyCtxt<'a, 'gcx, 'tcx>, - state: SipHasher + state: H } -impl<'a, 'gcx, 'tcx> TypeIdHasher<'a, 'gcx, 'tcx> { - fn hash<T: Hash>(&mut self, x: T) { +impl<'a, 'gcx, 'tcx, H: Hasher> TypeIdHasher<'a, 'gcx, 'tcx, H> { + pub fn new(tcx: TyCtxt<'a, 'gcx, 'tcx>, state: H) -> Self { + TypeIdHasher { + tcx: tcx, + state: state + } + } + + pub fn hash<T: Hash>(&mut self, x: T) { x.hash(&mut self.state); } + pub fn finish(self) -> u64 { + self.state.finish() + } + fn hash_discriminant_u8<T>(&mut self, x: &T) { let v = unsafe { intrinsics::discriminant_value(x) @@ -419,7 +427,7 @@ impl<'a, 'gcx, 'tcx> TypeIdHasher<'a, 'gcx, 'tcx> { } } -impl<'a, 'gcx, 'tcx> TypeVisitor<'tcx> for TypeIdHasher<'a, 'gcx, 'tcx> { +impl<'a, 'gcx, 'tcx, H: Hasher> TypeVisitor<'tcx> for TypeIdHasher<'a, 'gcx, 'tcx, H> { fn visit_ty(&mut self, ty: Ty<'tcx>) -> bool { // Distinguish between the Ty variants uniformly. self.hash_discriminant_u8(&ty.sty); diff --git a/src/librustc_metadata/csearch.rs b/src/librustc_metadata/csearch.rs index a30a5743c34..aae87005bf4 100644 --- a/src/librustc_metadata/csearch.rs +++ b/src/librustc_metadata/csearch.rs @@ -677,14 +677,6 @@ impl<'tcx> CrateStore<'tcx> for cstore::CStore { { loader::meta_section_name(target) } - fn encode_type<'a>(&self, - tcx: TyCtxt<'a, 'tcx, 'tcx>, - ty: Ty<'tcx>, - def_id_to_string: for<'b> fn(TyCtxt<'b, 'tcx, 'tcx>, DefId) -> String) - -> Vec<u8> - { - encoder::encoded_ty(tcx, ty, def_id_to_string) - } fn used_crates(&self, prefer: LinkagePreference) -> Vec<(CrateNum, Option<PathBuf>)> { diff --git a/src/librustc_metadata/encoder.rs b/src/librustc_metadata/encoder.rs index 9773823c77d..409982289d8 100644 --- a/src/librustc_metadata/encoder.rs +++ b/src/librustc_metadata/encoder.rs @@ -36,9 +36,8 @@ use rustc::session::config::{self, PanicStrategy, CrateTypeRustcMacro}; use rustc::util::nodemap::{FnvHashMap, NodeSet}; use rustc_serialize::{Encodable, SpecializedEncoder}; -use std::cell::RefCell; use std::io::prelude::*; -use std::io::{Cursor, SeekFrom}; +use std::io::SeekFrom; use std::ops::{Deref, DerefMut}; use std::rc::Rc; use std::u32; @@ -1891,17 +1890,3 @@ fn encode_metadata_inner(ecx: &mut EncodeContext, krate: &hir::Crate) { println!(" total bytes: {}", stats.total_bytes); } } - -// Get the encoded string for a type -pub fn encoded_ty<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, - t: Ty<'tcx>, - def_id_to_string: for<'b> fn(TyCtxt<'b, 'tcx, 'tcx>, DefId) -> String) - -> Vec<u8> { - let mut wr = Cursor::new(Vec::new()); - tyencode::enc_ty(&mut wr, &tyencode::ctxt { - ds: def_id_to_string, - tcx: tcx, - abbrevs: &RefCell::new(FnvHashMap()) - }, t); - wr.into_inner() -} diff --git a/src/librustc_trans/back/symbol_names.rs b/src/librustc_trans/back/symbol_names.rs index ab1474c2351..500e9edebf3 100644 --- a/src/librustc_trans/back/symbol_names.rs +++ b/src/librustc_trans/back/symbol_names.rs @@ -102,9 +102,10 @@ use monomorphize::Instance; use util::sha2::{Digest, Sha256}; use rustc::middle::weak_lang_items; -use rustc::hir::def_id::{DefId, LOCAL_CRATE}; +use rustc::hir::def_id::LOCAL_CRATE; use rustc::hir::map as hir_map; -use rustc::ty::{Ty, TyCtxt, TypeFoldable}; +use rustc::ty::{self, Ty, TypeFoldable}; +use rustc::ty::fold::TypeVisitor; use rustc::ty::item_path::{self, ItemPathBuffer, RootMode}; use rustc::ty::subst::Substs; use rustc::hir::map::definitions::{DefPath, DefPathData}; @@ -114,9 +115,18 @@ use syntax::attr; use syntax::parse::token::{self, InternedString}; use serialize::hex::ToHex; -pub fn def_id_to_string<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> String { - let def_path = tcx.def_path(def_id); - def_path.to_string(tcx) +use std::hash::Hasher; + +struct Sha256Hasher<'a>(&'a mut Sha256); + +impl<'a> Hasher for Sha256Hasher<'a> { + fn write(&mut self, msg: &[u8]) { + self.0.input(msg) + } + + fn finish(&self) -> u64 { + bug!("Sha256Hasher::finish should not be called"); + } } fn get_symbol_hash<'a, 'tcx>(scx: &SharedCrateContext<'a, 'tcx>, @@ -132,48 +142,43 @@ fn get_symbol_hash<'a, 'tcx>(scx: &SharedCrateContext<'a, 'tcx>, // values for generic type parameters, // if any. - substs: Option<&Substs<'tcx>>) + substs: Option<&'tcx Substs<'tcx>>) -> String { debug!("get_symbol_hash(def_path={:?}, parameters={:?})", def_path, substs); let tcx = scx.tcx(); - return record_time(&tcx.sess.perf_stats.symbol_hash_time, || { - let mut hash_state = scx.symbol_hasher().borrow_mut(); - + let mut hash_state = scx.symbol_hasher().borrow_mut(); + record_time(&tcx.sess.perf_stats.symbol_hash_time, || { hash_state.reset(); + let mut hasher = ty::util::TypeIdHasher::new(tcx, Sha256Hasher(&mut hash_state)); // the main symbol name is not necessarily unique; hash in the // compiler's internal def-path, guaranteeing each symbol has a // truly unique path - hash_state.input_str(&def_path.to_string(tcx)); + hasher.hash(def_path.to_string(tcx)); // Include the main item-type. Note that, in this case, the // assertions about `needs_subst` may not hold, but this item-type // ought to be the same for every reference anyway. assert!(!item_type.has_erasable_regions()); - let encoded_item_type = tcx.sess.cstore.encode_type(tcx, item_type, def_id_to_string); - hash_state.input(&encoded_item_type[..]); + hasher.visit_ty(item_type); // also include any type parameters (for generic items) if let Some(substs) = substs { - for t in substs.types() { - assert!(!t.has_erasable_regions()); - assert!(!t.needs_subst()); - let encoded_type = tcx.sess.cstore.encode_type(tcx, t, def_id_to_string); - hash_state.input(&encoded_type[..]); - } + assert!(!substs.has_erasable_regions()); + assert!(!substs.needs_subst()); + substs.visit_with(&mut hasher); } - - format!("h{}", truncated_hash_result(&mut *hash_state)) }); - fn truncated_hash_result(symbol_hasher: &mut Sha256) -> String { let output = symbol_hasher.result_bytes(); // 64 bits should be enough to avoid collisions. output[.. 8].to_hex() } + + format!("h{}", truncated_hash_result(&mut hash_state)) } impl<'a, 'tcx> Instance<'tcx> { |
