1
1
use rustc_data_structures:: sync:: worker:: { Worker , WorkerExecutor } ;
2
- use rustc_data_structures:: sync:: Lrc ;
2
+ use rustc_data_structures:: sync:: { Lrc , AtomicCell } ;
3
3
use rustc_data_structures:: { unlikely, cold_path} ;
4
- use rustc_data_structures:: indexed_vec:: { IndexVec , Idx } ;
5
- use rustc_serialize :: opaque ;
6
- use rustc_serialize:: { Decodable , Encodable } ;
4
+ use rustc_data_structures:: indexed_vec:: { Idx , IndexVec } ;
5
+ use rustc_data_structures :: fingerprint :: Fingerprint ;
6
+ use rustc_serialize:: { Decodable , Encodable , opaque } ;
7
7
use std:: mem;
8
8
use std:: fs:: File ;
9
9
use std:: io:: Write ;
10
+ use crate :: dep_graph:: dep_node:: DepNode ;
11
+ use super :: prev:: PreviousDepGraph ;
10
12
use super :: graph:: { DepNodeData , DepNodeIndex , DepNodeState } ;
11
13
12
- newtype_index ! {
13
- pub struct SerializedDepNodeIndex { .. }
14
- }
15
-
16
- impl SerializedDepNodeIndex {
17
- pub fn current ( self ) -> DepNodeIndex {
18
- DepNodeIndex :: from_u32 ( self . as_u32 ( ) )
19
- }
20
- }
21
-
22
14
#[ derive( Debug , Default ) ]
23
15
pub struct SerializedDepGraph {
24
- pub ( super ) nodes : IndexVec < DepNodeIndex , DepNodeData > ,
25
- pub ( super ) state : IndexVec < DepNodeIndex , DepNodeState > ,
16
+ pub ( super ) nodes : IndexVec < DepNodeIndex , SerializedDepNodeData > ,
17
+ pub ( super ) fingerprints : IndexVec < DepNodeIndex , Fingerprint > ,
18
+ }
19
+
20
+ #[ derive( Clone , Debug , RustcDecodable , RustcEncodable ) ]
21
+ pub ( super ) struct SerializedDepNodeData {
22
+ pub ( super ) node : DepNode ,
23
+ pub ( super ) edges : Vec < DepNodeIndex > ,
26
24
}
27
25
28
26
impl SerializedDepGraph {
29
- pub fn decode ( d : & mut opaque:: Decoder < ' _ > ) -> Result < Self , String > {
30
- let mut nodes = IndexVec :: new ( ) ;
31
- let mut invalidated_list = Vec :: new ( ) ;
27
+ pub fn decode (
28
+ d : & mut opaque:: Decoder < ' _ > ,
29
+ results_d : & mut opaque:: Decoder < ' _ > ,
30
+ ) -> Result < ( Self , IndexVec < DepNodeIndex , AtomicCell < DepNodeState > > ) , String > {
31
+ let fingerprints: IndexVec < DepNodeIndex , Fingerprint > = IndexVec :: decode ( results_d) ?;
32
+ let mut nodes = IndexVec :: with_capacity ( fingerprints. len ( ) ) ;
33
+ let mut state: IndexVec < _ , _ > = ( 0 ..fingerprints. len ( ) ) . map ( |_| {
34
+ AtomicCell :: new ( DepNodeState :: Unknown )
35
+ } ) . collect ( ) ;
32
36
loop {
33
37
if d. position ( ) == d. data . len ( ) {
34
38
break ;
35
39
}
36
- match Action :: decode ( d) ? {
37
- Action :: NewNodes ( new_nodes) => {
40
+ match SerializedAction :: decode ( d) ? {
41
+ SerializedAction :: NewNodes ( new_nodes) => {
42
+ for ( i, data) in new_nodes. iter ( ) . enumerate ( ) {
43
+ // Mark the result of eval_always nodes as invalid so they will
44
+ // get executed again.
45
+ if unlikely ! ( data. node. kind. is_eval_always( ) ) {
46
+ let idx = DepNodeIndex :: new ( nodes. len ( ) + i) ;
47
+ state[ idx] = AtomicCell :: new ( DepNodeState :: Invalid ) ;
48
+ }
49
+ }
38
50
nodes. extend ( new_nodes) ;
39
51
}
40
- Action :: UpdateNodes ( changed) => {
41
- for ( i, data) in changed {
42
- nodes[ i] = data;
52
+ SerializedAction :: UpdateEdges ( changed) => {
53
+ for ( i, edges) in changed {
54
+ // Updated results are valid again, except for eval_always nodes
55
+ // which always start out invalid.
56
+ if likely ! ( !nodes[ i] . node. kind. is_eval_always( ) ) {
57
+ state[ i] = AtomicCell :: new ( DepNodeState :: Unknown ) ;
58
+ }
59
+ nodes[ i] . edges = edges;
43
60
}
44
61
}
45
- Action :: InvalidateNodes ( nodes) => {
46
- invalidated_list. extend ( nodes) ;
62
+ SerializedAction :: InvalidateNodes ( nodes) => {
63
+ for i in nodes {
64
+ state[ i] = AtomicCell :: new ( DepNodeState :: Invalid ) ;
65
+ }
47
66
}
48
67
}
49
68
}
50
- let mut state: IndexVec < _ , _ > = ( 0 ..nodes. len ( ) ) . map ( |_| {
51
- DepNodeState :: Unknown
52
- } ) . collect ( ) ;
53
- for i in invalidated_list {
54
- state[ i] = DepNodeState :: Invalidated ;
55
- }
56
- Ok ( SerializedDepGraph {
69
+ Ok ( ( SerializedDepGraph {
57
70
nodes,
58
- state ,
59
- } )
71
+ fingerprints ,
72
+ } , state ) )
60
73
}
61
74
}
62
75
63
- #[ derive( Debug , RustcEncodable , RustcDecodable ) ]
76
+ #[ derive( Debug , RustcDecodable , RustcEncodable ) ]
77
+ enum SerializedAction {
78
+ NewNodes ( Vec < SerializedDepNodeData > ) ,
79
+ UpdateEdges ( Vec < ( DepNodeIndex , Vec < DepNodeIndex > ) > ) ,
80
+ InvalidateNodes ( Vec < DepNodeIndex > )
81
+ }
82
+
83
+ #[ derive( Debug ) ]
64
84
enum Action {
65
85
NewNodes ( Vec < DepNodeData > ) ,
66
86
UpdateNodes ( Vec < ( DepNodeIndex , DepNodeData ) > ) ,
@@ -73,36 +93,66 @@ enum Action {
73
93
}
74
94
75
95
struct SerializerWorker {
96
+ fingerprints : IndexVec < DepNodeIndex , Fingerprint > ,
97
+ previous : Lrc < PreviousDepGraph > ,
76
98
file : File ,
77
99
}
78
100
79
101
impl Worker for SerializerWorker {
80
102
type Message = ( usize , Action ) ;
81
- type Result = ( ) ;
103
+ type Result = IndexVec < DepNodeIndex , Fingerprint > ;
82
104
83
105
fn message ( & mut self , ( buffer_size_est, action) : ( usize , Action ) ) {
84
106
let mut encoder = opaque:: Encoder :: new ( Vec :: with_capacity ( buffer_size_est * 5 ) ) ;
107
+ let action = match action {
108
+ Action :: UpdateNodes ( nodes) => {
109
+ SerializedAction :: UpdateEdges ( nodes. into_iter ( ) . filter ( |& ( i, ref data) | {
110
+ self . fingerprints [ i] = data. fingerprint ;
111
+ // Only emit nodes which actually changed
112
+ & * data. edges != self . previous . edge_targets_from ( i)
113
+ } ) . map ( |( i, data) | ( i, data. edges . into_iter ( ) . collect :: < Vec < _ > > ( ) ) ) . collect ( ) )
114
+ }
115
+ Action :: NewNodes ( nodes) => {
116
+ SerializedAction :: NewNodes ( nodes. into_iter ( ) . map ( |data| {
117
+ self . fingerprints . push ( data. fingerprint ) ;
118
+ SerializedDepNodeData {
119
+ node : data. node ,
120
+ edges : data. edges . into_iter ( ) . collect ( ) ,
121
+ }
122
+ } ) . collect ( ) )
123
+ }
124
+ Action :: InvalidateNodes ( nodes) => SerializedAction :: InvalidateNodes ( nodes) ,
125
+ } ;
85
126
action. encode ( & mut encoder) . ok ( ) ;
86
127
self . file . write_all ( & encoder. into_inner ( ) ) . expect ( "unable to write to temp dep graph" ) ;
87
128
}
88
129
89
- fn complete ( self ) { }
130
+ fn complete ( self ) -> IndexVec < DepNodeIndex , Fingerprint > {
131
+ self . fingerprints
132
+ }
90
133
}
91
134
92
135
const BUFFER_SIZE : usize = 800000 ;
93
136
94
137
pub struct Serializer {
95
138
worker : Lrc < WorkerExecutor < SerializerWorker > > ,
139
+ node_count : u32 ,
96
140
new_buffer : Vec < DepNodeData > ,
97
141
new_buffer_size : usize ,
98
142
updated_buffer : Vec < ( DepNodeIndex , DepNodeData ) > ,
99
143
updated_buffer_size : usize ,
100
144
}
101
145
102
146
impl Serializer {
103
- pub fn new ( file : File ) -> Self {
147
+ pub fn new (
148
+ file : File ,
149
+ previous : Lrc < PreviousDepGraph > ,
150
+ ) -> Self {
104
151
Serializer {
152
+ node_count : previous. node_count ( ) as u32 ,
105
153
worker : Lrc :: new ( WorkerExecutor :: new ( SerializerWorker {
154
+ fingerprints : previous. fingerprints . clone ( ) ,
155
+ previous,
106
156
file,
107
157
} ) ) ,
108
158
new_buffer : Vec :: with_capacity ( BUFFER_SIZE ) ,
@@ -120,7 +170,7 @@ impl Serializer {
120
170
}
121
171
122
172
#[ inline]
123
- pub ( super ) fn serialize_new ( & mut self , data : DepNodeData ) {
173
+ pub ( super ) fn serialize_new ( & mut self , data : DepNodeData ) -> DepNodeIndex {
124
174
let edges = data. edges . len ( ) ;
125
175
self . new_buffer . push ( data) ;
126
176
self . new_buffer_size += 8 + edges;
@@ -129,6 +179,9 @@ impl Serializer {
129
179
self . flush_new ( ) ;
130
180
} )
131
181
}
182
+ let index = self . node_count ;
183
+ self . node_count += 1 ;
184
+ DepNodeIndex :: from_u32 ( index)
132
185
}
133
186
134
187
fn flush_updated ( & mut self ) {
@@ -153,7 +206,7 @@ impl Serializer {
153
206
pub fn complete (
154
207
& mut self ,
155
208
invalidate : Vec < DepNodeIndex > ,
156
- ) {
209
+ ) -> IndexVec < DepNodeIndex , Fingerprint > {
157
210
if self . new_buffer . len ( ) > 0 {
158
211
self . flush_new ( ) ;
159
212
}
0 commit comments