@@ -53,9 +53,13 @@ impl DepNodeColor {
53
53
54
54
#[ derive( Copy , Clone , Debug , PartialEq , Eq , Hash ) ]
55
55
pub enum DepNodeState {
56
- /// The node is invalid since its result is older than the previous session .
56
+ /// The dep node index is invalid and does not refer to any dep node .
57
57
Invalid ,
58
58
59
+ /// The node is from the previous session and it is a eval_always node,
60
+ // but its state is unknown.
61
+ UnknownEvalAlways ,
62
+
59
63
/// The node is from the previous session, but its state is unknown
60
64
Unknown ,
61
65
@@ -73,7 +77,8 @@ pub enum DepNodeState {
73
77
impl DepNodeState {
74
78
pub fn color ( self ) -> Option < DepNodeColor > {
75
79
match self {
76
- DepNodeState :: Invalid |
80
+ DepNodeState :: Invalid => bug ! ( ) ,
81
+ DepNodeState :: UnknownEvalAlways |
77
82
DepNodeState :: Unknown |
78
83
DepNodeState :: WasUnknownWillBeGreen => None ,
79
84
DepNodeState :: Red => Some ( DepNodeColor :: Red ) ,
@@ -128,6 +133,7 @@ pub struct DepGraphArgs {
128
133
pub prev_work_products : FxHashMap < WorkProductId , WorkProduct > ,
129
134
pub file : File ,
130
135
pub state : IndexVec < DepNodeIndex , AtomicCell < DepNodeState > > ,
136
+ pub invalidated : Vec < DepNodeIndex > ,
131
137
}
132
138
133
139
impl DepGraph {
@@ -141,7 +147,7 @@ impl DepGraph {
141
147
data : Some ( Lrc :: new ( DepGraphData {
142
148
previous_work_products : args. prev_work_products ,
143
149
dep_node_debug : Default :: default ( ) ,
144
- current : CurrentDepGraph :: new ( prev_graph. clone ( ) , args. file ) ,
150
+ current : CurrentDepGraph :: new ( prev_graph. clone ( ) , args. file , args . invalidated ) ,
145
151
emitted_diagnostics : Default :: default ( ) ,
146
152
emitted_diagnostics_cond_var : Condvar :: new ( ) ,
147
153
colors,
@@ -551,11 +557,28 @@ impl DepGraph {
551
557
pub fn serialize ( & self ) -> IndexVec < DepNodeIndex , Fingerprint > {
552
558
let data = self . data . as_ref ( ) . unwrap ( ) ;
553
559
// Invalidate dep nodes with unknown state as these cannot safely
554
- // be marked green in the next session.
560
+ // be marked green in the next session. One of the dependencies of the
561
+ // unknown node may have changed in this session (and is currently marked red),
562
+ // but might be green again in the next session, which may cause the unknown node
563
+ // to incorrectly be marked green in the next session, even though one of its dependencies
564
+ // did actually change.
565
+
555
566
let invalidate = data. colors . values . indices ( ) . filter_map ( |prev_index| {
556
567
match data. colors . get ( prev_index) {
557
- DepNodeState :: Unknown => Some ( prev_index) ,
558
- _ => None ,
568
+ // In order to this invalidation to be safe, none of the valid nodes can
569
+ // point to unknown nodes.
570
+ DepNodeState :: Unknown |
571
+ DepNodeState :: UnknownEvalAlways => Some ( prev_index) ,
572
+
573
+ DepNodeState :: WasUnknownWillBeGreen => bug ! ( ) ,
574
+
575
+ // For green nodes, we either executed the query (which always uses valid nodes)
576
+ // or we marked it as green because all its dependencies are green and valid.
577
+ DepNodeState :: Green |
578
+ // Red nodes were always exexuted.
579
+ DepNodeState :: Red |
580
+ // We don't need to invalidate already invalid nodes
581
+ DepNodeState :: Invalid => None ,
559
582
}
560
583
} ) . collect ( ) ;
561
584
// FIXME: Can this deadlock?
@@ -606,8 +629,11 @@ impl DepGraph {
606
629
let prev_index = data. previous . node_to_index_opt ( dep_node) ?;
607
630
608
631
match data. colors . get ( prev_index) {
632
+ DepNodeState :: Invalid => bug ! ( ) ,
609
633
DepNodeState :: Green => Some ( prev_index) ,
610
- DepNodeState :: Invalid |
634
+ // We don't need to mark eval_always nodes as green here, since we'll just be executing
635
+ // the query after anyway.
636
+ DepNodeState :: UnknownEvalAlways |
611
637
DepNodeState :: Red => None ,
612
638
DepNodeState :: Unknown |
613
639
DepNodeState :: WasUnknownWillBeGreen => {
@@ -677,6 +703,7 @@ impl DepGraph {
677
703
false
678
704
}
679
705
DepNodeState :: Invalid |
706
+ DepNodeState :: UnknownEvalAlways |
680
707
DepNodeState :: Unknown |
681
708
DepNodeState :: WasUnknownWillBeGreen => {
682
709
bug ! ( "try_force_previous_green() - Forcing the DepNode \
@@ -720,6 +747,7 @@ impl DepGraph {
720
747
let dep_dep_node_color = data. colors . get ( dep_dep_node_index) ;
721
748
722
749
match dep_dep_node_color {
750
+ DepNodeState :: Invalid => bug ! ( ) ,
723
751
DepNodeState :: Green => {
724
752
// This dependency has been marked as green before, we are
725
753
// still fine and can continue with checking the other
@@ -740,9 +768,8 @@ impl DepGraph {
740
768
data. previous. index_to_node( dep_dep_node_index) ) ;
741
769
return false
742
770
}
743
- // Either the previous result is too old or
744
- // this is a eval_always node. Try to force the node
745
- DepNodeState :: Invalid => {
771
+ // This is a eval_always node. Try to force the node
772
+ DepNodeState :: UnknownEvalAlways => {
746
773
if !self . try_force_previous_green ( tcx, data, dep_dep_node_index) {
747
774
return false ;
748
775
}
@@ -885,8 +912,15 @@ impl DepGraph {
885
912
}
886
913
}
887
914
DepNodeState :: WasUnknownWillBeGreen => bug ! ( "no tasks should be in progress" ) ,
915
+
916
+ // There cannot be results stored for invalid indices.
888
917
DepNodeState :: Invalid |
918
+
919
+ // Unknown nodes are unused, so we don't want to promote these and we would
920
+ // not to mark their colors in order to do so anyway.
921
+ DepNodeState :: UnknownEvalAlways |
889
922
DepNodeState :: Unknown |
923
+
890
924
DepNodeState :: Red => {
891
925
// We can skip red nodes because a node can only be marked
892
926
// as red if the query result was recomputed and thus is
@@ -1003,7 +1037,11 @@ pub(super) struct CurrentDepGraph {
1003
1037
}
1004
1038
1005
1039
impl CurrentDepGraph {
1006
- fn new ( prev_graph : Lrc < PreviousDepGraph > , file : File ) -> CurrentDepGraph {
1040
+ fn new (
1041
+ prev_graph : Lrc < PreviousDepGraph > ,
1042
+ file : File ,
1043
+ invalidated : Vec < DepNodeIndex > ,
1044
+ ) -> CurrentDepGraph {
1007
1045
use std:: time:: { SystemTime , UNIX_EPOCH } ;
1008
1046
1009
1047
let duration = SystemTime :: now ( ) . duration_since ( UNIX_EPOCH ) . unwrap ( ) ;
@@ -1040,7 +1078,7 @@ impl CurrentDepGraph {
1040
1078
forbidden_edge,
1041
1079
total_read_count : AtomicU64 :: new ( 0 ) ,
1042
1080
total_duplicate_read_count : AtomicU64 :: new ( 0 ) ,
1043
- serializer : Lock :: new ( Serializer :: new ( file, prev_graph) ) ,
1081
+ serializer : Lock :: new ( Serializer :: new ( file, prev_graph, invalidated ) ) ,
1044
1082
}
1045
1083
}
1046
1084
0 commit comments