1
Fork 0

Use Freeze for SourceFile.external_src

This commit is contained in:
John Kåre Alsaker 2023-08-31 12:50:44 +02:00
parent f00c139998
commit c5996b80be
8 changed files with 91 additions and 46 deletions

View file

@ -64,7 +64,7 @@ pub mod fatal_error;
pub mod profiling;
use rustc_data_structures::stable_hasher::{Hash128, Hash64, HashStable, StableHasher};
use rustc_data_structures::sync::{Lock, Lrc};
use rustc_data_structures::sync::{FreezeLock, FreezeWriteGuard, Lock, Lrc};
use std::borrow::Cow;
use std::cmp::{self, Ordering};
@ -1206,7 +1206,6 @@ pub enum ExternalSourceKind {
AbsentOk,
/// A failed attempt has been made to load the external source.
AbsentErr,
Unneeded,
}
impl ExternalSource {
@ -1343,7 +1342,7 @@ pub struct SourceFile {
pub src_hash: SourceFileHash,
/// The external source code (used for external crates, which will have a `None`
/// value as `self.src`.
pub external_src: Lock<ExternalSource>,
pub external_src: FreezeLock<ExternalSource>,
/// The start position of this source in the `SourceMap`.
pub start_pos: BytePos,
/// The byte length of this source.
@ -1368,7 +1367,10 @@ impl Clone for SourceFile {
name: self.name.clone(),
src: self.src.clone(),
src_hash: self.src_hash,
external_src: Lock::new(self.external_src.borrow().clone()),
external_src: {
let lock = self.external_src.read();
FreezeLock::with(lock.clone(), self.external_src.is_frozen())
},
start_pos: self.start_pos,
source_len: self.source_len,
lines: Lock::new(self.lines.borrow().clone()),
@ -1488,7 +1490,7 @@ impl<D: Decoder> Decodable<D> for SourceFile {
src_hash,
// Unused - the metadata decoder will construct
// a new SourceFile, filling in `external_src` properly
external_src: Lock::new(ExternalSource::Unneeded),
external_src: FreezeLock::frozen(ExternalSource::Unneeded),
lines: Lock::new(lines),
multibyte_chars,
non_narrow_chars,
@ -1530,7 +1532,7 @@ impl SourceFile {
name,
src: Some(Lrc::new(src)),
src_hash,
external_src: Lock::new(ExternalSource::Unneeded),
external_src: FreezeLock::frozen(ExternalSource::Unneeded),
start_pos: BytePos::from_u32(0),
source_len: RelativeBytePos::from_u32(source_len),
lines: Lock::new(SourceFileLines::Lines(lines)),
@ -1612,35 +1614,37 @@ impl SourceFile {
where
F: FnOnce() -> Option<String>,
{
if matches!(
*self.external_src.borrow(),
ExternalSource::Foreign { kind: ExternalSourceKind::AbsentOk, .. }
) {
if !self.external_src.is_frozen() {
let src = get_src();
let mut external_src = self.external_src.borrow_mut();
// Check that no-one else have provided the source while we were getting it
if let ExternalSource::Foreign {
kind: src_kind @ ExternalSourceKind::AbsentOk, ..
} = &mut *external_src
{
if let Some(mut src) = src {
// The src_hash needs to be computed on the pre-normalized src.
if self.src_hash.matches(&src) {
normalize_src(&mut src);
*src_kind = ExternalSourceKind::Present(Lrc::new(src));
return true;
}
let src = src.and_then(|mut src| {
// The src_hash needs to be computed on the pre-normalized src.
self.src_hash.matches(&src).then(|| {
normalize_src(&mut src);
src
})
});
self.external_src.try_write().map(|mut external_src| {
if let ExternalSource::Foreign {
kind: src_kind @ ExternalSourceKind::AbsentOk,
..
} = &mut *external_src
{
*src_kind = if let Some(src) = src {
ExternalSourceKind::Present(Lrc::new(src))
} else {
ExternalSourceKind::AbsentErr
};
} else {
*src_kind = ExternalSourceKind::AbsentErr;
panic!("unexpected state {:?}", *external_src)
}
false
} else {
self.src.is_some() || external_src.get_source().is_some()
}
} else {
self.src.is_some() || self.external_src.borrow().get_source().is_some()
// Freeze this so we don't try to load the source again.
FreezeWriteGuard::freeze(external_src)
});
}
self.src.is_some() || self.external_src.read().get_source().is_some()
}
/// Gets a line from the list of pre-computed line-beginnings.

View file

@ -340,7 +340,7 @@ impl SourceMap {
name: filename,
src: None,
src_hash,
external_src: Lock::new(ExternalSource::Foreign {
external_src: FreezeLock::new(ExternalSource::Foreign {
kind: ExternalSourceKind::AbsentOk,
metadata_index,
}),
@ -564,7 +564,7 @@ impl SourceMap {
end: (local_end.sf.name.clone(), local_end.sf.start_pos),
})))
} else {
self.ensure_source_file_source_present(local_begin.sf.clone());
self.ensure_source_file_source_present(&local_begin.sf);
let start_index = local_begin.pos.to_usize();
let end_index = local_end.pos.to_usize();
@ -581,7 +581,7 @@ impl SourceMap {
if let Some(ref src) = local_begin.sf.src {
extract_source(src, start_index, end_index)
} else if let Some(src) = local_begin.sf.external_src.borrow().get_source() {
} else if let Some(src) = local_begin.sf.external_src.read().get_source() {
extract_source(src, start_index, end_index)
} else {
Err(SpanSnippetError::SourceNotAvailable { filename: local_begin.sf.name.clone() })
@ -873,7 +873,7 @@ impl SourceMap {
let sp = sp.data();
let local_begin = self.lookup_byte_offset(sp.lo);
let start_index = local_begin.pos.to_usize();
let src = local_begin.sf.external_src.borrow();
let src = local_begin.sf.external_src.read();
let snippet = if let Some(ref src) = local_begin.sf.src {
Some(&src[start_index..])
@ -983,7 +983,7 @@ impl SourceMap {
return 1;
}
let src = local_begin.sf.external_src.borrow();
let src = local_begin.sf.external_src.read();
let snippet = if let Some(src) = &local_begin.sf.src {
src
@ -1030,7 +1030,7 @@ impl SourceMap {
self.files().iter().fold(0, |a, f| a + f.count_lines())
}
pub fn ensure_source_file_source_present(&self, source_file: Lrc<SourceFile>) -> bool {
pub fn ensure_source_file_source_present(&self, source_file: &SourceFile) -> bool {
source_file.add_external_src(|| {
let FileName::Real(ref name) = source_file.name else {
return None;