mirror of
https://github.com/oxc-project/oxc.git
synced 2026-11-04 10:29:58 +00:00
refactor(lexer): #[inline(always)] on Tokens::next_start (#28652)
Part of effort to move to runtime CPU feature detection. Fixes codegen drift from on earlier step in this stack. Before the migration, `Tokens::next_start` was inlined everywhere. Since `cpu_versions!` was applied in C7, Level 3's `Walk::step` called its generic copy out of line. It only wraps the `#[inline(always)]` `bits::next1`, and needs no CPU type. So it gets `#[inline(always)]` instead of `cpu_versions!`, and loses its `cpu` parameter, as in step B12. Its callers stop passing `cpu`. `Tokens::next_sig` and `Tokens::run_len` now pass `cpu` to nothing, so they rename it to `_cpu`. `Walk::advance` no longer needs `let cpu = BASELINE;`. Codegen: `next_start` is inlined everywhere again, in all builds. aarch64 grows from 35,428 instructions to 35,445. In the x86_64 build, the generic code grows from 36,553 instructions to 36,586, and the AVX2 copies grow by 4.
This commit is contained in:
1 parent
3700e973d1
commit
30e09a4126
7 files changed
+20
-23
No files matched your search
@@ -106,23 +106,22 @@ impl Tokens<'_> {
|
||||
/// Keyword code of the word at `w` (0 for a plain name).
|
||||
#[inline(always)]
|
||||
pub fn ident_kw(&self, w: usize, cpu: impl Cpu) -> u8 {
|
||||
let e = self.next_start(w + 1, cpu);
|
||||
let e = self.next_start(w + 1);
|
||||
self.word_kw(w, e - w, cpu)
|
||||
}
|
||||
|
||||
/// The token start at or after `i`, or `n`.
|
||||
#[apply(cpu_versions)]
|
||||
#[inline]
|
||||
pub fn next_start(&self, i: usize, _cpu: impl Cpu) -> usize {
|
||||
#[inline(always)]
|
||||
pub fn next_start(&self, i: usize) -> usize {
|
||||
bits::next1(self.st, i, self.n)
|
||||
}
|
||||
|
||||
/// The significant token start at or after `i` (skipping trivia), or `n`.
|
||||
#[apply(cpu_versions)]
|
||||
#[inline]
|
||||
pub fn next_sig(&self, mut i: usize, cpu: impl Cpu) -> usize {
|
||||
pub fn next_sig(&self, mut i: usize, _cpu: impl Cpu) -> usize {
|
||||
loop {
|
||||
i = self.next_start(i, cpu);
|
||||
i = self.next_start(i);
|
||||
if i >= self.n {
|
||||
return self.n;
|
||||
}
|
||||
@@ -207,8 +206,8 @@ impl Tokens<'_> {
|
||||
/// Number of `c` bytes the token at `p` starts with (a fused `>>>` counts three, a lone `>`
|
||||
/// one).
|
||||
#[apply(cpu_versions)]
|
||||
pub fn run_len(&self, p: usize, c: u8, cpu: impl Cpu) -> i32 {
|
||||
let e = self.next_start(p + 1, cpu);
|
||||
pub fn run_len(&self, p: usize, c: u8, _cpu: impl Cpu) -> i32 {
|
||||
let e = self.next_start(p + 1);
|
||||
let mut i = p;
|
||||
while i < e && self.src[i] == c {
|
||||
i += 1;
|
||||
|
||||
@@ -75,7 +75,7 @@ fn stmt_boundary(tokens: &Tokens, p: usize, prev: Prev) -> bool {
|
||||
Prev::Op(_, b'}') => !in_jsx_tag(tokens, p),
|
||||
Prev::Word(_, tk!(KwElse | KwDo | KwExport | KwDefault | KwDeclare | KwAbstract)) => true,
|
||||
Prev::Op(q, _) | Prev::Word(q, _) | Prev::Other(q) => {
|
||||
let e = tokens.next_start(q + 1, cpu);
|
||||
let e = tokens.next_start(q + 1);
|
||||
tokens.line_break_between(e, p, cpu) && !in_jsx_tag(tokens, p)
|
||||
}
|
||||
}
|
||||
@@ -85,7 +85,7 @@ fn stmt_boundary(tokens: &Tokens, p: usize, prev: Prev) -> bool {
|
||||
pub(super) fn anchor_at(tokens: &Tokens, p: usize) -> (u8, Option<Anchor>) {
|
||||
let cpu = BASELINE;
|
||||
|
||||
let e = tokens.next_start(p + 1, cpu);
|
||||
let e = tokens.next_start(p + 1);
|
||||
let kw = tokens.word_kw(p, e - p, cpu);
|
||||
(kw, anchor_of(tokens, p, e, kw))
|
||||
}
|
||||
|
||||
@@ -92,12 +92,12 @@ impl Walk {
|
||||
let end = match k {
|
||||
tk!(Ident) => self.step_word(tokens, pos),
|
||||
tk!(Number | BigInt | String | RegExp | TemplateNoSub | PrivateIdent) => {
|
||||
let e = tokens.next_start(pos + 1, cpu);
|
||||
let e = tokens.next_start(pos + 1);
|
||||
self.literal(tokens, k, e);
|
||||
e
|
||||
}
|
||||
tk!(TemplateHead | TemplateMiddle) => {
|
||||
let e = tokens.next_start(pos + 1, cpu);
|
||||
let e = tokens.next_start(pos + 1);
|
||||
if k == tk!(TemplateMiddle) && self.pop_to(|k| k == FrameKind::Sub).is_none() {
|
||||
self.unbalanced();
|
||||
}
|
||||
@@ -108,7 +108,7 @@ impl Walk {
|
||||
e
|
||||
}
|
||||
tk!(TemplateTail) => {
|
||||
let e = tokens.next_start(pos + 1, cpu);
|
||||
let e = tokens.next_start(pos + 1);
|
||||
if self.pop_to(|k| k == FrameKind::Sub).is_none() {
|
||||
self.unbalanced();
|
||||
}
|
||||
|
||||
@@ -261,11 +261,9 @@ impl Walk {
|
||||
}
|
||||
|
||||
pub(super) fn advance(&mut self, tokens: &Tokens, limit: usize) {
|
||||
let cpu = BASELINE;
|
||||
|
||||
let mut pos = self.walked_to;
|
||||
loop {
|
||||
pos = tokens.next_start(pos, cpu);
|
||||
pos = tokens.next_start(pos);
|
||||
if pos >= limit || pos >= tokens.n {
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ impl Walk {
|
||||
pub(super) fn step_word(&mut self, tokens: &Tokens, pos: usize) -> usize {
|
||||
let cpu = BASELINE;
|
||||
|
||||
let end = tokens.next_start(pos + 1, cpu);
|
||||
let end = tokens.next_start(pos + 1);
|
||||
let kw = if self.after_dot { 0 } else { tokens.word_kw(pos, end - pos, cpu) };
|
||||
|
||||
if self.in_type() {
|
||||
|
||||
@@ -68,11 +68,11 @@ pub fn not_operator_position(tokens: &Tokens, walks: &mut Walks, p: usize, cpu:
|
||||
continue;
|
||||
}
|
||||
if k == tk!(String) {
|
||||
return ends_decl(tokens, walks, qi, tokens.next_start(qi + 1, cpu), p, cpu);
|
||||
return ends_decl(tokens, walks, qi, tokens.next_start(qi + 1), p, cpu);
|
||||
}
|
||||
if matches_tk!(k, Number | TemplateNoSub | TemplateTail) {
|
||||
// A literal ends a value: division, unless TS ASI applies.
|
||||
return ts && ends_decl(tokens, walks, qi, tokens.next_start(qi + 1, cpu), p, cpu);
|
||||
return ts && ends_decl(tokens, walks, qi, tokens.next_start(qi + 1), p, cpu);
|
||||
}
|
||||
if matches_tk!(k, RegExp | PrivateIdent | PrivateIdentEscaped | JsxTagEnd | JsxLt) {
|
||||
return false;
|
||||
@@ -81,7 +81,7 @@ pub fn not_operator_position(tokens: &Tokens, walks: &mut Walks, p: usize, cpu:
|
||||
return true;
|
||||
}
|
||||
if matches_tk!(k, Ident | IdentEscaped) {
|
||||
let e = tokens.next_start(qi + 1, cpu);
|
||||
let e = tokens.next_start(qi + 1);
|
||||
let newline = tokens.line_break_between(e, p, cpu);
|
||||
if tokens.property_name(qi, cpu) {
|
||||
return ts && newline && context::after(tokens, walks, qi) == After::EndsDecl;
|
||||
@@ -113,7 +113,7 @@ pub fn not_operator_position(tokens: &Tokens, walks: &mut Walks, p: usize, cpu:
|
||||
let Some(q2) = tokens.prev_sig(qi, cpu) else {
|
||||
return true;
|
||||
};
|
||||
if tokens.line_break_between(tokens.next_start(q2 + 1, cpu), qi, cpu) {
|
||||
if tokens.line_break_between(tokens.next_start(q2 + 1), qi, cpu) {
|
||||
return true;
|
||||
}
|
||||
q = Some(q2);
|
||||
|
||||
@@ -135,7 +135,7 @@ fn list_in_any_context(tokens: &Tokens, lt: usize, cpu: impl Cpu) -> bool {
|
||||
Prev::Word(k, tk!(KwFunction | KwClass)) => !tokens.property_name(k, cpu),
|
||||
Prev::Word(head, 0) => {
|
||||
type_args_at(tokens, lt, cpu)
|
||||
|| (!tokens.line_break_between(tokens.next_start(head + 1, cpu), lt, cpu)
|
||||
|| (!tokens.line_break_between(tokens.next_start(head + 1), lt, cpu)
|
||||
&& type_reference_head(tokens, head, cpu))
|
||||
}
|
||||
_ => false,
|
||||
@@ -164,7 +164,7 @@ fn type_reference_head(tokens: &Tokens, head: usize, cpu: impl Cpu) -> bool {
|
||||
Prev::Word(k, tk!(KwExtends | KwClass | KwFunction)) => !tokens.property_name(k, cpu),
|
||||
Prev::Word(k, tk!(KwImplements | KwAs | KwSatisfies | KwKeyof | KwInterface | KwType)) => {
|
||||
!tokens.property_name(k, cpu)
|
||||
&& !tokens.line_break_between(tokens.next_start(k + 1, cpu), h, cpu)
|
||||
&& !tokens.line_break_between(tokens.next_start(k + 1), h, cpu)
|
||||
}
|
||||
Prev::Op(c, b':') => return_type_colon(tokens, c, cpu),
|
||||
_ => false,
|
||||
|
||||
Reference in new issue
Block a user