Skip to content

Commit 976a17b

Browse files
authored
Rollup merge of rust-lang#49396 - Zoxc:sync-on-disk-cache, r=michaelwoerister
Make OnDiskCache thread-safer I'm not sure if `synthetic_expansion_infos` is handled correctly. `interpret_alloc_cache` and `interpret_alloc_size` seems to be wrong though, since the code may now decode two `AllocId`s in parallel. I'd like some input on how to fix that. cc @oli-obk r? @michaelwoerister
2 parents eec3208 + 807c1a0 commit 976a17b

File tree

2 files changed

+25
-26
lines changed

2 files changed

+25
-26
lines changed

src/librustc/ty/context.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ use rustc_data_structures::indexed_vec::IndexVec;
6161
use rustc_data_structures::sync::{Lrc, Lock};
6262
use std::any::Any;
6363
use std::borrow::Borrow;
64-
use std::cell::{Cell, RefCell};
64+
use std::cell::Cell;
6565
use std::cmp::Ordering;
6666
use std::collections::hash_map::{self, Entry};
6767
use std::hash::{Hash, Hasher};
@@ -890,7 +890,7 @@ pub struct GlobalCtxt<'tcx> {
890890
maybe_unused_extern_crates: Vec<(DefId, Span)>,
891891

892892
// Internal cache for metadata decoding. No need to track deps on this.
893-
pub rcache: RefCell<FxHashMap<ty::CReaderCacheKey, Ty<'tcx>>>,
893+
pub rcache: Lock<FxHashMap<ty::CReaderCacheKey, Ty<'tcx>>>,
894894

895895
/// Caches the results of trait selection. This cache is used
896896
/// for things that do not have to do with the parameters in scope.
@@ -1286,7 +1286,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
12861286
hir,
12871287
def_path_hash_to_def_id,
12881288
maps: maps::Maps::new(providers),
1289-
rcache: RefCell::new(FxHashMap()),
1289+
rcache: Lock::new(FxHashMap()),
12901290
selection_cache: traits::SelectionCache::new(),
12911291
evaluation_cache: traits::EvaluationCache::new(),
12921292
crate_name: Symbol::intern(crate_name),

src/librustc/ty/maps/on_disk_cache.rs

+22-23
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ use hir::map::definitions::DefPathHash;
1717
use ich::{CachingCodemapView, Fingerprint};
1818
use mir::{self, interpret};
1919
use rustc_data_structures::fx::FxHashMap;
20-
use rustc_data_structures::sync::Lrc;
20+
use rustc_data_structures::sync::{Lrc, Lock, HashMapExt, Once};
2121
use rustc_data_structures::indexed_vec::{IndexVec, Idx};
2222
use rustc_serialize::{Decodable, Decoder, Encodable, Encoder, opaque,
2323
SpecializedDecoder, SpecializedEncoder,
@@ -57,17 +57,17 @@ pub struct OnDiskCache<'sess> {
5757

5858
// This field collects all Diagnostics emitted during the current
5959
// compilation session.
60-
current_diagnostics: RefCell<FxHashMap<DepNodeIndex, Vec<Diagnostic>>>,
60+
current_diagnostics: Lock<FxHashMap<DepNodeIndex, Vec<Diagnostic>>>,
6161

6262
prev_cnums: Vec<(u32, String, CrateDisambiguator)>,
63-
cnum_map: RefCell<Option<IndexVec<CrateNum, Option<CrateNum>>>>,
63+
cnum_map: Once<IndexVec<CrateNum, Option<CrateNum>>>,
6464

6565
codemap: &'sess CodeMap,
6666
file_index_to_stable_id: FxHashMap<FileMapIndex, StableFilemapId>,
6767

6868
// These two fields caches that are populated lazily during decoding.
69-
file_index_to_file: RefCell<FxHashMap<FileMapIndex, Lrc<FileMap>>>,
70-
synthetic_expansion_infos: RefCell<FxHashMap<AbsoluteBytePos, SyntaxContext>>,
69+
file_index_to_file: Lock<FxHashMap<FileMapIndex, Lrc<FileMap>>>,
70+
synthetic_expansion_infos: Lock<FxHashMap<AbsoluteBytePos, SyntaxContext>>,
7171

7272
// A map from dep-node to the position of the cached query result in
7373
// `serialized_data`.
@@ -140,14 +140,14 @@ impl<'sess> OnDiskCache<'sess> {
140140
OnDiskCache {
141141
serialized_data: data,
142142
file_index_to_stable_id: footer.file_index_to_stable_id,
143-
file_index_to_file: RefCell::new(FxHashMap()),
143+
file_index_to_file: Lock::new(FxHashMap()),
144144
prev_cnums: footer.prev_cnums,
145-
cnum_map: RefCell::new(None),
145+
cnum_map: Once::new(),
146146
codemap: sess.codemap(),
147-
current_diagnostics: RefCell::new(FxHashMap()),
147+
current_diagnostics: Lock::new(FxHashMap()),
148148
query_result_index: footer.query_result_index.into_iter().collect(),
149149
prev_diagnostics_index: footer.diagnostics_index.into_iter().collect(),
150-
synthetic_expansion_infos: RefCell::new(FxHashMap()),
150+
synthetic_expansion_infos: Lock::new(FxHashMap()),
151151
interpret_alloc_cache: RefCell::new(FxHashMap::default()),
152152
interpret_alloc_size: RefCell::new(FxHashMap::default()),
153153
}
@@ -157,14 +157,14 @@ impl<'sess> OnDiskCache<'sess> {
157157
OnDiskCache {
158158
serialized_data: Vec::new(),
159159
file_index_to_stable_id: FxHashMap(),
160-
file_index_to_file: RefCell::new(FxHashMap()),
160+
file_index_to_file: Lock::new(FxHashMap()),
161161
prev_cnums: vec![],
162-
cnum_map: RefCell::new(None),
162+
cnum_map: Once::new(),
163163
codemap,
164-
current_diagnostics: RefCell::new(FxHashMap()),
164+
current_diagnostics: Lock::new(FxHashMap()),
165165
query_result_index: FxHashMap(),
166166
prev_diagnostics_index: FxHashMap(),
167-
synthetic_expansion_infos: RefCell::new(FxHashMap()),
167+
synthetic_expansion_infos: Lock::new(FxHashMap()),
168168
interpret_alloc_cache: RefCell::new(FxHashMap::default()),
169169
interpret_alloc_size: RefCell::new(FxHashMap::default()),
170170
}
@@ -383,18 +383,16 @@ impl<'sess> OnDiskCache<'sess> {
383383
return None
384384
};
385385

386-
// Initialize the cnum_map if it is not initialized yet.
387-
if self.cnum_map.borrow().is_none() {
388-
let mut cnum_map = self.cnum_map.borrow_mut();
389-
*cnum_map = Some(Self::compute_cnum_map(tcx, &self.prev_cnums[..]));
390-
}
391-
let cnum_map = self.cnum_map.borrow();
386+
// Initialize the cnum_map using the value from the thread which finishes the closure first
387+
self.cnum_map.init_nonlocking_same(|| {
388+
Self::compute_cnum_map(tcx, &self.prev_cnums[..])
389+
});
392390

393391
let mut decoder = CacheDecoder {
394392
tcx,
395393
opaque: opaque::Decoder::new(&self.serialized_data[..], pos.to_usize()),
396394
codemap: self.codemap,
397-
cnum_map: cnum_map.as_ref().unwrap(),
395+
cnum_map: self.cnum_map.get(),
398396
file_index_to_file: &self.file_index_to_file,
399397
file_index_to_stable_id: &self.file_index_to_stable_id,
400398
synthetic_expansion_infos: &self.synthetic_expansion_infos,
@@ -458,8 +456,8 @@ struct CacheDecoder<'a, 'tcx: 'a, 'x> {
458456
opaque: opaque::Decoder<'x>,
459457
codemap: &'x CodeMap,
460458
cnum_map: &'x IndexVec<CrateNum, Option<CrateNum>>,
461-
synthetic_expansion_infos: &'x RefCell<FxHashMap<AbsoluteBytePos, SyntaxContext>>,
462-
file_index_to_file: &'x RefCell<FxHashMap<FileMapIndex, Lrc<FileMap>>>,
459+
synthetic_expansion_infos: &'x Lock<FxHashMap<AbsoluteBytePos, SyntaxContext>>,
460+
file_index_to_file: &'x Lock<FxHashMap<FileMapIndex, Lrc<FileMap>>>,
463461
file_index_to_stable_id: &'x FxHashMap<FileMapIndex, StableFilemapId>,
464462
interpret_alloc_cache: &'x RefCell<FxHashMap<usize, interpret::AllocId>>,
465463
interpret_alloc_size: &'x RefCell<FxHashMap<usize, usize>>,
@@ -557,7 +555,8 @@ impl<'a, 'tcx: 'a, 'x> ty_codec::TyDecoder<'a, 'tcx> for CacheDecoder<'a, 'tcx,
557555
}
558556

559557
let ty = or_insert_with(self)?;
560-
tcx.rcache.borrow_mut().insert(cache_key, ty);
558+
// This may overwrite the entry, but it should overwrite with the same value
559+
tcx.rcache.borrow_mut().insert_same(cache_key, ty);
561560
Ok(ty)
562561
}
563562

0 commit comments

Comments
 (0)