summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Woerister <michaelwoerister@posteo>2019-10-09 16:41:24 +0200
committerMichael Woerister <michaelwoerister@posteo>2019-10-09 16:58:10 +0200
commit9dbd7be70f8b09aad232d5c4eda684cff622102d (patch)
treef371b6fa1ae51e6b5c7b4bf2892be599ae54312d
parent275cf4bcacad3fbe5539ecd5840462793ae46eec (diff)
downloadrust-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.rs2
-rw-r--r--src/librustc_metadata/creader.rs6
-rw-r--r--src/librustc_metadata/cstore.rs10
-rw-r--r--src/librustc_metadata/cstore_impl.rs16
-rw-r--r--src/librustc_metadata/decoder.rs25
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