Remove DepKind::CrateMetadata and pre-allocation of DepNodes
Remove much of the special-case handling around crate metadata dependency tracking by replacing `DepKind::CrateMetadata` and the pre-allocation of corresponding `DepNodes` with on-demand invocation of the `crate_hash` query.
This commit is contained in:
parent
497c9a256b
commit
62139ffad4
9 changed files with 24 additions and 107 deletions
|
@ -10,7 +10,7 @@ use rustc_data_structures::captures::Captures;
|
|||
use rustc_data_structures::fingerprint::{Fingerprint, FingerprintDecoder};
|
||||
use rustc_data_structures::fx::FxHashMap;
|
||||
use rustc_data_structures::svh::Svh;
|
||||
use rustc_data_structures::sync::{AtomicCell, Lock, LockGuard, Lrc, OnceCell};
|
||||
use rustc_data_structures::sync::{Lock, LockGuard, Lrc, OnceCell};
|
||||
use rustc_data_structures::unhash::UnhashMap;
|
||||
use rustc_errors::ErrorReported;
|
||||
use rustc_expand::base::{SyntaxExtension, SyntaxExtensionKind};
|
||||
|
@ -21,7 +21,6 @@ use rustc_hir::def_id::{CrateNum, DefId, DefIndex, CRATE_DEF_INDEX, LOCAL_CRATE}
|
|||
use rustc_hir::definitions::{DefKey, DefPath, DefPathData, DefPathHash};
|
||||
use rustc_hir::lang_items;
|
||||
use rustc_index::vec::{Idx, IndexVec};
|
||||
use rustc_middle::dep_graph::{self, DepNode, DepNodeExt, DepNodeIndex};
|
||||
use rustc_middle::hir::exports::Export;
|
||||
use rustc_middle::middle::cstore::{CrateSource, ExternCrate};
|
||||
use rustc_middle::middle::cstore::{ForeignModule, LinkagePreference, NativeLib};
|
||||
|
@ -84,11 +83,6 @@ crate struct CrateMetadata {
|
|||
def_path_hash_map: OnceCell<UnhashMap<DefPathHash, DefIndex>>,
|
||||
/// Used for decoding interpret::AllocIds in a cached & thread-safe manner.
|
||||
alloc_decoding_state: AllocDecodingState,
|
||||
/// The `DepNodeIndex` of the `DepNode` representing this upstream crate.
|
||||
/// It is initialized on the first access in `get_crate_dep_node_index()`.
|
||||
/// Do not access the value directly, as it might not have been initialized yet.
|
||||
/// The field must always be initialized to `DepNodeIndex::INVALID`.
|
||||
dep_node_index: AtomicCell<DepNodeIndex>,
|
||||
/// Caches decoded `DefKey`s.
|
||||
def_key_cache: Lock<FxHashMap<DefIndex, DefKey>>,
|
||||
/// Caches decoded `DefPathHash`es.
|
||||
|
@ -1592,31 +1586,6 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
|
|||
self.def_path_hash_unlocked(index, &mut def_path_hashes)
|
||||
}
|
||||
|
||||
/// Get the `DepNodeIndex` corresponding this crate. The result of this
|
||||
/// method is cached in the `dep_node_index` field.
|
||||
fn get_crate_dep_node_index(&self, tcx: TyCtxt<'tcx>) -> DepNodeIndex {
|
||||
let mut dep_node_index = self.dep_node_index.load();
|
||||
|
||||
if unlikely!(dep_node_index == DepNodeIndex::INVALID) {
|
||||
// We have not cached the DepNodeIndex for this upstream crate yet,
|
||||
// so use the dep-graph to find it out and cache it.
|
||||
// Note that multiple threads can enter this block concurrently.
|
||||
// That is fine because the DepNodeIndex remains constant
|
||||
// throughout the whole compilation session, and multiple stores
|
||||
// would always write the same value.
|
||||
|
||||
let def_path_hash = self.def_path_hash(CRATE_DEF_INDEX);
|
||||
let dep_node =
|
||||
DepNode::from_def_path_hash(def_path_hash, dep_graph::DepKind::CrateMetadata);
|
||||
|
||||
dep_node_index = tcx.dep_graph.dep_node_index_of(&dep_node);
|
||||
assert!(dep_node_index != DepNodeIndex::INVALID);
|
||||
self.dep_node_index.store(dep_node_index);
|
||||
}
|
||||
|
||||
dep_node_index
|
||||
}
|
||||
|
||||
/// Imports the source_map from an external crate into the source_map of the crate
|
||||
/// currently being compiled (the "local crate").
|
||||
///
|
||||
|
@ -1833,7 +1802,6 @@ impl CrateMetadata {
|
|||
source_map_import_info: OnceCell::new(),
|
||||
def_path_hash_map: Default::default(),
|
||||
alloc_decoding_state,
|
||||
dep_node_index: AtomicCell::new(DepNodeIndex::INVALID),
|
||||
cnum,
|
||||
cnum_map,
|
||||
dependencies,
|
||||
|
|
|
@ -44,18 +44,33 @@ macro_rules! provide {
|
|||
let ($def_id, $other) = def_id_arg.into_args();
|
||||
assert!(!$def_id.is_local());
|
||||
|
||||
let $cdata = CStore::from_tcx($tcx).get_crate_data($def_id.krate);
|
||||
|
||||
if $tcx.dep_graph.is_fully_enabled() {
|
||||
let crate_dep_node_index = $cdata.get_crate_dep_node_index($tcx);
|
||||
$tcx.dep_graph.read_index(crate_dep_node_index);
|
||||
$tcx.ensure().crate_hash($def_id.krate);
|
||||
}
|
||||
|
||||
let $cdata = CStore::from_tcx($tcx).get_crate_data($def_id.krate);
|
||||
|
||||
$compute
|
||||
})*
|
||||
|
||||
// The other external query providers call `crate_hash` in order to register a
|
||||
// dependency on the crate metadata. The `crate_hash` implementation differs in
|
||||
// that it doesn't need to do this (and can't, as it would cause a query cycle).
|
||||
fn crate_hash<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
def_id_arg: ty::query::query_keys::crate_hash<'tcx>,
|
||||
) -> ty::query::query_values::crate_hash<'tcx> {
|
||||
let _prof_timer = tcx.prof.generic_activity("metadata_decode_entry_crate_hash");
|
||||
|
||||
let (def_id, _) = def_id_arg.into_args();
|
||||
assert!(!def_id.is_local());
|
||||
|
||||
CStore::from_tcx(tcx).get_crate_data(def_id.krate).root.hash
|
||||
}
|
||||
|
||||
*providers = Providers {
|
||||
$($name,)*
|
||||
crate_hash,
|
||||
..*providers
|
||||
};
|
||||
}
|
||||
|
@ -191,7 +206,6 @@ provide! { <'tcx> tcx, def_id, other, cdata,
|
|||
})
|
||||
}
|
||||
crate_disambiguator => { cdata.root.disambiguator }
|
||||
crate_hash => { cdata.root.hash }
|
||||
crate_host_hash => { cdata.host_hash }
|
||||
original_crate_name => { cdata.root.name }
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue