@@ -88,7 +88,7 @@ pub fn gc_dep_graph(
88
88
result : & DecodedDepGraph ,
89
89
file : & mut File ,
90
90
) {
91
- let ( nodes, edges) = time_ext ( time_passes, None , "read dep-graph positions" , || {
91
+ let ( nodes, edges) = time_ext ( time_passes, None , "read dep-graph positions" , || {
92
92
read_dep_graph_positions ( d, result) . unwrap ( )
93
93
} ) ;
94
94
@@ -150,32 +150,100 @@ pub fn gc_dep_graph(
150
150
}
151
151
}
152
152
153
+ /// A simpler dep graph used for debugging and testing purposes.
154
+ #[ derive( Clone , Debug , RustcEncodable , RustcDecodable , Default ) ]
155
+ pub struct DepGraphModel {
156
+ pub data : FxHashMap < DepNodeIndex , DepNodeData > ,
157
+ }
158
+
159
+ impl DepGraphModel {
160
+ fn apply ( & mut self , action : & Action ) {
161
+ match action {
162
+ Action :: UpdateNodes ( nodes) => {
163
+ for n in nodes {
164
+ self . data
165
+ . entry ( n. 0 )
166
+ . or_insert_with ( || panic ! ( ) ) . edges = n. 1 . edges . clone ( ) ;
167
+ }
168
+ }
169
+ Action :: NewNodes ( nodes) => {
170
+ for n in nodes {
171
+ assert ! ( self . data. insert( n. 0 , n. 1 . clone( ) ) . is_none( ) ) ;
172
+ }
173
+ }
174
+ Action :: InvalidateNodes ( nodes) => {
175
+ for n in nodes {
176
+ assert ! ( self . data. remove( & n) . is_some( ) ) ;
177
+ }
178
+ } ,
179
+ }
180
+ }
181
+ }
182
+
183
+ #[ derive( Clone , Debug , RustcEncodable , RustcDecodable , Default ) ]
184
+ pub struct CompletedDepGraph {
185
+ /// Hashes of the results of dep nodes
186
+ pub ( super ) results : IndexVec < DepNodeIndex , Fingerprint > ,
187
+ /// A simpler dep graph stored alongside the result for debugging purposes.
188
+ /// This is also constructed when we want to query the dep graph.
189
+ pub model : Option < DepGraphModel > ,
190
+ }
191
+
153
192
pub struct DecodedDepGraph {
154
193
pub prev_graph : PreviousDepGraph ,
155
194
pub state : IndexVec < DepNodeIndex , AtomicCell < DepNodeState > > ,
156
195
pub invalidated : Vec < DepNodeIndex > ,
157
196
pub needs_gc : bool ,
197
+ pub model : Option < DepGraphModel > ,
198
+ }
199
+
200
+ impl DecodedDepGraph {
201
+ /// Asserts that the model matches the real dep graph we decoded
202
+ fn validate_model ( & mut self ) {
203
+ let model = if let Some ( ref model) = self . model {
204
+ model
205
+ } else {
206
+ return
207
+ } ;
208
+
209
+ for i in self . state . indices ( ) {
210
+ if * self . state [ i] . get_mut ( ) == DepNodeState :: Invalid {
211
+ assert ! ( !model. data. contains_key( & i) ) ;
212
+ assert_eq ! ( self . prev_graph. edges[ i] , None ) ;
213
+ } else {
214
+ let data = model. data . get ( & i) . unwrap ( ) ;
215
+ assert_eq ! ( self . prev_graph. nodes[ i] , data. node) ;
216
+ assert_eq ! ( & self . prev_graph. edges[ i] . as_ref( ) . unwrap( ) [ ..] , & data. edges[ ..] ) ;
217
+ }
218
+ }
219
+
220
+ for k in model. data . keys ( ) {
221
+ assert ! ( ( k. as_u32( ) as usize ) < self . state. len( ) ) ;
222
+ }
223
+
224
+ }
158
225
}
159
226
160
227
pub fn decode_dep_graph (
161
228
time_passes : bool ,
162
229
d : & mut opaque:: Decoder < ' _ > ,
163
230
results_d : & mut opaque:: Decoder < ' _ > ,
164
231
) -> Result < DecodedDepGraph , String > {
165
- // Metrics used to decided when to GC
232
+ // Metrics used to decide when to GC
166
233
let mut valid_data = 0 ;
167
234
let mut total_data = 0 ;
168
235
169
- let fingerprints: IndexVec < DepNodeIndex , Fingerprint > =
170
- time_ext ( time_passes, None , "decode prev result fingerprints" , || {
171
- IndexVec :: decode ( results_d)
172
- } ) ?;
236
+ let result_format = time_ext ( time_passes, None , "decode prev result fingerprints" , || {
237
+ CompletedDepGraph :: decode ( results_d)
238
+ } ) ?;
239
+
240
+ let node_count = result_format. results . len ( ) ;
173
241
let mut nodes: IndexVec < _ , _ > = repeat ( DepNode {
174
242
kind : DepKind :: Null ,
175
243
hash : Fingerprint :: ZERO ,
176
- } ) . take ( fingerprints . len ( ) ) . collect ( ) ;
177
- let mut edges: IndexVec < _ , _ > = repeat ( None ) . take ( fingerprints . len ( ) ) . collect ( ) ;
178
- let mut state: IndexVec < _ , _ > = ( 0 ..fingerprints . len ( ) ) . map ( |_| {
244
+ } ) . take ( node_count ) . collect ( ) ;
245
+ let mut edges: IndexVec < _ , _ > = repeat ( None ) . take ( node_count ) . collect ( ) ;
246
+ let mut state: IndexVec < _ , _ > = ( 0 ..node_count ) . map ( |_| {
179
247
AtomicCell :: new ( DepNodeState :: Invalid )
180
248
} ) . collect ( ) ;
181
249
loop {
@@ -221,6 +289,7 @@ pub fn decode_dep_graph(
221
289
let i = DepNodeIndex :: decode ( d) ?;
222
290
valid_data -= edges[ i] . as_ref ( ) . map_or ( 0 , |edges| edges. len ( ) ) ;
223
291
state[ i] = AtomicCell :: new ( DepNodeState :: Invalid ) ;
292
+ edges[ i] = None ;
224
293
}
225
294
valid_data -= len as usize * 8 ;
226
295
}
@@ -241,19 +310,24 @@ pub fn decode_dep_graph(
241
310
valid_data as f32 / total_data as f32
242
311
) ;
243
312
244
- Ok ( DecodedDepGraph {
313
+ let mut graph = DecodedDepGraph {
245
314
prev_graph : PreviousDepGraph {
246
315
index,
247
316
nodes,
248
- fingerprints,
317
+ fingerprints : result_format . results ,
249
318
edges,
250
319
} ,
251
320
invalidated : state. indices ( )
252
321
. filter ( |& i| * state[ i] . get_mut ( ) == DepNodeState :: Invalid )
253
322
. collect ( ) ,
254
323
state,
255
324
needs_gc : valid_data + valid_data / 3 < total_data,
256
- } )
325
+ model : result_format. model ,
326
+ } ;
327
+
328
+ graph. validate_model ( ) ;
329
+
330
+ Ok ( graph)
257
331
}
258
332
259
333
#[ derive( Debug , RustcDecodable , RustcEncodable ) ]
@@ -279,6 +353,7 @@ struct SerializerWorker {
279
353
fingerprints : IndexVec < DepNodeIndex , Fingerprint > ,
280
354
previous : Lrc < PreviousDepGraph > ,
281
355
file : File ,
356
+ model : Option < DepGraphModel > ,
282
357
}
283
358
284
359
impl SerializerWorker {
@@ -397,9 +472,12 @@ impl SerializerWorker {
397
472
398
473
impl Worker for SerializerWorker {
399
474
type Message = ( usize , Action ) ;
400
- type Result = IndexVec < DepNodeIndex , Fingerprint > ;
475
+ type Result = CompletedDepGraph ;
401
476
402
477
fn message ( & mut self , ( buffer_size_est, action) : ( usize , Action ) ) {
478
+ // Apply the action to the model if present
479
+ self . model . as_mut ( ) . map ( |model| model. apply ( & action) ) ;
480
+
403
481
let mut encoder = opaque:: Encoder :: new ( Vec :: with_capacity ( buffer_size_est * 5 ) ) ;
404
482
let action = match action {
405
483
Action :: UpdateNodes ( nodes) => {
@@ -420,8 +498,11 @@ impl Worker for SerializerWorker {
420
498
self . file . write_all ( & encoder. into_inner ( ) ) . expect ( "unable to write to temp dep graph" ) ;
421
499
}
422
500
423
- fn complete ( self ) -> IndexVec < DepNodeIndex , Fingerprint > {
424
- self . fingerprints
501
+ fn complete ( self ) -> CompletedDepGraph {
502
+ CompletedDepGraph {
503
+ results : self . fingerprints ,
504
+ model : self . model
505
+ }
425
506
}
426
507
}
427
508
@@ -430,7 +511,7 @@ const BUFFER_SIZE: usize = 800000;
430
511
pub struct Serializer {
431
512
worker : Lrc < WorkerExecutor < SerializerWorker > > ,
432
513
node_count : u32 ,
433
- invalids : Vec < DepNodeIndex > ,
514
+ invalidated : Vec < DepNodeIndex > ,
434
515
new_buffer : Vec < ( DepNodeIndex , DepNodeData ) > ,
435
516
new_buffer_size : usize ,
436
517
updated_buffer : Vec < ( DepNodeIndex , DepNodeData ) > ,
@@ -441,15 +522,17 @@ impl Serializer {
441
522
pub fn new (
442
523
file : File ,
443
524
previous : Lrc < PreviousDepGraph > ,
444
- invalids : Vec < DepNodeIndex > ,
525
+ invalidated : Vec < DepNodeIndex > ,
526
+ model : Option < DepGraphModel > ,
445
527
) -> Self {
446
528
Serializer {
447
- invalids ,
448
- node_count : previous. node_count ( ) as u32 ,
529
+ invalidated ,
530
+ node_count : previous. nodes . len ( ) as u32 ,
449
531
worker : Lrc :: new ( WorkerExecutor :: new ( SerializerWorker {
450
532
fingerprints : previous. fingerprints . clone ( ) ,
451
533
previous,
452
534
file,
535
+ model,
453
536
} ) ) ,
454
537
new_buffer : Vec :: with_capacity ( BUFFER_SIZE ) ,
455
538
new_buffer_size : 0 ,
@@ -467,9 +550,9 @@ impl Serializer {
467
550
468
551
#[ inline]
469
552
fn alloc_index ( & mut self ) -> DepNodeIndex {
470
- if let Some ( invalid ) = self . invalids . pop ( ) {
553
+ if let Some ( invalidated ) = self . invalidated . pop ( ) {
471
554
// Reuse an invalided index
472
- invalid
555
+ invalidated
473
556
} else {
474
557
// Create a new index
475
558
let index = self . node_count ;
@@ -511,10 +594,10 @@ impl Serializer {
511
594
}
512
595
}
513
596
514
- pub fn complete (
597
+ pub ( super ) fn complete (
515
598
& mut self ,
516
599
invalidate : Vec < DepNodeIndex > ,
517
- ) -> IndexVec < DepNodeIndex , Fingerprint > {
600
+ ) -> CompletedDepGraph {
518
601
if self . new_buffer . len ( ) > 0 {
519
602
self . flush_new ( ) ;
520
603
}
0 commit comments