@@ -12,7 +12,7 @@ use hir;
12
12
use hir:: def_id:: { DefId , DefIndex } ;
13
13
use hir:: map:: DefPathHash ;
14
14
use hir:: map:: definitions:: Definitions ;
15
- use ich:: { self , CachingCodemapView } ;
15
+ use ich:: { self , CachingCodemapView , Fingerprint } ;
16
16
use middle:: cstore:: CrateStore ;
17
17
use ty:: { TyCtxt , fast_reject} ;
18
18
use session:: Session ;
@@ -28,12 +28,13 @@ use syntax::codemap::CodeMap;
28
28
use syntax:: ext:: hygiene:: SyntaxContext ;
29
29
use syntax:: symbol:: Symbol ;
30
30
use syntax_pos:: { Span , DUMMY_SP } ;
31
+ use syntax_pos:: hygiene;
31
32
32
33
use rustc_data_structures:: stable_hasher:: { HashStable , StableHashingContextProvider ,
33
34
StableHasher , StableHasherResult ,
34
35
ToStableHashKey } ;
35
36
use rustc_data_structures:: accumulate_vec:: AccumulateVec ;
36
- use rustc_data_structures:: fx:: FxHashSet ;
37
+ use rustc_data_structures:: fx:: { FxHashSet , FxHashMap } ;
37
38
38
39
thread_local ! ( static IGNORED_ATTR_NAMES : RefCell <FxHashSet <Symbol >> =
39
40
RefCell :: new( FxHashSet ( ) ) ) ;
@@ -349,7 +350,31 @@ impl<'gcx> HashStable<StableHashingContext<'gcx>> for Span {
349
350
TAG_NO_EXPANSION . hash_stable ( hcx, hasher) ;
350
351
} else {
351
352
TAG_EXPANSION . hash_stable ( hcx, hasher) ;
352
- span. ctxt . outer ( ) . expn_info ( ) . hash_stable ( hcx, hasher) ;
353
+
354
+ // Since the same expansion context is usually referenced many
355
+ // times, we cache a stable hash of it and hash that instead of
356
+ // recursing every time.
357
+ thread_local ! {
358
+ static CACHE : RefCell <FxHashMap <hygiene:: Mark , u64 >> =
359
+ RefCell :: new( FxHashMap ( ) ) ;
360
+ }
361
+
362
+ let sub_hash: u64 = CACHE . with ( |cache| {
363
+ let mark = span. ctxt . outer ( ) ;
364
+
365
+ if let Some ( & sub_hash) = cache. borrow ( ) . get ( & mark) {
366
+ return sub_hash;
367
+ }
368
+
369
+ let mut hasher = StableHasher :: new ( ) ;
370
+ mark. expn_info ( ) . hash_stable ( hcx, & mut hasher) ;
371
+ let sub_hash: Fingerprint = hasher. finish ( ) ;
372
+ let sub_hash = sub_hash. to_smaller_hash ( ) ;
373
+ cache. borrow_mut ( ) . insert ( mark, sub_hash) ;
374
+ sub_hash
375
+ } ) ;
376
+
377
+ sub_hash. hash_stable ( hcx, hasher) ;
353
378
}
354
379
}
355
380
}
0 commit comments