Repository navigation
Report GC time and full GC count for every isolate lock - #8099
Conversation
There was a problem hiding this comment.
Superseded by the review of
bc6c62f4.
This review, of 4104eca4
✅ Approved — No issues found: GC is measured over the whole time the lock is held, and the observer interface change is small and consistent with how it is called.
The decision is advisory: this review is a comment and never approves, blocks or requests changes on the pull request.
✅ All checks passed
📋 Code Quality: ✅ LGTM
No issues found. The LongTaskStats reset and read bracket the time the lock is held, the full-GC counter is kept per lock and incremented only for mark-compact epilogues, and WebAssembly instance cleanup in the GC prologue still works as before.
📝 Documentation: ✅ LGTM
No issues found. The new reportGc() doc comment and the updated comments where the callbacks are registered describe the current behaviour accurately.
Reviewed commit: 4104eca4
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #8099 +/- ##
=======================================
Coverage 68.31% 68.31%
=======================================
Files 726 726
Lines 189662 189670 +8
Branches 29672 29672
=======================================
+ Hits 129567 129577 +10
Misses 42719 42719
+ Partials 17376 17374 -2 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
uncleDecart
left a comment
There was a problem hiding this comment.
lgtm, only thing I'd add is virtual destuctor to LockTiming class
4104eca to
bc6c62f
Compare
|
@uncleDecart Added in bc6c62f: |
There was a problem hiding this comment.
Superseded by the review of
e7776447.
This review, of bc6c62f4
✅ Approved — No issues found: the only change since the last review is the requested virtual destructor on LockTiming, and the GC measurement logic is still correct.
The decision is advisory: this review is a comment and never approves, blocks or requests changes on the pull request.
✅ All checks passed
📋 Code Quality: ✅ LGTM
No issues found. virtual ~LockTiming() noexcept(false) = default; is correct for an interface owned through kj::Own<LockTiming>. The LongTaskStats reset happens after the lock is acquired, and the read happens before currentLock is cleared, so it brackets the whole time the lock is held. fullGcCount only goes up for kGCTypeMarkSweepCompact. LockRecord::reportGc does nothing when there is no LockTiming. Nothing in the tree still refers to the removed hooks.
📝 Documentation: ✅ LGTM
No issues found. The reportGc() doc comment and the updated comments at the places where the callbacks are registered match what the code does now.
Reviewed commit: bc6c62f4
LockTiming used to time GC itself, through GC prologue and epilogue hooks, and only when the request was traced in Jaeger. Those hooks bracket only the atomic pause, so incremental marking steps run on the main thread went uncounted. The isolate lock now measures GC with V8's LongTaskStats: it resets the stats when the lock is taken and reads them before release, which covers young collections, full atomic pauses and incremental marking. It also counts the full (mark-compact) collections that finish under the lock. Both are passed to the new LockTiming::reportGc(), which replaces gcPrologue() and gcEpilogue(), on every lock rather than only traced ones. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
It is an interface that implementations subclass and that is owned through kj::Own<LockTiming>, like the other observer interfaces in this file, which already declare one. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
bc6c62f to
e777644
Compare
There was a problem hiding this comment.
✅ Approved — No issues found: the only change since the last review is the requested virtual destructor on LockTiming, and the GC measurement logic is still correct.
The decision is advisory: this review is a comment and never approves, blocks or requests changes on the pull request.
✅ All checks passed
📋 Code Quality: ✅ LGTM
No issues found. virtual ~LockTiming() noexcept(false) = default; is correct for an interface owned through kj::Own<LockTiming>. The LongTaskStats reset happens after the lock is acquired, and the read happens before currentLock is cleared, so it brackets the whole time the lock is held. fullGcCount only goes up for kGCTypeMarkSweepCompact. LockRecord::reportGc does nothing when there is no LockTiming. Nothing in the tree still refers to the removed hooks.
📝 Documentation: ✅ LGTM
No issues found. The reportGc() doc comment and the updated comments at the places where the callbacks are registered match what the code does now.
Reviewed commit: e7776447 — same changes as bc6c62f4, so this is that commit's review (no new review was run; line numbers are as of bc6c62f4)
LockTimingused to time GC itself, through GC prologue and epilogue hooks, and only when the request was traced in Jaeger. Those hooks bracket only the atomic pause, so incremental marking steps run on the main thread went uncounted.The isolate lock now measures GC with V8's
LongTaskStats: it resets the stats when the lock is taken and reads them before release. That covers young collections, full atomic pauses and incremental marking. The lock also counts the full (mark-compact) collections that finish while it is held. Both values go to the newLockTiming::reportGc(), which replacesgcPrologue()andgcEpilogue(), and it is called on every lock, not only traced ones.Downstream, edgeworker uses this to publish per-invocation GC time and full GC count in its invocation logs. Nothing else implements
LockTiming's GC hooks.About
LongTaskStatsbeing experimentalv8::metrics::LongTaskStatsis marked experimental inv8-metrics.h, but it's well established:v8_execute_uswas added, and has only seen mechanical refactors since.Reset()at the start of every main-thread task (PerformanceMonitor::WillProcessTask) andGet()for thePerformanceAPI.LongTaskUKM (RecordLongTaskUkmincore/timing/performance.cc). Blink computesDuration.V8.GCfrom the same three-field sum we use. The V8 GC leads own that UKM.LongTaskStatsFullAtomic,LongTaskStatsFullIncremental, ...).If it is removed, the build breaks at the V8 upgrade. If it silently stops reporting, edgeworker's
gc-loggingtest, which asserts that GC time is non-zero after forced GCs, catches it.🤖 Generated with Claude Code