about summary refs log tree commit diff
diff options
context:
space:
mode:
authorAmos Wenger <amoswenger@gmail.com>2022-07-21 14:57:09 +0200
committerAmos Wenger <amoswenger@gmail.com>2022-07-21 14:57:09 +0200
commit05d8f5fee7ceacb68e18a6c9c7fc4d15adc75b22 (patch)
tree24a15c7adf225b37caf9e5d67a83480c61ec6946
parent30769598a406a30f05d4b8a72430824708bdc73f (diff)
downloadrust-05d8f5fee7ceacb68e18a6c9c7fc4d15adc75b22.tar.gz
rust-05d8f5fee7ceacb68e18a6c9c7fc4d15adc75b22.zip
Use a thread-local for the symbol interner (1/2)
-rw-r--r--Cargo.lock1
-rw-r--r--crates/proc-macro-srv/Cargo.toml1
-rw-r--r--crates/proc-macro-srv/src/abis/abi_sysroot/ra_server.rs17
-rw-r--r--crates/proc-macro-srv/src/abis/abi_sysroot/ra_server/symbol.rs31
4 files changed, 33 insertions, 17 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 5d313b93083..0204617d5df 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -1167,7 +1167,6 @@ dependencies = [
  "mbe",
  "memmap2",
  "object 0.29.0",
- "once_cell",
  "paths",
  "proc-macro-api",
  "proc-macro-test",
diff --git a/crates/proc-macro-srv/Cargo.toml b/crates/proc-macro-srv/Cargo.toml
index 06348afdede..e39026ac70b 100644
--- a/crates/proc-macro-srv/Cargo.toml
+++ b/crates/proc-macro-srv/Cargo.toml
@@ -24,7 +24,6 @@ tt = { path = "../tt", version = "0.0.0" }
 mbe = { path = "../mbe", version = "0.0.0" }
 paths = { path = "../paths", version = "0.0.0" }
 proc-macro-api = { path = "../proc-macro-api", version = "0.0.0" }
-once_cell = "1.13.0"
 
 [dev-dependencies]
 expect-test = "1.4.0"
diff --git a/crates/proc-macro-srv/src/abis/abi_sysroot/ra_server.rs b/crates/proc-macro-srv/src/abis/abi_sysroot/ra_server.rs
index 69f1e13fb06..066e0e26ac8 100644
--- a/crates/proc-macro-srv/src/abis/abi_sysroot/ra_server.rs
+++ b/crates/proc-macro-srv/src/abis/abi_sysroot/ra_server.rs
@@ -83,7 +83,7 @@ impl server::FreeFunctions for RustAnalyzer {
         s: &str,
     ) -> Result<bridge::Literal<Self::Span, Self::Symbol>, ()> {
         // FIXME: keep track of LitKind and Suffix
-        let symbol = SYMBOL_INTERNER.lock().unwrap().intern(s);
+        let symbol = ThreadLocalSymbolInterner::intern(s);
         Ok(bridge::Literal {
             kind: bridge::LitKind::Err,
             symbol,
@@ -124,7 +124,7 @@ impl server::TokenStream for RustAnalyzer {
 
             bridge::TokenTree::Ident(ident) => {
                 // FIXME: handle raw idents
-                let text = SYMBOL_INTERNER.lock().unwrap().get(&ident.sym).clone();
+                let text = ThreadLocalSymbolInterner::get_cloned(&ident.sym);
                 let ident: tt::Ident = tt::Ident { text, id: ident.span };
                 let leaf = tt::Leaf::from(ident);
                 let tree = TokenTree::from(leaf);
@@ -132,10 +132,11 @@ impl server::TokenStream for RustAnalyzer {
             }
 
             bridge::TokenTree::Literal(literal) => {
-                let symbol = SYMBOL_INTERNER.lock().unwrap().get(&literal.symbol).clone();
+                // FIXME: remove unnecessary clones here
+                let symbol = ThreadLocalSymbolInterner::get_cloned(&literal.symbol);
 
                 let text: tt::SmolStr = if let Some(suffix) = literal.suffix {
-                    let suffix = SYMBOL_INTERNER.lock().unwrap().get(&suffix).clone();
+                    let suffix = ThreadLocalSymbolInterner::get_cloned(&suffix);
                     format!("{symbol}{suffix}").into()
                 } else {
                     symbol
@@ -203,7 +204,7 @@ impl server::TokenStream for RustAnalyzer {
             .map(|tree| match tree {
                 tt::TokenTree::Leaf(tt::Leaf::Ident(ident)) => {
                     bridge::TokenTree::Ident(bridge::Ident {
-                        sym: SYMBOL_INTERNER.lock().unwrap().intern(&ident.text),
+                        sym: ThreadLocalSymbolInterner::intern(&ident.text),
                         // FIXME: handle raw idents
                         is_raw: false,
                         span: ident.id,
@@ -213,7 +214,7 @@ impl server::TokenStream for RustAnalyzer {
                     bridge::TokenTree::Literal(bridge::Literal {
                         // FIXME: handle literal kinds
                         kind: bridge::LitKind::Err,
-                        symbol: SYMBOL_INTERNER.lock().unwrap().intern(&lit.text),
+                        symbol: ThreadLocalSymbolInterner::intern(&lit.text),
                         // FIXME: handle suffixes
                         suffix: None,
                         span: lit.id,
@@ -407,11 +408,11 @@ impl server::Server for RustAnalyzer {
     }
 
     fn intern_symbol(ident: &str) -> Self::Symbol {
-        SYMBOL_INTERNER.lock().unwrap().intern(&tt::SmolStr::from(ident))
+        ThreadLocalSymbolInterner::intern(&tt::SmolStr::from(ident))
     }
 
     fn with_symbol_string(symbol: &Self::Symbol, f: impl FnOnce(&str)) {
-        f(SYMBOL_INTERNER.lock().unwrap().get(symbol).as_str())
+        ThreadLocalSymbolInterner::with(symbol, |s| f(s.as_str()))
     }
 }
 
diff --git a/crates/proc-macro-srv/src/abis/abi_sysroot/ra_server/symbol.rs b/crates/proc-macro-srv/src/abis/abi_sysroot/ra_server/symbol.rs
index d16c2d22440..294ef76c24a 100644
--- a/crates/proc-macro-srv/src/abis/abi_sysroot/ra_server/symbol.rs
+++ b/crates/proc-macro-srv/src/abis/abi_sysroot/ra_server/symbol.rs
@@ -1,23 +1,24 @@
 //! Symbol interner for proc-macro-srv
 
-use once_cell::sync::Lazy;
-use std::{collections::HashMap, sync::Mutex};
+use std::{cell::RefCell, collections::HashMap};
 use tt::SmolStr;
 
-pub(super) static SYMBOL_INTERNER: Lazy<Mutex<SymbolInterner>> = Lazy::new(|| Default::default());
+thread_local! {
+    static SYMBOL_INTERNER: RefCell<SymbolInterner> = Default::default();
+}
 
 // ID for an interned symbol.
 #[derive(Hash, Eq, PartialEq, Copy, Clone)]
 pub struct Symbol(u32);
 
 #[derive(Default)]
-pub(super) struct SymbolInterner {
+struct SymbolInterner {
     idents: HashMap<SmolStr, u32>,
     ident_data: Vec<SmolStr>,
 }
 
 impl SymbolInterner {
-    pub(super) fn intern(&mut self, data: &str) -> Symbol {
+    fn intern(&mut self, data: &str) -> Symbol {
         if let Some(index) = self.idents.get(data) {
             return Symbol(*index);
         }
@@ -29,7 +30,23 @@ impl SymbolInterner {
         Symbol(index)
     }
 
-    pub(super) fn get(&self, index: &Symbol) -> &SmolStr {
-        &self.ident_data[index.0 as usize]
+    fn get(&self, sym: &Symbol) -> &SmolStr {
+        &self.ident_data[sym.0 as usize]
+    }
+}
+
+pub(super) struct ThreadLocalSymbolInterner;
+
+impl ThreadLocalSymbolInterner {
+    pub(super) fn intern(data: &str) -> Symbol {
+        SYMBOL_INTERNER.with(|i| i.borrow_mut().intern(data))
+    }
+
+    pub(super) fn with<T>(sym: &Symbol, f: impl FnOnce(&SmolStr) -> T) -> T {
+        SYMBOL_INTERNER.with(|i| f(i.borrow().get(sym)))
+    }
+
+    pub(super) fn get_cloned(sym: &Symbol) -> SmolStr {
+        Self::with(sym, |s| s.clone())
     }
 }