@@ -121,7 +121,7 @@ impl SerializedDepGraph {
121121 pub fn edge_targets_from (
122122 & self ,
123123 source : SerializedDepNodeIndex ,
124- ) -> impl Iterator < Item = SerializedDepNodeIndex > + ' _ {
124+ ) -> impl Iterator < Item = SerializedDepNodeIndex > + Clone + ' _ {
125125 let header = self . edge_list_indices [ source] ;
126126 let mut raw = & self . edge_list_data [ header. start ( ) ..] ;
127127 // Figure out where the edge list for `source` ends by getting the start index of the next
@@ -393,21 +393,24 @@ impl<D: Deps> SerializedNodeHeader<D> {
393393 const MAX_INLINE_LEN : usize = ( u16:: MAX as usize >> ( Self :: TOTAL_BITS - Self :: LEN_BITS ) ) - 1 ;
394394
395395 #[ inline]
396- fn new ( node_info : & NodeInfo ) -> Self {
396+ fn new (
397+ node : DepNode ,
398+ fingerprint : Fingerprint ,
399+ edge_max_index : u32 ,
400+ edge_count : usize ,
401+ ) -> Self {
397402 debug_assert_eq ! ( Self :: TOTAL_BITS , Self :: LEN_BITS + Self :: WIDTH_BITS + Self :: KIND_BITS ) ;
398403
399- let NodeInfo { node, fingerprint, edges } = node_info;
400-
401404 let mut head = node. kind . as_inner ( ) ;
402405
403- let free_bytes = edges . max_index ( ) . leading_zeros ( ) as usize / 8 ;
406+ let free_bytes = edge_max_index . leading_zeros ( ) as usize / 8 ;
404407 let bytes_per_index = ( DEP_NODE_SIZE - free_bytes) . saturating_sub ( 1 ) ;
405408 head |= ( bytes_per_index as u16 ) << Self :: KIND_BITS ;
406409
407410 // Encode number of edges + 1 so that we can reserve 0 to indicate that the len doesn't fit
408411 // in this bitfield.
409- if edges . len ( ) <= Self :: MAX_INLINE_LEN {
410- head |= ( edges . len ( ) as u16 + 1 ) << ( Self :: KIND_BITS + Self :: WIDTH_BITS ) ;
412+ if edge_count <= Self :: MAX_INLINE_LEN {
413+ head |= ( edge_count as u16 + 1 ) << ( Self :: KIND_BITS + Self :: WIDTH_BITS ) ;
411414 }
412415
413416 let hash: Fingerprint = node. hash . into ( ) ;
@@ -421,10 +424,10 @@ impl<D: Deps> SerializedNodeHeader<D> {
421424 #[ cfg( debug_assertions) ]
422425 {
423426 let res = Self { bytes, _marker : PhantomData } ;
424- assert_eq ! ( node_info . fingerprint, res. fingerprint( ) ) ;
425- assert_eq ! ( node_info . node, res. node( ) ) ;
427+ assert_eq ! ( fingerprint, res. fingerprint( ) ) ;
428+ assert_eq ! ( node, res. node( ) ) ;
426429 if let Some ( len) = res. len ( ) {
427- assert_eq ! ( node_info . edges . len ( ) , len) ;
430+ assert_eq ! ( edge_count , len) ;
428431 }
429432 }
430433 Self { bytes, _marker : PhantomData }
@@ -487,20 +490,55 @@ struct NodeInfo {
487490
488491impl NodeInfo {
489492 fn encode < D : Deps > ( & self , e : & mut FileEncoder ) {
490- let header = SerializedNodeHeader :: < D > :: new ( self ) ;
493+ let NodeInfo { node, fingerprint, ref edges } = * self ;
494+ let header =
495+ SerializedNodeHeader :: < D > :: new ( node, fingerprint, edges. max_index ( ) , edges. len ( ) ) ;
496+ e. write_array ( header. bytes ) ;
497+
498+ if header. len ( ) . is_none ( ) {
499+ e. emit_usize ( edges. len ( ) ) ;
500+ }
501+
502+ let bytes_per_index = header. bytes_per_index ( ) ;
503+ for node_index in edges. iter ( ) {
504+ e. write_with ( |dest| {
505+ * dest = node_index. as_u32 ( ) . to_le_bytes ( ) ;
506+ bytes_per_index
507+ } ) ;
508+ }
509+ }
510+
511+ #[ inline]
512+ fn encode_promoted < D : Deps > (
513+ e : & mut FileEncoder ,
514+ node : DepNode ,
515+ fingerprint : Fingerprint ,
516+ prev_index : SerializedDepNodeIndex ,
517+ prev_index_to_index : & mut IndexVec < SerializedDepNodeIndex , Option < DepNodeIndex > > ,
518+ previous : & SerializedDepGraph ,
519+ ) -> usize {
520+ let edges = previous. edge_targets_from ( prev_index) ;
521+ let edge_count = edges. size_hint ( ) . 0 ;
522+ let edge_max =
523+ edges. clone ( ) . map ( |i| prev_index_to_index[ i] . unwrap ( ) . as_u32 ( ) ) . max ( ) . unwrap_or ( 0 ) ;
524+
525+ let header = SerializedNodeHeader :: < D > :: new ( node, fingerprint, edge_max, edge_count) ;
491526 e. write_array ( header. bytes ) ;
492527
493528 if header. len ( ) . is_none ( ) {
494- e. emit_usize ( self . edges . len ( ) ) ;
529+ e. emit_usize ( edge_count ) ;
495530 }
496531
497532 let bytes_per_index = header. bytes_per_index ( ) ;
498- for node_index in self . edges . iter ( ) {
533+ for node_index in edges {
534+ let node_index = prev_index_to_index[ node_index] . unwrap ( ) ;
499535 e. write_with ( |dest| {
500536 * dest = node_index. as_u32 ( ) . to_le_bytes ( ) ;
501537 bytes_per_index
502538 } ) ;
503539 }
540+
541+ edge_count
504542 }
505543}
506544
@@ -511,6 +549,7 @@ struct Stat {
511549}
512550
513551struct EncoderState < D : Deps > {
552+ previous : Arc < SerializedDepGraph > ,
514553 encoder : FileEncoder ,
515554 total_node_count : usize ,
516555 total_edge_count : usize ,
@@ -522,8 +561,9 @@ struct EncoderState<D: Deps> {
522561}
523562
524563impl < D : Deps > EncoderState < D > {
525- fn new ( encoder : FileEncoder , record_stats : bool ) -> Self {
564+ fn new ( encoder : FileEncoder , record_stats : bool , previous : Arc < SerializedDepGraph > ) -> Self {
526565 Self {
566+ previous,
527567 encoder,
528568 total_edge_count : 0 ,
529569 total_node_count : 0 ,
@@ -533,38 +573,90 @@ impl<D: Deps> EncoderState<D> {
533573 }
534574 }
535575
536- fn encode_node (
576+ #[ inline]
577+ fn record (
537578 & mut self ,
538- node : & NodeInfo ,
579+ node : DepNode ,
580+ edge_count : usize ,
581+ edges : impl FnOnce ( & mut Self ) -> Vec < DepNodeIndex > ,
539582 record_graph : & Option < Lock < DepGraphQuery > > ,
540583 ) -> DepNodeIndex {
541584 let index = DepNodeIndex :: new ( self . total_node_count ) ;
542- self . total_node_count += 1 ;
543- self . kind_stats [ node. node . kind . as_usize ( ) ] += 1 ;
544585
545- let edge_count = node. edges . len ( ) ;
586+ self . total_node_count += 1 ;
587+ self . kind_stats [ node. kind . as_usize ( ) ] += 1 ;
546588 self . total_edge_count += edge_count;
547589
548590 if let Some ( record_graph) = & record_graph {
549- // Do not ICE when a query is called from within `with_query`.
550- if let Some ( record_graph) = & mut record_graph. try_lock ( ) {
551- record_graph. push ( index, node. node , & node. edges ) ;
552- }
591+ let edges = edges ( self ) ;
592+ outline ( move || {
593+ // Do not ICE when a query is called from within `with_query`.
594+ if let Some ( record_graph) = & mut record_graph. try_lock ( ) {
595+ record_graph. push ( index, node, & edges) ;
596+ }
597+ } ) ;
553598 }
554599
555600 if let Some ( stats) = & mut self . stats {
556- let kind = node. node . kind ;
601+ let kind = node. kind ;
557602
558- let stat = stats. entry ( kind) . or_insert ( Stat { kind, node_counter : 0 , edge_counter : 0 } ) ;
559- stat. node_counter += 1 ;
560- stat. edge_counter += edge_count as u64 ;
603+ outline ( move || {
604+ let stat =
605+ stats. entry ( kind) . or_insert ( Stat { kind, node_counter : 0 , edge_counter : 0 } ) ;
606+ stat. node_counter += 1 ;
607+ stat. edge_counter += edge_count as u64 ;
608+ } ) ;
561609 }
562610
563- let encoder = & mut self . encoder ;
564- node. encode :: < D > ( encoder) ;
565611 index
566612 }
567613
614+ fn encode_node (
615+ & mut self ,
616+ node : & NodeInfo ,
617+ record_graph : & Option < Lock < DepGraphQuery > > ,
618+ ) -> DepNodeIndex {
619+ node. encode :: < D > ( & mut self . encoder ) ;
620+ self . record (
621+ node. node ,
622+ node. edges . len ( ) ,
623+ |_| node. edges [ ..] . iter ( ) . copied ( ) . collect ( ) ,
624+ record_graph,
625+ )
626+ }
627+
628+ #[ inline]
629+ fn promote_node (
630+ & mut self ,
631+ prev_index : SerializedDepNodeIndex ,
632+ record_graph : & Option < Lock < DepGraphQuery > > ,
633+ prev_index_to_index : & mut IndexVec < SerializedDepNodeIndex , Option < DepNodeIndex > > ,
634+ ) -> DepNodeIndex {
635+ let node = self . previous . index_to_node ( prev_index) ;
636+
637+ let fingerprint = self . previous . fingerprint_by_index ( prev_index) ;
638+ let edge_count = NodeInfo :: encode_promoted :: < D > (
639+ & mut self . encoder ,
640+ node,
641+ fingerprint,
642+ prev_index,
643+ prev_index_to_index,
644+ & self . previous ,
645+ ) ;
646+
647+ self . record (
648+ node,
649+ edge_count,
650+ |this| {
651+ this. previous
652+ . edge_targets_from ( prev_index)
653+ . map ( |i| prev_index_to_index[ i] . unwrap ( ) )
654+ . collect ( )
655+ } ,
656+ record_graph,
657+ )
658+ }
659+
568660 fn finish ( self , profiler : & SelfProfilerRef ) -> FileEncodeResult {
569661 let Self {
570662 mut encoder,
@@ -573,6 +665,7 @@ impl<D: Deps> EncoderState<D> {
573665 stats : _,
574666 kind_stats,
575667 marker : _,
668+ previous : _,
576669 } = self ;
577670
578671 let node_count = total_node_count. try_into ( ) . unwrap ( ) ;
@@ -612,9 +705,10 @@ impl<D: Deps> GraphEncoder<D> {
612705 record_graph : bool ,
613706 record_stats : bool ,
614707 profiler : & SelfProfilerRef ,
708+ previous : Arc < SerializedDepGraph > ,
615709 ) -> Self {
616710 let record_graph = record_graph. then ( || Lock :: new ( DepGraphQuery :: new ( prev_node_count) ) ) ;
617- let status = Lock :: new ( Some ( EncoderState :: new ( encoder, record_stats) ) ) ;
711+ let status = Lock :: new ( Some ( EncoderState :: new ( encoder, record_stats, previous ) ) ) ;
618712 GraphEncoder { status, record_graph, profiler : profiler. clone ( ) }
619713 }
620714
@@ -688,6 +782,20 @@ impl<D: Deps> GraphEncoder<D> {
688782 self . status . lock ( ) . as_mut ( ) . unwrap ( ) . encode_node ( & node, & self . record_graph )
689783 }
690784
785+ #[ inline]
786+ pub ( crate ) fn promote (
787+ & self ,
788+ prev_index : SerializedDepNodeIndex ,
789+ prev_index_to_index : & mut IndexVec < SerializedDepNodeIndex , Option < DepNodeIndex > > ,
790+ ) -> DepNodeIndex {
791+ let _prof_timer = self . profiler . generic_activity ( "incr_comp_encode_dep_graph" ) ;
792+ self . status . lock ( ) . as_mut ( ) . unwrap ( ) . promote_node (
793+ prev_index,
794+ & self . record_graph ,
795+ prev_index_to_index,
796+ )
797+ }
798+
691799 pub fn finish ( & self ) -> FileEncodeResult {
692800 let _prof_timer = self . profiler . generic_activity ( "incr_comp_encode_dep_graph_finish" ) ;
693801
0 commit comments