diff --git a/benchmark/misc/trace.js b/benchmark/misc/trace.js new file mode 100644 index 00000000000000..75c87d363a6b03 --- /dev/null +++ b/benchmark/misc/trace.js @@ -0,0 +1,75 @@ +'use strict'; + +const common = require('../common.js'); + +const bench = common.createBenchmark(main, { + n: [100000], + method: ['trace', 'emit', 'isTraceCategoryEnabled', 'categoryGroupEnabled'] +}, { + flags: ['--expose-internals', '--trace-event-categories', 'foo'] +}); + +const { + trace, + isTraceCategoryEnabled, + emit, + categoryGroupEnabled +} = process.binding('trace_events'); + +const { + TRACE_EVENT_PHASE_NESTABLE_ASYNC_BEGIN: kBeforeEvent +} = process.binding('constants').trace; + +function doEmit(n) { + bench.start(); + for (var i = 0; i < n; i++) { + emit(kBeforeEvent, 'foo', 'test', 0, 'arg1', 1); + } + bench.end(n); +} + +function doTrace(n) { + bench.start(); + for (var i = 0; i < n; i++) { + trace(kBeforeEvent, 'foo', 'test', 0, 'test'); + } + bench.end(n); +} + +function doIsTraceCategoryEnabled(n) { + bench.start(); + for (var i = 0; i < n; i++) { + isTraceCategoryEnabled('foo'); + isTraceCategoryEnabled('bar'); + } + bench.end(n); +} + +function doCategoryGroupEnabled(n) { + bench.start(); + for (var i = 0; i < n; i++) { + categoryGroupEnabled('foo'); + categoryGroupEnabled('bar'); + } + bench.end(n); +} + +function main({ n, method }) { + switch (method) { + case '': + case 'trace': + doTrace(n); + break; + case 'emit': + doEmit(n); + break; + case 'isTraceCategoryEnabled': + doIsTraceCategoryEnabled(n); + break; + case 'categoryGroupEnabled': + doCategoryGroupEnabled(n); + break; + default: + throw new Error(`Unexpected method "${method}"`); + } +} diff --git a/src/node_constants.cc b/src/node_constants.cc index c1e39244b359b4..61aa42a8efb6b2 100644 --- a/src/node_constants.cc +++ b/src/node_constants.cc @@ -1282,6 +1282,35 @@ void DefineDLOpenConstants(Local target) { #endif } +void DefineTraceConstants(Local target) { + NODE_DEFINE_CONSTANT(target, TRACE_EVENT_PHASE_BEGIN); + NODE_DEFINE_CONSTANT(target, TRACE_EVENT_PHASE_END); + NODE_DEFINE_CONSTANT(target, TRACE_EVENT_PHASE_COMPLETE); + NODE_DEFINE_CONSTANT(target, TRACE_EVENT_PHASE_INSTANT); + NODE_DEFINE_CONSTANT(target, TRACE_EVENT_PHASE_ASYNC_BEGIN); + NODE_DEFINE_CONSTANT(target, TRACE_EVENT_PHASE_ASYNC_STEP_INTO); + NODE_DEFINE_CONSTANT(target, TRACE_EVENT_PHASE_ASYNC_STEP_PAST); + NODE_DEFINE_CONSTANT(target, TRACE_EVENT_PHASE_ASYNC_END); + NODE_DEFINE_CONSTANT(target, TRACE_EVENT_PHASE_NESTABLE_ASYNC_BEGIN); + NODE_DEFINE_CONSTANT(target, TRACE_EVENT_PHASE_NESTABLE_ASYNC_END); + NODE_DEFINE_CONSTANT(target, TRACE_EVENT_PHASE_NESTABLE_ASYNC_INSTANT); + NODE_DEFINE_CONSTANT(target, TRACE_EVENT_PHASE_FLOW_BEGIN); + NODE_DEFINE_CONSTANT(target, TRACE_EVENT_PHASE_FLOW_STEP); + NODE_DEFINE_CONSTANT(target, TRACE_EVENT_PHASE_FLOW_END); + NODE_DEFINE_CONSTANT(target, TRACE_EVENT_PHASE_METADATA); + NODE_DEFINE_CONSTANT(target, TRACE_EVENT_PHASE_COUNTER); + NODE_DEFINE_CONSTANT(target, TRACE_EVENT_PHASE_SAMPLE); + NODE_DEFINE_CONSTANT(target, TRACE_EVENT_PHASE_CREATE_OBJECT); + NODE_DEFINE_CONSTANT(target, TRACE_EVENT_PHASE_SNAPSHOT_OBJECT); + NODE_DEFINE_CONSTANT(target, TRACE_EVENT_PHASE_DELETE_OBJECT); + NODE_DEFINE_CONSTANT(target, TRACE_EVENT_PHASE_MEMORY_DUMP); + NODE_DEFINE_CONSTANT(target, TRACE_EVENT_PHASE_MARK); + NODE_DEFINE_CONSTANT(target, TRACE_EVENT_PHASE_CLOCK_SYNC); + NODE_DEFINE_CONSTANT(target, TRACE_EVENT_PHASE_ENTER_CONTEXT); + NODE_DEFINE_CONSTANT(target, TRACE_EVENT_PHASE_LEAVE_CONTEXT); + NODE_DEFINE_CONSTANT(target, TRACE_EVENT_PHASE_LINK_IDS); +} + } // anonymous namespace void DefineConstants(v8::Isolate* isolate, Local target) { @@ -1315,6 +1344,10 @@ void DefineConstants(v8::Isolate* isolate, Local target) { CHECK(dlopen_constants->SetPrototype(env->context(), Null(env->isolate())).FromJust()); + Local trace_constants = Object::New(isolate); + CHECK(trace_constants->SetPrototype(env->context(), + Null(env->isolate())).FromJust()); + DefineErrnoConstants(err_constants); DefineWindowsErrorConstants(err_constants); DefineSignalConstants(sig_constants); @@ -1323,6 +1356,7 @@ void DefineConstants(v8::Isolate* isolate, Local target) { DefineCryptoConstants(crypto_constants); DefineZlibConstants(zlib_constants); DefineDLOpenConstants(dlopen_constants); + DefineTraceConstants(trace_constants); // Define libuv constants. NODE_DEFINE_CONSTANT(os_constants, UV_UDP_REUSEADDR); @@ -1334,6 +1368,7 @@ void DefineConstants(v8::Isolate* isolate, Local target) { target->Set(OneByteString(isolate, "fs"), fs_constants); target->Set(OneByteString(isolate, "crypto"), crypto_constants); target->Set(OneByteString(isolate, "zlib"), zlib_constants); + target->Set(OneByteString(isolate, "trace"), trace_constants); } } // namespace node diff --git a/src/node_trace_events.cc b/src/node_trace_events.cc index 0904311dad865b..a2f42249483cd7 100644 --- a/src/node_trace_events.cc +++ b/src/node_trace_events.cc @@ -232,6 +232,19 @@ void Initialize(Local target, target->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "CategorySet"), category_set->GetFunction()); + + Local isTraceCategoryEnabled = + FIXED_ONE_BYTE_STRING(env->isolate(), "isTraceCategoryEnabled"); + Local trace = FIXED_ONE_BYTE_STRING(env->isolate(), "trace"); + + // Grab the trace and isTraceCategoryEnabled intrinsics from the binding + // object and expose those to our binding layer. + Local binding = context->GetExtrasBindingObject(); + target->Set(context, isTraceCategoryEnabled, + binding->Get(context, isTraceCategoryEnabled).ToLocalChecked()) + .FromJust(); + target->Set(context, trace, + binding->Get(context, trace).ToLocalChecked()).FromJust(); } } // namespace node diff --git a/test/parallel/test-binding-constants.js b/test/parallel/test-binding-constants.js index aaf0ebde5230a8..b8e852b3525ab8 100644 --- a/test/parallel/test-binding-constants.js +++ b/test/parallel/test-binding-constants.js @@ -5,7 +5,7 @@ const constants = process.binding('constants'); const assert = require('assert'); assert.deepStrictEqual( - Object.keys(constants).sort(), ['crypto', 'fs', 'os', 'zlib'] + Object.keys(constants).sort(), ['crypto', 'fs', 'os', 'trace', 'zlib'] ); assert.deepStrictEqual( @@ -26,6 +26,6 @@ function test(obj) { } [ - constants, constants.crypto, constants.fs, constants.os, constants.zlib, - constants.os.dlopen, constants.os.errno, constants.os.signals + constants, constants.crypto, constants.fs, constants.os, constants.trace, + constants.zlib, constants.os.dlopen, constants.os.errno, constants.os.signals ].forEach(test);