@@ -13,24 +13,13 @@ use std::marker::PhantomData;
13
13
use std:: mem;
14
14
use sip128:: SipHasher128 ;
15
15
16
- /// When hashing something that ends up affecting properties like symbol names. We
17
- /// want these symbol names to be calculated independent of other factors like
18
- /// what architecture you're compiling *from*.
16
+ /// When hashing something that ends up affecting properties like symbol names,
17
+ /// we want these symbol names to be calculated independently of other factors
18
+ /// like what architecture you're compiling *from*.
19
19
///
20
- /// The hashing just uses the standard `Hash` trait, but the implementations of
21
- /// `Hash` for the `usize` and `isize` types are *not* architecture independent
22
- /// (e.g. they has 4 or 8 bytes). As a result we want to avoid `usize` and
23
- /// `isize` completely when hashing.
24
- ///
25
- /// To do that, we encode all integers to be hashed with some
26
- /// arch-independent encoding.
27
- ///
28
- /// At the moment, we pass i8/u8 straight through and encode
29
- /// all other integers using leb128.
30
- ///
31
- /// This hasher currently always uses the stable Blake2b algorithm
32
- /// and allows for variable output lengths through its type
33
- /// parameter.
20
+ /// To that end we always convert integers to little-endian format before
21
+ /// hashing and the architecture dependent `isize` and `usize` types are
22
+ /// extended to 64 bits if needed.
34
23
pub struct StableHasher < W > {
35
24
state : SipHasher128 ,
36
25
bytes_hashed : u64 ,
@@ -86,9 +75,6 @@ impl<W> StableHasher<W> {
86
75
}
87
76
}
88
77
89
- // For the non-u8 integer cases we leb128 encode them first. Because small
90
- // integers dominate, this significantly and cheaply reduces the number of
91
- // bytes hashed, which is good because blake2b is expensive.
92
78
impl < W > Hasher for StableHasher < W > {
93
79
fn finish ( & self ) -> u64 {
94
80
panic ! ( "use StableHasher::finalize instead" ) ;
@@ -132,8 +118,11 @@ impl<W> Hasher for StableHasher<W> {
132
118
133
119
#[ inline]
134
120
fn write_usize ( & mut self , i : usize ) {
135
- self . state . write_usize ( i. to_le ( ) ) ;
136
- self . bytes_hashed += :: std:: mem:: size_of :: < usize > ( ) as u64 ;
121
+ // Always treat usize as u64 so we get the same results on 32 and 64 bit
122
+ // platforms. This is important for symbol hashes when cross compiling,
123
+ // for example.
124
+ self . state . write_u64 ( ( i as u64 ) . to_le ( ) ) ;
125
+ self . bytes_hashed += 8 ;
137
126
}
138
127
139
128
#[ inline]
@@ -168,8 +157,11 @@ impl<W> Hasher for StableHasher<W> {
168
157
169
158
#[ inline]
170
159
fn write_isize ( & mut self , i : isize ) {
171
- self . state . write_isize ( i. to_le ( ) ) ;
172
- self . bytes_hashed += :: std:: mem:: size_of :: < isize > ( ) as u64 ;
160
+ // Always treat isize as i64 so we get the same results on 32 and 64 bit
161
+ // platforms. This is important for symbol hashes when cross compiling,
162
+ // for example.
163
+ self . state . write_i64 ( ( i as i64 ) . to_le ( ) ) ;
164
+ self . bytes_hashed += 8 ;
173
165
}
174
166
}
175
167
0 commit comments