Skip to content

Commit

Permalink
Rollup merge of rust-lang#65979 - spastorino:crate-metadata-mutexes, …
Browse files Browse the repository at this point in the history
…r=Mark-Simulacrum

Switch CrateMetadata's source_map_import_info from RwLock to Once
  • Loading branch information
Centril authored Oct 31, 2019
2 parents 60fa6d8 + 12273cb commit 30ed544
Show file tree
Hide file tree
Showing 4 changed files with 75 additions and 92 deletions.
14 changes: 8 additions & 6 deletions src/librustc_data_structures/sync.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
4 changes: 2 additions & 2 deletions src/librustc_metadata/creader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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,
Expand Down
4 changes: 2 additions & 2 deletions src/librustc_metadata/cstore.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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.
Expand Down
145 changes: 63 additions & 82 deletions src/librustc_metadata/decoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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
Expand Down

0 comments on commit 30ed544

Please sign in to comment.