Skip to content

Commit 0b81d7c

Browse files
committed
Lazify SourceFile::lines.
`SourceFile::lines` is a big part of metadata. It's stored in a compressed form (a difference list) to save disk space. Decoding it is a big fraction of compile time for very small crates/programs. This commit introduces a new type `SourceFileLines` which has a `Lines` form and a `Diffs` form. The latter is used when the metadata is first read, and it is only decoded into the `Lines` form when line data is actually needed. This avoids the decoding cost for many files, especially in `std`. It's a performance win of up to 15% for tiny crates/programs where metadata decoding is a high part of compilation costs. A `Lock` is needed because the methods that access lines data (which can trigger decoding) take `&self` rather than `&mut self`. To allow for this, `SourceFile::lines` now takes a `FnMut` that operates on the lines slice rather than returning the lines slice.
1 parent bef2b7c commit 0b81d7c

File tree

8 files changed

+218
-121
lines changed

8 files changed

+218
-121
lines changed

compiler/rustc_query_impl/src/on_disk_cache.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -713,7 +713,7 @@ impl<'a, 'tcx> Decodable<CacheDecoder<'a, 'tcx>> for Span {
713713
let len = BytePos::decode(decoder);
714714

715715
let file_lo = decoder.file_index_to_file(file_lo_index);
716-
let lo = file_lo.lines[line_lo - 1] + col_lo;
716+
let lo = file_lo.lines(|lines| lines[line_lo - 1] + col_lo);
717717
let hi = lo + len;
718718

719719
Span::new(lo, hi, ctxt, parent)

compiler/rustc_query_system/src/ich/impls_syntax.rs

+12-5
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use crate::ich::StableHashingContext;
55

66
use rustc_ast as ast;
77
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
8-
use rustc_span::{BytePos, NormalizedPos, SourceFile};
8+
use rustc_span::{BytePos, NormalizedPos, SourceFile, SourceFileLines};
99
use std::assert_matches::assert_matches;
1010

1111
use smallvec::SmallVec;
@@ -60,7 +60,7 @@ impl<'ctx> rustc_ast::HashStableContext for StableHashingContext<'ctx> {
6060
impl<'a> HashStable<StableHashingContext<'a>> for SourceFile {
6161
fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
6262
let SourceFile {
63-
name: _, // We hash the smaller name_hash instead of this
63+
ref name, // We hash the smaller name_hash instead of this
6464
name_hash,
6565
cnum,
6666
// Do not hash the source as it is not encoded
@@ -80,9 +80,16 @@ impl<'a> HashStable<StableHashingContext<'a>> for SourceFile {
8080
src_hash.hash_stable(hcx, hasher);
8181

8282
// We only hash the relative position within this source_file
83-
lines.len().hash_stable(hcx, hasher);
84-
for &line in lines.iter() {
85-
stable_byte_pos(line, start_pos).hash_stable(hcx, hasher);
83+
match &*lines.borrow() {
84+
SourceFileLines::Lines { lines } => {
85+
lines.len().hash_stable(hcx, hasher);
86+
for &line in lines.iter() {
87+
stable_byte_pos(line, start_pos).hash_stable(hcx, hasher);
88+
}
89+
}
90+
SourceFileLines::Diffs { .. } => {
91+
panic!("called hash_stable on SourceFileLines::Diffs for {:?}", name);
92+
}
8693
}
8794

8895
// We only hash the relative position within this source_file

0 commit comments

Comments
 (0)