@@ -12,7 +12,7 @@ use hir;
1212use hir:: def_id:: { DefId , DefIndex } ;
1313use hir:: map:: DefPathHash ;
1414use hir:: map:: definitions:: Definitions ;
15- use ich:: { self , CachingCodemapView } ;
15+ use ich:: { self , CachingCodemapView , Fingerprint } ;
1616use middle:: cstore:: CrateStore ;
1717use ty:: { TyCtxt , fast_reject} ;
1818use session:: Session ;
@@ -28,12 +28,13 @@ use syntax::codemap::CodeMap;
2828use syntax:: ext:: hygiene:: SyntaxContext ;
2929use syntax:: symbol:: Symbol ;
3030use syntax_pos:: { Span , DUMMY_SP } ;
31+ use syntax_pos:: hygiene;
3132
3233use rustc_data_structures:: stable_hasher:: { HashStable , StableHashingContextProvider ,
3334 StableHasher , StableHasherResult ,
3435 ToStableHashKey } ;
3536use rustc_data_structures:: accumulate_vec:: AccumulateVec ;
36- use rustc_data_structures:: fx:: FxHashSet ;
37+ use rustc_data_structures:: fx:: { FxHashSet , FxHashMap } ;
3738
3839thread_local ! ( static IGNORED_ATTR_NAMES : RefCell <FxHashSet <Symbol >> =
3940 RefCell :: new( FxHashSet ( ) ) ) ;
@@ -349,7 +350,31 @@ impl<'gcx> HashStable<StableHashingContext<'gcx>> for Span {
349350 TAG_NO_EXPANSION . hash_stable ( hcx, hasher) ;
350351 } else {
351352 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) ;
353378 }
354379 }
355380}
0 commit comments