From 74ebad4b63ce2ccaa6051b60031a6597ee4468ec Mon Sep 17 00:00:00 2001 From: Michael Woerister Date: Mon, 16 Oct 2017 14:06:07 +0200 Subject: Use SipHasher128 in StableHasher. --- src/librustc/ich/fingerprint.rs | 15 +--- src/librustc_data_structures/lib.rs | 1 + src/librustc_data_structures/stable_hasher.rs | 119 ++++++++++++++------------ 3 files changed, 70 insertions(+), 65 deletions(-) (limited to 'src') diff --git a/src/librustc/ich/fingerprint.rs b/src/librustc/ich/fingerprint.rs index 2391b61253a..f3bb3b38566 100644 --- a/src/librustc/ich/fingerprint.rs +++ b/src/librustc/ich/fingerprint.rs @@ -9,8 +9,6 @@ // except according to those terms. use rustc_data_structures::stable_hasher; -use std::mem; -use std::slice; #[derive(Eq, PartialEq, Ord, PartialOrd, Hash, Debug, Clone, Copy, RustcEncodable, RustcDecodable)] pub struct Fingerprint(u64, u64); @@ -54,16 +52,9 @@ impl ::std::fmt::Display for Fingerprint { } impl stable_hasher::StableHasherResult for Fingerprint { - fn finish(mut hasher: stable_hasher::StableHasher) -> Self { - let hash_bytes: &[u8] = hasher.finalize(); - - assert!(hash_bytes.len() >= mem::size_of::() * 2); - let hash_bytes: &[u64] = unsafe { - slice::from_raw_parts(hash_bytes.as_ptr() as *const u64, 2) - }; - - // The bytes returned bytes the Blake2B hasher are always little-endian. - Fingerprint(u64::from_le(hash_bytes[0]), u64::from_le(hash_bytes[1])) + fn finish(hasher: stable_hasher::StableHasher) -> Self { + let (_0, _1) = hasher.finalize(); + Fingerprint(_0, _1) } } diff --git a/src/librustc_data_structures/lib.rs b/src/librustc_data_structures/lib.rs index 1277123d700..3a20343033c 100644 --- a/src/librustc_data_structures/lib.rs +++ b/src/librustc_data_structures/lib.rs @@ -28,6 +28,7 @@ #![feature(fn_traits)] #![feature(unsize)] #![feature(i128_type)] +#![feature(i128)] #![feature(conservative_impl_trait)] #![feature(specialization)] diff --git a/src/librustc_data_structures/stable_hasher.rs b/src/librustc_data_structures/stable_hasher.rs index 9aba48c5bef..3e526900110 100644 --- a/src/librustc_data_structures/stable_hasher.rs +++ b/src/librustc_data_structures/stable_hasher.rs @@ -11,16 +11,7 @@ use std::hash::{Hash, Hasher, BuildHasher}; use std::marker::PhantomData; use std::mem; -use blake2b::Blake2bHasher; -use rustc_serialize::leb128; - -fn write_unsigned_leb128_to_buf(buf: &mut [u8; 16], value: u64) -> usize { - leb128::write_unsigned_leb128_to(value as u128, |i, v| buf[i] = v) -} - -fn write_signed_leb128_to_buf(buf: &mut [u8; 16], value: i64) -> usize { - leb128::write_signed_leb128_to(value as i128, |i, v| buf[i] = v) -} +use sip128::SipHasher128; /// When hashing something that ends up affecting properties like symbol names. We /// 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 { /// and allows for variable output lengths through its type /// parameter. pub struct StableHasher { - state: Blake2bHasher, + state: SipHasher128, bytes_hashed: u64, width: PhantomData, } @@ -59,7 +50,7 @@ pub trait StableHasherResult: Sized { impl StableHasher { pub fn new() -> Self { StableHasher { - state: Blake2bHasher::new(mem::size_of::(), &[]), + state: SipHasher128::new_with_keys(0, 0), bytes_hashed: 0, width: PhantomData, } @@ -71,57 +62,59 @@ impl StableHasher { } impl StableHasherResult for [u8; 20] { - fn finish(mut hasher: StableHasher) -> Self { - let mut result: [u8; 20] = [0; 20]; - result.copy_from_slice(hasher.state.finalize()); - result + fn finish(hasher: StableHasher) -> Self { + let (_0, _1) = hasher.finalize(); + + [ + (_0 >> 0) as u8, + (_0 >> 8) as u8, + (_0 >> 16) as u8, + (_0 >> 24) as u8, + (_0 >> 32) as u8, + (_0 >> 40) as u8, + (_0 >> 48) as u8, + (_0 >> 56) as u8, + + 17, + 33, + 47, + 3, + + (_1 >> 0) as u8, + (_1 >> 8) as u8, + (_1 >> 16) as u8, + (_1 >> 24) as u8, + (_1 >> 32) as u8, + (_1 >> 40) as u8, + (_1 >> 48) as u8, + (_1 >> 56) as u8, + ] } } impl StableHasherResult for u128 { - fn finish(mut hasher: StableHasher) -> Self { - let hash_bytes: &[u8] = hasher.finalize(); - assert!(hash_bytes.len() >= mem::size_of::()); - - unsafe { - ::std::ptr::read_unaligned(hash_bytes.as_ptr() as *const u128) - } + fn finish(hasher: StableHasher) -> Self { + let (_0, _1) = hasher.finalize(); + (_0 as u128) | ((_1 as u128) << 64) } } impl StableHasherResult for u64 { - fn finish(mut hasher: StableHasher) -> Self { - hasher.state.finalize(); - hasher.state.finish() + fn finish(hasher: StableHasher) -> Self { + hasher.finalize().0 } } impl StableHasher { #[inline] - pub fn finalize(&mut self) -> &[u8] { - self.state.finalize() + pub fn finalize(self) -> (u64, u64) { + self.state.finish128() } #[inline] pub fn bytes_hashed(&self) -> u64 { self.bytes_hashed } - - #[inline] - fn write_uleb128(&mut self, value: u64) { - let mut buf = [0; 16]; - let len = write_unsigned_leb128_to_buf(&mut buf, value); - self.state.write(&buf[..len]); - self.bytes_hashed += len as u64; - } - - #[inline] - fn write_ileb128(&mut self, value: i64) { - let mut buf = [0; 16]; - let len = write_signed_leb128_to_buf(&mut buf, value); - self.state.write(&buf[..len]); - self.bytes_hashed += len as u64; - } } // For the non-u8 integer cases we leb128 encode them first. Because small @@ -129,7 +122,7 @@ impl StableHasher { // bytes hashed, which is good because blake2b is expensive. impl Hasher for StableHasher { fn finish(&self) -> u64 { - panic!("use StableHasher::finish instead"); + panic!("use StableHasher::finalize instead"); } #[inline] @@ -146,22 +139,32 @@ impl Hasher for StableHasher { #[inline] fn write_u16(&mut self, i: u16) { - self.write_uleb128(i as u64); + self.state.write_u16(i.to_le()); + self.bytes_hashed += 2; } #[inline] fn write_u32(&mut self, i: u32) { - self.write_uleb128(i as u64); + self.state.write_u32(i.to_le()); + self.bytes_hashed += 4; } #[inline] fn write_u64(&mut self, i: u64) { - self.write_uleb128(i); + self.state.write_u64(i.to_le()); + self.bytes_hashed += 8; + } + + #[inline] + fn write_u128(&mut self, i: u128) { + self.state.write_u128(i.to_le()); + self.bytes_hashed += 16; } #[inline] fn write_usize(&mut self, i: usize) { - self.write_uleb128(i as u64); + self.state.write_usize(i.to_le()); + self.bytes_hashed += ::std::mem::size_of::() as u64; } #[inline] @@ -172,22 +175,32 @@ impl Hasher for StableHasher { #[inline] fn write_i16(&mut self, i: i16) { - self.write_ileb128(i as i64); + self.state.write_i16(i.to_le()); + self.bytes_hashed += 2; } #[inline] fn write_i32(&mut self, i: i32) { - self.write_ileb128(i as i64); + self.state.write_i32(i.to_le()); + self.bytes_hashed += 4; } #[inline] fn write_i64(&mut self, i: i64) { - self.write_ileb128(i); + self.state.write_i64(i.to_le()); + self.bytes_hashed += 8; + } + + #[inline] + fn write_i128(&mut self, i: i128) { + self.state.write_i128(i.to_le()); + self.bytes_hashed += 16; } #[inline] fn write_isize(&mut self, i: isize) { - self.write_ileb128(i as i64); + self.state.write_isize(i.to_le()); + self.bytes_hashed += ::std::mem::size_of::() as u64; } } -- cgit 1.4.1-3-g733a5