incr.comp.: Speed up span hashing by caching expansion context hashes.
This commit is contained in:
parent
8624ea5117
commit
9faa31612f
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user