From 510fcd318b61d0e45165cdb0de880ee2f4f9cde2 Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Wed, 17 Jan 2024 17:09:04 -0500 Subject: [PATCH] Use UnhashMap for a few more maps This avoids hashing data that's already hashed. --- compiler/rustc_data_structures/src/hashes.rs | 12 +++++++++++- .../rustc_data_structures/src/stable_hasher.rs | 14 +++++++++++++- compiler/rustc_span/src/hygiene.rs | 4 ++-- compiler/rustc_span/src/source_map.rs | 4 ++-- 4 files changed, 28 insertions(+), 6 deletions(-) diff --git a/compiler/rustc_data_structures/src/hashes.rs b/compiler/rustc_data_structures/src/hashes.rs index 291ee5bbe26e3..1564eeb4baee2 100644 --- a/compiler/rustc_data_structures/src/hashes.rs +++ b/compiler/rustc_data_structures/src/hashes.rs @@ -75,11 +75,21 @@ impl fmt::LowerHex for Hash64 { } } -#[derive(Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord, Default)] +#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Default)] pub struct Hash128 { inner: u128, } +// We expect Hash128 to be well mixed. So there's no point in hashing both parts. +// +// This also allows using Hash128-containing types in UnHash-based hashmaps, which would otherwise +// debug_assert! that we're hashing more than a single u64. +impl std::hash::Hash for Hash128 { + fn hash(&self, h: &mut H) { + h.write_u64(self.truncate().as_u64()); + } +} + impl Hash128 { #[inline] pub fn truncate(self) -> Hash64 { diff --git a/compiler/rustc_data_structures/src/stable_hasher.rs b/compiler/rustc_data_structures/src/stable_hasher.rs index afe26f80de8c8..52304c72a2f8d 100644 --- a/compiler/rustc_data_structures/src/stable_hasher.rs +++ b/compiler/rustc_data_structures/src/stable_hasher.rs @@ -314,7 +314,19 @@ impl_stable_traits_for_trivial_type!(char); impl_stable_traits_for_trivial_type!(()); impl_stable_traits_for_trivial_type!(Hash64); -impl_stable_traits_for_trivial_type!(Hash128); + +// We need a custom impl as the default hash function will only hash half the bits. For stable +// hashing we want to hash the full 128-bit hash. +impl HashStable for Hash128 { + #[inline] + fn hash_stable(&self, _: &mut CTX, hasher: &mut StableHasher) { + self.as_u128().hash(hasher); + } +} + +unsafe impl StableOrd for Hash128 { + const CAN_USE_UNSTABLE_SORT: bool = true; +} impl HashStable for ! { fn hash_stable(&self, _ctx: &mut CTX, _hasher: &mut StableHasher) { diff --git a/compiler/rustc_span/src/hygiene.rs b/compiler/rustc_span/src/hygiene.rs index d03965b539c84..5be794f3e17b9 100644 --- a/compiler/rustc_span/src/hygiene.rs +++ b/compiler/rustc_span/src/hygiene.rs @@ -330,7 +330,7 @@ pub(crate) struct HygieneData { /// would have collisions without a disambiguator. /// The keys of this map are always computed with `ExpnData.disambiguator` /// set to 0. - expn_data_disambiguators: FxHashMap, + expn_data_disambiguators: UnhashMap, } impl HygieneData { @@ -359,7 +359,7 @@ impl HygieneData { dollar_crate_name: kw::DollarCrate, }], syntax_context_map: FxHashMap::default(), - expn_data_disambiguators: FxHashMap::default(), + expn_data_disambiguators: UnhashMap::default(), } } diff --git a/compiler/rustc_span/src/source_map.rs b/compiler/rustc_span/src/source_map.rs index 72a8b23721d7f..df7635e447da8 100644 --- a/compiler/rustc_span/src/source_map.rs +++ b/compiler/rustc_span/src/source_map.rs @@ -10,8 +10,8 @@ //! information, source code snippets, etc. use crate::*; -use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::sync::{IntoDynSyncSend, MappedReadGuard, ReadGuard, RwLock}; +use rustc_data_structures::unhash::UnhashMap; use std::fs; use std::io::{self, BorrowedBuf, Read}; use std::path::{self}; @@ -164,7 +164,7 @@ impl FileLoader for RealFileLoader { #[derive(Default)] struct SourceMapFiles { source_files: monotonic::MonotonicVec>, - stable_id_to_source_file: FxHashMap>, + stable_id_to_source_file: UnhashMap>, } pub struct SourceMap {