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: https://github.com/nodejs/node/pull/25853
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Gus Caplan <me@gus.host>
Reviewed-By: James M Snell <jasnell@gmail.com>
This commit is contained in:
Joyee Cheung 2019-02-01 01:04:44 +08:00 committed by Anna Henningsen
parent cc5de5a5cc
commit 475c43c1b0
No known key found for this signature in database
GPG Key ID: 9C63F3A6CD2AD8F9
2 changed files with 14 additions and 4 deletions

View File

@ -11,7 +11,8 @@ const {
timeOrigin,
timeOriginTimestamp,
timerify,
constants
constants,
setupGarbageCollectionTracking
} = internalBinding('performance');
const {
@ -273,6 +274,8 @@ class PerformanceObserverEntryList {
}
}
let gcTrackingIsEnabled = false;
class PerformanceObserver extends AsyncResource {
constructor(callback) {
if (typeof callback !== 'function') {
@ -334,6 +337,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]);

View File

@ -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,
@ -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);
@ -452,8 +456,6 @@ void Initialize(Local<Object> target,
env->constants_string(),
constants,
attr).ToChecked();
SetupGarbageCollectionTracking(env);
}
} // namespace performance