Skip to content
Open
Show file tree
Hide file tree
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
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -1572,7 +1572,7 @@ LINT_CPP_EXCLUDE ?=
LINT_CPP_EXCLUDE += src/node_root_certs.h
LINT_CPP_EXCLUDE += $(LINT_CPP_ADDON_DOC_FILES)
# These files were copied more or less verbatim from V8.
LINT_CPP_EXCLUDE += src/tracing/trace_event.h src/tracing/trace_event_common.h
LINT_CPP_EXCLUDE += src/tracing/trace_event_legacy.h src/tracing/trace_event_legacy_inl.h

# deps/ncrypto is included in this list, as it is maintained in
# this repository, and should be linted. Eventually it should move
Expand Down
2 changes: 1 addition & 1 deletion common.gypi
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@
'v8_enable_external_code_space%': 0,
'v8_enable_sandbox%': 0,
'v8_enable_v8_checks%': 0,
'v8_use_perfetto': 0,
'v8_use_perfetto%': 0,
'tsan%': 0,

##### end V8 defaults #####
Expand Down
7 changes: 7 additions & 0 deletions configure.py
Original file line number Diff line number Diff line change
Expand Up @@ -1123,6 +1123,12 @@
default=None,
help='disable the V8 inspector protocol')

parser.add_argument('--with-perfetto',
action='store_true',
dest='with_perfetto',
default=None,
help='enable perfetto support')

parser.add_argument('--shared',
action='store_true',
dest='shared',
Expand Down Expand Up @@ -2223,6 +2229,7 @@ def configure_v8(o, configs):
options.v8_disable_temporal_support = True
o['variables']['v8_enable_temporal_support'] = 0 if options.v8_disable_temporal_support else 1
o['variables']['v8_trace_maps'] = 1 if options.trace_maps else 0
o['variables']['v8_use_perfetto'] = 1 if options.with_perfetto else 0
o['variables']['node_use_v8_platform'] = b(not options.without_v8_platform)
o['variables']['node_use_bundled_v8'] = b(not options.without_bundled_v8)
o['variables']['force_dynamic_crt'] = 1 if options.shared else 0
Expand Down
7 changes: 2 additions & 5 deletions lib/internal/console/constructor.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ const {
SymbolToStringTag,
} = primordials;

const { trace } = internalBinding('trace_events');
const { trace, nodeTraceEventCategory, kTraceCount } = require('internal/trace_events');
const {
codes: {
ERR_CONSOLE_WRITABLE_STREAM,
Expand All @@ -59,9 +59,6 @@ const {
const {
isTypedArray, isSet, isMap, isSetIterator, isMapIterator,
} = require('internal/util/types');
const {
CHAR_UPPERCASE_C: kTraceCount,
} = require('internal/constants');
const kCounts = Symbol('counts');
const { time, timeLog, timeEnd, kNone } = require('internal/util/debuglog');
const { channel } = require('diagnostics_channel');
Expand All @@ -72,7 +69,7 @@ const onError = channel('console.error');
const onInfo = channel('console.info');
const onDebug = channel('console.debug');

const kTraceConsoleCategory = 'node,node.console';
const kTraceConsoleCategory = nodeTraceEventCategory('node.console');

const kMaxGroupIndentation = 1000;

Expand Down
2 changes: 2 additions & 0 deletions lib/internal/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@ module.exports = {
CHAR_UPPERCASE_Z: 90, /* Z */
CHAR_LOWERCASE_Z: 122, /* z */
CHAR_UPPERCASE_C: 67, /* C */
CHAR_UPPERCASE_B: 66, /* B */
CHAR_LOWERCASE_B: 98, /* b */
CHAR_UPPERCASE_E: 69, /* E */
CHAR_LOWERCASE_E: 101, /* e */
CHAR_LOWERCASE_N: 110, /* n */

Expand Down
16 changes: 9 additions & 7 deletions lib/internal/http.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,13 @@ const {
} = primordials;

const { setUnrefTimeout } = require('internal/timers');
const { getCategoryEnabledBuffer, trace } = internalBinding('trace_events');
const {
CHAR_LOWERCASE_B,
CHAR_LOWERCASE_E,
} = require('internal/constants');
getCategoryEnabledBuffer,
trace,
nodeTraceEventCategory,
kAsyncBegin,
kAsyncEnd,
} = require('internal/trace_events');

const { URL } = require('internal/url');
const { Buffer } = require('buffer');
Expand Down Expand Up @@ -48,14 +50,14 @@ function isTraceHTTPEnabled() {
return httpEnabled[0] > 0;
}

const traceEventCategory = 'node,node.http';
const traceEventCategory = nodeTraceEventCategory('node.http');

function traceBegin(...args) {
trace(CHAR_LOWERCASE_B, traceEventCategory, ...args);
trace(kAsyncBegin, traceEventCategory, ...args);
}

function traceEnd(...args) {
trace(CHAR_LOWERCASE_E, traceEventCategory, ...args);
trace(kAsyncEnd, traceEventCategory, ...args);
}

function ipToInt(ip) {
Expand Down
56 changes: 56 additions & 0 deletions lib/internal/trace_events.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
'use strict';

const { getCategoryEnabledBuffer, trace, usePerfetto } = internalBinding('trace_events');
const {
CHAR_UPPERCASE_B,
CHAR_LOWERCASE_B,
CHAR_UPPERCASE_C,
CHAR_LOWERCASE_E,
CHAR_UPPERCASE_E,
CHAR_LOWERCASE_N,
} = require('internal/constants');

let nodeTraceEventCategory;
if (usePerfetto) {
nodeTraceEventCategory = (category) => `${category}`;
} else {
nodeTraceEventCategory = (category) => `node,${category}`;
}

// The async events describe the execution of a single asynchronous operation, and are
// used to measure the time spent in a single asynchronous operation.
// Async events may overlap with each other. Different events do not have
// to be nested, or FILO (first in last out).
// TODO(legendecas): V8 `trace` API does not support async marks in perfetto yet.
const kAsyncBegin = usePerfetto ? CHAR_UPPERCASE_B : CHAR_LOWERCASE_B;
const kAsyncEnd = usePerfetto ? CHAR_UPPERCASE_E : CHAR_LOWERCASE_E;

// The sync events describe the execution of a single thread, and are
// used to measure the time spent in a function.
// Sync events must be nested, and are FILO (first in last out), in a stack
// manner.
const kSyncBegin = CHAR_UPPERCASE_B;
const kSyncEnd = CHAR_UPPERCASE_E;

// Counter events track a named numeric value as it changes over time. Each
// event records the value at a point in time, and the trace viewer renders the
// series as a graph.
// TODO(legendecas): V8 `trace` API does not support count marks in perfetto yet.
const kTraceCount = usePerfetto ? CHAR_LOWERCASE_N : CHAR_UPPERCASE_C;

// Instant events mark a single moment in time. They have no duration and do
// not need to be paired or nested.
const kTraceInstant = CHAR_LOWERCASE_N;

module.exports = {
usePerfetto,
getCategoryEnabledBuffer,
trace,
nodeTraceEventCategory,
kAsyncBegin,
kAsyncEnd,
kSyncBegin,
kSyncEnd,
kTraceCount,
kTraceInstant,
};
28 changes: 13 additions & 15 deletions lib/internal/trace_events_async_hooks.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,20 +7,18 @@ const {
Symbol,
} = primordials;

const { trace } = internalBinding('trace_events');
const {
trace,
nodeTraceEventCategory,
kAsyncBegin,
kAsyncEnd,
kSyncBegin,
kSyncEnd,
} = require('internal/trace_events');
const async_wrap = internalBinding('async_wrap');
const async_hooks = require('async_hooks');
const {
CHAR_LOWERCASE_B,
CHAR_LOWERCASE_E,
} = require('internal/constants');

// Use small letters such that chrome://tracing groups by the name.
// The behavior is not only useful but the same as the events emitted using
// the specific C++ macros.
const kBeforeEvent = CHAR_LOWERCASE_B;
const kEndEvent = CHAR_LOWERCASE_E;
const kTraceEventCategory = 'node,node.async_hooks';
const kTraceEventCategory = nodeTraceEventCategory('node.async_hooks');

const kEnabled = Symbol('enabled');

Expand All @@ -45,7 +43,7 @@ function createHook() {
if (nativeProviders.has(type)) return;

typeMemory.set(asyncId, type);
trace(kBeforeEvent, kTraceEventCategory,
trace(kAsyncBegin, kTraceEventCategory,
type, asyncId,
{
triggerAsyncId,
Expand All @@ -57,21 +55,21 @@ function createHook() {
const type = typeMemory.get(asyncId);
if (type === undefined) return;

trace(kBeforeEvent, kTraceEventCategory, `${type}_CALLBACK`, asyncId);
trace(kSyncBegin, kTraceEventCategory, `${type}_CALLBACK`, asyncId);
},

after(asyncId) {
const type = typeMemory.get(asyncId);
if (type === undefined) return;

trace(kEndEvent, kTraceEventCategory, `${type}_CALLBACK`, asyncId);
trace(kSyncEnd, kTraceEventCategory, `${type}_CALLBACK`, asyncId);
},

destroy(asyncId) {
const type = typeMemory.get(asyncId);
if (type === undefined) return;

trace(kEndEvent, kTraceEventCategory, type, asyncId);
trace(kAsyncEnd, kTraceEventCategory, type, asyncId);

// Cleanup asyncId to type map
typeMemory.delete(asyncId);
Expand Down
20 changes: 11 additions & 9 deletions lib/internal/util/debuglog.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,15 @@ const {
StringPrototypeToLowerCase,
StringPrototypeToUpperCase,
} = primordials;
const {
CHAR_LOWERCASE_B: kTraceBegin,
CHAR_LOWERCASE_E: kTraceEnd,
CHAR_LOWERCASE_N: kTraceInstant,
} = require('internal/constants');
const { inspect, format, formatWithOptions } = require('internal/util/inspect');
const { getCategoryEnabledBuffer, trace } = internalBinding('trace_events');
const {
getCategoryEnabledBuffer,
trace,
nodeTraceEventCategory,
kAsyncBegin,
kAsyncEnd,
kTraceInstant,
} = require('internal/trace_events');

// `debugImpls` and `testEnabled` are deliberately not initialized so any call
// to `debuglog()` before `initializeDebugEnv()` is called will throw.
Expand Down Expand Up @@ -246,7 +248,7 @@ function time(timesStore, traceCategory, implementation, timerFlags, logLabel =

if ((timerFlags & kSkipTrace) === 0) {
traceLabel = safeTraceLabel(traceLabel);
trace(kTraceBegin, traceCategory, traceLabel, 0);
trace(kAsyncBegin, traceCategory, traceLabel, 0);
}

timesStore.set(logLabel, process.hrtime());
Expand Down Expand Up @@ -286,7 +288,7 @@ function timeEnd(

if ((timerFlags & kSkipTrace) === 0) {
traceLabel = safeTraceLabel(traceLabel);
trace(kTraceEnd, traceCategory, traceLabel, 0);
trace(kAsyncEnd, traceCategory, traceLabel, 0);
}

timesStore.delete(logLabel);
Expand Down Expand Up @@ -385,7 +387,7 @@ function debugWithTimer(set, cb) {
);
}

const traceCategory = `node,node.${StringPrototypeToLowerCase(set)}`;
const traceCategory = nodeTraceEventCategory(`node.${StringPrototypeToLowerCase(set)}`);
let traceCategoryBuffer;
let debugLogCategoryEnabled = false;
let timerFlags = kNone;
Expand Down
48 changes: 40 additions & 8 deletions node.gyp
Original file line number Diff line number Diff line change
Expand Up @@ -200,10 +200,7 @@
'src/timers.cc',
'src/timer_wrap.cc',
'src/tracing/agent.cc',
'src/tracing/agent_legacy.cc',
'src/tracing/node_trace_buffer.cc',
'src/tracing/node_trace_writer.cc',
'src/tracing/trace_event.cc',
'src/tracing/trace_event_helper.cc',
'src/tracing/traced_value.cc',
'src/tty_wrap.cc',
'src/udp_wrap.cc',
Expand Down Expand Up @@ -339,11 +336,8 @@
'src/tcp_wrap.h',
'src/timers.h',
'src/tracing/agent.h',
'src/tracing/agent_legacy.h',
'src/tracing/node_trace_buffer.h',
'src/tracing/node_trace_writer.h',
'src/tracing/trace_event_helper.h',
'src/tracing/trace_event.h',
'src/tracing/trace_event_common.h',
'src/tracing/traced_value.h',
'src/timer_wrap.h',
'src/timer_wrap-inl.h',
Expand Down Expand Up @@ -460,6 +454,22 @@
'src/node_crypto.cc',
'src/node_crypto.h',
],
'node_tracing_perfetto_sources': [
'src/tracing/agent_perfetto.cc',
'src/tracing/agent_perfetto.h',
'src/tracing/trace_event_perfetto.cc',
'src/tracing/trace_event_perfetto.h',
],
'node_tracing_legacy_sources': [
'src/tracing/agent_legacy.cc',
'src/tracing/agent_legacy.h',
'src/tracing/node_trace_buffer.cc',
'src/tracing/node_trace_buffer.h',
'src/tracing/node_trace_writer.cc',
'src/tracing/node_trace_writer.h',
'src/tracing/trace_event_legacy_inl.h',
'src/tracing/trace_event_legacy.h',
],
'node_cctest_openssl_sources': [
'test/cctest/test_crypto_clienthello.cc',
'test/cctest/test_node_crypto.cc',
Expand Down Expand Up @@ -963,6 +973,18 @@
}],
],
}],
[ 'v8_use_perfetto==1', {
'sources': [
'<@(node_tracing_perfetto_sources)',
],
'dependencies': [
'deps/perfetto/perfetto.gyp:perfetto_sdk',
],
}, {
'sources': [
'<@(node_tracing_legacy_sources)',
],
}],
[ 'v8_enable_inspector==1', {
'includes' : [ 'src/inspector/node_inspector.gypi' ],
}, {
Expand Down Expand Up @@ -1462,6 +1484,11 @@
}, {
'sources!': [ '<@(node_cctest_quic_sources)' ],
}],
[ 'v8_use_perfetto==1', {
'dependencies': [
'deps/perfetto/perfetto.gyp:perfetto_sdk',
],
}],
['v8_enable_inspector==1', {
'defines': [
'HAVE_INSPECTOR=1',
Expand Down Expand Up @@ -1783,6 +1810,11 @@
'NODE_USE_NODE_CODE_CACHE=1',
],
}],
[ 'v8_use_perfetto==1', {
'dependencies': [
'deps/perfetto/perfetto.gyp:perfetto_sdk',
],
}],
['v8_enable_inspector==1', {
'defines': [
'HAVE_INSPECTOR=1',
Expand Down
Loading
Loading