Skip to content

Perf: add guarded integer specialization to the baseline JIT #56

Description

@chrisbbreuer

Parent JIT: #52
Arithmetic target: #46

Problem

After block accounting, register-resident numeric locals, compare/branch fusion, and hot-successor batching, the arithmetic kernel remained roughly 2.8x behind the then-accepted JSC direct result. Repeated A/B experiments showed that removing FP moves or constant-divisor setup was neutral: the critical path was keeping integer loop state as f64, validating it, converting it to an integer, dividing, and converting it back on every %.

Resolution

The guarded integer specialization landed as a sequence of general baseline-JIT changes:

  • 69dfc786 — unsigned entry guards before native work
  • 6011cc1b — integer provenance dataflow
  • 1fc7e9c1 — bounded integer ranges
  • 5b8aacb3 and b21cdfb7 — branch refinement and conservative threshold widening
  • 8dd91738 — checked unsigned 64-bit arithmetic
  • 61b379cc — integer register selection
  • 6a1c844c — guarded integer-region lowering

The implementation now:

  • evaluates parameter kind/range guards before native step accounting or frame-slot mutation;
  • propagates integer provenance and conservative ranges through loops, branches, and merges;
  • keeps selected locals and operand values in GPRs and materializes canonical Number words at checkpoints/returns;
  • lowers guarded integer add/sub/mul/comparisons and remainder without repeated f64 round trips;
  • rejects or falls back before observable native work when entry assumptions fail, with checked range/overflow behavior rather than wrapping;
  • retains exact bytecode step accounting, the 1,024-step checkpoint contract, termination/GC/GIL servicing, and interpreter fallback for fractional, NaN, negative-zero, escaped-frame, or unsupported shapes;
  • selects only from bytecode/runtime guards—never source strings, function names, benchmark names, or call-site identity.

Focused tests cover guard acceptance/rejection, mixed-kind provenance rejection, bounded ranges, guarded remainder execution, register encodings, exact native step limits, and non-number fallback. The new zig build test-jit small root keeps those tests directly runnable without the monolithic integration artifact.

Accepted performance evidence

The July 15, 2026 128-byte-slab comparison report measures identical arithmetic source/work across engines:

Required work

  • Add per-parameter integer/range guards evaluated before native step accounting or slot mutation.
  • Extend numeric dataflow with integer provenance and conservative ranges across loops/merges.
  • Allocate integer locals/operand values to GPRs while retaining canonical Number publication at safepoints and returns.
  • Lower integer add/sub/mul/comparisons and constant remainder without repeated f64 round trips.
  • Define checked overflow handling through proofs, guarded fallback, or rejection before observable work.
  • Preserve max-step errors, 1,024-step GIL/GC/termination checkpoints, NaN/-0/fractional fallback, and escaped-frame rejection.
  • Add focused guard/deopt/range tests plus accepted order-balanced arithmetic evidence.
  • Publish the symmetric JSC report only after the optimization batch and gates were material.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions