From 3f53b6f586c8c96ce683d9ecf97a9fdaf5b35e5e Mon Sep 17 00:00:00 2001 From: rzvxa <3788964+rzvxa@users.noreply.github.com> Date: Sat, 3 Aug 2024 12:23:41 +0000 Subject: [PATCH] refactor(ast): make AST structs `repr(C)`. (#4614) Make structs `#[repr(C)]` without reordering them to benchmark the performance implications of it. This PR adds 136 bytes of padding in total. You can visit the list of these types [here](https://github.com/oxc-project/oxc/pull/4404/files/)(checkout the `assert_layouts.rs` diff). Update: Doesn't seem too bad! ![image](https://github.com/user-attachments/assets/05ac9cc8-7cb0-4ed5-9220-44f65c7f5bb9) * Linter: We can easily get more than 1% performance gain in the linter to even things out * Prepass: If we fix our issue with Rust `1.80.0` we gain 13% And it should also be possible to find some other areas there to gain back this one percent. The most notable thing is that `parser` isn't impacted by this, That is our most optimized crate which every percent counts(and it can be hard to gain back any perf regression there). --- crates/oxc_ast_macros/src/lib.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/crates/oxc_ast_macros/src/lib.rs b/crates/oxc_ast_macros/src/lib.rs index 75cd7e505..c6726f109 100644 --- a/crates/oxc_ast_macros/src/lib.rs +++ b/crates/oxc_ast_macros/src/lib.rs @@ -17,9 +17,10 @@ fn enum_repr(enum_: &syn::ItemEnum) -> TokenStream2 { /// It is also a lightweight macro; All of its computation is cached and /// it only applies the following changes without any complex operation: /// +/// * Prepend `#[repr(C)]` to structs /// * Prepend `#[repr(C, u8)]` to fieldful enums e.g. `enum E { X: u32, Y: u8 }` /// * Prepend `#[repr(u8)]` to unit (fieldless) enums e.g. `enum E { X, Y, Z, }` -/// * Prepend `#[derive(oxc_ast_macros::Ast)]` +/// * Prepend `#[derive(oxc_ast_macros::Ast)]` to all structs and enums /// #[proc_macro_attribute] #[allow(clippy::missing_panics_doc)] @@ -28,8 +29,7 @@ pub fn ast(_args: TokenStream, input: TokenStream) -> TokenStream { let repr = match input { syn::Item::Enum(ref enum_) => enum_repr(enum_), - // In future, we'll add `#[repr(C)]` to structs, but at present this is disabled - syn::Item::Struct(_) => TokenStream2::default(), + syn::Item::Struct(_) => quote!(#[repr(C)]), _ => { unreachable!()