mirror of
https://github.com/oxc-project/oxc.git
synced 2026-11-04 10:29:58 +00:00
perf(parser): avoid span lookup for arrow expression body (#23788)
This avoids calling `Expression::span()` when wrapping an expression-bodied arrow function in a synthetic `ExpressionStatement`. The parser already knows the expression body starts at the current token before parsing and ends at `prev_token_end` afterwards, so this can use `start_span()` / `end_span()` directly. That keeps the returned `Expression` in registers instead of materializing it on the stack just to call the generated `GetSpan` impl. Before, the optimized parser assembly spilled the returned expression and called `Expression::span()`: ```asm bl parse_assignment_expression_or_higher_impl mov x20, x0 mov x22, x1 strh w21, [x19, #1196] strb w0, [sp, #16] str x1, [sp, #24] add x0, sp, #16 bl GetSpan_for_Expression_span ... str x0, [x21] ; ExpressionStatement span strb w20, [x21, #16] ; Expression tag str x22, [x21, #24] ; Expression payload ``` After, the span is built from parser token state and the expression result is written directly into the arena allocation: ```asm ldr x20, [x0, #816] ; current token span before parse ... bl parse_assignment_expression_or_higher_impl strh w21, [x19, #1196] ldr w8, [x19, #1192] ; previous token end after parse bfi x20, x8, #32, #32 ... str x20, [x21] ; ExpressionStatement span strb w0, [x21, #16] ; Expression tag str x1, [x21, #24] ; Expression payload ``` This also reduced the first monomorphized parse_arrow_function_expression_body stack frame from 432 bytes to 416 bytes in my local release assembly.
This commit is contained in:
1 parent
025045deae
commit
a6d8e45cb9
1 file changed
+3
-2
@@ -1,6 +1,6 @@
|
||||
use oxc_allocator::{ArenaBox, ArenaVec};
|
||||
use oxc_ast::{NONE, ast::*};
|
||||
use oxc_span::{FileExtension, GetSpan};
|
||||
use oxc_span::FileExtension;
|
||||
use oxc_syntax::precedence::Precedence;
|
||||
|
||||
use super::{FunctionKind, Tristate};
|
||||
@@ -315,10 +315,11 @@ impl<'a, C: Config> ParserImpl<'a, C> {
|
||||
let expression = !self.at(Kind::LCurly);
|
||||
let body = if expression {
|
||||
// Remove TopLevel context for arrow function expression body
|
||||
let span = self.start_span();
|
||||
let expr = self.context_remove(Context::TopLevel, |p| {
|
||||
p.parse_assignment_expression_or_higher_impl(allow_return_type_in_arrow_function)
|
||||
});
|
||||
let span = expr.span();
|
||||
let span = self.end_span(span);
|
||||
let expr_stmt = Statement::new_expression_statement(span, expr, self);
|
||||
FunctionBody::boxed(
|
||||
span,
|
||||
|
||||
Reference in new issue
Block a user