diff options
| author | Michael Woerister <michaelwoerister@posteo> | 2017-12-07 16:46:31 +0100 |
|---|---|---|
| committer | Michael Woerister <michaelwoerister@posteo> | 2017-12-14 10:15:10 -0600 |
| commit | 9faa31612fb7a847a1c85836996846b9a6f20116 (patch) | |
| tree | 64ebfef720abdccff8f316c8841929ab7f6617e6 | |
| parent | 8624ea51172c8a86d5c7c47d740be65a3a9efbc6 (diff) | |
| download | rust-9faa31612fb7a847a1c85836996846b9a6f20116.tar.gz rust-9faa31612fb7a847a1c85836996846b9a6f20116.zip | |
incr.comp.: Speed up span hashing by caching expansion context hashes.
| -rw-r--r-- | src/librustc/ich/hcx.rs | 31 | ||||
| -rw-r--r-- | src/libsyntax_pos/hygiene.rs | 9 |
2 files changed, 37 insertions, 3 deletions
diff --git a/src/librustc/ich/hcx.rs b/src/librustc/ich/hcx.rs index 0ef42177c14..2d20836814c 100644 --- a/src/librustc/ich/hcx.rs +++ b/src/librustc/ich/hcx.rs @@ -12,7 +12,7 @@ use hir; use hir::def_id::{DefId, DefIndex}; use hir::map::DefPathHash; use hir::map::definitions::Definitions; -use ich::{self, CachingCodemapView}; +use ich::{self, CachingCodemapView, Fingerprint}; use middle::cstore::CrateStore; use ty::{TyCtxt, fast_reject}; use session::Session; @@ -28,12 +28,13 @@ use syntax::codemap::CodeMap; use syntax::ext::hygiene::SyntaxContext; use syntax::symbol::Symbol; use syntax_pos::{Span, DUMMY_SP}; +use syntax_pos::hygiene; use rustc_data_structures::stable_hasher::{HashStable, StableHashingContextProvider, StableHasher, StableHasherResult, ToStableHashKey}; use rustc_data_structures::accumulate_vec::AccumulateVec; -use rustc_data_structures::fx::FxHashSet; +use rustc_data_structures::fx::{FxHashSet, FxHashMap}; thread_local!(static IGNORED_ATTR_NAMES: RefCell<FxHashSet<Symbol>> = RefCell::new(FxHashSet())); @@ -349,7 +350,31 @@ impl<'gcx> HashStable<StableHashingContext<'gcx>> for Span { TAG_NO_EXPANSION.hash_stable(hcx, hasher); } else { TAG_EXPANSION.hash_stable(hcx, hasher); - span.ctxt.outer().expn_info().hash_stable(hcx, hasher); + + // Since the same expansion context is usually referenced many + // times, we cache a stable hash of it and hash that instead of + // recursing every time. + thread_local! { + static CACHE: RefCell<FxHashMap<hygiene::Mark, u64>> = + RefCell::new(FxHashMap()); + } + + let sub_hash: u64 = CACHE.with(|cache| { + let mark = span.ctxt.outer(); + + if let Some(&sub_hash) = cache.borrow().get(&mark) { + return sub_hash; + } + + let mut hasher = StableHasher::new(); + mark.expn_info().hash_stable(hcx, &mut hasher); + let sub_hash: Fingerprint = hasher.finish(); + let sub_hash = sub_hash.to_smaller_hash(); + cache.borrow_mut().insert(mark, sub_hash); + sub_hash + }); + + sub_hash.hash_stable(hcx, hasher); } } } diff --git a/src/libsyntax_pos/hygiene.rs b/src/libsyntax_pos/hygiene.rs index ab6c3f7d62d..55342c2768a 100644 --- a/src/libsyntax_pos/hygiene.rs +++ b/src/libsyntax_pos/hygiene.rs @@ -60,22 +60,27 @@ impl Mark { } /// The mark of the theoretical expansion that generates freshly parsed, unexpanded AST. + #[inline] pub fn root() -> Self { Mark(0) } + #[inline] pub fn as_u32(self) -> u32 { self.0 } + #[inline] pub fn from_u32(raw: u32) -> Mark { Mark(raw) } + #[inline] pub fn expn_info(self) -> Option<ExpnInfo> { HygieneData::with(|data| data.marks[self.0 as usize].expn_info.clone()) } + #[inline] pub fn set_expn_info(self, info: ExpnInfo) { HygieneData::with(|data| data.marks[self.0 as usize].expn_info = Some(info)) } @@ -91,10 +96,12 @@ impl Mark { }) } + #[inline] pub fn kind(self) -> MarkKind { HygieneData::with(|data| data.marks[self.0 as usize].kind) } + #[inline] pub fn set_kind(self, kind: MarkKind) { HygieneData::with(|data| data.marks[self.0 as usize].kind = kind) } @@ -309,10 +316,12 @@ impl SyntaxContext { Some(scope) } + #[inline] pub fn modern(self) -> SyntaxContext { HygieneData::with(|data| data.syntax_contexts[self.0 as usize].modern) } + #[inline] pub fn outer(self) -> Mark { HygieneData::with(|data| data.syntax_contexts[self.0 as usize].outer_mark) } |
