Parents: #474, #482 Related: #480, #493, #885
Problem
Two microtask queue ownership paths can silently discard already-committed jobs under allocator pressure:
transferMicrotasksUnlockedcallsappendPendingSlice(... ) catch {}and then clears the source queue unconditionally. If the destination grow fails, every source job is lost while Thread completion continues.drainJobQueuerestores untouched jobs after an abrupt callback withprependSlice(... ) catch {}. If prepend allocation fails, the original error is returned and the batch is deinitialized, discarding the remaining jobs. Reentrant jobs already in the destination survive, so observable FIFO state becomes a partial suffix.
jobQueueDequeueBatch itself leaves the source unchanged when its initial batch copy fails; the unsound boundaries are the later transfer/restore ownership handoffs.
#885 owns Promise state-to-job publication. This issue owns queue-to-queue and batch-to-queue transfer after jobs already exist.
Required implementation
- Make source-to-destination transfer commit only after the complete pending source suffix is guaranteed publishable, or transfer backing/segments allocation-free with exact ownership.
- Make abrupt restoration preserve every untouched batch job ahead of reentrantly enqueued work even when allocator recovery fails.
- Represent ownership explicitly so exactly one live root owns each queued job throughout transfer, restore, GC tracing, Thread exit, and Context teardown.
- Preserve FIFO across source jobs, destination jobs, reentrant jobs, next ticks, Promise reactions, native jobs, thenable jobs, and private ABI work.
- Keep queue locking ordered for two-queue transfer and compatible with concurrent marking/no-GIL producers.
- Do not swallow OOM, clear a source after failed publication, reverse or drop a suffix, cap queue size, retry callbacks, globally serialize JavaScript, or rely on Context destruction.
Acceptance
- Deterministic allocator-fault witnesses cover empty/nonempty destination transfer and abrupt restoration before/after reentrant enqueue.
- Every failure point proves exact source/destination/batch membership, order, GC rooting, and eventual one-time execution after recovery.
- Thread completion cannot publish
donewhile orphaning its local queue; termination and asyncJoin ordering remain exact. - A throwing next-tick/Promise/native callback preserves all untouched jobs before reentrant work without duplicating the throwing job.
- Moving/concurrent GC, bounded heap, Context teardown, private ABI, relevant threadfuzz, full units, and suppression-free TSan pass.
- Exact Promise/async/queue Test262 coverage has zero regressions and documentation makes no unsupported OOM guarantee.
Security boundary
Job count, callback failure, reentrancy, Thread timing, and allocation pressure are script-controlled. Queue ownership must fail closed rather than silently erase committed work or expose a reordered partial schedule after recovery.