diff options
author | Michael Woerister <michaelwoerister@posteo> | 2019-10-09 16:41:24 +0200 |
---|---|---|
committer | Michael Woerister <michaelwoerister@posteo> | 2019-10-09 16:58:10 +0200 |
commit | 9dbd7be70f8b09aad232d5c4eda684cff622102d (patch) | |
tree | f371b6fa1ae51e6b5c7b4bf2892be599ae54312d | |
parent | 275cf4bcacad3fbe5539ecd5840462793ae46eec (diff) | |
download | rust-9dbd7be70f8b09aad232d5c4eda684cff622102d.tar.gz |
Cache the DepNodeIndex of upstream crates in order to avoid multiple locks and table lookups on each access of crate metadata.
-rw-r--r-- | src/librustc/dep_graph/graph.rs | 2 | ||||
-rw-r--r-- | src/librustc_metadata/creader.rs | 6 | ||||
-rw-r--r-- | src/librustc_metadata/cstore.rs | 10 | ||||
-rw-r--r-- | src/librustc_metadata/cstore_impl.rs | 16 | ||||
-rw-r--r-- | src/librustc_metadata/decoder.rs | 25 |
5 files changed, 45 insertions, 14 deletions
diff --git a/src/librustc/dep_graph/graph.rs b/src/librustc/dep_graph/graph.rs index e0cb00cf697..7e506f6e1b7 100644 --- a/src/librustc/dep_graph/graph.rs +++ b/src/librustc/dep_graph/graph.rs @@ -30,7 +30,7 @@ rustc_index::newtype_index! { } impl DepNodeIndex { - const INVALID: DepNodeIndex = DepNodeIndex::MAX; + pub const INVALID: DepNodeIndex = DepNodeIndex::MAX; } #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] diff --git a/src/librustc_metadata/creader.rs b/src/librustc_metadata/creader.rs index 042252bc13e..cae4858c844 100644 --- a/src/librustc_metadata/creader.rs +++ b/src/librustc_metadata/creader.rs @@ -3,10 +3,11 @@ use crate::cstore::{self, CStore, CrateSource, MetadataBlob}; use crate::locator::{self, CratePaths}; use crate::schema::{CrateRoot, CrateDep}; -use rustc_data_structures::sync::{Lrc, RwLock, Lock}; +use rustc_data_structures::sync::{Lrc, RwLock, Lock, AtomicCell}; use rustc::hir::def_id::CrateNum; use rustc_data_structures::svh::Svh; +use rustc::dep_graph::DepNodeIndex; use rustc::middle::cstore::DepKind; use rustc::mir::interpret::AllocDecodingState; use rustc::session::{Session, CrateDisambiguator}; @@ -271,7 +272,8 @@ impl<'a> CrateLoader<'a> { }, private_dep, span, - raw_proc_macros + raw_proc_macros, + dep_node_index: AtomicCell::new(DepNodeIndex::INVALID), }; let cmeta = Lrc::new(cmeta); diff --git a/src/librustc_metadata/cstore.rs b/src/librustc_metadata/cstore.rs index 833c846573f..98a08e501f1 100644 --- a/src/librustc_metadata/cstore.rs +++ b/src/librustc_metadata/cstore.rs @@ -2,6 +2,7 @@ // crates and libraries use crate::schema; +use rustc::dep_graph::DepNodeIndex; use rustc::hir::def_id::{CrateNum, DefIndex}; use rustc::hir::map::definitions::DefPathTable; use rustc::middle::cstore::{DepKind, ExternCrate, MetadataLoader}; @@ -9,7 +10,7 @@ use rustc::mir::interpret::AllocDecodingState; use rustc_index::vec::IndexVec; use rustc::util::nodemap::{FxHashMap, NodeMap}; -use rustc_data_structures::sync::{Lrc, RwLock, Lock}; +use rustc_data_structures::sync::{Lrc, RwLock, Lock, AtomicCell}; use syntax::ast; use syntax::ext::base::SyntaxExtension; use syntax_pos; @@ -83,6 +84,13 @@ pub struct CrateMetadata { pub span: Span, pub raw_proc_macros: Option<&'static [ProcMacro]>, + + /// 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`. + pub(super) dep_node_index: AtomicCell<DepNodeIndex>, } pub struct CStore { diff --git a/src/librustc_metadata/cstore_impl.rs b/src/librustc_metadata/cstore_impl.rs index cce0900bef3..b9f1d5a0a92 100644 --- a/src/librustc_metadata/cstore_impl.rs +++ b/src/librustc_metadata/cstore_impl.rs @@ -51,19 +51,15 @@ 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(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); let $cdata = $cdata.downcast_ref::<cstore::CrateMetadata>() .expect("CrateStore created data is not a CrateMetadata"); + + 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); + } + $compute })* diff --git a/src/librustc_metadata/decoder.rs b/src/librustc_metadata/decoder.rs index eed355cbc13..ce66534e565 100644 --- a/src/librustc_metadata/decoder.rs +++ b/src/librustc_metadata/decoder.rs @@ -13,6 +13,7 @@ use rustc::hir::def::{self, Res, DefKind, CtorOf, CtorKind}; use rustc::hir::def_id::{CrateNum, DefId, DefIndex, LocalDefId, CRATE_DEF_INDEX, LOCAL_CRATE}; use rustc_data_structures::fingerprint::Fingerprint; use rustc_data_structures::fx::FxHashMap; +use rustc::dep_graph::{DepNodeIndex, DepKind}; use rustc::middle::lang_items; use rustc::mir::{self, interpret}; use rustc::mir::interpret::AllocDecodingSession; @@ -1365,6 +1366,30 @@ impl<'a, 'tcx> CrateMetadata { // This shouldn't borrow twice, but there is no way to downgrade RefMut to Ref. self.source_map_import_info.borrow() } + + /// Get the `DepNodeIndex` corresponding this crate. The result of this + /// method is cached in the `dep_node_index` field. + pub(super) fn get_crate_dep_node_index(&self, tcx: TyCtxt<'tcx>) -> DepNodeIndex { + let mut dep_node_index = self.dep_node_index.load(); + + if 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 = def_path_hash.to_dep_node(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 + } } // Cannot be implemented on 'ProcMacro', as libproc_macro |