node/test/parallel/test-performance-gc.js
Attila Szegedi 5075bb4e1f
perf_hooks: add NODE_PERFORMANCE_GC_MINOR_MARK_SWEEP constant
V8's Minor Mark-Sweep collector, enabled with the --minor-ms flag
(available since Node.js 22), reports garbage collection performance
entries with kind kGCTypeMinorMarkSweep (value 2). perf_hooks exposed
constants for every other GC kind (major, minor, incremental, weakcb)
but not this one, so consumers inspecting performanceEntry.detail.kind
had no constant to compare against and saw an unmapped value.

Expose it as perf_hooks.constants.NODE_PERFORMANCE_GC_MINOR_MARK_SWEEP,
mirroring the existing v8::GCType mappings, and document it alongside
the other GC kinds.

Signed-off-by: Attila Szegedi <attila.szegedi@datadoghq.com>
PR-URL: https://github.com/nodejs/node/pull/63877
Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de>
Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com>
Reviewed-By: Ilyas Shabi <ilyasshabi94@gmail.com>
Reviewed-By: Chengzhong Wu <legendecas@gmail.com>
2026-06-23 15:24:08 +00:00

56 lines
1.6 KiB
JavaScript

// Flags: --expose-gc --no-warnings
'use strict';
const common = require('../common');
const assert = require('assert');
const {
PerformanceObserver,
constants
} = require('perf_hooks');
const {
NODE_PERFORMANCE_GC_MAJOR,
NODE_PERFORMANCE_GC_MINOR,
NODE_PERFORMANCE_GC_MINOR_MARK_SWEEP,
NODE_PERFORMANCE_GC_INCREMENTAL,
NODE_PERFORMANCE_GC_WEAKCB,
NODE_PERFORMANCE_GC_FLAGS_FORCED
} = constants;
const kinds = [
NODE_PERFORMANCE_GC_MAJOR,
NODE_PERFORMANCE_GC_MINOR,
NODE_PERFORMANCE_GC_MINOR_MARK_SWEEP,
NODE_PERFORMANCE_GC_INCREMENTAL,
NODE_PERFORMANCE_GC_WEAKCB,
];
// Adding an observer should force at least one gc to appear
{
const obs = new PerformanceObserver(common.mustCallAtLeast((list) => {
const entry = list.getEntries()[0];
assert(entry);
assert.strictEqual(entry.name, 'gc');
assert.strictEqual(entry.entryType, 'gc');
assert(kinds.includes(entry.detail.kind));
assert.strictEqual(entry.detail.flags, NODE_PERFORMANCE_GC_FLAGS_FORCED);
assert.strictEqual(typeof entry.startTime, 'number');
assert(entry.startTime < 1e4, 'startTime should be relative to performance.timeOrigin.');
assert.strictEqual(typeof entry.duration, 'number');
obs.disconnect();
}));
obs.observe({ entryTypes: ['gc'] });
globalThis.gc();
// Keep the event loop alive to witness the GC async callback happen.
setImmediate(() => setImmediate(() => 0));
}
// GC should not keep the event loop alive
{
let didCall = false;
process.on('beforeExit', common.mustCall(() => {
assert(!didCall);
didCall = true;
globalThis.gc();
}));
}