mirror of
https://github.com/oxc-project/oxc.git
synced 2026-11-04 10:29:58 +00:00
perf(parser): inline hot paths and fold function dispatch (#28404)
Inline twelve parser helpers and fold function-expression recognition into primary dispatch. Keep the lexer identifier scanner shared. Native M3 Max throughput, same `426c1510` base and release settings: | Comparison | Standard, 5 files | Held-out, 3 files | | --- | ---: | ---: | | Main | +4.32% | +3.80% | | Previous revision `651ea83` | +1.12% | +1.06% | Eight standard rounds and six held-out rounds. Background load was monitored: 22/40 standard blocks were uncontended and stable; that subset agreed. Normal ASLR reproduced the +1.12% gain. Seven parser hints were statistically tied. Release parser example: **1,643,216 → 1,659,728 bytes (+1.00%)**, **16,528 bytes smaller** than the previous revision. `cargo asm`: shared scanning shrinks `L_A` from 936 to 308 instruction bytes while restoring 23 static scanner calls; full parser inlining removes two static identifier-reference calls. The dispatch-only comparison shrinks the primary/LHS helper from 1,012 to 952 instruction bytes. Final paired `xcrun xctrace` CPU-counter recordings had no detected contention; they do not establish a cache-miss reduction. AI-assisted with Codex.
This commit is contained in:
1 file changed
+35
-8
@@ -93,6 +93,8 @@ impl<'a, C: Config> ParserImpl<'a, C> {
|
||||
Expression::Identifier(self.alloc(IdentifierReference::new(span, name, self)))
|
||||
}
|
||||
|
||||
#[expect(clippy::inline_always)]
|
||||
#[inline(always)]
|
||||
pub(crate) fn parse_identifier_reference(&mut self) -> IdentifierReference<'a> {
|
||||
// allow `await` and `yield`, let semantic analysis report error
|
||||
let kind = self.cur_kind();
|
||||
@@ -156,6 +158,8 @@ impl<'a, C: Config> ParserImpl<'a, C> {
|
||||
LabelIdentifier::new(span, name, self)
|
||||
}
|
||||
|
||||
#[expect(clippy::inline_always)]
|
||||
#[inline(always)]
|
||||
pub(crate) fn parse_identifier_name(&mut self) -> IdentifierName<'a> {
|
||||
if !self.cur_kind().is_identifier_name() {
|
||||
return self.unexpected();
|
||||
@@ -266,23 +270,28 @@ impl<'a, C: Config> ParserImpl<'a, C> {
|
||||
/// `RegularExpressionLiteral`
|
||||
/// `TemplateLiteral`[?Yield, ?Await, ~Tagged]
|
||||
/// `CoverParenthesizedExpressionAndArrowParameterList`[?Yield, ?Await]
|
||||
#[expect(clippy::inline_always)]
|
||||
#[inline(always)]
|
||||
fn parse_primary_expression(&mut self) -> Expression<'a> {
|
||||
// Ordinary identifiers do not need async-function or contextual-keyword disambiguation.
|
||||
if self.at(Kind::Ident) {
|
||||
return self.parse_identifier_expression();
|
||||
}
|
||||
// FunctionExpression, GeneratorExpression
|
||||
// AsyncFunctionExpression, AsyncGeneratorExpression
|
||||
if self.at_function_with_async() {
|
||||
let start = self.cur_start();
|
||||
let r#async = self.eat(Kind::Async);
|
||||
return self.parse_function_expression(start, r#async);
|
||||
}
|
||||
|
||||
let kind = self.cur_kind();
|
||||
match kind {
|
||||
// Fast path: `Ident` is already classified as a valid identifier reference.
|
||||
Kind::Ident => self.parse_plain_identifier_expression(),
|
||||
Kind::Function => self.parse_function_expression(self.cur_start(), false),
|
||||
Kind::Async
|
||||
if {
|
||||
let token = self.lexer.peek_token();
|
||||
token.kind() == Kind::Function && !token.is_on_new_line()
|
||||
} =>
|
||||
{
|
||||
let start = self.cur_start();
|
||||
self.bump_any();
|
||||
self.parse_function_expression(start, true)
|
||||
}
|
||||
// ArrayLiteral
|
||||
Kind::LBrack => self.parse_array_expression(),
|
||||
// ObjectLiteral
|
||||
@@ -802,6 +811,8 @@ impl<'a, C: Config> ParserImpl<'a, C> {
|
||||
self.with_pure_comments(Self::parse_lhs_expression_or_higher_impl)
|
||||
}
|
||||
|
||||
#[expect(clippy::inline_always)]
|
||||
#[inline(always)]
|
||||
fn parse_lhs_expression_or_higher_impl(&mut self) -> Expression<'a> {
|
||||
let start = self.cur_start();
|
||||
// `MemberExpression`
|
||||
@@ -842,6 +853,8 @@ impl<'a, C: Config> ParserImpl<'a, C> {
|
||||
}
|
||||
}
|
||||
|
||||
#[expect(clippy::inline_always)]
|
||||
#[inline(always)]
|
||||
fn with_pure_comments(
|
||||
&mut self,
|
||||
parse: impl FnOnce(&mut Self) -> Expression<'a>,
|
||||
@@ -912,6 +925,8 @@ impl<'a, C: Config> ParserImpl<'a, C> {
|
||||
}
|
||||
|
||||
/// parse rhs of a member expression, starting from lhs
|
||||
#[expect(clippy::inline_always)]
|
||||
#[inline(always)]
|
||||
fn parse_member_expression_rest(
|
||||
&mut self,
|
||||
lhs_start: u32,
|
||||
@@ -1015,6 +1030,8 @@ impl<'a, C: Config> ParserImpl<'a, C> {
|
||||
|
||||
/// Section 13.3 `MemberExpression`
|
||||
/// static member `a.b`
|
||||
#[expect(clippy::inline_always)]
|
||||
#[inline(always)]
|
||||
fn parse_static_member_expression(
|
||||
&mut self,
|
||||
lhs_start: u32,
|
||||
@@ -1219,6 +1236,8 @@ impl<'a, C: Config> ParserImpl<'a, C> {
|
||||
lhs
|
||||
}
|
||||
|
||||
#[expect(clippy::inline_always)]
|
||||
#[inline(always)]
|
||||
fn parse_call_arguments(
|
||||
&mut self,
|
||||
lhs_start: u32,
|
||||
@@ -1258,6 +1277,8 @@ impl<'a, C: Config> ParserImpl<'a, C> {
|
||||
}
|
||||
|
||||
/// Section 13.4 Update Expression
|
||||
#[expect(clippy::inline_always)]
|
||||
#[inline(always)]
|
||||
fn parse_update_expression(&mut self, lhs_start: u32) -> Expression<'a> {
|
||||
let kind = self.cur_kind();
|
||||
// ++ -- prefix update expressions
|
||||
@@ -1308,6 +1329,8 @@ impl<'a, C: Config> ParserImpl<'a, C> {
|
||||
}
|
||||
|
||||
/// Section 13.5 Unary Expression
|
||||
#[expect(clippy::inline_always)]
|
||||
#[inline(always)]
|
||||
pub(crate) fn parse_unary_expression_or_higher(&mut self, lhs_start: u32) -> Expression<'a> {
|
||||
match self.cur_kind() {
|
||||
// `UnaryExpression : (delete | void | typeof | + | - | ~ | !) UnaryExpression`
|
||||
@@ -1365,6 +1388,8 @@ impl<'a, C: Config> ParserImpl<'a, C> {
|
||||
Expression::new_unary_expression(self.end_span(start), operator, argument, self)
|
||||
}
|
||||
|
||||
#[expect(clippy::inline_always)]
|
||||
#[inline(always)]
|
||||
pub(crate) fn parse_binary_expression_or_higher(
|
||||
&mut self,
|
||||
lhs_precedence: Precedence,
|
||||
@@ -1560,6 +1585,8 @@ impl<'a, C: Config> ParserImpl<'a, C> {
|
||||
/// `ConditionalExpression`[In, Yield, Await] :
|
||||
/// `ShortCircuitExpression`[?In, ?Yield, ?Await]
|
||||
/// `ShortCircuitExpression`[?In, ?Yield, ?Await] ? `AssignmentExpression`[+In, ?Yield, ?Await] : `AssignmentExpression`[?In, ?Yield, ?Await]
|
||||
#[expect(clippy::inline_always)]
|
||||
#[inline(always)]
|
||||
fn parse_conditional_expression_rest(
|
||||
&mut self,
|
||||
lhs_start: u32,
|
||||
|
||||
Reference in new issue
Block a user