incr.comp.: Remove support for loading metadata fingerprints.
This commit is contained in:
parent
5974ec745e
commit
2a50d127dd
17 changed files with 105 additions and 308 deletions
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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") }
|
||||
|
|
|
|||
|
|
@ -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)"),
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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())
|
||||
}
|
||||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -15,7 +15,6 @@
|
|||
mod data;
|
||||
mod dirty_clean;
|
||||
mod fs;
|
||||
mod hash;
|
||||
mod load;
|
||||
mod preds;
|
||||
mod save;
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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)]
|
||||
|
|
|
|||
|
|
@ -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)]
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue