@@ -17,7 +17,7 @@ use hir::map::definitions::DefPathHash;
1717use ich:: { CachingCodemapView , Fingerprint } ;
1818use mir:: { self , interpret} ;
1919use rustc_data_structures:: fx:: FxHashMap ;
20- use rustc_data_structures:: sync:: Lrc ;
20+ use rustc_data_structures:: sync:: { Lrc , Lock , HashMapExt , Once } ;
2121use rustc_data_structures:: indexed_vec:: { IndexVec , Idx } ;
2222use 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