Skip to content

Commit 8809118

Browse files
committed
Avoid double hashing by using raw entry APIs
1 parent 616633f commit 8809118

File tree

2 files changed

+20
-5
lines changed

2 files changed

+20
-5
lines changed

compiler/rustc_span/src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#![feature(crate_visibility_modifier)]
1919
#![feature(const_fn)]
2020
#![feature(const_panic)]
21+
#![feature(hash_raw_entry)]
2122
#![feature(negative_impls)]
2223
#![feature(nll)]
2324
#![feature(min_specialization)]

compiler/rustc_span/src/symbol.rs

+19-5
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
//! type, and vice versa.
66
77
use rustc_arena::DroplessArena;
8-
use rustc_data_structures::fx::FxHashMap;
8+
use rustc_data_structures::fx::{FxHashMap, FxHasher};
99
use rustc_data_structures::stable_hasher::{HashStable, StableHasher, ToStableHashKey};
1010
use rustc_macros::HashStable_Generic;
1111
use rustc_serialize::{Decodable, Decoder, Encodable, Encoder};
@@ -5051,17 +5051,26 @@ rustc_index::newtype_index! {
50515051
pub struct SymbolIndex { .. }
50525052
}
50535053

5054+
fn fx_hash(string: &str) -> u64 {
5055+
let mut hasher = FxHasher::default();
5056+
string.hash(&mut hasher);
5057+
hasher.finish()
5058+
}
5059+
50545060
impl Symbol {
50555061
const fn new(n: u32) -> Self {
50565062
Symbol(SymbolIndex::from_u32(n))
50575063
}
50585064

50595065
/// Maps a string to its interned representation.
50605066
pub fn intern(string: &str) -> Self {
5061-
if let Some(symbol) = unsafe { STATIC_SYMBOLS.get(string) } {
5067+
let hash = fx_hash(string);
5068+
if let Some((_, symbol)) =
5069+
unsafe { &STATIC_SYMBOLS }.raw_entry().from_key_hashed_nocheck(hash, string)
5070+
{
50625071
*symbol
50635072
} else {
5064-
with_interner(|interner| interner.intern(string))
5073+
with_interner(|interner| interner.intern_ext(hash, string))
50655074
}
50665075
}
50675076

@@ -5163,8 +5172,8 @@ impl Interner {
51635172
}
51645173

51655174
#[inline]
5166-
pub fn intern(&mut self, string: &str) -> Symbol {
5167-
if let Some(&name) = self.names.get(string) {
5175+
fn intern_ext(&mut self, hash: u64, string: &str) -> Symbol {
5176+
if let Some((_, &name)) = self.names.raw_entry().from_key_hashed_nocheck(hash, string) {
51685177
return name;
51695178
}
51705179

@@ -5182,6 +5191,11 @@ impl Interner {
51825191
name
51835192
}
51845193

5194+
#[inline]
5195+
pub fn intern(&mut self, string: &str) -> Symbol {
5196+
self.intern_ext(fx_hash(string), string)
5197+
}
5198+
51855199
// Get the symbol as a string. `Symbol::as_str()` should be used in
51865200
// preference to this function.
51875201
pub fn get(&self, symbol: Symbol) -> &str {

0 commit comments

Comments
 (0)