1
Fork 0

Sanity check fingerprints in the dep-graph.

This commit is contained in:
Camille GILLOT 2022-05-08 14:42:12 +02:00
parent 7c45772bc9
commit ca42dd6716
2 changed files with 39 additions and 19 deletions

View file

@ -916,6 +916,11 @@ pub(super) struct CurrentDepGraph<K: DepKind> {
new_node_to_index: Sharded<FxHashMap<DepNode<K>, DepNodeIndex>>, new_node_to_index: Sharded<FxHashMap<DepNode<K>, DepNodeIndex>>,
prev_index_to_index: Lock<IndexVec<SerializedDepNodeIndex, Option<DepNodeIndex>>>, prev_index_to_index: Lock<IndexVec<SerializedDepNodeIndex, Option<DepNodeIndex>>>,
/// This is used to verify that fingerprints do not change between the creation of a node
/// and its recomputation.
#[cfg(debug_assertions)]
fingerprints: Lock<FxHashMap<DepNode<K>, Fingerprint>>,
/// Used to trap when a specific edge is added to the graph. /// Used to trap when a specific edge is added to the graph.
/// This is used for debug purposes and is only active with `debug_assertions`. /// This is used for debug purposes and is only active with `debug_assertions`.
#[cfg(debug_assertions)] #[cfg(debug_assertions)]
@ -999,6 +1004,8 @@ impl<K: DepKind> CurrentDepGraph<K> {
anon_id_seed, anon_id_seed,
#[cfg(debug_assertions)] #[cfg(debug_assertions)]
forbidden_edge, forbidden_edge,
#[cfg(debug_assertions)]
fingerprints: Lock::new(Default::default()),
total_read_count: AtomicU64::new(0), total_read_count: AtomicU64::new(0),
total_duplicate_read_count: AtomicU64::new(0), total_duplicate_read_count: AtomicU64::new(0),
node_intern_event_id, node_intern_event_id,
@ -1006,10 +1013,18 @@ impl<K: DepKind> CurrentDepGraph<K> {
} }
#[cfg(debug_assertions)] #[cfg(debug_assertions)]
fn record_edge(&self, dep_node_index: DepNodeIndex, key: DepNode<K>) { fn record_edge(&self, dep_node_index: DepNodeIndex, key: DepNode<K>, fingerprint: Fingerprint) {
if let Some(forbidden_edge) = &self.forbidden_edge { if let Some(forbidden_edge) = &self.forbidden_edge {
forbidden_edge.index_to_node.lock().insert(dep_node_index, key); forbidden_edge.index_to_node.lock().insert(dep_node_index, key);
} }
match self.fingerprints.lock().entry(key) {
Entry::Vacant(v) => {
v.insert(fingerprint);
}
Entry::Occupied(o) => {
assert_eq!(*o.get(), fingerprint, "Unstable fingerprints for {:?}", key);
}
}
} }
/// Writes the node to the current dep-graph and allocates a `DepNodeIndex` for it. /// Writes the node to the current dep-graph and allocates a `DepNodeIndex` for it.
@ -1021,17 +1036,21 @@ impl<K: DepKind> CurrentDepGraph<K> {
edges: EdgesVec, edges: EdgesVec,
current_fingerprint: Fingerprint, current_fingerprint: Fingerprint,
) -> DepNodeIndex { ) -> DepNodeIndex {
match self.new_node_to_index.get_shard_by_value(&key).lock().entry(key) { let dep_node_index = match self.new_node_to_index.get_shard_by_value(&key).lock().entry(key)
{
Entry::Occupied(entry) => *entry.get(), Entry::Occupied(entry) => *entry.get(),
Entry::Vacant(entry) => { Entry::Vacant(entry) => {
let dep_node_index = let dep_node_index =
self.encoder.borrow().send(profiler, key, current_fingerprint, edges); self.encoder.borrow().send(profiler, key, current_fingerprint, edges);
entry.insert(dep_node_index); entry.insert(dep_node_index);
#[cfg(debug_assertions)]
self.record_edge(dep_node_index, key);
dep_node_index dep_node_index
} }
} };
#[cfg(debug_assertions)]
self.record_edge(dep_node_index, key, current_fingerprint);
dep_node_index
} }
fn intern_node( fn intern_node(
@ -1072,7 +1091,7 @@ impl<K: DepKind> CurrentDepGraph<K> {
}; };
#[cfg(debug_assertions)] #[cfg(debug_assertions)]
self.record_edge(dep_node_index, key); self.record_edge(dep_node_index, key, fingerprint);
(dep_node_index, Some((prev_index, DepNodeColor::Green(dep_node_index)))) (dep_node_index, Some((prev_index, DepNodeColor::Green(dep_node_index))))
} else { } else {
if print_status { if print_status {
@ -1094,7 +1113,7 @@ impl<K: DepKind> CurrentDepGraph<K> {
}; };
#[cfg(debug_assertions)] #[cfg(debug_assertions)]
self.record_edge(dep_node_index, key); self.record_edge(dep_node_index, key, fingerprint);
(dep_node_index, Some((prev_index, DepNodeColor::Red))) (dep_node_index, Some((prev_index, DepNodeColor::Red)))
} }
} else { } else {
@ -1119,7 +1138,7 @@ impl<K: DepKind> CurrentDepGraph<K> {
}; };
#[cfg(debug_assertions)] #[cfg(debug_assertions)]
self.record_edge(dep_node_index, key); self.record_edge(dep_node_index, key, Fingerprint::ZERO);
(dep_node_index, Some((prev_index, DepNodeColor::Red))) (dep_node_index, Some((prev_index, DepNodeColor::Red)))
} }
} else { } else {
@ -1150,19 +1169,16 @@ impl<K: DepKind> CurrentDepGraph<K> {
Some(dep_node_index) => dep_node_index, Some(dep_node_index) => dep_node_index,
None => { None => {
let key = prev_graph.index_to_node(prev_index); let key = prev_graph.index_to_node(prev_index);
let dep_node_index = self.encoder.borrow().send( let edges = prev_graph
profiler, .edge_targets_from(prev_index)
key, .iter()
prev_graph.fingerprint_by_index(prev_index), .map(|i| prev_index_to_index[*i].unwrap())
prev_graph .collect();
.edge_targets_from(prev_index) let fingerprint = prev_graph.fingerprint_by_index(prev_index);
.iter() let dep_node_index = self.encoder.borrow().send(profiler, key, fingerprint, edges);
.map(|i| prev_index_to_index[*i].unwrap())
.collect(),
);
prev_index_to_index[prev_index] = Some(dep_node_index); prev_index_to_index[prev_index] = Some(dep_node_index);
#[cfg(debug_assertions)] #[cfg(debug_assertions)]
self.record_edge(dep_node_index, key); self.record_edge(dep_node_index, key, fingerprint);
dep_node_index dep_node_index
} }
} }

View file

@ -117,6 +117,8 @@ where
let mut lock = self.cache.get_shard_by_value(&key).lock(); let mut lock = self.cache.get_shard_by_value(&key).lock();
#[cfg(not(parallel_compiler))] #[cfg(not(parallel_compiler))]
let mut lock = self.cache.lock(); let mut lock = self.cache.lock();
// We may be overwriting another value. This is all right, since the dep-graph
// will check that the fingerprint matches.
lock.insert(key, (value.clone(), index)); lock.insert(key, (value.clone(), index));
value value
} }
@ -202,6 +204,8 @@ where
let mut lock = self.cache.get_shard_by_value(&key).lock(); let mut lock = self.cache.get_shard_by_value(&key).lock();
#[cfg(not(parallel_compiler))] #[cfg(not(parallel_compiler))]
let mut lock = self.cache.lock(); let mut lock = self.cache.lock();
// We may be overwriting another value. This is all right, since the dep-graph
// will check that the fingerprint matches.
lock.insert(key, value); lock.insert(key, value);
&value.0 &value.0
} }