Skip to content

Commit 03eb75f

Browse files
committed
rustc_query_system: avoid race condition when using edge_count
1 parent 22ed751 commit 03eb75f

File tree

1 file changed

+6
-11
lines changed
  • compiler/rustc_query_system/src/dep_graph

1 file changed

+6
-11
lines changed

compiler/rustc_query_system/src/dep_graph/graph.rs

+6-11
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet};
33
use rustc_data_structures::profiling::QueryInvocationId;
44
use rustc_data_structures::sharded::{self, Sharded};
55
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
6-
use rustc_data_structures::sync::{AtomicU32, AtomicU64, Lock, Lrc, Ordering};
6+
use rustc_data_structures::sync::{AtomicU32, AtomicU64, Lock, LockGuard, Lrc, Ordering};
77
use rustc_data_structures::unlikely;
88
use rustc_errors::Diagnostic;
99
use rustc_index::vec::{Idx, IndexVec};
@@ -135,16 +135,14 @@ impl<K: DepKind> DepGraph<K> {
135135
}
136136

137137
pub fn query(&self) -> DepGraphQuery<K> {
138-
// We call this before acquiring locks, since it also acquires them.
139-
// The extra locking is not a big deal, as this gets called rarely.
140-
let edge_count = self.edge_count();
141138
let data = self.data.as_ref().unwrap();
142139
let previous = &data.previous;
143140

144141
// Note locking order: `prev_index_to_index`, then `data`.
145142
let prev_index_to_index = data.current.prev_index_to_index.lock();
146143
let data = data.current.data.lock();
147144
let node_count = data.hybrid_indices.len();
145+
let edge_count = self.edge_count(&data);
148146

149147
let mut nodes = Vec::with_capacity(node_count);
150148
let mut edge_list_indices = Vec::with_capacity(node_count);
@@ -566,14 +564,13 @@ impl<K: DepKind> DepGraph<K> {
566564
}
567565
}
568566

569-
fn edge_count(&self) -> usize {
567+
fn edge_count(&self, node_data: &LockGuard<'_, DepNodeData<K>>) -> usize {
570568
let data = self.data.as_ref().unwrap();
571569
let previous = &data.previous;
572-
let data = data.current.data.lock();
573570

574-
let mut edge_count = data.unshared_edges.len();
571+
let mut edge_count = node_data.unshared_edges.len();
575572

576-
for &hybrid_index in data.hybrid_indices.iter() {
573+
for &hybrid_index in node_data.hybrid_indices.iter() {
577574
if let HybridIndex::DarkGreen(prev_index) = hybrid_index.into() {
578575
edge_count += previous.edge_targets_from(prev_index).len()
579576
}
@@ -585,16 +582,14 @@ impl<K: DepKind> DepGraph<K> {
585582
pub fn serialize(&self) -> SerializedDepGraph<K> {
586583
type SDNI = SerializedDepNodeIndex;
587584

588-
// We call this before acquiring locks, since it also acquires them.
589-
// The extra locking is not a big deal, as this only gets called once.
590-
let edge_count = self.edge_count();
591585
let data = self.data.as_ref().unwrap();
592586
let previous = &data.previous;
593587

594588
// Note locking order: `prev_index_to_index`, then `data`.
595589
let prev_index_to_index = data.current.prev_index_to_index.lock();
596590
let data = data.current.data.lock();
597591
let node_count = data.hybrid_indices.len();
592+
let edge_count = self.edge_count(&data);
598593

599594
let mut nodes = IndexVec::with_capacity(node_count);
600595
let mut fingerprints = IndexVec::with_capacity(node_count);

0 commit comments

Comments
 (0)