@@ -11,7 +11,7 @@ use rustc_data_structures::outline;
11
11
use rustc_data_structures:: profiling:: QueryInvocationId ;
12
12
use rustc_data_structures:: sharded:: { self , ShardedHashMap } ;
13
13
use rustc_data_structures:: stable_hasher:: { HashStable , StableHasher } ;
14
- use rustc_data_structures:: sync:: { AtomicU64 , Lock , is_dyn_thread_safe } ;
14
+ use rustc_data_structures:: sync:: { AtomicU64 , Lock } ;
15
15
use rustc_data_structures:: unord:: UnordMap ;
16
16
use rustc_errors:: DiagInner ;
17
17
use rustc_index:: IndexVec ;
@@ -68,18 +68,9 @@ pub struct MarkFrame<'a> {
68
68
69
69
#[ derive( Debug ) ]
70
70
pub ( super ) enum DepNodeColor {
71
- Red ,
72
71
Green ( DepNodeIndex ) ,
73
- }
74
-
75
- impl DepNodeColor {
76
- #[ inline]
77
- fn is_green ( self ) -> bool {
78
- match self {
79
- DepNodeColor :: Red => false ,
80
- DepNodeColor :: Green ( _) => true ,
81
- }
82
- }
72
+ Red ,
73
+ Unknown ,
83
74
}
84
75
85
76
pub ( crate ) struct DepGraphData < D : Deps > {
@@ -148,10 +139,9 @@ impl<D: Deps> DepGraph<D> {
148
139
) ;
149
140
assert_eq ! ( red_node_index, DepNodeIndex :: FOREVER_RED_NODE ) ;
150
141
if prev_graph_node_count > 0 {
151
- colors. insert (
152
- SerializedDepNodeIndex :: from_u32 ( DepNodeIndex :: FOREVER_RED_NODE . as_u32 ( ) ) ,
153
- DepNodeColor :: Red ,
154
- ) ;
142
+ colors. insert_red ( SerializedDepNodeIndex :: from_u32 (
143
+ DepNodeIndex :: FOREVER_RED_NODE . as_u32 ( ) ,
144
+ ) ) ;
155
145
}
156
146
157
147
DepGraph {
@@ -625,7 +615,7 @@ impl<D: Deps> DepGraphData<D> {
625
615
) {
626
616
if let Some ( prev_index) = self . previous . node_to_index_opt ( dep_node) {
627
617
let current = self . colors . get ( prev_index) ;
628
- assert ! ( current. is_none ( ) , "{}" , msg( ) )
618
+ assert_matches ! ( current, DepNodeColor :: Unknown , "{}" , msg( ) )
629
619
} else if let Some ( nodes_in_current_session) = & self . current . nodes_in_current_session {
630
620
outline ( || {
631
621
let seen = nodes_in_current_session. lock ( ) . contains_key ( dep_node) ;
@@ -634,20 +624,20 @@ impl<D: Deps> DepGraphData<D> {
634
624
}
635
625
}
636
626
637
- fn node_color ( & self , dep_node : & DepNode ) -> Option < DepNodeColor > {
627
+ fn node_color ( & self , dep_node : & DepNode ) -> DepNodeColor {
638
628
if let Some ( prev_index) = self . previous . node_to_index_opt ( dep_node) {
639
629
self . colors . get ( prev_index)
640
630
} else {
641
631
// This is a node that did not exist in the previous compilation session.
642
- None
632
+ DepNodeColor :: Unknown
643
633
}
644
634
}
645
635
646
636
/// Returns true if the given node has been marked as green during the
647
637
/// current compilation session. Used in various assertions
648
638
#[ inline]
649
639
pub ( crate ) fn is_index_green ( & self , prev_index : SerializedDepNodeIndex ) -> bool {
650
- self . colors . get ( prev_index) . is_some_and ( |c| c . is_green ( ) )
640
+ matches ! ( self . colors. get( prev_index) , DepNodeColor :: Green ( _ ) )
651
641
}
652
642
653
643
#[ inline]
@@ -821,12 +811,12 @@ impl<D: Deps> DepGraph<D> {
821
811
self . data . as_ref ( ) ?. dep_node_debug . borrow ( ) . get ( & dep_node) . cloned ( )
822
812
}
823
813
824
- fn node_color ( & self , dep_node : & DepNode ) -> Option < DepNodeColor > {
814
+ fn node_color ( & self , dep_node : & DepNode ) -> DepNodeColor {
825
815
if let Some ( ref data) = self . data {
826
816
return data. node_color ( dep_node) ;
827
817
}
828
818
829
- None
819
+ DepNodeColor :: Unknown
830
820
}
831
821
832
822
pub fn try_mark_green < Qcx : QueryContext < Deps = D > > (
@@ -855,9 +845,9 @@ impl<D: Deps> DepGraphData<D> {
855
845
let prev_index = self . previous . node_to_index_opt ( dep_node) ?;
856
846
857
847
match self . colors . get ( prev_index) {
858
- Some ( DepNodeColor :: Green ( dep_node_index) ) => Some ( ( prev_index, dep_node_index) ) ,
859
- Some ( DepNodeColor :: Red ) => None ,
860
- None => {
848
+ DepNodeColor :: Green ( dep_node_index) => Some ( ( prev_index, dep_node_index) ) ,
849
+ DepNodeColor :: Red => None ,
850
+ DepNodeColor :: Unknown => {
861
851
// This DepNode and the corresponding query invocation existed
862
852
// in the previous compilation session too, so we can try to
863
853
// mark it as green by recursively marking all of its
@@ -873,12 +863,12 @@ impl<D: Deps> DepGraphData<D> {
873
863
& self ,
874
864
qcx : Qcx ,
875
865
parent_dep_node_index : SerializedDepNodeIndex ,
876
- frame : Option < & MarkFrame < ' _ > > ,
866
+ frame : & MarkFrame < ' _ > ,
877
867
) -> Option < ( ) > {
878
868
let get_dep_dep_node = || self . previous . index_to_node ( parent_dep_node_index) ;
879
869
880
870
match self . colors . get ( parent_dep_node_index) {
881
- Some ( DepNodeColor :: Green ( _) ) => {
871
+ DepNodeColor :: Green ( _) => {
882
872
// This dependency has been marked as green before, we are
883
873
// still fine and can continue with checking the other
884
874
// dependencies.
@@ -889,15 +879,15 @@ impl<D: Deps> DepGraphData<D> {
889
879
debug ! ( "dependency {:?} was immediately green" , get_dep_dep_node( ) ) ;
890
880
return Some ( ( ) ) ;
891
881
}
892
- Some ( DepNodeColor :: Red ) => {
882
+ DepNodeColor :: Red => {
893
883
// We found a dependency the value of which has changed
894
884
// compared to the previous compilation session. We cannot
895
885
// mark the DepNode as green and also don't need to bother
896
886
// with checking any of the other dependencies.
897
887
debug ! ( "dependency {:?} was immediately red" , get_dep_dep_node( ) ) ;
898
888
return None ;
899
889
}
900
- None => { }
890
+ DepNodeColor :: Unknown => { }
901
891
}
902
892
903
893
let dep_dep_node = & get_dep_dep_node ( ) ;
@@ -911,7 +901,7 @@ impl<D: Deps> DepGraphData<D> {
911
901
) ;
912
902
913
903
let node_index =
914
- self . try_mark_previous_green ( qcx, parent_dep_node_index, dep_dep_node, frame) ;
904
+ self . try_mark_previous_green ( qcx, parent_dep_node_index, dep_dep_node, Some ( frame) ) ;
915
905
916
906
if node_index. is_some ( ) {
917
907
debug ! ( "managed to MARK dependency {dep_dep_node:?} as green" ) ;
@@ -928,15 +918,15 @@ impl<D: Deps> DepGraphData<D> {
928
918
}
929
919
930
920
match self . colors . get ( parent_dep_node_index) {
931
- Some ( DepNodeColor :: Green ( _) ) => {
921
+ DepNodeColor :: Green ( _) => {
932
922
debug ! ( "managed to FORCE dependency {dep_dep_node:?} to green" ) ;
933
923
return Some ( ( ) ) ;
934
924
}
935
- Some ( DepNodeColor :: Red ) => {
925
+ DepNodeColor :: Red => {
936
926
debug ! ( "dependency {dep_dep_node:?} was red after forcing" ) ;
937
927
return None ;
938
928
}
939
- None => { }
929
+ DepNodeColor :: Unknown => { }
940
930
}
941
931
942
932
if let None = qcx. dep_context ( ) . sess ( ) . dcx ( ) . has_errors_or_delayed_bugs ( ) {
@@ -976,7 +966,7 @@ impl<D: Deps> DepGraphData<D> {
976
966
let prev_deps = self . previous . edge_targets_from ( prev_dep_node_index) ;
977
967
978
968
for dep_dep_node_index in prev_deps {
979
- self . try_mark_parent_green ( qcx, dep_dep_node_index, Some ( & frame) ) ?;
969
+ self . try_mark_parent_green ( qcx, dep_dep_node_index, & frame) ?;
980
970
}
981
971
982
972
// If we got here without hitting a `return` that means that all
@@ -1001,13 +991,13 @@ impl<D: Deps> DepGraph<D> {
1001
991
/// Returns true if the given node has been marked as red during the
1002
992
/// current compilation session. Used in various assertions
1003
993
pub fn is_red ( & self , dep_node : & DepNode ) -> bool {
1004
- matches ! ( self . node_color( dep_node) , Some ( DepNodeColor :: Red ) )
994
+ matches ! ( self . node_color( dep_node) , DepNodeColor :: Red )
1005
995
}
1006
996
1007
997
/// Returns true if the given node has been marked as green during the
1008
998
/// current compilation session. Used in various assertions
1009
999
pub fn is_green ( & self , dep_node : & DepNode ) -> bool {
1010
- self . node_color ( dep_node) . is_some_and ( |c| c . is_green ( ) )
1000
+ matches ! ( self . node_color( dep_node) , DepNodeColor :: Green ( _ ) )
1011
1001
}
1012
1002
1013
1003
pub fn assert_dep_node_not_yet_allocated_in_current_session < S : std:: fmt:: Display > (
@@ -1034,11 +1024,11 @@ impl<D: Deps> DepGraph<D> {
1034
1024
let data = self . data . as_ref ( ) . unwrap ( ) ;
1035
1025
for prev_index in data. colors . values . indices ( ) {
1036
1026
match data. colors . get ( prev_index) {
1037
- Some ( DepNodeColor :: Green ( _) ) => {
1027
+ DepNodeColor :: Green ( _) => {
1038
1028
let dep_node = data. previous . index_to_node ( prev_index) ;
1039
1029
tcx. try_load_from_on_disk_cache ( dep_node) ;
1040
1030
}
1041
- None | Some ( DepNodeColor :: Red ) => {
1031
+ DepNodeColor :: Unknown | DepNodeColor :: Red => {
1042
1032
// We can skip red nodes because a node can only be marked
1043
1033
// as red if the query result was recomputed and thus is
1044
1034
// already in memory.
@@ -1318,23 +1308,21 @@ impl Default for TaskDeps {
1318
1308
}
1319
1309
}
1320
1310
}
1311
+
1321
1312
// A data structure that stores Option<DepNodeColor> values as a contiguous
1322
1313
// array, using one u32 per entry.
1323
1314
pub ( super ) struct DepNodeColorMap {
1324
1315
values : IndexVec < SerializedDepNodeIndex , AtomicU32 > ,
1325
- sync : bool ,
1326
1316
}
1327
1317
1328
- const COMPRESSED_NONE : u32 = u32 :: MAX ;
1318
+ // All values below `COMPRESSED_RED` are green.
1329
1319
const COMPRESSED_RED : u32 = u32:: MAX - 1 ;
1320
+ const COMPRESSED_UNKNOWN : u32 = u32:: MAX ;
1330
1321
1331
1322
impl DepNodeColorMap {
1332
1323
fn new ( size : usize ) -> DepNodeColorMap {
1333
1324
debug_assert ! ( COMPRESSED_RED > DepNodeIndex :: MAX_AS_U32 ) ;
1334
- DepNodeColorMap {
1335
- values : ( 0 ..size) . map ( |_| AtomicU32 :: new ( COMPRESSED_NONE ) ) . collect ( ) ,
1336
- sync : is_dyn_thread_safe ( ) ,
1337
- }
1325
+ DepNodeColorMap { values : ( 0 ..size) . map ( |_| AtomicU32 :: new ( COMPRESSED_UNKNOWN ) ) . collect ( ) }
1338
1326
}
1339
1327
1340
1328
#[ inline]
@@ -1353,58 +1341,48 @@ impl DepNodeColorMap {
1353
1341
index : DepNodeIndex ,
1354
1342
) -> Result < ( ) , DepNodeIndex > {
1355
1343
let value = & self . values [ prev_index] ;
1356
- if self . sync {
1357
- match value. compare_exchange (
1358
- COMPRESSED_NONE ,
1359
- index. as_u32 ( ) ,
1360
- Ordering :: Relaxed ,
1361
- Ordering :: Relaxed ,
1362
- ) {
1363
- Ok ( _) => Ok ( ( ) ) ,
1364
- Err ( v) => Err ( DepNodeIndex :: from_u32 ( v) ) ,
1365
- }
1366
- } else {
1367
- let v = value. load ( Ordering :: Relaxed ) ;
1368
- if v == COMPRESSED_NONE {
1369
- value. store ( index. as_u32 ( ) , Ordering :: Relaxed ) ;
1370
- Ok ( ( ) )
1371
- } else {
1372
- Err ( DepNodeIndex :: from_u32 ( v) )
1373
- }
1344
+ match value. compare_exchange (
1345
+ COMPRESSED_UNKNOWN ,
1346
+ index. as_u32 ( ) ,
1347
+ Ordering :: Relaxed ,
1348
+ Ordering :: Relaxed ,
1349
+ ) {
1350
+ Ok ( _) => Ok ( ( ) ) ,
1351
+ Err ( v) => Err ( DepNodeIndex :: from_u32 ( v) ) ,
1374
1352
}
1375
1353
}
1376
1354
1377
1355
#[ inline]
1378
- pub ( super ) fn get ( & self , index : SerializedDepNodeIndex ) -> Option < DepNodeColor > {
1379
- match self . values [ index] . load ( Ordering :: Acquire ) {
1380
- COMPRESSED_NONE => None ,
1381
- COMPRESSED_RED => Some ( DepNodeColor :: Red ) ,
1382
- value => Some ( DepNodeColor :: Green ( DepNodeIndex :: from_u32 ( value) ) ) ,
1356
+ pub ( super ) fn get ( & self , index : SerializedDepNodeIndex ) -> DepNodeColor {
1357
+ let value = self . values [ index] . load ( Ordering :: Acquire ) ;
1358
+ // Green is by far the most common case. Check for that first so we can succeed with a
1359
+ // single comparison.
1360
+ if value < COMPRESSED_RED {
1361
+ DepNodeColor :: Green ( DepNodeIndex :: from_u32 ( value) )
1362
+ } else if value == COMPRESSED_RED {
1363
+ DepNodeColor :: Red
1364
+ } else {
1365
+ debug_assert_eq ! ( value, COMPRESSED_UNKNOWN ) ;
1366
+ DepNodeColor :: Unknown
1383
1367
}
1384
1368
}
1385
1369
1386
1370
#[ inline]
1387
- pub ( super ) fn insert ( & self , index : SerializedDepNodeIndex , color : DepNodeColor ) {
1388
- self . values [ index] . store (
1389
- match color {
1390
- DepNodeColor :: Red => COMPRESSED_RED ,
1391
- DepNodeColor :: Green ( index) => index. as_u32 ( ) ,
1392
- } ,
1393
- Ordering :: Release ,
1394
- )
1371
+ pub ( super ) fn insert_red ( & self , index : SerializedDepNodeIndex ) {
1372
+ self . values [ index] . store ( COMPRESSED_RED , Ordering :: Release )
1395
1373
}
1396
1374
}
1397
1375
1398
1376
#[ inline( never) ]
1399
1377
#[ cold]
1400
- pub ( crate ) fn print_markframe_trace < D : Deps > ( graph : & DepGraph < D > , frame : Option < & MarkFrame < ' _ > > ) {
1378
+ pub ( crate ) fn print_markframe_trace < D : Deps > ( graph : & DepGraph < D > , frame : & MarkFrame < ' _ > ) {
1401
1379
let data = graph. data . as_ref ( ) . unwrap ( ) ;
1402
1380
1403
1381
eprintln ! ( "there was a panic while trying to force a dep node" ) ;
1404
1382
eprintln ! ( "try_mark_green dep node stack:" ) ;
1405
1383
1406
1384
let mut i = 0 ;
1407
- let mut current = frame;
1385
+ let mut current = Some ( frame) ;
1408
1386
while let Some ( frame) = current {
1409
1387
let node = data. previous . index_to_node ( frame. index ) ;
1410
1388
eprintln ! ( "#{i} {node:?}" ) ;
0 commit comments