From 679cc68e1ffbf6078d7e8d28373de31fb3e66a41 Mon Sep 17 00:00:00 2001 From: overlookmotel <557937+overlookmotel@users.noreply.github.com> Date: Wed, 16 Oct 2024 06:48:02 +0000 Subject: [PATCH] refactor(transformer): `HelperLoader` common transform: construct string directly in arena (#6596) Small optimization. Avoid allocating a temporary `String` which then gets copied into the arena, by constructing the string directly in the arena. We should probably have a dedicated API for doing this, but for now just do it here. --- .../src/common/helper_loader.rs | 26 ++++++++++++++----- 1 file changed, 19 insertions(+), 7 deletions(-) diff --git a/crates/oxc_transformer/src/common/helper_loader.rs b/crates/oxc_transformer/src/common/helper_loader.rs index e9fc0bccfa1f8..abfa4fa753696 100644 --- a/crates/oxc_transformer/src/common/helper_loader.rs +++ b/crates/oxc_transformer/src/common/helper_loader.rs @@ -65,7 +65,7 @@ use std::{borrow::Cow, cell::RefCell}; use rustc_hash::FxHashMap; use serde::Deserialize; -use oxc_allocator::Vec; +use oxc_allocator::{String as AString, Vec}; use oxc_ast::ast::{Argument, CallExpression, Expression, Program, TSTypeParameterInstantiation}; use oxc_semantic::{ReferenceFlags, SymbolFlags}; use oxc_span::{Atom, SPAN}; @@ -238,15 +238,27 @@ impl<'a> HelperLoaderStore<'a> { ctx: &mut TraverseCtx<'a>, ) -> Expression<'a> { let mut loaded_helpers = self.loaded_helpers.borrow_mut(); - let loaded_helper = loaded_helpers.entry(helper).or_insert_with(|| { - let helper_name = helper.name(); - let source = ctx.ast.atom(&format!("{}/helpers/{helper_name}", self.module_name)); - let local = ctx.generate_uid_in_root_scope(helper_name, SymbolFlags::Import); - LoadedHelper { source, local } - }); + let loaded_helper = + loaded_helpers.entry(helper).or_insert_with(|| self.get_runtime_helper(helper, ctx)); loaded_helper.local.create_read_expression(ctx) } + fn get_runtime_helper(&self, helper: Helper, ctx: &mut TraverseCtx<'a>) -> LoadedHelper<'a> { + let helper_name = helper.name(); + + // Construct string directly in arena without an intermediate temp allocation + let len = self.module_name.len() + "/helpers/".len() + helper_name.len(); + let mut source = AString::with_capacity_in(len, ctx.ast.allocator); + source.push_str(&self.module_name); + source.push_str("/helpers/"); + source.push_str(helper_name); + let source = Atom::from(source.into_bump_str()); + + let local = ctx.generate_uid_in_root_scope(helper_name, SymbolFlags::Import); + + LoadedHelper { source, local } + } + fn transform_for_external_helper(helper: Helper, ctx: &mut TraverseCtx<'a>) -> Expression<'a> { static HELPER_VAR: &str = "babelHelpers";