@@ -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,22 +106,12 @@ 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
-
116
- // The number of edges for this node is implicitly stored in the combination of the byte
117
- // width and the length.
109
+
118
110
let bytes_per_index = header. bytes_per_index ( ) ;
119
- let len = ( end - header. start ( ) ) / bytes_per_index;
120
111
121
112
// LLVM doesn't hoist EdgeHeader::mask so we do it ourselves.
122
113
let mask = header. mask ( ) ;
123
- ( 0 ..len ) . map ( move |_| {
114
+ ( 0 ..header . num_edges ) . map ( move |_| {
124
115
// Doing this slicing in this order ensures that the first bounds check suffices for
125
116
// all the others.
126
117
let index = & raw [ ..DEP_NODE_SIZE ] ;
@@ -163,6 +154,7 @@ impl SerializedDepGraph {
163
154
#[ derive( Debug , Clone , Copy ) ]
164
155
struct EdgeHeader {
165
156
repr : usize ,
157
+ num_edges : u32 ,
166
158
}
167
159
168
160
impl EdgeHeader {
@@ -205,9 +197,14 @@ impl SerializedDepGraph {
205
197
206
198
let graph_bytes = d. len ( ) - ( 2 * IntEncodedWithFixedSize :: ENCODED_SIZE ) - d. position ( ) ;
207
199
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
+
211
208
// This estimation assumes that all of the encoded bytes are for the edge lists or for the
212
209
// fixed-size node headers. But that's not necessarily true; if any edge list has a length
213
210
// that spills out of the size we can bit-pack into SerializedNodeHeader then some of the
@@ -226,11 +223,14 @@ impl SerializedDepGraph {
226
223
let node_header =
227
224
SerializedNodeHeader :: < D > { bytes : d. read_array ( ) , _marker : PhantomData } ;
228
225
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 ( ) ;
231
232
232
- let _i: SerializedDepNodeIndex = fingerprints. push ( node_header. fingerprint ( ) ) ;
233
- debug_assert_eq ! ( _i. index( ) , _index) ;
233
+ fingerprints[ index] = node_header. fingerprint ( ) ;
234
234
235
235
// If the length of this node's edge list is small, the length is stored in the header.
236
236
// If it is not, we fall back to another decoder call.
@@ -242,12 +242,11 @@ impl SerializedDepGraph {
242
242
let edges_len_bytes = node_header. bytes_per_index ( ) * ( num_edges as usize ) ;
243
243
// The in-memory structure for the edges list stores the byte width of the edges on
244
244
// 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 ) ;
246
246
247
247
edge_list_data. extend ( d. read_raw_bytes ( edges_len_bytes) ) ;
248
248
249
- let _i: SerializedDepNodeIndex = edge_list_indices. push ( edges_header) ;
250
- debug_assert_eq ! ( _i. index( ) , _index) ;
249
+ edge_list_indices[ index] = edges_header;
251
250
}
252
251
253
252
// 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 {
298
297
/// * In whatever bits remain, the length of the edge list for this node, if it fits
299
298
struct SerializedNodeHeader < D > {
300
299
// 2 bytes for the DepNode
300
+ // 4 bytes for the index
301
301
// 16 for Fingerprint in DepNode
302
302
// 16 for Fingerprint in NodeInfo
303
- bytes : [ u8 ; 34 ] ,
303
+ bytes : [ u8 ; 38 ] ,
304
304
_marker : PhantomData < D > ,
305
305
}
306
306
@@ -310,6 +310,7 @@ struct Unpacked {
310
310
len : Option < u32 > ,
311
311
bytes_per_index : usize ,
312
312
kind : DepKind ,
313
+ index : SerializedDepNodeIndex ,
313
314
hash : PackedFingerprint ,
314
315
fingerprint : Fingerprint ,
315
316
}
@@ -331,6 +332,7 @@ impl<D: Deps> SerializedNodeHeader<D> {
331
332
#[ inline]
332
333
fn new (
333
334
node : DepNode ,
335
+ index : DepNodeIndex ,
334
336
fingerprint : Fingerprint ,
335
337
edge_max_index : u32 ,
336
338
edge_count : usize ,
@@ -352,10 +354,11 @@ impl<D: Deps> SerializedNodeHeader<D> {
352
354
let hash: Fingerprint = node. hash . into ( ) ;
353
355
354
356
// 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 ] ;
356
358
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 ( ) ) ;
359
362
360
363
#[ cfg( debug_assertions) ]
361
364
{
@@ -372,8 +375,9 @@ impl<D: Deps> SerializedNodeHeader<D> {
372
375
#[ inline]
373
376
fn unpack ( & self ) -> Unpacked {
374
377
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 ( ) ;
377
381
378
382
let kind = head & mask ( Self :: KIND_BITS ) as u16 ;
379
383
let bytes_per_index = ( head >> Self :: KIND_BITS ) & mask ( Self :: WIDTH_BITS ) as u16 ;
@@ -383,6 +387,7 @@ impl<D: Deps> SerializedNodeHeader<D> {
383
387
len : len. checked_sub ( 1 ) ,
384
388
bytes_per_index : bytes_per_index as usize + 1 ,
385
389
kind : DepKind :: new ( kind) ,
390
+ index : SerializedDepNodeIndex :: from_u32 ( index) ,
386
391
hash : Fingerprint :: from_le_bytes ( hash) . into ( ) ,
387
392
fingerprint : Fingerprint :: from_le_bytes ( fingerprint) ,
388
393
}
@@ -398,6 +403,11 @@ impl<D: Deps> SerializedNodeHeader<D> {
398
403
self . unpack ( ) . bytes_per_index
399
404
}
400
405
406
+ #[ inline]
407
+ fn index ( & self ) -> SerializedDepNodeIndex {
408
+ self . unpack ( ) . index
409
+ }
410
+
401
411
#[ inline]
402
412
fn fingerprint ( & self ) -> Fingerprint {
403
413
self . unpack ( ) . fingerprint
@@ -410,9 +420,10 @@ impl<D: Deps> SerializedNodeHeader<D> {
410
420
}
411
421
412
422
#[ inline]
413
- fn edges_header ( & self , edge_list_data : & [ u8 ] ) -> EdgeHeader {
423
+ fn edges_header ( & self , edge_list_data : & [ u8 ] , num_edges : u32 ) -> EdgeHeader {
414
424
EdgeHeader {
415
425
repr : ( edge_list_data. len ( ) << DEP_NODE_WIDTH_BITS ) | ( self . bytes_per_index ( ) - 1 ) ,
426
+ num_edges,
416
427
}
417
428
}
418
429
}
@@ -425,10 +436,15 @@ struct NodeInfo {
425
436
}
426
437
427
438
impl NodeInfo {
428
- fn encode < D : Deps > ( & self , e : & mut FileEncoder ) {
439
+ fn encode < D : Deps > ( & self , e : & mut MemEncoder , index : DepNodeIndex ) {
429
440
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
+ ) ;
432
448
e. write_array ( header. bytes ) ;
433
449
434
450
if header. len ( ) . is_none ( ) {
@@ -450,8 +466,9 @@ impl NodeInfo {
450
466
/// This avoids the overhead of constructing `EdgesVec`, which would be needed to call `encode`.
451
467
#[ inline]
452
468
fn encode_promoted < D : Deps > (
453
- e : & mut FileEncoder ,
469
+ e : & mut MemEncoder ,
454
470
node : DepNode ,
471
+ index : DepNodeIndex ,
455
472
fingerprint : Fingerprint ,
456
473
prev_index : SerializedDepNodeIndex ,
457
474
colors : & DepNodeColorMap ,
@@ -464,7 +481,7 @@ impl NodeInfo {
464
481
let edge_max =
465
482
edges. clone ( ) . map ( |i| colors. current ( i) . unwrap ( ) . as_u32 ( ) ) . max ( ) . unwrap_or ( 0 ) ;
466
483
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) ;
468
485
e. write_array ( header. bytes ) ;
469
486
470
487
if header. len ( ) . is_none ( ) {
@@ -498,6 +515,8 @@ struct EncoderState<D: Deps> {
498
515
total_edge_count : usize ,
499
516
stats : Option < FxHashMap < DepKind , Stat > > ,
500
517
518
+ mem_encoder : MemEncoder ,
519
+
501
520
/// Stores the number of times we've encoded each dep kind.
502
521
kind_stats : Vec < u32 > ,
503
522
marker : PhantomData < D > ,
@@ -511,22 +530,28 @@ impl<D: Deps> EncoderState<D> {
511
530
total_edge_count : 0 ,
512
531
total_node_count : 0 ,
513
532
stats : record_stats. then ( FxHashMap :: default) ,
533
+ mem_encoder : MemEncoder :: new ( ) ,
514
534
kind_stats : iter:: repeat ( 0 ) . take ( D :: DEP_KIND_MAX as usize + 1 ) . collect ( ) ,
515
535
marker : PhantomData ,
516
536
}
517
537
}
518
538
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
+
519
546
#[ inline]
520
547
fn record (
521
548
& mut self ,
522
549
node : DepNode ,
550
+ index : DepNodeIndex ,
523
551
edge_count : usize ,
524
552
edges : impl FnOnce ( & mut Self ) -> Vec < DepNodeIndex > ,
525
553
record_graph : & Option < Lock < DepGraphQuery > > ,
526
554
) -> DepNodeIndex {
527
- let index = DepNodeIndex :: new ( self . total_node_count ) ;
528
-
529
- self . total_node_count += 1 ;
530
555
self . kind_stats [ node. kind . as_usize ( ) ] += 1 ;
531
556
self . total_edge_count += edge_count;
532
557
@@ -558,14 +583,25 @@ impl<D: Deps> EncoderState<D> {
558
583
index
559
584
}
560
585
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
+
561
595
/// Encodes a node to the current graph.
562
596
fn encode_node (
563
597
& mut self ,
564
598
node : & NodeInfo ,
565
599
record_graph : & Option < Lock < DepGraphQuery > > ,
566
600
) -> 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)
569
605
}
570
606
571
607
/// 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> {
581
617
record_graph : & Option < Lock < DepGraphQuery > > ,
582
618
colors : & DepNodeColorMap ,
583
619
) -> DepNodeIndex {
620
+ let index = self . alloc_index ( ) ;
584
621
let node = self . previous . index_to_node ( prev_index) ;
585
-
586
622
let fingerprint = self . previous . fingerprint_by_index ( prev_index) ;
587
623
let edge_count = NodeInfo :: encode_promoted :: < D > (
588
- & mut self . encoder ,
624
+ & mut self . mem_encoder ,
589
625
node,
626
+ index,
590
627
fingerprint,
591
628
prev_index,
592
629
colors,
593
630
& self . previous ,
594
631
) ;
595
-
632
+ self . flush_mem_encoder ( ) ;
596
633
self . record (
597
634
node,
635
+ index,
598
636
edge_count,
599
637
|this| {
600
638
this. previous
@@ -603,12 +641,14 @@ impl<D: Deps> EncoderState<D> {
603
641
. collect ( )
604
642
} ,
605
643
record_graph,
606
- )
644
+ ) ;
645
+ index
607
646
}
608
647
609
648
fn finish ( self , profiler : & SelfProfilerRef ) -> FileEncodeResult {
610
649
let Self {
611
650
mut encoder,
651
+ mem_encoder,
612
652
total_node_count,
613
653
total_edge_count,
614
654
stats : _,
@@ -617,6 +657,8 @@ impl<D: Deps> EncoderState<D> {
617
657
previous,
618
658
} = self ;
619
659
660
+ encoder. emit_raw_bytes ( & mem_encoder. data ) ;
661
+
620
662
let node_count = total_node_count. try_into ( ) . unwrap ( ) ;
621
663
let edge_count = total_edge_count. try_into ( ) . unwrap ( ) ;
622
664
0 commit comments