1
1
use crate :: QueryCtxt ;
2
2
use rustc_data_structures:: fx:: { FxHashMap , FxHashSet , FxIndexSet } ;
3
3
use 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 } ;
5
5
use rustc_data_structures:: unhash:: UnhashMap ;
6
6
use rustc_hir:: def_id:: { CrateNum , DefId , DefIndex , LocalDefId , StableCrateId , LOCAL_CRATE } ;
7
7
use rustc_hir:: definitions:: DefPathHash ;
@@ -43,7 +43,7 @@ const TAG_EXPN_DATA: u8 = 1;
43
43
/// any side effects that have been emitted during a query.
44
44
pub struct OnDiskCache < ' sess > {
45
45
// The complete cache data in serialized form.
46
- serialized_data : Option < Mmap > ,
46
+ serialized_data : RwLock < Option < Mmap > > ,
47
47
48
48
// Collects all `QuerySideEffects` created during the current compilation
49
49
// session.
@@ -206,7 +206,7 @@ impl<'sess> rustc_middle::ty::OnDiskCache<'sess> for OnDiskCache<'sess> {
206
206
} ;
207
207
208
208
Self {
209
- serialized_data : Some ( data) ,
209
+ serialized_data : RwLock :: new ( Some ( data) ) ,
210
210
file_index_to_stable_id : footer. file_index_to_stable_id ,
211
211
file_index_to_file : Default :: default ( ) ,
212
212
cnum_map : OnceCell :: new ( ) ,
@@ -227,7 +227,7 @@ impl<'sess> rustc_middle::ty::OnDiskCache<'sess> for OnDiskCache<'sess> {
227
227
228
228
fn new_empty ( source_map : & ' sess SourceMap ) -> Self {
229
229
Self {
230
- serialized_data : None ,
230
+ serialized_data : RwLock :: new ( None ) ,
231
231
file_index_to_stable_id : Default :: default ( ) ,
232
232
file_index_to_file : Default :: default ( ) ,
233
233
cnum_map : OnceCell :: new ( ) ,
@@ -246,7 +246,26 @@ impl<'sess> rustc_middle::ty::OnDiskCache<'sess> for OnDiskCache<'sess> {
246
246
}
247
247
}
248
248
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 {
250
269
// Serializing the `DepGraph` should not modify it.
251
270
tcx. dep_graph . with_ignore ( || {
252
271
// Allocate `SourceFileIndex`es.
@@ -268,21 +287,6 @@ impl<'sess> rustc_middle::ty::OnDiskCache<'sess> for OnDiskCache<'sess> {
268
287
( file_to_file_index, file_index_to_stable_id)
269
288
} ;
270
289
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
-
286
290
let latest_foreign_def_path_hashes = self . latest_foreign_def_path_hashes . lock ( ) . clone ( ) ;
287
291
let hygiene_encode_context = HygieneEncodeContext :: default ( ) ;
288
292
@@ -566,7 +570,7 @@ impl<'sess> OnDiskCache<'sess> {
566
570
} )
567
571
}
568
572
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 > (
570
574
& ' sess self ,
571
575
tcx : TyCtxt < ' tcx > ,
572
576
pos : AbsoluteBytePos ,
@@ -577,12 +581,10 @@ impl<'sess> OnDiskCache<'sess> {
577
581
{
578
582
let cnum_map = self . cnum_map . get_or_init ( || Self :: compute_cnum_map ( tcx) ) ;
579
583
584
+ let serialized_data = self . serialized_data . read ( ) ;
580
585
let mut decoder = CacheDecoder {
581
586
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 ( ) ) ,
586
588
source_map : self . source_map ,
587
589
cnum_map,
588
590
file_index_to_file : & self . file_index_to_file ,
0 commit comments