#54948: test: count live PromiseHandles without taking heap snapshots
Description of Change
cpp heap > gin_helper::Promise cppgc > PromiseHandle should not leak timed out on slow CI machines that run with the default 30 s timeout: macOS x64, and an ASan build without a raised timeout.
Each time it failed, all three retries also timed out at 30 s.
The test counted PromiseHandles with three recordState() calls.
Each call takes a heap snapshot of the main process, builds the snapshot's full JS object graph, and builds Node's embedder graph.
In a failing ASan shard, a spec that takes one such snapshot ran for 8.7–11.8 s, while a spec in the same file with no snapshot ran for 2.1 s.
So each snapshot cost about 8.5 s, and three of them can overrun the timeout.
Even a passing run on that kind of machine took 24.9 s of the 30 s.
This change reads the count from the C++ heap's detailed statistics (v8.getCppHeapStatistics('detailed')) instead.
They show the same objects a snapshot does, in about a millisecond.
They include any handle not yet reclaimed, garbage too, so the test collects before each count, and the count then reflects the handles live at that point.
Locally the test now takes about 0.25 s instead of about 3 s.
Collection now uses V8's gc({ execution: 'async' }).
It runs from a fresh task without scanning the native stack, so a stale pointer cannot keep the released handle alive.
v8Util's async collection is not used because the promise it returns is itself a PromiseHandle.
Collecting before holding the promise keeps garbage out of the first count, so comparing it with the count after a collection checks that the held handle survives.
The assertions are unchanged.
Testing:
- The new test passed 50 of 50 repetitions in one worker.
- Removing the clear, clearing early, or skipping the collection makes the matching assertion fail.
🤖 Generated with Claude Code
Checklist
- I have built and tested this change
- I have filled out the PR description
- I have reviewed and verified the changes
- tests are changed or added
Release Notes
Notes: none
Backports
Semver Impact
Semantic Versioning helps users understand the impact of updates:
- Major (X.y.z): Breaking changes that may require code modifications
- Minor (x.Y.z): New features that maintain backward compatibility
- Patch (x.y.Z): Bug fixes that don't change the API
- None: Changes that don't affect using facing parts of Electron