Skip to content

Commit e81c6c8

Browse files
joyeecheungaddaleax
authored andcommitted
perf_hooks: only enable GC tracking when it's requested
Previously a GC prologue callback and a GC epilogue callback are always unconditionally enabled during bootstrap when the `performance` binding is loaded, even when the user does not use the performance timeline API to enable GC tracking. This patch makes the callback addition conditional and only enables them when the user explicitly requests `observer.observe(['gc'])` to avoid the overhead. PR-URL: #25853 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Gus Caplan <me@gus.host> Reviewed-By: James M Snell <jasnell@gmail.com>
1 parent b7fb49e commit e81c6c8

File tree

2 files changed

+14
-4
lines changed

2 files changed

+14
-4
lines changed

lib/perf_hooks.js

+9-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,8 @@ const {
1111
timeOrigin,
1212
timeOriginTimestamp,
1313
timerify,
14-
constants
14+
constants,
15+
setupGarbageCollectionTracking
1516
} = internalBinding('performance');
1617

1718
const {
@@ -275,6 +276,8 @@ class PerformanceObserverEntryList {
275276
}
276277
}
277278

279+
let gcTrackingIsEnabled = false;
280+
278281
class PerformanceObserver extends AsyncResource {
279282
constructor(callback) {
280283
if (typeof callback !== 'function') {
@@ -336,6 +339,11 @@ class PerformanceObserver extends AsyncResource {
336339
if (entryTypes.length === 0) {
337340
throw new errors.ERR_VALID_PERFORMANCE_ENTRY_TYPE();
338341
}
342+
if (entryTypes.includes(NODE_PERFORMANCE_ENTRY_TYPE_GC) &&
343+
!gcTrackingIsEnabled) {
344+
setupGarbageCollectionTracking();
345+
gcTrackingIsEnabled = true;
346+
}
339347
this.disconnect();
340348
this[kBuffer][kEntries] = [];
341349
L.init(this[kBuffer][kEntries]);

src/node_perf.cc

+5-3
Original file line numberDiff line numberDiff line change
@@ -296,8 +296,10 @@ void MarkGarbageCollectionEnd(Isolate* isolate,
296296
entry);
297297
}
298298

299+
static void SetupGarbageCollectionTracking(
300+
const FunctionCallbackInfo<Value>& args) {
301+
Environment* env = Environment::GetCurrent(args);
299302

300-
inline void SetupGarbageCollectionTracking(Environment* env) {
301303
env->isolate()->AddGCPrologueCallback(MarkGarbageCollectionStart,
302304
static_cast<void*>(env));
303305
env->isolate()->AddGCEpilogueCallback(MarkGarbageCollectionEnd,
@@ -416,6 +418,8 @@ void Initialize(Local<Object> target,
416418
env->SetMethod(target, "markMilestone", MarkMilestone);
417419
env->SetMethod(target, "setupObservers", SetupPerformanceObservers);
418420
env->SetMethod(target, "timerify", Timerify);
421+
env->SetMethod(
422+
target, "setupGarbageCollectionTracking", SetupGarbageCollectionTracking);
419423

420424
Local<Object> constants = Object::New(isolate);
421425

@@ -452,8 +456,6 @@ void Initialize(Local<Object> target,
452456
env->constants_string(),
453457
constants,
454458
attr).ToChecked();
455-
456-
SetupGarbageCollectionTracking(env);
457459
}
458460

459461
} // namespace performance

0 commit comments

Comments
 (0)