@@ -88,7 +88,7 @@ pub fn gc_dep_graph(
8888 result : & DecodedDepGraph ,
8989 file : & mut File ,
9090) {
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" , || {
9292 read_dep_graph_positions ( d, result) . unwrap ( )
9393 } ) ;
9494
@@ -150,32 +150,100 @@ pub fn gc_dep_graph(
150150 }
151151}
152152
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+
153192pub struct DecodedDepGraph {
154193 pub prev_graph : PreviousDepGraph ,
155194 pub state : IndexVec < DepNodeIndex , AtomicCell < DepNodeState > > ,
156195 pub invalidated : Vec < DepNodeIndex > ,
157196 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+ }
158225}
159226
160227pub fn decode_dep_graph (
161228 time_passes : bool ,
162229 d : & mut opaque:: Decoder < ' _ > ,
163230 results_d : & mut opaque:: Decoder < ' _ > ,
164231) -> Result < DecodedDepGraph , String > {
165- // Metrics used to decided when to GC
232+ // Metrics used to decide when to GC
166233 let mut valid_data = 0 ;
167234 let mut total_data = 0 ;
168235
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 ( ) ;
173241 let mut nodes: IndexVec < _ , _ > = repeat ( DepNode {
174242 kind : DepKind :: Null ,
175243 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 ( |_| {
179247 AtomicCell :: new ( DepNodeState :: Invalid )
180248 } ) . collect ( ) ;
181249 loop {
@@ -221,6 +289,7 @@ pub fn decode_dep_graph(
221289 let i = DepNodeIndex :: decode ( d) ?;
222290 valid_data -= edges[ i] . as_ref ( ) . map_or ( 0 , |edges| edges. len ( ) ) ;
223291 state[ i] = AtomicCell :: new ( DepNodeState :: Invalid ) ;
292+ edges[ i] = None ;
224293 }
225294 valid_data -= len as usize * 8 ;
226295 }
@@ -241,19 +310,24 @@ pub fn decode_dep_graph(
241310 valid_data as f32 / total_data as f32
242311 ) ;
243312
244- Ok ( DecodedDepGraph {
313+ let mut graph = DecodedDepGraph {
245314 prev_graph : PreviousDepGraph {
246315 index,
247316 nodes,
248- fingerprints,
317+ fingerprints : result_format . results ,
249318 edges,
250319 } ,
251320 invalidated : state. indices ( )
252321 . filter ( |& i| * state[ i] . get_mut ( ) == DepNodeState :: Invalid )
253322 . collect ( ) ,
254323 state,
255324 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)
257331}
258332
259333#[ derive( Debug , RustcDecodable , RustcEncodable ) ]
@@ -279,6 +353,7 @@ struct SerializerWorker {
279353 fingerprints : IndexVec < DepNodeIndex , Fingerprint > ,
280354 previous : Lrc < PreviousDepGraph > ,
281355 file : File ,
356+ model : Option < DepGraphModel > ,
282357}
283358
284359impl SerializerWorker {
@@ -397,9 +472,12 @@ impl SerializerWorker {
397472
398473impl Worker for SerializerWorker {
399474 type Message = ( usize , Action ) ;
400- type Result = IndexVec < DepNodeIndex , Fingerprint > ;
475+ type Result = CompletedDepGraph ;
401476
402477 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+
403481 let mut encoder = opaque:: Encoder :: new ( Vec :: with_capacity ( buffer_size_est * 5 ) ) ;
404482 let action = match action {
405483 Action :: UpdateNodes ( nodes) => {
@@ -420,8 +498,11 @@ impl Worker for SerializerWorker {
420498 self . file . write_all ( & encoder. into_inner ( ) ) . expect ( "unable to write to temp dep graph" ) ;
421499 }
422500
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+ }
425506 }
426507}
427508
@@ -430,7 +511,7 @@ const BUFFER_SIZE: usize = 800000;
430511pub struct Serializer {
431512 worker : Lrc < WorkerExecutor < SerializerWorker > > ,
432513 node_count : u32 ,
433- invalids : Vec < DepNodeIndex > ,
514+ invalidated : Vec < DepNodeIndex > ,
434515 new_buffer : Vec < ( DepNodeIndex , DepNodeData ) > ,
435516 new_buffer_size : usize ,
436517 updated_buffer : Vec < ( DepNodeIndex , DepNodeData ) > ,
@@ -441,15 +522,17 @@ impl Serializer {
441522 pub fn new (
442523 file : File ,
443524 previous : Lrc < PreviousDepGraph > ,
444- invalids : Vec < DepNodeIndex > ,
525+ invalidated : Vec < DepNodeIndex > ,
526+ model : Option < DepGraphModel > ,
445527 ) -> Self {
446528 Serializer {
447- invalids ,
448- node_count : previous. node_count ( ) as u32 ,
529+ invalidated ,
530+ node_count : previous. nodes . len ( ) as u32 ,
449531 worker : Lrc :: new ( WorkerExecutor :: new ( SerializerWorker {
450532 fingerprints : previous. fingerprints . clone ( ) ,
451533 previous,
452534 file,
535+ model,
453536 } ) ) ,
454537 new_buffer : Vec :: with_capacity ( BUFFER_SIZE ) ,
455538 new_buffer_size : 0 ,
@@ -467,9 +550,9 @@ impl Serializer {
467550
468551 #[ inline]
469552 fn alloc_index ( & mut self ) -> DepNodeIndex {
470- if let Some ( invalid ) = self . invalids . pop ( ) {
553+ if let Some ( invalidated ) = self . invalidated . pop ( ) {
471554 // Reuse an invalided index
472- invalid
555+ invalidated
473556 } else {
474557 // Create a new index
475558 let index = self . node_count ;
@@ -511,10 +594,10 @@ impl Serializer {
511594 }
512595 }
513596
514- pub fn complete (
597+ pub ( super ) fn complete (
515598 & mut self ,
516599 invalidate : Vec < DepNodeIndex > ,
517- ) -> IndexVec < DepNodeIndex , Fingerprint > {
600+ ) -> CompletedDepGraph {
518601 if self . new_buffer . len ( ) > 0 {
519602 self . flush_new ( ) ;
520603 }
0 commit comments