@@ -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) ]
0 commit comments