ReviewOS

zig-utils/zig-js

Runtime: keep Annex B binding analysis scratch recoverable under heap limits

#628
Closed chris opened this 9 days ago ·
9 days ago

Problem

On Linux x86-64 with Zig 0.17.0-dev.1818+7051f8e73, both the ordinary and TSan unit shards fail Context heap_limit_bytes never publishes a torn object under recovery pressure before the JavaScript pressure loop executes. The escaping OutOfMemory comes from annexbPushLexical growing its temporary NameStack through the realm arena while scanning the top-level const declaration.

Evidence: CI run 32338430544, unit shard 0 and TSan shard 0. The same full suite passes locally on macOS (1,738 pass / 1 skip), so the test currently depends on host allocation size rather than only the declared 4 MiB realm contract.

Required implementation

  • Make Annex B B.3.3 analysis use reclaimable invocation scratch with explicit lifetime, including the lexical name stack and candidate indexes.
  • Preserve the heap-limit security boundary: do not raise the test limit, bypass accounting for input-sized storage, skip Annex B analysis, or swallow OOM.
  • Publish no partial legacy-binding state when scratch allocation fails.
  • Preserve interpreter/VM semantics for sloppy block functions and strict-mode exclusions.

Acceptance

  • The focused recovery-pressure witness passes under exact dev.1818 on Linux and under TSan.
  • Existing Annex B semantic tests pass.
  • Full unit suite and dependency audit pass with no leaks.
  • Add a focused ownership/lifetime witness if the corrected scratch path is not already directly observable.

Parent: #480 Related: #493, #626

9 days ago

Implemented in d3d86580. Annex B lexical stacks and candidate indexes now use the Context’s freeable but still heap-budgeted scratch allocator; all three containers deinitialize after the active analysis pointers are restored. Exact dev.1818 passes the focused heap-limit witness (1/1), Annex B filters (5/5), and the matching 434-test shard with zero failures/leaks. Keeping this issue open until Linux and TSan CI confirm the host-sensitive 4 MiB witness.

9 days ago

Fresh Linux unit shard 0 reached past the Annex B analysis fixed in d3d86580, then exposed the next real budget consumer in the same unchanged 4 MiB recovery witness: unit (shard 0/4) failed while perIterEnv duplicated the binding name for the initial for (let r = 0; …) environment. The common uncaptured initializer path does not need a distinct environment: just as subsequent iterations already reuse an uncaptured environment, the initial CreatePerIterationEnvironment copy is observable only if initializer evaluation captured it. I am keeping #628 open and splitting that semantic allocation fix into a linked child; no heap-cap or witness adjustment.

9 days ago

Linked child #633 is implemented in 935930c7. On exact Zig dev.1818, the unchanged recovery witness now passes normally and under TSan, and exact shard 0 passes 435/435. #628 remains open until the fresh Linux shard-0 and TSan shard-0 jobs confirm the combined Annex B scratch and initial-loop-environment reclamation.

9 days ago

Fresh Linux unit shard 0 confirms the Annex B scratch and initial for-let copy fixes both execute, then exposes the next exact allocation boundary: the repeated loop body’s uncaptured { const o = … } environment exhausts the same 4 MiB cap while duplicating o. I split the semantic lifetime fix into #634; #628 remains open. The cap and witness stay unchanged.

9 days ago

The retained-allocation child #634 is implemented by 12078f3e: repeated uncaptured block environments now reuse one precisely rooted cell, while captured identity remains distinct. Exact local shard, TSan, moving-GC, recovery, and Test262 evidence is recorded on #634. Fresh Linux CI is pending before closing the child or advancing this parent.

9 days ago

Fresh CI reached a distinct post-script boundary after the Annex B and block-environment fixes: the script completed, but the host allocated its completion root afterward and escaped OOM. That defect is tracked and fixed separately in #645 by ee476876. The original unchanged recovery witness now passes locally normally and under TSan; keeping #628 open until the new Linux shard confirms the complete chain.

9 days ago

A fresh macOS test-parallel run at ee476876 plus the isolated #641 worktree exposed a later nondeterministic boundary in the unchanged recovery witness: 1,741 pass / 1 skip / 1 fail / 0 leaks. The script completed and recorded the pressure OOM, but made was 0, so the post-pressure probe had no successful publication to validate. The same exact artifact immediately passes the focused witness 1/1 (2.7 s). This is independent of DateTimeFormat and shows #628 must remain open until the live-hoard recovery probe is deterministic across full-shard scheduling; I am not weakening its 4 MiB cap or its torn-object oracle.

9 days ago

The schedule-dependent publication witness is stabilized by abb0a28c. The test now holds an exact-shape reserve live through the pressure OOM, releases it, and explicitly collects before the probe. This keeps the same 4 MiB cap and still rejects every torn object, while guaranteeing that the post-pressure oracle has a bounded reclaimable window instead of depending on collection timing.

Exact dev.1818 evidence: 13/13 focused normal runs passed; TSan passed 1/1 with no leaks or races; the schedule that exposed the defect now passes the full suite at 1,742 pass / 1 skip / 0 fail / 0 leaks across 10 shards. Keeping #628 open until the fresh Linux unit and TSan shards confirm the complete chain.

9 days ago

Fresh Linux CI confirms the complete unchanged-cap recovery chain at 2da6f4bb: unit shard 0/4 passed, TSan unit shard 0/4 passed with no reported race, and the dependency audit passed. This covers the Annex B scratch owner, initial and repeated uncaptured lexical-environment reuse, completion-root recovery, and the deterministic post-pressure publication oracle under the original 4 MiB limit. Closing as completed; later independent bounded-heap consumers remain tracked by their own issues.

Sign in to comment on this issue.