| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -141,6 +141,7 @@ | |||
| 141 | 141 | 'src/node_os.cc', | |
| 142 | 142 | 'src/node_perf.cc', | |
| 143 | 143 | 'src/node_platform.cc', | |
| 144 | + 'src/node_profiling.cc', | ||
| 144 | 145 | 'src/node_postmortem_metadata.cc', | |
| 145 | 146 | 'src/node_process_events.cc', | |
| 146 | 147 | 'src/node_process_methods.cc', | |
@@ -283,6 +284,7 @@ | |||
| 283 | 284 | 'src/node_perf.h', | |
| 284 | 285 | 'src/node_perf_common.h', | |
| 285 | 286 | 'src/node_platform.h', | |
| 287 | + 'src/node_profiling.h', | ||
| 286 | 288 | 'src/node_process.h', | |
| 287 | 289 | 'src/node_process-inl.h', | |
| 288 | 290 | 'src/node_realm.h', | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -42,6 +42,7 @@ | |||
| 42 | 42 | #include "node_main_instance.h" | |
| 43 | 43 | #include "node_options.h" | |
| 44 | 44 | #include "node_perf_common.h" | |
| 45 | + #include "node_profiling.h" | ||
| 45 | 46 | #include "node_realm.h" | |
| 46 | 47 | #include "node_snapshotable.h" | |
| 47 | 48 | #include "permission/permission.h" | |
| Original file line number | Diff line number | Diff 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 | ||
| Original file line number | Diff line number | Diff 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_ | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -26,6 +26,7 @@ | |||
| 26 | 26 | #include "memory_tracker-inl.h" | |
| 27 | 27 | #include "node.h" | |
| 28 | 28 | #include "node_external_reference.h" | |
| 29 | + #include "node_profiling.h" | ||
| 29 | 30 | #include "util-inl.h" | |
| 30 | 31 | #include "v8-profiler.h" | |
| 31 | 32 | #include "v8.h" | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -8,6 +8,7 @@ | |||
| 8 | 8 | #include "node_external_reference.h" | |
| 9 | 9 | #include "node_options-inl.h" | |
| 10 | 10 | #include "node_perf.h" | |
| 11 | + #include "node_profiling.h" | ||
| 11 | 12 | #include "node_snapshot_builder.h" | |
| 12 | 13 | #include "permission/permission.h" | |
| 13 | 14 | #include "util-inl.h" | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -26,7 +26,6 @@ | |||
| 26 | 26 | ||
| 27 | 27 | #include "debug_utils-inl.h" | |
| 28 | 28 | #include "env-inl.h" | |
| 29 | - #include "json_utils.h" | ||
| 30 | 29 | #include "node_buffer.h" | |
| 31 | 30 | #include "node_errors.h" | |
| 32 | 31 | #include "node_internals.h" | |
@@ -86,13 +85,10 @@ constexpr int kMaximumCopyMode = | |||
| 86 | 85 | ||
| 87 | 86 | namespace node { | |
| 88 | 87 | ||
| 89 | - using v8::AllocationProfile; | ||
| 90 | 88 | using v8::ArrayBuffer; | |
| 91 | 89 | using v8::ArrayBufferView; | |
| 92 | 90 | using v8::Context; | |
| 93 | 91 | using v8::FunctionTemplate; | |
| 94 | - using v8::HandleScope; | ||
| 95 | - using v8::HeapProfiler; | ||
| 96 | 92 | using v8::Isolate; | |
| 97 | 93 | using v8::Local; | |
| 98 | 94 | using v8::Object; | |
@@ -816,96 +812,4 @@ v8::Maybe<int> GetValidFileMode(Environment* env, | |||
| 816 | 812 | return v8::Just(mode); | |
| 817 | 813 | } | |
| 818 | 814 | ||
| 819 | - static void BuildHeapProfileNode(Isolate* isolate, | ||
| 820 | - const AllocationProfile::Node* node, | ||
| 821 | - JSONWriter* writer) { | ||
| 822 | - size_t selfSize = 0; | ||
| 823 | - for (const auto& allocation : node->allocations) | ||
| 824 | - selfSize += allocation.size * allocation.count; | ||
| 825 | - | ||
| 826 | - writer->json_keyvalue("selfSize", selfSize); | ||
| 827 | - writer->json_keyvalue("id", node->node_id); | ||
| 828 | - writer->json_objectstart("callFrame"); | ||
| 829 | - writer->json_keyvalue("scriptId", node->script_id); | ||
| 830 | - writer->json_keyvalue("lineNumber", node->line_number - 1); | ||
| 831 | - writer->json_keyvalue("columnNumber", node->column_number - 1); | ||
| 832 | - Utf8Value name(isolate, node->name); | ||
| 833 | - Utf8Value script_name(isolate, node->script_name); | ||
| 834 | - writer->json_keyvalue("functionName", *name); | ||
| 835 | - writer->json_keyvalue("url", *script_name); | ||
| 836 | - writer->json_objectend(); | ||
| 837 | - | ||
| 838 | - writer->json_arraystart("children"); | ||
| 839 | - for (const auto* child : node->children) { | ||
| 840 | - writer->json_start(); | ||
| 841 | - BuildHeapProfileNode(isolate, child, writer); | ||
| 842 | - writer->json_end(); | ||
| 843 | - } | ||
| 844 | - writer->json_arrayend(); | ||
| 845 | - } | ||
| 846 | - | ||
| 847 | - bool SerializeHeapProfile(Isolate* isolate, std::ostringstream& out_stream) { | ||
| 848 | - HandleScope scope(isolate); | ||
| 849 | - HeapProfiler* profiler = isolate->GetHeapProfiler(); | ||
| 850 | - std::unique_ptr<AllocationProfile> profile(profiler->GetAllocationProfile()); | ||
| 851 | - if (!profile) { | ||
| 852 | - return false; | ||
| 853 | - } | ||
| 854 | - profiler->StopSamplingHeapProfiler(); | ||
| 855 | - JSONWriter writer(out_stream, true); | ||
| 856 | - writer.json_start(); | ||
| 857 | - | ||
| 858 | - writer.json_arraystart("samples"); | ||
| 859 | - for (const auto& sample : profile->GetSamples()) { | ||
| 860 | - writer.json_start(); | ||
| 861 | - writer.json_keyvalue("size", sample.size * sample.count); | ||
| 862 | - writer.json_keyvalue("nodeId", sample.node_id); | ||
| 863 | - writer.json_keyvalue("ordinal", static_cast<double>(sample.sample_id)); | ||
| 864 | - writer.json_end(); | ||
| 865 | - } | ||
| 866 | - writer.json_arrayend(); | ||
| 867 | - | ||
| 868 | - writer.json_objectstart("head"); | ||
| 869 | - BuildHeapProfileNode(isolate, profile->GetRootNode(), &writer); | ||
| 870 | - writer.json_objectend(); | ||
| 871 | - | ||
| 872 | - writer.json_end(); | ||
| 873 | - return true; | ||
| 874 | - } | ||
| 875 | - | ||
| 876 | - HeapProfileOptions ParseHeapProfileOptions( | ||
| 877 | - const v8::FunctionCallbackInfo<v8::Value>& args) { | ||
| 878 | - HeapProfileOptions options; | ||
| 879 | - CHECK_LE(args.Length(), 3); | ||
| 880 | - if (args.Length() > 0) { | ||
| 881 | - CHECK(args[0]->IsNumber()); | ||
| 882 | - options.sample_interval = | ||
| 883 | - static_cast<uint64_t>(args[0].As<v8::Number>()->Value()); | ||
| 884 | - } | ||
| 885 | - if (args.Length() > 1) { | ||
| 886 | - CHECK(args[1]->IsInt32()); | ||
| 887 | - options.stack_depth = args[1].As<v8::Int32>()->Value(); | ||
| 888 | - } | ||
| 889 | - if (args.Length() > 2) { | ||
| 890 | - CHECK(args[2]->IsUint32()); | ||
| 891 | - options.flags = static_cast<v8::HeapProfiler::SamplingFlags>( | ||
| 892 | - args[2].As<v8::Uint32>()->Value()); | ||
| 893 | - } | ||
| 894 | - return options; | ||
| 895 | - } | ||
| 896 | - | ||
| 897 | - CpuProfileOptions ParseCpuProfileOptions( | ||
| 898 | - const v8::FunctionCallbackInfo<v8::Value>& args) { | ||
| 899 | - CpuProfileOptions options; | ||
| 900 | - CHECK_LE(args.Length(), 2); | ||
| 901 | - if (args.Length() > 0) { | ||
| 902 | - CHECK(args[0]->IsInt32()); | ||
| 903 | - options.sampling_interval_us = args[0].As<v8::Int32>()->Value(); | ||
| 904 | - } | ||
| 905 | - if (args.Length() > 1) { | ||
| 906 | - CHECK(args[1]->IsUint32()); | ||
| 907 | - options.max_samples = args[1].As<v8::Uint32>()->Value(); | ||
| 908 | - } | ||
| 909 | - return options; | ||
| 910 | - } | ||
| 911 | 815 | } // namespace node | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1078,26 +1078,6 @@ inline v8::Local<v8::String> Uint32ToString(v8::Local<v8::Context> context, | |||
| 1078 | 1078 | ->ToString(context) | |
| 1079 | 1079 | .ToLocalChecked(); | |
| 1080 | 1080 | } | |
| 1081 | - bool SerializeHeapProfile(v8::Isolate* isolate, std::ostringstream& out_stream); | ||
| 1082 | - | ||
| 1083 | - struct HeapProfileOptions { | ||
| 1084 | - uint64_t sample_interval = 512 * 1024; | ||
| 1085 | - int stack_depth = 16; | ||
| 1086 | - v8::HeapProfiler::SamplingFlags flags = | ||
| 1087 | - v8::HeapProfiler::SamplingFlags::kSamplingNoFlags; | ||
| 1088 | - }; | ||
| 1089 | - | ||
| 1090 | - HeapProfileOptions ParseHeapProfileOptions( | ||
| 1091 | - const v8::FunctionCallbackInfo<v8::Value>& args); | ||
| 1092 | - | ||
| 1093 | - struct CpuProfileOptions { | ||
| 1094 | - int sampling_interval_us = 0; | ||
| 1095 | - uint32_t max_samples = v8::CpuProfilingOptions::kNoSampleLimit; | ||
| 1096 | - }; | ||
| 1097 | - | ||
| 1098 | - CpuProfileOptions ParseCpuProfileOptions( | ||
| 1099 | - const v8::FunctionCallbackInfo<v8::Value>& args); | ||
| 1100 | - | ||
| 1101 | 1081 | } // namespace node | |
| 1102 | 1082 | ||
| 1103 | 1083 | #endif // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS | |
| Back | FazBrowse Home | New Git URL |
0 commit comments