Skip to content

Commit 8ac5d77

Browse files
IlyasShabisxa
authored andcommitted
src: split profiling helpers from util
Signed-off-by: ishabi <ilyasshabi94@gmail.com> PR-URL: #63008 Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com> Reviewed-By: Anna Henningsen <anna@addaleax.net> Signed-off-by: Stewart X Addison <sxa@ibm.com>
1 parent 2551abd commit 8ac5d77

7 files changed

Lines changed: 194 additions & 1 deletion

File tree

node.gyp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,7 @@
135135
'src/node_os.cc',
136136
'src/node_perf.cc',
137137
'src/node_platform.cc',
138+
'src/node_profiling.cc',
138139
'src/node_postmortem_metadata.cc',
139140
'src/node_process_events.cc',
140141
'src/node_process_methods.cc',
@@ -275,6 +276,7 @@
275276
'src/node_perf.h',
276277
'src/node_perf_common.h',
277278
'src/node_platform.h',
279+
'src/node_profiling.h',
278280
'src/node_process.h',
279281
'src/node_process-inl.h',
280282
'src/node_realm.h',

src/env.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
#include "node_main_instance.h"
4343
#include "node_options.h"
4444
#include "node_perf_common.h"
45+
#include "node_profiling.h"
4546
#include "node_realm.h"
4647
#include "node_snapshotable.h"
4748
#include "permission/permission.h"

src/node_profiling.cc

Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
// Copyright Joyent, Inc. and other Node contributors.
2+
//
3+
// Permission is hereby granted, free of charge, to any person obtaining a
4+
// copy of this software and associated documentation files (the
5+
// "Software"), to deal in the Software without restriction, including
6+
// without limitation the rights to use, copy, modify, merge, publish,
7+
// distribute, sublicense, and/or sell copies of the Software, and to permit
8+
// persons to whom the Software is furnished to do so, subject to the
9+
// following conditions:
10+
//
11+
// The above copyright notice and this permission notice shall be included
12+
// in all copies or substantial portions of the Software.
13+
//
14+
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15+
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16+
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
17+
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
18+
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
19+
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
20+
// USE OR OTHER DEALINGS IN THE SOFTWARE.
21+
22+
#include "node_profiling.h"
23+
24+
#include "json_utils.h"
25+
#include "util.h"
26+
27+
#include <memory>
28+
29+
namespace node {
30+
31+
using v8::AllocationProfile;
32+
using v8::HandleScope;
33+
using v8::HeapProfiler;
34+
using v8::Isolate;
35+
using v8::Value;
36+
37+
static void BuildHeapProfileNode(Isolate* isolate,
38+
const AllocationProfile::Node* node,
39+
JSONWriter* writer) {
40+
size_t selfSize = 0;
41+
for (const auto& allocation : node->allocations)
42+
selfSize += allocation.size * allocation.count;
43+
44+
writer->json_keyvalue("selfSize", selfSize);
45+
writer->json_keyvalue("id", node->node_id);
46+
writer->json_objectstart("callFrame");
47+
writer->json_keyvalue("scriptId", node->script_id);
48+
writer->json_keyvalue("lineNumber", node->line_number - 1);
49+
writer->json_keyvalue("columnNumber", node->column_number - 1);
50+
Utf8Value name(isolate, node->name);
51+
Utf8Value script_name(isolate, node->script_name);
52+
writer->json_keyvalue("functionName", *name);
53+
writer->json_keyvalue("url", *script_name);
54+
writer->json_objectend();
55+
56+
writer->json_arraystart("children");
57+
for (const auto* child : node->children) {
58+
writer->json_start();
59+
BuildHeapProfileNode(isolate, child, writer);
60+
writer->json_end();
61+
}
62+
writer->json_arrayend();
63+
}
64+
65+
bool SerializeHeapProfile(Isolate* isolate, std::ostringstream& out_stream) {
66+
HandleScope scope(isolate);
67+
HeapProfiler* profiler = isolate->GetHeapProfiler();
68+
std::unique_ptr<AllocationProfile> profile(profiler->GetAllocationProfile());
69+
if (!profile) {
70+
return false;
71+
}
72+
profiler->StopSamplingHeapProfiler();
73+
JSONWriter writer(out_stream, true);
74+
writer.json_start();
75+
76+
writer.json_arraystart("samples");
77+
for (const auto& sample : profile->GetSamples()) {
78+
writer.json_start();
79+
writer.json_keyvalue("size", sample.size * sample.count);
80+
writer.json_keyvalue("nodeId", sample.node_id);
81+
writer.json_keyvalue("ordinal", static_cast<double>(sample.sample_id));
82+
writer.json_end();
83+
}
84+
writer.json_arrayend();
85+
86+
writer.json_objectstart("head");
87+
BuildHeapProfileNode(isolate, profile->GetRootNode(), &writer);
88+
writer.json_objectend();
89+
90+
writer.json_end();
91+
return true;
92+
}
93+
94+
HeapProfileOptions ParseHeapProfileOptions(
95+
const v8::FunctionCallbackInfo<Value>& args) {
96+
HeapProfileOptions options;
97+
CHECK_LE(args.Length(), 3);
98+
if (args.Length() > 0) {
99+
CHECK(args[0]->IsNumber());
100+
options.sample_interval =
101+
static_cast<uint64_t>(args[0].As<v8::Number>()->Value());
102+
}
103+
if (args.Length() > 1) {
104+
CHECK(args[1]->IsInt32());
105+
options.stack_depth = args[1].As<v8::Int32>()->Value();
106+
}
107+
if (args.Length() > 2) {
108+
CHECK(args[2]->IsUint32());
109+
options.flags = static_cast<v8::HeapProfiler::SamplingFlags>(
110+
args[2].As<v8::Uint32>()->Value());
111+
}
112+
return options;
113+
}
114+
115+
CpuProfileOptions ParseCpuProfileOptions(
116+
const v8::FunctionCallbackInfo<Value>& args) {
117+
CpuProfileOptions options;
118+
CHECK_LE(args.Length(), 2);
119+
if (args.Length() > 0) {
120+
CHECK(args[0]->IsInt32());
121+
options.sampling_interval_us = args[0].As<v8::Int32>()->Value();
122+
}
123+
if (args.Length() > 1) {
124+
CHECK(args[1]->IsUint32());
125+
options.max_samples = args[1].As<v8::Uint32>()->Value();
126+
}
127+
return options;
128+
}
129+
130+
} // namespace node

src/node_profiling.h

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
// Copyright Joyent, Inc. and other Node contributors.
2+
//
3+
// Permission is hereby granted, free of charge, to any person obtaining a
4+
// copy of this software and associated documentation files (the
5+
// "Software"), to deal in the Software without restriction, including
6+
// without limitation the rights to use, copy, modify, merge, publish,
7+
// distribute, sublicense, and/or sell copies of the Software, and to permit
8+
// persons to whom the Software is furnished to do so, subject to the
9+
// following conditions:
10+
//
11+
// The above copyright notice and this permission notice shall be included
12+
// in all copies or substantial portions of the Software.
13+
//
14+
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15+
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16+
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
17+
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
18+
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
19+
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
20+
// USE OR OTHER DEALINGS IN THE SOFTWARE.
21+
22+
#ifndef SRC_NODE_PROFILING_H_
23+
#define SRC_NODE_PROFILING_H_
24+
25+
#if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
26+
27+
#include "v8-profiler.h"
28+
#include "v8.h"
29+
30+
#include <cstdint>
31+
#include <sstream>
32+
33+
namespace node {
34+
35+
struct HeapProfileOptions {
36+
uint64_t sample_interval = 512 * 1024;
37+
int stack_depth = 16;
38+
v8::HeapProfiler::SamplingFlags flags =
39+
v8::HeapProfiler::SamplingFlags::kSamplingNoFlags;
40+
};
41+
42+
HeapProfileOptions ParseHeapProfileOptions(
43+
const v8::FunctionCallbackInfo<v8::Value>& args);
44+
45+
bool SerializeHeapProfile(v8::Isolate* isolate, std::ostringstream& out_stream);
46+
47+
struct CpuProfileOptions {
48+
int sampling_interval_us = 0;
49+
uint32_t max_samples = v8::CpuProfilingOptions::kNoSampleLimit;
50+
};
51+
52+
CpuProfileOptions ParseCpuProfileOptions(
53+
const v8::FunctionCallbackInfo<v8::Value>& args);
54+
55+
} // namespace node
56+
57+
#endif // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
58+
59+
#endif // SRC_NODE_PROFILING_H_

src/node_v8.cc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
#include "memory_tracker-inl.h"
2727
#include "node.h"
2828
#include "node_external_reference.h"
29+
#include "node_profiling.h"
2930
#include "util-inl.h"
3031
#include "v8-profiler.h"
3132
#include "v8.h"

src/node_worker.cc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#include "node_external_reference.h"
99
#include "node_options-inl.h"
1010
#include "node_perf.h"
11+
#include "node_profiling.h"
1112
#include "node_snapshot_builder.h"
1213
#include "permission/permission.h"
1314
#include "util-inl.h"

src/util.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1084,7 +1084,6 @@ inline v8::Local<v8::String> Uint32ToString(v8::Local<v8::Context> context,
10841084
->ToString(context)
10851085
.ToLocalChecked();
10861086
}
1087-
10881087
} // namespace node
10891088

10901089
#endif // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS

0 commit comments

Comments
 (0)