Skip to content

Commit d73c68c

Browse files
committed
leb128-encode integers before hashing them in IchHasher.
This significantly reduces the number of bytes hashed by IchHasher.
1 parent af0b27e commit d73c68c

File tree

1 file changed

+37
-1
lines changed
  • src/librustc_incremental/calculate_svh

1 file changed

+37
-1
lines changed

src/librustc_incremental/calculate_svh/hasher.rs

+37-1
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,16 @@
99
// except according to those terms.
1010

1111
use std::mem;
12+
use std::hash::Hasher;
1213
use rustc_data_structures::blake2b::Blake2bHasher;
1314
use rustc::ty::util::ArchIndependentHasher;
1415
use ich::Fingerprint;
16+
use rustc_serialize::leb128::write_unsigned_leb128;
1517

1618
#[derive(Debug)]
1719
pub struct IchHasher {
1820
state: ArchIndependentHasher<Blake2bHasher>,
21+
leb128_helper: Vec<u8>,
1922
bytes_hashed: u64,
2023
}
2124

@@ -24,6 +27,7 @@ impl IchHasher {
2427
let hash_size = mem::size_of::<Fingerprint>();
2528
IchHasher {
2629
state: ArchIndependentHasher::new(Blake2bHasher::new(hash_size, &[])),
30+
leb128_helper: vec![],
2731
bytes_hashed: 0
2832
}
2933
}
@@ -37,9 +41,19 @@ impl IchHasher {
3741
fingerprint.0.copy_from_slice(self.state.into_inner().finalize());
3842
fingerprint
3943
}
44+
45+
#[inline]
46+
fn write_uleb128(&mut self, value: u64) {
47+
let len = write_unsigned_leb128(&mut self.leb128_helper, 0, value);
48+
self.state.write(&self.leb128_helper[0..len]);
49+
self.bytes_hashed += len as u64;
50+
}
4051
}
4152

42-
impl ::std::hash::Hasher for IchHasher {
53+
// For the non-u8 integer cases we leb128 encode them first. Because small
54+
// integers dominate, this significantly and cheaply reduces the number of
55+
// bytes hashed, which is good because blake2b is expensive.
56+
impl Hasher for IchHasher {
4357
fn finish(&self) -> u64 {
4458
bug!("Use other finish() implementation to get the full 128-bit hash.");
4559
}
@@ -49,4 +63,26 @@ impl ::std::hash::Hasher for IchHasher {
4963
self.state.write(bytes);
5064
self.bytes_hashed += bytes.len() as u64;
5165
}
66+
67+
// There is no need to leb128-encode u8 values.
68+
69+
#[inline]
70+
fn write_u16(&mut self, i: u16) {
71+
self.write_uleb128(i as u64);
72+
}
73+
74+
#[inline]
75+
fn write_u32(&mut self, i: u32) {
76+
self.write_uleb128(i as u64);
77+
}
78+
79+
#[inline]
80+
fn write_u64(&mut self, i: u64) {
81+
self.write_uleb128(i);
82+
}
83+
84+
#[inline]
85+
fn write_usize(&mut self, i: usize) {
86+
self.write_uleb128(i as u64);
87+
}
5288
}

0 commit comments

Comments
 (0)