diff --git a/lib/perf_hooks.js b/lib/perf_hooks.js index 5862e35d738058..041bbf68f2f6c4 100644 --- a/lib/perf_hooks.js +++ b/lib/perf_hooks.js @@ -11,7 +11,8 @@ const { timeOrigin, timeOriginTimestamp, timerify, - constants + constants, + setupGarbageCollectionTracking } = internalBinding('performance'); const { @@ -275,6 +276,8 @@ class PerformanceObserverEntryList { } } +let gcTrackingIsEnabled = false; + class PerformanceObserver extends AsyncResource { constructor(callback) { if (typeof callback !== 'function') { @@ -336,6 +339,11 @@ class PerformanceObserver extends AsyncResource { if (entryTypes.length === 0) { throw new errors.ERR_VALID_PERFORMANCE_ENTRY_TYPE(); } + if (entryTypes.includes(NODE_PERFORMANCE_ENTRY_TYPE_GC) && + !gcTrackingIsEnabled) { + setupGarbageCollectionTracking(); + gcTrackingIsEnabled = true; + } this.disconnect(); this[kBuffer][kEntries] = []; L.init(this[kBuffer][kEntries]); diff --git a/src/node_perf.cc b/src/node_perf.cc index cefd0ff26dbf95..33dd1d2051872c 100644 --- a/src/node_perf.cc +++ b/src/node_perf.cc @@ -296,8 +296,10 @@ void MarkGarbageCollectionEnd(Isolate* isolate, entry); } +static void SetupGarbageCollectionTracking( + const FunctionCallbackInfo& args) { + Environment* env = Environment::GetCurrent(args); -inline void SetupGarbageCollectionTracking(Environment* env) { env->isolate()->AddGCPrologueCallback(MarkGarbageCollectionStart, static_cast(env)); env->isolate()->AddGCEpilogueCallback(MarkGarbageCollectionEnd, @@ -416,6 +418,8 @@ void Initialize(Local target, env->SetMethod(target, "markMilestone", MarkMilestone); env->SetMethod(target, "setupObservers", SetupPerformanceObservers); env->SetMethod(target, "timerify", Timerify); + env->SetMethod( + target, "setupGarbageCollectionTracking", SetupGarbageCollectionTracking); Local constants = Object::New(isolate); @@ -452,8 +456,6 @@ void Initialize(Local target, env->constants_string(), constants, attr).ToChecked(); - - SetupGarbageCollectionTracking(env); } } // namespace performance