Skip to content

Commit baffc5e

Browse files
Rollup merge of #154201 - Zalathar:try-set-color, r=nnethercote
Use enums to clarify `DepNodeColorMap` color marking When a function's documentation has to explain the meaning of nested results and options, then it is often a good candidate for using a custom result enum instead. This PR also renames `DepNodeColorMap::try_mark` to `try_set_color`, to make it more distinct from the similarly-named `DepGraph::try_mark_green`. The difference is that `try_mark_green` is a higher-level operation that tries to determine whether a node _can_ be marked green, whereas `try_set_color` is a lower-level operation that actually records a colour for the node. The updated docs for `try_set_color` also fix a typo: *atomicaly* → *atomically*. r? nnethercote (or compiler)
2 parents 20612ce + 1fec51c commit baffc5e

3 files changed

Lines changed: 55 additions & 34 deletions

File tree

compiler/rustc_middle/src/dep_graph/graph.rs

Lines changed: 40 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -164,9 +164,10 @@ impl DepGraph {
164164
);
165165
assert_eq!(red_node_index, DepNodeIndex::FOREVER_RED_NODE);
166166
if prev_graph_node_count > 0 {
167-
colors.insert_red(SerializedDepNodeIndex::from_u32(
168-
DepNodeIndex::FOREVER_RED_NODE.as_u32(),
169-
));
167+
let prev_index =
168+
const { SerializedDepNodeIndex::from_u32(DepNodeIndex::FOREVER_RED_NODE.as_u32()) };
169+
let result = colors.try_set_color(prev_index, DesiredColor::Red);
170+
assert_matches!(result, TrySetColorResult::Success);
170171
}
171172

172173
DepGraph {
@@ -1415,28 +1416,29 @@ impl DepNodeColorMap {
14151416
if value <= DepNodeIndex::MAX_AS_U32 { Some(DepNodeIndex::from_u32(value)) } else { None }
14161417
}
14171418

1418-
/// This tries to atomically mark a node green and assign `index` as the new
1419-
/// index if `green` is true, otherwise it will try to atomicaly mark it red.
1419+
/// Atomically sets the color of a previous-session dep node to either green
1420+
/// or red, if it has not already been colored.
14201421
///
1421-
/// This returns `Ok` if `index` gets assigned or the node is marked red, otherwise it returns
1422-
/// the already allocated index in `Err` if it is green already. If it was already
1423-
/// red, `Err(None)` is returned.
1422+
/// If the node already has a color, the new color is ignored, and the
1423+
/// return value indicates the existing color.
14241424
#[inline(always)]
1425-
pub(super) fn try_mark(
1425+
pub(super) fn try_set_color(
14261426
&self,
14271427
prev_index: SerializedDepNodeIndex,
1428-
index: DepNodeIndex,
1429-
green: bool,
1430-
) -> Result<(), Option<DepNodeIndex>> {
1431-
let value = &self.values[prev_index];
1432-
match value.compare_exchange(
1428+
color: DesiredColor,
1429+
) -> TrySetColorResult {
1430+
match self.values[prev_index].compare_exchange(
14331431
COMPRESSED_UNKNOWN,
1434-
if green { index.as_u32() } else { COMPRESSED_RED },
1432+
match color {
1433+
DesiredColor::Red => COMPRESSED_RED,
1434+
DesiredColor::Green { index } => index.as_u32(),
1435+
},
14351436
Ordering::Relaxed,
14361437
Ordering::Relaxed,
14371438
) {
1438-
Ok(_) => Ok(()),
1439-
Err(v) => Err(if v == COMPRESSED_RED { None } else { Some(DepNodeIndex::from_u32(v)) }),
1439+
Ok(_) => TrySetColorResult::Success,
1440+
Err(COMPRESSED_RED) => TrySetColorResult::AlreadyRed,
1441+
Err(index) => TrySetColorResult::AlreadyGreen { index: DepNodeIndex::from_u32(index) },
14401442
}
14411443
}
14421444

@@ -1454,13 +1456,28 @@ impl DepNodeColorMap {
14541456
DepNodeColor::Unknown
14551457
}
14561458
}
1459+
}
14571460

1458-
#[inline]
1459-
pub(super) fn insert_red(&self, index: SerializedDepNodeIndex) {
1460-
let value = self.values[index].swap(COMPRESSED_RED, Ordering::Release);
1461-
// Sanity check for duplicate nodes
1462-
assert_eq!(value, COMPRESSED_UNKNOWN, "tried to color an already colored node as red");
1463-
}
1461+
/// The color that [`DepNodeColorMap::try_set_color`] should try to apply to a node.
1462+
#[derive(Clone, Copy, Debug)]
1463+
pub(super) enum DesiredColor {
1464+
/// Try to mark the node red.
1465+
Red,
1466+
/// Try to mark the node green, associating it with a current-session node index.
1467+
Green { index: DepNodeIndex },
1468+
}
1469+
1470+
/// Return value of [`DepNodeColorMap::try_set_color`], indicating success or failure,
1471+
/// and (on failure) what the existing color is.
1472+
#[derive(Clone, Copy, Debug)]
1473+
pub(super) enum TrySetColorResult {
1474+
/// The [`DesiredColor`] was freshly applied to the node.
1475+
Success,
1476+
/// Coloring failed because the node was already marked red.
1477+
AlreadyRed,
1478+
/// Coloring failed because the node was already marked green,
1479+
/// and corresponds to node `index` in the current-session dep graph.
1480+
AlreadyGreen { index: DepNodeIndex },
14641481
}
14651482

14661483
#[inline(never)]

compiler/rustc_middle/src/dep_graph/serialized.rs

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ use rustc_serialize::{Decodable, Decoder, Encodable, Encoder};
5858
use rustc_session::Session;
5959
use tracing::{debug, instrument};
6060

61-
use super::graph::{CurrentDepGraph, DepNodeColorMap};
61+
use super::graph::{CurrentDepGraph, DepNodeColorMap, DesiredColor, TrySetColorResult};
6262
use super::retained::RetainedDepGraph;
6363
use super::{DepKind, DepNode, DepNodeIndex};
6464
use crate::dep_graph::edges::EdgesVec;
@@ -905,13 +905,14 @@ impl GraphEncoder {
905905
let mut local = self.status.local.borrow_mut();
906906

907907
let index = self.status.next_index(&mut *local);
908+
let color = if is_green { DesiredColor::Green { index } } else { DesiredColor::Red };
908909

909-
// Use `try_mark` to avoid racing when `send_promoted` is called concurrently
910+
// Use `try_set_color` to avoid racing when `send_promoted` is called concurrently
910911
// on the same index.
911-
match colors.try_mark(prev_index, index, is_green) {
912-
Ok(()) => (),
913-
Err(None) => panic!("dep node {:?} is unexpectedly red", prev_index),
914-
Err(Some(dep_node_index)) => return dep_node_index,
912+
match colors.try_set_color(prev_index, color) {
913+
TrySetColorResult::Success => {}
914+
TrySetColorResult::AlreadyRed => panic!("dep node {prev_index:?} is unexpectedly red"),
915+
TrySetColorResult::AlreadyGreen { index } => return index,
915916
}
916917

917918
self.status.bump_index(&mut *local);
@@ -923,7 +924,8 @@ impl GraphEncoder {
923924
/// from the previous dep graph and expects all edges to already have a new dep node index
924925
/// assigned.
925926
///
926-
/// This will also ensure the dep node is marked green if `Some` is returned.
927+
/// Tries to mark the dep node green, and returns Some if it is now green,
928+
/// or None if had already been concurrently marked red.
927929
#[inline]
928930
pub(crate) fn send_promoted(
929931
&self,
@@ -935,10 +937,10 @@ impl GraphEncoder {
935937
let mut local = self.status.local.borrow_mut();
936938
let index = self.status.next_index(&mut *local);
937939

938-
// Use `try_mark_green` to avoid racing when `send_promoted` or `send_and_color`
940+
// Use `try_set_color` to avoid racing when `send_promoted` or `send_and_color`
939941
// is called concurrently on the same index.
940-
match colors.try_mark(prev_index, index, true) {
941-
Ok(()) => {
942+
match colors.try_set_color(prev_index, DesiredColor::Green { index }) {
943+
TrySetColorResult::Success => {
942944
self.status.bump_index(&mut *local);
943945
self.status.encode_promoted_node(
944946
index,
@@ -949,7 +951,8 @@ impl GraphEncoder {
949951
);
950952
Some(index)
951953
}
952-
Err(dep_node_index) => dep_node_index,
954+
TrySetColorResult::AlreadyRed => None,
955+
TrySetColorResult::AlreadyGreen { index } => Some(index),
953956
}
954957
}
955958

typos.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ unstalled = "unstalled" # short for un-stalled
4848
# the non-empty form can be automatically fixed by `--bless`.
4949
#
5050
# tidy-alphabetical-start
51+
atomicaly = "atomically"
5152
definitinon = "definition"
5253
dependy = ""
5354
similarlty = "similarity"

0 commit comments

Comments
 (0)