]> git.lizzy.rs Git - rust.git/commitdiff
rustc_trans: use the TypeId hashing mechanism instead of metadata.
authorEduard Burtescu <edy.burt@gmail.com>
Thu, 1 Sep 2016 08:04:21 +0000 (11:04 +0300)
committerEduard Burtescu <edy.burt@gmail.com>
Tue, 20 Sep 2016 17:08:00 +0000 (20:08 +0300)
src/librustc/middle/cstore.rs
src/librustc/ty/util.rs
src/librustc_metadata/csearch.rs
src/librustc_metadata/encoder.rs
src/librustc_trans/back/symbol_names.rs

index 55a895b37ee330613580e0dfe396d99e8944e750..513fa30861adb2cb0b5d4dd5b990e6478ce951ce 100644 (file)
@@ -258,11 +258,6 @@ fn maybe_get_item_mir<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)
     // 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 @@ fn used_link_args(&self) -> Vec<String> { vec![] }
     // 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") }
index 2090877fb3c92635c5144a02812f36a5b5627200..5c71f348b9925db8ae6d9534a599175877c40e49 100644 (file)
@@ -352,12 +352,9 @@ pub fn required_region_bounds(self,
     /// 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 @@ pub fn is_adt_dtorck(self, adt: ty::AdtDef) -> bool {
     }
 }
 
-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 @@ fn def_id(&mut self, did: DefId) {
     }
 }
 
-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);
index a30a5743c34f2d122569605b1a9075b81401edf5..aae87005bf42e11c333132f9e39d286dd4d6cd02 100644 (file)
@@ -677,14 +677,6 @@ fn metadata_section_name(&self, target: &Target) -> &str
     {
         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>)>
     {
index 9773823c77ded4b71737c7c5684d312d7b26abf4..409982289d8140c2ab1b995523f6c7c79731c784 100644 (file)
@@ -36,9 +36,8 @@
 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 @@ struct Stats {
         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()
-}
index ab1474c235132ac13e6a203cf9b962c78b521291..500e9edebf3fe7fa976d4a9cd2e70cae2cb92056 100644 (file)
 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};
 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> {