Skip to content

Commit

Permalink
perf_hooks: only enable GC tracking when it's requested
Browse files Browse the repository at this point in the history
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: nodejs#25853
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Gus Caplan <me@gus.host>
Reviewed-By: James M Snell <jasnell@gmail.com>
  • Loading branch information
joyeecheung authored and addaleax committed Feb 6, 2019
1 parent b7fb49e commit e81c6c8
Show file tree
Hide file tree
Showing 2 changed files with 14 additions and 4 deletions.
10 changes: 9 additions & 1 deletion lib/perf_hooks.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ const {
timeOrigin,
timeOriginTimestamp,
timerify,
constants
constants,
setupGarbageCollectionTracking
} = internalBinding('performance');

const {
Expand Down Expand Up @@ -275,6 +276,8 @@ class PerformanceObserverEntryList {
}
}

let gcTrackingIsEnabled = false;

class PerformanceObserver extends AsyncResource {
constructor(callback) {
if (typeof callback !== 'function') {
Expand Down Expand Up @@ -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]);
Expand Down
8 changes: 5 additions & 3 deletions src/node_perf.cc
Original file line number Diff line number Diff line change
Expand Up @@ -296,8 +296,10 @@ void MarkGarbageCollectionEnd(Isolate* isolate,
entry);
}

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

inline void SetupGarbageCollectionTracking(Environment* env) {
env->isolate()->AddGCPrologueCallback(MarkGarbageCollectionStart,
static_cast<void*>(env));
env->isolate()->AddGCEpilogueCallback(MarkGarbageCollectionEnd,
Expand Down Expand Up @@ -416,6 +418,8 @@ void Initialize(Local<Object> target,
env->SetMethod(target, "markMilestone", MarkMilestone);
env->SetMethod(target, "setupObservers", SetupPerformanceObservers);
env->SetMethod(target, "timerify", Timerify);
env->SetMethod(
target, "setupGarbageCollectionTracking", SetupGarbageCollectionTracking);

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

Expand Down Expand Up @@ -452,8 +456,6 @@ void Initialize(Local<Object> target,
env->constants_string(),
constants,
attr).ToChecked();

SetupGarbageCollectionTracking(env);
}

} // namespace performance
Expand Down

0 comments on commit e81c6c8

Please sign in to comment.