Skip to content

Commit 064bbb8

Browse files
committed
Make try_mark_previous_green lock-free.
1 parent ac230b7 commit 064bbb8

File tree

3 files changed

+288
-219
lines changed

3 files changed

+288
-219
lines changed

compiler/rustc_data_structures/src/sync.rs

+10-1
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ cfg_if! {
4040
}
4141
}
4242

43-
use std::ops::Add;
43+
use std::ops::{Add, BitOr};
4444
use std::panic::{resume_unwind, catch_unwind, AssertUnwindSafe};
4545

4646
/// This is a single threaded variant of AtomicCell provided by crossbeam.
@@ -147,6 +147,15 @@ cfg_if! {
147147
}
148148
}
149149

150+
impl<T: BitOr<Output=T> + Copy> Atomic<T> {
151+
#[inline]
152+
pub fn fetch_or(&self, val: T, _: Ordering) -> T {
153+
let old = self.0.get();
154+
self.0.set(old | val);
155+
old
156+
}
157+
}
158+
150159
pub type AtomicUsize = Atomic<usize>;
151160
pub type AtomicBool = Atomic<bool>;
152161
pub type AtomicU32 = Atomic<u32>;

compiler/rustc_query_system/src/dep_graph/graph.rs

+51-41
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,10 @@ impl std::convert::From<DepNodeIndex> for QueryInvocationId {
4646
}
4747

4848
struct DepGraphData<K: DepKind> {
49+
/// The dep-graph from the previous compilation session. It contains all
50+
/// nodes and edges as well as all fingerprints of nodes that have them.
51+
serialized: SerializedDepGraph<K>,
52+
4953
/// The dep-graph from the compilation session. It contains all
5054
/// nodes and edges as well as all fingerprints of nodes that have them.
5155
graph: RwLock<CurrentDepGraph<K>>,
@@ -118,9 +122,11 @@ impl<K: DepKind> DepGraph<K> {
118122
Err(_) => None,
119123
};
120124

125+
let graph = RwLock::new(CurrentDepGraph::new(&prev_graph));
121126
DepGraph {
122127
data: Some(Lrc::new(DepGraphData {
123-
graph: RwLock::new(CurrentDepGraph::new(prev_graph)),
128+
serialized: prev_graph,
129+
graph,
124130
emitting_diagnostics: Default::default(),
125131
previous_work_products: prev_work_products,
126132
dep_node_debug: Default::default(),
@@ -148,7 +154,7 @@ impl<K: DepKind> DepGraph<K> {
148154

149155
pub fn query(&self) -> DepGraphQuery<K> {
150156
let data = self.data.as_ref().unwrap();
151-
data.graph.read().query()
157+
data.graph.read().query(&data.serialized)
152158
}
153159

154160
pub fn assert_ignored(&self) {
@@ -239,6 +245,7 @@ impl<K: DepKind> DepGraph<K> {
239245

240246
// Intern the new `DepNode`.
241247
let dep_node_index = data.graph.write().intern_task_node(
248+
&data.serialized,
242249
key,
243250
&edges[..],
244251
current_fingerprint,
@@ -284,8 +291,11 @@ impl<K: DepKind> DepGraph<K> {
284291
hash: data.anon_id_seed.combine(hasher.finish()).into(),
285292
};
286293

287-
let dep_node_index =
288-
data.graph.write().intern_anon_node(target_dep_node, &task_deps.reads[..]);
294+
let dep_node_index = data.graph.write().intern_anon_node(
295+
&data.serialized,
296+
target_dep_node,
297+
&task_deps.reads[..],
298+
);
289299

290300
(result, dep_node_index)
291301
} else {
@@ -334,7 +344,10 @@ impl<K: DepKind> DepGraph<K> {
334344
#[cfg(debug_assertions)]
335345
if let Some(target) = task_deps.node {
336346
if let Some(ref forbidden_edge) = _data.forbidden_edge {
337-
let src = self.dep_node_of(dep_node_index);
347+
let src = _data
348+
.graph
349+
.read()
350+
.index_to_node(&_data.serialized, dep_node_index);
338351
if forbidden_edge.test(&src, &target) {
339352
panic!("forbidden edge {:?} -> {:?} created", src, target)
340353
}
@@ -352,24 +365,18 @@ impl<K: DepKind> DepGraph<K> {
352365
#[inline]
353366
fn dep_node_index_of_opt(&self, dep_node: &DepNode<K>) -> Option<DepNodeIndex> {
354367
let data = self.data.as_ref()?;
355-
data.graph.read().dep_node_index_of_opt(dep_node)
368+
data.graph.read().dep_node_index_of_opt(&data.serialized, dep_node)
356369
}
357370

358371
#[inline]
359372
pub fn dep_node_exists(&self, dep_node: &DepNode<K>) -> bool {
360373
self.dep_node_index_of_opt(dep_node).is_some()
361374
}
362375

363-
#[inline]
364-
fn dep_node_of(&self, dep_node_index: DepNodeIndex) -> DepNode<K> {
365-
let data = self.data.as_ref().unwrap();
366-
data.graph.read().dep_node_of(dep_node_index)
367-
}
368-
369376
#[inline]
370377
pub(crate) fn fingerprint_of(&self, dep_node_index: DepNodeIndex) -> Fingerprint {
371378
let data = self.data.as_ref().unwrap();
372-
data.graph.read().fingerprint_of(dep_node_index)
379+
data.graph.read().fingerprint_of(&data.serialized, dep_node_index)
373380
}
374381

375382
/// Checks whether a previous work product exists for `v` and, if
@@ -405,8 +412,8 @@ impl<K: DepKind> DepGraph<K> {
405412
pub fn node_color(&self, dep_node: &DepNode<K>) -> Option<DepNodeColor> {
406413
if let Some(ref data) = self.data {
407414
let graph = data.graph.read();
408-
if let Some(prev_index) = graph.node_to_index_opt(dep_node) {
409-
return graph.color(prev_index);
415+
if let Some(prev_index) = graph.node_to_index_opt(&data.serialized, dep_node) {
416+
return data.serialized.color(prev_index);
410417
} else {
411418
// This is a node that did not exist in the previous compilation
412419
// session, so we consider it to be red.
@@ -444,8 +451,8 @@ impl<K: DepKind> DepGraph<K> {
444451
let data = self.data.as_ref()?;
445452

446453
// Return None if the dep node didn't exist in the previous session
447-
let prev_index = data.graph.read().node_to_index_opt(dep_node)?;
448-
let prev_deps = data.graph.read().color_or_edges(prev_index);
454+
let prev_index = data.graph.read().node_to_index_opt(&data.serialized, dep_node)?;
455+
let prev_deps = data.serialized.color_or_edges(prev_index);
449456
let prev_deps = match prev_deps {
450457
Err(prev_deps) => prev_deps,
451458
Ok(DepNodeColor::Green) => return Some((prev_index, prev_index.rejuvenate())),
@@ -468,7 +475,7 @@ impl<K: DepKind> DepGraph<K> {
468475
parent_dep_node_index: SerializedDepNodeIndex,
469476
dep_node: &DepNode<K>,
470477
) -> Option<()> {
471-
let dep_dep_node_color = data.graph.read().color_or_edges(parent_dep_node_index);
478+
let dep_dep_node_color = data.serialized.color_or_edges(parent_dep_node_index);
472479
let prev_deps = match dep_dep_node_color {
473480
Ok(DepNodeColor::Green) => {
474481
// This dependency has been marked as green before, we are
@@ -477,7 +484,7 @@ impl<K: DepKind> DepGraph<K> {
477484
debug!(
478485
"try_mark_parent_green({:?}) --- found dependency {:?} to be immediately green",
479486
dep_node,
480-
data.graph.read().index_to_node(parent_dep_node_index)
487+
data.serialized.index_to_node(parent_dep_node_index)
481488
);
482489
return Some(());
483490
}
@@ -489,7 +496,7 @@ impl<K: DepKind> DepGraph<K> {
489496
debug!(
490497
"try_mark_parent_green({:?}) - END - dependency {:?} was immediately red",
491498
dep_node,
492-
data.graph.read().index_to_node(parent_dep_node_index)
499+
data.serialized.index_to_node(parent_dep_node_index)
493500
);
494501
return None;
495502
}
@@ -503,12 +510,12 @@ impl<K: DepKind> DepGraph<K> {
503510
is unknown, trying to mark it green",
504511
dep_node,
505512
{
506-
let dep_dep_node = data.graph.read().index_to_node(parent_dep_node_index);
513+
let dep_dep_node = data.serialized.index_to_node(parent_dep_node_index);
507514
(dep_dep_node, dep_dep_node.hash)
508515
}
509516
);
510517

511-
let dep_dep_node = &data.graph.read().index_to_node(parent_dep_node_index);
518+
let dep_dep_node = &data.serialized.index_to_node(parent_dep_node_index);
512519
let node_index =
513520
self.try_mark_previous_green(tcx, data, parent_dep_node_index, prev_deps, dep_dep_node);
514521
if node_index.is_some() {
@@ -533,7 +540,7 @@ impl<K: DepKind> DepGraph<K> {
533540
return None;
534541
}
535542

536-
let dep_dep_node_color = data.graph.read().color(parent_dep_node_index);
543+
let dep_dep_node_color = data.serialized.color(parent_dep_node_index);
537544

538545
match dep_dep_node_color {
539546
Some(DepNodeColor::Green) => {
@@ -592,15 +599,15 @@ impl<K: DepKind> DepGraph<K> {
592599

593600
// We never try to mark eval_always nodes as green
594601
debug_assert!(!dep_node.kind.is_eval_always());
595-
debug_assert_eq!(data.graph.read().index_to_node(prev_dep_node_index), *dep_node);
602+
debug_assert_eq!(data.serialized.index_to_node(prev_dep_node_index), *dep_node);
596603

597604
for &dep_dep_node_index in prev_deps {
598605
self.try_mark_parent_green(tcx, data, dep_dep_node_index, dep_node)?
599606
}
600607

601608
#[cfg(not(parallel_compiler))]
602609
debug_assert_eq!(
603-
data.graph.read().color(prev_dep_node_index),
610+
data.serialized.color(prev_dep_node_index),
604611
None,
605612
"DepGraph::try_mark_previous_green() - Duplicate DepNodeColor \
606613
insertion for {:?}",
@@ -616,7 +623,7 @@ impl<K: DepKind> DepGraph<K> {
616623
let dep_node_index = {
617624
// We allocating an entry for the node in the current dependency graph and
618625
// adding all the appropriate edges imported from the previous graph
619-
data.graph.write().intern_dark_green_node(prev_dep_node_index)
626+
data.serialized.intern_dark_green_node(prev_dep_node_index)
620627
};
621628

622629
// ... and emitting any stored diagnostic.
@@ -672,11 +679,10 @@ impl<K: DepKind> DepGraph<K> {
672679
let _prof_timer = tcx.profiler().generic_activity("incr_comp_query_cache_promotion");
673680

674681
let data = self.data.as_ref().unwrap();
675-
let graph = data.graph.read();
676-
for prev_index in graph.serialized_indices() {
677-
match graph.color(prev_index) {
682+
for prev_index in data.serialized.serialized_indices() {
683+
match data.serialized.color(prev_index) {
678684
Some(DepNodeColor::Green) => {
679-
let dep_node = data.graph.read().index_to_node(prev_index);
685+
let dep_node = data.serialized.index_to_node(prev_index);
680686
debug!("PROMOTE {:?} {:?}", prev_index, dep_node);
681687
qcx.try_load_from_on_disk_cache(&dep_node);
682688
}
@@ -692,11 +698,10 @@ impl<K: DepKind> DepGraph<K> {
692698
// Register reused dep nodes (i.e. nodes we've marked red or green) with the context.
693699
pub fn register_reused_dep_nodes<Ctxt: DepContext<DepKind = K>>(&self, tcx: Ctxt) {
694700
let data = self.data.as_ref().unwrap();
695-
let graph = data.graph.read();
696-
for prev_index in graph.serialized_indices() {
697-
match graph.color(prev_index) {
701+
for prev_index in data.serialized.serialized_indices() {
702+
match data.serialized.color(prev_index) {
698703
Some(_) => {
699-
let dep_node = data.graph.read().index_to_node(prev_index);
704+
let dep_node = data.serialized.index_to_node(prev_index);
700705
tcx.register_reused_dep_node(&dep_node);
701706
}
702707
None => {}
@@ -717,17 +722,17 @@ impl<K: DepKind> DepGraph<K> {
717722

718723
let mut stats: FxHashMap<_, Stat<K>> = FxHashMap::with_hasher(Default::default());
719724

720-
for index in prev.live_indices() {
721-
let kind = prev.dep_node_of(index).kind;
722-
let edge_count = prev.edge_targets_from(index).len();
725+
for index in prev.live_indices(&data.serialized) {
726+
let kind = prev.index_to_node(&data.serialized, index).kind;
727+
let edge_count = prev.edge_targets_from(&data.serialized, index).len();
723728

724729
let stat = stats.entry(kind).or_insert(Stat { kind, node_counter: 0, edge_counter: 0 });
725730
stat.node_counter += 1;
726731
stat.edge_counter += edge_count as u64;
727732
}
728733

729-
let total_node_count = prev.node_count();
730-
let total_edge_count = prev.edge_count();
734+
let total_node_count = prev.node_count(&data.serialized);
735+
let total_edge_count = prev.edge_count(&data.serialized);
731736

732737
// Drop the lock guard.
733738
std::mem::drop(prev);
@@ -792,14 +797,19 @@ impl<K: DepKind> DepGraph<K> {
792797
}
793798

794799
pub fn compression_map(&self) -> IndexVec<DepNodeIndex, Option<SerializedDepNodeIndex>> {
795-
self.data.as_ref().unwrap().graph.read().compression_map()
800+
let data = self.data.as_ref().unwrap();
801+
data.graph.read().compression_map(&data.serialized)
796802
}
797803

798804
pub fn encode<E: Encoder>(&self, encoder: &mut E) -> Result<(), E::Error>
799805
where
800806
K: Encodable<E>,
801807
{
802-
if let Some(data) = &self.data { data.graph.read().encode(encoder) } else { Ok(()) }
808+
if let Some(data) = &self.data {
809+
data.graph.read().encode(&data.serialized, encoder)
810+
} else {
811+
Ok(())
812+
}
803813
}
804814
}
805815

0 commit comments

Comments
 (0)