diff options
| author | Mazdak Farrokhzad <twingoow@gmail.com> | 2019-10-31 02:54:11 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2019-10-31 02:54:11 +0100 |
| commit | 30ed544948dc12b487e6c307bf76c43785841f8a (patch) | |
| tree | 8cb7e61f451d177cfbca4238d78b9b39ca334073 | |
| parent | 60fa6d8ac258400a3b4da72019f5edda7e513dbe (diff) | |
| parent | 12273cb7f66f463683ad4d6c54b17afe0b7d8422 (diff) | |
| download | rust-30ed544948dc12b487e6c307bf76c43785841f8a.tar.gz rust-30ed544948dc12b487e6c307bf76c43785841f8a.zip | |
Rollup merge of #65979 - spastorino:crate-metadata-mutexes, r=Mark-Simulacrum
Switch CrateMetadata's source_map_import_info from RwLock to Once
| -rw-r--r-- | src/librustc_data_structures/sync.rs | 14 | ||||
| -rw-r--r-- | src/librustc_metadata/creader.rs | 4 | ||||
| -rw-r--r-- | src/librustc_metadata/cstore.rs | 4 | ||||
| -rw-r--r-- | src/librustc_metadata/decoder.rs | 145 |
4 files changed, 75 insertions, 92 deletions
diff --git a/src/librustc_data_structures/sync.rs b/src/librustc_data_structures/sync.rs index f09474ff4d3..d111471f53d 100644 --- a/src/librustc_data_structures/sync.rs +++ b/src/librustc_data_structures/sync.rs @@ -497,13 +497,15 @@ impl<T> Once<T> { /// If the value was already initialized the closure is not called and `false` is returned, /// otherwise if the value from the closure initializes the inner value, `true` is returned #[inline] - pub fn init_locking<F: FnOnce() -> T>(&self, f: F) -> bool { - let mut lock = self.0.lock(); - if lock.is_some() { - return false; + pub fn init_locking<F: FnOnce() -> T>(&self, f: F) -> &T { + { + let mut lock = self.0.lock(); + if lock.is_none() { + *lock = Some(f()); + } } - *lock = Some(f()); - true + + self.borrow() } /// Tries to initialize the inner value by calling the closure without ensuring that no-one diff --git a/src/librustc_metadata/creader.rs b/src/librustc_metadata/creader.rs index 234a5395047..540b06b3a8b 100644 --- a/src/librustc_metadata/creader.rs +++ b/src/librustc_metadata/creader.rs @@ -3,7 +3,7 @@ use crate::cstore::{self, CStore, MetadataBlob}; use crate::locator::{self, CratePaths}; use crate::schema::{CrateRoot, CrateDep}; -use rustc_data_structures::sync::{RwLock, Lock, AtomicCell}; +use rustc_data_structures::sync::{Lock, Once, AtomicCell}; use rustc::hir::def_id::CrateNum; use rustc_data_structures::svh::Svh; @@ -249,7 +249,7 @@ impl<'a> CrateLoader<'a> { cnum_map, cnum, dependencies: Lock::new(dependencies), - source_map_import_info: RwLock::new(vec![]), + source_map_import_info: Once::new(), alloc_decoding_state: AllocDecodingState::new(interpret_alloc_index), dep_kind: Lock::new(dep_kind), source, diff --git a/src/librustc_metadata/cstore.rs b/src/librustc_metadata/cstore.rs index 6b06cf575ed..8dfc921c95b 100644 --- a/src/librustc_metadata/cstore.rs +++ b/src/librustc_metadata/cstore.rs @@ -9,7 +9,7 @@ use rustc::middle::cstore::{CrateSource, DepKind, ExternCrate}; use rustc::mir::interpret::AllocDecodingState; use rustc_index::vec::IndexVec; use rustc::util::nodemap::FxHashMap; -use rustc_data_structures::sync::{Lrc, RwLock, Lock, MetadataRef, AtomicCell}; +use rustc_data_structures::sync::{Lrc, Lock, MetadataRef, Once, AtomicCell}; use syntax::ast; use syntax::edition::Edition; use syntax_expand::base::SyntaxExtension; @@ -62,7 +62,7 @@ crate struct CrateMetadata { /// Proc macro descriptions for this crate, if it's a proc macro crate. crate raw_proc_macros: Option<&'static [ProcMacro]>, /// Source maps for code from the crate. - crate source_map_import_info: RwLock<Vec<ImportedSourceFile>>, + crate source_map_import_info: Once<Vec<ImportedSourceFile>>, /// Used for decoding interpret::AllocIds in a cached & thread-safe manner. crate alloc_decoding_state: AllocDecodingState, /// The `DepNodeIndex` of the `DepNode` representing this upstream crate. diff --git a/src/librustc_metadata/decoder.rs b/src/librustc_metadata/decoder.rs index 0e6ecbbf017..c5954e1ea1d 100644 --- a/src/librustc_metadata/decoder.rs +++ b/src/librustc_metadata/decoder.rs @@ -5,7 +5,7 @@ use crate::schema::*; use crate::table::{FixedSizeEncoding, PerDefTable}; use rustc_index::vec::IndexVec; -use rustc_data_structures::sync::{Lrc, ReadGuard}; +use rustc_data_structures::sync::Lrc; use rustc::hir::map::{DefKey, DefPath, DefPathData, DefPathHash}; use rustc::hir; use rustc::middle::cstore::{LinkagePreference, NativeLibrary, ForeignModule}; @@ -664,7 +664,7 @@ impl<'a, 'tcx> CrateMetadata { tcx: TyCtxt<'tcx>, ) -> ty::GenericPredicates<'tcx> { self.root.per_def.predicates.get(self, item_id).unwrap().decode((self, tcx)) -} + } crate fn get_predicates_defined_on( &self, @@ -1290,87 +1290,68 @@ impl<'a, 'tcx> CrateMetadata { fn imported_source_files( &'a self, local_source_map: &source_map::SourceMap, - ) -> ReadGuard<'a, Vec<cstore::ImportedSourceFile>> { - { - let source_files = self.source_map_import_info.borrow(); - if !source_files.is_empty() { - return source_files; - } - } - - // Lock the source_map_import_info to ensure this only happens once - let mut source_map_import_info = self.source_map_import_info.borrow_mut(); - - if !source_map_import_info.is_empty() { - drop(source_map_import_info); - return self.source_map_import_info.borrow(); - } - - let external_source_map = self.root.source_map.decode(self); - - let imported_source_files = external_source_map.map(|source_file_to_import| { - // We can't reuse an existing SourceFile, so allocate a new one - // containing the information we need. - let syntax_pos::SourceFile { name, - name_was_remapped, - src_hash, - start_pos, - end_pos, - mut lines, - mut multibyte_chars, - mut non_narrow_chars, - mut normalized_pos, - name_hash, - .. } = source_file_to_import; - - let source_length = (end_pos - start_pos).to_usize(); - - // Translate line-start positions and multibyte character - // position into frame of reference local to file. - // `SourceMap::new_imported_source_file()` will then translate those - // coordinates to their new global frame of reference when the - // offset of the SourceFile is known. - for pos in &mut lines { - *pos = *pos - start_pos; - } - for mbc in &mut multibyte_chars { - mbc.pos = mbc.pos - start_pos; - } - for swc in &mut non_narrow_chars { - *swc = *swc - start_pos; - } - for np in &mut normalized_pos { - np.pos = np.pos - start_pos; - } - - let local_version = local_source_map.new_imported_source_file(name, - name_was_remapped, - self.cnum.as_u32(), - src_hash, - name_hash, - source_length, - lines, - multibyte_chars, - non_narrow_chars, - normalized_pos); - debug!("CrateMetaData::imported_source_files alloc \ - source_file {:?} original (start_pos {:?} end_pos {:?}) \ - translated (start_pos {:?} end_pos {:?})", - local_version.name, start_pos, end_pos, - local_version.start_pos, local_version.end_pos); - - cstore::ImportedSourceFile { - original_start_pos: start_pos, - original_end_pos: end_pos, - translated_source_file: local_version, - } - }).collect(); - - *source_map_import_info = imported_source_files; - drop(source_map_import_info); + ) -> &[cstore::ImportedSourceFile] { + self.source_map_import_info.init_locking(|| { + let external_source_map = self.root.source_map.decode(self); + + external_source_map.map(|source_file_to_import| { + // We can't reuse an existing SourceFile, so allocate a new one + // containing the information we need. + let syntax_pos::SourceFile { name, + name_was_remapped, + src_hash, + start_pos, + end_pos, + mut lines, + mut multibyte_chars, + mut non_narrow_chars, + mut normalized_pos, + name_hash, + .. } = source_file_to_import; + + let source_length = (end_pos - start_pos).to_usize(); + + // Translate line-start positions and multibyte character + // position into frame of reference local to file. + // `SourceMap::new_imported_source_file()` will then translate those + // coordinates to their new global frame of reference when the + // offset of the SourceFile is known. + for pos in &mut lines { + *pos = *pos - start_pos; + } + for mbc in &mut multibyte_chars { + mbc.pos = mbc.pos - start_pos; + } + for swc in &mut non_narrow_chars { + *swc = *swc - start_pos; + } + for np in &mut normalized_pos { + np.pos = np.pos - start_pos; + } - // This shouldn't borrow twice, but there is no way to downgrade RefMut to Ref. - self.source_map_import_info.borrow() + let local_version = local_source_map.new_imported_source_file(name, + name_was_remapped, + self.cnum.as_u32(), + src_hash, + name_hash, + source_length, + lines, + multibyte_chars, + non_narrow_chars, + normalized_pos); + debug!("CrateMetaData::imported_source_files alloc \ + source_file {:?} original (start_pos {:?} end_pos {:?}) \ + translated (start_pos {:?} end_pos {:?})", + local_version.name, start_pos, end_pos, + local_version.start_pos, local_version.end_pos); + + cstore::ImportedSourceFile { + original_start_pos: start_pos, + original_end_pos: end_pos, + translated_source_file: local_version, + } + }).collect() + }) } /// Get the `DepNodeIndex` corresponding this crate. The result of this |
