Skip to content

Lazily decode SourceFile from metadata #100209

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 8 commits into from
Aug 19, 2022
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 8 additions & 10 deletions compiler/rustc_metadata/src/rmeta/decoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -581,28 +581,26 @@ impl<'a, 'tcx> Decodable<DecodeContext<'a, 'tcx>> for Span {
foreign_data.imported_source_file(metadata_index, sess)
};

// Make sure our binary search above is correct.
// Make sure our span is well-formed.
debug_assert!(
lo >= source_file.original_start_pos && lo <= source_file.original_end_pos,
"Bad binary search: lo={:?} source_file.original_start_pos={:?} source_file.original_end_pos={:?}",
lo + source_file.original_start_pos <= source_file.original_end_pos,
"Malformed encoded span: lo={:?} source_file.original_start_pos={:?} source_file.original_end_pos={:?}",
lo,
source_file.original_start_pos,
source_file.original_end_pos
);

// Make sure we correctly filtered out invalid spans during encoding
// Make sure we correctly filtered out invalid spans during encoding.
debug_assert!(
hi >= source_file.original_start_pos && hi <= source_file.original_end_pos,
"Bad binary search: hi={:?} source_file.original_start_pos={:?} source_file.original_end_pos={:?}",
hi + source_file.original_start_pos <= source_file.original_end_pos,
"Malformed encoded span: hi={:?} source_file.original_start_pos={:?} source_file.original_end_pos={:?}",
hi,
source_file.original_start_pos,
source_file.original_end_pos
);

let lo =
(lo + source_file.translated_source_file.start_pos) - source_file.original_start_pos;
let hi =
(hi + source_file.translated_source_file.start_pos) - source_file.original_start_pos;
let lo = lo + source_file.translated_source_file.start_pos;
let hi = hi + source_file.translated_source_file.start_pos;

// Do not try to decode parent for foreign spans.
Span::new(lo, hi, ctxt, None)
Expand Down
26 changes: 13 additions & 13 deletions compiler/rustc_metadata/src/rmeta/encoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -235,16 +235,14 @@ impl<'a, 'tcx> Encodable<EncodeContext<'a, 'tcx>> for Span {
(source_map.files()[source_file_index].clone(), source_file_index);
}
let (ref source_file, source_file_index) = s.source_file_cache;
debug_assert!(source_file.contains(span.lo));

if !source_file.contains(span.hi) {
// Unfortunately, macro expansion still sometimes generates Spans
// that malformed in this way.
return TAG_PARTIAL_SPAN.encode(s);
}

// Length is independent of the span provenance.
let len = span.hi - span.lo;

// There are two possible cases here:
// 1. This span comes from a 'foreign' crate - e.g. some crate upstream of the
// crate we are writing metadata for. When the metadata for *this* crate gets
Expand All @@ -261,7 +259,7 @@ impl<'a, 'tcx> Encodable<EncodeContext<'a, 'tcx>> for Span {
// if we're a proc-macro crate.
// This allows us to avoid loading the dependencies of proc-macro crates: all of
// the information we need to decode `Span`s is stored in the proc-macro crate.
let (tag, lo, metadata_index) = if source_file.is_imported() && !s.is_proc_macro {
let (tag, metadata_index) = if source_file.is_imported() && !s.is_proc_macro {
// To simplify deserialization, we 'rebase' this span onto the crate it originally came from
// (the crate that 'owns' the file it references. These rebased 'lo' and 'hi' values
// are relative to the source map information for the 'foreign' crate whose CrateNum
Expand All @@ -271,18 +269,15 @@ impl<'a, 'tcx> Encodable<EncodeContext<'a, 'tcx>> for Span {
//
// All of this logic ensures that the final result of deserialization is a 'normal'
// Span that can be used without any additional trouble.
let (external_start_pos, metadata_index) = {
let metadata_index = {
// Introduce a new scope so that we drop the 'lock()' temporary
match &*source_file.external_src.lock() {
ExternalSource::Foreign { original_start_pos, metadata_index, .. } => {
(*original_start_pos, *metadata_index)
}
ExternalSource::Foreign { metadata_index, .. } => *metadata_index,
src => panic!("Unexpected external source {:?}", src),
}
};
let lo = (span.lo - source_file.start_pos) + external_start_pos;

(TAG_VALID_SPAN_FOREIGN, lo, metadata_index)
(TAG_VALID_SPAN_FOREIGN, metadata_index)
} else {
// Record the fact that we need to encode the data for this `SourceFile`
let source_files =
Expand All @@ -291,14 +286,19 @@ impl<'a, 'tcx> Encodable<EncodeContext<'a, 'tcx>> for Span {
let metadata_index: u32 =
metadata_index.try_into().expect("cannot export more than U32_MAX files");

(TAG_VALID_SPAN_LOCAL, span.lo, metadata_index)
(TAG_VALID_SPAN_LOCAL, metadata_index)
};

tag.encode(s);
lo.encode(s);
// Encode the start position relative to the file start, so we profit more from the
// variable-length integer encoding.
let lo = span.lo - source_file.start_pos;

// Encode length which is usually less than span.hi and profits more
// from the variable-length integer encoding that we use.
let len = span.hi - span.lo;

tag.encode(s);
lo.encode(s);
len.encode(s);

// Encode the index of the `SourceFile` for the span, in order to make decoding faster.
Expand Down
4 changes: 0 additions & 4 deletions compiler/rustc_span/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1094,10 +1094,6 @@ pub enum ExternalSource {
Unneeded,
Foreign {
kind: ExternalSourceKind,
/// This SourceFile's byte-offset within the source_map of its original crate.
original_start_pos: BytePos,
/// The end of this SourceFile within the source_map of its original crate.
original_end_pos: BytePos,
/// Index of the file inside metadata.
metadata_index: u32,
},
Expand Down
4 changes: 1 addition & 3 deletions compiler/rustc_span/src/source_map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -336,7 +336,7 @@ impl SourceMap {
mut file_local_non_narrow_chars: Vec<NonNarrowChar>,
mut file_local_normalized_pos: Vec<NormalizedPos>,
original_start_pos: BytePos,
original_end_pos: BytePos,
_original_end_pos: BytePos,
metadata_index: u32,
) -> Lrc<SourceFile> {
let start_pos = self
Expand Down Expand Up @@ -382,8 +382,6 @@ impl SourceMap {
src_hash,
external_src: Lock::new(ExternalSource::Foreign {
kind: ExternalSourceKind::AbsentOk,
original_start_pos,
original_end_pos,
metadata_index,
}),
start_pos,
Expand Down