Skip to content

Commit 19193d6

Browse files
committed
Auto merge of #42504 - michaelwoerister:hash-dep-nodes-prep, r=nikomatsakis
Some preparatory refactorings for hash-based DepNodes This PR collects some changes that turn out to be necessary for implementing `DepNodes` based on stable hashes (see #42294). The commits are self-contained and mostly straightforward. The most interesting change here is the introduction of `DefIndices` for things that are not part of the AST: Some pieces of crate metadata now have a `DefIndex` too. cc @eddyb r? @nikomatsakis
2 parents 2416e22 + 8b36d33 commit 19193d6

31 files changed

+464
-348
lines changed

src/librustc/dep_graph/dep_node.rs

+12-18
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,10 @@
99
// except according to those terms.
1010

1111
use hir::def_id::CrateNum;
12+
use ich::Fingerprint;
13+
use rustc_data_structures::stable_hasher::StableHasher;
1214
use std::fmt::Debug;
13-
use std::sync::Arc;
15+
use std::hash::Hash;
1416

1517
macro_rules! try_opt {
1618
($e:expr) => (
@@ -51,12 +53,9 @@ pub enum DepNode<D: Clone + Debug> {
5153
/// in an extern crate.
5254
MetaData(D),
5355

54-
/// Represents some piece of metadata global to its crate.
55-
GlobalMetaData(D, GlobalMetaDataKind),
56-
5756
/// Represents some artifact that we save to disk. Note that these
5857
/// do not have a def-id as part of their identifier.
59-
WorkProduct(Arc<WorkProductId>),
58+
WorkProduct(WorkProductId),
6059

6160
// Represents different phases in the compiler.
6261
RegionMaps(D),
@@ -307,7 +306,6 @@ impl<D: Clone + Debug> DepNode<D> {
307306
ItemBodyNestedBodies(ref d) => op(d).map(ItemBodyNestedBodies),
308307
ConstIsRvaluePromotableToStatic(ref d) => op(d).map(ConstIsRvaluePromotableToStatic),
309308
IsMirAvailable(ref d) => op(d).map(IsMirAvailable),
310-
GlobalMetaData(ref d, kind) => op(d).map(|d| GlobalMetaData(d, kind)),
311309
}
312310
}
313311
}
@@ -318,17 +316,13 @@ impl<D: Clone + Debug> DepNode<D> {
318316
/// the need to be mapped or unmapped. (This ensures we can serialize
319317
/// them even in the absence of a tcx.)
320318
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable)]
321-
pub struct WorkProductId(pub String);
319+
pub struct WorkProductId(pub Fingerprint);
322320

323-
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable)]
324-
pub enum GlobalMetaDataKind {
325-
Krate,
326-
CrateDeps,
327-
DylibDependencyFormats,
328-
LangItems,
329-
LangItemsMissing,
330-
NativeLibraries,
331-
CodeMap,
332-
Impls,
333-
ExportedSymbols,
321+
impl WorkProductId {
322+
pub fn from_cgu_name(cgu_name: &str) -> WorkProductId {
323+
let mut hasher = StableHasher::new();
324+
cgu_name.len().hash(&mut hasher);
325+
cgu_name.hash(&mut hasher);
326+
WorkProductId(hasher.finish())
327+
}
334328
}

src/librustc/dep_graph/graph.rs

+7-8
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ use rustc_data_structures::fx::FxHashMap;
1313
use session::config::OutputType;
1414
use std::cell::{Ref, RefCell};
1515
use std::rc::Rc;
16-
use std::sync::Arc;
1716

1817
use super::dep_node::{DepNode, WorkProductId};
1918
use super::query::DepGraphQuery;
@@ -35,10 +34,10 @@ struct DepGraphData {
3534
/// things available to us. If we find that they are not dirty, we
3635
/// load the path to the file storing those work-products here into
3736
/// this map. We can later look for and extract that data.
38-
previous_work_products: RefCell<FxHashMap<Arc<WorkProductId>, WorkProduct>>,
37+
previous_work_products: RefCell<FxHashMap<WorkProductId, WorkProduct>>,
3938

4039
/// Work-products that we generate in this run.
41-
work_products: RefCell<FxHashMap<Arc<WorkProductId>, WorkProduct>>,
40+
work_products: RefCell<FxHashMap<WorkProductId, WorkProduct>>,
4241
}
4342

4443
impl DepGraph {
@@ -120,7 +119,7 @@ impl DepGraph {
120119
/// Indicates that a previous work product exists for `v`. This is
121120
/// invoked during initial start-up based on what nodes are clean
122121
/// (and what files exist in the incr. directory).
123-
pub fn insert_previous_work_product(&self, v: &Arc<WorkProductId>, data: WorkProduct) {
122+
pub fn insert_previous_work_product(&self, v: &WorkProductId, data: WorkProduct) {
124123
debug!("insert_previous_work_product({:?}, {:?})", v, data);
125124
self.data.previous_work_products.borrow_mut()
126125
.insert(v.clone(), data);
@@ -129,29 +128,29 @@ impl DepGraph {
129128
/// Indicates that we created the given work-product in this run
130129
/// for `v`. This record will be preserved and loaded in the next
131130
/// run.
132-
pub fn insert_work_product(&self, v: &Arc<WorkProductId>, data: WorkProduct) {
131+
pub fn insert_work_product(&self, v: &WorkProductId, data: WorkProduct) {
133132
debug!("insert_work_product({:?}, {:?})", v, data);
134133
self.data.work_products.borrow_mut()
135134
.insert(v.clone(), data);
136135
}
137136

138137
/// Check whether a previous work product exists for `v` and, if
139138
/// so, return the path that leads to it. Used to skip doing work.
140-
pub fn previous_work_product(&self, v: &Arc<WorkProductId>) -> Option<WorkProduct> {
139+
pub fn previous_work_product(&self, v: &WorkProductId) -> Option<WorkProduct> {
141140
self.data.previous_work_products.borrow()
142141
.get(v)
143142
.cloned()
144143
}
145144

146145
/// Access the map of work-products created during this run. Only
147146
/// used during saving of the dep-graph.
148-
pub fn work_products(&self) -> Ref<FxHashMap<Arc<WorkProductId>, WorkProduct>> {
147+
pub fn work_products(&self) -> Ref<FxHashMap<WorkProductId, WorkProduct>> {
149148
self.data.work_products.borrow()
150149
}
151150

152151
/// Access the map of work-products created during the cached run. Only
153152
/// used during saving of the dep-graph.
154-
pub fn previous_work_products(&self) -> Ref<FxHashMap<Arc<WorkProductId>, WorkProduct>> {
153+
pub fn previous_work_products(&self) -> Ref<FxHashMap<WorkProductId, WorkProduct>> {
155154
self.data.previous_work_products.borrow()
156155
}
157156
}

src/librustc/dep_graph/mod.rs

-1
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ mod thread;
2222
pub use self::dep_tracking_map::{DepTrackingMap, DepTrackingMapConfig};
2323
pub use self::dep_node::DepNode;
2424
pub use self::dep_node::WorkProductId;
25-
pub use self::dep_node::GlobalMetaDataKind;
2625
pub use self::graph::DepGraph;
2726
pub use self::graph::WorkProduct;
2827
pub use self::query::DepGraphQuery;

src/librustc/hir/map/definitions.rs

+106-12
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,8 @@
1515
//! expressions) that are mostly just leftovers.
1616
1717
use hir;
18-
use hir::def_id::{CrateNum, DefId, DefIndex, LOCAL_CRATE, DefIndexAddressSpace};
18+
use hir::def_id::{CrateNum, DefId, DefIndex, LOCAL_CRATE, DefIndexAddressSpace,
19+
CRATE_DEF_INDEX};
1920
use ich::Fingerprint;
2021
use rustc_data_structures::fx::FxHashMap;
2122
use rustc_data_structures::indexed_vec::IndexVec;
@@ -396,6 +397,11 @@ pub enum DefPathData {
396397
ImplTrait,
397398
/// A `typeof` type node.
398399
Typeof,
400+
401+
/// GlobalMetaData identifies a piece of crate metadata that is global to
402+
/// a whole crate (as opposed to just one item). GlobalMetaData components
403+
/// are only supposed to show up right below the crate root.
404+
GlobalMetaData(Ident)
399405
}
400406

401407
#[derive(Copy, Clone, Hash, PartialEq, Eq, PartialOrd, Ord, Debug,
@@ -427,8 +433,8 @@ impl Definitions {
427433

428434
/// Get the number of definitions.
429435
pub fn def_index_counts_lo_hi(&self) -> (usize, usize) {
430-
(self.def_index_to_node[DefIndexAddressSpace::Low.index()].len(),
431-
self.def_index_to_node[DefIndexAddressSpace::High.index()].len())
436+
(self.table.index_to_key[DefIndexAddressSpace::Low.index()].len(),
437+
self.table.index_to_key[DefIndexAddressSpace::High.index()].len())
432438
}
433439

434440
pub fn def_key(&self, index: DefIndex) -> DefKey {
@@ -469,7 +475,12 @@ impl Definitions {
469475
if def_id.krate == LOCAL_CRATE {
470476
let space_index = def_id.index.address_space().index();
471477
let array_index = def_id.index.as_array_index();
472-
Some(self.def_index_to_node[space_index][array_index])
478+
let node_id = self.def_index_to_node[space_index][array_index];
479+
if node_id != ast::DUMMY_NODE_ID {
480+
Some(node_id)
481+
} else {
482+
None
483+
}
473484
} else {
474485
None
475486
}
@@ -498,12 +509,16 @@ impl Definitions {
498509

499510
// Create the definition.
500511
let address_space = super::ITEM_LIKE_SPACE;
501-
let index = self.table.allocate(key, def_path_hash, address_space);
512+
let root_index = self.table.allocate(key, def_path_hash, address_space);
513+
assert_eq!(root_index, CRATE_DEF_INDEX);
502514
assert!(self.def_index_to_node[address_space.index()].is_empty());
503515
self.def_index_to_node[address_space.index()].push(ast::CRATE_NODE_ID);
504-
self.node_to_def_index.insert(ast::CRATE_NODE_ID, index);
516+
self.node_to_def_index.insert(ast::CRATE_NODE_ID, root_index);
505517

506-
index
518+
// Allocate some other DefIndices that always must exist.
519+
GlobalMetaDataKind::allocate_def_indices(self);
520+
521+
root_index
507522
}
508523

509524
/// Add a definition with a parent definition.
@@ -550,13 +565,19 @@ impl Definitions {
550565
assert_eq!(index.as_array_index(),
551566
self.def_index_to_node[address_space.index()].len());
552567
self.def_index_to_node[address_space.index()].push(node_id);
568+
569+
// Some things for which we allocate DefIndices don't correspond to
570+
// anything in the AST, so they don't have a NodeId. For these cases
571+
// we don't need a mapping from NodeId to DefIndex.
572+
if node_id != ast::DUMMY_NODE_ID {
573+
debug!("create_def_with_parent: def_index_to_node[{:?} <-> {:?}", index, node_id);
574+
self.node_to_def_index.insert(node_id, index);
575+
}
576+
553577
if expansion.is_modern() {
554578
self.expansions.insert(index, expansion);
555579
}
556580

557-
debug!("create_def_with_parent: def_index_to_node[{:?} <-> {:?}", index, node_id);
558-
self.node_to_def_index.insert(node_id, index);
559-
560581
index
561582
}
562583

@@ -594,7 +615,8 @@ impl DefPathData {
594615
LifetimeDef(ident) |
595616
EnumVariant(ident) |
596617
Binding(ident) |
597-
Field(ident) => Some(ident),
618+
Field(ident) |
619+
GlobalMetaData(ident) => Some(ident),
598620

599621
Impl |
600622
CrateRoot |
@@ -622,7 +644,8 @@ impl DefPathData {
622644
LifetimeDef(ident) |
623645
EnumVariant(ident) |
624646
Binding(ident) |
625-
Field(ident) => {
647+
Field(ident) |
648+
GlobalMetaData(ident) => {
626649
return ident.name.as_str();
627650
}
628651

@@ -667,3 +690,74 @@ impl ::std::hash::Hash for DefPathData {
667690
}
668691
}
669692
}
693+
694+
695+
// We define the GlobalMetaDataKind enum with this macro because we want to
696+
// make sure that we exhaustively iterate over all variants when registering
697+
// the corresponding DefIndices in the DefTable.
698+
macro_rules! define_global_metadata_kind {
699+
(pub enum GlobalMetaDataKind {
700+
$($variant:ident),*
701+
}) => (
702+
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash,
703+
RustcEncodable, RustcDecodable)]
704+
pub enum GlobalMetaDataKind {
705+
$($variant),*
706+
}
707+
708+
impl GlobalMetaDataKind {
709+
fn allocate_def_indices(definitions: &mut Definitions) {
710+
$({
711+
let instance = GlobalMetaDataKind::$variant;
712+
definitions.create_def_with_parent(
713+
CRATE_DEF_INDEX,
714+
ast::DUMMY_NODE_ID,
715+
DefPathData::GlobalMetaData(instance.ident()),
716+
DefIndexAddressSpace::High,
717+
Mark::root()
718+
);
719+
720+
// Make sure calling def_index does not crash.
721+
instance.def_index(&definitions.table);
722+
})*
723+
}
724+
725+
pub fn def_index(&self, def_path_table: &DefPathTable) -> DefIndex {
726+
let def_key = DefKey {
727+
parent: Some(CRATE_DEF_INDEX),
728+
disambiguated_data: DisambiguatedDefPathData {
729+
data: DefPathData::GlobalMetaData(self.ident()),
730+
disambiguator: 0,
731+
}
732+
};
733+
734+
def_path_table.key_to_index[&def_key]
735+
}
736+
737+
fn ident(&self) -> Ident {
738+
739+
let string = match *self {
740+
$(
741+
GlobalMetaDataKind::$variant => {
742+
concat!("{{GlobalMetaData::", stringify!($variant), "}}")
743+
}
744+
)*
745+
};
746+
747+
Ident::from_str(string)
748+
}
749+
}
750+
)
751+
}
752+
753+
define_global_metadata_kind!(pub enum GlobalMetaDataKind {
754+
Krate,
755+
CrateDeps,
756+
DylibDependencyFormats,
757+
LangItems,
758+
LangItemsMissing,
759+
NativeLibraries,
760+
CodeMap,
761+
Impls,
762+
ExportedSymbols
763+
});

src/librustc/ich/caching_codemap_view.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,8 @@ pub struct CachingCodemapView<'tcx> {
2929
time_stamp: usize,
3030
}
3131

32-
impl<'tcx> CachingCodemapView<'tcx> {
33-
pub fn new<'a>(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> CachingCodemapView<'tcx> {
32+
impl<'gcx> CachingCodemapView<'gcx> {
33+
pub fn new<'a, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>) -> CachingCodemapView<'gcx> {
3434
let codemap = tcx.sess.codemap();
3535
let files = codemap.files();
3636
let first_file = files[0].clone();

0 commit comments

Comments
 (0)