Skip to content

Threads: maintain the shared-realm JavaScript memory model #12

Description

@chrisbbreuer

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

  • Specify ordering guarantees for Lock, Condition, property Atomics, typed-array Atomics, Thread join/asyncJoin, and task/microtask delivery.
  • Document which ordinary object races have unspecified values versus explicit ConcurrentAccessError behavior.
  • Align GC write-barrier/publication rules with the landed nursery and concurrent full collector.
  • Add litmus tests for the documented happens-before guarantees.
  • Audit the memory-model docs and suppression boundary for the nursery/shared-state changes.
  • Remove stale TSan suppression wiring and keep required gates running suppression-free.
  • Harden shared-buffer and C-API handle lifetime accounting against refcount/protection-count wraparound and wrong-context handle use.

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions