Skip to content

Commit

Permalink
Make OnDiskCache thread-safer
Browse files Browse the repository at this point in the history
  • Loading branch information
Zoxc committed Apr 12, 2018
1 parent 6c53749 commit 807c1a0
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 26 deletions.
6 changes: 3 additions & 3 deletions src/librustc/ty/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ use rustc_data_structures::indexed_vec::IndexVec;
use rustc_data_structures::sync::{Lrc, Lock};
use std::any::Any;
use std::borrow::Borrow;
use std::cell::{Cell, RefCell};
use std::cell::Cell;
use std::cmp::Ordering;
use std::collections::hash_map::{self, Entry};
use std::hash::{Hash, Hasher};
Expand Down Expand Up @@ -867,7 +867,7 @@ pub struct GlobalCtxt<'tcx> {
maybe_unused_extern_crates: Vec<(DefId, Span)>,

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

/// Caches the results of trait selection. This cache is used
/// for things that do not have to do with the parameters in scope.
Expand Down Expand Up @@ -1263,7 +1263,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
hir,
def_path_hash_to_def_id,
maps: maps::Maps::new(providers),
rcache: RefCell::new(FxHashMap()),
rcache: Lock::new(FxHashMap()),
selection_cache: traits::SelectionCache::new(),
evaluation_cache: traits::EvaluationCache::new(),
crate_name: Symbol::intern(crate_name),
Expand Down
45 changes: 22 additions & 23 deletions src/librustc/ty/maps/on_disk_cache.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ use hir::map::definitions::DefPathHash;
use ich::{CachingCodemapView, Fingerprint};
use mir::{self, interpret};
use rustc_data_structures::fx::FxHashMap;
use rustc_data_structures::sync::Lrc;
use rustc_data_structures::sync::{Lrc, Lock, HashMapExt, Once};
use rustc_data_structures::indexed_vec::{IndexVec, Idx};
use rustc_serialize::{Decodable, Decoder, Encodable, Encoder, opaque,
SpecializedDecoder, SpecializedEncoder,
Expand Down Expand Up @@ -57,17 +57,17 @@ pub struct OnDiskCache<'sess> {

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

prev_cnums: Vec<(u32, String, CrateDisambiguator)>,
cnum_map: RefCell<Option<IndexVec<CrateNum, Option<CrateNum>>>>,
cnum_map: Once<IndexVec<CrateNum, Option<CrateNum>>>,

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

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

// A map from dep-node to the position of the cached query result in
// `serialized_data`.
Expand Down Expand Up @@ -140,14 +140,14 @@ impl<'sess> OnDiskCache<'sess> {
OnDiskCache {
serialized_data: data,
file_index_to_stable_id: footer.file_index_to_stable_id,
file_index_to_file: RefCell::new(FxHashMap()),
file_index_to_file: Lock::new(FxHashMap()),
prev_cnums: footer.prev_cnums,
cnum_map: RefCell::new(None),
cnum_map: Once::new(),
codemap: sess.codemap(),
current_diagnostics: RefCell::new(FxHashMap()),
current_diagnostics: Lock::new(FxHashMap()),
query_result_index: footer.query_result_index.into_iter().collect(),
prev_diagnostics_index: footer.diagnostics_index.into_iter().collect(),
synthetic_expansion_infos: RefCell::new(FxHashMap()),
synthetic_expansion_infos: Lock::new(FxHashMap()),
interpret_alloc_cache: RefCell::new(FxHashMap::default()),
interpret_alloc_size: RefCell::new(FxHashMap::default()),
}
Expand All @@ -157,14 +157,14 @@ impl<'sess> OnDiskCache<'sess> {
OnDiskCache {
serialized_data: Vec::new(),
file_index_to_stable_id: FxHashMap(),
file_index_to_file: RefCell::new(FxHashMap()),
file_index_to_file: Lock::new(FxHashMap()),
prev_cnums: vec![],
cnum_map: RefCell::new(None),
cnum_map: Once::new(),
codemap,
current_diagnostics: RefCell::new(FxHashMap()),
current_diagnostics: Lock::new(FxHashMap()),
query_result_index: FxHashMap(),
prev_diagnostics_index: FxHashMap(),
synthetic_expansion_infos: RefCell::new(FxHashMap()),
synthetic_expansion_infos: Lock::new(FxHashMap()),
interpret_alloc_cache: RefCell::new(FxHashMap::default()),
interpret_alloc_size: RefCell::new(FxHashMap::default()),
}
Expand Down Expand Up @@ -383,18 +383,16 @@ impl<'sess> OnDiskCache<'sess> {
return None
};

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

let mut decoder = CacheDecoder {
tcx,
opaque: opaque::Decoder::new(&self.serialized_data[..], pos.to_usize()),
codemap: self.codemap,
cnum_map: cnum_map.as_ref().unwrap(),
cnum_map: self.cnum_map.get(),
file_index_to_file: &self.file_index_to_file,
file_index_to_stable_id: &self.file_index_to_stable_id,
synthetic_expansion_infos: &self.synthetic_expansion_infos,
Expand Down Expand Up @@ -458,8 +456,8 @@ struct CacheDecoder<'a, 'tcx: 'a, 'x> {
opaque: opaque::Decoder<'x>,
codemap: &'x CodeMap,
cnum_map: &'x IndexVec<CrateNum, Option<CrateNum>>,
synthetic_expansion_infos: &'x RefCell<FxHashMap<AbsoluteBytePos, SyntaxContext>>,
file_index_to_file: &'x RefCell<FxHashMap<FileMapIndex, Lrc<FileMap>>>,
synthetic_expansion_infos: &'x Lock<FxHashMap<AbsoluteBytePos, SyntaxContext>>,
file_index_to_file: &'x Lock<FxHashMap<FileMapIndex, Lrc<FileMap>>>,
file_index_to_stable_id: &'x FxHashMap<FileMapIndex, StableFilemapId>,
interpret_alloc_cache: &'x RefCell<FxHashMap<usize, interpret::AllocId>>,
interpret_alloc_size: &'x RefCell<FxHashMap<usize, usize>>,
Expand Down Expand Up @@ -557,7 +555,8 @@ impl<'a, 'tcx: 'a, 'x> ty_codec::TyDecoder<'a, 'tcx> for CacheDecoder<'a, 'tcx,
}

let ty = or_insert_with(self)?;
tcx.rcache.borrow_mut().insert(cache_key, ty);
// This may overwrite the entry, but it should overwrite with the same value
tcx.rcache.borrow_mut().insert_same(cache_key, ty);
Ok(ty)
}

Expand Down

0 comments on commit 807c1a0

Please sign in to comment.