Files
scriptc/tests
Malte Ubl bdba4a7a1c Test an exact per-thread pending word in ELF worker executables
Worker programs on Linux tested a process-wide alert word after every
call that may throw and called scr_exc_pending on its slow path to answer
for the calling thread. Each of the ~55k slow-path calls in tsc-ts counted
against LLVM's inline cost, and while any thread had an exception in
flight every other thread took the slow path.

ELF worker executables (the emitter's executableTls targets) now give
every script thread an exact pending word in the executable's static TLS
block, and the emitted check is one thread-pointer-relative load and a
branch to the unwind, with no out-of-line call:

- bit 0 mirrors "active cell kind != NONE". Only the owner thread writes
  it, at every change of its active cell (throws, rethrows, take/clear,
  fiber switches, payload moves, the termination sentinel). The uncaught
  printer now settles it after resetting the cell.
- bit 1 requests the context's stop. worker.terminate() sets it through a
  pointer the worker registers under a mutex while its script runs (a
  terminate before registration is found through the cancel flag), and
  scr_context_stop sets it for process.exit() and fatal paths. The stop
  bit counts as the stop signal in scr_context_quiet/checkpoint.

A set stop bit unwinds while the active cell may still be clear, so every
consumer of an unwind installs the TERMINATE sentinel before inspecting
the cell: emitted try regions test the bit before entering a handler and
call scr_context_checkpoint, and fiber completion, the uncaught handlers
and exit listeners checkpoint instead of only testing
scr_context_stopping. The runtime's out-of-line scr_exc_pending already
checkpoints. Darwin and Windows keep the alert word (a Darwin thread-local
access is a call).

New corpus programs pin terminate() inside catch and finally bodies, with
exceptions stashed or propagating, inside generator and async bodies and
runtime callbacks, and before the worker starts, plus every way an
exception is raised, moved, consumed or discarded on the main thread and
in a worker, each followed by a may-throw call that must not unwind.
2026-10-11 06:39:42 -07:00
..
2026-07-22 18:08:04 -05:00