@@ -76,12 +76,11 @@ pub struct OnDiskCache<'sess> {
76
76
// `serialized_data`.
77
77
prev_diagnostics_index : FxHashMap < SerializedDepNodeIndex , AbsoluteBytePos > ,
78
78
79
- // A cache to ensure we don't read allocations twice
80
- interpret_alloc_cache : RefCell < FxHashMap < usize , interpret :: AllocId > > ,
79
+ // Alloc indices to memory location map
80
+ prev_interpret_alloc_index : Vec < AbsoluteBytePos > ,
81
81
82
- // A map from positions to size of the serialized allocation
83
- // so we can skip over already processed allocations
84
- interpret_alloc_size : RefCell < FxHashMap < usize , usize > > ,
82
+ /// Deserialization: A cache to ensure we don't read allocations twice
83
+ interpret_alloc_cache : RefCell < FxHashMap < usize , interpret:: AllocId > > ,
85
84
}
86
85
87
86
// This type is used only for (de-)serialization.
@@ -91,6 +90,8 @@ struct Footer {
91
90
prev_cnums : Vec < ( u32 , String , CrateDisambiguator ) > ,
92
91
query_result_index : EncodedQueryResultIndex ,
93
92
diagnostics_index : EncodedQueryResultIndex ,
93
+ // the location of all allocations
94
+ interpret_alloc_index : Vec < AbsoluteBytePos > ,
94
95
}
95
96
96
97
type EncodedQueryResultIndex = Vec < ( SerializedDepNodeIndex , AbsoluteBytePos ) > ;
@@ -147,8 +148,8 @@ impl<'sess> OnDiskCache<'sess> {
147
148
query_result_index : footer. query_result_index . into_iter ( ) . collect ( ) ,
148
149
prev_diagnostics_index : footer. diagnostics_index . into_iter ( ) . collect ( ) ,
149
150
synthetic_expansion_infos : RefCell :: new ( FxHashMap ( ) ) ,
151
+ prev_interpret_alloc_index : footer. interpret_alloc_index ,
150
152
interpret_alloc_cache : RefCell :: new ( FxHashMap :: default ( ) ) ,
151
- interpret_alloc_size : RefCell :: new ( FxHashMap :: default ( ) ) ,
152
153
}
153
154
}
154
155
@@ -164,8 +165,8 @@ impl<'sess> OnDiskCache<'sess> {
164
165
query_result_index : FxHashMap ( ) ,
165
166
prev_diagnostics_index : FxHashMap ( ) ,
166
167
synthetic_expansion_infos : RefCell :: new ( FxHashMap ( ) ) ,
168
+ prev_interpret_alloc_index : Vec :: new ( ) ,
167
169
interpret_alloc_cache : RefCell :: new ( FxHashMap :: default ( ) ) ,
168
- interpret_alloc_size : RefCell :: new ( FxHashMap :: default ( ) ) ,
169
170
}
170
171
}
171
172
@@ -198,7 +199,9 @@ impl<'sess> OnDiskCache<'sess> {
198
199
type_shorthands : FxHashMap ( ) ,
199
200
predicate_shorthands : FxHashMap ( ) ,
200
201
expn_info_shorthands : FxHashMap ( ) ,
201
- interpret_alloc_shorthands : FxHashMap ( ) ,
202
+ interpret_allocs : FxHashMap ( ) ,
203
+ interpret_alloc_ids : FxHashSet ( ) ,
204
+ interpret_allocs_inverse : Vec :: new ( ) ,
202
205
codemap : CachingCodemapView :: new ( tcx. sess . codemap ( ) ) ,
203
206
file_to_file_index,
204
207
} ;
@@ -272,6 +275,31 @@ impl<'sess> OnDiskCache<'sess> {
272
275
diagnostics_index
273
276
} ;
274
277
278
+ let interpret_alloc_index = {
279
+ let mut interpret_alloc_index = Vec :: new ( ) ;
280
+ let mut n = 0 ;
281
+ loop {
282
+ let new_n = encoder. interpret_alloc_ids . len ( ) ;
283
+ for idx in n..new_n {
284
+ let id = encoder. interpret_allocs_inverse [ idx] ;
285
+ let pos = AbsoluteBytePos :: new ( encoder. position ( ) ) ;
286
+ interpret_alloc_index. push ( pos) ;
287
+ interpret:: specialized_encode_alloc_id (
288
+ & mut encoder,
289
+ tcx,
290
+ id,
291
+ ) ?;
292
+ }
293
+ // if we have found new ids, serialize those, too
294
+ if n == new_n {
295
+ // otherwise, abort
296
+ break ;
297
+ }
298
+ n = new_n;
299
+ }
300
+ interpret_alloc_index
301
+ } ;
302
+
275
303
let sorted_cnums = sorted_cnums_including_local_crate ( tcx) ;
276
304
let prev_cnums: Vec < _ > = sorted_cnums. iter ( ) . map ( |& cnum| {
277
305
let crate_name = tcx. original_crate_name ( cnum) . as_str ( ) . to_string ( ) ;
@@ -286,6 +314,7 @@ impl<'sess> OnDiskCache<'sess> {
286
314
prev_cnums,
287
315
query_result_index,
288
316
diagnostics_index,
317
+ interpret_alloc_index,
289
318
} ) ?;
290
319
291
320
// Encode the position of the footer as the last 8 bytes of the
@@ -393,8 +422,8 @@ impl<'sess> OnDiskCache<'sess> {
393
422
file_index_to_file : & self . file_index_to_file ,
394
423
file_index_to_stable_id : & self . file_index_to_stable_id ,
395
424
synthetic_expansion_infos : & self . synthetic_expansion_infos ,
425
+ prev_interpret_alloc_index : & self . prev_interpret_alloc_index ,
396
426
interpret_alloc_cache : & self . interpret_alloc_cache ,
397
- interpret_alloc_size : & self . interpret_alloc_size ,
398
427
} ;
399
428
400
429
match decode_tagged ( & mut decoder, dep_node_index) {
@@ -457,7 +486,8 @@ struct CacheDecoder<'a, 'tcx: 'a, 'x> {
457
486
file_index_to_file : & ' x RefCell < FxHashMap < FileMapIndex , Lrc < FileMap > > > ,
458
487
file_index_to_stable_id : & ' x FxHashMap < FileMapIndex , StableFilemapId > ,
459
488
interpret_alloc_cache : & ' x RefCell < FxHashMap < usize , interpret:: AllocId > > ,
460
- interpret_alloc_size : & ' x RefCell < FxHashMap < usize , usize > > ,
489
+ /// maps from index in the cache file to location in the cache file
490
+ prev_interpret_alloc_index : & ' x [ AbsoluteBytePos ] ,
461
491
}
462
492
463
493
impl < ' a , ' tcx , ' x > CacheDecoder < ' a , ' tcx , ' x > {
@@ -580,36 +610,29 @@ implement_ty_decoder!( CacheDecoder<'a, 'tcx, 'x> );
580
610
impl < ' a , ' tcx , ' x > SpecializedDecoder < interpret:: AllocId > for CacheDecoder < ' a , ' tcx , ' x > {
581
611
fn specialized_decode ( & mut self ) -> Result < interpret:: AllocId , Self :: Error > {
582
612
let tcx = self . tcx ;
583
- let pos = TyDecoder :: position ( self ) ;
584
- trace ! ( "specialized_decode_alloc_id: {:?}" , pos) ;
585
- if let Some ( cached) = self . interpret_alloc_cache . borrow ( ) . get ( & pos) . cloned ( ) {
586
- // if there's no end position we are currently deserializing a recursive
587
- // allocation
588
- if let Some ( end) = self . interpret_alloc_size . borrow ( ) . get ( & pos) . cloned ( ) {
589
- trace ! ( "{} already cached as {:?}" , pos, cached) ;
590
- // skip ahead
591
- self . opaque . set_position ( end) ;
592
- return Ok ( cached)
593
- }
613
+ let idx = usize:: decode ( self ) ?;
614
+ trace ! ( "loading index {}" , idx) ;
615
+
616
+ if let Some ( cached) = self . interpret_alloc_cache . borrow ( ) . get ( & idx) . cloned ( ) {
617
+ trace ! ( "loading alloc id {:?} from alloc_cache" , cached) ;
618
+ return Ok ( cached) ;
594
619
}
595
- let id = interpret:: specialized_decode_alloc_id (
596
- self ,
597
- tcx,
598
- pos,
599
- |this, pos, alloc_id| {
600
- assert ! ( this. interpret_alloc_cache. borrow_mut( ) . insert( pos, alloc_id) . is_none( ) ) ;
601
- } ,
602
- |this, shorthand| {
603
- // need to load allocation
604
- this. with_position ( shorthand, |this| interpret:: AllocId :: decode ( this) )
605
- }
606
- ) ?;
607
- assert ! ( self
608
- . interpret_alloc_size
609
- . borrow_mut( )
610
- . insert( pos, TyDecoder :: position( self ) )
611
- . is_none( ) ) ;
612
- Ok ( id)
620
+ let pos = self . prev_interpret_alloc_index [ idx] . to_usize ( ) ;
621
+ trace ! ( "loading position {}" , pos) ;
622
+ self . with_position ( pos, |this| {
623
+ interpret:: specialized_decode_alloc_id (
624
+ this,
625
+ tcx,
626
+ |this, alloc_id| {
627
+ trace ! ( "caching idx {} for alloc id {} at position {}" , idx, alloc_id, pos) ;
628
+ assert ! ( this
629
+ . interpret_alloc_cache
630
+ . borrow_mut( )
631
+ . insert( idx, alloc_id)
632
+ . is_none( ) ) ;
633
+ } ,
634
+ )
635
+ } )
613
636
}
614
637
}
615
638
impl < ' a , ' tcx , ' x > SpecializedDecoder < Span > for CacheDecoder < ' a , ' tcx , ' x > {
@@ -773,7 +796,9 @@ struct CacheEncoder<'enc, 'a, 'tcx, E>
773
796
type_shorthands : FxHashMap < ty:: Ty < ' tcx > , usize > ,
774
797
predicate_shorthands : FxHashMap < ty:: Predicate < ' tcx > , usize > ,
775
798
expn_info_shorthands : FxHashMap < Mark , AbsoluteBytePos > ,
776
- interpret_alloc_shorthands : FxHashMap < interpret:: AllocId , usize > ,
799
+ interpret_allocs : FxHashMap < interpret:: AllocId , usize > ,
800
+ interpret_allocs_inverse : Vec < interpret:: AllocId > ,
801
+ interpret_alloc_ids : FxHashSet < interpret:: AllocId > ,
777
802
codemap : CachingCodemapView < ' tcx > ,
778
803
file_to_file_index : FxHashMap < * const FileMap , FileMapIndex > ,
779
804
}
@@ -810,27 +835,17 @@ impl<'enc, 'a, 'tcx, E> SpecializedEncoder<interpret::AllocId> for CacheEncoder<
810
835
where E : ' enc + ty_codec:: TyEncoder
811
836
{
812
837
fn specialized_encode ( & mut self , alloc_id : & interpret:: AllocId ) -> Result < ( ) , Self :: Error > {
813
- use std:: collections:: hash_map:: Entry ;
814
- let tcx = self . tcx ;
815
- let pos = self . position ( ) ;
816
- let shorthand = match self . interpret_alloc_shorthands . entry ( * alloc_id) {
817
- Entry :: Occupied ( entry) => Some ( entry. get ( ) . clone ( ) ) ,
818
- Entry :: Vacant ( entry) => {
819
- // ensure that we don't place any AllocIds at the very beginning
820
- // of the metadata file, because that would end up making our indices
821
- // not special. It is essentially impossible for that to happen,
822
- // but let's make sure
823
- assert ! ( pos >= interpret:: SHORTHAND_START ) ;
824
- entry. insert ( pos) ;
825
- None
826
- } ,
838
+ let index = if self . interpret_alloc_ids . insert ( * alloc_id) {
839
+ let idx = self . interpret_alloc_ids . len ( ) - 1 ;
840
+ assert_eq ! ( idx, self . interpret_allocs_inverse. len( ) ) ;
841
+ self . interpret_allocs_inverse . push ( * alloc_id) ;
842
+ assert ! ( self . interpret_allocs. insert( * alloc_id, idx) . is_none( ) ) ;
843
+ idx
844
+ } else {
845
+ self . interpret_allocs [ alloc_id]
827
846
} ;
828
- interpret:: specialized_encode_alloc_id (
829
- self ,
830
- tcx,
831
- * alloc_id,
832
- shorthand,
833
- )
847
+
848
+ index. encode ( self )
834
849
}
835
850
}
836
851
0 commit comments