mirror of
https://github.com/swc-project/swc.git
synced 2024-12-25 22:56:11 +03:00
perf(atoms): Introduce AtomStoreCell
(#8232)
This commit is contained in:
parent
5472afb40e
commit
a5a6eb53a5
@ -247,3 +247,18 @@ impl AtomStore {
|
||||
Atom(self.0.atom(s))
|
||||
}
|
||||
}
|
||||
|
||||
/// A fast internally mutable cell for [AtomStore].
|
||||
#[derive(Default)]
|
||||
pub struct AtomStoreCell(std::cell::UnsafeCell<AtomStore>);
|
||||
|
||||
impl AtomStoreCell {
|
||||
#[inline]
|
||||
pub fn atom<'a>(&self, s: impl Into<Cow<'a, str>>) -> Atom {
|
||||
// SAFETY: We can skip the borrow check of RefCell because
|
||||
// this API enforces a safe contract. It is slightly faster
|
||||
// to use an UnsafeCell. Note the borrow here is short lived
|
||||
// only to this block.
|
||||
unsafe { (*self.0.get()).atom(s) }
|
||||
}
|
||||
}
|
||||
|
@ -47,7 +47,7 @@ impl<'a> Lexer<'a> {
|
||||
});
|
||||
|
||||
return Ok(Some(Token::JSXText {
|
||||
raw: self.atoms.borrow_mut().atom(out),
|
||||
raw: self.atoms.atom(out),
|
||||
}));
|
||||
}
|
||||
'>' => {
|
||||
@ -322,10 +322,9 @@ impl<'a> Lexer<'a> {
|
||||
|
||||
raw.push(quote);
|
||||
|
||||
let mut b = self.atoms.borrow_mut();
|
||||
Ok(Token::Str {
|
||||
value: b.atom(out),
|
||||
raw: b.atom(raw),
|
||||
value: self.atoms.atom(out),
|
||||
raw: self.atoms.atom(raw),
|
||||
})
|
||||
}
|
||||
|
||||
@ -351,7 +350,7 @@ impl<'a> Lexer<'a> {
|
||||
});
|
||||
|
||||
Ok(Token::JSXName {
|
||||
name: self.atoms.borrow_mut().atom(slice),
|
||||
name: self.atoms.atom(slice),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -5,7 +5,7 @@ use std::{cell::RefCell, char, iter::FusedIterator, rc::Rc};
|
||||
use either::Either::{Left, Right};
|
||||
use smallvec::{smallvec, SmallVec};
|
||||
use smartstring::SmartString;
|
||||
use swc_atoms::{Atom, AtomStore};
|
||||
use swc_atoms::{Atom, AtomStoreCell};
|
||||
use swc_common::{comments::Comments, input::StringInput, BytePos, Span};
|
||||
use swc_ecma_ast::{op, AssignOp, EsVersion};
|
||||
|
||||
@ -133,7 +133,7 @@ pub struct Lexer<'a> {
|
||||
|
||||
buf: Rc<RefCell<String>>,
|
||||
|
||||
atoms: Rc<RefCell<AtomStore>>,
|
||||
atoms: Rc<AtomStoreCell>,
|
||||
}
|
||||
|
||||
impl FusedIterator for Lexer<'_> {}
|
||||
@ -767,9 +767,8 @@ impl<'a> Lexer<'a> {
|
||||
fn read_ident_unknown(&mut self) -> LexResult<Token> {
|
||||
debug_assert!(self.cur().is_some());
|
||||
|
||||
let (word, _) = self.read_word_as_str_with(|l, s, _, _| {
|
||||
Word::Ident(IdentLike::Other(l.atoms.borrow_mut().atom(s)))
|
||||
})?;
|
||||
let (word, _) = self
|
||||
.read_word_as_str_with(|l, s, _, _| Word::Ident(IdentLike::Other(l.atoms.atom(s))))?;
|
||||
|
||||
Ok(Word(word))
|
||||
}
|
||||
@ -790,7 +789,7 @@ impl<'a> Lexer<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
Word::Ident(IdentLike::Other(l.atoms.borrow_mut().atom(s)))
|
||||
Word::Ident(IdentLike::Other(l.atoms.atom(s)))
|
||||
})?;
|
||||
|
||||
// Note: ctx is store in lexer because of this error.
|
||||
@ -1022,10 +1021,9 @@ impl<'a> Lexer<'a> {
|
||||
|
||||
l.bump();
|
||||
|
||||
let mut b = l.atoms.borrow_mut();
|
||||
return Ok(Token::Str {
|
||||
value: b.atom(&*out),
|
||||
raw: b.atom(raw),
|
||||
value: l.atoms.atom(&*out),
|
||||
raw: l.atoms.atom(raw),
|
||||
});
|
||||
}
|
||||
'\\' => {
|
||||
@ -1057,10 +1055,9 @@ impl<'a> Lexer<'a> {
|
||||
|
||||
l.emit_error(start, SyntaxError::UnterminatedStrLit);
|
||||
|
||||
let mut b = l.atoms.borrow_mut();
|
||||
Ok(Token::Str {
|
||||
value: b.atom(&*out),
|
||||
raw: b.atom(raw),
|
||||
value: l.atoms.atom(&*out),
|
||||
raw: l.atoms.atom(raw),
|
||||
})
|
||||
})
|
||||
}
|
||||
@ -1108,7 +1105,7 @@ impl<'a> Lexer<'a> {
|
||||
buf.push(c);
|
||||
}
|
||||
|
||||
Ok(l.atoms.borrow_mut().atom(&**buf))
|
||||
Ok(l.atoms.atom(&**buf))
|
||||
})?;
|
||||
|
||||
// input is terminated without following `/`
|
||||
@ -1129,7 +1126,7 @@ impl<'a> Lexer<'a> {
|
||||
let flags = {
|
||||
match self.cur() {
|
||||
Some(c) if c.is_ident_start() => self
|
||||
.read_word_as_str_with(|l, s, _, _| l.atoms.borrow_mut().atom(s))
|
||||
.read_word_as_str_with(|l, s, _, _| l.atoms.atom(s))
|
||||
.map(Some),
|
||||
_ => Ok(None),
|
||||
}
|
||||
@ -1151,7 +1148,7 @@ impl<'a> Lexer<'a> {
|
||||
self.input.bump();
|
||||
}
|
||||
let s = self.input.uncons_while(|c| !c.is_line_terminator());
|
||||
Ok(Some(self.atoms.borrow_mut().atom(s)))
|
||||
Ok(Some(self.atoms.atom(s)))
|
||||
}
|
||||
|
||||
fn read_tmpl_token(&mut self, start_of_tpl: BytePos) -> LexResult<Token> {
|
||||
@ -1176,7 +1173,7 @@ impl<'a> Lexer<'a> {
|
||||
// TODO: Handle error
|
||||
return Ok(Token::Template {
|
||||
cooked: cooked.map(Atom::from),
|
||||
raw: self.atoms.borrow_mut().atom(&*raw),
|
||||
raw: self.atoms.atom(&*raw),
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -64,7 +64,7 @@ impl<'a> Lexer<'a> {
|
||||
|
||||
return Ok(Either::Right((
|
||||
Box::new(s.into_value()),
|
||||
self.atoms.borrow_mut().atom(&*raw),
|
||||
self.atoms.atom(&*raw),
|
||||
)));
|
||||
}
|
||||
|
||||
@ -84,9 +84,9 @@ impl<'a> Lexer<'a> {
|
||||
// e.g. `000` is octal
|
||||
if start.0 != self.last_pos().0 - 1 {
|
||||
// `-1` is utf 8 length of `0`
|
||||
return self.make_legacy_octal(start, 0f64).map(|value| {
|
||||
Either::Left((value, self.atoms.borrow_mut().atom(&*raw)))
|
||||
});
|
||||
return self
|
||||
.make_legacy_octal(start, 0f64)
|
||||
.map(|value| Either::Left((value, self.atoms.atom(&*raw))));
|
||||
}
|
||||
} else {
|
||||
// strict mode hates non-zero decimals starting with zero.
|
||||
@ -113,9 +113,9 @@ impl<'a> Lexer<'a> {
|
||||
panic!("failed to parse {} into float using BigInt", val_str)
|
||||
});
|
||||
|
||||
return self.make_legacy_octal(start, val).map(|value| {
|
||||
Either::Left((value, self.atoms.borrow_mut().atom(&*raw)))
|
||||
});
|
||||
return self
|
||||
.make_legacy_octal(start, val)
|
||||
.map(|value| Either::Left((value, self.atoms.atom(&*raw))));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -227,7 +227,7 @@ impl<'a> Lexer<'a> {
|
||||
|
||||
self.ensure_not_ident()?;
|
||||
|
||||
Ok(Either::Left((val, self.atoms.borrow_mut().atom(&*raw_str))))
|
||||
Ok(Either::Left((val, self.atoms.atom(&*raw_str))))
|
||||
}
|
||||
|
||||
/// Returns `Left(value)` or `Right(BigInt)`
|
||||
@ -268,13 +268,13 @@ impl<'a> Lexer<'a> {
|
||||
|
||||
return Ok(Either::Right((
|
||||
Box::new(s.into_value()),
|
||||
l.atoms.borrow_mut().atom(&**buf),
|
||||
l.atoms.atom(&**buf),
|
||||
)));
|
||||
}
|
||||
|
||||
l.ensure_not_ident()?;
|
||||
|
||||
Ok(Either::Left((val, l.atoms.borrow_mut().atom(&**buf))))
|
||||
Ok(Either::Left((val, l.atoms.atom(&**buf))))
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -257,7 +257,7 @@ impl<'a> Lexer<'a> {
|
||||
let cmt = Comment {
|
||||
kind: CommentKind::Line,
|
||||
span: Span::new(start, end, SyntaxContext::empty()),
|
||||
text: self.atoms.borrow_mut().atom(s),
|
||||
text: self.atoms.atom(s),
|
||||
};
|
||||
|
||||
if is_for_next {
|
||||
@ -343,7 +343,7 @@ impl<'a> Lexer<'a> {
|
||||
let cmt = Comment {
|
||||
kind: CommentKind::Block,
|
||||
span: Span::new(start, end, SyntaxContext::empty()),
|
||||
text: self.atoms.borrow_mut().atom(s),
|
||||
text: self.atoms.atom(s),
|
||||
};
|
||||
|
||||
let _ = self.input.peek();
|
||||
|
Loading…
Reference in New Issue
Block a user