Skip to content

Numeric helper call trees on f64; number-only leaves take converted arguments - #157

Merged
Lewin671 merged 3 commits into
mainfrom
agent/perf-22/claude
Sep 26, 2026
Merged

Lewin671 merged 3 commits into
mainfrom
agent/perf-22/claude

Conversation

@Lewin671

Copy link
Copy Markdown
Owner

Summary

  • Numeric helper call trees: a typed loop's numeric helper may now call another helper of its graph (itself included) when its arguments are proven numbers; the whole recursion runs on f64 registers under the same recursion bound, and settle drops (to a fixed point) any body whose callee is not numeric or does not return a number. recursive_call_tree: 716 -> 370 instructions a call.
  • Number-only leaves whose parameters reach the result only through operators take boolean and undefined arguments by ToNumber (sha1's safe_add(e, w[j]) past the end of w had deoptimized its block loops). A parameter returned as passed (id(x)) still declines.
  • T033 records the units, the stack run and three rejected experiments (global-function helper sites, a hand-written Value::clone, borrowed prototype-chain proofs).

Evidence

Formal stack run 7d18c3f vs main 8310883 (30 blocks, target/comparison/perf24-7d18c3ff): external geomean 0.998 vs main (0.772 vs QuickJS-NG); sentinels 0.901 vs main, 0.847 vs QuickJS-NG -- every sentinel now at or below QuickJS-NG (recursive_call_tree 0.682).

Verification

  • cargo test -p qjs-runtime (2251): new unit tests for recursive numeric bodies (fib, recursion past the bound, boolean-returning callee, untyped argument) and end-to-end tests (self/mutual recursion, undefined/boolean arguments, id(undefined)), expected values from V8.
  • check.sh via pre-push.

🤖 Generated with Claude Code

Lewin671 and others added 3 commits September 26, 2026 01:06
A typed loop's helper whose body only holds numbers ran on f64
registers -- unless it called a helper, as any recursion does, when the
whole tree fell to the tagged interpreter, which also clears a 24-entry
register file per call. A numeric body may now call another helper of
its graph (itself included) when every argument is proven a number: the
arguments are copied to contiguous registers above the body's, the call
runs the callee's numeric body under the tagged interpreter's recursion
bound, and `settle` drops, to a fixed point, any body whose callee is
not numeric or does not return a number (lowering assumed it did).
recursive_call_tree: 716 -> 370 instructions a call, 0.566 cycles
against main (QuickJS-NG 509 instructions).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
A number-only closed-form leaf (sha1's `safe_add`) declined any argument
that was not a number, so `safe_add(e, w[j])` with `w[j]` read past the
end of the input deoptimized crypto-sha1's block loops. Its operators
all apply ToNumber, so such an argument gives the same result as its
number -- unless a parameter reaches the result as passed
(`function id(x) { return x; }`). Compilation now tracks which values are
raw parameters, and a program that never returns one takes boolean and
undefined arguments by ToNumber.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@Lewin671
Lewin671 merged commit 5110c21 into main Sep 26, 2026
7 of 10 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant