Rollup merge of #46839 - michaelwoerister:faster-span-hashing-2, r=nikomatsakis

incr.comp.: Precompute small hash for filenames to save some work.

For each span we hash the filename of the file it points to. Since filenames can be quite long, especially with absolute paths, this PR pre-computes a hash of the filename and we then only hash the hash.

r? @nikomatsakis
This commit is contained in:
kennytm 2017-12-22 02:50:51 +08:00 committed by GitHub
commit 614e285fa9
6 changed files with 36 additions and 8 deletions

View file

@ -341,7 +341,7 @@ impl<'gcx> HashStable<StableHashingContext<'gcx>> for Span {
std_hash::Hash::hash(&TAG_VALID_SPAN, hasher);
// We truncate the stable_id hash and line and col numbers. The chances
// of causing a collision this way should be minimal.
std_hash::Hash::hash(&file_lo.name, hasher);
std_hash::Hash::hash(&(file_lo.name_hash as u64), hasher);
let col = (col_lo.0 as u64) & 0xFF;
let line = ((line_lo as u64) & 0xFF_FF_FF) << 8;

View file

@ -387,7 +387,8 @@ impl<'gcx> HashStable<StableHashingContext<'gcx>> for FileMap {
hcx: &mut StableHashingContext<'gcx>,
hasher: &mut StableHasher<W>) {
let FileMap {
ref name,
name: _, // We hash the smaller name_hash instead of this
name_hash,
name_was_remapped,
unmapped_path: _,
crate_of_origin,
@ -402,7 +403,7 @@ impl<'gcx> HashStable<StableHashingContext<'gcx>> for FileMap {
ref non_narrow_chars,
} = *self;
name.hash_stable(hcx, hasher);
(name_hash as u64).hash_stable(hcx, hasher);
name_was_remapped.hash_stable(hcx, hasher);
DefId {

View file

@ -1129,6 +1129,7 @@ impl<'a, 'tcx> CrateMetadata {
lines,
multibyte_chars,
non_narrow_chars,
name_hash,
.. } = filemap_to_import;
let source_length = (end_pos - start_pos).to_usize();
@ -1155,6 +1156,7 @@ impl<'a, 'tcx> CrateMetadata {
name_was_remapped,
self.cnum.as_u32(),
src_hash,
name_hash,
source_length,
lines,
multibyte_chars,

View file

@ -28,8 +28,10 @@ use rustc::ty::codec::{self as ty_codec, TyEncoder};
use rustc::session::config::{self, CrateTypeProcMacro};
use rustc::util::nodemap::{FxHashMap, NodeSet};
use rustc_data_structures::stable_hasher::StableHasher;
use rustc_serialize::{Encodable, Encoder, SpecializedEncoder, opaque};
use std::hash::Hash;
use std::io::prelude::*;
use std::io::Cursor;
use std::path::Path;
@ -290,6 +292,11 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
} else {
let mut adapted = (**filemap).clone();
adapted.name = Path::new(&working_dir).join(name).into();
adapted.name_hash = {
let mut hasher: StableHasher<u128> = StableHasher::new();
adapted.name.hash(&mut hasher);
hasher.finish()
};
Rc::new(adapted)
}
},

View file

@ -246,6 +246,7 @@ impl CodeMap {
name_was_remapped: bool,
crate_of_origin: u32,
src_hash: u128,
name_hash: u128,
source_len: usize,
mut file_local_lines: Vec<BytePos>,
mut file_local_multibyte_chars: Vec<MultiByteChar>,
@ -282,6 +283,7 @@ impl CodeMap {
lines: RefCell::new(file_local_lines),
multibyte_chars: RefCell::new(file_local_multibyte_chars),
non_narrow_chars: RefCell::new(file_local_non_narrow_chars),
name_hash,
});
files.push(filemap.clone());

View file

@ -30,7 +30,7 @@ use std::borrow::Cow;
use std::cell::{Cell, RefCell};
use std::cmp::{self, Ordering};
use std::fmt;
use std::hash::Hasher;
use std::hash::{Hasher, Hash};
use std::ops::{Add, Sub};
use std::path::PathBuf;
use std::rc::Rc;
@ -691,6 +691,8 @@ pub struct FileMap {
pub multibyte_chars: RefCell<Vec<MultiByteChar>>,
/// Width of characters that are not narrow in the source code
pub non_narrow_chars: RefCell<Vec<NonNarrowChar>>,
/// A hash of the filename, used for speeding up the incr. comp. hashing.
pub name_hash: u128,
}
impl Encodable for FileMap {
@ -752,6 +754,9 @@ impl Encodable for FileMap {
})?;
s.emit_struct_field("non_narrow_chars", 8, |s| {
(*self.non_narrow_chars.borrow()).encode(s)
})?;
s.emit_struct_field("name_hash", 9, |s| {
self.name_hash.encode(s)
})
})
}
@ -801,6 +806,8 @@ impl Decodable for FileMap {
d.read_struct_field("multibyte_chars", 7, |d| Decodable::decode(d))?;
let non_narrow_chars: Vec<NonNarrowChar> =
d.read_struct_field("non_narrow_chars", 8, |d| Decodable::decode(d))?;
let name_hash: u128 =
d.read_struct_field("name_hash", 9, |d| Decodable::decode(d))?;
Ok(FileMap {
name,
name_was_remapped,
@ -816,7 +823,8 @@ impl Decodable for FileMap {
external_src: RefCell::new(ExternalSource::AbsentOk),
lines: RefCell::new(lines),
multibyte_chars: RefCell::new(multibyte_chars),
non_narrow_chars: RefCell::new(non_narrow_chars)
non_narrow_chars: RefCell::new(non_narrow_chars),
name_hash,
})
})
}
@ -836,9 +844,16 @@ impl FileMap {
start_pos: BytePos) -> FileMap {
remove_bom(&mut src);
let mut hasher: StableHasher<u128> = StableHasher::new();
hasher.write(src.as_bytes());
let src_hash = hasher.finish();
let src_hash = {
let mut hasher: StableHasher<u128> = StableHasher::new();
hasher.write(src.as_bytes());
hasher.finish()
};
let name_hash = {
let mut hasher: StableHasher<u128> = StableHasher::new();
name.hash(&mut hasher);
hasher.finish()
};
let end_pos = start_pos.to_usize() + src.len();
FileMap {
@ -854,6 +869,7 @@ impl FileMap {
lines: RefCell::new(Vec::new()),
multibyte_chars: RefCell::new(Vec::new()),
non_narrow_chars: RefCell::new(Vec::new()),
name_hash,
}
}