Skip to content

Commit 74ebad4

Browse files
Use SipHasher128 in StableHasher.
1 parent 25014b5 commit 74ebad4

File tree

3 files changed

+70
-65
lines changed

3 files changed

+70
-65
lines changed

src/librustc/ich/fingerprint.rs

+3-12
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,6 @@
99
// except according to those terms.
1010

1111
use rustc_data_structures::stable_hasher;
12-
use std::mem;
13-
use std::slice;
1412

1513
#[derive(Eq, PartialEq, Ord, PartialOrd, Hash, Debug, Clone, Copy, RustcEncodable, RustcDecodable)]
1614
pub struct Fingerprint(u64, u64);
@@ -54,16 +52,9 @@ impl ::std::fmt::Display for Fingerprint {
5452
}
5553

5654
impl stable_hasher::StableHasherResult for Fingerprint {
57-
fn finish(mut hasher: stable_hasher::StableHasher<Self>) -> Self {
58-
let hash_bytes: &[u8] = hasher.finalize();
59-
60-
assert!(hash_bytes.len() >= mem::size_of::<u64>() * 2);
61-
let hash_bytes: &[u64] = unsafe {
62-
slice::from_raw_parts(hash_bytes.as_ptr() as *const u64, 2)
63-
};
64-
65-
// The bytes returned bytes the Blake2B hasher are always little-endian.
66-
Fingerprint(u64::from_le(hash_bytes[0]), u64::from_le(hash_bytes[1]))
55+
fn finish(hasher: stable_hasher::StableHasher<Self>) -> Self {
56+
let (_0, _1) = hasher.finalize();
57+
Fingerprint(_0, _1)
6758
}
6859
}
6960

src/librustc_data_structures/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
#![feature(fn_traits)]
2929
#![feature(unsize)]
3030
#![feature(i128_type)]
31+
#![feature(i128)]
3132
#![feature(conservative_impl_trait)]
3233
#![feature(specialization)]
3334

src/librustc_data_structures/stable_hasher.rs

+66-53
Original file line numberDiff line numberDiff line change
@@ -11,16 +11,7 @@
1111
use std::hash::{Hash, Hasher, BuildHasher};
1212
use std::marker::PhantomData;
1313
use std::mem;
14-
use blake2b::Blake2bHasher;
15-
use rustc_serialize::leb128;
16-
17-
fn write_unsigned_leb128_to_buf(buf: &mut [u8; 16], value: u64) -> usize {
18-
leb128::write_unsigned_leb128_to(value as u128, |i, v| buf[i] = v)
19-
}
20-
21-
fn write_signed_leb128_to_buf(buf: &mut [u8; 16], value: i64) -> usize {
22-
leb128::write_signed_leb128_to(value as i128, |i, v| buf[i] = v)
23-
}
14+
use sip128::SipHasher128;
2415

2516
/// When hashing something that ends up affecting properties like symbol names. We
2617
/// want these symbol names to be calculated independent of other factors like
@@ -41,7 +32,7 @@ fn write_signed_leb128_to_buf(buf: &mut [u8; 16], value: i64) -> usize {
4132
/// and allows for variable output lengths through its type
4233
/// parameter.
4334
pub struct StableHasher<W> {
44-
state: Blake2bHasher,
35+
state: SipHasher128,
4536
bytes_hashed: u64,
4637
width: PhantomData<W>,
4738
}
@@ -59,7 +50,7 @@ pub trait StableHasherResult: Sized {
5950
impl<W: StableHasherResult> StableHasher<W> {
6051
pub fn new() -> Self {
6152
StableHasher {
62-
state: Blake2bHasher::new(mem::size_of::<W>(), &[]),
53+
state: SipHasher128::new_with_keys(0, 0),
6354
bytes_hashed: 0,
6455
width: PhantomData,
6556
}
@@ -71,65 +62,67 @@ impl<W: StableHasherResult> StableHasher<W> {
7162
}
7263

7364
impl StableHasherResult for [u8; 20] {
74-
fn finish(mut hasher: StableHasher<Self>) -> Self {
75-
let mut result: [u8; 20] = [0; 20];
76-
result.copy_from_slice(hasher.state.finalize());
77-
result
65+
fn finish(hasher: StableHasher<Self>) -> Self {
66+
let (_0, _1) = hasher.finalize();
67+
68+
[
69+
(_0 >> 0) as u8,
70+
(_0 >> 8) as u8,
71+
(_0 >> 16) as u8,
72+
(_0 >> 24) as u8,
73+
(_0 >> 32) as u8,
74+
(_0 >> 40) as u8,
75+
(_0 >> 48) as u8,
76+
(_0 >> 56) as u8,
77+
78+
17,
79+
33,
80+
47,
81+
3,
82+
83+
(_1 >> 0) as u8,
84+
(_1 >> 8) as u8,
85+
(_1 >> 16) as u8,
86+
(_1 >> 24) as u8,
87+
(_1 >> 32) as u8,
88+
(_1 >> 40) as u8,
89+
(_1 >> 48) as u8,
90+
(_1 >> 56) as u8,
91+
]
7892
}
7993
}
8094

8195
impl StableHasherResult for u128 {
82-
fn finish(mut hasher: StableHasher<Self>) -> Self {
83-
let hash_bytes: &[u8] = hasher.finalize();
84-
assert!(hash_bytes.len() >= mem::size_of::<u128>());
85-
86-
unsafe {
87-
::std::ptr::read_unaligned(hash_bytes.as_ptr() as *const u128)
88-
}
96+
fn finish(hasher: StableHasher<Self>) -> Self {
97+
let (_0, _1) = hasher.finalize();
98+
(_0 as u128) | ((_1 as u128) << 64)
8999
}
90100
}
91101

92102
impl StableHasherResult for u64 {
93-
fn finish(mut hasher: StableHasher<Self>) -> Self {
94-
hasher.state.finalize();
95-
hasher.state.finish()
103+
fn finish(hasher: StableHasher<Self>) -> Self {
104+
hasher.finalize().0
96105
}
97106
}
98107

99108
impl<W> StableHasher<W> {
100109
#[inline]
101-
pub fn finalize(&mut self) -> &[u8] {
102-
self.state.finalize()
110+
pub fn finalize(self) -> (u64, u64) {
111+
self.state.finish128()
103112
}
104113

105114
#[inline]
106115
pub fn bytes_hashed(&self) -> u64 {
107116
self.bytes_hashed
108117
}
109-
110-
#[inline]
111-
fn write_uleb128(&mut self, value: u64) {
112-
let mut buf = [0; 16];
113-
let len = write_unsigned_leb128_to_buf(&mut buf, value);
114-
self.state.write(&buf[..len]);
115-
self.bytes_hashed += len as u64;
116-
}
117-
118-
#[inline]
119-
fn write_ileb128(&mut self, value: i64) {
120-
let mut buf = [0; 16];
121-
let len = write_signed_leb128_to_buf(&mut buf, value);
122-
self.state.write(&buf[..len]);
123-
self.bytes_hashed += len as u64;
124-
}
125118
}
126119

127120
// For the non-u8 integer cases we leb128 encode them first. Because small
128121
// integers dominate, this significantly and cheaply reduces the number of
129122
// bytes hashed, which is good because blake2b is expensive.
130123
impl<W> Hasher for StableHasher<W> {
131124
fn finish(&self) -> u64 {
132-
panic!("use StableHasher::finish instead");
125+
panic!("use StableHasher::finalize instead");
133126
}
134127

135128
#[inline]
@@ -146,22 +139,32 @@ impl<W> Hasher for StableHasher<W> {
146139

147140
#[inline]
148141
fn write_u16(&mut self, i: u16) {
149-
self.write_uleb128(i as u64);
142+
self.state.write_u16(i.to_le());
143+
self.bytes_hashed += 2;
150144
}
151145

152146
#[inline]
153147
fn write_u32(&mut self, i: u32) {
154-
self.write_uleb128(i as u64);
148+
self.state.write_u32(i.to_le());
149+
self.bytes_hashed += 4;
155150
}
156151

157152
#[inline]
158153
fn write_u64(&mut self, i: u64) {
159-
self.write_uleb128(i);
154+
self.state.write_u64(i.to_le());
155+
self.bytes_hashed += 8;
156+
}
157+
158+
#[inline]
159+
fn write_u128(&mut self, i: u128) {
160+
self.state.write_u128(i.to_le());
161+
self.bytes_hashed += 16;
160162
}
161163

162164
#[inline]
163165
fn write_usize(&mut self, i: usize) {
164-
self.write_uleb128(i as u64);
166+
self.state.write_usize(i.to_le());
167+
self.bytes_hashed += ::std::mem::size_of::<usize>() as u64;
165168
}
166169

167170
#[inline]
@@ -172,22 +175,32 @@ impl<W> Hasher for StableHasher<W> {
172175

173176
#[inline]
174177
fn write_i16(&mut self, i: i16) {
175-
self.write_ileb128(i as i64);
178+
self.state.write_i16(i.to_le());
179+
self.bytes_hashed += 2;
176180
}
177181

178182
#[inline]
179183
fn write_i32(&mut self, i: i32) {
180-
self.write_ileb128(i as i64);
184+
self.state.write_i32(i.to_le());
185+
self.bytes_hashed += 4;
181186
}
182187

183188
#[inline]
184189
fn write_i64(&mut self, i: i64) {
185-
self.write_ileb128(i);
190+
self.state.write_i64(i.to_le());
191+
self.bytes_hashed += 8;
192+
}
193+
194+
#[inline]
195+
fn write_i128(&mut self, i: i128) {
196+
self.state.write_i128(i.to_le());
197+
self.bytes_hashed += 16;
186198
}
187199

188200
#[inline]
189201
fn write_isize(&mut self, i: isize) {
190-
self.write_ileb128(i as i64);
202+
self.state.write_isize(i.to_le());
203+
self.bytes_hashed += ::std::mem::size_of::<isize>() as u64;
191204
}
192205
}
193206

0 commit comments

Comments
 (0)