11
11
//! This module contains `HashStable` implementations for various data types
12
12
//! from rustc::ty in no particular order.
13
13
14
- use ich:: { StableHashingContext , NodeIdHashingMode } ;
14
+ use ich:: { Fingerprint , StableHashingContext , NodeIdHashingMode } ;
15
+ use rustc_data_structures:: fx:: FxHashMap ;
15
16
use rustc_data_structures:: stable_hasher:: { HashStable , ToStableHashKey ,
16
17
StableHasher , StableHasherResult } ;
18
+ use std:: cell:: RefCell ;
17
19
use std:: hash as std_hash;
18
20
use std:: mem;
19
21
use middle:: region;
@@ -26,7 +28,26 @@ for &'gcx ty::Slice<T>
26
28
fn hash_stable < W : StableHasherResult > ( & self ,
27
29
hcx : & mut StableHashingContext < ' gcx > ,
28
30
hasher : & mut StableHasher < W > ) {
29
- ( & self [ ..] ) . hash_stable ( hcx, hasher) ;
31
+ thread_local ! {
32
+ static CACHE : RefCell <FxHashMap <( usize , usize ) , Fingerprint >> =
33
+ RefCell :: new( FxHashMap ( ) ) ;
34
+ }
35
+
36
+ let hash = CACHE . with ( |cache| {
37
+ let key = ( self . as_ptr ( ) as usize , self . len ( ) ) ;
38
+ if let Some ( & hash) = cache. borrow ( ) . get ( & key) {
39
+ return hash;
40
+ }
41
+
42
+ let mut hasher = StableHasher :: new ( ) ;
43
+ ( & self [ ..] ) . hash_stable ( hcx, & mut hasher) ;
44
+
45
+ let hash: Fingerprint = hasher. finish ( ) ;
46
+ cache. borrow_mut ( ) . insert ( key, hash) ;
47
+ hash
48
+ } ) ;
49
+
50
+ hash. hash_stable ( hcx, hasher) ;
30
51
}
31
52
}
32
53
0 commit comments