Skip to content

Commit 30837cb

Browse files
committed
Auto merge of #155550 - zetanumbers:cache_insert_unique, r=oli-obk
Replace `ShardedHashMap` method `insert` with debug-checked `insert_unique` Currently every use of `ShardedHashMap::insert` checks that it won't evict an old value due to unique key. I haven't found any issue related to that faulty condition, so I thought of replacing it with `ShardedHashMap::insert_unique` which doesn't check for this condition unless `debug_assertions` are enabled. This might improve the performance. r? @petrochenkov
2 parents 913e4be + fa4d2ad commit 30837cb

3 files changed

Lines changed: 25 additions & 24 deletions

File tree

compiler/rustc_data_structures/src/sharded.rs

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use std::borrow::Borrow;
22
use std::hash::{Hash, Hasher};
3-
use std::{iter, mem};
3+
use std::iter;
44

55
use either::Either;
66
use hashbrown::hash_table::{self, Entry, HashTable};
@@ -183,19 +183,27 @@ impl<K: Eq + Hash, V> ShardedHashMap<K, V> {
183183
}
184184
}
185185

186+
/// Insert value into the [`ShardedHashMap`] with unique key.
187+
///
188+
/// This function panics if debug_assertions are enabled and uniqueness is violated.
189+
/// If uniqueness is violated but debug_assertions are disabled then lookups will arbitrarily
190+
/// return one of the inserted elements.
186191
#[inline]
187-
pub fn insert(&self, key: K, value: V) -> Option<V> {
192+
pub fn insert_unique(&self, key: K, value: V) {
188193
let hash = make_hash(&key);
189194
let mut shard = self.lock_shard_by_hash(hash);
190195

191-
match table_entry(&mut shard, hash, &key) {
192-
Entry::Occupied(e) => {
193-
let previous = mem::replace(&mut e.into_mut().1, value);
194-
Some(previous)
196+
cfg_select! {
197+
debug_assertions => match table_entry(&mut shard, hash, &key) {
198+
Entry::Occupied(_) => {
199+
panic!("tried to insert key that's already present");
200+
}
201+
Entry::Vacant(e) => {
202+
e.insert((key, value));
203+
}
195204
}
196-
Entry::Vacant(e) => {
197-
e.insert((key, value));
198-
None
205+
_ => {
206+
shard.insert_unique(hash, (key, value), |(k, _)| make_hash(k));
199207
}
200208
}
201209
}

compiler/rustc_middle/src/mir/interpret/mod.rs

Lines changed: 7 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -473,9 +473,8 @@ impl<'tcx> TyCtxt<'tcx> {
473473
}
474474
let id = self.alloc_map.reserve();
475475
debug!("creating alloc {:?} with id {id:?}", alloc_salt.0);
476-
let had_previous = self.alloc_map.to_alloc.insert(id, alloc_salt.0.clone()).is_some();
477476
// We just reserved, so should always be unique.
478-
assert!(!had_previous);
477+
self.alloc_map.to_alloc.insert_unique(id, alloc_salt.0.clone());
479478
dedup.insert(alloc_salt, id);
480479
id
481480
}
@@ -548,21 +547,17 @@ impl<'tcx> TyCtxt<'tcx> {
548547
}
549548

550549
/// Freezes an `AllocId` created with `reserve` by pointing it at an `Allocation`. Trying to
551-
/// call this function twice, even with the same `Allocation` will ICE the compiler.
550+
/// call this function twice, even with the same `Allocation` will ICE the compiler if
551+
/// debug_assertions are enabled.
552552
pub fn set_alloc_id_memory(self, id: AllocId, mem: ConstAllocation<'tcx>) {
553-
if let Some(old) = self.alloc_map.to_alloc.insert(id, GlobalAlloc::Memory(mem)) {
554-
bug!("tried to set allocation ID {id:?}, but it was already existing as {old:#?}");
555-
}
553+
self.alloc_map.to_alloc.insert_unique(id, GlobalAlloc::Memory(mem))
556554
}
557555

558556
/// Freezes an `AllocId` created with `reserve` by pointing it at a static item. Trying to
559-
/// call this function twice, even with the same `DefId` will ICE the compiler.
557+
/// call this function twice, even with the same `DefId` will ICE the compiler if
558+
/// debug_assertions are enabled.
560559
pub fn set_nested_alloc_id_static(self, id: AllocId, def_id: LocalDefId) {
561-
if let Some(old) =
562-
self.alloc_map.to_alloc.insert(id, GlobalAlloc::Static(def_id.to_def_id()))
563-
{
564-
bug!("tried to set allocation ID {id:?}, but it was already existing as {old:#?}");
565-
}
560+
self.alloc_map.to_alloc.insert_unique(id, GlobalAlloc::Static(def_id.to_def_id()))
566561
}
567562
}
568563

compiler/rustc_middle/src/query/caches.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -65,9 +65,7 @@ where
6565

6666
#[inline]
6767
fn complete(&self, key: K, value: V, index: DepNodeIndex) {
68-
// We may be overwriting another value. This is all right, since the dep-graph
69-
// will check that the value fingerprint matches.
70-
self.cache.insert(key, (value, index));
68+
self.cache.insert_unique(key, (value, index));
7169
}
7270

7371
fn for_each(&self, f: &mut dyn FnMut(&Self::Key, &Self::Value, DepNodeIndex)) {

0 commit comments

Comments
 (0)