Conversation
Fixes for the per-hunk review of #249 (review finding ids: 000-1). - CMakeLists: export GCSafepointEpoch/GCThreadLocalCache/HeapClientSet/JSThreadsSafepoint headers
…om table ordering Fixes for the per-hunk review of #249 (review finding ids: 131-5, 151-1, 151-2, 152-1, 153-1, 153-2, 154-1, 154-2, 154-3). - BitSet: gate relaxed-atomic zeroing constructor on TSAN_ENABLED, keep aggregate zero-init otherwise - DeferrableRefCounted: gate the atomic refcount RMWs on a process-latched GIL-off Config byte - StringImpl: keep the legacy load/modify/store in cost, setIsAtom and setHash when the shared atom table is off - SymbolImpl: make the symbol hash counter atomic - Thread: add WTF Thread::tryCreate and throw RangeError when the OS refuses a thread - WTF Thread: reword dedicated-byte flag comments to name the real writer/reader race - WTF: define SharedAtomStringTable::singleton and the latch in SharedAtomStringTable.cpp - WTF: state the migrate-then-latch-then-clear order in enableSharedAtomStringTable without citing the spec
…er, drop temporary diagnostics Fixes for the per-hunk review of #249 (review finding ids: 033-1, 033-2, 033-3, 034-1, 034-2, 034-3, 034-5, 035-1, 035-2, 035-3, 036-1, 036-3, 036-4, 036-5, 036-6, 037-1, 037-2, 038-1, 038-2, 038-3, 039-1, 039-2, 039-3, 040-1, 041-1, 041-3, 042-1, 042-2, 042-3, 043-1, 043-2, 043-3, 043-4, 043-5, 044-1, 044-2, 045-1, 045-2, 045-3, 046-1, 046-2, 046-3, 046-4, 046-5, 046-6, 046-7, 047-2, 047-3, 047-4, 048-1, 048-2, 048-3, 048-4, 048-5, 049-1, 049-2, 050-1, 050-2, 051-3, 052-1, 052-2, 052-3, 052-4, 052-5, 053-1, 053-2, 053-3, 054-1, 054-2, 055-1, 055-2, 056-1, 056-2, 116-6, 135-3). - BlockDirectory: assert the lock-free m_bits witness is this thread's exclusive MSPL or own stripe - BlockDirectory: make assertSweeperIsSuspended a world-stopped/exclusive-owner assertion; drop sweeper-disabled claims - BlockDirectory: remove findOwnEmptyBlockForRefill, whose target population cannot exist - BlockDirectory: step the steal cursor past weak-bearing empties instead of declining them - CompleteSubspace::allocate: test the server allocator before the useSharedGCHeap branch - CompleteSubspace::allocate: trust the per-thread TLC snapshot only when vm is gilOff - Drop the dead null-client disjunct from the TLC hit ASSERT and restate its invariant - GCIncomingRefCountedSet: take the incoming-reference lock only under gilOffProcess - GCIncomingRefCountedSet: walk the set unlocked in sweep/lastChanceToFinalize (world stopped) - GCThreadLocalCache: remove uncalled allocatorFor(BlockDirectory&), stopAllocating, prepareForAllocation, server - GCThreadLocalCache: replace unreachable growTable realloc leg with a fixed-capacity RELEASE_ASSERT - HandleSet: fold the Strong leaf lock into the class, drop the process-global side table - HandleSet: lock the live protected-cell walk; route the NODELETE counter through m_strongLock - HandleSet: make m_strongLock a real member and rewrite the seam comments as invariants - HandleSet: take m_strongLock in forEachStrongHandle under gilOff - Heap: correct the F28 successor-open comments to the drain the code performs - Heap: correct the Wlr comment: Auxiliary witnesses are marked, not traced - Heap: count drainFromShared entrants for the marker pause; restore flag-off steal denominator - Heap: create sibling-assist visitors in runBeginPhase, decline assists when the pool is empty - Heap: delete dead allocationClientForJITCodegen and the duplicate free resolver - Heap: delete the dead namespace-scope allocationClientForCurrentThread and its stale note - Heap: delete the never-constructed SharedGCWindowOpen::TicketDrainSuccessor arm - Heap: delete the unreferenced allocationClientForJITCodegen resolver - Heap: describe the STW-forbidden scope depth as a release-mode per-thread counter - Heap: document that a LambdaFinalizer may receive a null JSCell* under GIL-off - Heap: document that shared-mode hooks/reclaim/rebias run once per drained ticket batch - Heap: document the GIL-off LambdaFinalizer contract (null cell, runs after the world resumes) - Heap: drain GCSafepointEpoch retired items in lastChanceToFinalize, before blocks are freed - Heap: drain an orphaned needFinalizeBit inside the ISS flip before storing ISS - Heap: drop dead sharedGCWindowedStagesEnabled(); Heap.cpp keeps the one stage-flag list - Heap: drop stale NOTE claiming worldIsStopped() still does a plain read - Heap: drop the untimed JSThreadsStopScope ctor; harness uses the watchdog ctor - Heap: drop the unused 1-byte layout pad and state what the trailer guards check - Heap: drop unused GCClient::CompleteSubspaceView, its members and bind hook - Heap: exempt the PreventCollectionScope holder from the shared conduct-tenure gate - Heap: fix comments still claiming the IncrementalSweeper is disabled when shared - Heap: gate DeferGC slot routing on useSharedGCHeap and resolve both slots once - Heap: gate allocationClientForCurrentThread on gilOffWithProcessGate, drop stale rationale - Heap: gate the freelisted-block walk in stopThePeriphery on Options::verifyGC() - Heap: gate the possibly-accessed-strings append lock on gilOff - Heap: gate the shared-GC root-snapshot/endMarking/freelisted-block checks behind Options::verifyGC() - Heap: make barrierThreshold()/mutatorShouldBeFenced() plain server-master reads - Heap: make sharedGCMaxSiblingMarkingAssists=0 mean disabled and drop the dead auto branch - Heap: read the server master barrier pair in mutatorShouldBeFenced/barrierThreshold - Heap: register the epochReclaim safepoint hook per heap, make hook registry idempotent - Heap: remove the unconsumed CompleteSubspaceView wrappers and bind hook - Heap: route server-level acquire/release/hasAccess to the calling thread's client GIL-off - Heap: run TID-rebias fires as the GC conductor and retire the stale tripwire banner - Heap: run the conservative-scan constraint on the conductor when sibling assists are admissible - Heap: run verifyStickySharedServerDesignation before HeapClientSet::add's sticky trigger - Heap: scan and grant the shared collectAsync ticket under one m_threadLock hold - Heap: serialize the server mutator mark stack with a Heap lock, not a MarkStackArray flag - Heap: state the pin-lock-then-codeBlockSet-lock order at pinRetiredCallLinkRecordCodeBlock - Heap: state the shared-mode no-runloop-push rule and log access-barrier stalls - Heap: strip the TEMPORARY ring-liveness diagnostics from the shared-heap harness - Heap: take m_possiblyAccessedStringsFromConcurrentThreadsLock only under gilOff - Heap: take m_protectedValuesLock in protect/unprotect and statistics walks under gilOff - Heap: test useSharedGCHeap before isSharedServer in the per-client slot dispatchers - HeapClientSet: run the sticky-server designation check before the second-client ISS flip - IsoSubspace: inline GCClient::IsoSubspace::tlcSlot, drop false out-of-line rationale - IsoSubspace: remove unused GCClient::IsoSubspace::allocateForClient - Key the TLC snapshot hit on vm.gilOff() so nested foreign-VM entry cannot allocate from the wrong heap - MarkedBlock: correct the isMarkedRaw comment to name its callers' protocols - MarkedBlock: drop the unreachable allocBit leg and last-era skip from the window snapshot - MarkedBlock: state the real stale-true argument for the destructible hint; keep it in lockstep for false - MarkedBlock: take the heapRandom lock in specializedSweep only when sweeps can run concurrently - MarkedSpace: bound TLC slot reservation by numCompleteSubspaces * numSizeClasses - MarkedSpace: say isPagedOut's only caller skips it when shared, not that it never fires - MarkingConstraint: delete dead m_lock member and the comment deferring its removal - SharedHeapTestHarness: remove the ring-liveness diagnostics and the Heap.cpp audit seam - SlotVisitor: arm the per-batch helper pause checkpoint in the gilOff single-handoff shape - Threads: relinquish a spawned thread's allocators while its lite is Live, not from the client dtor - TinyBloomFilter: replace relaxed fetch_or in add() with relaxed load+store - VMManager.h: declare the thread-granular conductor predicates once; drop seven hand copies
…hared butterfly protocol Fixes for the per-hunk review of #249 (review finding ids: 021-2, 036-2, 061-3, 061-4, 072-1, 072-2, 072-3, 072-4, 073-1, 073-2, 073-5, 075-1, 075-2, 075-3, 076-1, 076-2, 076-3, 077-1, 077-2, 078-1, 078-2, 078-3, 079-1, 079-2, 080-2, 080-3, 080-4, 083-1, 084-1, 084-2, 084-4, 086-1, 086-2, 086-3, 086-4, 086-5, 087-1, 087-2, 087-3, 087-4, 087-5, 088-1, 088-2, 089-3, 089-4, 090-2, 090-4, 090-5, 090-6, 091-3, 099-1, 099-2, 099-3, 100-1, 100-2, 100-3, 100-4, 100-5, 101-1, 101-2, 102-2, 102-3, 102-4, 102-6, 103-1, 103-2, 103-4, 104-2, 104-3, 104-4, 105-1, 105-2, 105-3, 106-5, 108-4, 110-2, 111-1, 112-1, 112-2, 113-1, 113-2, 113-3, 116-2, 116-3, 116-4, 117-1, 118-1, 118-2, 119-1, 119-2, 119-3, 120-2, 121-1, 121-2, 121-4, 122-1, 122-2, 123-1, 123-2, 123-3, 124-1, 124-4, 132-1, 149-1). - ArrayPrototype: derive join/indexOf/concat fast paths from one tagged butterfly word snapshot - ArrayPrototype: re-read indexing types after the concat result allocation flag-on - ArrayPrototype: reverse fast path flips SW for foreign writers and uses one butterfly snapshot - ButterflyInlines: keep optimalContiguousVectorLength within MAX_STORAGE_VECTOR_LENGTH - ClonedArguments: copyToArguments reads one butterfly-word snapshot, bails on segmented/null - ClonedArguments: serialize GIL-off materializeSpecials under a park-capable lock - ConcurrentButterfly.h: document the gilOff StayFlatShared transition in the regime contract - ConcurrentButterfly.h: read the verify/stress options directly instead of SFINAE probes - ConcurrentButterfly: StayFlat copy-grow copies no element payload for typed-array views - ConcurrentButterfly: assert non-null fragments under verifyConcurrentButterfly in the GC visit - ConcurrentButterfly: bail out of the ensureLength/shrink drivers when an AS conversion lands - ConcurrentButterfly: delete the uncalled segmentedTransition/structureOnlyTransition drivers - ConcurrentButterfly: drop the process-global stub world-stopped witness - ConcurrentButterfly: make butterflyWorldIsStopped the JSThreadsSafepoint predicate alone - ConcurrentButterfly: name the useSharedGCHeap gate in the mode (b) rarity comments - ConcurrentButterfly: register the quarantine epoch hook on every Heap, not per address - ConcurrentButterfly: remove the uncalled spineOutOfLineFragment/spineIndexedFragment exports - ConcurrentButterfly: route far-beyond-vector indexed stores to the sparse-map path flag-on - ConcurrentButterfly: size typed-array view conversions from a zero indexed payload - ConcurrentButterfly: state the GC visit bound as the spine's vectorLength in code comments - ConcurrentButterflyOperations: drop __has_include scaffolding and the TID-0 shim - ConcurrentButterflyOperations: remove the seven unreachable JIT operation shims - DFG operationCreateThis: validate the allocation profile snapshot under gilOff like slow_path_create_this - DirectArguments: serialize overrideThings puts and bitmap publication under gilOff - FunctionRareData: GIL-off .prototype store is followed by a clear that waits for the initializer - GetterSetter: restore WriteBarrier::set() in ctor, drop stale hand-expansion and comment - JSArray AS shift/unshift concurrent: re-check the caller's range under the cell lock and bail - JSArray/JSObject: replace GIL-only sparse-map iterators on flag-on paths with keyed locked access - JSArray::appendMemcpy: re-read both indexing types after ensureLength before the memcpy - JSArray::copyToArguments: clamp the flat scan to the caller's length as well as the snapshot - JSArray::fastFill: bail when the flag-on relabel left indexingType != nextType - JSArray::fastFlat: bail flag-on when pass 2 copied a different count than pass 1 - JSArray::fastFlat: bail when the source shape changed across the result allocation - JSArray::fastSlice: hold one GCDeferralContext across butterfly allocation, copy and cell allocation - JSArray::fastToReversed/fastWith/fastToSpliced: re-read indexingType after the result allocation - JSArray::pop: return undefined when a racing shrink emptied the array before the generic tail - JSArray::setLength/pop/fastShift: restart on a null word paired with an indexed mode - JSArray::unshiftCountSlowCase: drop unreachable flag-on branches - JSBigInt: throw OutOfMemoryError from createFromDigit instead of RELEASE_ASSERT - JSCJSValue: make the 64-bit JSValue slot accessors relaxed atomics only under TSAN - JSCell: drop no-op decontaminate() in structure(); state the nuke-bit contract - JSCellInlines: delete orphaned comment describing the withdrawn H-CALLSITE-LASTSIZE-LA mechanism - JSCellInlines: make tlcSlotForSubspace fail closed for non-CompleteSubspace kinds - JSCellLock: maintain GCCellLockDepth in lock/tryLock/unlock so the no-park asserts are live - JSFunction: CAS-publish FunctionRareData under gilOff so racing installs adopt one cell - JSObject.h: drop the stale i03-i37 FIXME in tryMakeWritableInt32 - JSObject.h: remove uncalled butterflyRegime() and isSharedArrayStorage() - JSObject: RESTART stop-published indexing transitions when a dictionary table was edited in place - JSObject: always CAS-max publicLength after flag-on dense stores and ensureLength - JSObject: barrier the owner after the AS-COPY growth publication - JSObject: butterfly() contract drops the guard-then-reload witness; snapshot JSCellButterfly::createFromArray - JSObject: check the ThrowScope when putInlineSlow's thread-restrict gate throws - JSObject: check the ThrowScope when threadRestrictCheck fails in getNonIndexPropertySlot - JSObject: correct the flatten re-check comment about renumberPropertyOffsets' edit stamp - JSObject: dispatch flag-on indexed delete on one loaded word, never the flat switch - JSObject: fence mode-then-word loads in indexed names walk and beyond-vector put - JSObject: install a fresh sparse map under the cell lock only if none is installed (flag-on) - JSObject: load mode before the fenced word in setIndexQuicklyConcurrent; putDirectIndex uses the try variant - JSObject: publish dictionary attribute changes under the cell lock with a table-stamp re-check - JSObject: putDirectIndex AS grow arm re-checks the vector bound under the lock before storing - JSObject: re-check i < vectorLength under the lock after increaseVectorLength before storing - JSObject: re-check vectorLength on the fresh word in setIndexQuicklyConcurrent and route putDirectIndex via try - JSObject: re-dispatch putDirectIndex after createArrayStorage instead of indexing the returned vector - JSObject: re-validate structureID after the word load in createInitialIndexedStorageConcurrent - JSObject: recount m_numValuesInVector under the lock in sparse-map consolidation - JSObject: return the settled ArrayStorage from convertToArrayStorageConcurrent when a racer converted first - JSObject: route null-word foreign-keyed indexed first installs to the shared stop leg - JSObject: run the F1 SW flip before cell-locked ArrayStorage stores in putByIndex and the AS funnels - JSObjectWithButterfly: delete the uncalled getDirectConcurrent/putDirectConcurrent - JSPropertyNameEnumerator: drop stale NOTE, state the relaxed store/load invariant - LazyProperty: drop unreachable initializer-abandonment restore in callFunc - MegamorphicCache: restore plain epoch bump; make bumpEpoch a no-op under useJSThreads - ObjectConstructor: clone fast paths copy from one tagged-word snapshot paired with the structure - PropertyTable: document that inline deleted offsets are quarantined too - PropertyTable: fold deleted-offset bookkeeping into one side struct (cell 80 -> 48 bytes) - PropertyTable: say seal()/freeze() edit a still-private table; keep the seqlock bracket - PropertyTable: skip the quarantine walk when the oldest stamp is not yet promotable - PropertyTable: state the TSAN pairing rationale for relaxed constructor stores - SparseArrayValueMap: decide flag-on putEntry/putDirect under the lock, throw and call setters after it - SparseArrayValueMap: dispatch putEntry on the value word and lock every flag-on entry writer - SparseArrayValueMap: insert a sparse entry only once the write is allowed (no placeholder) - Structure: condense the DEFINE_BITFIELD perf narrative to the lost-update invariant - Structure: drop the unused DeferredWatchpointFire parameter of firePropertyReplacementWatchpointSet - Structure: gate SAL locker construction in Structure::create/createStructure on the latched option - Structure: gate the lock-free transition precheck on useJSThreads for the IC/DFG callers - Structure: name the lock-free republish store as the only unlocked chain writer - Structure: pre-allocate the shrunk flatten butterfly outside the stop window - Structure: re-copy seenProperties/propertyHash into a transition under the source m_lock - Structure: remove the never-passed deferred parameter and its API comment - Structure: replace transitionThreadLocalTIDOffset with a restampTransitionThreadLocalTID setter - Structure: restore .set()/.setMayBeNull() at four slot writers; drop stale plain-store comments - Structure: revalidate isDictionary and object->structure in the flatten stop closure - Structure: snapshot forEachProperty entries under m_lock and run the functor unlocked - Structure::add<ShouldPin::Yes>: recheck under m_lock that the table was not stolen - StructureChain: bound finishCreation's lane walk by the size create() allocated - StructureRareData: GCSafe, flag-on-only lock around the special property cache install - StructureRareData: move retired enumerator watchpoint list out of the cell into the Heap - TypeInfoBlob/Structure: make the blob, outOfLineTypeFlags and classInfo reader loads TSAN-only - WriteBarrier: make the cell-pointer slot accessors relaxed atomics only under TSAN - ensureLengthSlowConcurrent: drop the dead availableOldLength computation and T5 comment - fastArrayJoin: snapshot the butterfly word once and re-probe it after user code - shiftCountWithArrayStorageConcurrent: allocate the fresh AS before the scalar stores
…nd lifetime races Fixes for the per-hunk review of #249 (review finding ids: 070-1, 070-2, 070-3, 070-4, 070-5, 070-6, 071-1, 071-2, 072-5, 072-6, 074-3, 089-1, 089-2, 089-5, 090-1, 090-3, 091-1, 091-2, 091-4, 092-1, 092-2, 092-3, 092-4, 107-1, 107-3, 107-4, 108-1, 108-2, 108-3, 114-1, 114-2, 114-3, 114-4, 115-1, 116-1, 117-2, 124-3, 125-1, 125-2, 125-3, 125-4, 125-5, 126-1, 126-3, 126-4, 128-2, 148-2, 148-5). - ArrayBuffer: allocate the GIL-off resizable transfer copy without a VM so it cannot collect - ArrayBuffer: fail the GIL-off transferTo whose detach lost the flag race, as already detached - ArrayBuffer: fail the racing transfer loser so exactly one transfer of a buffer succeeds - ArrayBuffer: make isDetached() read a sticky GIL-off detached flag; drop the side-table probes - ArrayBuffer: make isDetached() read the sticky GIL-off flag, drop isArrayBufferDetachedGILOff - ArrayBuffer: neuter views before the mapping enters the quarantine in GIL-off detach - ArrayBuffer: quarantine a relocated wasm mapping in the growing VM's heap quarantine - ArrayBuffer: re-check isDetached() and maxByteLength under the lock on every resizeGILOff pass - ArrayBuffer: register the quarantine safepoint hook per Heap at VM init, not per address - ArrayBuffer: snapshot length and maxByteLength under the handle lock in GIL-off transferTo - Atomics: delete the D8 single-flight TA sync-wait gate; lift the 4.5-1a spawned gate GIL-off only - AtomicsObject: run the GIL-off detach re-check before ToIndex so the TA path keeps RangeError - ConcatKeyAtomStringCache: read/store m_mode through relaxed atomics in getOrInsert - DataView get/set: keep the plain byte loop flag-off, relaxed atomics only under gilOffWithProcessGate - DataView get/set: snapshot the view base before the length proof, throw detached on null GIL-off - DateCache: route GIL-off entry points to a per-thread cache instead of one VM-wide leaf lock - JSArrayBufferView: convert shared flat views before the GIL-off wastage copy; retry a failed CAS - JSArrayBufferView: give a segmented Fast/Oversize view a header fragment in slowDownAndWasteMemory - JSString: derive every rope-walk decision from one per-node m_fiber snapshot - JSString: plain constructor-time rope stores in production, relaxed atomics only under TSAN - JSString: remove dead resolveRopeInternalNoSubstring - KeyAtomStringCache: relaxed slot snapshot load in production, acquire only under TSAN - KeyAtomStringCacheInlines: drop unused Options.h, stdlib.h and DataLog.h includes - RegExp: make m_atom write-once so lock-free atom() readers never see it freed - RegExp: publish bytecode before m_state=ByteCode; never hand Yarr::interpret a null pattern - RegExp: take cellLock in reset(), route error-code reads through one relaxed accessor - RegExp: write-once m_atom and bytecode-before-state publication (same fix as 114-1/114-2) - RegExpCache: clear Yarr code under a stop-the-world window when gilOff - SimpleTypedArrayController: actually defer the displaced dead wrapper Weak under GIL-off - StringRecursionChecker: use the per-thread recursion state in every useJSThreads mode - Symbol: return the canonical cell from finishCreation instead of re-probing symbolImplToSymbolMap - ThreadAtomics: DeferGC around the Missing-add ArrayStorage cell-lock window - ThreadAtomics: bump ArrayStorage length only after the conditional add publishes - ThreadAtomics: drop the never-incremented g_threadAtomicsSlotCASRetries stub and its dump field - ThreadAtomics: drop the never-incremented slotCASRetries counter - ThreadAtomics: flip SW before the Missing-add ArrayStorage cell lock - ThreadAtomics: grow dense shapes for beyond-vector Atomics.store adds GIL-off - ThreadAtomics: release the waitAsync ticket at dequeue instead of at timer fire - ThreadAtomics: state the in-window teardown-sweep finalizer contract - ThreadAtomics: state why property waitAsync stays an uncounted keepalive registration - TypedArray copyWithin: return early on a null base snapshot in the GIL-off lane loop - TypedArray element accessors and sort: gate on g_jscConfig.gilOffProcess, not VM::isGILOffProcess() - TypedArray fill: return early on a null base snapshot in the GIL-off lane loop - TypedArray forEach: test the base snapshot instead of isDetached() in the arms that re-read the base - TypedArray includes/indexOf/lastIndexOf/reverse/sort: handle a null base snapshot GIL-off - TypedArray setFromTypedArray/sort/copyFrom*ShapeArray: never deref a base re-read after the bounds proof GIL-off - WaiterListManager: settle a foreign VM's TA waitAsync under list->lock in the GIL-off notify arm - jsAtomString: republish the atom when a lost GIL-off publish race left a non-atom impl
…, Lock, Condition and ThreadLocal Fixes for the per-hunk review of #249 (review finding ids: 051-1, 059-3, 081-1, 082-1, 082-2, 082-4, 096-2, 098-1, 098-2, 106-1, 106-4, 109-1, 109-2, 109-3, 109-4, 109-5, 111-5, 111-6, 129-1, 129-2, 129-3, 129-4, 129-5, 130-1, 130-2, 130-3, 130-4, 130-5, 131-1, 131-2, 131-3, 131-4, 134-4, 148-1, 148-3, 148-4, 149-2, 149-3). - ConcurrentAccessError constructor: derive the Structure from newTarget - ConditionObject: consume the async grant under m_queueLock before asyncWait's (b) release - DeferredWorkTimer: capture the timer, not Ref<VM>, in gilOff run-loop dispatches - DeferredWorkTimer: fix stale runRunLoop comment about the non-gilOff arm taking m_taskLock - DeferredWorkTimer: make TicketData::m_isCancelled a relaxed std::atomic<bool> - GILDroppedSection: stop publishing a coop GC root snapshot from the out-of-line ctor - JSMicrotask: delete the unreferenced publishAsyncGeneratorResume host function - JSMicrotask: gate the generatedJITCodeForCall mirror assert on !gilOff - JSPromise: keep GIL-off spawned threads off VM::m_synchronousModuleQueue - JSPromise: read m_asyncContextData directly at the five capture sites - LockObject: count asyncHold registrations toward the spawned registrant's keepalive - LockObject: keep a termination pending in the asyncHold(fn) settle instead of rejecting - LockObject: keep the GILDroppedSection coop root snapshot on the park-site frame - LockObject: open the park-resumption window at the holder's release, not at park entry - LockObject: run the async-grant pump inline for a spawned head registrant under gilOff - MicrotaskCall: relaxed entry/codeBlock loads, acquire fence only in the gilOff arm - MicrotaskQueue: clearForGlobalObject also filters the GIL-off foreign inbox - MicrotaskQueue: record that the marker takes the inbox lock under VMLiteRegistry::lock - Thread.restrict: refuse realmless (wasm GC) receivers before the species check - ThreadManager.h: drop the stale useThreads-alias paragraph from the gate comment - ThreadManager.h: keepalive banner lists only the two real decrement sites - ThreadManager.h: replace the stale U-T9-INT1 gate block with the current keepalive invariant - ThreadManager: clear pending termination exception before publishing Error("Thread terminated") - ThreadManager: decrement keepalive in retireUnsettled; document which sites count - ThreadManager: default maxJSThreads to the 16383-id spawned TID partition and document the GIL-on lifetime cap - ThreadManager: delete stale reviewer NOTE about unapplied threadRestrictCheck hooks - ThreadManager: remove dead currentTID() and the VM-blind allocateSpawnedThreadState() - ThreadManager: remove the dead ThreadWaitDeadline registrant-deadline machinery - ThreadManager: remove the never-populated waitDeadlines expire/harvest path - Threads: make spawned threads always blockable GIL-off; drop dead mayBlockSynchronously - Watchdog.h: document the GIL-on cross-thread CPU-budget limitation for spawned servicers - Watchdog.h: say GIL-on/flag-off are behavior-identical, noting the uncontended m_lock take - Watchdog/LockObject: delete stale WIRING STATUS block and dead jsThreadParkTerminationRequested - Watchdog: describe the W1 parked-carrier verdict as wall-clock authoritative, drop WIRING STATUS - Watchdog: guard the GIL-off carrier depth decrement so a mid-entry-created watchdog cannot wrap - threadMain: drop the AB18-I residual-exception fold and its dataLog line - throwConcurrentAccessError: pass JSValue() so engine throws carry no own cause
…stry, traps and stop-the-world Fixes for the per-hunk review of #249 (review finding ids: 007-1, 016-1, 016-2, 016-3, 023-2, 027-2, 028-2, 038-4, 057-1, 057-3, 057-4, 057-5, 058-1, 058-2, 058-3, 058-4, 066-2, 073-3, 073-4, 074-2, 080-1, 083-2, 084-3, 093-1, 093-2, 093-3, 093-4, 093-5, 093-6, 094-1, 096-1, 096-3, 096-4, 097-1, 097-2, 097-3, 097-4, 097-5, 097-6, 098-3, 110-1, 111-2, 111-3, 114-5, 115-2, 115-3, 116-5, 128-1, 131-6, 133-1, 133-2, 133-3, 133-4, 133-5, 134-2, 134-3, 135-1, 135-2, 135-4, 136-3, 136-4, 136-5, 136-6, 137-1, 137-2, 138-1, 138-3, 138-4, 139-1, 139-2, 139-3, 139-4, 139-5, 139-6, 140-1, 140-2, 140-3, 140-4, 140-5, 141-1, 141-2, 141-3, 141-5, 141-6, 141-7, 142-1, 142-2, 142-3, 142-4, 142-5, 143-1, 143-2, 143-3, 143-5, 143-6, 144-1, 144-2, 144-3, 145-1, 146-1, 146-2, 146-3, 146-4, 147-1, 147-2, 147-3, 148-6, 149-4, 150-3, 150-5). - AbstractModuleRecord: take cellLock() around m_resolutionCache reads and inserts - CLoopStack: create segments lazily; register and bump the cache epoch only for stacks with segments - CLoopStack: republish the running thread's stack limit at JSLock acquisition - CLoopStack: setSoftReservedZoneSize grows only the caller's segment; zone size is a relaxed atomic - CLoopStack: test top frame containment before topOfFrame(); read it through group3Primitives - CachedCall: gate the foreign-drain skip and m_ownerThread on the per-VM gilOff mode - CodeCache: take the GIL-off compilation lock in clear() - CodeCache: use the shared GILOffCompilationLocker from JSThreadsSafepoint.h - CommonSlowPaths: state that the fast-iteration-mode popcount bound is best effort under races - ConcurrentAccessError: cache the per-realm Structure and inherit the constructor from Error - ConcurrentButterfly.h: include VMLite.h unconditionally, drop the TID-0 __has_include shim - Debugger: detach a destructing global inline instead of requesting a stop from the sweep - Debugger: register spawned-thread CodeBlocks under a stop instead of dropping carrier breakpoints - Debugger: state deleteAllCode's registry-keyed idle deferral at recompileAllJSFunctions - Declare the jsThreads stop-protocol seams once in VMManager.h and VMLite.h - Declare the park-site poll and carrier-park helpers in VMTraps.h/JSLock.h; drop five redeclarations - ExceptionScope/VM: state RETURN_IF_EXCEPTION's flag-off Config byte-test cost in the comments - FrameTracers/VM: remove uncalled pre-resolved tracer overloads and group3Primitives(preResolved) - FrameTracers: drop stale NOTE claiming prepareCallOperation is unconverted under gilOff - FunctionExecutable: drop dead codeBlockWithEntrypointFor and replaceCodeBlockWith - Interpreter: relaxed CachedCall entry loads, gate absorb/snapshot on gilOffWithProcessGate() - JSDollarVM: register sharedHeapTest allowIfNotFuzz like other crash-on-misuse entries - JSGlobalObject: drop the dead per-lite AsyncLocalStorage cursor scaffolding - JSGlobalObject: keep a global's own MicrotaskQueue when a spawned thread enqueues GIL-off - JSGlobalObject: route generator claim/publish hooks through atomicInternalField() - JSGlobalObject: state the eager-init invariant for the two arguments lazy properties - JSGlobalObject: take the Function-constructor cache lock only under gilOff - JSGlobalObject: visit per-lite realm entries only for a gilOff VM - JSLock.h: document both unlockAllForThreadParking callers and the nested-bracket shape - JSLock/VMLite: describe per-lite microtask queue routing as landed, drop 'not rerouted' notes - JSLock: clear the thread-client slot when a gilOff carrier enters a GIL-on VM - JSLock: drop the write-only spAtEntry and constant releaseAccessAtDepthZero token fields - JSLock: gate the F.5 outer-carrier restore on this thread's own blocking-section drop - JSLock: gate token retirement and the deferred carrier restore on useVMLite - JSLock: release the carrier client's access at every gilOff depth-0 release - JSLock: test g_jscConfig.gilOffProcess, not VM::isGILOffProcess(), on every lock() - JSLock: unlockAllForThreadParking comment states the landed GILDroppedSection split - JSPI: refuse pinball fulfill/reject resumption on spawned Threads (SD7) - JSThreadsSafepoint: walk the parked thread's own topCallFrame for the epoch-overlap jettison - MarkedVector: drop m_markSetLock, recover the shard lock from m_markSet under useSharedGCHeap - Options: fail-stop when useProfiler/forceEagerCompilation undo useJSThreads => useConcurrentJIT - Options: state that the gilOffProcess latch in notifyOptionsChanged is permanent - Options: wire useThreadedDFG as a DFG/FTL tier kill switch under useJSThreads - Options: wire useThreadedFTL as a tier kill switch (useFTLJIT off under useJSThreads) - RaceAmplifier.h: describe the landed perturb() sites, drop the stale plan and unused isEnabled() - Refuse import() and new ShadowRealm() on a spawned thread under GIL-off - SamplingProfiler.h: drop never-instantiated WhileTargetSuspendedScope and the stale audit table - SamplingProfiler: refuse to sample a gilOff VM with a logged diagnostic instead of silent dormancy - ScratchBufferRegistry: one baked scratch index per size class instead of one per compile - ScriptExecutable: delete dead replaceCodeBlockWith helpers; publish CodeBlock slots via one helper - SharedVMState: fail-stop on same-thread StructureAllocationLocker nesting instead of hanging - ThreadLocal: cache the per-realm instance Structure and honor newTarget - VM.h: replace the exception-scope-verification review log with the member's invariant - VM: correct the flag-off cost claims on the exception/trap mode-split accessors - VM: count DrainMicrotaskDelayScope per thread GIL-off so spawned drains are never stranded - VM: decide the inline soft-stack-limit and VMEntryScope gates on gilOffWithProcessGate() - VM: decide whenIdle against the lite registry under gilOff and run pop listeners on the last thread out - VM: document heapRandomUint64Concurrent as the concurrent-sweep-only path - VM: fan notifyNeedTermination VM-wide so the carrier shield cannot swallow it - VM: heap-allocate rejection handoff records so no Strong op runs under the queue lock - VM: make the soft reserved zone size per-lite under gilOff and drop the RMW lock - VM: remove the unused everHadSecondMutator/gilOffMultiMutator bit and its registerLite scan - VM: replace the stale g_jscCurrentVMLite rationale block with the current contract - VM: restore eager time zone initialization at VM creation (flag-off identity) - VM: retire concurrent entry-scope service bits VM-wide under gilOff - VM: retire the cross-thread-entry note from ~VM, not from the main carrier's ~VMLite - VM: retire the cross-thread-entry note from ~VM, not from ~VMLite - VM: retire the cross-thread-entry note from ~VM; ~VMLite never dereferences vm - VM: route notifyNeedTermination through fireTrapVMWide so parked lites observe it - VM: state that every JSPromise.cpp tracker call routes through the cross-thread gate - VM: state the real VMLiteRegistry lock rank and drop the leaf claims - VM: whenIdle uses the per-lite entry records under gilOff (same defect as 135-2) - VMEntryScope: delete the dead N-entry refusal walk and the per-round status log - VMEntryScope: whenIdle now honors the per-lite entered record the comment describes (same defect as 135-2) - VMInspector: resolve GIL-off frames through the lite's VM group3Primitives() - VMLite: delete dead lazyInit* block and mark GATE-3 landed in LazyPropertyInlines.h - VMLite: delete the unused lazy-init owner side table - VMLite: drop the dead Darwin TLS mirror; refuse GIL-off on non-Linux at option validation - VMLite: drop the unused TLC chain verifier; assert the tlcTable/tlcTableBound mirror instead - VMLite: drop the unused regExpAllocator and sizeOfLastScratchBuffer fields - VMLite: fail-stop a compilation that asks the installed lite for a scratch buffer - VMLite: key baked scratch indices by size class so the index space is bounded - VMLite: never dereference vm in ~VMLite; retire the cross-thread-entry note from ~VM - VMLite: remove the vacuous LZ1.3 teardown assert with its empty table - VMLite: replace the Phase A/HARD GATE comments with the landed GIL-off routing - VMLite: state the baked-scratch contract every tier now keeps - VMLite: stop dereferencing vm in ~VMLite (a DETACHED carrier can outlive ~VM) - VMLite: update the WS1.2 status list to match RegExpCache and ThreadManager as shipped - VMLiteRegistry: document the real lock order; the registry lock is not a leaf - VMLiteShared: call the STW-forbidden scope unconditionally; drop the N7 shim macro - VMLiteShared: everHadSecondMutator scan already removed with VM finding 136-6; verified no residue - VMLiteShared: state that the SAL locker is out-of-line and must be constructed only with the option on - VMManager: delete the unused numberOfEnteredThreads helper - VMManager: document jsThreadsStopPendingFor as the thread-granular-window probe only - VMManager: gilOff cancelStop clears sibling lites through VM::clearVMWideEntryScopeService (135-1) - VMManager: key the A.3 arbitration ParkingLot queue on the window token, not the Lock's address - VMManager: let gilOff acquirers through the Mode-stop gate until a representative is elected - VMManager: make a nested notifyVMStop from the servicing thread's STW callback a no-op - VMManager: publish the function-scope root snapshot at the A.3 ticket park site too - VMManager: remove BUGHUNT env-gated window-latency instrumentation and its includes - VMManager: same Mode-stop gate fix as 144-1 (idle-VM debugger stop no longer parks every acquirer) - VMTraps.h: replace the stale activation checklist with the current per-lite traps contract - VMTraps: drop the stale VM-level DeferTermination keying note in handleTraps - VMTraps: leave NeedWatchdogCheck pending when a GIL-off carrier polls without an entry scope - VMTraps: make the per-thread defer counters plain scalars again - VMTraps: resolve topCallFrame per-lite for the epoch jettison and debugger-break invalidation - jsc: read hasPendingTerminationException while the lock keeps the carrier lite installed - offlineasm: add cloop pseudo-instructions for the lite TLS read and the relaxed trap poll
…and flag-off codegen Fixes for the per-hunk review of #249 (review finding ids: 000-2, 000-3, 001-1, 002-1, 002-2, 002-3, 003-1, 003-2, 003-3, 004-1, 004-2, 004-3, 005-1, 006-1, 006-3, 006-5, 007-2, 007-3, 007-4, 007-5, 007-6, 008-1, 008-2, 008-3, 009-1, 009-2, 010-1, 010-2, 010-3, 011-1, 011-3, 012-2, 012-3, 012-4, 013-1, 013-2, 013-3, 014-1, 014-2, 014-4, 014-5, 014-6, 014-7, 015-1, 015-2, 015-3, 015-5, 015-6, 016-4, 016-5, 016-6, 017-1, 018-1, 018-2, 018-3, 019-1, 019-2, 020-1, 020-2, 020-3, 020-5, 020-6, 021-1, 021-3, 021-4, 022-1, 022-2, 022-3, 022-4, 022-5, 022-6, 022-7, 025-1, 025-2, 025-3, 025-4, 026-1, 026-2, 027-1, 027-3, 027-4, 027-5, 028-1, 028-3, 028-5, 029-1, 029-2, 029-3, 029-4, 030-1, 030-2, 031-2, 032-1, 032-2, 032-3, 041-2, 059-1, 059-2, 059-4, 059-5, 060-1, 060-2, 060-3, 060-4, 061-1, 061-2, 061-5, 062-1, 063-1, 063-2, 063-3, 064-1, 064-2, 064-3, 064-4, 064-5, 065-1, 065-2, 065-3, 065-4, 065-5, 066-3, 066-4, 067-2, 067-3, 067-4, 068-2, 068-3, 069-1, 074-1, 085-1, 103-3, 106-2, 120-1, 134-1, 147-4, 150-1, 150-6). - AbstractMacroAssembler: remove dead initializeRandom() superseded by nextRandomSeed() - AssemblyHelpers.h: state the real loadVMLite contract (any GPR, no scratch) at every gilOff helper - AssemblyHelpers: RELEASE_ASSERT iso request fits cellSize in tlcSlotForConcurrentlyWithIso - AssemblyHelpers: arity-check stack limit compares with GreaterThan again; contract requires the base condition - AssemblyHelpers: collapse the dead Darwin loadVMLite leg now that non-Linux GIL-off is refused - AssemblyHelpers: drop the wrong data-temp contract on loadVMLite; emitter clobbers only dest - AssemblyHelpers: fold copyLLIntBaselineCalleeSaves into one VM&-keyed definition - AssemblyHelpers: make loadVMLite the member implementation, declare the free form once, drop the macro guard - AssemblyHelpers: rekey LLInt/Baseline callee-save spooler to VM&, drop duplicate in JITOpcodes - Baseline enumerator_put_by_val: send flag-on out-of-line stores to the generic IC, not structureMismatch - Baseline/thunk stack checks: pass the base's signed condition so flag-off bytes match - Bytecode: fold if (@gilOffProcess) at codegen and drop the dead arm in builtins - BytecodeGenerator: drop the last local GILOffCompilationLocker use; declaration now lives in one header - BytecodeIntrinsicRegistry: derive @gilOffProcess via VM::isGILOffProcess(), drop stale comment - CCallHelpers: drop __has_include scaffolding and unused includes, use ConcurrentButterfly.h constants - CallLinkInfo: first polymorphic publish can no longer pair the new record with a null m_stub on ARM64 - CallLinkInfo: make the thunk's m_stub load address-dependent on the record load (ARM64) - CallLinkInfo: pack Mode with the write-once callType/type byte, returning sizeof to base + m_record - CallLinkInfo: state the real reason s_callLinkSerializationLock is recursive and ban GC-cell allocation under it - CallLinkInfo: store the mode with relaxed byte accesses instead of seq_cst Atomic stores - CodeBlock: drop the DFG JITData leak arm and the no-op retireOptimizedJITCode wrapper - CodeBlock: free metadata, JITData and OpCatch buffers inline in ~CodeBlock with JS threads on - CodeBlock: unlink leaked metadata/DFG-JITData call sites in ~CodeBlock so records release their pins - CompactTDZEnvironmentMap: serialize the TDZ interning table itself instead of one codegen caller - DFG AI: clobber structures across GIL-off parkable nodes instead of folding the clobber - DFG EnumeratorPutByVal: run the butterfly write predicate before the out-of-line store - DFG OSR exit ramp: use the invalidating scratch temp as the gilOff per-lite scratch base - DFG compileSpread: copy from the butterfly snapshot the length came from flag-on - DFG prologue stack check: pass GreaterThan so flag-off bytes match the merge base - DFG/FTL: skip the PerformPromiseThenOneHandler inline install for a gilOff VM - DFG: accept PutByValDirectResolved on the segmented-aware PutByVal path - DFG: dispatch operationArrayPopAndRecoverLength on the butterfly regime; drop stale FIXME - DFG: drop mergeOSREntryValue zero-StructureID bail and validated-freeze scaffolding - DFG: drop the __has_include(ConcurrentButterfly.h) scaffolding and frozen fallback constants - DFG: fail the compilation when a desired watchpoint set was fired before the link - DFG: gate m_tierUpTriggersLock on useJSThreads in operationTriggerTierUpNowInLoop - DFG: gate the clobberize validator suppression on vm().gilOff(), not the process option pair - DFG: keep the segmented-butterfly bit for Convert+Original array modes - DFG: make the segmented-aware Double GetByVal SaneChain arm pure and format-correct - DFG: remove the dead DW-1 sort-comparator OSR-exit stash record - DFG: resolve operand scratch buffers per lite under gilOff instead of baking VM addresses - DFG: skip inline-offset by-offset nodes in the butterfly tag-discipline lint - DFG: state the compilation lock's scope in Plan::finalize instead of a residual-race note - DFG: state the landed usePollingTraps invariant at JumpReplacement::installVMTrapBreakpoint - DFG: state the usePollingTraps invariant at the VMTrap breakpoint asserts - DFG: use the shared GILOffCompilationLocker from JSThreadsSafepoint.h in Plan::finalize - DFG: write MiscFields at the GIL-off CheckTraps poll so typed-array vector/length reload per poll - DFGMayExit: report PutByOffset as Exits flag-on only for out-of-line offsets - DFGOSRExitCompilerCommon: drop loadVMLite redeclaration, call the AssemblyHelpers member - DFGThunks: drop the stale Release VM-block fallback from the OSR exit destination comments - DFGThunks: use header loadVMLite; pin per-lite scratch offsets to the ARM64 ldr immediate range - FTL ArithRandom: drop the GIL-off operation detour; inline path matches DFG and thunk tiers - FTL MaterializeNewObject: say why the slow-path butterfly mask is required, not a no-op - FTL MultiDeleteByOffset: RELEASE_ASSERT flag-off; remove the dead threaded slot-clear arm - FTL compileDelBy: assert base != result before the handler-IC shuffle aliases them on ARM64 - FTL lazy slow path: consumer-side instruction sync before executing a foreign-thread stub (gilOff) - FTL prologue: restore signed GreaterThan stack check so flag-off bytes match the base - FTL varargs frame: restore signed GreaterThan soft-stack-limit check for flag-off byte identity - FTL: TID-tag inline-allocated butterflies under useJSThreads, not only gilOff - FTL: address the handler-IC dummy ArrayProfile off jitDataRegister like the DFG - FTL: correct the E1 comment; the owner compare is not a segmented-word backstop - FTL: drop the stale useThreadedFTL wiring comment in compilePutByOffset - FTL: drop unreachable slow-path call from handler-IC GetById/GetByIdWithThis late paths - FTL: include ConcurrentButterfly.h unconditionally; drop duplicated tag-encoding fallback - FTL: skip E2 writeThreadLocal registration for KnownNonArrayStorage read plans - FTLOSRExitCompiler: drop the loadVMLite self-declaration and call the AssemblyHelpers member - FTLSaveRestore: make materializers clobber only dest; loadVMLite via member - FTLSaveRestore: remove the loadVMLite self-declaration and bring-up comment - FTLThunks: document why the baked exit-thunk scratch dump survives the generation call - FunctionExecutable: remove the uncalled codeBlockWithEntrypointFor - GCAwareJITStubRoutine: defer the zero-refcount delete only while the JITStubRoutineSet holds the routine - GetByStatus::computeFromLLInt: read LLInt cache mode and structureID words with relaxed atomic loads - InferredValue: add() reports a refused link so the DFG singleton fold is not installed stale - InlineCacheCompiler ArrayLength stub: bail only for SW=1 ArrayStorage/SlowPut, not every SW=1 flat word - InlineCacheCompiler: drop the false EOR zeroing-idiom claim from the ArrayLength dependency comment - InlineCacheCompiler: give the shared stateless stub no owner CodeBlock - InlineCacheCompiler: make the flag-on per-case Replace stub store through the write predicate - InlineWatchpointSet: CAS thin-state stores and retry the inflateSlow publish flag-on - JIT inline allocation: TID-tag the installed butterfly under GIL-on as well as GIL-off - JIT: release a record's CodeBlock pin when the owning CallLinkInfo frees the record inline - JITOperations: fail-stop operationReallocateButterflyAndTransition under useJSThreads - JITThunks: gate hostFunctionStub/finalize m_lock on useJSThreads - JITThunks: state the real m_lock scope, held across thunk generation - JITWorklist: drop unused <wtf/NeverDestroyed.h> include and finalizingKeys history note - JITWorklist: print duplicate-plan verbose log via locker dump to avoid re-locking m_lock - JSThreadsSafepoint.h: declare gilOffCompilationLock and GILOffCompilationLocker once - JSThreadsSafepoint.h: describe the live GIL-on stub and gilOff conductor paths and the live watchdog - JSThreadsSafepoint: GIL-on Class-A fire tolerates a second entered VM; add regression test - JSThreadsSafepoint: GIL-on stub no longer requires every other VM in the process to be idle - JSThreadsSafepoint: accept only this thread's own stub depth as thread-stable stopped evidence - JSThreadsSafepoint: declare the heap-fact rewrite epoch API in its own header, not VMTraps.h - JSThreadsSafepoint: drop the __has_include probes, dead #else arms and the OM stub witness reads - JSThreadsSafepoint: make the stop-the-world watchdog timeout an Option (0 = disabled) - JSThreadsSafepoint: scope the entered-VM tripwires to VMs attached to the caller's server heap - JSThreadsSafepoint: state the in-window bump as load-bearing and the ctor/dtor bumps as edges - LLInt callHelper: name x6/a6 as the ARM64 register invokeForTailCall clobbers - LLInt loadButterflyTIDTagToT6: state the non-Linux slow-path cliff, not a missing slot - LLInt virtualThunkFor: state that the slot recompare is belt-and-braces, not the defense - LLInt: drop the DW-1 sort-comparator stash cross-check and its release-build dataLogLn - LLInt: drop the Group-3 break tripwire now that Options refuses GIL-off off Linux - LLInt: drop the gilOffProcess fence test from op_put_internal_field on x86-64 (TSO) - LLInt: gate the varargs frame echo and its RELEASE_ASSERTs on vm.gilOff() - LLInt: load m_cache.structureID with a relaxed atomic in try_get_by_id/get_by_id_direct - LLInt: remove the non-Linux Group-3 break tripwire from production code - LLInt: restore flag-off memory-operand structure compares in enumerator ops and put_to_scope - LLInt: revalidate the slot offset against the keyed structure before a GIL-off one-word publish - LLInt: wire the useThreadedLLIntICs kill switch into the one-word cache publishers - LOLJIT: pass signed GreaterThan to branchPtrAgainstSoftStackLimit to keep flag-off bytes - MacroAssemblerARM64: make loadFromELFTLS64 scratch-free (mrs; add hi12; ldr lo12) - OSR exit: crossModifyingCodeFence before reusing a ramp compiled on another thread - OSR exit: share one generation lock between DFG and FTL exit compilers under gilOff - PropertyInlineCache: document resetStubAsJumpInAccess as a live publish, not world-stopped - PropertyInlineCache: make m_identifier an ICRacyCell so every writer is a relaxed store - PropertyInlineCache: state the real flag-off per-IC footprint cost and its sizeof consumers - Repatch.cpp: state that the cacheable-dictionary guard exists so ICs settle at GaveUp via the addAccessCase funnel - Repatch/InlineCacheCompiler: name the real gate for flag-on put transitions - Repatch: count only consecutive no-progress retries before GIL-off GaveUp demotion - Repatch: gilOff linkMonomorphicCall loser bails unless the site is still Mode::Init - RetiredJITArtifacts: drop __has_include scaffolding, leak arms and always-true epoch predicate - RetiredJITArtifacts: replace unreachable lazy makeGCAware promotion with RELEASE_ASSERT(isGCAware) - SetupVarargsFrame: restore signed GreaterThan soft-stack-limit compare (flag-off byte identity) - SharedJITStubSet: make find() take its reference with tryRef so a dying routine is never resurrected - UnlinkedFunctionExecutable: make recordParse fields dedicated relaxed-atomic bytes - UnlinkedMetadataTable::link: drop TSAN-only relaxed zeroing, keep memset - Watchpoint: drop the out-of-line Dependency::fence from InlineWatchpointSet fat reads - Watchpoint: drop the unused fireEarlyForGILOff/hasClassAFirePending and state the real deferral ordering - Watchpoint: refuse add() on an invalidated set flag-on; enumerator install falls back to traversing - Watchpoint: remove the BUGHUNT Class-A fire instrumentation - Watchpoint: remove the uncalled fireEarlyForGILOff/hasClassAFirePending scaffolding - WatchpointSet: arm by CAS, refuse add() on an invalidated set, make callers honor the refusal - WatchpointSet: route already-stopped Class-A fires through stopTheWorldAndRun's guarded path - Yarr: drop the false matchLimit stop-latency bound claim and its static_assert ratchet - YarrJIT: restore the signed LessThanOrEqual soft-stack-limit check so flag-off bytes match base - resolve_scope slow paths: read m_resolveType with a relaxed atomic load like its writers - resolve_scope: freeze op_resolve_scope metadata after linking flag-on in all three writers
…support Fixes for the per-hunk review of #249 (review finding ids: 150-2, 150-4, 150-7). - Wasm: gate the spawned-thread refusal on useJSThreads so flag-off skips the TLS lookup - Wasm: refuse GC-typed modules under useSharedGCHeap with CompileError/LinkError, not abort - WasmMemory: mark GIL-off relocating-grow stop arm dormant, drop audit-closure claims
…ctories Binaries, logs, core-dump backtraces, per-run outputs and crash dumps were checked in with the bring-up tooling: a 2.3 MB compiled Go benchmark (Tools/threads/scalebench/out-run1/bench-go), 18 Java .class files, 3.8 MB of gzipped logs, 121 .bt backtraces, 290 .out files and the matching .time/.err/.jsonl run records, 10 crash logs with /root/WebKit build paths under JSTests/threads/cve, and two candidate patches stored as .diff files under docs/threads. None of these are inputs to a build or a test. The sources that produced them (Bench.java, go/main.go, bench.js, run.sh, the fuzz profile and its registration patch) stay.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Draft. Fixes for the per-hunk review of #249, on top of
jarred/threadsat 3a14f2a. The base is the threads branch, so the diff is only the fixes. The branch is not rebased ontomain.What this does
JSTests/threads/. 33 of them fail on the unfixed head with--useJSThreads=1and the default GIL..classfiles, gzipped logs, 121 core backtraces, 290.outrun records, crash dumps, two candidate.difffiles). That is its own commit and can be dropped.Verification
All on Linux x86-64, Release (
-DPORT=JSCOnly, thebuild.tsflags), same toolchain for both binaries.Tools/threads/run-tests.sh, GIL-on (--useJSThreads=1): 153 passed, 0 failed, 2 skipped. Unfixed head: 102/0/2 (the delta is the new tests).JSC_useSharedGCHeap=1 JSC_useThreadGILOffUnsafe=1 JSC_useThreadGIL=0): 152 passed, 0 failed, 3 skipped. Unfixed head: 101/0/3.//@ requireOptionsheaders: 56/56 in both modes.JSTests/stressfiles (every 40th), identical stdout, stderr and exit code between the unfixed and the fixedjsc. Flag-on GIL-on: 131 other stress files, identical.jsc --useJSThreads=1 -e 'JSON.stringify({a:{a:1}})'hangs on the unfixed head (timeout) and prints on this branch.Not run: TSAN, the bench gate, macOS, Windows, arm64, Bun itself. Nothing here was benchmarked.
Commits
One commit per area. The tree builds at the head; an intermediate commit may not, because a header and its users can sit in different areas. Each commit body lists the fixes it carries, one line each, and the review finding ids.
Heap.handJSObjectInlines.hnow include (Bun did not compile against the PR tree).deref()andDeferrableRefCountedno longer pay atomic RMWs;SharedAtomStringTablemigrate/latch order documented as the code does it.m_protectedValuesandHandleSetstrong list locked under GIL-off; epoch drain moved before~VMnulls the shared stubs; call-link pins released when the owningCallLinkInfofrees its record; the TEMPORARY GC diagnostics and the exported test hook removed; duplicate collection tickets deduped under one lock hold; the per-thread allocator snapshot is trusted only for the GIL-off VM that owns it.forEachPropertyfunctor outside the Structure lock,EnumeratorPutByValthrough the write choke point, typed-array views converted with a header fragment instead of theArrayBuffer*read asvectorLength), the Baseline for-in store index bug, and the check-then-reload and stale-snapshot paths inJSArray,JSObject,ArrayPrototype,ObjectConstructorInlines,ClonedArguments,SparseArrayValueMap,Structure.m_atomwrite-once, bytecode published beforem_state, per-threadDateCacheandStringRecursionCheckerunder GIL-off.Thread.restricton realmless receivers,Thread/ThreadLocal/ConcurrentAccessErrorhonournewTarget, terminated-close publishes theError, the park-resumption window opens at release, the async-grant pump runs inline for a counted spawned registrant (see Notes),maxJSThreadsdefaults to the real TID partition.whenIdleanddeleteAllCodeBlockskey on the per-lite entry records under GIL-off;notifyNeedTerminationreaches parked threads; the main carrier releases pre-acquired heap access across parks; baked scratch indices are per size class (the 16384 cap is gone);VMLiteno longer keeps a danglingVM*; the second-VMRELEASE_ASSERTin the GIL-on stop stub is scoped to VMs that share the server heap.WatchpointSet::addrefuses an invalidated set;inflateSlowretries a lost CAS; the epoch jettison walks the per-litetopCallFrame; DFG and FTL exit compilers share one lock for the lazy profile; ARM64loadVMLiteuses a scratch theload64fallback cannot clobber; the flag-off stack checks keep the signed compare; theuseThreaded*kill switches that nothing read are wired (LLInt cache publication, DFG and FTL tier gating).Left open
These need a decision the review did not settle, so the code is unchanged and the reasoning is in the review thread: BlockDirectory destructor sweeps vs stale sibling readers; the CLoop per-thread stack segment lookup flag-off; ConcurrentButterfly mode (b) fragment liveness under GIL-off; the FTL indexed stores through the read predicate (GIL-only gap, documented); the indexed store stub SW=1 length bump;
DeferredWorkTimerembedder hooks on the settling thread;JSPromisereject-before-handle order across two spawned threads;JSStringdisplaced impl lifetime underswapToAtomString; the LLInt flag-off discriminator cost (needs a handler-table redesign); the GIL-on single VM-wide entry record with parked threads; the 30 s stop watchdog policy; the single-handoff concurrent marking window default; the pre-latch atomization fail-stop (a Bun question); one docs-only item (TTL inheritance rule in SPEC-objectmodel).Notes
Two decisions made while reconciling fixes from different areas
lock.asyncHoldstays an uncounted registration. One fix had made it count toward the spawned registrant's keepalive (SPEC-ungil E.3). That deadlocksapi/thread-lifecycle.jssection 2 andapi/lock-async-hold.jssection 5 under GIL-off: the registrant's completion then waits for a grant that only the current holder can produce, and that holder is the main thread parked injoin()on the registrant. SPEC-api 4.6.2 (tickets outlive their registering thread) is the behaviour the existing tests encode, so that is what ships.cond.asyncWaitstays counted.lock-async-hold.jssection 5). Without this split the inline grant handed the lock to a finished thread's ticket and the next sync hold on main waited forever for a release that only main's own run loop could run.Three existing tests changed:
api/blocking-gate.jsandatomics/ta-wait-thread-gate.jsassert the GIL-only gates only when$vm.useThreadGIL()is true (GIL-off lifts them per SPEC-ungil G.1 and C.6);vmstate/regexp-atom-retained-across-delete-all-code.js(new in this PR) creates its/gregexps per call instead of sharinglastIndexacross threads.How the fixes were produced and checked
Each review finding was handled by a worker that read the finding, confirmed it against the code, fixed it or recorded why not, compiled the translation unit it touched, and added a regression test when the defect is deterministic. 129 file groups ran in parallel, sequentially within a group. The tree was then built in full, the two thread corpora and the new tests were run in both GIL modes, and a flag-off and a flag-on stress sample were diffed against the unfixed build. Four test failures surfaced in GIL-off and were traced to the two decisions above plus the two test expectation changes; everything else passed on the first full build.
The per-finding reports (status, summary, what was verified, what was not) are the source of the commit bodies.