1111//! This module contains `HashStable` implementations for various data types
1212//! from rustc::ty in no particular order.
1313
14- use ich:: { StableHashingContext , NodeIdHashingMode } ;
14+ use ich:: { Fingerprint , StableHashingContext , NodeIdHashingMode } ;
15+ use rustc_data_structures:: fx:: FxHashMap ;
1516use rustc_data_structures:: stable_hasher:: { HashStable , ToStableHashKey ,
1617 StableHasher , StableHasherResult } ;
18+ use std:: cell:: RefCell ;
1719use std:: hash as std_hash;
1820use std:: mem;
1921use middle:: region;
@@ -26,7 +28,26 @@ for &'gcx ty::Slice<T>
2628 fn hash_stable < W : StableHasherResult > ( & self ,
2729 hcx : & mut StableHashingContext < ' gcx > ,
2830 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) ;
3051 }
3152}
3253
0 commit comments