Parent: #1
Goal
Keep the public contract for JavaScript-defined races, engine-state races, synchronization, and GC publication precise as the runtime evolves.
Current baseline
docs/threads/memory-model.md now defines:
- Lock/Atomics.Mutex release-to-acquire publication.
- Condition wait release/reacquire semantics, predicate-loop requirements, non-buffered notifications, and the fact that notify alone is not a publication substitute.
- Sequentially consistent typed-array Atomics and per-
(object, key) property-Atomics linearization/publication.
- Thread join/asyncJoin completion, result/exception identity, and prior-side-effect publication.
- Per-queue microtask FIFO and synchronized cross-thread queue handoff without a promised global order across independent producers.
- The boundary between ordinary racing values, explicit
ConcurrentAccessError restriction, and engine-state corruption.
- GC reachability publication as an internal safety mechanism that does not create JavaScript happens-before.
ThreadSanitizer currently runs without a suppression file. Intentional JavaScript shared-buffer byte races are either synchronized in the engine paths or must be handled by a future narrow, load-bearing suppression witness; engine metadata, synchronization, GC, root, lifetime, and handle state remain unsuppressed. Recent maintenance also hardened engine-owned lifetime/handle state: SharedBufferStorage retain counts and C-API protected-handle counts use checked increments, and C value/object boxes carry owner-context tags so context-taking APIs fail closed on wrong-realm handles.
Completed milestone
Ongoing maintenance
- Re-run the focused
memory model: normal and TSan tests whenever synchronization or queue handoff changes.
- Add a minimized litmus test before strengthening any public ordering claim.
- Keep GC publication explicitly separate from program synchronization.
- Keep test-only controls excluded from the stable embedder API.
- Re-audit the no-suppression ThreadSanitizer policy whenever a new raw program-byte access helper is introduced. If a future suppression becomes necessary, land it with a deterministic witness that fails without the suppression and passes with it.
- Keep owner-context and lifetime/refcount invariants regression-gated whenever public C handles or shared backing storage change.
Acceptance criteria
- Public guarantees have executable witnesses.
- TSan runs remain suppression-free, or any future suppression is narrow and load-bearing.
- Test-only controls remain clearly excluded from the stable embedder API.
Parent: #1
Goal
Keep the public contract for JavaScript-defined races, engine-state races, synchronization, and GC publication precise as the runtime evolves.
Current baseline
docs/threads/memory-model.mdnow defines:(object, key)property-Atomics linearization/publication.ConcurrentAccessErrorrestriction, and engine-state corruption.ThreadSanitizer currently runs without a suppression file. Intentional JavaScript shared-buffer byte races are either synchronized in the engine paths or must be handled by a future narrow, load-bearing suppression witness; engine metadata, synchronization, GC, root, lifetime, and handle state remain unsuppressed. Recent maintenance also hardened engine-owned lifetime/handle state: SharedBufferStorage retain counts and C-API protected-handle counts use checked increments, and C value/object boxes carry owner-context tags so context-taking APIs fail closed on wrong-realm handles.
Completed milestone
ConcurrentAccessErrorbehavior.Ongoing maintenance
memory model:normal and TSan tests whenever synchronization or queue handoff changes.Acceptance criteria