From 45bd091e76db5a743a2f251612408e77a2610099 Mon Sep 17 00:00:00 2001 From: Wesley Wiser Date: Thu, 11 Jan 2018 23:01:27 -0500 Subject: [PATCH] [incremental] Cache ty::Slice hashes Fixes #47294 --- src/librustc/ich/impls_ty.rs | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/src/librustc/ich/impls_ty.rs b/src/librustc/ich/impls_ty.rs index ea3a1074aa269..4ae114c4e69da 100644 --- a/src/librustc/ich/impls_ty.rs +++ b/src/librustc/ich/impls_ty.rs @@ -11,9 +11,11 @@ //! This module contains `HashStable` implementations for various data types //! from rustc::ty in no particular order. -use ich::{StableHashingContext, NodeIdHashingMode}; +use ich::{Fingerprint, StableHashingContext, NodeIdHashingMode}; +use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::stable_hasher::{HashStable, ToStableHashKey, StableHasher, StableHasherResult}; +use std::cell::RefCell; use std::hash as std_hash; use std::mem; use middle::region; @@ -26,7 +28,26 @@ for &'gcx ty::Slice fn hash_stable(&self, hcx: &mut StableHashingContext<'gcx>, hasher: &mut StableHasher) { - (&self[..]).hash_stable(hcx, hasher); + thread_local! { + static CACHE: RefCell> = + RefCell::new(FxHashMap()); + } + + let hash = CACHE.with(|cache| { + let key = (self.as_ptr() as usize, self.len()); + if let Some(&hash) = cache.borrow().get(&key) { + return hash; + } + + let mut hasher = StableHasher::new(); + (&self[..]).hash_stable(hcx, &mut hasher); + + let hash: Fingerprint = hasher.finish(); + cache.borrow_mut().insert(key, hash); + hash + }); + + hash.hash_stable(hcx, hasher); } }