ReviewOS

zig-utils/zig-js

TypedArray: bound Debug no-GIL detach/resize storm latency

#653
Closed chris opened this 8 days ago ·
8 days ago

Parent: #493 Related: #430, #651

Evidence

At 9b359d8f3065dbdaa2e8e783e596a112f86e87c6, the isolated Linux Debug no-GIL shard passes 61/62 cases and then exhausts the unchanged 600-second per-case deadline in cve/mc-tear-typedarray-detach-grow-shrink.js with empty runner stdout/stderr:

https://github.com/zig-utils/zig-js/actions/runs/32385115603/job/96477799898

The matching ReleaseSafe shard passes all 62 cases in the same run:

https://github.com/zig-utils/zig-js/actions/runs/32385115603/job/96477799729

The checked terminal evidence records the exact witness passing no-GIL in 15,336 ms. Earlier bring-up documentation characterized a property-mode Atomics failure after 893 seconds before the terminal artifact was published, so this surface has shown pathological Debug cost before.

This is distinct from #651: after owned key snapshots removed the stale-property panic, Debug progresses through the other 61 shard cases and exposes this later TypedArray/ArrayBuffer storm timeout.

Scope

  • Reproduce the single case in Debug no-GIL mode and sample the active process before treating elapsed time as a hang.
  • Attribute work across TypedArray length/index reads, ArrayBuffer resize/transfer/detach, property-mode Atomics, and concurrent GC.
  • Remove the algorithmic or synchronization pathology in the engine while preserving exact detach, resize, transfer, and torn-pair safety semantics.
  • Keep the existing case, workload, and 600-second deadline unchanged.

Acceptance

  • The exact single case passes Debug no-GIL within the existing production deadline with a measured nonzero result.
  • The matching ReleaseSafe, serialized/GIL, and suppression-free TSan witnesses pass.
  • ArrayBuffer/TypedArray detach, transfer, resizable-buffer, DataView, and property-Atomics focused tests pass.
  • Full unit and no-GIL corpus gates report no regressions.
  • Any performance claim records exact mode, hardware/runner, work, and raw timing evidence.

No-workaround rules

No deadline increase, case reduction/skip, baseline exemption, forced GIL, disabled resizing/transfer, weaker torn-pair oracle, or hidden retention.

8 days ago

Diagnosis and first candidate evidence:

  • A 3-second macOS Debug sample of the unchanged single case showed the main mutator in callPlain binding-table allocation / SafeAllocator stack capture while filling the 64 KiB victim through millions of SENTINEL(i) calls. The three readers were mostly parked or allocating short property-Atomics waiter state while waiting for the first publication. The ArrayBuffer resize mutex was not the long pole.
  • Recycling only the activation GC cell was insufficient: a second sample showed every return deinitializing and reallocating the same binding hash tables. The candidate now retains only the same ASTs bounded static binding layout, clears every Value to undefined, and refuses captured, aliased, or dynamic-eval (deletable) environments.
  • A third sample isolated invocation-local Annex B maps and parameter stacks despite the function having no possible block-function candidate. Function creation now records a conservative allocation-free AST classification; candidate-free bodies skip those empty per-call structures.

The unchanged witness now passes locally with exact Zig 0.17.0-dev.1818+7051f8e73 in Debug no-GIL mode:

  • PASS cve/mc-tear-typedarray-detach-grow-shrink.js (32582 ms)
  • process wall/user/sys: 33.77s / 102.44s / 7.70s
  • maximum RSS: 177,766,400 bytes
  • 709,563,945,747 retired instructions; 356,670,558,843 cycles (macOS /usr/bin/time -l)

The new forced-tree-walker unit executes 2,000 hot calls under a constant environment-allocation ceiling and keeps two mapped-arguments objects plus captured closures distinct. It passes in 1.625s. Existing moving-root relocation, block-environment reuse, and all five Annex B focused units pass.

This is local diagnostic evidence, not publication benchmark evidence. ReleaseSafe, TSan, serialized, full-unit, and fresh Linux gates remain before closure.

8 days ago

Implemented and pushed in c6dcbe6d: one fully-cleared uncaptured tree-walker activation is retained per interpreter, with bounded static binding storage reused only for the same function AST. Closures, mapped arguments, dynamic eval bindings, live aliases, disposable state, and failed instantiations cannot enter the cache; the cached cell is an exact traced/relocated GC root. Functions also receive a one-time structural Annex B classification so the common binding-free call avoids empty per-invocation maps without weakening B.3.3 handling.

Evidence:

  • exact unchanged cve/mc-tear-typedarray-detach-grow-shrink.js: Debug no-GIL 32.582 s (prior Linux CI timeout at 600 s); TSan no-GIL 337.429 s, no TSan report; ReleaseSafe no-GIL 3.094 s; ReleaseSafe serialized 12.883 s
  • full unit suite: 1,746 passed, 1 skipped, 0 failed, 0 leaked
  • focused activation, GC-root relocation, and five Annex B witnesses pass normally and under TSan
  • exact Test262 before/after: function expressions 264/264, function statements 451/451, Annex B language 845/845, arguments objects 263/263, function code 217/217; 2,040/2,040, 0 flips

Fresh Linux CI is pending before closure.

8 days ago

Implemented by perf(interpreter): reuse bounded call activations (#653).

The unchanged witness passed locally with exact Zig dev.1818 in every requested mode: Debug no-GIL 32.582 s, TSan no-GIL 337.429 s with no report, ReleaseSafe no-GIL 3.094 s, and ReleaseSafe serialized 12.883 s. These are diagnostic exact-mode timings, not a public throughput claim. The full local unit suite passed 1,746 tests with 1 skip, 0 failures, and 0 leaks; the five scored Test262 subtrees passed 2,040/2,040 with 0 flips.

Fresh cumulative Linux evidence:

The fix retains one fully-cleared, uncaptured tree-walker activation only for the same static function layout and keeps closures, mapped arguments, dynamic eval, aliases, disposables, and failed instantiation out of the cache. No deadline, workload, torn-pair oracle, resize/transfer behavior, or GIL mode changed.

Sign in to comment on this issue.