Skip to content

perf(parser): force-inline read_non_decimal to fold per-digit number dispatch#23157

Merged
graphite-app[bot] merged 1 commit into
mainfrom
perf/f2-inline-read-non-decimal
Jun 9, 2026
Merged

perf(parser): force-inline read_non_decimal to fold per-digit number dispatch#23157
graphite-app[bot] merged 1 commit into
mainfrom
perf/f2-inline-read-non-decimal

Conversation

@Boshen

@Boshen Boshen commented Jun 9, 2026

Copy link
Copy Markdown
Member

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

@Boshen Boshen self-assigned this Jun 9, 2026
@github-actions github-actions Bot added the A-parser Area - Parser label Jun 9, 2026
@codspeed-hq

codspeed-hq Bot commented Jun 9, 2026

Copy link
Copy Markdown

Merging this PR will not alter performance

✅ 62 untouched benchmarks
⏩ 9 skipped benchmarks1


Comparing perf/f2-inline-read-non-decimal (160ac54) with main (cd0b384)

Open in CodSpeed

Footnotes

  1. 9 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports.

@Boshen Boshen marked this pull request as ready for review June 9, 2026 15:08
@Boshen Boshen added the 0-merge Merge with Graphite Merge Queue label Jun 9, 2026

Boshen commented Jun 9, 2026

Copy link
Copy Markdown
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)
@graphite-app graphite-app Bot force-pushed the perf/f2-inline-read-non-decimal branch from 160ac54 to a6c11fa Compare June 9, 2026 16:31
@graphite-app graphite-app Bot merged commit a6c11fa into main Jun 9, 2026
30 checks passed
@graphite-app graphite-app Bot removed the 0-merge Merge with Graphite Merge Queue label Jun 9, 2026
@graphite-app graphite-app Bot deleted the perf/f2-inline-read-non-decimal branch June 9, 2026 16:37
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>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-parser Area - Parser

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant