Skip to content

Commit

Permalink
Avoid double hashing by using raw entry APIs
Browse files Browse the repository at this point in the history
  • Loading branch information
petrochenkov committed Jan 1, 2021
1 parent 616633f commit 8809118
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 5 deletions.
1 change: 1 addition & 0 deletions compiler/rustc_span/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#![feature(crate_visibility_modifier)]
#![feature(const_fn)]
#![feature(const_panic)]
#![feature(hash_raw_entry)]
#![feature(negative_impls)]
#![feature(nll)]
#![feature(min_specialization)]
Expand Down
24 changes: 19 additions & 5 deletions compiler/rustc_span/src/symbol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
//! type, and vice versa.

use rustc_arena::DroplessArena;
use rustc_data_structures::fx::FxHashMap;
use rustc_data_structures::fx::{FxHashMap, FxHasher};
use rustc_data_structures::stable_hasher::{HashStable, StableHasher, ToStableHashKey};
use rustc_macros::HashStable_Generic;
use rustc_serialize::{Decodable, Decoder, Encodable, Encoder};
Expand Down Expand Up @@ -5051,17 +5051,26 @@ rustc_index::newtype_index! {
pub struct SymbolIndex { .. }
}

fn fx_hash(string: &str) -> u64 {
let mut hasher = FxHasher::default();
string.hash(&mut hasher);
hasher.finish()
}

impl Symbol {
const fn new(n: u32) -> Self {
Symbol(SymbolIndex::from_u32(n))
}

/// Maps a string to its interned representation.
pub fn intern(string: &str) -> Self {
if let Some(symbol) = unsafe { STATIC_SYMBOLS.get(string) } {
let hash = fx_hash(string);
if let Some((_, symbol)) =
unsafe { &STATIC_SYMBOLS }.raw_entry().from_key_hashed_nocheck(hash, string)
{
*symbol
} else {
with_interner(|interner| interner.intern(string))
with_interner(|interner| interner.intern_ext(hash, string))
}
}

Expand Down Expand Up @@ -5163,8 +5172,8 @@ impl Interner {
}

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

Expand All @@ -5182,6 +5191,11 @@ impl Interner {
name
}

#[inline]
pub fn intern(&mut self, string: &str) -> Symbol {
self.intern_ext(fx_hash(string), string)
}

// Get the symbol as a string. `Symbol::as_str()` should be used in
// preference to this function.
pub fn get(&self, symbol: Symbol) -> &str {
Expand Down

0 comments on commit 8809118

Please sign in to comment.