incr.comp.: Speed up span hashing by caching expansion context hashes.

This commit is contained in:
Michael Woerister 2017-12-07 16:46:31 +01:00
parent 8624ea5117
commit 9faa31612f
2 changed files with 37 additions and 3 deletions

View file

@ -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);
}
}
}

View file

@ -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)
}