Skip to content

Commit 9dbd7be

Browse files
Cache the DepNodeIndex of upstream crates in order to avoid multiple locks and table lookups on each access of crate metadata.
1 parent 275cf4b commit 9dbd7be

File tree

5 files changed

+45
-14
lines changed

5 files changed

+45
-14
lines changed

src/librustc/dep_graph/graph.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ rustc_index::newtype_index! {
3030
}
3131

3232
impl DepNodeIndex {
33-
const INVALID: DepNodeIndex = DepNodeIndex::MAX;
33+
pub const INVALID: DepNodeIndex = DepNodeIndex::MAX;
3434
}
3535

3636
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]

src/librustc_metadata/creader.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,11 @@
33
use crate::cstore::{self, CStore, CrateSource, MetadataBlob};
44
use crate::locator::{self, CratePaths};
55
use crate::schema::{CrateRoot, CrateDep};
6-
use rustc_data_structures::sync::{Lrc, RwLock, Lock};
6+
use rustc_data_structures::sync::{Lrc, RwLock, Lock, AtomicCell};
77

88
use rustc::hir::def_id::CrateNum;
99
use rustc_data_structures::svh::Svh;
10+
use rustc::dep_graph::DepNodeIndex;
1011
use rustc::middle::cstore::DepKind;
1112
use rustc::mir::interpret::AllocDecodingState;
1213
use rustc::session::{Session, CrateDisambiguator};
@@ -271,7 +272,8 @@ impl<'a> CrateLoader<'a> {
271272
},
272273
private_dep,
273274
span,
274-
raw_proc_macros
275+
raw_proc_macros,
276+
dep_node_index: AtomicCell::new(DepNodeIndex::INVALID),
275277
};
276278

277279
let cmeta = Lrc::new(cmeta);

src/librustc_metadata/cstore.rs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,15 @@
22
// crates and libraries
33

44
use crate::schema;
5+
use rustc::dep_graph::DepNodeIndex;
56
use rustc::hir::def_id::{CrateNum, DefIndex};
67
use rustc::hir::map::definitions::DefPathTable;
78
use rustc::middle::cstore::{DepKind, ExternCrate, MetadataLoader};
89
use rustc::mir::interpret::AllocDecodingState;
910
use rustc_index::vec::IndexVec;
1011
use rustc::util::nodemap::{FxHashMap, NodeMap};
1112

12-
use rustc_data_structures::sync::{Lrc, RwLock, Lock};
13+
use rustc_data_structures::sync::{Lrc, RwLock, Lock, AtomicCell};
1314
use syntax::ast;
1415
use syntax::ext::base::SyntaxExtension;
1516
use syntax_pos;
@@ -83,6 +84,13 @@ pub struct CrateMetadata {
8384
pub span: Span,
8485

8586
pub raw_proc_macros: Option<&'static [ProcMacro]>,
87+
88+
/// The `DepNodeIndex` of the `DepNode` representing this upstream crate.
89+
/// It is initialized on the first access in `get_crate_dep_node_index()`.
90+
/// Do not access the value directly, as it might not have been initialized
91+
/// yet.
92+
/// The field must always be initialized to `DepNodeIndex::INVALID`.
93+
pub(super) dep_node_index: AtomicCell<DepNodeIndex>,
8694
}
8795

8896
pub struct CStore {

src/librustc_metadata/cstore_impl.rs

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -51,19 +51,15 @@ macro_rules! provide {
5151
let ($def_id, $other) = def_id_arg.into_args();
5252
assert!(!$def_id.is_local());
5353

54-
let def_path_hash = $tcx.def_path_hash(DefId {
55-
krate: $def_id.krate,
56-
index: CRATE_DEF_INDEX
57-
});
58-
let dep_node = def_path_hash
59-
.to_dep_node(rustc::dep_graph::DepKind::CrateMetadata);
60-
// The DepNodeIndex of the DepNode::CrateMetadata should be
61-
// cached somewhere, so that we can use read_index().
62-
$tcx.dep_graph.read(dep_node);
63-
6454
let $cdata = $tcx.crate_data_as_rc_any($def_id.krate);
6555
let $cdata = $cdata.downcast_ref::<cstore::CrateMetadata>()
6656
.expect("CrateStore created data is not a CrateMetadata");
57+
58+
if $tcx.dep_graph.is_fully_enabled() {
59+
let crate_dep_node_index = $cdata.get_crate_dep_node_index($tcx);
60+
$tcx.dep_graph.read_index(crate_dep_node_index);
61+
}
62+
6763
$compute
6864
})*
6965

src/librustc_metadata/decoder.rs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ use rustc::hir::def::{self, Res, DefKind, CtorOf, CtorKind};
1313
use rustc::hir::def_id::{CrateNum, DefId, DefIndex, LocalDefId, CRATE_DEF_INDEX, LOCAL_CRATE};
1414
use rustc_data_structures::fingerprint::Fingerprint;
1515
use rustc_data_structures::fx::FxHashMap;
16+
use rustc::dep_graph::{DepNodeIndex, DepKind};
1617
use rustc::middle::lang_items;
1718
use rustc::mir::{self, interpret};
1819
use rustc::mir::interpret::AllocDecodingSession;
@@ -1365,6 +1366,30 @@ impl<'a, 'tcx> CrateMetadata {
13651366
// This shouldn't borrow twice, but there is no way to downgrade RefMut to Ref.
13661367
self.source_map_import_info.borrow()
13671368
}
1369+
1370+
/// Get the `DepNodeIndex` corresponding this crate. The result of this
1371+
/// method is cached in the `dep_node_index` field.
1372+
pub(super) fn get_crate_dep_node_index(&self, tcx: TyCtxt<'tcx>) -> DepNodeIndex {
1373+
let mut dep_node_index = self.dep_node_index.load();
1374+
1375+
if dep_node_index == DepNodeIndex::INVALID {
1376+
// We have not cached the DepNodeIndex for this upstream crate yet,
1377+
// so use the dep-graph to find it out and cache it.
1378+
// Note that multiple threads can enter this block concurrently.
1379+
// That is fine because the DepNodeIndex remains constant
1380+
// throughout the whole compilation session, and multiple stores
1381+
// would always write the same value.
1382+
1383+
let def_path_hash = self.def_path_hash(CRATE_DEF_INDEX);
1384+
let dep_node = def_path_hash.to_dep_node(DepKind::CrateMetadata);
1385+
1386+
dep_node_index = tcx.dep_graph.dep_node_index_of(&dep_node);
1387+
assert!(dep_node_index != DepNodeIndex::INVALID);
1388+
self.dep_node_index.store(dep_node_index);
1389+
}
1390+
1391+
dep_node_index
1392+
}
13681393
}
13691394

13701395
// Cannot be implemented on 'ProcMacro', as libproc_macro

0 commit comments

Comments
 (0)