@@ -76,12 +76,11 @@ pub struct OnDiskCache<'sess> {
7676 // `serialized_data`.
7777 prev_diagnostics_index : FxHashMap < SerializedDepNodeIndex , AbsoluteBytePos > ,
7878
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 > ,
8181
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 > > ,
8584}
8685
8786// This type is used only for (de-)serialization.
@@ -91,6 +90,8 @@ struct Footer {
9190 prev_cnums : Vec < ( u32 , String , CrateDisambiguator ) > ,
9291 query_result_index : EncodedQueryResultIndex ,
9392 diagnostics_index : EncodedQueryResultIndex ,
93+ // the location of all allocations
94+ interpret_alloc_index : Vec < AbsoluteBytePos > ,
9495}
9596
9697type EncodedQueryResultIndex = Vec < ( SerializedDepNodeIndex , AbsoluteBytePos ) > ;
@@ -147,8 +148,8 @@ impl<'sess> OnDiskCache<'sess> {
147148 query_result_index : footer. query_result_index . into_iter ( ) . collect ( ) ,
148149 prev_diagnostics_index : footer. diagnostics_index . into_iter ( ) . collect ( ) ,
149150 synthetic_expansion_infos : RefCell :: new ( FxHashMap ( ) ) ,
151+ prev_interpret_alloc_index : footer. interpret_alloc_index ,
150152 interpret_alloc_cache : RefCell :: new ( FxHashMap :: default ( ) ) ,
151- interpret_alloc_size : RefCell :: new ( FxHashMap :: default ( ) ) ,
152153 }
153154 }
154155
@@ -164,8 +165,8 @@ impl<'sess> OnDiskCache<'sess> {
164165 query_result_index : FxHashMap ( ) ,
165166 prev_diagnostics_index : FxHashMap ( ) ,
166167 synthetic_expansion_infos : RefCell :: new ( FxHashMap ( ) ) ,
168+ prev_interpret_alloc_index : Vec :: new ( ) ,
167169 interpret_alloc_cache : RefCell :: new ( FxHashMap :: default ( ) ) ,
168- interpret_alloc_size : RefCell :: new ( FxHashMap :: default ( ) ) ,
169170 }
170171 }
171172
@@ -198,7 +199,9 @@ impl<'sess> OnDiskCache<'sess> {
198199 type_shorthands : FxHashMap ( ) ,
199200 predicate_shorthands : FxHashMap ( ) ,
200201 expn_info_shorthands : FxHashMap ( ) ,
201- interpret_alloc_shorthands : FxHashMap ( ) ,
202+ interpret_allocs : FxHashMap ( ) ,
203+ interpret_alloc_ids : FxHashSet ( ) ,
204+ interpret_allocs_inverse : Vec :: new ( ) ,
202205 codemap : CachingCodemapView :: new ( tcx. sess . codemap ( ) ) ,
203206 file_to_file_index,
204207 } ;
@@ -272,6 +275,31 @@ impl<'sess> OnDiskCache<'sess> {
272275 diagnostics_index
273276 } ;
274277
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+
275303 let sorted_cnums = sorted_cnums_including_local_crate ( tcx) ;
276304 let prev_cnums: Vec < _ > = sorted_cnums. iter ( ) . map ( |& cnum| {
277305 let crate_name = tcx. original_crate_name ( cnum) . as_str ( ) . to_string ( ) ;
@@ -286,6 +314,7 @@ impl<'sess> OnDiskCache<'sess> {
286314 prev_cnums,
287315 query_result_index,
288316 diagnostics_index,
317+ interpret_alloc_index,
289318 } ) ?;
290319
291320 // Encode the position of the footer as the last 8 bytes of the
@@ -393,8 +422,8 @@ impl<'sess> OnDiskCache<'sess> {
393422 file_index_to_file : & self . file_index_to_file ,
394423 file_index_to_stable_id : & self . file_index_to_stable_id ,
395424 synthetic_expansion_infos : & self . synthetic_expansion_infos ,
425+ prev_interpret_alloc_index : & self . prev_interpret_alloc_index ,
396426 interpret_alloc_cache : & self . interpret_alloc_cache ,
397- interpret_alloc_size : & self . interpret_alloc_size ,
398427 } ;
399428
400429 match decode_tagged ( & mut decoder, dep_node_index) {
@@ -457,7 +486,8 @@ struct CacheDecoder<'a, 'tcx: 'a, 'x> {
457486 file_index_to_file : & ' x RefCell < FxHashMap < FileMapIndex , Lrc < FileMap > > > ,
458487 file_index_to_stable_id : & ' x FxHashMap < FileMapIndex , StableFilemapId > ,
459488 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 ] ,
461491}
462492
463493impl < ' a , ' tcx , ' x > CacheDecoder < ' a , ' tcx , ' x > {
@@ -580,36 +610,29 @@ implement_ty_decoder!( CacheDecoder<'a, 'tcx, 'x> );
580610impl < ' a , ' tcx , ' x > SpecializedDecoder < interpret:: AllocId > for CacheDecoder < ' a , ' tcx , ' x > {
581611 fn specialized_decode ( & mut self ) -> Result < interpret:: AllocId , Self :: Error > {
582612 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) ;
594619 }
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+ } )
613636 }
614637}
615638impl < ' a , ' tcx , ' x > SpecializedDecoder < Span > for CacheDecoder < ' a , ' tcx , ' x > {
@@ -773,7 +796,9 @@ struct CacheEncoder<'enc, 'a, 'tcx, E>
773796 type_shorthands : FxHashMap < ty:: Ty < ' tcx > , usize > ,
774797 predicate_shorthands : FxHashMap < ty:: Predicate < ' tcx > , usize > ,
775798 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 > ,
777802 codemap : CachingCodemapView < ' tcx > ,
778803 file_to_file_index : FxHashMap < * const FileMap , FileMapIndex > ,
779804}
@@ -810,27 +835,17 @@ impl<'enc, 'a, 'tcx, E> SpecializedEncoder<interpret::AllocId> for CacheEncoder<
810835 where E : ' enc + ty_codec:: TyEncoder
811836{
812837 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]
827846 } ;
828- interpret:: specialized_encode_alloc_id (
829- self ,
830- tcx,
831- * alloc_id,
832- shorthand,
833- )
847+
848+ index. encode ( self )
834849 }
835850}
836851
0 commit comments