]> git.lizzy.rs Git - rust.git/commitdiff
Rollup merge of #65979 - spastorino:crate-metadata-mutexes, r=Mark-Simulacrum
authorMazdak Farrokhzad <twingoow@gmail.com>
Thu, 31 Oct 2019 01:54:11 +0000 (02:54 +0100)
committerGitHub <noreply@github.com>
Thu, 31 Oct 2019 01:54:11 +0000 (02:54 +0100)
Switch CrateMetadata's source_map_import_info from RwLock to Once

src/librustc_data_structures/sync.rs
src/librustc_metadata/creader.rs
src/librustc_metadata/cstore.rs
src/librustc_metadata/decoder.rs

index f09474ff4d344a8c37f801b09cd9b2de1f42d60a..d111471f53d7d80ad863ca0840423acf914238a2 100644 (file)
@@ -497,13 +497,15 @@ pub fn set(&self, value: 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
index 234a5395047c6a321d2166a020ee45d759922e7d..540b06b3a8be99e692201836c32fc11a7b1ca0b8 100644 (file)
@@ -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 @@ fn register_crate(
             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,
index 6b06cf575edcf5557aeddaf70335f4f4e7e809de..8dfc921c95b3d1205848148a491c2c5b345802a4 100644 (file)
@@ -9,7 +9,7 @@
 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 @@
     /// 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.
index 0e6ecbbf0176a8c0a69900df4e12e21ca89eafac..c5954e1ea1d9830e2433ef64e8e4bff57e16abb0 100644 (file)
@@ -5,7 +5,7 @@
 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 @@ fn get_variant(
         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 @@ fn reverse_translate_def_id(&self, did: DefId) -> Option<DefId> {
     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