From d692ad880e54c01d92ee48a3f7ddfa5d4c45e758 Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 2 Oct 2026 22:22:20 +0000 Subject: [PATCH] Collect garbage between the phases of pnpm bench Garbage from one phase (render10000Items, for example) was collected inside a later phase, wherever V8 decided to. A change that allocates more or less moved those collections between phases, so phase times shifted for reasons unrelated to the phase itself. Chrome now runs with --expose-gc, and waitForIdle() calls gc() before the next phase starts, outside the measured marks. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01JqJMavyH9FWrQWG3PAGzsT --- bin/benchmark/run.mjs | 4 ++++ smoke-tests/benchmark-app/app/run-benchmark.js | 11 ++++++++++- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/bin/benchmark/run.mjs b/bin/benchmark/run.mjs index 3a1cf6bcc0a..454376b7386 100644 --- a/bin/benchmark/run.mjs +++ b/bin/benchmark/run.mjs @@ -177,6 +177,10 @@ async function bootAndRun({ headless = true } = {}) { // as the contradictory flags cause use-after-free crashes on macOS '--disable-gpu', '--disable-gpu-compositing', + // Exposes gc(), which the benchmark app calls between phases (see + // waitForIdle in smoke-tests/benchmark-app/app/run-benchmark.js), so + // the garbage of one phase is not collected inside a later one. + '--js-flags=--expose-gc', ].join(','), ]; diff --git a/smoke-tests/benchmark-app/app/run-benchmark.js b/smoke-tests/benchmark-app/app/run-benchmark.js index 23c79e915c1..5083d3b49d3 100644 --- a/smoke-tests/benchmark-app/app/run-benchmark.js +++ b/smoke-tests/benchmark-app/app/run-benchmark.js @@ -29,7 +29,16 @@ export function emitDomClickEvent(selector) { export function waitForIdle() { return new Promise((resolve) => { - requestIdleCallback(resolve); + requestIdleCallback(() => { + // Collect the previous phase's garbage outside of any measured phase. + // Chrome only exposes gc() with --js-flags=--expose-gc. + if (typeof globalThis.gc === 'function') { + globalThis.gc(); + requestIdleCallback(resolve); + } else { + resolve(); + } + }); }); }