| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1394,6 +1394,30 @@ setTimeout(() => { | |||
| 1394 | 1394 | }, 1000); | |
| 1395 | 1395 | ``` | |
| 1396 | 1396 | ||
| 1397 | + ## Class: `SyncCPUProfileHandle` | ||
| 1398 | + | ||
| 1399 | + <!-- YAML | ||
| 1400 | + added: REPLACEME | ||
| 1401 | + --> | ||
| 1402 | + | ||
| 1403 | + ### `syncCpuProfileHandle.stop()` | ||
| 1404 | + | ||
| 1405 | + <!-- YAML | ||
| 1406 | + added: REPLACEME | ||
| 1407 | + --> | ||
| 1408 | + | ||
| 1409 | + * Returns: {string} | ||
| 1410 | + | ||
| 1411 | + Stopping collecting the profile and return the profile data. | ||
| 1412 | + | ||
| 1413 | + ### `syncCpuProfileHandle[Symbol.dispose]()` | ||
| 1414 | + | ||
| 1415 | + <!-- YAML | ||
| 1416 | + added: REPLACEME | ||
| 1417 | + --> | ||
| 1418 | + | ||
| 1419 | + Stopping collecting the profile and the profile will be discarded. | ||
| 1420 | + | ||
| 1397 | 1421 | ## Class: `CPUProfileHandle` | |
| 1398 | 1422 | ||
| 1399 | 1423 | <!-- YAML | |
@@ -1489,6 +1513,23 @@ writeString('hello'); | |||
| 1489 | 1513 | writeString('你好'); | |
| 1490 | 1514 | ``` | |
| 1491 | 1515 | ||
| 1516 | + ## `v8.startCpuProfile()` | ||
| 1517 | + | ||
| 1518 | + <!-- YAML | ||
| 1519 | + added: REPLACEME | ||
| 1520 | + --> | ||
| 1521 | + | ||
| 1522 | + * Returns: {SyncCPUProfileHandle} | ||
| 1523 | + | ||
| 1524 | + Starting a CPU profile then return a `SyncCPUProfileHandle` object. | ||
| 1525 | + This API supports `using` syntax. | ||
| 1526 | + | ||
| 1527 | + ```cjs | ||
| 1528 | + const handle = v8.startCpuProfile(); | ||
| 1529 | + const profile = handle.stop(); | ||
| 1530 | + console.log(profile); | ||
| 1531 | + ``` | ||
| 1532 | + | ||
| 1492 | 1533 | [CppHeap]: https://v8docs.nodesource.com/node-22.4/d9/dc4/classv8_1_1_cpp_heap.html | |
| 1493 | 1534 | [HTML structured clone algorithm]: https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Structured_clone_algorithm | |
| 1494 | 1535 | [Hook Callbacks]: #hook-callbacks | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -27,6 +27,7 @@ const { | |||
| 27 | 27 | Int8Array, | |
| 28 | 28 | JSONParse, | |
| 29 | 29 | ObjectPrototypeToString, | |
| 30 | + SymbolDispose, | ||
| 30 | 31 | Uint16Array, | |
| 31 | 32 | Uint32Array, | |
| 32 | 33 | Uint8Array, | |
@@ -112,6 +113,8 @@ const binding = internalBinding('v8'); | |||
| 112 | 113 | const { | |
| 113 | 114 | cachedDataVersionTag, | |
| 114 | 115 | setFlagsFromString: _setFlagsFromString, | |
| 116 | + startCpuProfile: _startCpuProfile, | ||
| 117 | + stopCpuProfile: _stopCpuProfile, | ||
| 115 | 118 | isStringOneByteRepresentation: _isStringOneByteRepresentation, | |
| 116 | 119 | updateHeapStatisticsBuffer, | |
| 117 | 120 | updateHeapSpaceStatisticsBuffer, | |
@@ -166,6 +169,36 @@ function setFlagsFromString(flags) { | |||
| 166 | 169 | _setFlagsFromString(flags); | |
| 167 | 170 | } | |
| 168 | 171 | ||
| 172 | + class SyncCPUProfileHandle { | ||
| 173 | + #id = null; | ||
| 174 | + #stopped = false; | ||
| 175 | + | ||
| 176 | + constructor(id) { | ||
| 177 | + this.#id = id; | ||
| 178 | + } | ||
| 179 | + | ||
| 180 | + stop() { | ||
| 181 | + if (this.#stopped) { | ||
| 182 | + return; | ||
| 183 | + } | ||
| 184 | + this.#stopped = true; | ||
| 185 | + return _stopCpuProfile(this.#id); | ||
| 186 | + }; | ||
| 187 | + | ||
| 188 | + [SymbolDispose]() { | ||
| 189 | + this.stop(); | ||
| 190 | + } | ||
| 191 | + } | ||
| 192 | + | ||
| 193 | + /** | ||
| 194 | + * Starting CPU Profile. | ||
| 195 | + * @returns {SyncCPUProfileHandle} | ||
| 196 | + */ | ||
| 197 | + function startCpuProfile() { | ||
| 198 | + const id = _startCpuProfile(); | ||
| 199 | + return new SyncCPUProfileHandle(id); | ||
| 200 | + } | ||
| 201 | + | ||
| 169 | 202 | /** | |
| 170 | 203 | * Return whether this string uses one byte as underlying representation or not. | |
| 171 | 204 | * @param {string} content | |
@@ -478,4 +511,5 @@ module.exports = { | |||
| 478 | 511 | setHeapSnapshotNearHeapLimit, | |
| 479 | 512 | GCProfiler, | |
| 480 | 513 | isStringOneByteRepresentation, | |
| 514 | + startCpuProfile, | ||
| 481 | 515 | }; | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -27,6 +27,7 @@ | |||
| 27 | 27 | #include "node.h" | |
| 28 | 28 | #include "node_external_reference.h" | |
| 29 | 29 | #include "util-inl.h" | |
| 30 | + #include "v8-profiler.h" | ||
| 30 | 31 | #include "v8.h" | |
| 31 | 32 | ||
| 32 | 33 | namespace node { | |
@@ -35,6 +36,9 @@ using v8::Array; | |||
| 35 | 36 | using v8::BigInt; | |
| 36 | 37 | using v8::CFunction; | |
| 37 | 38 | using v8::Context; | |
| 39 | + using v8::CpuProfile; | ||
| 40 | + using v8::CpuProfilingResult; | ||
| 41 | + using v8::CpuProfilingStatus; | ||
| 38 | 42 | using v8::DictionaryTemplate; | |
| 39 | 43 | using v8::FunctionCallbackInfo; | |
| 40 | 44 | using v8::FunctionTemplate; | |
@@ -47,6 +51,7 @@ using v8::Isolate; | |||
| 47 | 51 | using v8::Local; | |
| 48 | 52 | using v8::LocalVector; | |
| 49 | 53 | using v8::MaybeLocal; | |
| 54 | + using v8::Number; | ||
| 50 | 55 | using v8::Object; | |
| 51 | 56 | using v8::ScriptCompiler; | |
| 52 | 57 | using v8::String; | |
@@ -241,6 +246,39 @@ void SetFlagsFromString(const FunctionCallbackInfo<Value>& args) { | |||
| 241 | 246 | V8::SetFlagsFromString(*flags, static_cast<size_t>(flags.length())); | |
| 242 | 247 | } | |
| 243 | 248 | ||
| 249 | + void StartCpuProfile(const FunctionCallbackInfo<Value>& args) { | ||
| 250 | + Environment* env = Environment::GetCurrent(args); | ||
| 251 | + Isolate* isolate = env->isolate(); | ||
| 252 | + CpuProfilingResult result = env->StartCpuProfile(); | ||
| 253 | + if (result.status == CpuProfilingStatus::kErrorTooManyProfilers) { | ||
| 254 | + return THROW_ERR_CPU_PROFILE_TOO_MANY(isolate, | ||
| 255 | + "There are too many CPU profiles"); | ||
| 256 | + } else if (result.status == CpuProfilingStatus::kStarted) { | ||
| 257 | + args.GetReturnValue().Set(Number::New(isolate, result.id)); | ||
| 258 | + } | ||
| 259 | + } | ||
| 260 | + | ||
| 261 | + void StopCpuProfile(const FunctionCallbackInfo<Value>& args) { | ||
| 262 | + Environment* env = Environment::GetCurrent(args); | ||
| 263 | + Isolate* isolate = env->isolate(); | ||
| 264 | + CHECK(args[0]->IsUint32()); | ||
| 265 | + uint32_t profile_id = args[0]->Uint32Value(env->context()).FromJust(); | ||
| 266 | + CpuProfile* profile = env->StopCpuProfile(profile_id); | ||
| 267 | + if (!profile) { | ||
| 268 | + return THROW_ERR_CPU_PROFILE_NOT_STARTED(isolate, | ||
| 269 | + "CPU profile not started"); | ||
| 270 | + } | ||
| 271 | + auto json_out_stream = std::make_unique<node::JSONOutputStream>(); | ||
| 272 | + profile->Serialize(json_out_stream.get(), | ||
| 273 | + CpuProfile::SerializationFormat::kJSON); | ||
| 274 | + profile->Delete(); | ||
| 275 | + Local<Value> ret; | ||
| 276 | + if (ToV8Value(env->context(), json_out_stream->out_stream().str(), isolate) | ||
| 277 | + .ToLocal(&ret)) { | ||
| 278 | + args.GetReturnValue().Set(ret); | ||
| 279 | + } | ||
| 280 | + } | ||
| 281 | + | ||
| 244 | 282 | static void IsStringOneByteRepresentation( | |
| 245 | 283 | const FunctionCallbackInfo<Value>& args) { | |
| 246 | 284 | CHECK_EQ(args.Length(), 1); | |
@@ -699,6 +737,9 @@ void Initialize(Local<Object> target, | |||
| 699 | 737 | // Export symbols used by v8.setFlagsFromString() | |
| 700 | 738 | SetMethod(context, target, "setFlagsFromString", SetFlagsFromString); | |
| 701 | 739 | ||
| 740 | + SetMethod(context, target, "startCpuProfile", StartCpuProfile); | ||
| 741 | + SetMethod(context, target, "stopCpuProfile", StopCpuProfile); | ||
| 742 | + | ||
| 702 | 743 | // Export symbols used by v8.isStringOneByteRepresentation() | |
| 703 | 744 | SetFastMethodNoSideEffect(context, | |
| 704 | 745 | target, | |
@@ -743,6 +784,8 @@ void RegisterExternalReferences(ExternalReferenceRegistry* registry) { | |||
| 743 | 784 | registry->Register(GetCppHeapStatistics); | |
| 744 | 785 | registry->Register(IsStringOneByteRepresentation); | |
| 745 | 786 | registry->Register(fast_is_string_one_byte_representation_); | |
| 787 | + registry->Register(StartCpuProfile); | ||
| 788 | + registry->Register(StopCpuProfile); | ||
| 746 | 789 | } | |
| 747 | 790 | ||
| 748 | 791 | } // namespace v8_utils | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -7,6 +7,7 @@ | |||
| 7 | 7 | #include "aliased_buffer.h" | |
| 8 | 8 | #include "base_object.h" | |
| 9 | 9 | #include "json_utils.h" | |
| 10 | + #include "node_errors.h" | ||
| 10 | 11 | #include "node_snapshotable.h" | |
| 11 | 12 | #include "util.h" | |
| 12 | 13 | #include "v8.h" | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,12 @@ | |||
| 1 | + 'use strict'; | ||
| 2 | + | ||
| 3 | + require('../common'); | ||
| 4 | + const assert = require('assert'); | ||
| 5 | + const v8 = require('v8'); | ||
| 6 | + | ||
| 7 | + const handle = v8.startCpuProfile(); | ||
| 8 | + const profile = handle.stop(); | ||
| 9 | + assert.ok(typeof profile === 'string'); | ||
| 10 | + assert.ok(profile.length > 0); | ||
| 11 | + // Call stop() again | ||
| 12 | + assert.ok(handle.stop() === undefined); | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -351,6 +351,7 @@ const customTypesMap = { | |||
| 351 | 351 | 'LockManagerSnapshot': 'https://developer.mozilla.org/en-US/docs/Web/API/LockManagerSnapshot', | |
| 352 | 352 | 'CPUProfileHandle': 'v8.html#class-cpuprofilehandle', | |
| 353 | 353 | 'HeapProfileHandle': 'v8.html#class-heapprofilehandle', | |
| 354 | + 'SyncCPUProfileHandle': 'v8.html#class-synccpuprofilehandle', | ||
| 354 | 355 | }; | |
| 355 | 356 | ||
| 356 | 357 | const arrayPart = /(?:\[])+$/; | |
| Back | FazBrowse Home | New Git URL |
0 commit comments