@@ -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 {
@@ -142,7 +148,7 @@ impl DepGraph {
142
148
data : Some ( Lrc :: new ( DepGraphData {
143
149
previous_work_products : args. prev_work_products ,
144
150
dep_node_debug : Default :: default ( ) ,
145
- current : CurrentDepGraph :: new ( prev_graph. clone ( ) , args. file ) ,
151
+ current : CurrentDepGraph :: new ( prev_graph. clone ( ) , args. file , args . invalidated ) ,
146
152
emitted_diagnostics : Default :: default ( ) ,
147
153
emitted_diagnostics_cond_var : Condvar :: new ( ) ,
148
154
colors,
@@ -552,11 +558,28 @@ impl DepGraph {
552
558
pub fn serialize ( & self ) -> IndexVec < DepNodeIndex , Fingerprint > {
553
559
let data = self . data . as_ref ( ) . unwrap ( ) ;
554
560
// Invalidate dep nodes with unknown state as these cannot safely
555
- // be marked green in the next session.
561
+ // be marked green in the next session. One of the dependencies of the
562
+ // unknown node may have changed in this session (and is currently marked red),
563
+ // but might be green again in the next session, which may cause the unknown node
564
+ // to incorrectly be marked green in the next session, even though one of its dependencies
565
+ // did actually change.
566
+
556
567
let invalidate = data. colors . values . indices ( ) . filter_map ( |prev_index| {
557
568
match data. colors . get ( prev_index) {
558
- DepNodeState :: Unknown => Some ( prev_index) ,
559
- _ => None ,
569
+ // In order to this invalidation to be safe, none of the valid nodes can
570
+ // point to unknown nodes.
571
+ DepNodeState :: Unknown |
572
+ DepNodeState :: UnknownEvalAlways => Some ( prev_index) ,
573
+
574
+ DepNodeState :: WasUnknownWillBeGreen => bug ! ( ) ,
575
+
576
+ // For green nodes, we either executed the query (which always uses valid nodes)
577
+ // or we marked it as green because all its dependencies are green and valid.
578
+ DepNodeState :: Green |
579
+ // Red nodes were always exexuted.
580
+ DepNodeState :: Red |
581
+ // We don't need to invalidate already invalid nodes
582
+ DepNodeState :: Invalid => None ,
560
583
}
561
584
} ) . collect ( ) ;
562
585
// FIXME: Can this deadlock?
@@ -607,8 +630,11 @@ impl DepGraph {
607
630
let prev_index = data. previous . node_to_index_opt ( dep_node) ?;
608
631
609
632
match data. colors . get ( prev_index) {
633
+ DepNodeState :: Invalid => bug ! ( ) ,
610
634
DepNodeState :: Green => Some ( prev_index) ,
611
- DepNodeState :: Invalid |
635
+ // We don't need to mark eval_always nodes as green here, since we'll just be executing
636
+ // the query after anyway.
637
+ DepNodeState :: UnknownEvalAlways |
612
638
DepNodeState :: Red => None ,
613
639
DepNodeState :: Unknown |
614
640
DepNodeState :: WasUnknownWillBeGreen => {
@@ -678,6 +704,7 @@ impl DepGraph {
678
704
false
679
705
}
680
706
DepNodeState :: Invalid |
707
+ DepNodeState :: UnknownEvalAlways |
681
708
DepNodeState :: Unknown |
682
709
DepNodeState :: WasUnknownWillBeGreen => {
683
710
bug ! ( "try_force_previous_green() - Forcing the DepNode \
@@ -721,6 +748,7 @@ impl DepGraph {
721
748
let dep_dep_node_color = data. colors . get ( dep_dep_node_index) ;
722
749
723
750
match dep_dep_node_color {
751
+ DepNodeState :: Invalid => bug ! ( ) ,
724
752
DepNodeState :: Green => {
725
753
// This dependency has been marked as green before, we are
726
754
// still fine and can continue with checking the other
@@ -741,9 +769,8 @@ impl DepGraph {
741
769
data. previous. index_to_node( dep_dep_node_index) ) ;
742
770
return false
743
771
}
744
- // Either the previous result is too old or
745
- // this is a eval_always node. Try to force the node
746
- DepNodeState :: Invalid => {
772
+ // This is a eval_always node. Try to force the node
773
+ DepNodeState :: UnknownEvalAlways => {
747
774
if !self . try_force_previous_green ( tcx, data, dep_dep_node_index) {
748
775
return false ;
749
776
}
@@ -886,8 +913,15 @@ impl DepGraph {
886
913
}
887
914
}
888
915
DepNodeState :: WasUnknownWillBeGreen => bug ! ( "no tasks should be in progress" ) ,
916
+
917
+ // There cannot be results stored for invalid indices.
889
918
DepNodeState :: Invalid |
919
+
920
+ // Unknown nodes are unused, so we don't want to promote these and we would
921
+ // not to mark their colors in order to do so anyway.
922
+ DepNodeState :: UnknownEvalAlways |
890
923
DepNodeState :: Unknown |
924
+
891
925
DepNodeState :: Red => {
892
926
// We can skip red nodes because a node can only be marked
893
927
// as red if the query result was recomputed and thus is
@@ -1004,7 +1038,11 @@ pub(super) struct CurrentDepGraph {
1004
1038
}
1005
1039
1006
1040
impl CurrentDepGraph {
1007
- fn new ( prev_graph : Lrc < PreviousDepGraph > , file : File ) -> CurrentDepGraph {
1041
+ fn new (
1042
+ prev_graph : Lrc < PreviousDepGraph > ,
1043
+ file : File ,
1044
+ invalidated : Vec < DepNodeIndex > ,
1045
+ ) -> CurrentDepGraph {
1008
1046
use std:: time:: { SystemTime , UNIX_EPOCH } ;
1009
1047
1010
1048
let duration = SystemTime :: now ( ) . duration_since ( UNIX_EPOCH ) . unwrap ( ) ;
@@ -1041,7 +1079,7 @@ impl CurrentDepGraph {
1041
1079
forbidden_edge,
1042
1080
total_read_count : AtomicU64 :: new ( 0 ) ,
1043
1081
total_duplicate_read_count : AtomicU64 :: new ( 0 ) ,
1044
- serializer : Lock :: new ( Serializer :: new ( file, prev_graph) ) ,
1082
+ serializer : Lock :: new ( Serializer :: new ( file, prev_graph, invalidated ) ) ,
1045
1083
}
1046
1084
}
1047
1085
0 commit comments