11use crate :: QueryCtxt ;
22use rustc_data_structures:: fx:: { FxHashMap , FxHashSet , FxIndexSet } ;
33use rustc_data_structures:: memmap:: Mmap ;
4- use rustc_data_structures:: sync:: { HashMapExt , Lock , Lrc , OnceCell } ;
4+ use rustc_data_structures:: sync:: { HashMapExt , Lock , Lrc , OnceCell , RwLock } ;
55use rustc_data_structures:: unhash:: UnhashMap ;
66use rustc_hir:: def_id:: { CrateNum , DefId , DefIndex , LocalDefId , StableCrateId , LOCAL_CRATE } ;
77use rustc_hir:: definitions:: DefPathHash ;
@@ -43,7 +43,7 @@ const TAG_EXPN_DATA: u8 = 1;
4343/// any side effects that have been emitted during a query.
4444pub struct OnDiskCache < ' sess > {
4545 // The complete cache data in serialized form.
46- serialized_data : Option < Mmap > ,
46+ serialized_data : RwLock < Option < Mmap > > ,
4747
4848 // Collects all `QuerySideEffects` created during the current compilation
4949 // session.
@@ -206,7 +206,7 @@ impl<'sess> rustc_middle::ty::OnDiskCache<'sess> for OnDiskCache<'sess> {
206206 } ;
207207
208208 Self {
209- serialized_data : Some ( data) ,
209+ serialized_data : RwLock :: new ( Some ( data) ) ,
210210 file_index_to_stable_id : footer. file_index_to_stable_id ,
211211 file_index_to_file : Default :: default ( ) ,
212212 cnum_map : OnceCell :: new ( ) ,
@@ -227,7 +227,7 @@ impl<'sess> rustc_middle::ty::OnDiskCache<'sess> for OnDiskCache<'sess> {
227227
228228 fn new_empty ( source_map : & ' sess SourceMap ) -> Self {
229229 Self {
230- serialized_data : None ,
230+ serialized_data : RwLock :: new ( None ) ,
231231 file_index_to_stable_id : Default :: default ( ) ,
232232 file_index_to_file : Default :: default ( ) ,
233233 cnum_map : OnceCell :: new ( ) ,
@@ -246,7 +246,26 @@ impl<'sess> rustc_middle::ty::OnDiskCache<'sess> for OnDiskCache<'sess> {
246246 }
247247 }
248248
249- fn serialize ( & self , tcx : TyCtxt < ' sess > , encoder : & mut FileEncoder ) -> FileEncodeResult {
249+ fn drop_serialized_data ( & self , tcx : TyCtxt < ' tcx > ) {
250+ // Register any dep nodes that we reused from the previous session,
251+ // but didn't `DepNode::construct` in this session. This ensures
252+ // that their `DefPathHash` to `RawDefId` mappings are registered
253+ // in 'latest_foreign_def_path_hashes' if necessary, since that
254+ // normally happens in `DepNode::construct`.
255+ tcx. dep_graph . register_reused_dep_nodes ( tcx) ;
256+
257+ // Load everything into memory so we can write it out to the on-disk
258+ // cache. The vast majority of cacheable query results should already
259+ // be in memory, so this should be a cheap operation.
260+ // Do this *before* we clone 'latest_foreign_def_path_hashes', since
261+ // loading existing queries may cause us to create new DepNodes, which
262+ // may in turn end up invoking `store_foreign_def_id_hash`
263+ tcx. dep_graph . exec_cache_promotions ( QueryCtxt :: from_tcx ( tcx) ) ;
264+
265+ * self . serialized_data . write ( ) = None ;
266+ }
267+
268+ fn serialize < ' tcx > ( & self , tcx : TyCtxt < ' tcx > , encoder : & mut FileEncoder ) -> FileEncodeResult {
250269 // Serializing the `DepGraph` should not modify it.
251270 tcx. dep_graph . with_ignore ( || {
252271 // Allocate `SourceFileIndex`es.
@@ -268,21 +287,6 @@ impl<'sess> rustc_middle::ty::OnDiskCache<'sess> for OnDiskCache<'sess> {
268287 ( file_to_file_index, file_index_to_stable_id)
269288 } ;
270289
271- // Register any dep nodes that we reused from the previous session,
272- // but didn't `DepNode::construct` in this session. This ensures
273- // that their `DefPathHash` to `RawDefId` mappings are registered
274- // in 'latest_foreign_def_path_hashes' if necessary, since that
275- // normally happens in `DepNode::construct`.
276- tcx. dep_graph . register_reused_dep_nodes ( tcx) ;
277-
278- // Load everything into memory so we can write it out to the on-disk
279- // cache. The vast majority of cacheable query results should already
280- // be in memory, so this should be a cheap operation.
281- // Do this *before* we clone 'latest_foreign_def_path_hashes', since
282- // loading existing queries may cause us to create new DepNodes, which
283- // may in turn end up invoking `store_foreign_def_id_hash`
284- tcx. dep_graph . exec_cache_promotions ( QueryCtxt :: from_tcx ( tcx) ) ;
285-
286290 let latest_foreign_def_path_hashes = self . latest_foreign_def_path_hashes . lock ( ) . clone ( ) ;
287291 let hygiene_encode_context = HygieneEncodeContext :: default ( ) ;
288292
@@ -566,7 +570,7 @@ impl<'sess> OnDiskCache<'sess> {
566570 } )
567571 }
568572
569- fn with_decoder < ' a , ' tcx , T , F : FnOnce ( & mut CacheDecoder < ' sess , ' tcx > ) -> T > (
573+ fn with_decoder < ' a , ' tcx , T , F : for < ' s > FnOnce ( & mut CacheDecoder < ' s , ' tcx > ) -> T > (
570574 & ' sess self ,
571575 tcx : TyCtxt < ' tcx > ,
572576 pos : AbsoluteBytePos ,
@@ -577,12 +581,10 @@ impl<'sess> OnDiskCache<'sess> {
577581 {
578582 let cnum_map = self . cnum_map . get_or_init ( || Self :: compute_cnum_map ( tcx) ) ;
579583
584+ let serialized_data = self . serialized_data . read ( ) ;
580585 let mut decoder = CacheDecoder {
581586 tcx,
582- opaque : opaque:: Decoder :: new (
583- self . serialized_data . as_deref ( ) . unwrap_or ( & [ ] ) ,
584- pos. to_usize ( ) ,
585- ) ,
587+ opaque : opaque:: Decoder :: new ( serialized_data. as_deref ( ) . unwrap_or ( & [ ] ) , pos. to_usize ( ) ) ,
586588 source_map : self . source_map ,
587589 cnum_map,
588590 file_index_to_file : & self . file_index_to_file ,
0 commit comments