ReviewOS

zig-utils/zig-js

Threads: preserve spawned butterfly objects under no-GIL stress

#837
Closed chris opened this 12 days ago ·
12 days ago

Parents: #478, #476. Related: #812 and #502.

Evidence

Pushed Linux CI for current main bcc3e75 fails the promoted PR-249 case jit/spawned-thread-butterfly-stress.js in both optimization modes:

The case exits immediately with TypeError: undefined is not an object. In each run one spawned Thread record reports threw=true and all records report done/exited/joins-settled. The failure is deterministic across Debug and ReleaseSafe in this run, is not a timeout, and is not a reported sanitizer race. Root cause and introducing revision are not yet established.

Scope

Reproduce the promoted case directly in no-GIL mode, minimize the failing object/property lifecycle, and identify whether object backing publication, shape/property synchronization, root retention, or thread completion transport exposes undefined. Preserve the intended shared-realm program-race contract while keeping every engine metadata transition race-free and memory-safe.

Acceptance

  • The exact promoted case and a minimized deterministic witness preserve every expected object/property value in Debug and ReleaseSafe.
  • The responsible publication/root/shape boundary has an explicit synchronization and moving-GC ownership proof.
  • Focused unsuppressed TSan coverage passes without masking a program-byte race.
  • Full no-GIL corpus, unit/TSan, lifecycle/mid-GC/threadfuzz, and relevant object/GC gates pass.
  • No hidden GIL, blanket object lock, disabled GC/JIT, retry-until-pass loop, weakened assertion, or corpus exemption.
12 days ago

Addressed on main by 14278310 — fix(threads): separate host task quiescence from child completion (#836, #837).

This case failed in the same pushed integration run as the #836 child-completion stalls: one spawned record threw TypeError: undefined is not an object in both Debug and ReleaseSafe while all records reached done/exited/joins-settled. The landed change removes the invalid dependency from spawned completion to unrelated host-owned in-flight tasks and preserves all reentrant task roots. It does not add an object lock, retry, GC/JIT disablement, or program-race serialization.

Verification on the committed tree:

  • jit/spawned-thread-butterfly-stress.js passes in the complete 253/253 Debug and 253/253 ReleaseSafe no-GIL gates
  • the focused unsuppressed TSan case passes in 31.723 s
  • full units pass 2,228/2,228 executed with 1 expected skip and no leak
  • normal/TSan mid-GC profiles pass 900/900 and 90/90

The original TypeError was Linux-observed and did not reproduce locally as an isolated before-run, so this comment does not over-claim a separately minimized object-publication cause. The exact Linux push gate is pending at https://github.com/zig-utils/zig-js/actions/runs/33440235057; if that case recurs, this issue should be reopened with its new thread-state diagnostics rather than reclassified from local inference.

Sign in to comment on this issue.