Skip to content

Commit 9faa316

Browse files
incr.comp.: Speed up span hashing by caching expansion context hashes.
1 parent 8624ea5 commit 9faa316

File tree

2 files changed

+37
-3
lines changed

2 files changed

+37
-3
lines changed

src/librustc/ich/hcx.rs

+28-3
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use hir;
1212
use hir::def_id::{DefId, DefIndex};
1313
use hir::map::DefPathHash;
1414
use hir::map::definitions::Definitions;
15-
use ich::{self, CachingCodemapView};
15+
use ich::{self, CachingCodemapView, Fingerprint};
1616
use middle::cstore::CrateStore;
1717
use ty::{TyCtxt, fast_reject};
1818
use session::Session;
@@ -28,12 +28,13 @@ use syntax::codemap::CodeMap;
2828
use syntax::ext::hygiene::SyntaxContext;
2929
use syntax::symbol::Symbol;
3030
use syntax_pos::{Span, DUMMY_SP};
31+
use syntax_pos::hygiene;
3132

3233
use rustc_data_structures::stable_hasher::{HashStable, StableHashingContextProvider,
3334
StableHasher, StableHasherResult,
3435
ToStableHashKey};
3536
use rustc_data_structures::accumulate_vec::AccumulateVec;
36-
use rustc_data_structures::fx::FxHashSet;
37+
use rustc_data_structures::fx::{FxHashSet, FxHashMap};
3738

3839
thread_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
}

src/libsyntax_pos/hygiene.rs

+9
Original file line numberDiff line numberDiff line change
@@ -60,22 +60,27 @@ impl Mark {
6060
}
6161

6262
/// The mark of the theoretical expansion that generates freshly parsed, unexpanded AST.
63+
#[inline]
6364
pub fn root() -> Self {
6465
Mark(0)
6566
}
6667

68+
#[inline]
6769
pub fn as_u32(self) -> u32 {
6870
self.0
6971
}
7072

73+
#[inline]
7174
pub fn from_u32(raw: u32) -> Mark {
7275
Mark(raw)
7376
}
7477

78+
#[inline]
7579
pub fn expn_info(self) -> Option<ExpnInfo> {
7680
HygieneData::with(|data| data.marks[self.0 as usize].expn_info.clone())
7781
}
7882

83+
#[inline]
7984
pub fn set_expn_info(self, info: ExpnInfo) {
8085
HygieneData::with(|data| data.marks[self.0 as usize].expn_info = Some(info))
8186
}
@@ -91,10 +96,12 @@ impl Mark {
9196
})
9297
}
9398

99+
#[inline]
94100
pub fn kind(self) -> MarkKind {
95101
HygieneData::with(|data| data.marks[self.0 as usize].kind)
96102
}
97103

104+
#[inline]
98105
pub fn set_kind(self, kind: MarkKind) {
99106
HygieneData::with(|data| data.marks[self.0 as usize].kind = kind)
100107
}
@@ -309,10 +316,12 @@ impl SyntaxContext {
309316
Some(scope)
310317
}
311318

319+
#[inline]
312320
pub fn modern(self) -> SyntaxContext {
313321
HygieneData::with(|data| data.syntax_contexts[self.0 as usize].modern)
314322
}
315323

324+
#[inline]
316325
pub fn outer(self) -> Mark {
317326
HygieneData::with(|data| data.syntax_contexts[self.0 as usize].outer_mark)
318327
}

0 commit comments

Comments
 (0)