ckerr

#54948: test: count live PromiseHandles without taking heap snapshots

Merged
Created: Oct 14, 2026, 4:26:23 PM
Merged: Oct 14, 2026, 9:33:08 PM
5 comments
Target: main

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

Release Notes

Notes: none

Backports

42-x-y
Merged
PR Number
#54981
Merged At
Oct 14, 2026, 11:50:34 PM
Released In
Not yet
Release Date
Not yet
43-x-y
Merged
PR Number
#54982
Merged At
Oct 14, 2026, 11:50:22 PM
Released In
Not yet
Release Date
Not yet
44-x-y
Merged
PR Number
#54983
Merged At
Oct 14, 2026, 11:50:08 PM
Released In
Not yet
Release Date
Not yet
45-x-y
Merged
PR Number
#54984
Merged At
Oct 14, 2026, 11:49:53 PM
Released In
Not yet
Release Date
Not yet

Semver Impact

Major
Breaking changes
Minor
New features
Patch
Bug fixes
None
Docs, tests, etc.

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