]> git.lizzy.rs Git - rust.git/blobdiff - src/librustc_incremental/calculate_svh/mod.rs
Use 128 instead of 64 bits for DefPath hashes
[rust.git] / src / librustc_incremental / calculate_svh / mod.rs
index c80a5a1627797bfbae1448530bd649f99ca9b55d..c9ed9ad3c7d2d4d2027ab5b31fee1bac4259980d 100644 (file)
 
 use std::cell::RefCell;
 use std::hash::Hash;
+use std::sync::Arc;
 use rustc::dep_graph::DepNode;
 use rustc::hir;
-use rustc::hir::def_id::{CRATE_DEF_INDEX, DefId};
+use rustc::hir::def_id::{LOCAL_CRATE, CRATE_DEF_INDEX, DefId};
 use rustc::hir::itemlikevisit::ItemLikeVisitor;
 use rustc::ich::{Fingerprint, StableHashingContext};
 use rustc::ty::TyCtxt;
+use rustc::util::common::record_time;
 use rustc_data_structures::stable_hasher::{StableHasher, HashStable};
 use rustc_data_structures::fx::FxHashMap;
-use rustc::util::common::record_time;
+use rustc_data_structures::accumulate_vec::AccumulateVec;
 
 pub type IchHasher = StableHasher<Fingerprint>;
 
@@ -60,6 +62,10 @@ pub fn new() -> IncrementalHashesMap {
         }
     }
 
+    pub fn get(&self, k: &DepNode<DefId>) -> Option<&Fingerprint> {
+        self.hashes.get(k)
+    }
+
     pub fn insert(&mut self, k: DepNode<DefId>, v: Fingerprint) -> Option<Fingerprint> {
         self.hashes.insert(k, v)
     }
@@ -99,6 +105,13 @@ fn compute_and_store_ich_for_item_like<T>(&mut self,
                                               item_like: T)
         where T: HashStable<StableHashingContext<'a, 'tcx>>
     {
+        if !hash_bodies && !self.hcx.tcx().sess.opts.build_dep_graph() {
+            // If we just need the hashes in order to compute the SVH, we don't
+            // need have two hashes per item. Just the one containing also the
+            // item's body is sufficient.
+            return
+        }
+
         let mut hasher = IchHasher::new();
         self.hcx.while_hashing_hir_bodies(hash_bodies, |hcx| {
             item_like.hash_stable(hcx, &mut hasher);
@@ -133,17 +146,42 @@ fn compute_crate_hash(&mut self) {
             let hcx = &mut self.hcx;
             let mut item_hashes: Vec<_> =
                 self.hashes.iter()
-                           .map(|(item_dep_node, &item_hash)| {
-                               // convert from a DepNode<DefId> tp a
-                               // DepNode<u64> where the u64 is the
-                               // hash of the def-id's def-path:
-                               let item_dep_node =
-                                   item_dep_node.map_def(|&did| Some(hcx.def_path_hash(did)))
-                                                .unwrap();
-                               (item_dep_node, item_hash)
+                           .filter_map(|(item_dep_node, &item_hash)| {
+                                // This `match` determines what kinds of nodes
+                                // go into the SVH:
+                                match *item_dep_node {
+                                    DepNode::Hir(_) |
+                                    DepNode::HirBody(_) => {
+                                        // We want to incoporate these into the
+                                        // SVH.
+                                    }
+                                    DepNode::FileMap(..) => {
+                                        // These don't make a semantic
+                                        // difference, filter them out.
+                                        return None
+                                    }
+                                    DepNode::AllLocalTraitImpls => {
+                                        // These are already covered by hashing
+                                        // the HIR.
+                                        return None
+                                    }
+                                    ref other => {
+                                        bug!("Found unexpected DepNode during \
+                                              SVH computation: {:?}",
+                                             other)
+                                    }
+                                }
+
+                                // Convert from a DepNode<DefId> to a
+                                // DepNode<u64> where the u64 is the hash of
+                                // the def-id's def-path:
+                                let item_dep_node =
+                                    item_dep_node.map_def(|&did| Some(hcx.def_path_hash(did)))
+                                                 .unwrap();
+                                Some((item_dep_node, item_hash))
                            })
                            .collect();
-            item_hashes.sort(); // avoid artificial dependencies on item ordering
+            item_hashes.sort_unstable(); // avoid artificial dependencies on item ordering
             item_hashes.hash(&mut crate_state);
         }
 
@@ -181,6 +219,49 @@ fn hash_crate_root_module(&mut self, krate: &'tcx hir::Crate) {
                                                  true,
                                                  (module, (span, attrs)));
     }
+
+    fn compute_and_store_ich_for_trait_impls(&mut self, krate: &'tcx hir::Crate)
+    {
+        let tcx = self.hcx.tcx();
+
+        let mut impls: Vec<(Fingerprint, Fingerprint)> = krate
+            .trait_impls
+            .iter()
+            .map(|(&trait_id, impls)| {
+                let trait_id = tcx.def_path_hash(trait_id);
+                let mut impls: AccumulateVec<[_; 32]> = impls
+                    .iter()
+                    .map(|&node_id| {
+                        let def_id = tcx.hir.local_def_id(node_id);
+                        tcx.def_path_hash(def_id)
+                    })
+                    .collect();
+
+                impls.sort_unstable();
+                let mut hasher = StableHasher::new();
+                impls.hash_stable(&mut self.hcx, &mut hasher);
+                (trait_id, hasher.finish())
+            })
+            .collect();
+
+        impls.sort_unstable();
+
+        let mut default_impls: AccumulateVec<[_; 32]> = krate
+            .trait_default_impl
+            .iter()
+            .map(|(&trait_def_id, &impl_node_id)| {
+                let impl_def_id = tcx.hir.local_def_id(impl_node_id);
+                (tcx.def_path_hash(trait_def_id), tcx.def_path_hash(impl_def_id))
+            })
+            .collect();
+
+        default_impls.sort_unstable();
+
+        let mut hasher = StableHasher::new();
+        impls.hash_stable(&mut self.hcx, &mut hasher);
+
+        self.hashes.insert(DepNode::AllLocalTraitImpls, hasher.finish());
+    }
 }
 
 impl<'a, 'tcx: 'a> ItemLikeVisitor<'tcx> for ComputeItemHashesVisitor<'a, 'tcx> {
@@ -203,6 +284,8 @@ fn visit_impl_item(&mut self, item: &'tcx hir::ImplItem) {
     }
 }
 
+
+
 pub fn compute_incremental_hashes_map<'a, 'tcx: 'a>(tcx: TyCtxt<'a, 'tcx, 'tcx>)
                                                     -> IncrementalHashesMap {
     let _ignore = tcx.dep_graph.in_ignore();
@@ -222,6 +305,26 @@ pub fn compute_incremental_hashes_map<'a, 'tcx: 'a>(tcx: TyCtxt<'a, 'tcx, 'tcx>)
             visitor.compute_and_store_ich_for_item_like(DepNode::Hir(def_id), false, macro_def);
             visitor.compute_and_store_ich_for_item_like(DepNode::HirBody(def_id), true, macro_def);
         }
+
+        for filemap in tcx.sess
+                          .codemap()
+                          .files_untracked()
+                          .iter()
+                          .filter(|fm| !fm.is_imported()) {
+            assert_eq!(LOCAL_CRATE.as_u32(), filemap.crate_of_origin);
+            let def_id = DefId {
+                krate: LOCAL_CRATE,
+                index: CRATE_DEF_INDEX,
+            };
+            let name = Arc::new(filemap.name.clone());
+            let dep_node = DepNode::FileMap(def_id, name);
+            let mut hasher = IchHasher::new();
+            filemap.hash_stable(&mut visitor.hcx, &mut hasher);
+            let fingerprint = hasher.finish();
+            visitor.hashes.insert(dep_node, fingerprint);
+        }
+
+        visitor.compute_and_store_ich_for_trait_impls(krate);
     });
 
     tcx.sess.perf_stats.incr_comp_hashes_count.set(visitor.hashes.len() as u64);