Rollup merge of #65979 - spastorino:crate-metadata-mutexes, r=Mark-Simulacrum
Switch CrateMetadata's source_map_import_info from RwLock to Once
This commit is contained in:
commit
30ed544948
4 changed files with 71 additions and 88 deletions
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
) -> &[cstore::ImportedSourceFile] {
|
||||
self.source_map_import_info.init_locking(|| {
|
||||
let external_source_map = self.root.source_map.decode(self);
|
||||
|
||||
// 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();
|
||||
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;
|
||||
|
||||
if !source_map_import_info.is_empty() {
|
||||
drop(source_map_import_info);
|
||||
return self.source_map_import_info.borrow();
|
||||
}
|
||||
let source_length = (end_pos - start_pos).to_usize();
|
||||
|
||||
let external_source_map = self.root.source_map.decode(self);
|
||||
// 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 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 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);
|
||||
|
||||
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);
|
||||
|
||||
// This shouldn't borrow twice, but there is no way to downgrade RefMut to Ref.
|
||||
self.source_map_import_info.borrow()
|
||||
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
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue