about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorMichael Woerister <michaelwoerister@posteo>2017-09-22 13:03:15 +0200
committerMichael Woerister <michaelwoerister@posteo>2017-09-23 19:47:37 +0200
commit2a50d127ddc8a40c526d3409159a328517a6ff84 (patch)
treea6754404610a0d2b9a7abdef73f2fd3da5eb71e4 /src
parent5974ec745e97af456e50a04473e468db9007bd07 (diff)
incr.comp.: Remove support for loading metadata fingerprints.
Diffstat (limited to 'src')
-rw-r--r--src/librustc/dep_graph/dep_node.rs20
-rw-r--r--src/librustc/middle/cstore.rs6
-rw-r--r--src/librustc/session/config.rs2
-rw-r--r--src/librustc/ty/context.rs20
-rw-r--r--src/librustc_incremental/persist/fs.rs71
-rw-r--r--src/librustc_incremental/persist/hash.rs202
-rw-r--r--src/librustc_incremental/persist/load.rs13
-rw-r--r--src/librustc_incremental/persist/mod.rs1
-rw-r--r--src/librustc_incremental/persist/preds/mod.rs12
-rw-r--r--src/librustc_incremental/persist/save.rs33
-rw-r--r--src/librustc_metadata/cstore_impl.rs21
-rw-r--r--src/test/incremental/callee_caller_cross_crate/b.rs2
-rw-r--r--src/test/incremental/change_private_fn_cc/struct_point.rs2
-rw-r--r--src/test/incremental/change_private_impl_method_cc/struct_point.rs2
-rw-r--r--src/test/incremental/rlib_cross_crate/b.rs2
-rw-r--r--src/test/incremental/struct_change_field_type_cross_crate/b.rs2
-rw-r--r--src/test/incremental/type_alias_cross_crate/b.rs2
17 files changed, 105 insertions, 308 deletions
diff --git a/src/librustc/dep_graph/dep_node.rs b/src/librustc/dep_graph/dep_node.rs
index 77db2fc70bc..b492caf10bb 100644
--- a/src/librustc/dep_graph/dep_node.rs
+++ b/src/librustc/dep_graph/dep_node.rs
@@ -60,7 +60,7 @@
 //! user of the `DepNode` API of having to know how to compute the expected
 //! fingerprint for a given set of node parameters.
 
-use hir::def_id::{CrateNum, DefId, DefIndex};
+use hir::def_id::{CrateNum, DefId, DefIndex, CRATE_DEF_INDEX};
 use hir::map::DefPathHash;
 use hir::{HirId, ItemLocalId};
 
@@ -420,7 +420,7 @@ define_dep_nodes!( <'tcx>
     [input] Hir(DefId),
 
     // Represents metadata from an extern crate.
-    [input] MetaData(DefId),
+    [input] CrateMetadata(CrateNum),
 
     // Represents some artifact that we save to disk. Note that these
     // do not have a def-id as part of their identifier.
@@ -678,6 +678,22 @@ impl<'a, 'gcx: 'tcx + 'a, 'tcx: 'a> DepNodeParams<'a, 'gcx, 'tcx> for (DefIndex,
     }
 }
 
+impl<'a, 'gcx: 'tcx + 'a, 'tcx: 'a> DepNodeParams<'a, 'gcx, 'tcx> for (CrateNum,) {
+    const CAN_RECONSTRUCT_QUERY_KEY: bool = true;
+
+    fn to_fingerprint(&self, tcx: TyCtxt) -> Fingerprint {
+        let def_id = DefId {
+            krate: self.0,
+            index: CRATE_DEF_INDEX,
+        };
+        tcx.def_path_hash(def_id).0
+    }
+
+    fn to_debug_str(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> String {
+        tcx.crate_name(self.0).as_str().to_string()
+    }
+}
+
 impl<'a, 'gcx: 'tcx + 'a, 'tcx: 'a> DepNodeParams<'a, 'gcx, 'tcx> for (DefId, DefId) {
     const CAN_RECONSTRUCT_QUERY_KEY: bool = false;
 
diff --git a/src/librustc/middle/cstore.rs b/src/librustc/middle/cstore.rs
index de647913f0f..a97bfa05369 100644
--- a/src/librustc/middle/cstore.rs
+++ b/src/librustc/middle/cstore.rs
@@ -267,6 +267,8 @@ pub trait CrateStore {
     fn export_macros_untracked(&self, cnum: CrateNum);
     fn dep_kind_untracked(&self, cnum: CrateNum) -> DepKind;
     fn crate_name_untracked(&self, cnum: CrateNum) -> Symbol;
+    fn crate_disambiguator_untracked(&self, cnum: CrateNum) -> Symbol;
+    fn crate_hash_untracked(&self, cnum: CrateNum) -> Svh;
     fn struct_field_names_untracked(&self, def: DefId) -> Vec<ast::Name>;
     fn item_children_untracked(&self, did: DefId, sess: &Session) -> Vec<def::Export>;
     fn load_macro_untracked(&self, did: DefId, sess: &Session) -> LoadedMacro;
@@ -336,6 +338,10 @@ impl CrateStore for DummyCrateStore {
     fn dep_kind_untracked(&self, cnum: CrateNum) -> DepKind { bug!("is_explicitly_linked") }
     fn export_macros_untracked(&self, cnum: CrateNum) { bug!("export_macros") }
     fn crate_name_untracked(&self, cnum: CrateNum) -> Symbol { bug!("crate_name") }
+    fn crate_disambiguator_untracked(&self, cnum: CrateNum) -> Symbol {
+        bug!("crate_disambiguator")
+    }
+    fn crate_hash_untracked(&self, cnum: CrateNum) -> Svh { bug!("crate_hash") }
 
     // resolve
     fn def_key(&self, def: DefId) -> DefKey { bug!("def_key") }
diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs
index 1d490c8f27d..d3256357941 100644
--- a/src/librustc/session/config.rs
+++ b/src/librustc/session/config.rs
@@ -1021,7 +1021,7 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options,
           "attempt to recover from parse errors (experimental)"),
     incremental: Option<String> = (None, parse_opt_string, [UNTRACKED],
           "enable incremental compilation (experimental)"),
-    incremental_cc: bool = (true, parse_bool, [UNTRACKED],
+    incremental_cc: bool = (false, parse_bool, [UNTRACKED],
           "enable cross-crate incremental compilation (even more experimental)"),
     incremental_info: bool = (false, parse_bool, [UNTRACKED],
         "print high-level information about incremental reuse (or the lack thereof)"),
diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs
index d7327d2bd0f..054c5e122df 100644
--- a/src/librustc/ty/context.rs
+++ b/src/librustc/ty/context.rs
@@ -11,6 +11,7 @@
 //! type context book-keeping
 
 use dep_graph::DepGraph;
+use dep_graph::{DepNode, DepConstructor};
 use errors::DiagnosticBuilder;
 use session::Session;
 use session::config::OutputFilenames;
@@ -1237,6 +1238,25 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
                                   self.cstore)
     }
 
+    // This method makes sure that we have a DepNode and a Fingerprint for
+    // every upstream crate. It needs to be called once right after the tcx is
+    // created.
+    // With full-fledged red/green, the method will probably become unnecessary
+    // as this will be done on-demand.
+    pub fn allocate_metadata_dep_nodes(self) {
+        // We cannot use the query versions of crates() and crate_hash(), since
+        // those would need the DepNodes that we are allocating here.
+        for cnum in self.cstore.crates_untracked() {
+            let dep_node = DepNode::new(self, DepConstructor::CrateMetadata(cnum));
+            let crate_hash = self.cstore.crate_hash_untracked(cnum);
+            self.dep_graph.with_task(dep_node,
+                                     self,
+                                     crate_hash,
+                                     |_, x| x // No transformation needed
+            );
+        }
+    }
+
     // This method exercises the `in_scope_traits_map` query for all possible
     // values so that we have their fingerprints available in the DepGraph.
     // This is only required as long as we still use the old dependency tracking
diff --git a/src/librustc_incremental/persist/fs.rs b/src/librustc_incremental/persist/fs.rs
index ccd2fdb6089..8d729e5e052 100644
--- a/src/librustc_incremental/persist/fs.rs
+++ b/src/librustc_incremental/persist/fs.rs
@@ -114,15 +114,12 @@
 //! unsupported file system and emit a warning in that case. This is not yet
 //! implemented.
 
-use rustc::hir::def_id::CrateNum;
 use rustc::hir::svh::Svh;
 use rustc::session::Session;
-use rustc::ty::TyCtxt;
 use rustc::util::fs as fs_util;
 use rustc_data_structures::{flock, base_n};
 use rustc_data_structures::fx::{FxHashSet, FxHashMap};
 
-use std::ffi::OsString;
 use std::fs as std_fs;
 use std::io;
 use std::mem;
@@ -158,10 +155,6 @@ pub fn metadata_hash_export_path(sess: &Session) -> PathBuf {
     in_incr_comp_dir_sess(sess, METADATA_HASHES_FILENAME)
 }
 
-pub fn metadata_hash_import_path(import_session_dir: &Path) -> PathBuf {
-    import_session_dir.join(METADATA_HASHES_FILENAME)
-}
-
 pub fn lock_file_path(session_dir: &Path) -> PathBuf {
     let crate_dir = session_dir.parent().unwrap();
 
@@ -621,70 +614,6 @@ fn string_to_timestamp(s: &str) -> Result<SystemTime, ()> {
     Ok(UNIX_EPOCH + duration)
 }
 
-fn crate_path_tcx(tcx: TyCtxt, cnum: CrateNum) -> PathBuf {
-    crate_path(tcx.sess, &tcx.crate_name(cnum).as_str(), &tcx.crate_disambiguator(cnum).as_str())
-}
-
-/// Finds the session directory containing the correct metadata hashes file for
-/// the given crate. In order to do that it has to compute the crate directory
-/// of the given crate, and in there, look for the session directory with the
-/// correct SVH in it.
-/// Note that we have to match on the exact SVH here, not just the
-/// crate's (name, disambiguator) pair. The metadata hashes are only valid for
-/// the exact version of the binary we are reading from now (i.e. the hashes
-/// are part of the dependency graph of a specific compilation session).
-pub fn find_metadata_hashes_for(tcx: TyCtxt, cnum: CrateNum) -> Option<PathBuf> {
-    let crate_directory = crate_path_tcx(tcx, cnum);
-
-    if !crate_directory.exists() {
-        return None
-    }
-
-    let dir_entries = match crate_directory.read_dir() {
-        Ok(dir_entries) => dir_entries,
-        Err(e) => {
-            tcx.sess
-               .err(&format!("incremental compilation: Could not read crate directory `{}`: {}",
-                             crate_directory.display(), e));
-            return None
-        }
-    };
-
-    let target_svh = tcx.crate_hash(cnum);
-    let target_svh = base_n::encode(target_svh.as_u64(), INT_ENCODE_BASE);
-
-    let sub_dir = find_metadata_hashes_iter(&target_svh, dir_entries.filter_map(|e| {
-        e.ok().map(|e| e.file_name().to_string_lossy().into_owned())
-    }));
-
-    sub_dir.map(|sub_dir_name| crate_directory.join(&sub_dir_name))
-}
-
-fn find_metadata_hashes_iter<'a, I>(target_svh: &str, iter: I) -> Option<OsString>
-    where I: Iterator<Item=String>
-{
-    for sub_dir_name in iter {
-        if !is_session_directory(&sub_dir_name) || !is_finalized(&sub_dir_name) {
-            // This is not a usable session directory
-            continue
-        }
-
-        let is_match = if let Some(last_dash_pos) = sub_dir_name.rfind("-") {
-            let candidate_svh = &sub_dir_name[last_dash_pos + 1 .. ];
-            target_svh == candidate_svh
-        } else {
-            // some kind of invalid directory name
-            continue
-        };
-
-        if is_match {
-            return Some(OsString::from(sub_dir_name))
-        }
-    }
-
-    None
-}
-
 fn crate_path(sess: &Session,
               crate_name: &str,
               crate_disambiguator: &str)
diff --git a/src/librustc_incremental/persist/hash.rs b/src/librustc_incremental/persist/hash.rs
deleted file mode 100644
index f7ea0a07f3d..00000000000
--- a/src/librustc_incremental/persist/hash.rs
+++ /dev/null
@@ -1,202 +0,0 @@
-// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-use rustc::dep_graph::{DepNode, DepKind};
-use rustc::hir::def_id::{CrateNum, DefId, LOCAL_CRATE};
-use rustc::hir::svh::Svh;
-use rustc::ich::Fingerprint;
-use rustc::ty::TyCtxt;
-use rustc_data_structures::fx::FxHashMap;
-use rustc_data_structures::flock;
-use rustc_serialize::Decodable;
-use rustc_serialize::opaque::Decoder;
-
-use super::data::*;
-use super::fs::*;
-use super::file_format;
-
-use std::hash::Hash;
-use std::fmt::Debug;
-
-pub struct HashContext<'a, 'tcx: 'a> {
-    pub tcx: TyCtxt<'a, 'tcx, 'tcx>,
-    metadata_hashes: FxHashMap<DefId, Fingerprint>,
-    crate_hashes: FxHashMap<CrateNum, Svh>,
-}
-
-impl<'a, 'tcx> HashContext<'a, 'tcx> {
-    pub fn new(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> Self {
-        HashContext {
-            tcx,
-            metadata_hashes: FxHashMap(),
-            crate_hashes: FxHashMap(),
-        }
-    }
-
-    pub fn hash(&mut self, dep_node: &DepNode) -> Option<Fingerprint> {
-        match dep_node.kind {
-            // HIR nodes (which always come from our crate) are an input:
-            DepKind::Krate |
-            DepKind::InScopeTraits |
-            DepKind::Hir |
-            DepKind::HirBody => {
-                Some(self.tcx.dep_graph.fingerprint_of(dep_node).unwrap())
-            }
-
-            // MetaData from other crates is an *input* to us.
-            // MetaData nodes from *our* crates are an *output*; we
-            // don't hash them, but we do compute a hash for them and
-            // save it for others to use.
-            DepKind::MetaData => {
-                let def_id = dep_node.extract_def_id(self.tcx).unwrap();
-                assert!(!def_id.is_local());
-
-                Some(self.metadata_hash(def_id,
-                                        def_id.krate,
-                                        |this| &mut this.metadata_hashes))
-            }
-
-            _ => {
-                // Other kinds of nodes represent computed by-products
-                // that we don't hash directly; instead, they should
-                // have some transitive dependency on a Hir or
-                // MetaData node, so we'll just hash that
-                None
-            }
-        }
-    }
-
-    fn metadata_hash<K, C>(&mut self,
-                           key: K,
-                           cnum: CrateNum,
-                           cache: C)
-                           -> Fingerprint
-        where K: Hash + Eq + Debug,
-              C: Fn(&mut Self) -> &mut FxHashMap<K, Fingerprint>,
-    {
-        debug!("metadata_hash(key={:?})", key);
-
-        debug_assert!(cnum != LOCAL_CRATE);
-        loop {
-            // check whether we have a result cached for this def-id
-            if let Some(&hash) = cache(self).get(&key) {
-                return hash;
-            }
-
-            // check whether we did not find detailed metadata for this
-            // krate; in that case, we just use the krate's overall hash
-            if let Some(&svh) = self.crate_hashes.get(&cnum) {
-                // micro-"optimization": avoid a cache miss if we ask
-                // for metadata from this particular def-id again.
-                let fingerprint = svh_to_fingerprint(svh);
-                cache(self).insert(key, fingerprint);
-
-                return fingerprint;
-            }
-
-            // otherwise, load the data and repeat.
-            self.load_data(cnum);
-            assert!(self.crate_hashes.contains_key(&cnum));
-        }
-    }
-
-    fn load_data(&mut self, cnum: CrateNum) {
-        debug!("load_data(cnum={})", cnum);
-
-        let svh = self.tcx.crate_hash(cnum);
-        let old = self.crate_hashes.insert(cnum, svh);
-        debug!("load_data: svh={}", svh);
-        assert!(old.is_none(), "loaded data for crate {:?} twice", cnum);
-
-        if let Some(session_dir) = find_metadata_hashes_for(self.tcx, cnum) {
-            debug!("load_data: session_dir={:?}", session_dir);
-
-            // Lock the directory we'll be reading  the hashes from.
-            let lock_file_path = lock_file_path(&session_dir);
-            let _lock = match flock::Lock::new(&lock_file_path,
-                                               false,   // don't wait
-                                               false,   // don't create the lock-file
-                                               false) { // shared lock
-                Ok(lock) => lock,
-                Err(err) => {
-                    debug!("Could not acquire lock on `{}` while trying to \
-                            load metadata hashes: {}",
-                            lock_file_path.display(),
-                            err);
-
-                    // Could not acquire the lock. The directory is probably in
-                    // in the process of being deleted. It's OK to just exit
-                    // here. It's the same scenario as if the file had not
-                    // existed in the first place.
-                    return
-                }
-            };
-
-            let hashes_file_path = metadata_hash_import_path(&session_dir);
-
-            match file_format::read_file(self.tcx.sess, &hashes_file_path)
-            {
-                Ok(Some(data)) => {
-                    match self.load_from_data(cnum, &data, svh) {
-                        Ok(()) => { }
-                        Err(err) => {
-                            bug!("decoding error in dep-graph from `{}`: {}",
-                                 &hashes_file_path.display(), err);
-                        }
-                    }
-                }
-                Ok(None) => {
-                    // If the file is not found, that's ok.
-                }
-                Err(err) => {
-                    self.tcx.sess.err(
-                        &format!("could not load dep information from `{}`: {}",
-                                 hashes_file_path.display(), err));
-                }
-            }
-        }
-    }
-
-    fn load_from_data(&mut self,
-                      cnum: CrateNum,
-                      data: &[u8],
-                      expected_svh: Svh) -> Result<(), String> {
-        debug!("load_from_data(cnum={})", cnum);
-
-        // Load up the hashes for the def-ids from this crate.
-        let mut decoder = Decoder::new(data, 0);
-        let svh_in_hashes_file = Svh::decode(&mut decoder)?;
-
-        if svh_in_hashes_file != expected_svh {
-            // We should not be able to get here. If we do, then
-            // `fs::find_metadata_hashes_for()` has messed up.
-            bug!("mismatch between SVH in crate and SVH in incr. comp. hashes")
-        }
-
-        let serialized_hashes = SerializedMetadataHashes::decode(&mut decoder)?;
-        for serialized_hash in serialized_hashes.entry_hashes {
-            // the hashes are stored with just a def-index, which is
-            // always relative to the old crate; convert that to use
-            // our internal crate number
-            let def_id = DefId { krate: cnum, index: serialized_hash.def_index };
-
-            // record the hash for this dep-node
-            let old = self.metadata_hashes.insert(def_id, serialized_hash.hash);
-            debug!("load_from_data: def_id={:?} hash={}", def_id, serialized_hash.hash);
-            assert!(old.is_none(), "already have hash for {:?}", def_id);
-        }
-
-        Ok(())
-    }
-}
-
-fn svh_to_fingerprint(svh: Svh) -> Fingerprint {
-    Fingerprint::from_smaller_hash(svh.as_u64())
-}
diff --git a/src/librustc_incremental/persist/load.rs b/src/librustc_incremental/persist/load.rs
index 9e2036c522f..28d05a897c8 100644
--- a/src/librustc_incremental/persist/load.rs
+++ b/src/librustc_incremental/persist/load.rs
@@ -10,7 +10,7 @@
 
 //! Code to save/load the dep-graph from files.
 
-use rustc::dep_graph::{DepNode, WorkProductId, DepKind};
+use rustc::dep_graph::{DepNode, WorkProductId, DepKind, PreviousDepGraph};
 use rustc::hir::svh::Svh;
 use rustc::ich::Fingerprint;
 use rustc::session::Session;
@@ -24,7 +24,6 @@ use std::path::{Path};
 
 use super::data::*;
 use super::dirty_clean;
-use super::hash::*;
 use super::fs::*;
 use super::file_format;
 use super::work_product;
@@ -40,6 +39,7 @@ pub type DirtyNodes = FxHashMap<DepNodeIndex, DepNodeIndex>;
 /// actually it doesn't matter all that much.) See `README.md` for
 /// more general overview.
 pub fn load_dep_graph<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
+    tcx.allocate_metadata_dep_nodes();
     tcx.precompute_in_scope_traits_hashes();
     if tcx.sess.incr_session_load_dep_graph() {
         let _ignore = tcx.dep_graph.in_ignore();
@@ -103,7 +103,7 @@ fn does_still_exist(tcx: TyCtxt, dep_node: &DepNode) -> bool {
         DepKind::Hir |
         DepKind::HirBody |
         DepKind::InScopeTraits |
-        DepKind::MetaData => {
+        DepKind::CrateMetadata => {
             dep_node.extract_def_id(tcx).is_some()
         }
         _ => {
@@ -198,15 +198,12 @@ fn initial_dirty_nodes<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                                  nodes: &IndexVec<DepNodeIndex, DepNode>,
                                  serialized_hashes: &[(DepNodeIndex, Fingerprint)])
                                  -> DirtyNodes {
-    let mut hcx = HashContext::new(tcx);
     let mut dirty_nodes = FxHashMap();
 
     for &(dep_node_index, prev_hash) in serialized_hashes {
         let dep_node = nodes[dep_node_index];
         if does_still_exist(tcx, &dep_node) {
-            let current_hash = hcx.hash(&dep_node).unwrap_or_else(|| {
-                bug!("Cannot find current ICH for input that still exists?")
-            });
+            let current_hash = tcx.dep_graph.fingerprint_of(&dep_node);
 
             if current_hash == prev_hash {
                 debug!("initial_dirty_nodes: {:?} is clean (hash={:?})",
@@ -416,7 +413,7 @@ fn process_edge<'a, 'tcx, 'edges>(
     // clean target because removing the input would have dirtied the input
     // node and transitively dirtied the target.
     debug_assert!(match nodes[source].kind {
-        DepKind::Hir | DepKind::HirBody | DepKind::MetaData => {
+        DepKind::Hir | DepKind::HirBody | DepKind::CrateMetadata => {
             does_still_exist(tcx, &nodes[source])
         }
         _ => true,
diff --git a/src/librustc_incremental/persist/mod.rs b/src/librustc_incremental/persist/mod.rs
index 6514cb8555a..688d8add57e 100644
--- a/src/librustc_incremental/persist/mod.rs
+++ b/src/librustc_incremental/persist/mod.rs
@@ -15,7 +15,6 @@
 mod data;
 mod dirty_clean;
 mod fs;
-mod hash;
 mod load;
 mod preds;
 mod save;
diff --git a/src/librustc_incremental/persist/preds/mod.rs b/src/librustc_incremental/persist/preds/mod.rs
index 46bb37b017f..a552a27c62a 100644
--- a/src/librustc_incremental/persist/preds/mod.rs
+++ b/src/librustc_incremental/persist/preds/mod.rs
@@ -10,10 +10,10 @@
 
 use rustc::dep_graph::{DepGraphQuery, DepNode, DepKind};
 use rustc::ich::Fingerprint;
+use rustc::ty::TyCtxt;
 use rustc_data_structures::fx::FxHashMap;
 use rustc_data_structures::graph::{Graph, NodeIndex};
 
-use super::hash::*;
 
 mod compress;
 
@@ -40,15 +40,13 @@ pub struct Predecessors<'query> {
 }
 
 impl<'q> Predecessors<'q> {
-    pub fn new(query: &'q DepGraphQuery, hcx: &mut HashContext) -> Self {
-        let tcx = hcx.tcx;
-
+    pub fn new(tcx: TyCtxt, query: &'q DepGraphQuery) -> Self {
         // Find the set of "start nodes". These are nodes that we will
         // possibly query later.
         let is_output = |node: &DepNode| -> bool {
             match node.kind {
                 DepKind::WorkProduct => true,
-                DepKind::MetaData => {
+                DepKind::CrateMetadata => {
                     // We do *not* create dep-nodes for the current crate's
                     // metadata anymore, just for metadata that we import/read
                     // from other crates.
@@ -74,7 +72,7 @@ impl<'q> Predecessors<'q> {
             let input = *graph.node_data(input_index);
             debug!("computing hash for input node `{:?}`", input);
             hashes.entry(input)
-                  .or_insert_with(|| hcx.hash(input).unwrap());
+                  .or_insert_with(|| tcx.dep_graph.fingerprint_of(&input));
         }
 
         if tcx.sess.opts.debugging_opts.query_dep_graph {
@@ -89,7 +87,7 @@ impl<'q> Predecessors<'q> {
 
             for node in hir_nodes {
                 hashes.entry(node)
-                      .or_insert_with(|| hcx.hash(node).unwrap());
+                      .or_insert_with(|| tcx.dep_graph.fingerprint_of(&node));
             }
         }
 
diff --git a/src/librustc_incremental/persist/save.rs b/src/librustc_incremental/persist/save.rs
index bc8cfd7da35..c9efd97d47b 100644
--- a/src/librustc_incremental/persist/save.rs
+++ b/src/librustc_incremental/persist/save.rs
@@ -15,6 +15,7 @@ use rustc::ich::Fingerprint;
 use rustc::middle::cstore::EncodedMetadataHashes;
 use rustc::session::Session;
 use rustc::ty::TyCtxt;
+use rustc::util::common::time;
 use rustc::util::nodemap::DefIdMap;
 use rustc_data_structures::fx::FxHashMap;
 use rustc_data_structures::graph;
@@ -26,7 +27,6 @@ use std::fs::{self, File};
 use std::path::PathBuf;
 
 use super::data::*;
-use super::hash::*;
 use super::preds::*;
 use super::fs::*;
 use super::dirty_clean;
@@ -45,13 +45,6 @@ pub fn save_dep_graph<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
         return;
     }
 
-    let query = tcx.dep_graph.query();
-
-    if tcx.sess.opts.debugging_opts.incremental_info {
-        eprintln!("incremental: {} nodes in dep-graph", query.graph.len_nodes());
-        eprintln!("incremental: {} edges in dep-graph", query.graph.len_edges());
-    }
-
     // We load the previous metadata hashes now before overwriting the file
     // (if we need them for testing).
     let prev_metadata_hashes = if tcx.sess.opts.debugging_opts.query_dep_graph {
@@ -60,8 +53,6 @@ pub fn save_dep_graph<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
         DefIdMap()
     };
 
-    let mut hcx = HashContext::new(tcx);
-    let preds = Predecessors::new(&query, &mut hcx);
     let mut current_metadata_hashes = FxHashMap();
 
     // IMPORTANT: We are saving the metadata hashes *before* the dep-graph,
@@ -78,9 +69,25 @@ pub fn save_dep_graph<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                                            e));
     }
 
-    save_in(sess,
-            dep_graph_path(sess),
-            |e| encode_dep_graph(tcx, &preds, e));
+    time(sess.time_passes(), "persist dep-graph (old)", || {
+        let query = tcx.dep_graph.query();
+
+        if tcx.sess.opts.debugging_opts.incremental_info {
+            eprintln!("incremental: {} nodes in dep-graph", query.graph.len_nodes());
+            eprintln!("incremental: {} edges in dep-graph", query.graph.len_edges());
+        }
+
+        let preds = Predecessors::new(tcx, &query);
+        save_in(sess,
+                dep_graph_path(sess),
+                |e| encode_dep_graph(tcx, &preds, e));
+    });
+
+    time(sess.time_passes(), "persist dep-graph (new)", || {
+        save_in(sess,
+                dep_graph_path_new(sess),
+                |e| encode_dep_graph_new(tcx, e));
+    });
 
     dirty_clean::check_dirty_clean_metadata(tcx,
                                             &prev_metadata_hashes,
diff --git a/src/librustc_metadata/cstore_impl.rs b/src/librustc_metadata/cstore_impl.rs
index f785d7bd407..8eacc21ab00 100644
--- a/src/librustc_metadata/cstore_impl.rs
+++ b/src/librustc_metadata/cstore_impl.rs
@@ -55,9 +55,14 @@ macro_rules! provide {
                 let ($def_id, $other) = def_id_arg.into_args();
                 assert!(!$def_id.is_local());
 
-                let def_path_hash = $tcx.def_path_hash($def_id);
-                let dep_node = def_path_hash.to_dep_node(::rustc::dep_graph::DepKind::MetaData);
-
+                let def_path_hash = $tcx.def_path_hash(DefId {
+                    krate: $def_id.krate,
+                    index: CRATE_DEF_INDEX
+                });
+                let dep_node = def_path_hash
+                    .to_dep_node(::rustc::dep_graph::DepKind::CrateMetadata);
+                // The DepNodeIndex of the DepNode::CrateMetadata should be
+                // cached somewhere, so that we can use read_index().
                 $tcx.dep_graph.read(dep_node);
 
                 let $cdata = $tcx.crate_data_as_rc_any($def_id.krate);
@@ -379,6 +384,16 @@ impl CrateStore for cstore::CStore {
         self.get_crate_data(cnum).name
     }
 
+    fn crate_disambiguator_untracked(&self, cnum: CrateNum) -> Symbol
+    {
+        self.get_crate_data(cnum).disambiguator()
+    }
+
+    fn crate_hash_untracked(&self, cnum: CrateNum) -> hir::svh::Svh
+    {
+        self.get_crate_data(cnum).hash()
+    }
+
     /// Returns the `DefKey` for a given `DefId`. This indicates the
     /// parent `DefId` as well as some idea of what kind of data the
     /// `DefId` refers to.
diff --git a/src/test/incremental/callee_caller_cross_crate/b.rs b/src/test/incremental/callee_caller_cross_crate/b.rs
index 9e56d34636f..355983e9ca1 100644
--- a/src/test/incremental/callee_caller_cross_crate/b.rs
+++ b/src/test/incremental/callee_caller_cross_crate/b.rs
@@ -12,6 +12,8 @@
 // revisions:rpass1 rpass2
 // compile-flags:-Z query-dep-graph
 
+// ignore-test -- ignored until red/green restores cross-crate tracking fidelity
+
 #![feature(rustc_attrs)]
 
 extern crate a;
diff --git a/src/test/incremental/change_private_fn_cc/struct_point.rs b/src/test/incremental/change_private_fn_cc/struct_point.rs
index a6d029515d7..d58a9bacdb5 100644
--- a/src/test/incremental/change_private_fn_cc/struct_point.rs
+++ b/src/test/incremental/change_private_fn_cc/struct_point.rs
@@ -15,6 +15,8 @@
 // compile-flags: -Z query-dep-graph
 // aux-build:point.rs
 
+// ignore-test -- ignored until red/green restores cross-crate tracking fidelity
+
 #![feature(rustc_attrs)]
 #![feature(stmt_expr_attributes)]
 #![allow(dead_code)]
diff --git a/src/test/incremental/change_private_impl_method_cc/struct_point.rs b/src/test/incremental/change_private_impl_method_cc/struct_point.rs
index 05c076b9f4b..3f665f5c820 100644
--- a/src/test/incremental/change_private_impl_method_cc/struct_point.rs
+++ b/src/test/incremental/change_private_impl_method_cc/struct_point.rs
@@ -15,6 +15,8 @@
 // compile-flags: -Z query-dep-graph
 // aux-build:point.rs
 
+// ignore-test -- ignored until red/green restores cross-crate tracking fidelity
+
 #![feature(rustc_attrs)]
 #![feature(stmt_expr_attributes)]
 #![allow(dead_code)]
diff --git a/src/test/incremental/rlib_cross_crate/b.rs b/src/test/incremental/rlib_cross_crate/b.rs
index 9849e93d3ff..39065d9671a 100644
--- a/src/test/incremental/rlib_cross_crate/b.rs
+++ b/src/test/incremental/rlib_cross_crate/b.rs
@@ -18,6 +18,8 @@
 // no-prefer-dynamic
 // compile-flags: -Z query-dep-graph
 
+// ignore-test -- ignored until red/green restores cross-crate tracking fidelity
+
 #![feature(rustc_attrs)]
 
 extern crate a;
diff --git a/src/test/incremental/struct_change_field_type_cross_crate/b.rs b/src/test/incremental/struct_change_field_type_cross_crate/b.rs
index 9660f47da35..e5ec9784847 100644
--- a/src/test/incremental/struct_change_field_type_cross_crate/b.rs
+++ b/src/test/incremental/struct_change_field_type_cross_crate/b.rs
@@ -12,6 +12,8 @@
 // revisions:rpass1 rpass2
 // compile-flags: -Z query-dep-graph
 
+// ignore-test -- ignored until red/green restores cross-crate tracking fidelity
+
 #![feature(rustc_attrs)]
 
 extern crate a;
diff --git a/src/test/incremental/type_alias_cross_crate/b.rs b/src/test/incremental/type_alias_cross_crate/b.rs
index ee35a4d9b9c..63e1437f068 100644
--- a/src/test/incremental/type_alias_cross_crate/b.rs
+++ b/src/test/incremental/type_alias_cross_crate/b.rs
@@ -12,6 +12,8 @@
 // revisions:rpass1 rpass2 rpass3
 // compile-flags: -Z query-dep-graph
 
+// ignore-test -- ignored until red/green restores cross-crate tracking fidelity
+
 #![feature(rustc_attrs)]
 
 extern crate a;