Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 33 additions & 2 deletions bindings/profiler.cc
Original file line number Diff line number Diff line change
Expand Up @@ -96,8 +96,14 @@ NAN_METHOD(GetAllocationProfile) {
}

// Time profiler

#if NODE_MODULE_VERSION > NODE_8_0_MODULE_VERSION
#if NODE_MODULE_VERSION >= NODE_12_0_MODULE_VERSION
// For Node 12 and Node 14, a new CPU profiler object will be created each
// time profiling is started to work around
// https://bugs.chromium.org/p/v8/issues/detail?id=11051.
CpuProfiler* cpuProfiler;
// Default sampling interval is 1000us.
int samplingIntervalUS = 1000;
#elif NODE_MODULE_VERSION > NODE_8_0_MODULE_VERSION
// This profiler exists for the lifetime of the program. Not calling
// CpuProfiler::Dispose() is intentional.
CpuProfiler* cpuProfiler = CpuProfiler::New(v8::Isolate::GetCurrent());
Expand Down Expand Up @@ -264,6 +270,17 @@ NAN_METHOD(StartProfiling) {
return Nan::ThrowTypeError("Second argument must be a boolean.");
}

#if NODE_MODULE_VERSION >= NODE_12_0_MODULE_VERSION
// Since the CPU profiler is created and destroyed each time a CPU
// profile is collected, there cannot be multiple CPU profiling requests
// inflight in parallel.
if (cpuProfiler) {
return Nan::ThrowError("CPU profiler is already started.");
}
cpuProfiler = CpuProfiler::New(v8::Isolate::GetCurrent());
cpuProfiler->SetSamplingInterval(samplingIntervalUS);
#endif

Local<String> name =
Nan::MaybeLocal<String>(info[0].As<String>()).ToLocalChecked();

Expand All @@ -289,6 +306,11 @@ NAN_METHOD(StartProfiling) {
// Signature:
// stopProfiling(runName: string, includeLineInfo: boolean): TimeProfile
NAN_METHOD(StopProfiling) {
#if NODE_MODULE_VERSION >= NODE_12_0_MODULE_VERSION
if (!cpuProfiler) {
return Nan::ThrowError("StopProfiling called without an active CPU profiler.");
}
#endif
if (info.Length() != 2) {
return Nan::ThrowTypeError("StopProfling must have two arguments.");
}
Expand All @@ -307,6 +329,11 @@ NAN_METHOD(StopProfiling) {
Local<Value> translated_profile =
TranslateTimeProfile(profile, includeLineInfo);
profile->Delete();
#if NODE_MODULE_VERSION >= NODE_12_0_MODULE_VERSION
// Dispose of CPU profiler to work around memory leak.
cpuProfiler->Dispose();
cpuProfiler = NULL;
#endif
info.GetReturnValue().Set(translated_profile);
}

Expand All @@ -318,7 +345,11 @@ NAN_METHOD(SetSamplingInterval) {
#else
int us = info[0].As<Integer>()->IntegerValue();
#endif
#if NODE_MODULE_VERSION >= NODE_12_0_MODULE_VERSION
samplingIntervalUS = us;
#else
cpuProfiler->SetSamplingInterval(us);
#endif
}

NAN_MODULE_INIT(InitAll) {
Expand Down