Skip to content

Commit 740bf78

Browse files
jasnellMylesBorins
authored andcommitted
vm,trace_events: add node.vm.script trace events category
Add basic trace events for node_contextify. These generally align very well with V8.ScriptCompile and V8.ScriptExecute trace events and provide good additional context. For instance, using the node.vm.script trace category at startup allows us to see exactly how long compilation and init of each of our core modules adds to the startup time. PR-URL: #20728 Reviewed-By: Anna Henningsen <[email protected]> Reviewed-By: Ali Ijaz Sheikh <[email protected]> Reviewed-By: Colin Ihrig <[email protected]>
1 parent 8f489a2 commit 740bf78

File tree

3 files changed

+80
-0
lines changed

3 files changed

+80
-0
lines changed

doc/api/tracing.md

+2
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ The available categories are:
2424
* `node.perf.timerify` - Enables capture of only Performance API timerify
2525
measurements.
2626
* `node.fs.sync` - Enables capture of trace data for file system sync methods.
27+
* `node.vm.script` - Enables capture of trace data for the `vm` module's
28+
`runInNewContext()`, `runInContext()`, and `runInThisContext()` methods.
2729
* `v8` - The [V8] events are GC, compiling, and execution related.
2830

2931
By default the `node`, `node.async_hooks`, and `v8` categories are enabled.

src/node_contextify.cc

+36
Original file line numberDiff line numberDiff line change
@@ -665,6 +665,16 @@ class ContextifyScript : public BaseObject {
665665
ContextifyScript* contextify_script =
666666
new ContextifyScript(env, args.This());
667667

668+
if (*TRACE_EVENT_API_GET_CATEGORY_GROUP_ENABLED(
669+
TRACING_CATEGORY_NODE2(vm, script)) != 0) {
670+
Utf8Value fn(isolate, filename);
671+
TRACE_EVENT_NESTABLE_ASYNC_BEGIN1(
672+
TRACING_CATEGORY_NODE2(vm, script),
673+
"ContextifyScript::New",
674+
contextify_script,
675+
"filename", TRACE_STR_COPY(*fn));
676+
}
677+
668678
ScriptCompiler::CachedData* cached_data = nullptr;
669679
if (!cached_data_buf.IsEmpty()) {
670680
ArrayBuffer::Contents contents = cached_data_buf->Buffer()->GetContents();
@@ -694,6 +704,10 @@ class ContextifyScript : public BaseObject {
694704
DecorateErrorStack(env, try_catch);
695705
no_abort_scope.Close();
696706
try_catch.ReThrow();
707+
TRACE_EVENT_NESTABLE_ASYNC_END0(
708+
TRACING_CATEGORY_NODE2(vm, script),
709+
"ContextifyScript::New",
710+
contextify_script);
697711
return;
698712
}
699713
contextify_script->script_.Reset(isolate, v8_script.ToLocalChecked());
@@ -717,6 +731,10 @@ class ContextifyScript : public BaseObject {
717731
env->cached_data_produced_string(),
718732
Boolean::New(isolate, cached_data_produced));
719733
}
734+
TRACE_EVENT_NESTABLE_ASYNC_END0(
735+
TRACING_CATEGORY_NODE2(vm, script),
736+
"ContextifyScript::New",
737+
contextify_script);
720738
}
721739

722740

@@ -729,6 +747,12 @@ class ContextifyScript : public BaseObject {
729747
static void RunInThisContext(const FunctionCallbackInfo<Value>& args) {
730748
Environment* env = Environment::GetCurrent(args);
731749

750+
ContextifyScript* wrapped_script;
751+
ASSIGN_OR_RETURN_UNWRAP(&wrapped_script, args.Holder());
752+
753+
TRACE_EVENT_NESTABLE_ASYNC_BEGIN0(
754+
TRACING_CATEGORY_NODE2(vm, script), "RunInThisContext", wrapped_script);
755+
732756
CHECK_EQ(args.Length(), 3);
733757

734758
CHECK(args[0]->IsNumber());
@@ -742,11 +766,17 @@ class ContextifyScript : public BaseObject {
742766

743767
// Do the eval within this context
744768
EvalMachine(env, timeout, display_errors, break_on_sigint, args);
769+
770+
TRACE_EVENT_NESTABLE_ASYNC_END0(
771+
TRACING_CATEGORY_NODE2(vm, script), "RunInThisContext", wrapped_script);
745772
}
746773

747774
static void RunInContext(const FunctionCallbackInfo<Value>& args) {
748775
Environment* env = Environment::GetCurrent(args);
749776

777+
ContextifyScript* wrapped_script;
778+
ASSIGN_OR_RETURN_UNWRAP(&wrapped_script, args.Holder());
779+
750780
CHECK_EQ(args.Length(), 4);
751781

752782
CHECK(args[0]->IsObject());
@@ -759,6 +789,9 @@ class ContextifyScript : public BaseObject {
759789
if (contextify_context->context().IsEmpty())
760790
return;
761791

792+
TRACE_EVENT_NESTABLE_ASYNC_BEGIN0(
793+
TRACING_CATEGORY_NODE2(vm, script), "RunInContext", wrapped_script);
794+
762795
CHECK(args[1]->IsNumber());
763796
int64_t timeout = args[1]->IntegerValue(env->context()).FromJust();
764797

@@ -775,6 +808,9 @@ class ContextifyScript : public BaseObject {
775808
display_errors,
776809
break_on_sigint,
777810
args);
811+
812+
TRACE_EVENT_NESTABLE_ASYNC_END0(
813+
TRACING_CATEGORY_NODE2(vm, script), "RunInContext", wrapped_script);
778814
}
779815

780816
static void DecorateErrorStack(Environment* env, const TryCatch& try_catch) {

test/parallel/test-trace-events-vm.js

+42
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
'use strict';
2+
const common = require('../common');
3+
const assert = require('assert');
4+
const cp = require('child_process');
5+
const path = require('path');
6+
const fs = require('fs');
7+
const tmpdir = require('../common/tmpdir');
8+
9+
const names = [
10+
'ContextifyScript::New',
11+
'RunInThisContext',
12+
'RunInContext'
13+
];
14+
15+
if (process.argv[2] === 'child') {
16+
const vm = require('vm');
17+
vm.runInNewContext('1 + 1');
18+
} else {
19+
tmpdir.refresh();
20+
process.chdir(tmpdir.path);
21+
22+
const proc = cp.fork(__filename,
23+
[ 'child' ], {
24+
execArgv: [
25+
'--trace-event-categories',
26+
'node.vm.script'
27+
]
28+
});
29+
30+
proc.once('exit', common.mustCall(() => {
31+
const file = path.join(tmpdir.path, 'node_trace.1.log');
32+
33+
assert(common.fileExists(file));
34+
fs.readFile(file, common.mustCall((err, data) => {
35+
const traces = JSON.parse(data.toString()).traceEvents;
36+
traces.forEach((trace) => {
37+
assert.strictEqual(trace.pid, proc.pid);
38+
assert(names.includes(trace.name));
39+
});
40+
}));
41+
}));
42+
}

0 commit comments

Comments
 (0)