@@ -46,6 +46,7 @@ use rustc_data_structures::profiling::SelfProfilerRef;
46
46
use rustc_data_structures:: sync:: Lock ;
47
47
use rustc_data_structures:: unhash:: UnhashMap ;
48
48
use rustc_index:: { Idx , IndexVec } ;
49
+ use rustc_serialize:: opaque:: mem_encoder:: MemEncoder ;
49
50
use rustc_serialize:: opaque:: { FileEncodeResult , FileEncoder , IntEncodedWithFixedSize , MemDecoder } ;
50
51
use rustc_serialize:: { Decodable , Decoder , Encodable , Encoder } ;
51
52
use tracing:: { debug, instrument} ;
@@ -105,18 +106,11 @@ impl SerializedDepGraph {
105
106
) -> impl Iterator < Item = SerializedDepNodeIndex > + Clone {
106
107
let header = self . edge_list_indices [ source] ;
107
108
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
109
116
110
// The number of edges for this node is implicitly stored in the combination of the byte
117
111
// width and the length.
118
112
let bytes_per_index = header. bytes_per_index ( ) ;
119
- let len = ( end - header. start ( ) ) / bytes_per_index ;
113
+ let len = header. edges ;
120
114
121
115
// LLVM doesn't hoist EdgeHeader::mask so we do it ourselves.
122
116
let mask = header. mask ( ) ;
@@ -163,6 +157,7 @@ impl SerializedDepGraph {
163
157
#[ derive( Debug , Clone , Copy ) ]
164
158
struct EdgeHeader {
165
159
repr : usize ,
160
+ edges : u32 ,
166
161
}
167
162
168
163
impl EdgeHeader {
@@ -205,9 +200,17 @@ impl SerializedDepGraph {
205
200
206
201
let graph_bytes = d. len ( ) - ( 2 * IntEncodedWithFixedSize :: ENCODED_SIZE ) - d. position ( ) ;
207
202
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) ;
203
+ let mut nodes: IndexVec < SerializedDepNodeIndex , _ > = ( 0 ..node_count)
204
+ . map ( |_| DepNode {
205
+ kind : D :: DEP_KIND_NULL ,
206
+ hash : PackedFingerprint :: from ( Fingerprint :: ZERO ) ,
207
+ } )
208
+ . collect ( ) ;
209
+ let mut fingerprints: IndexVec < SerializedDepNodeIndex , _ > =
210
+ ( 0 ..node_count) . map ( |_| Fingerprint :: ZERO ) . collect ( ) ;
211
+ let mut edge_list_indices: IndexVec < SerializedDepNodeIndex , _ > =
212
+ ( 0 ..node_count) . map ( |_| EdgeHeader { repr : 0 , edges : 0 } ) . collect ( ) ;
213
+
211
214
// This estimation assumes that all of the encoded bytes are for the edge lists or for the
212
215
// fixed-size node headers. But that's not necessarily true; if any edge list has a length
213
216
// that spills out of the size we can bit-pack into SerializedNodeHeader then some of the
@@ -226,11 +229,10 @@ impl SerializedDepGraph {
226
229
let node_header =
227
230
SerializedNodeHeader :: < D > { bytes : d. read_array ( ) , _marker : PhantomData } ;
228
231
229
- let _i: SerializedDepNodeIndex = nodes. push ( node_header. node ( ) ) ;
230
- debug_assert_eq ! ( _i. index( ) , _index) ;
232
+ let index = node_header. index ( ) ;
231
233
232
- let _i : SerializedDepNodeIndex = fingerprints . push ( node_header. fingerprint ( ) ) ;
233
- debug_assert_eq ! ( _i . index( ) , _index ) ;
234
+ nodes [ index ] = node_header. node ( ) ;
235
+ fingerprints [ index] = node_header . fingerprint ( ) ;
234
236
235
237
// If the length of this node's edge list is small, the length is stored in the header.
236
238
// If it is not, we fall back to another decoder call.
@@ -242,12 +244,11 @@ impl SerializedDepGraph {
242
244
let edges_len_bytes = node_header. bytes_per_index ( ) * ( num_edges as usize ) ;
243
245
// The in-memory structure for the edges list stores the byte width of the edges on
244
246
// this node with the offset into the global edge data array.
245
- let edges_header = node_header. edges_header ( & edge_list_data) ;
247
+ let edges_header = node_header. edges_header ( & edge_list_data, num_edges ) ;
246
248
247
249
edge_list_data. extend ( d. read_raw_bytes ( edges_len_bytes) ) ;
248
250
249
- let _i: SerializedDepNodeIndex = edge_list_indices. push ( edges_header) ;
250
- debug_assert_eq ! ( _i. index( ) , _index) ;
251
+ edge_list_indices[ index] = edges_header;
251
252
}
252
253
253
254
// When we access the edge list data, we do a fixed-size read from the edge list data then
@@ -298,9 +299,10 @@ impl SerializedDepGraph {
298
299
/// * In whatever bits remain, the length of the edge list for this node, if it fits
299
300
struct SerializedNodeHeader < D > {
300
301
// 2 bytes for the DepNode
302
+ // 4 bytes for the index
301
303
// 16 for Fingerprint in DepNode
302
304
// 16 for Fingerprint in NodeInfo
303
- bytes : [ u8 ; 34 ] ,
305
+ bytes : [ u8 ; 38 ] ,
304
306
_marker : PhantomData < D > ,
305
307
}
306
308
@@ -310,6 +312,7 @@ struct Unpacked {
310
312
len : Option < u32 > ,
311
313
bytes_per_index : usize ,
312
314
kind : DepKind ,
315
+ index : SerializedDepNodeIndex ,
313
316
hash : PackedFingerprint ,
314
317
fingerprint : Fingerprint ,
315
318
}
@@ -331,6 +334,7 @@ impl<D: Deps> SerializedNodeHeader<D> {
331
334
#[ inline]
332
335
fn new (
333
336
node : DepNode ,
337
+ index : DepNodeIndex ,
334
338
fingerprint : Fingerprint ,
335
339
edge_max_index : u32 ,
336
340
edge_count : usize ,
@@ -352,10 +356,11 @@ impl<D: Deps> SerializedNodeHeader<D> {
352
356
let hash: Fingerprint = node. hash . into ( ) ;
353
357
354
358
// Using half-open ranges ensures an unconditional panic if we get the magic numbers wrong.
355
- let mut bytes = [ 0u8 ; 34 ] ;
359
+ let mut bytes = [ 0u8 ; 38 ] ;
356
360
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 ( ) ) ;
361
+ bytes[ 2 ..6 ] . copy_from_slice ( & index. as_u32 ( ) . to_le_bytes ( ) ) ;
362
+ bytes[ 6 ..22 ] . copy_from_slice ( & hash. to_le_bytes ( ) ) ;
363
+ bytes[ 22 ..] . copy_from_slice ( & fingerprint. to_le_bytes ( ) ) ;
359
364
360
365
#[ cfg( debug_assertions) ]
361
366
{
@@ -372,8 +377,9 @@ impl<D: Deps> SerializedNodeHeader<D> {
372
377
#[ inline]
373
378
fn unpack ( & self ) -> Unpacked {
374
379
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 ( ) ;
380
+ let index = u32:: from_le_bytes ( self . bytes [ 2 ..6 ] . try_into ( ) . unwrap ( ) ) ;
381
+ let hash = self . bytes [ 6 ..22 ] . try_into ( ) . unwrap ( ) ;
382
+ let fingerprint = self . bytes [ 22 ..] . try_into ( ) . unwrap ( ) ;
377
383
378
384
let kind = head & mask ( Self :: KIND_BITS ) as u16 ;
379
385
let bytes_per_index = ( head >> Self :: KIND_BITS ) & mask ( Self :: WIDTH_BITS ) as u16 ;
@@ -383,6 +389,7 @@ impl<D: Deps> SerializedNodeHeader<D> {
383
389
len : len. checked_sub ( 1 ) ,
384
390
bytes_per_index : bytes_per_index as usize + 1 ,
385
391
kind : DepKind :: new ( kind) ,
392
+ index : SerializedDepNodeIndex :: from_u32 ( index) ,
386
393
hash : Fingerprint :: from_le_bytes ( hash) . into ( ) ,
387
394
fingerprint : Fingerprint :: from_le_bytes ( fingerprint) ,
388
395
}
@@ -398,6 +405,11 @@ impl<D: Deps> SerializedNodeHeader<D> {
398
405
self . unpack ( ) . bytes_per_index
399
406
}
400
407
408
+ #[ inline]
409
+ fn index ( & self ) -> SerializedDepNodeIndex {
410
+ self . unpack ( ) . index
411
+ }
412
+
401
413
#[ inline]
402
414
fn fingerprint ( & self ) -> Fingerprint {
403
415
self . unpack ( ) . fingerprint
@@ -410,9 +422,10 @@ impl<D: Deps> SerializedNodeHeader<D> {
410
422
}
411
423
412
424
#[ inline]
413
- fn edges_header ( & self , edge_list_data : & [ u8 ] ) -> EdgeHeader {
425
+ fn edges_header ( & self , edge_list_data : & [ u8 ] , edges : u32 ) -> EdgeHeader {
414
426
EdgeHeader {
415
427
repr : ( edge_list_data. len ( ) << DEP_NODE_WIDTH_BITS ) | ( self . bytes_per_index ( ) - 1 ) ,
428
+ edges,
416
429
}
417
430
}
418
431
}
@@ -425,10 +438,15 @@ struct NodeInfo {
425
438
}
426
439
427
440
impl NodeInfo {
428
- fn encode < D : Deps > ( & self , e : & mut FileEncoder ) {
441
+ fn encode < D : Deps > ( & self , e : & mut MemEncoder , index : DepNodeIndex ) {
429
442
let NodeInfo { node, fingerprint, ref edges } = * self ;
430
- let header =
431
- SerializedNodeHeader :: < D > :: new ( node, fingerprint, edges. max_index ( ) , edges. len ( ) ) ;
443
+ let header = SerializedNodeHeader :: < D > :: new (
444
+ node,
445
+ index,
446
+ fingerprint,
447
+ edges. max_index ( ) ,
448
+ edges. len ( ) ,
449
+ ) ;
432
450
e. write_array ( header. bytes ) ;
433
451
434
452
if header. len ( ) . is_none ( ) {
@@ -450,8 +468,9 @@ impl NodeInfo {
450
468
/// This avoids the overhead of constructing `EdgesVec`, which would be needed to call `encode`.
451
469
#[ inline]
452
470
fn encode_promoted < D : Deps > (
453
- e : & mut FileEncoder ,
471
+ e : & mut MemEncoder ,
454
472
node : DepNode ,
473
+ index : DepNodeIndex ,
455
474
fingerprint : Fingerprint ,
456
475
prev_index : SerializedDepNodeIndex ,
457
476
colors : & DepNodeColorMap ,
@@ -464,7 +483,7 @@ impl NodeInfo {
464
483
let edge_max =
465
484
edges. clone ( ) . map ( |i| colors. current ( i) . unwrap ( ) . as_u32 ( ) ) . max ( ) . unwrap_or ( 0 ) ;
466
485
467
- let header = SerializedNodeHeader :: < D > :: new ( node, fingerprint, edge_max, edge_count) ;
486
+ let header = SerializedNodeHeader :: < D > :: new ( node, index , fingerprint, edge_max, edge_count) ;
468
487
e. write_array ( header. bytes ) ;
469
488
470
489
if header. len ( ) . is_none ( ) {
@@ -498,6 +517,8 @@ struct EncoderState<D: Deps> {
498
517
total_edge_count : usize ,
499
518
stats : Option < FxHashMap < DepKind , Stat > > ,
500
519
520
+ mem_encoder : MemEncoder ,
521
+
501
522
/// Stores the number of times we've encoded each dep kind.
502
523
kind_stats : Vec < u32 > ,
503
524
marker : PhantomData < D > ,
@@ -511,22 +532,28 @@ impl<D: Deps> EncoderState<D> {
511
532
total_edge_count : 0 ,
512
533
total_node_count : 0 ,
513
534
stats : record_stats. then ( FxHashMap :: default) ,
535
+ mem_encoder : MemEncoder :: new ( ) ,
514
536
kind_stats : iter:: repeat ( 0 ) . take ( D :: DEP_KIND_MAX as usize + 1 ) . collect ( ) ,
515
537
marker : PhantomData ,
516
538
}
517
539
}
518
540
541
+ #[ inline]
542
+ fn alloc_index ( & mut self ) -> DepNodeIndex {
543
+ let index = DepNodeIndex :: new ( self . total_node_count ) ;
544
+ self . total_node_count += 1 ;
545
+ index
546
+ }
547
+
519
548
#[ inline]
520
549
fn record (
521
550
& mut self ,
522
551
node : DepNode ,
552
+ index : DepNodeIndex ,
523
553
edge_count : usize ,
524
554
edges : impl FnOnce ( & mut Self ) -> Vec < DepNodeIndex > ,
525
555
record_graph : & Option < Lock < DepGraphQuery > > ,
526
556
) -> DepNodeIndex {
527
- let index = DepNodeIndex :: new ( self . total_node_count ) ;
528
-
529
- self . total_node_count += 1 ;
530
557
self . kind_stats [ node. kind . as_usize ( ) ] += 1 ;
531
558
self . total_edge_count += edge_count;
532
559
@@ -558,14 +585,25 @@ impl<D: Deps> EncoderState<D> {
558
585
index
559
586
}
560
587
588
+ #[ inline]
589
+ fn flush_mem_encoder ( & mut self ) {
590
+ let data = & mut self . mem_encoder . data ;
591
+ if data. len ( ) > 64 * 1024 {
592
+ self . encoder . emit_raw_bytes ( & data[ ..] ) ;
593
+ data. clear ( ) ;
594
+ }
595
+ }
596
+
561
597
/// Encodes a node to the current graph.
562
598
fn encode_node (
563
599
& mut self ,
564
600
node : & NodeInfo ,
565
601
record_graph : & Option < Lock < DepGraphQuery > > ,
566
602
) -> DepNodeIndex {
567
- node. encode :: < D > ( & mut self . encoder ) ;
568
- self . record ( node. node , node. edges . len ( ) , |_| node. edges [ ..] . to_vec ( ) , record_graph)
603
+ let index = self . alloc_index ( ) ;
604
+ node. encode :: < D > ( & mut self . mem_encoder , index) ;
605
+ self . flush_mem_encoder ( ) ;
606
+ self . record ( node. node , index, node. edges . len ( ) , |_| node. edges [ ..] . to_vec ( ) , record_graph)
569
607
}
570
608
571
609
/// Encodes a node that was promoted from the previous graph. It reads the information directly from
@@ -581,20 +619,22 @@ impl<D: Deps> EncoderState<D> {
581
619
record_graph : & Option < Lock < DepGraphQuery > > ,
582
620
colors : & DepNodeColorMap ,
583
621
) -> DepNodeIndex {
622
+ let index = self . alloc_index ( ) ;
584
623
let node = self . previous . index_to_node ( prev_index) ;
585
-
586
624
let fingerprint = self . previous . fingerprint_by_index ( prev_index) ;
587
625
let edge_count = NodeInfo :: encode_promoted :: < D > (
588
- & mut self . encoder ,
626
+ & mut self . mem_encoder ,
589
627
node,
628
+ index,
590
629
fingerprint,
591
630
prev_index,
592
631
colors,
593
632
& self . previous ,
594
633
) ;
595
-
634
+ self . flush_mem_encoder ( ) ;
596
635
self . record (
597
636
node,
637
+ index,
598
638
edge_count,
599
639
|this| {
600
640
this. previous
@@ -603,12 +643,14 @@ impl<D: Deps> EncoderState<D> {
603
643
. collect ( )
604
644
} ,
605
645
record_graph,
606
- )
646
+ ) ;
647
+ index
607
648
}
608
649
609
650
fn finish ( self , profiler : & SelfProfilerRef ) -> FileEncodeResult {
610
651
let Self {
611
652
mut encoder,
653
+ mem_encoder,
612
654
total_node_count,
613
655
total_edge_count,
614
656
stats : _,
@@ -617,6 +659,8 @@ impl<D: Deps> EncoderState<D> {
617
659
previous,
618
660
} = self ;
619
661
662
+ encoder. emit_raw_bytes ( & mem_encoder. data ) ;
663
+
620
664
let node_count = total_node_count. try_into ( ) . unwrap ( ) ;
621
665
let edge_count = total_edge_count. try_into ( ) . unwrap ( ) ;
622
666
0 commit comments