Skip to content

Extend the tight-loop lane to while and do-while statements#2688

Merged
lahma merged 2 commits into
sebastienros:mainfrom
lahma:perf-while-tight-lane
Jul 15, 2026
Merged

Extend the tight-loop lane to while and do-while statements#2688
lahma merged 2 commits into
sebastienros:mainfrom
lahma:perf-while-tight-lane

Conversation

@lahma

@lahma lahma commented Jul 15, 2026

Copy link
Copy Markdown
Collaborator

Summary

for-loops with structurally-Normal bodies (expression statements, var/let/const, if/else chains — nothing that routes a break/continue/return/label) bypass per-iteration completion bookkeeping, suspension probes and per-statement ceremony via JintForStatement.TightForBody. while and do-while loops with the identical body shapes still paid all of it — a Completion struct and value-liveness check per iteration, two suspendable probes, and full _body.Execute dispatch.

This extends the same lane to while and do-while: the shared IsTightBodyShape predicate decides eligibility, and eligible bodies run through the same ExecuteDiscarded path — test, discarded body statements and a deferred-error poll per iteration, with amortized constraints (timeout/cancellation/memory) driven through the existing shared countdown. Bodies with lexical declarations stay on the generic path (while/do-while have no loop-env flattening machinery, so a let still needs its per-iteration block environment), as do observable-completion contexts (eval/global completion values), debug mode, exact constraints and suspendable (generator/async) frames.

Benchmarks (default jobs, adjacent A/B on latest main)

New FunctionLocalNumberLoopBenchmark rows (the while/do-while twins of the existing for-loop accumulators; committed alongside):

Benchmark main PR Δ
WhileAccumulator 5.807 ms 2.496 ms −57.0%
DoWhileCounter 6.298 ms 2.299 ms −63.5%

Allocations unchanged (904 B both sides — the lane removes per-iteration Completion structs, which don't allocate).

SunSpider rows with while loops (crypto-md5/sha1, string-unpack-code, bitops-nsieve-bits, string-tagcloud) are neutral — their hot loops are for-loops or top-level while loops whose completion values are observable, so they don't hit the new lane; this PR targets function-local while/do-while, which the suite otherwise didn't cover.

Semantics (12-case REPL verification, cold + cache-armed)

while/do-while sums, do-while runs body once when test false, break/continue/labeled-continue bodies stay generic and correct, let in body forces the generic path with correct closures, observable completion values (eval) force generic path, empty body with side-effectful test, exceptions propagate from tight bodies with correct loop state.

Gates

  • Jint.Tests: 3,597 (net10.0) + 3,534 (net472) passed, 0 failed
  • Jint.Tests.PublicInterface: 114 × 2 TFMs passed
  • Jint.Tests.CommonScripts: 28 × 2 TFMs passed
  • Test262: 99,429 passed, 0 failed

🤖 Generated with Claude Code

lahma and others added 2 commits July 14, 2026 20:01
for-loops with structurally-Normal bodies bypass per-iteration completion
bookkeeping, suspension probes and per-statement ceremony via TightForBody;
while and do-while loops with the same body shapes still paid all of it.

Reuse JintForStatement''s body-shape predicate and run eligible while /
do-while bodies through the same ExecuteDiscarded lane: test, discarded
body statements and deferred-error polls per iteration, with amortized
constraints driven through the shared countdown. Bodies with lexical
declarations stay generic (while has no loop-env flattening machinery),
as do observable-completion contexts, debug mode, exact constraints and
suspendable frames.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…chmark

The suite had for-loop accumulator coverage but nothing exercising the
same tight-lane body shapes under while / do-while statements.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@lahma
lahma merged commit f185738 into sebastienros:main Jul 15, 2026
4 checks passed
@lahma
lahma deleted the perf-while-tight-lane branch July 15, 2026 06:19
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