perf(ast)!: reduce size of TSTypePredicateName#21711
Conversation
How to use the Graphite Merge QueueAdd either label to this PR to merge it via the merge queue:
You must have a Graphite account in order to use the merge queue. Sign up using this link. An organization admin has enabled the Graphite Merge Queue in this repository. Please do not merge from GitHub as this will restart CI on PRs being processed by the merge queue. This stack of pull requests is managed by Graphite. Learn more about stacking. |
Merging this PR will not alter performance
Comparing Footnotes
|
There was a problem hiding this comment.
Pull request overview
This PR reduces the memory footprint of TSTypePredicateName by boxing the This variant’s TSThisType, bringing the enum back down in size after the introduction of NodeId.
Changes:
- Change
TSTypePredicateName::Thisfrom an unboxedTSThisTypetoBox<'a, TSThisType>. - Update Rust traversal/formatter/parser code paths to dereference the boxed
TSThisType. - Regenerate/update JS NAPI lazy constructors/walkers/deserializers to match the new binary layout offsets.
Reviewed changes
Copilot reviewed 2 out of 22 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
| napi/parser/src-js/generated/lazy/walk.js | Updates walker offsets for TSTypePredicate and walks boxed TSThisType in TSTypePredicateName. |
| napi/parser/src-js/generated/lazy/constructors.js | Updates TSTypePredicate field offsets and constructs boxed TSThisType for TSTypePredicateName::This. |
| napi/parser/src-js/generated/deserialize/ts_range_parent.js | Adjusts TSTypePredicate.typeAnnotation offset and deserializes boxed TSThisType. |
| napi/parser/src-js/generated/deserialize/ts_range.js | Adjusts TSTypePredicate.typeAnnotation offset and deserializes boxed TSThisType. |
| napi/parser/src-js/generated/deserialize/ts_parent.js | Adjusts TSTypePredicate.typeAnnotation offset and deserializes boxed TSThisType. |
| napi/parser/src-js/generated/deserialize/ts.js | Adjusts TSTypePredicate.typeAnnotation offset and deserializes boxed TSThisType. |
| napi/parser/src-js/generated/deserialize/js_range_parent.js | Adjusts TSTypePredicate.typeAnnotation offset and deserializes boxed TSThisType. |
| napi/parser/src-js/generated/deserialize/js_range.js | Adjusts TSTypePredicate.typeAnnotation offset and deserializes boxed TSThisType. |
| napi/parser/src-js/generated/deserialize/js_parent.js | Adjusts TSTypePredicate.typeAnnotation offset and deserializes boxed TSThisType. |
| napi/parser/src-js/generated/deserialize/js.js | Adjusts TSTypePredicate.typeAnnotation offset and deserializes boxed TSThisType. |
| crates/oxc_traverse/src/generated/walk.rs | Fixes traversal of TSTypePredicateName::This by dereferencing the boxed TSThisType. |
| crates/oxc_parser/src/ts/types.rs | Allocates TSThisType into the arena and threads Box<TSThisType> through type-predicate parsing. |
| crates/oxc_minifier/src/generated/walk.rs | Fixes traversal of TSTypePredicateName::This by dereferencing the boxed TSThisType. |
| crates/oxc_formatter/src/ast_nodes/generated/ast_nodes.rs | Formats/unwraps TSTypePredicateName::This via as_ref() to obtain &TSThisType. |
| crates/oxc_ast/src/generated/get_id.rs | Adds #[inline(always)] to TSTypePredicateName::node_id() (consistent with other wrappers). |
| crates/oxc_ast/src/generated/derive_get_span_mut.rs | Updates GetSpanMut impl to dereference boxed TSThisType. |
| crates/oxc_ast/src/generated/derive_get_span.rs | Updates GetSpan impl to dereference boxed TSThisType. |
| crates/oxc_ast/src/generated/derive_dummy.rs | Updates dummy docs to reflect that TSTypePredicate/TSTypePredicateName now allocate (due to boxing). |
| crates/oxc_ast/src/generated/ast_builder.rs | Builds TSTypePredicateName::This using alloc_ts_this_type to match new boxed variant. |
| crates/oxc_ast/src/generated/assert_layouts.rs | Updates layout assertions (sizes/offsets) for TSTypePredicate and TSTypePredicateName. |
| crates/oxc_ast/src/ast/ts.rs | Changes TSTypePredicateName::This variant to Box<'a, TSThisType>. |
| apps/oxlint/src-js/generated/deserialize.js | Adjusts TSTypePredicate.typeAnnotation offset and deserializes boxed TSThisType. |
d0a2933 to
9d1c55b
Compare
db9b1f5 to
9842ab0
Compare
TSTypePredicateNameTSTypePredicateName
Merge activity
|
#21653 revealed that `TSTypePredicateName` has an unboxed variant `This`. Before the introduction of `NodeId` fields, this was fine as `TSThisType` contained only a `Span` (8 bytes). But with `NodeId` field added, it's 16 bytes, which makes `TSTypePredicateName` larger too - 24 bytes. Box `TSThisType` in this variant, bringing `TSTypePredicateName` back down to 16 bytes. This also has the side-effect of making `TSTypePredicateName`'s `node_id`, `span`, and `span_mut` methods branchless.
9d1c55b to
5651539
Compare
9842ab0 to
502e804
Compare
### 💥 BREAKING CHANGES - 502e804 ast: [**BREAKING**] Reduce size of `TSTypePredicateName` (#21711) (overlookmotel) - 5651539 ast: [**BREAKING**] Reduce size of `JSXExpression` (#21710) (overlookmotel) - c44e280 ast: [**BREAKING**] Reduce size of `ArrayExpressionElement` (#21709) (overlookmotel) - c5b3deb syntax: [**BREAKING**] Remove `CommentNodeId` (#21679) (overlookmotel) ### 🚀 Features - b738a39 allocator: Add `Allocator::cursor_ptr` method (#21773) (overlookmotel) - 678767e ast: Generate node_id accessors for AST enum wrappers (#21653) (camc314) - f091d77 minifier: Inline constant spread elements into arrays (#21095) (Armano) ### 🐛 Bug Fixes - 0d608c2 minifier: Preserve raw CR in template literals (#21645) (Dunqing) - a889ea9 minifier: Track pure functions in DCE mode (#21722) (Dunqing) - 674dfac allocator: `Arena` retry allocation when chunk size approaches maximum (#21777) (overlookmotel) - f130cc0 allocator: Fix arithmetic overflow in `Arena::new_chunk_memory_details` (#21745) (overlookmotel) - b9bf239 allocator: Fix UB in `Arena::grow_zeroed` (#21739) (overlookmotel) - d2b9389 allocator: Clippy warning when building without `testing` feature (#21681) (camc314) - 503dc86 codegen: Map sourcemaps from visible output starts (#21662) (Dunqing) - c92bd3b transformer: Use SPAN for synthesized helper calls to prevent comment misattribution (#21578) (Dunqing) - 0d80441 codegen: Add mapping before printing `#` for private ident (#21619) (camc314) ### ⚡ Performance - 9fa362e napi/parser: Do not generate tokens except in tests (#21811) (overlookmotel) - 0044392 allocator: Reduce branches when allocating new chunk (#21776) (overlookmotel) - 7896bd0 allocator: `Allocator::used_bytes` do not use chunk iterator (#21771) (overlookmotel) - a5c562f allocator: Remove check in `Arena::new_chunk_memory_details` (#21750) (overlookmotel) - 35bbe1f allocator: `Arena` use unchecked size round up where guaranteed no overflow (#21743) (overlookmotel) - ffe229b allocator: Remove unnecessary check from `Arena::try_alloc_layout_slow_impl` (#21732) (overlookmotel) - 72fece5 allocator: Use `NonNull::offset_from_unsigned` in `Arena::chunk_capacity` (#21731) (overlookmotel) - cab32ae ast: Add `#[inline(always)]` to `node_id` methods on enums with all variants unboxed (#21707) (overlookmotel) - b179688 parser: Allocate `TriviaBuilder` comments in the arena (#21512) (Boshen) - 2290f31 lexer: Fix perf of `Token::set_*` methods on Rust 1.95.0 (#21659) (overlookmotel) - 1b58029 allocator: Move code into cold path in `Arena::alloc_layout` (#21622) (overlookmotel) - 3cf7cef allocator: Reduce instructions on allocation hot path (#21510) (overlookmotel) ### 📚 Documentation - ce65070 data_structures: Document why `as_ref` and `as_mut` on `NonNullConst` and `NonNullMut` take `self` (#21800) (overlookmotel) - 93b7dbd allocator: Improve doc comments for `ChunkFooter` (#21733) (overlookmotel) - 295db8d transformer: Fix comment (#21717) (overlookmotel) - 5c93af8 ast: Add comments explaining `#[inline(always)]` to `node_id` methods on enums (#21706) (overlookmotel) - e4cea25 transform: Use the `node:` namespace in the example (#19998) (루밀LuMir) ### 🛡️ Security - d8076c9 deps: Update rolldown (#21639) (renovate) Co-authored-by: Boshen <1430279+Boshen@users.noreply.github.com>
# Oxlint ### 💥 BREAKING CHANGES - 502e804 ast: [**BREAKING**] Reduce size of `TSTypePredicateName` (#21711) (overlookmotel) - 5651539 ast: [**BREAKING**] Reduce size of `JSXExpression` (#21710) (overlookmotel) - c44e280 ast: [**BREAKING**] Reduce size of `ArrayExpressionElement` (#21709) (overlookmotel) ### 🚀 Features - b4acdbd linter/vue: Implement no-deprecated-delete-set rule (#21766) (bab) - 613bfef linter: Split jest/prefer-to-contain into a jest and a vitest rule. (#21821) (connorshea) - c629719 linter/vue: Implement no-deprecated-events-api rule (#21793) (Alex Peshkov) - f2a8528 linter: Split jest/require-top-level-describe rule into a Jest and a Vitest rule. (#21822) (connorshea) - ea4b358 linter: Split jest/prefer-todo into a shared rule and a vitest-specific rule. (#21820) (connorshea) - 3a66819 linter: Split jest/no-mocks-import into vitest/no-mocks-import (#21818) (camchenry) - 0b3ffce linter: Split jest/no-large-snapshots into vitest/no-large-snapshots (#21814) (camchenry) - d1cf22e linter: Split jest/no-interpolation-in-snapshots into vitest/no-interpolation-in-snapshots (#21812) (camchenry) - bb0c359 linter: Split jest/no-identical-title into vitest/no-identical-title (#21810) (camchenry) - c26ea41 linter: Split jest/no-hooks into vitest/no-hooks (#21809) (camchenry) - 46b32f2 linter: Split jest/no-focused-tests into vitest/no-focused-tests (#21804) (camchenry) - acf41a8 linter: Split jest/no-duplicate-hooks into vitest/no-duplicate-hooks (#21803) (camchenry) - 54d787f linter: Split jest/no-disabled-tests into vitest/no-disabled-tests (#21802) (camchenry) - 9c9a676 linter/vue: Implement no-deprecated-data-object-declaration rule (#21764) (bab) - 4445855 linter: Split `jest/no-conditional-in-test` into `vitest/no-conditional-in-test` (#21763) (camchenry) - b8604de linter: Split `jest/no-conditional-expect` into `vitest/no-conditional-expect` (#21762) (camchenry) - 0dbd650 linter: Split `jest/no-commented-out-tests` into `vitest/no-commented-out-tests` (#21761) (camchenry) - 7f1a97c linter: Split `jest/no-alias-methods` into `vitest/no-alias-methods` (#21760) (camchenry) - eb97c49 linter: Split `jest/max-nested-describe` into `vitest/max-nested-describe` (#21759) (camchenry) - d870cad linter: Split `jest/max-expects` into `vitest/max-expects` (#21758) (camchenry) - 1b97124 linter/vue: Implement no-deprecated-vue-config-keycodes rule (#21699) (bab) - 5f81883 linter/eslint: Implement `func-name-matching` rule (#21708) (Mikhail Baev) - 348f46c linter: Add `respectEslintDisableDirectives` option (#21384) (Christian Vuerings) - 63ec351 linter: Support nested vite+ config discovery (#21638) (camc314) - 560feb4 linter: Introduce `Vite` variant to `DiscoveredConfigFile` (#21637) (camc314) - 07dc41e linter/eslint: Implement `no-underscore-dangle` rule (#21630) (Paul-Arthur THIERY) - e270d54 linter/react: Impl react/no-did-update-set-state (#17322) (Kenzo Wada) - ca81199 linter/react: Implement `forbid-component-props` rule (#20005) (Mikhail Baev) - 6776403 linter/branches-sharing-code: Move rule from nursery to pedantic (#21621) (camc314) - ce7a4dc linter/no-unreachable: Move rule from nursery to correctness (#21618) (camc314) - e3b5e78 linter/getter-return: Move rule from nursery to correctness (#21617) (camc314) - d3a7e9a linter/unicorn: Implement suggestion for `no-useless-iterator-to-array` rule (#21610) (Mikhail Baev) - a0c883c oxlint/lsp: Add vite plus version to server info (#21587) (Sysix) - 67ff860 linter/no-unknown-property: Support React 19 `precedence` prop (#21590) (João Pedro Schmitz) ### 🐛 Bug Fixes - aace797 linter: Detect Svelte TS and module scripts correctly (#20819) (mustafa0x) - 3612db1 linter/prefer-default-parameters: Skip reporting on object/class setters (#21836) (camc314) - 28c3521 oxlint/lsp: Remove overlapping edits for `source.fixAllDangerous.oxc` code action (#21785) (Sysix) - 705a82c linter/no-non-null-asserted-nullish-coalescing: Add fixer (#21827) (yyh) - 33f5535 linter: Add checks that `Program` is in current allocator chunk before JS plugins linting (#21774) (overlookmotel) - d122877 linter/no-extra-non-null-assertions: Add fixer (#21744) (yyh) - 37f0731 linter: `with_plugin_vitest(true)` working realiable in test mode (#21769) (Said Atrahouch) - e42e6a6 linter/role-supports-aria-props: False positive with `combobox` and `haspopup` (#21725) (Leonabcd123) - e24324f linter: Iframe-has-title false positive for template literals (#21714) (Leonabcd123) - 41a6510 linter/vitest/hoisted-apis-on-top: Only check first member (#20068) (Sidharth Vinod) - 98ed888 linter: Check initializer for allowConstantExport in only-export-components (#20608) (Eyüp Can Akman) - 1946e8b linter: Avoid applying override plugin categories to eslint rules (#21521) (bab) - 3d1e83a linter: Parse `<script>` tag attributes with curly braces in Svelte files (#21089) (bab) - bc6ade5 linter: Report actual disable directive prefix (#21682) (camc314) - bf84466 linter: Respect category settings in overrides (#19411) (Connor Shea) - 52ecb45 linter/vitest: Don't treat `test.extend` or `it.extend` as test functions (#21668) (Said Atrahouch) - aa1a00c linter: Support jsx-a11y attributes setting in anchor-is-valid rule (#21665) (camchenry) - 30e0ad3 linter/prefer-default-parameters: Preserve TS annotations in fixer (#21655) (camc314) - 8c425db linter: Allow string for jest version in config schema (#21649) (camc314) - 3617864 linter/react/display-name: Fix false positive for named default class (#21643) (Mikhail Baev) - f3a02cc linter/no-non-null-assertion: Improve diagnostic message (#21616) (Cameron) - c2ada2c linter: Make `--fix-dangerously` fix dangerous fixes and suggestions as documented (#13366) (Ulrich Stark) - 8265ed9 linter/sort-keys: Handle CRLF separated groups (#21608) (camc314) - 96c559e linter/no-shadow: Add note explaining enum member shadowing (#21607) (camc314) - 3b49389 linter: No-irregular-whitespace: add config options (#21559) (camchenry) ### ⚡ Performance - cdc9eae oxlint/lsp: Avoid clones on lsp options deserializion (#21748) (Sysix) - be2db80 linter/sort-keys: Reduce allocations (#21560) (camchenry) ### 📚 Documentation - 453d647 linter: Remove now-unnecessary compatibility notes from shared Jest/Vitest rules. (#21826) (connorshea) - b1574a2 linter: Fix the configuration docs for no-underscore-dangle rule. (#21801) (connorshea) - 6946aee linter: Remove no-longer-relevant documentation about vitest compatibility from shared Jest/Vitest rules. (#21799) (connorshea) - 0652ea2 linter: Misc grammar cleanup for Vitest rules. (#21755) (connorshea) - 99f0b68 linter: Improve docs for `vitest/require-mock-type-parameters` rule. (#21754) (connorshea) - 9e2796b linter: Improve the docs for the `vitest/hoisted-apis-on-top` rule. (#21753) (connorshea) - 2ccede2 linter: Improve function usage examples in doc comments (#21718) (overlookmotel) - 43adae9 linter: Add version section to rules page (#21601) (camchenry) - d15dad2 linter: Export rule version metadata (#21588) (Old Autumn) # Oxfmt ### 💥 BREAKING CHANGES - 502e804 ast: [**BREAKING**] Reduce size of `TSTypePredicateName` (#21711) (overlookmotel) - 5651539 ast: [**BREAKING**] Reduce size of `JSXExpression` (#21710) (overlookmotel) - c44e280 ast: [**BREAKING**] Reduce size of `ArrayExpressionElement` (#21709) (overlookmotel) ### 🚀 Features - 3bc54a9 oxfmt: Respect nested config for `--stdin-filepath` (#21627) (leaysgur) - 144f27a oxfmt: Respect ignore settings for `--stdin-filepath` (#21625) (leaysgur) - 81c7ae4 oxfmt/lsp: Add vite plus version to server info (#21586) (Sysix) ### 🐛 Bug Fixes - 477435b formatter/sort_imports: Keep leading blank line when decreasing group transitions (#21835) (leaysgur) - 38d1e82 oxfmt/lsp: Format non `file://` URIs without a authority (#21647) (Sysix) - 5eb8e2b formatter/sort_imports: Preserve blank lines around ignored side-effect imports (#21692) (leaysgur) - 0dce3c6 oxfmt: Handle invalid `overrides` config without panic (#21661) (Yuji Sugiura) - 9f82ed4 formatter: Escape backticks in JSDoc inline code spans (#21577) (bab) ### ⚡ Performance - db6c603 oxfmt/lsp: Avoid clones on lsp options deserializion (#21749) (Sysix) - 6a96c76 formatter: Avoid heap alloc for jsdoc delimiter (#21597) (leaysgur) --------- Co-authored-by: Boshen <1430279+Boshen@users.noreply.github.com> Co-authored-by: Cameron Clark <cameron.clark@hey.com>

#21653 revealed that
TSTypePredicateNamehas an unboxed variantThis.Before the introduction of
NodeIdfields, this was fine asTSThisTypecontained only aSpan(8 bytes). But withNodeIdfield added, it's 16 bytes, which makesTSTypePredicateNamelarger too - 24 bytes.Box
TSThisTypein this variant, bringingTSTypePredicateNameback down to 16 bytes.This also has the side-effect of making
TSTypePredicateName'snode_id,span, andspan_mutmethods branchless.