@@ -776,17 +776,22 @@ impl<D: Deps> DepGraphData<D> {
776776 }
777777 }
778778
779- fn promote_node_and_deps_to_current ( & self , prev_index : SerializedDepNodeIndex ) -> DepNodeIndex {
779+ fn promote_node_and_deps_to_current (
780+ & self ,
781+ prev_index : SerializedDepNodeIndex ,
782+ ) -> Option < DepNodeIndex > {
780783 self . current . debug_assert_not_in_new_nodes ( & self . previous , prev_index) ;
781784
782785 let dep_node_index = self . current . encoder . send_promoted ( prev_index, & self . colors ) ;
783786
784787 #[ cfg( debug_assertions) ]
785- self . current . record_edge (
786- dep_node_index,
787- * self . previous . index_to_node ( prev_index) ,
788- self . previous . fingerprint_by_index ( prev_index) ,
789- ) ;
788+ if let Some ( dep_node_index) = dep_node_index {
789+ self . current . record_edge (
790+ dep_node_index,
791+ * self . previous . index_to_node ( prev_index) ,
792+ self . previous . fingerprint_by_index ( prev_index) ,
793+ ) ;
794+ }
790795
791796 dep_node_index
792797 }
@@ -1006,8 +1011,10 @@ impl<D: Deps> DepGraphData<D> {
10061011 // There may be multiple threads trying to mark the same dep node green concurrently
10071012
10081013 // We allocating an entry for the node in the current dependency graph and
1009- // adding all the appropriate edges imported from the previous graph
1010- let dep_node_index = self . promote_node_and_deps_to_current ( prev_dep_node_index) ;
1014+ // adding all the appropriate edges imported from the previous graph.
1015+ //
1016+ // `no_hash` nodes may fail this promotion due to already being conservatively colored red.
1017+ let dep_node_index = self . promote_node_and_deps_to_current ( prev_dep_node_index) ?;
10111018
10121019 // ... and finally storing a "Green" entry in the color map.
10131020 // Multiple threads can all write the same color here
@@ -1377,26 +1384,27 @@ impl DepNodeColorMap {
13771384 }
13781385
13791386 /// This tries to atomically mark a node green and assign `index` as the new
1380- /// index. This returns `Ok` if `index` gets assigned, otherwise it returns
1381- /// the already allocated index in `Err`.
1382- #[ inline]
1383- pub ( super ) fn try_mark_green (
1387+ /// index if `green` is true, otherwise it will try to atomicaly mark it red.
1388+ ///
1389+ /// This returns `Ok` if `index` gets assigned or the node is marked red, otherwise it returns
1390+ /// the already allocated index in `Err` if it is green already. If it was already
1391+ /// red, `Err(None)` is returned.
1392+ #[ inline( always) ]
1393+ pub ( super ) fn try_mark (
13841394 & self ,
13851395 prev_index : SerializedDepNodeIndex ,
13861396 index : DepNodeIndex ,
1387- ) -> Result < ( ) , DepNodeIndex > {
1397+ green : bool ,
1398+ ) -> Result < ( ) , Option < DepNodeIndex > > {
13881399 let value = & self . values [ prev_index] ;
13891400 match value. compare_exchange (
13901401 COMPRESSED_UNKNOWN ,
1391- index. as_u32 ( ) ,
1402+ if green { index. as_u32 ( ) } else { COMPRESSED_RED } ,
13921403 Ordering :: Relaxed ,
13931404 Ordering :: Relaxed ,
13941405 ) {
13951406 Ok ( _) => Ok ( ( ) ) ,
1396- Err ( v) => Err ( {
1397- assert_ne ! ( v, COMPRESSED_RED , "tried to mark a red node as green" ) ;
1398- DepNodeIndex :: from_u32 ( v)
1399- } ) ,
1407+ Err ( v) => Err ( if v == COMPRESSED_RED { None } else { Some ( DepNodeIndex :: from_u32 ( v) ) } ) ,
14001408 }
14011409 }
14021410
@@ -1419,7 +1427,7 @@ impl DepNodeColorMap {
14191427 pub ( super ) fn insert_red ( & self , index : SerializedDepNodeIndex ) {
14201428 let value = self . values [ index] . swap ( COMPRESSED_RED , Ordering :: Release ) ;
14211429 // Sanity check for duplicate nodes
1422- assert_eq ! ( value, COMPRESSED_UNKNOWN , "trying to encode a dep node twice " ) ;
1430+ assert_eq ! ( value, COMPRESSED_UNKNOWN , "tried to color an already colored node as red " ) ;
14231431 }
14241432}
14251433
0 commit comments