perf(parser): force-inline read_non_decimal to fold per-digit number dispatch#23157
Merged
Merged
Conversation
Merging this PR will not alter performance
Comparing Footnotes
|
Member
Author
Merge activity
|
…dispatch (#23157) ## Finding (F2 from assembly audit) `read_non_decimal` (numeric.rs) has a comment stating it must inline into its 3 `read_zero` call sites so the constant `kind` lets `kind.matches_number_byte(b)` reduce to one match arm. **Assembly shows plain `#[inline]` did not achieve this** — it stayed a single out-of-line symbol taking `kind` as a runtime arg, re-masking + re-comparing `kind` on every digit of a `0x`/`0o`/`0b` literal. ## Change `#[inline]` → `#[inline(always)]`. The standalone `read_non_decimal` symbol disappears; each radix call site monomorphizes on its constant kind and the per-digit dispatch folds. ##⚠️ Tradeoff — needs CodSpeed before merge The `ZER` byte-handler grows **~68 → 293 instructions** (read_zero + read_non_decimal now inline for all 3 radices). `ZER` handles *all* `0`-prefixed tokens (`0`, `0.5`, `0n`, legacy octal), so this is a static-size/icache cost on those common paths in exchange for fewer dynamic instructions per non-decimal digit. **This is only a win if CodSpeed (instruction count) confirms it net-positive** on representative input; non-decimal literals are rare in typical JS/TS, so it may be neutral-to-negative. Draft pending that signal. ## Verification - Conformance: **byte-identical** to `main` across all 31 snapshot suites (test262/babel/typescript × parser/semantic/codegen/estree/transformer/minifier/formatter). - Assembly re-checked: `read_non_decimal` standalone symbol removed; folded dispatch confirmed in `ZER`. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
160ac54 to
a6c11fa
Compare
Boshen
added a commit
that referenced
this pull request
Jun 15, 2026
### 💥 BREAKING CHANGES - 7a24911 codegen: [**BREAKING**] Borrow sourcemaps from codegen (#23422) (Boshen) - bb0ed44 transformer: [**BREAKING**] Disable styled-components transpileTemplateLiterals by default (#23171) (Boshen) ### 🚀 Features - 1490a0a linter/react: Implement react-compiler rule (#23202) (Boshen) - 6c0bdf0 transformer/react-refresh: Support `module.property.useHook()` (#23190) (Dunqing) - 47991bd semantic: Report TS1228 for invalid type predicates (#23174) (camc314) - 1d3af58 parser: Add TS2398 parameter property diagnostic (#23216) (camc314) - 44313da semantic: Add `scope_is_descendant_of` api (#22313) (camc314) - e5050c0 parser: Improve diagnostic for rest initializer (#23205) (camc314) - ec266bb transformer: Run React Compiler as a feature-gated transform pass (#23201) (Boshen) - e7374fe parser: Report error for `const` modifier on interface type parameter (#23173) (camc314) - a7c1c9b parser: Report ambient definite variable assertions (#23165) (camc314) - d169fcd parser: Report invalid class definite assertions (#23164) (camc314) - 00244d8 parser: Report definite property initializer errors (#23160) (camc314) ### 🐛 Bug Fixes - 52d0c31 transformer: Replace ambient dot defines (#23231) (camc314) - 2c28748 transformer/class: Parent generated constructors to class scope (#23222) (camc314) - 8edd234 parser: Report accessor definite assertion on token (#23203) (camc314) - de38a3f react_compiler: Keep imports referenced only by a local re-export (#23176) (Boshen) - f5721c2 codegen: Preserve parentheses around `intrinsic` type reference (#23156) (Boshen) - e89f81d parser: Don't emit TS1477 for parenthesized instantiation expression (#23147) (Boshen) - 8a04149 parser: Reject module-referencing imports/exports in a namespace body (#22829) (Boshen) ### ⚡ Performance - 2783295 parser: Table-driven operator precedence lookup (#23346) (Boshen) - 231d5de parser: Single-match member expression dispatch (#23347) (Boshen) - e89729b codegen: Accept one-shot wrap closures (#23265) (camc314) - a6c11fa parser: Force-inline read_non_decimal to fold per-digit number dispatch (#23157) (Boshen) - d74964c parser: Store class definite assertion offset (#23170) (camc314) - f0fda4d parser: Shrink-wrap cold diagnostic tails out of hot frames (#23159) (Boshen) - a082180 parser: Store definite assertion offset (#23167) (camc314) - 534f9c6 oxc: Conditionally rebuild semantic in compiler pipeline (#23153) (Boshen) - b435c6a parser: Skip checkpoint for `infer T extends U` constraint in disallow context (#23128) (Boshen) - 7464dce parser: Peek instead of checkpoint/rewind for `export default` modifier (#23124) (Boshen) - 80a9a32 parser: Fast-path single-keyword TS declarations (#23083) (Boshen) - da1a6c6 diagnostics: Migrate to allocation-optimized oxc-miette (#23094) (Boshen) - b7b08ce parser: Peek once for the static modifier disambiguation (#23079) (Boshen) - e7e07a3 parser: Fold unary dispatch into a single match (#23076) (Boshen) ### 📚 Documentation - d241add semantic: Add `AGENTS.md` test guidance for agents (#23441) (camc314) - 026f1ae parser: Add `AGENTS.md` test guidance for agents (#23440) (camc314) - 09755ac transformer: Add `AGENTS.md` test guidance for agents (#23439) (camc314) - e6bdfd4 lexer: Correct reference link for `byte_handlers!` (#23313) (Dunqing) - 65b6d7a allocator: Fix memory leaks in `Arena` examples (#23257) (overlookmotel) Co-authored-by: Boshen <1430279+Boshen@users.noreply.github.com>
camc314
pushed a commit
that referenced
this pull request
Jul 3, 2026
…dispatch (#23157) ## Finding (F2 from assembly audit) `read_non_decimal` (numeric.rs) has a comment stating it must inline into its 3 `read_zero` call sites so the constant `kind` lets `kind.matches_number_byte(b)` reduce to one match arm. **Assembly shows plain `#[inline]` did not achieve this** — it stayed a single out-of-line symbol taking `kind` as a runtime arg, re-masking + re-comparing `kind` on every digit of a `0x`/`0o`/`0b` literal. ## Change `#[inline]` → `#[inline(always)]`. The standalone `read_non_decimal` symbol disappears; each radix call site monomorphizes on its constant kind and the per-digit dispatch folds. ##⚠️ Tradeoff — needs CodSpeed before merge The `ZER` byte-handler grows **~68 → 293 instructions** (read_zero + read_non_decimal now inline for all 3 radices). `ZER` handles *all* `0`-prefixed tokens (`0`, `0.5`, `0n`, legacy octal), so this is a static-size/icache cost on those common paths in exchange for fewer dynamic instructions per non-decimal digit. **This is only a win if CodSpeed (instruction count) confirms it net-positive** on representative input; non-decimal literals are rare in typical JS/TS, so it may be neutral-to-negative. Draft pending that signal. ## Verification - Conformance: **byte-identical** to `main` across all 31 snapshot suites (test262/babel/typescript × parser/semantic/codegen/estree/transformer/minifier/formatter). - Assembly re-checked: `read_non_decimal` standalone symbol removed; folded dispatch confirmed in `ZER`. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
camc314
pushed a commit
that referenced
this pull request
Jul 3, 2026
### 💥 BREAKING CHANGES - 7a24911 codegen: [**BREAKING**] Borrow sourcemaps from codegen (#23422) (Boshen) - bb0ed44 transformer: [**BREAKING**] Disable styled-components transpileTemplateLiterals by default (#23171) (Boshen) ### 🚀 Features - 1490a0a linter/react: Implement react-compiler rule (#23202) (Boshen) - 6c0bdf0 transformer/react-refresh: Support `module.property.useHook()` (#23190) (Dunqing) - 47991bd semantic: Report TS1228 for invalid type predicates (#23174) (camc314) - 1d3af58 parser: Add TS2398 parameter property diagnostic (#23216) (camc314) - 44313da semantic: Add `scope_is_descendant_of` api (#22313) (camc314) - e5050c0 parser: Improve diagnostic for rest initializer (#23205) (camc314) - ec266bb transformer: Run React Compiler as a feature-gated transform pass (#23201) (Boshen) - e7374fe parser: Report error for `const` modifier on interface type parameter (#23173) (camc314) - a7c1c9b parser: Report ambient definite variable assertions (#23165) (camc314) - d169fcd parser: Report invalid class definite assertions (#23164) (camc314) - 00244d8 parser: Report definite property initializer errors (#23160) (camc314) ### 🐛 Bug Fixes - 52d0c31 transformer: Replace ambient dot defines (#23231) (camc314) - 2c28748 transformer/class: Parent generated constructors to class scope (#23222) (camc314) - 8edd234 parser: Report accessor definite assertion on token (#23203) (camc314) - de38a3f react_compiler: Keep imports referenced only by a local re-export (#23176) (Boshen) - f5721c2 codegen: Preserve parentheses around `intrinsic` type reference (#23156) (Boshen) - e89f81d parser: Don't emit TS1477 for parenthesized instantiation expression (#23147) (Boshen) - 8a04149 parser: Reject module-referencing imports/exports in a namespace body (#22829) (Boshen) ### ⚡ Performance - 2783295 parser: Table-driven operator precedence lookup (#23346) (Boshen) - 231d5de parser: Single-match member expression dispatch (#23347) (Boshen) - e89729b codegen: Accept one-shot wrap closures (#23265) (camc314) - a6c11fa parser: Force-inline read_non_decimal to fold per-digit number dispatch (#23157) (Boshen) - d74964c parser: Store class definite assertion offset (#23170) (camc314) - f0fda4d parser: Shrink-wrap cold diagnostic tails out of hot frames (#23159) (Boshen) - a082180 parser: Store definite assertion offset (#23167) (camc314) - 534f9c6 oxc: Conditionally rebuild semantic in compiler pipeline (#23153) (Boshen) - b435c6a parser: Skip checkpoint for `infer T extends U` constraint in disallow context (#23128) (Boshen) - 7464dce parser: Peek instead of checkpoint/rewind for `export default` modifier (#23124) (Boshen) - 80a9a32 parser: Fast-path single-keyword TS declarations (#23083) (Boshen) - da1a6c6 diagnostics: Migrate to allocation-optimized oxc-miette (#23094) (Boshen) - b7b08ce parser: Peek once for the static modifier disambiguation (#23079) (Boshen) - e7e07a3 parser: Fold unary dispatch into a single match (#23076) (Boshen) ### 📚 Documentation - d241add semantic: Add `AGENTS.md` test guidance for agents (#23441) (camc314) - 026f1ae parser: Add `AGENTS.md` test guidance for agents (#23440) (camc314) - 09755ac transformer: Add `AGENTS.md` test guidance for agents (#23439) (camc314) - e6bdfd4 lexer: Correct reference link for `byte_handlers!` (#23313) (Dunqing) - 65b6d7a allocator: Fix memory leaks in `Arena` examples (#23257) (overlookmotel) Co-authored-by: Boshen <1430279+Boshen@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Finding (F2 from assembly audit)
read_non_decimal(numeric.rs) has a comment stating it must inline into its 3read_zerocall sites so the constantkindletskind.matches_number_byte(b)reduce to one match arm. Assembly shows plain#[inline]did not achieve this — it stayed a single out-of-line symbol takingkindas a runtime arg, re-masking + re-comparingkindon every digit of a0x/0o/0bliteral.Change
#[inline]→#[inline(always)]. The standaloneread_non_decimalsymbol disappears; each radix call site monomorphizes on its constant kind and the per-digit dispatch folds.The
ZERbyte-handler grows ~68 → 293 instructions (read_zero + read_non_decimal now inline for all 3 radices).ZERhandles all0-prefixed tokens (0,0.5,0n, legacy octal), so this is a static-size/icache cost on those common paths in exchange for fewer dynamic instructions per non-decimal digit. This is only a win if CodSpeed (instruction count) confirms it net-positive on representative input; non-decimal literals are rare in typical JS/TS, so it may be neutral-to-negative. Draft pending that signal.Verification
mainacross all 31 snapshot suites (test262/babel/typescript × parser/semantic/codegen/estree/transformer/minifier/formatter).read_non_decimalstandalone symbol removed; folded dispatch confirmed inZER.🤖 Generated with Claude Code