Skip to content

fix(jsc): wake passive collectors for synchronous GC on main - #22

Draft
steipete wants to merge 2 commits into
openclaw/mainfrom
steipete/fix-passive-gc-wakeup-main
Draft

steipete wants to merge 2 commits into
openclaw/mainfrom
steipete/fix-passive-gc-wakeup-main

Conversation

@steipete

@steipete steipete commented Oct 6, 2026

Copy link
Copy Markdown

Main-branch companion of #21. The collector fix and native probe are identical; this branch uses its existing qualification script and inline receipt gate.

A worker can stall inside synchronous inspector GC while the main thread waits for its database work. A collector that has already entered passive draining checks mutatorWaitingBit only on entry. If its mutator starts waiting afterward and shared helpers are occupied by another heap, neither side wakes the collector to take over the marking work.

Notify the marking condition under its mutex after releasing the thread lock, and recheck the waiting bit inside the passive loop. The collector then unlocks and drains actively. The 14 added production lines close both the missing notification and the missing predicate check; collection policy, helper counts, heap limits, and application concurrency remain unchanged.

The native regression uses actual Heap operations and ParkingLot observations, holds the shared helpers, and requires collection to finish before releasing them. The unchanged engine positively exhibits both parked waiters, with no timeout; the fixed engine completes and preserves rooted objects. The regression is included in the existing native qualification and its receipt verifier.

Validation so far:

  • macOS native control fails on the observed wait cycle; candidate passes. The integrated regression also passes on this PR's current main-branch base.
  • 345 surrounding Bun Worker/inspector tests and 25 OpenClaw worker-pool, memory-reclamation, and cleanup cases pass with the isolated fix.
  • Independent review of the complete change is clean at P2.
  • A separately instrumented maintained OpenClaw 100-client / 50-active run reproduced 20 reply deadlines. One SQLite-worker GC overlapped 99.96% of a 35.2-second held database admission, with 49 writes queued behind it. Native stacks show the mutator waiting for collection, a passive collector, and occupied shared helpers. These diagnostics identify the mechanism; debugger-overlapping latency spans are excluded from attribution.

Draft: paired Linux builds and the fixed 100/50 Gateway proof are still pending. No end-to-end load recovery is claimed yet. The separate heap-statistics cost is tracked in openclaw/openclaw#166104. Upstream searches found no matching repair; WebKit#72377 is already represented in the base and addresses a different notification path.

A concurrent collector can already be parked for shared helpers when its
mutator starts waiting for collection. Notify under the marking mutex and
recheck the waiting bit before sleeping so the collector can drain its own
work without relying on another heap to release helpers.

Add a native regression that observes the actual collector and mutator
parking addresses, holds shared helpers, and requires completion before
helper release while preserving rooted objects. Include it in the existing
native qualification gate.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant