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:
overlookmotel committed 2026-11-01 23:34:23 +00:00
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,