Skip to content

Commit 475c43c

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 cc5de5a commit 475c43c

File tree

2 files changed

+14
-4
lines changed

2 files changed

+14
-4
lines changed

lib/perf_hooks.js

Lines changed: 9 additions & 1 deletion
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 {
@@ -273,6 +274,8 @@ class PerformanceObserverEntryList {
273274
}
274275
}
275276

277+
let gcTrackingIsEnabled = false;
278+
276279
class PerformanceObserver extends AsyncResource {
277280
constructor(callback) {
278281
if (typeof callback !== 'function') {
@@ -334,6 +337,11 @@ class PerformanceObserver extends AsyncResource {
334337
if (entryTypes.length === 0) {
335338
throw new errors.ERR_VALID_PERFORMANCE_ENTRY_TYPE();
336339
}
340+
if (entryTypes.includes(NODE_PERFORMANCE_ENTRY_TYPE_GC) &&
341+
!gcTrackingIsEnabled) {
342+
setupGarbageCollectionTracking();
343+
gcTrackingIsEnabled = true;
344+
}
337345
this.disconnect();
338346
this[kBuffer][kEntries] = [];
339347
L.init(this[kBuffer][kEntries]);

src/node_perf.cc

Lines changed: 5 additions & 3 deletions
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)