perf(transformer): avoid large types on stack (#25035)

Continuation of #25034.

In transformer, move some allocations to happen earlier.

When we need an `ArenaBox<T>` for later method calls, it's preferable to allocate it into arena as swiftly as possible, so only hold an 8-byte `ArenaBox` on stack, instead of the whole `T`, which is much larger. This reduces stack and register pressure.
This commit is contained in:
overlookmotel committed 2026-07-28 22:40:02 +00:00
1 parent 8b80f8bf2f
commit 9fb1e3e2e4
7 files changed
+30 -24

No files matched your search

@@ -977,7 +977,7 @@ impl<'a> ArrowFunctionConverter<'a> {
);
}
let params = FormalParameters::new(
let params = FormalParameters::boxed(
SPAN,
FormalParameterKind::ArrowFormalParameters,
items,
@@ -985,7 +985,7 @@ impl<'a> ArrowFunctionConverter<'a> {
ctx,
);
let statement = Statement::new_expression_statement(SPAN, init, ctx);
let body = FunctionBody::new(SPAN, [], [statement], ctx);
let body = FunctionBody::boxed(SPAN, [], [statement], ctx);
let init = Expression::new_arrow_function_expression_with_scope_id_and_pure_and_pife(
SPAN, true, false, NONE, params, NONE, body, scope_id, false, false, ctx,
);
@@ -372,7 +372,7 @@ impl<'a> AsyncGeneratorFunctions<'a> {
ctx,
);
BlockStatement::new_with_scope_id(SPAN, [for_statement], block_scope_id, ctx)
BlockStatement::boxed_with_scope_id(SPAN, [for_statement], block_scope_id, ctx)
};
let catch_clause = {
@@ -383,11 +383,11 @@ impl<'a> AsyncGeneratorFunctions<'a> {
block_scope_id,
SymbolFlags::CatchVariable | SymbolFlags::FunctionScopedVariable,
);
Some(CatchClause::new_with_scope_id(
Some(CatchClause::boxed_with_scope_id(
SPAN,
Some(CatchParameter::new(SPAN, err_ident.create_binding_pattern(ctx), NONE, ctx)),
{
BlockStatement::new_with_scope_id(
BlockStatement::boxed_with_scope_id(
SPAN,
[
Statement::new_expression_statement(
@@ -482,7 +482,7 @@ impl<'a> AsyncGeneratorFunctions<'a> {
ctx,
)
};
let block = BlockStatement::new_with_scope_id(
let block = BlockStatement::boxed_with_scope_id(
SPAN,
[if_statement],
try_block_scope_id,
@@ -511,13 +511,13 @@ impl<'a> AsyncGeneratorFunctions<'a> {
ctx,
)
};
BlockStatement::new_with_scope_id(SPAN, [if_statement], finally_scope_id, ctx)
BlockStatement::boxed_with_scope_id(SPAN, [if_statement], finally_scope_id, ctx)
};
Statement::new_try_statement(SPAN, block, NONE, Some(finally), ctx)
};
let block_statement =
BlockStatement::new_with_scope_id(SPAN, [try_statement], finally_scope_id, ctx);
BlockStatement::boxed_with_scope_id(SPAN, [try_statement], finally_scope_id, ctx);
Some(block_statement)
};
@@ -147,14 +147,14 @@ impl<'a> NullishCoalescingOperator {
let id = binding.create_binding_pattern(ctx);
let param =
FormalParameter::new(SPAN, [], id, NONE, NONE, false, None, false, false, ctx);
let params = FormalParameters::new(
let params = FormalParameters::boxed(
SPAN,
FormalParameterKind::ArrowFormalParameters,
[param],
NONE,
ctx,
);
let body = FunctionBody::new(
let body = FunctionBody::boxed(
SPAN,
[],
[Statement::new_expression_statement(SPAN, new_expr, ctx)],
@@ -213,7 +213,7 @@ impl<'a> Traverse<'a, TransformState<'a>> for ExplicitResourceManagement<'a> {
block.set_scope_id(static_block_new_scope_id);
block.body = ArenaVec::from_value_in(
Self::create_try_stmt(
BlockStatement::new_with_scope_id(SPAN, new_stmts, scope_id, ctx),
BlockStatement::boxed_with_scope_id(SPAN, new_stmts, scope_id, ctx),
&using_ctx,
static_block_new_scope_id,
needs_await,
@@ -278,7 +278,7 @@ impl<'a> Traverse<'a, TransformState<'a>> for ExplicitResourceManagement<'a> {
body.statements = ArenaVec::from_value_in(
Self::create_try_stmt(
BlockStatement::new_with_scope_id(SPAN, new_stmts, block_stmt_scope_id, ctx),
BlockStatement::boxed_with_scope_id(SPAN, new_stmts, block_stmt_scope_id, ctx),
&using_ctx,
current_scope_id,
needs_await,
@@ -341,7 +341,7 @@ impl<'a> Traverse<'a, TransformState<'a>> for ExplicitResourceManagement<'a> {
node.block.body = ArenaVec::from_value_in(
Self::create_try_stmt(
BlockStatement::new_with_scope_id(SPAN, new_stmts, scope_id, ctx),
BlockStatement::boxed_with_scope_id(SPAN, new_stmts, scope_id, ctx),
&using_ctx,
block_stmt_scope_id,
needs_await,
@@ -633,7 +633,7 @@ impl<'a> ExplicitResourceManagement<'a> {
let current_scope_id = ctx.current_scope_id();
*stmt = Self::create_try_stmt(
BlockStatement::new_with_scope_id(SPAN, new_stmts, block_stmt.scope_id(), ctx),
BlockStatement::boxed_with_scope_id(SPAN, new_stmts, block_stmt.scope_id(), ctx),
&using_ctx,
current_scope_id,
needs_await,
@@ -774,7 +774,7 @@ impl<'a> ExplicitResourceManagement<'a> {
ctx,
);
BlockStatement::new_with_scope_id(SPAN, vec, block_stmt_sid, ctx)
BlockStatement::boxed_with_scope_id(SPAN, vec, block_stmt_sid, ctx)
};
let catch = Self::create_catch_clause(&using_ctx, current_scope_id, ctx);
@@ -903,7 +903,7 @@ impl<'a> ExplicitResourceManagement<'a> {
}
fn create_try_stmt(
body: BlockStatement<'a>,
body: ArenaBox<'a, BlockStatement<'a>>,
using_ctx: &BoundIdentifier<'a>,
parent_scope_id: ScopeId,
needs_await: bool,
@@ -961,7 +961,7 @@ impl<'a> ExplicitResourceManagement<'a> {
CatchClause::boxed_with_scope_id(
SPAN,
Some(catch_parameter),
BlockStatement::new_with_scope_id(SPAN, [stmt], block_scope_id, ctx),
BlockStatement::boxed_with_scope_id(SPAN, [stmt], block_scope_id, ctx),
catch_scope_id,
ctx,
)
+2 -2
View File
@@ -653,8 +653,8 @@ impl<'a> ReactRefresh<'a> {
if !custom_hooks_in_scope.is_empty() {
// function () { return custom_hooks_in_scope }
let formal_parameters =
FormalParameters::new(SPAN, FormalParameterKind::FormalParameter, [], NONE, ctx);
let function_body = FunctionBody::new(
FormalParameters::boxed(SPAN, FormalParameterKind::FormalParameter, [], NONE, ctx);
let function_body = FunctionBody::boxed(
SPAN,
[],
[Statement::new_return_statement(
@@ -297,7 +297,7 @@ impl<'a> TypeScriptNamespace {
parent_stmts.push(Statement::from(declaration));
}
}
let func_body = FunctionBody::new(SPAN, directives, new_stmts, ctx);
let func_body = FunctionBody::boxed(SPAN, directives, new_stmts, ctx);
parent_stmts.push(Self::transform_namespace(
span,
@@ -339,7 +339,7 @@ impl<'a> TypeScriptNamespace {
param_binding: &BoundIdentifier<'a>,
binding: &BoundIdentifier<'a>,
parent_binding: Option<&BoundIdentifier<'a>>,
func_body: FunctionBody<'a>,
func_body: ArenaBox<'a, FunctionBody<'a>>,
scope_id: ScopeId,
ctx: &mut TraverseCtx<'a>,
) -> Statement<'a> {
@@ -349,7 +349,13 @@ impl<'a> TypeScriptNamespace {
let params = {
let pattern = param_binding.create_binding_pattern(ctx);
let item = FormalParameter::new_plain(SPAN, pattern, ctx);
FormalParameters::new(SPAN, FormalParameterKind::FormalParameter, [item], NONE, ctx)
FormalParameters::boxed(
SPAN,
FormalParameterKind::FormalParameter,
[item],
NONE,
ctx,
)
};
let function_expr =
Expression::FunctionExpression(Function::boxed_plain_with_scope_id(
@@ -771,9 +771,9 @@ impl<'a> ModuleRunnerTransform<'a> {
ctx: &mut TraverseCtx<'a>,
) -> Expression<'a> {
let kind = FormalParameterKind::FormalParameter;
let params = FormalParameters::new(SPAN, kind, [], NONE, ctx);
let params = FormalParameters::boxed(SPAN, kind, [], NONE, ctx);
let statement = Statement::new_return_statement(SPAN, Some(expr), ctx);
let body = FunctionBody::new(SPAN, [], [statement], ctx);
let body = FunctionBody::boxed(SPAN, [], [statement], ctx);
let r#type = FunctionType::FunctionExpression;
let scope_id = ctx.create_child_scope(ctx.scoping().root_scope_id(), ScopeFlags::Function);
Expression::new_function_expression_with_scope_id_and_pure_and_pife(