|
| 1 | +// ignore-tidy-filelength |
| 2 | + |
1 | 3 | //! An "interner" is a data structure that associates values with usize tags and
|
2 | 4 | //! allows bidirectional lookup; i.e., given a value, one can easily find the
|
3 | 5 | //! type, and vice versa.
|
@@ -5056,7 +5058,7 @@ impl Symbol {
|
5056 | 5058 |
|
5057 | 5059 | /// Maps a string to its interned representation.
|
5058 | 5060 | pub fn intern(string: &str) -> Self {
|
5059 |
| - if let Some(symbol) = STATIC_SYMBOLS_PHF.get(string) { |
| 5061 | + if let Some(symbol) = unsafe { STATIC_SYMBOLS.get(string) } { |
5060 | 5062 | *symbol
|
5061 | 5063 | } else {
|
5062 | 5064 | with_interner(|interner| interner.intern(string))
|
@@ -5141,13 +5143,23 @@ pub struct Interner {
|
5141 | 5143 | strings: Vec<&'static str>,
|
5142 | 5144 | }
|
5143 | 5145 |
|
| 5146 | +use std::hash::BuildHasherDefault; |
| 5147 | +use std::marker::PhantomData; |
| 5148 | + |
| 5149 | +#[allow(unused)] |
| 5150 | +static mut STATIC_SYMBOLS: FxHashMap<&'static str, Symbol> = |
| 5151 | + FxHashMap::with_hasher(BuildHasherDefault(PhantomData)); |
| 5152 | + |
5144 | 5153 | impl Interner {
|
5145 | 5154 | fn prefill(init: &[&'static str]) -> Self {
|
5146 |
| - Interner { |
5147 |
| - strings: init.into(), |
5148 |
| - names: init.iter().copied().zip((0..).map(Symbol::new)).collect(), |
5149 |
| - ..Default::default() |
| 5155 | + let names: FxHashMap<_, _> = init.iter().copied().zip((0..).map(Symbol::new)).collect(); |
| 5156 | + unsafe { |
| 5157 | + STATIC_SYMBOLS = names.clone(); |
| 5158 | + // Some memory fence must go here, |
| 5159 | + // and all accesses to `Symbol::intern` must go after it. |
5150 | 5160 | }
|
| 5161 | + |
| 5162 | + Interner { strings: init.into(), names, ..Default::default() } |
5151 | 5163 | }
|
5152 | 5164 |
|
5153 | 5165 | #[inline]
|
|
0 commit comments