Skip to content

Commit 30ed544

Browse files
authored
Rollup merge of #65979 - spastorino:crate-metadata-mutexes, r=Mark-Simulacrum
Switch CrateMetadata's source_map_import_info from RwLock to Once
2 parents 60fa6d8 + 12273cb commit 30ed544

File tree

4 files changed

+75
-92
lines changed

4 files changed

+75
-92
lines changed

src/librustc_data_structures/sync.rs

+8-6
Original file line numberDiff line numberDiff line change
@@ -497,13 +497,15 @@ impl<T> Once<T> {
497497
/// If the value was already initialized the closure is not called and `false` is returned,
498498
/// otherwise if the value from the closure initializes the inner value, `true` is returned
499499
#[inline]
500-
pub fn init_locking<F: FnOnce() -> T>(&self, f: F) -> bool {
501-
let mut lock = self.0.lock();
502-
if lock.is_some() {
503-
return false;
500+
pub fn init_locking<F: FnOnce() -> T>(&self, f: F) -> &T {
501+
{
502+
let mut lock = self.0.lock();
503+
if lock.is_none() {
504+
*lock = Some(f());
505+
}
504506
}
505-
*lock = Some(f());
506-
true
507+
508+
self.borrow()
507509
}
508510

509511
/// Tries to initialize the inner value by calling the closure without ensuring that no-one

src/librustc_metadata/creader.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
use crate::cstore::{self, CStore, MetadataBlob};
44
use crate::locator::{self, CratePaths};
55
use crate::schema::{CrateRoot, CrateDep};
6-
use rustc_data_structures::sync::{RwLock, Lock, AtomicCell};
6+
use rustc_data_structures::sync::{Lock, Once, AtomicCell};
77

88
use rustc::hir::def_id::CrateNum;
99
use rustc_data_structures::svh::Svh;
@@ -249,7 +249,7 @@ impl<'a> CrateLoader<'a> {
249249
cnum_map,
250250
cnum,
251251
dependencies: Lock::new(dependencies),
252-
source_map_import_info: RwLock::new(vec![]),
252+
source_map_import_info: Once::new(),
253253
alloc_decoding_state: AllocDecodingState::new(interpret_alloc_index),
254254
dep_kind: Lock::new(dep_kind),
255255
source,

src/librustc_metadata/cstore.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ use rustc::middle::cstore::{CrateSource, DepKind, ExternCrate};
99
use rustc::mir::interpret::AllocDecodingState;
1010
use rustc_index::vec::IndexVec;
1111
use rustc::util::nodemap::FxHashMap;
12-
use rustc_data_structures::sync::{Lrc, RwLock, Lock, MetadataRef, AtomicCell};
12+
use rustc_data_structures::sync::{Lrc, Lock, MetadataRef, Once, AtomicCell};
1313
use syntax::ast;
1414
use syntax::edition::Edition;
1515
use syntax_expand::base::SyntaxExtension;
@@ -62,7 +62,7 @@ crate struct CrateMetadata {
6262
/// Proc macro descriptions for this crate, if it's a proc macro crate.
6363
crate raw_proc_macros: Option<&'static [ProcMacro]>,
6464
/// Source maps for code from the crate.
65-
crate source_map_import_info: RwLock<Vec<ImportedSourceFile>>,
65+
crate source_map_import_info: Once<Vec<ImportedSourceFile>>,
6666
/// Used for decoding interpret::AllocIds in a cached & thread-safe manner.
6767
crate alloc_decoding_state: AllocDecodingState,
6868
/// The `DepNodeIndex` of the `DepNode` representing this upstream crate.

src/librustc_metadata/decoder.rs

+63-82
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use crate::schema::*;
55
use crate::table::{FixedSizeEncoding, PerDefTable};
66

77
use rustc_index::vec::IndexVec;
8-
use rustc_data_structures::sync::{Lrc, ReadGuard};
8+
use rustc_data_structures::sync::Lrc;
99
use rustc::hir::map::{DefKey, DefPath, DefPathData, DefPathHash};
1010
use rustc::hir;
1111
use rustc::middle::cstore::{LinkagePreference, NativeLibrary, ForeignModule};
@@ -664,7 +664,7 @@ impl<'a, 'tcx> CrateMetadata {
664664
tcx: TyCtxt<'tcx>,
665665
) -> ty::GenericPredicates<'tcx> {
666666
self.root.per_def.predicates.get(self, item_id).unwrap().decode((self, tcx))
667-
}
667+
}
668668

669669
crate fn get_predicates_defined_on(
670670
&self,
@@ -1290,87 +1290,68 @@ impl<'a, 'tcx> CrateMetadata {
12901290
fn imported_source_files(
12911291
&'a self,
12921292
local_source_map: &source_map::SourceMap,
1293-
) -> ReadGuard<'a, Vec<cstore::ImportedSourceFile>> {
1294-
{
1295-
let source_files = self.source_map_import_info.borrow();
1296-
if !source_files.is_empty() {
1297-
return source_files;
1298-
}
1299-
}
1300-
1301-
// Lock the source_map_import_info to ensure this only happens once
1302-
let mut source_map_import_info = self.source_map_import_info.borrow_mut();
1303-
1304-
if !source_map_import_info.is_empty() {
1305-
drop(source_map_import_info);
1306-
return self.source_map_import_info.borrow();
1307-
}
1308-
1309-
let external_source_map = self.root.source_map.decode(self);
1310-
1311-
let imported_source_files = external_source_map.map(|source_file_to_import| {
1312-
// We can't reuse an existing SourceFile, so allocate a new one
1313-
// containing the information we need.
1314-
let syntax_pos::SourceFile { name,
1315-
name_was_remapped,
1316-
src_hash,
1317-
start_pos,
1318-
end_pos,
1319-
mut lines,
1320-
mut multibyte_chars,
1321-
mut non_narrow_chars,
1322-
mut normalized_pos,
1323-
name_hash,
1324-
.. } = source_file_to_import;
1325-
1326-
let source_length = (end_pos - start_pos).to_usize();
1327-
1328-
// Translate line-start positions and multibyte character
1329-
// position into frame of reference local to file.
1330-
// `SourceMap::new_imported_source_file()` will then translate those
1331-
// coordinates to their new global frame of reference when the
1332-
// offset of the SourceFile is known.
1333-
for pos in &mut lines {
1334-
*pos = *pos - start_pos;
1335-
}
1336-
for mbc in &mut multibyte_chars {
1337-
mbc.pos = mbc.pos - start_pos;
1338-
}
1339-
for swc in &mut non_narrow_chars {
1340-
*swc = *swc - start_pos;
1341-
}
1342-
for np in &mut normalized_pos {
1343-
np.pos = np.pos - start_pos;
1344-
}
1345-
1346-
let local_version = local_source_map.new_imported_source_file(name,
1347-
name_was_remapped,
1348-
self.cnum.as_u32(),
1349-
src_hash,
1350-
name_hash,
1351-
source_length,
1352-
lines,
1353-
multibyte_chars,
1354-
non_narrow_chars,
1355-
normalized_pos);
1356-
debug!("CrateMetaData::imported_source_files alloc \
1357-
source_file {:?} original (start_pos {:?} end_pos {:?}) \
1358-
translated (start_pos {:?} end_pos {:?})",
1359-
local_version.name, start_pos, end_pos,
1360-
local_version.start_pos, local_version.end_pos);
1361-
1362-
cstore::ImportedSourceFile {
1363-
original_start_pos: start_pos,
1364-
original_end_pos: end_pos,
1365-
translated_source_file: local_version,
1366-
}
1367-
}).collect();
1368-
1369-
*source_map_import_info = imported_source_files;
1370-
drop(source_map_import_info);
1293+
) -> &[cstore::ImportedSourceFile] {
1294+
self.source_map_import_info.init_locking(|| {
1295+
let external_source_map = self.root.source_map.decode(self);
1296+
1297+
external_source_map.map(|source_file_to_import| {
1298+
// We can't reuse an existing SourceFile, so allocate a new one
1299+
// containing the information we need.
1300+
let syntax_pos::SourceFile { name,
1301+
name_was_remapped,
1302+
src_hash,
1303+
start_pos,
1304+
end_pos,
1305+
mut lines,
1306+
mut multibyte_chars,
1307+
mut non_narrow_chars,
1308+
mut normalized_pos,
1309+
name_hash,
1310+
.. } = source_file_to_import;
1311+
1312+
let source_length = (end_pos - start_pos).to_usize();
1313+
1314+
// Translate line-start positions and multibyte character
1315+
// position into frame of reference local to file.
1316+
// `SourceMap::new_imported_source_file()` will then translate those
1317+
// coordinates to their new global frame of reference when the
1318+
// offset of the SourceFile is known.
1319+
for pos in &mut lines {
1320+
*pos = *pos - start_pos;
1321+
}
1322+
for mbc in &mut multibyte_chars {
1323+
mbc.pos = mbc.pos - start_pos;
1324+
}
1325+
for swc in &mut non_narrow_chars {
1326+
*swc = *swc - start_pos;
1327+
}
1328+
for np in &mut normalized_pos {
1329+
np.pos = np.pos - start_pos;
1330+
}
13711331

1372-
// This shouldn't borrow twice, but there is no way to downgrade RefMut to Ref.
1373-
self.source_map_import_info.borrow()
1332+
let local_version = local_source_map.new_imported_source_file(name,
1333+
name_was_remapped,
1334+
self.cnum.as_u32(),
1335+
src_hash,
1336+
name_hash,
1337+
source_length,
1338+
lines,
1339+
multibyte_chars,
1340+
non_narrow_chars,
1341+
normalized_pos);
1342+
debug!("CrateMetaData::imported_source_files alloc \
1343+
source_file {:?} original (start_pos {:?} end_pos {:?}) \
1344+
translated (start_pos {:?} end_pos {:?})",
1345+
local_version.name, start_pos, end_pos,
1346+
local_version.start_pos, local_version.end_pos);
1347+
1348+
cstore::ImportedSourceFile {
1349+
original_start_pos: start_pos,
1350+
original_end_pos: end_pos,
1351+
translated_source_file: local_version,
1352+
}
1353+
}).collect()
1354+
})
13741355
}
13751356

13761357
/// Get the `DepNodeIndex` corresponding this crate. The result of this

0 commit comments

Comments
 (0)