Repository navigation
fix(jsc): wake passive collectors for synchronous GC on main - #22
Merged
Merged
Conversation
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.
steipete
marked this pull request as ready for review
October 7, 2026 01:35
steipete
added a commit
to openclaw/openclaw
that referenced
this pull request
Oct 7, 2026
Worker idle collection only needs the current isolate's used-heap byte counter. Detailed heap statistics on Bun also enumerate live objects, adding avoidable synchronous work in worker lanes. Use process.memoryUsage().heapUsed for both samples while preserving the 32 MiB threshold, inspector collection, generation handling, and worker limits. Focused worker memory, pool, and resource-cleanup coverage passes on Node 24 and the shared Bun pin (25 cases each); changed-file checks pass. This removes the unnecessary heap census. The separate JSC passive-collector wakeup defect is tracked in openclaw/WebKit#21 and openclaw/WebKit#22.
github-actions Bot
pushed a commit
to tbohda2025/openclaw
that referenced
this pull request
Oct 7, 2026
Worker idle collection only needs the current isolate's used-heap byte counter. Detailed heap statistics on Bun also enumerate live objects, adding avoidable synchronous work in worker lanes. Use process.memoryUsage().heapUsed for both samples while preserving the 32 MiB threshold, inspector collection, generation handling, and worker limits. Focused worker memory, pool, and resource-cleanup coverage passes on Node 24 and the shared Bun pin (25 cases each); changed-file checks pass. This removes the unnecessary heap census. The separate JSC passive-collector wakeup defect is tracked in openclaw/WebKit#21 and openclaw/WebKit#22.
github-actions Bot
pushed a commit
to Desicool/openclaw
that referenced
this pull request
Oct 7, 2026
Worker idle collection only needs the current isolate's used-heap byte counter. Detailed heap statistics on Bun also enumerate live objects, adding avoidable synchronous work in worker lanes. Use process.memoryUsage().heapUsed for both samples while preserving the 32 MiB threshold, inspector collection, generation handling, and worker limits. Focused worker memory, pool, and resource-cleanup coverage passes on Node 24 and the shared Bun pin (25 cases each); changed-file checks pass. This removes the unnecessary heap census. The separate JSC passive-collector wakeup defect is tracked in openclaw/WebKit#21 and openclaw/WebKit#22.
steipete
added a commit
to openclaw/bun
that referenced
this pull request
Oct 7, 2026
### What does this PR do? Pin all ten archives from the immutable [OpenClaw WebKit collector-progress and worker-cadence release](https://github.com/openclaw/WebKit/releases/tag/autobuild-cb8d6f202b5a396caa204ee1bb75d78175aa841a). A passive collector now wakes and rechecks when its mutator begins waiting while shared helpers serve another heap. Budgeted workers can use young-generation collections while retaining full-GC heap-limit confirmation and bounded growth. The consuming immediate-timer wakeup is already on main in #129. `WEBKIT_VERSION` derives from the manifest, so the complete manifest updates engine identity and every archive checksum together. The compatibility note and changelog describe the resulting behavior. Engine fixes: openclaw/WebKit#14 and openclaw/WebKit#21, with the wakeup companion on engine main in openclaw/WebKit#22. ### How did you verify your code works? The [protected engine publication](https://github.com/openclaw/WebKit/actions/runs/37562460601) passed all ten builds, native Windows ARM64 probes, both paired 46/46 selections, and the 85-row upstream-synced selection. The native GC regression observed passive collection, completed before helper release, and preserved roots without a stall or timeout. Independent unauthenticated readback verified all fourteen public files, source/tag binding, immutability, GitHub digests, licenses, and byte identity with the checked candidate. On exact head `247fbb2f2bb71fb0c7898398c75156506c2cfe9b`, [native CI](https://github.com/openclaw/bun/actions/runs/37570558780) passed Linux 47/47 rows and macOS 52/52 rows, both with independent net checks. Its synthetic merge tree equals the reviewed head tree. [Windows qualification](https://github.com/openclaw/bun/actions/runs/37570558525) passed both x64 and ARM64 builds, native smokes, 31/31 compatibility rows per architecture, and independent net checks. Archive/executable hashes and PE architectures were independently checked; these remain unsigned test artifacts. The same verified Linux CI executable passed 348 Worker/inspector cases with zero failures on an isolated host, plus the standalone immediate-GC timer regression from #129. Source and executable hashes remained unchanged. Configure-time tests pass 29/29, formatting and the complete fork selector pass, and the committed head is scoped-clean at P2. The unchanged advisory Mordant job reports the existing resolver bare-boolean diagnostic across three targets; its workflow explicitly uses `continue-on-error: true`. The unchanged auxiliary issue matcher cannot start because provider authentication is not configured. All required platform gates above pass. No Bun tag, Bun release, or OpenClaw runtime pin update is included.
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.
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
mutatorWaitingBitonly 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:
The corrected native fixture passes on both macOS and Linux. It releases its context inside the existing JS lock scope; the earlier Linux teardown abort is retained as invalid fixture evidence, not an expected control failure. The fresh exact-source Linux pair positively detects the unchanged-engine wait cycle without timing out (4.413 ms); the candidate completes before helper release (5.456 ms). Both preserve rooted objects.
The completed maintained OpenClaw 100-client / 50-active / 4-driver prime now passes with the fixed engine: 101 replies (51 during the window, 50 during drain), zero errors, ACK p50/p95 9.628/14.025 s, clean 2.567 s shutdown, and no worker-timeout text. Node 26.10.0 on the same host also passes with 103 replies, zero errors, and ACK p50/p95 10.386/14.821 s. First-wave ACKs arrive 7.511–9.630 s after the first send on the fixed engine and 6.626–8.647 s on Node.
These unscored primes use identical frozen OpenClaw source
4998572a3abb0e4ae1a156fe38ffd8ebb5cf8124plus the separate cheap-counter patch in openclaw/openclaw#166104. Gateway CPUs are 0–3 on a Hetzner ccx53, with controllers/provider on 4–31; 60-second admission, 180-second reply deadline and 1,000 ms chunk pacing are unchanged. Both Bun arms were built from667c4ab22cbf6b101b3376c550b81cabc8c00518and enginef1e1ca1156c8cb3b468bec0e1989fbfa08899661, with identical release/non-LTO flags and only this 14-line runtime patch differing. This isolates the runtime repair on the original engine pin; the current PR bases additionally pass their own native builds and exact-head CI.The rebuilt unchanged-engine control failed warmup before load, so it supplies no matched load-window latency estimate. Earlier published 667c and 670b baselines both failed 100/50 while Node passed; an earlier host-interrupted paired unit is excluded entirely. The exact original single 63-second ACK wave and three literal timeout messages were not reproduced. The native regression proves the missed-wakeup defect; Gateway profiling and successful fixed primes support its workload relevance without assigning every historical stall to it.
No engine merge or artifact publication is performed by this work. Upstream searches found no matching repair; WebKit#72377 is already represented in the base and addresses a different notification path.
The final same-shape passive-timeout audit also passes: 102 replies, zero errors, 20 observed pools with no timeout events, and clean 2.195 s shutdown. It adds no timers, worker preloads, heap reads, or retries; the uninstrumented prime above remains the latency comparison.