Skip to content

Commit

Permalink
Change CrateMetadata's source_map_import_info from RwLock to Once
Browse files Browse the repository at this point in the history
This field is created lazily on first use and after that is read only.
That's exactly what Once is for.
  • Loading branch information
spastorino committed Oct 30, 2019
1 parent 308c4a6 commit a6ac22e
Show file tree
Hide file tree
Showing 3 changed files with 66 additions and 83 deletions.
4 changes: 2 additions & 2 deletions src/librustc_metadata/creader.rs
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
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
141 changes: 62 additions & 79 deletions src/librustc_metadata/decoder.rs
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 @@ -1290,86 +1290,69 @@ 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();
) -> &[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;
}

*source_map_import_info = imported_source_files;
drop(source_map_import_info);
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()
});

// This shouldn't borrow twice, but there is no way to downgrade RefMut to Ref.
self.source_map_import_info.borrow()
}

Expand Down

0 comments on commit a6ac22e

Please sign in to comment.