@@ -46,6 +46,7 @@ use rustc_data_structures::profiling::SelfProfilerRef;
4646use rustc_data_structures:: sync:: Lock ;
4747use rustc_data_structures:: unhash:: UnhashMap ;
4848use rustc_index:: { Idx , IndexVec } ;
49+ use rustc_serialize:: opaque:: mem_encoder:: MemEncoder ;
4950use rustc_serialize:: opaque:: { FileEncodeResult , FileEncoder , IntEncodedWithFixedSize , MemDecoder } ;
5051use rustc_serialize:: { Decodable , Decoder , Encodable , Encoder } ;
5152use tracing:: { debug, instrument} ;
@@ -105,22 +106,12 @@ impl SerializedDepGraph {
105106 ) -> impl Iterator < Item = SerializedDepNodeIndex > + Clone {
106107 let header = self . edge_list_indices [ source] ;
107108 let mut raw = & self . edge_list_data [ header. start ( ) ..] ;
108- // Figure out where the edge list for `source` ends by getting the start index of the next
109- // edge list, or the end of the array if this is the last edge.
110- let end = self
111- . edge_list_indices
112- . get ( source + 1 )
113- . map ( |h| h. start ( ) )
114- . unwrap_or_else ( || self . edge_list_data . len ( ) - DEP_NODE_PAD ) ;
115-
116- // The number of edges for this node is implicitly stored in the combination of the byte
117- // width and the length.
109+
118110 let bytes_per_index = header. bytes_per_index ( ) ;
119- let len = ( end - header. start ( ) ) / bytes_per_index;
120111
121112 // LLVM doesn't hoist EdgeHeader::mask so we do it ourselves.
122113 let mask = header. mask ( ) ;
123- ( 0 ..len ) . map ( move |_| {
114+ ( 0 ..header . num_edges ) . map ( move |_| {
124115 // Doing this slicing in this order ensures that the first bounds check suffices for
125116 // all the others.
126117 let index = & raw [ ..DEP_NODE_SIZE ] ;
@@ -163,6 +154,7 @@ impl SerializedDepGraph {
163154#[ derive( Debug , Clone , Copy ) ]
164155struct EdgeHeader {
165156 repr : usize ,
157+ num_edges : u32 ,
166158}
167159
168160impl EdgeHeader {
@@ -205,9 +197,14 @@ impl SerializedDepGraph {
205197
206198 let graph_bytes = d. len ( ) - ( 2 * IntEncodedWithFixedSize :: ENCODED_SIZE ) - d. position ( ) ;
207199
208- let mut nodes = IndexVec :: with_capacity ( node_count) ;
209- let mut fingerprints = IndexVec :: with_capacity ( node_count) ;
210- let mut edge_list_indices = IndexVec :: with_capacity ( node_count) ;
200+ let mut nodes = IndexVec :: from_elem_n (
201+ DepNode { kind : D :: DEP_KIND_NULL , hash : PackedFingerprint :: from ( Fingerprint :: ZERO ) } ,
202+ node_count,
203+ ) ;
204+ let mut fingerprints = IndexVec :: from_elem_n ( Fingerprint :: ZERO , node_count) ;
205+ let mut edge_list_indices =
206+ IndexVec :: from_elem_n ( EdgeHeader { repr : 0 , num_edges : 0 } , node_count) ;
207+
211208 // This estimation assumes that all of the encoded bytes are for the edge lists or for the
212209 // fixed-size node headers. But that's not necessarily true; if any edge list has a length
213210 // that spills out of the size we can bit-pack into SerializedNodeHeader then some of the
@@ -226,11 +223,14 @@ impl SerializedDepGraph {
226223 let node_header =
227224 SerializedNodeHeader :: < D > { bytes : d. read_array ( ) , _marker : PhantomData } ;
228225
229- let _i: SerializedDepNodeIndex = nodes. push ( node_header. node ( ) ) ;
230- debug_assert_eq ! ( _i. index( ) , _index) ;
226+ let index = node_header. index ( ) ;
227+
228+ let node = & mut nodes[ index] ;
229+ // Make sure there's no duplicate indices in the dep graph.
230+ assert ! ( node_header. node( ) . kind != D :: DEP_KIND_NULL && node. kind == D :: DEP_KIND_NULL ) ;
231+ * node = node_header. node ( ) ;
231232
232- let _i: SerializedDepNodeIndex = fingerprints. push ( node_header. fingerprint ( ) ) ;
233- debug_assert_eq ! ( _i. index( ) , _index) ;
233+ fingerprints[ index] = node_header. fingerprint ( ) ;
234234
235235 // If the length of this node's edge list is small, the length is stored in the header.
236236 // If it is not, we fall back to another decoder call.
@@ -242,12 +242,11 @@ impl SerializedDepGraph {
242242 let edges_len_bytes = node_header. bytes_per_index ( ) * ( num_edges as usize ) ;
243243 // The in-memory structure for the edges list stores the byte width of the edges on
244244 // this node with the offset into the global edge data array.
245- let edges_header = node_header. edges_header ( & edge_list_data) ;
245+ let edges_header = node_header. edges_header ( & edge_list_data, num_edges ) ;
246246
247247 edge_list_data. extend ( d. read_raw_bytes ( edges_len_bytes) ) ;
248248
249- let _i: SerializedDepNodeIndex = edge_list_indices. push ( edges_header) ;
250- debug_assert_eq ! ( _i. index( ) , _index) ;
249+ edge_list_indices[ index] = edges_header;
251250 }
252251
253252 // When we access the edge list data, we do a fixed-size read from the edge list data then
@@ -298,9 +297,10 @@ impl SerializedDepGraph {
298297/// * In whatever bits remain, the length of the edge list for this node, if it fits
299298struct SerializedNodeHeader < D > {
300299 // 2 bytes for the DepNode
300+ // 4 bytes for the index
301301 // 16 for Fingerprint in DepNode
302302 // 16 for Fingerprint in NodeInfo
303- bytes : [ u8 ; 34 ] ,
303+ bytes : [ u8 ; 38 ] ,
304304 _marker : PhantomData < D > ,
305305}
306306
@@ -310,6 +310,7 @@ struct Unpacked {
310310 len : Option < u32 > ,
311311 bytes_per_index : usize ,
312312 kind : DepKind ,
313+ index : SerializedDepNodeIndex ,
313314 hash : PackedFingerprint ,
314315 fingerprint : Fingerprint ,
315316}
@@ -331,6 +332,7 @@ impl<D: Deps> SerializedNodeHeader<D> {
331332 #[ inline]
332333 fn new (
333334 node : DepNode ,
335+ index : DepNodeIndex ,
334336 fingerprint : Fingerprint ,
335337 edge_max_index : u32 ,
336338 edge_count : usize ,
@@ -352,10 +354,11 @@ impl<D: Deps> SerializedNodeHeader<D> {
352354 let hash: Fingerprint = node. hash . into ( ) ;
353355
354356 // Using half-open ranges ensures an unconditional panic if we get the magic numbers wrong.
355- let mut bytes = [ 0u8 ; 34 ] ;
357+ let mut bytes = [ 0u8 ; 38 ] ;
356358 bytes[ ..2 ] . copy_from_slice ( & head. to_le_bytes ( ) ) ;
357- bytes[ 2 ..18 ] . copy_from_slice ( & hash. to_le_bytes ( ) ) ;
358- bytes[ 18 ..] . copy_from_slice ( & fingerprint. to_le_bytes ( ) ) ;
359+ bytes[ 2 ..6 ] . copy_from_slice ( & index. as_u32 ( ) . to_le_bytes ( ) ) ;
360+ bytes[ 6 ..22 ] . copy_from_slice ( & hash. to_le_bytes ( ) ) ;
361+ bytes[ 22 ..] . copy_from_slice ( & fingerprint. to_le_bytes ( ) ) ;
359362
360363 #[ cfg( debug_assertions) ]
361364 {
@@ -372,8 +375,9 @@ impl<D: Deps> SerializedNodeHeader<D> {
372375 #[ inline]
373376 fn unpack ( & self ) -> Unpacked {
374377 let head = u16:: from_le_bytes ( self . bytes [ ..2 ] . try_into ( ) . unwrap ( ) ) ;
375- let hash = self . bytes [ 2 ..18 ] . try_into ( ) . unwrap ( ) ;
376- let fingerprint = self . bytes [ 18 ..] . try_into ( ) . unwrap ( ) ;
378+ let index = u32:: from_le_bytes ( self . bytes [ 2 ..6 ] . try_into ( ) . unwrap ( ) ) ;
379+ let hash = self . bytes [ 6 ..22 ] . try_into ( ) . unwrap ( ) ;
380+ let fingerprint = self . bytes [ 22 ..] . try_into ( ) . unwrap ( ) ;
377381
378382 let kind = head & mask ( Self :: KIND_BITS ) as u16 ;
379383 let bytes_per_index = ( head >> Self :: KIND_BITS ) & mask ( Self :: WIDTH_BITS ) as u16 ;
@@ -383,6 +387,7 @@ impl<D: Deps> SerializedNodeHeader<D> {
383387 len : len. checked_sub ( 1 ) ,
384388 bytes_per_index : bytes_per_index as usize + 1 ,
385389 kind : DepKind :: new ( kind) ,
390+ index : SerializedDepNodeIndex :: from_u32 ( index) ,
386391 hash : Fingerprint :: from_le_bytes ( hash) . into ( ) ,
387392 fingerprint : Fingerprint :: from_le_bytes ( fingerprint) ,
388393 }
@@ -398,6 +403,11 @@ impl<D: Deps> SerializedNodeHeader<D> {
398403 self . unpack ( ) . bytes_per_index
399404 }
400405
406+ #[ inline]
407+ fn index ( & self ) -> SerializedDepNodeIndex {
408+ self . unpack ( ) . index
409+ }
410+
401411 #[ inline]
402412 fn fingerprint ( & self ) -> Fingerprint {
403413 self . unpack ( ) . fingerprint
@@ -410,9 +420,10 @@ impl<D: Deps> SerializedNodeHeader<D> {
410420 }
411421
412422 #[ inline]
413- fn edges_header ( & self , edge_list_data : & [ u8 ] ) -> EdgeHeader {
423+ fn edges_header ( & self , edge_list_data : & [ u8 ] , num_edges : u32 ) -> EdgeHeader {
414424 EdgeHeader {
415425 repr : ( edge_list_data. len ( ) << DEP_NODE_WIDTH_BITS ) | ( self . bytes_per_index ( ) - 1 ) ,
426+ num_edges,
416427 }
417428 }
418429}
@@ -425,10 +436,15 @@ struct NodeInfo {
425436}
426437
427438impl NodeInfo {
428- fn encode < D : Deps > ( & self , e : & mut FileEncoder ) {
439+ fn encode < D : Deps > ( & self , e : & mut MemEncoder , index : DepNodeIndex ) {
429440 let NodeInfo { node, fingerprint, ref edges } = * self ;
430- let header =
431- SerializedNodeHeader :: < D > :: new ( node, fingerprint, edges. max_index ( ) , edges. len ( ) ) ;
441+ let header = SerializedNodeHeader :: < D > :: new (
442+ node,
443+ index,
444+ fingerprint,
445+ edges. max_index ( ) ,
446+ edges. len ( ) ,
447+ ) ;
432448 e. write_array ( header. bytes ) ;
433449
434450 if header. len ( ) . is_none ( ) {
@@ -450,8 +466,9 @@ impl NodeInfo {
450466 /// This avoids the overhead of constructing `EdgesVec`, which would be needed to call `encode`.
451467 #[ inline]
452468 fn encode_promoted < D : Deps > (
453- e : & mut FileEncoder ,
469+ e : & mut MemEncoder ,
454470 node : DepNode ,
471+ index : DepNodeIndex ,
455472 fingerprint : Fingerprint ,
456473 prev_index : SerializedDepNodeIndex ,
457474 colors : & DepNodeColorMap ,
@@ -464,7 +481,7 @@ impl NodeInfo {
464481 let edge_max =
465482 edges. clone ( ) . map ( |i| colors. current ( i) . unwrap ( ) . as_u32 ( ) ) . max ( ) . unwrap_or ( 0 ) ;
466483
467- let header = SerializedNodeHeader :: < D > :: new ( node, fingerprint, edge_max, edge_count) ;
484+ let header = SerializedNodeHeader :: < D > :: new ( node, index , fingerprint, edge_max, edge_count) ;
468485 e. write_array ( header. bytes ) ;
469486
470487 if header. len ( ) . is_none ( ) {
@@ -498,6 +515,8 @@ struct EncoderState<D: Deps> {
498515 total_edge_count : usize ,
499516 stats : Option < FxHashMap < DepKind , Stat > > ,
500517
518+ mem_encoder : MemEncoder ,
519+
501520 /// Stores the number of times we've encoded each dep kind.
502521 kind_stats : Vec < u32 > ,
503522 marker : PhantomData < D > ,
@@ -511,22 +530,28 @@ impl<D: Deps> EncoderState<D> {
511530 total_edge_count : 0 ,
512531 total_node_count : 0 ,
513532 stats : record_stats. then ( FxHashMap :: default) ,
533+ mem_encoder : MemEncoder :: new ( ) ,
514534 kind_stats : iter:: repeat ( 0 ) . take ( D :: DEP_KIND_MAX as usize + 1 ) . collect ( ) ,
515535 marker : PhantomData ,
516536 }
517537 }
518538
539+ #[ inline]
540+ fn alloc_index ( & mut self ) -> DepNodeIndex {
541+ let index = DepNodeIndex :: new ( self . total_node_count ) ;
542+ self . total_node_count += 1 ;
543+ index
544+ }
545+
519546 #[ inline]
520547 fn record (
521548 & mut self ,
522549 node : DepNode ,
550+ index : DepNodeIndex ,
523551 edge_count : usize ,
524552 edges : impl FnOnce ( & mut Self ) -> Vec < DepNodeIndex > ,
525553 record_graph : & Option < Lock < DepGraphQuery > > ,
526554 ) -> DepNodeIndex {
527- let index = DepNodeIndex :: new ( self . total_node_count ) ;
528-
529- self . total_node_count += 1 ;
530555 self . kind_stats [ node. kind . as_usize ( ) ] += 1 ;
531556 self . total_edge_count += edge_count;
532557
@@ -558,14 +583,25 @@ impl<D: Deps> EncoderState<D> {
558583 index
559584 }
560585
586+ #[ inline]
587+ fn flush_mem_encoder ( & mut self ) {
588+ let data = & mut self . mem_encoder . data ;
589+ if data. len ( ) > 64 * 1024 {
590+ self . encoder . emit_raw_bytes ( & data[ ..] ) ;
591+ data. clear ( ) ;
592+ }
593+ }
594+
561595 /// Encodes a node to the current graph.
562596 fn encode_node (
563597 & mut self ,
564598 node : & NodeInfo ,
565599 record_graph : & Option < Lock < DepGraphQuery > > ,
566600 ) -> DepNodeIndex {
567- node. encode :: < D > ( & mut self . encoder ) ;
568- self . record ( node. node , node. edges . len ( ) , |_| node. edges [ ..] . to_vec ( ) , record_graph)
601+ let index = self . alloc_index ( ) ;
602+ node. encode :: < D > ( & mut self . mem_encoder , index) ;
603+ self . flush_mem_encoder ( ) ;
604+ self . record ( node. node , index, node. edges . len ( ) , |_| node. edges [ ..] . to_vec ( ) , record_graph)
569605 }
570606
571607 /// Encodes a node that was promoted from the previous graph. It reads the information directly from
@@ -581,20 +617,22 @@ impl<D: Deps> EncoderState<D> {
581617 record_graph : & Option < Lock < DepGraphQuery > > ,
582618 colors : & DepNodeColorMap ,
583619 ) -> DepNodeIndex {
620+ let index = self . alloc_index ( ) ;
584621 let node = self . previous . index_to_node ( prev_index) ;
585-
586622 let fingerprint = self . previous . fingerprint_by_index ( prev_index) ;
587623 let edge_count = NodeInfo :: encode_promoted :: < D > (
588- & mut self . encoder ,
624+ & mut self . mem_encoder ,
589625 node,
626+ index,
590627 fingerprint,
591628 prev_index,
592629 colors,
593630 & self . previous ,
594631 ) ;
595-
632+ self . flush_mem_encoder ( ) ;
596633 self . record (
597634 node,
635+ index,
598636 edge_count,
599637 |this| {
600638 this. previous
@@ -603,12 +641,14 @@ impl<D: Deps> EncoderState<D> {
603641 . collect ( )
604642 } ,
605643 record_graph,
606- )
644+ ) ;
645+ index
607646 }
608647
609648 fn finish ( self , profiler : & SelfProfilerRef ) -> FileEncodeResult {
610649 let Self {
611650 mut encoder,
651+ mem_encoder,
612652 total_node_count,
613653 total_edge_count,
614654 stats : _,
@@ -617,6 +657,8 @@ impl<D: Deps> EncoderState<D> {
617657 previous,
618658 } = self ;
619659
660+ encoder. emit_raw_bytes ( & mem_encoder. data ) ;
661+
620662 let node_count = total_node_count. try_into ( ) . unwrap ( ) ;
621663 let edge_count = total_edge_count. try_into ( ) . unwrap ( ) ;
622664
0 commit comments