Skip to content

Commit cab32ae

Browse files
committed
perf(ast): add #[inline(always)] to node_id methods on enums with all variants unboxed (#21707)
Follow-on after #21653. That PR revealed that some AST enums don't have all their variants boxed. Where all variants are boxed, `node_id` methods should boil down to a single instruction, so we mark the method `#[inline(always)]`. `node_id` method will also boil down to a single instruction where all variants are _not_ boxed, so add `#[inline(always)]` to them too. It's only where there's a mix of boxed and unboxed where the method will retain branching logic and be larger. Probably compiler will inline these methods anyway, but the attributes are a useful signal as to where we can improve the AST - all enums should consistently box _all_ their variants, or none of them.
1 parent 5c93af8 commit cab32ae

2 files changed

Lines changed: 12 additions & 4 deletions

File tree

crates/oxc_ast/src/generated/get_id.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3992,6 +3992,8 @@ impl ImportDeclarationSpecifier<'_> {
39923992

39933993
impl ImportAttributeKey<'_> {
39943994
/// Get [`NodeId`] of [`ImportAttributeKey`].
3995+
// `#[inline(always)]` because this should boil down to a single instruction.
3996+
#[inline(always)]
39953997
pub fn node_id(&self) -> NodeId {
39963998
match self {
39973999
Self::Identifier(it) => it.node_id(),
@@ -4058,6 +4060,8 @@ impl ExportDefaultDeclarationKind<'_> {
40584060

40594061
impl ModuleExportName<'_> {
40604062
/// Get [`NodeId`] of [`ModuleExportName`].
4063+
// `#[inline(always)]` because this should boil down to a single instruction.
4064+
#[inline(always)]
40614065
pub fn node_id(&self) -> NodeId {
40624066
match self {
40634067
Self::IdentifierName(it) => it.node_id(),
@@ -4366,6 +4370,8 @@ impl TSTypePredicateName<'_> {
43664370

43674371
impl TSModuleDeclarationName<'_> {
43684372
/// Get [`NodeId`] of [`TSModuleDeclarationName`].
4373+
// `#[inline(always)]` because this should boil down to a single instruction.
4374+
#[inline(always)]
43694375
pub fn node_id(&self) -> NodeId {
43704376
match self {
43714377
Self::Identifier(it) => it.node_id(),

tasks/ast_tools/src/generators/get_id.rs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -150,13 +150,15 @@ fn generate_for_struct(
150150

151151
fn generate_for_enum(enum_def: &EnumDef, schema: &Schema) -> Option<TokenStream> {
152152
// Check all variants are structs with a `NodeId` field (`has_kind` is only `true` for structs that do).
153-
// Also check if all variants are boxed.
153+
// Also check if all variants are consistently boxed or consistently unboxed.
154154
let mut all_variants_boxed = true;
155+
let mut all_variants_unboxed = true;
155156

156157
for variant in enum_def.all_variants(schema) {
157158
let mut field_type = variant.field_type(schema)?;
158159
if let Some(box_def) = field_type.as_box() {
159160
field_type = box_def.inner_type(schema);
161+
all_variants_unboxed = false;
160162
} else {
161163
all_variants_boxed = false;
162164
}
@@ -167,10 +169,10 @@ fn generate_for_enum(enum_def: &EnumDef, schema: &Schema) -> Option<TokenStream>
167169
}
168170
}
169171

170-
// If all variants are boxed, add `#[inline(always)]` to the method.
171-
// `NodeId` field is in a consistent position in all AST structs, so if all variants are boxed,
172+
// If all variants are consistently boxed or consistently unboxed, add `#[inline(always)]` to the method.
173+
// `NodeId` field is in a consistent position in all AST structs, so if all variants have the same shape,
172174
// the method should boil down to a single instruction.
173-
let maybe_inline = if all_variants_boxed {
175+
let maybe_inline = if all_variants_boxed || all_variants_unboxed {
174176
quote! {
175177
///@ `#[inline(always)]` because this should boil down to a single instruction.
176178
#[inline(always)]

0 commit comments

Comments
 (0)