1 #ifndef SRC_INSPECTOR_PROFILER_H_ 2 #define SRC_INSPECTOR_PROFILER_H_ 3 4 #if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS 5 6 #if !HAVE_INSPECTOR 7 #error("This header can only be used when inspector is enabled") 8 #endif 9 10 #include <unordered_set> 11 #include "inspector_agent.h" 12 13 namespace node { 14 // Forward declaration to break recursive dependency chain with src/env.h. 15 class Environment; 16 17 namespace profiler { 18 19 class V8ProfilerConnection { 20 public: 21 class V8ProfilerSessionDelegate : public inspector::InspectorSessionDelegate { 22 public: V8ProfilerSessionDelegate(V8ProfilerConnection * connection)23 explicit V8ProfilerSessionDelegate(V8ProfilerConnection* connection) 24 : connection_(connection) {} 25 26 void SendMessageToFrontend( 27 const v8_inspector::StringView& message) override; 28 29 private: 30 V8ProfilerConnection* connection_; 31 }; 32 33 explicit V8ProfilerConnection(Environment* env); 34 virtual ~V8ProfilerConnection() = default; 35 env()36 Environment* env() const { return env_; } 37 38 // Dispatch a protocol message, and returns the id of the message. 39 // `method` does not need to be surrounded by quotes. 40 // The optional `params` should be formatted in JSON. 41 // The strings should be in one byte characters - which is enough for 42 // the commands we use here. 43 uint32_t DispatchMessage(const char* method, 44 const char* params = nullptr, 45 bool is_profile_request = false); 46 47 // Use DispatchMessage() to dispatch necessary inspector messages 48 // to start and end the profiling. 49 virtual void Start() = 0; 50 virtual void End() = 0; 51 52 // Return a descriptive name of the profile for debugging. 53 virtual const char* type() const = 0; 54 // Return if the profile is ending and the response can be parsed. 55 virtual bool ending() const = 0; 56 // Return the directory where the profile should be placed. 57 virtual std::string GetDirectory() const = 0; 58 // Return the filename the profile should be written as. 59 virtual std::string GetFilename() const = 0; 60 // Return the profile object parsed from `message.result`, 61 // which will be then written as a JSON. 62 virtual v8::MaybeLocal<v8::Object> GetProfile( 63 v8::Local<v8::Object> result) = 0; 64 virtual void WriteProfile(v8::Local<v8::Object> result); 65 HasProfileId(uint32_t id)66 bool HasProfileId(uint32_t id) const { 67 return profile_ids_.find(id) != profile_ids_.end(); 68 } 69 RemoveProfileId(uint32_t id)70 void RemoveProfileId(uint32_t id) { profile_ids_.erase(id); } 71 72 private: next_id()73 uint32_t next_id() { return id_++; } 74 std::unique_ptr<inspector::InspectorSession> session_; 75 uint32_t id_ = 1; 76 std::unordered_set<uint32_t> profile_ids_; 77 78 protected: 79 Environment* env_ = nullptr; 80 }; 81 82 class V8CoverageConnection : public V8ProfilerConnection { 83 public: V8CoverageConnection(Environment * env)84 explicit V8CoverageConnection(Environment* env) : V8ProfilerConnection(env) {} 85 86 void Start() override; 87 void End() override; 88 type()89 const char* type() const override { return "coverage"; } ending()90 bool ending() const override { return ending_; } 91 92 std::string GetDirectory() const override; 93 std::string GetFilename() const override; 94 v8::MaybeLocal<v8::Object> GetProfile(v8::Local<v8::Object> result) override; 95 void WriteProfile(v8::Local<v8::Object> result) override; 96 void WriteSourceMapCache(); 97 void TakeCoverage(); 98 void StopCoverage(); 99 100 private: 101 std::unique_ptr<inspector::InspectorSession> session_; 102 bool ending_ = false; 103 }; 104 105 class V8CpuProfilerConnection : public V8ProfilerConnection { 106 public: V8CpuProfilerConnection(Environment * env)107 explicit V8CpuProfilerConnection(Environment* env) 108 : V8ProfilerConnection(env) {} 109 110 void Start() override; 111 void End() override; 112 type()113 const char* type() const override { return "CPU"; } ending()114 bool ending() const override { return ending_; } 115 116 std::string GetDirectory() const override; 117 std::string GetFilename() const override; 118 v8::MaybeLocal<v8::Object> GetProfile(v8::Local<v8::Object> result) override; 119 120 private: 121 std::unique_ptr<inspector::InspectorSession> session_; 122 bool ending_ = false; 123 }; 124 125 class V8HeapProfilerConnection : public V8ProfilerConnection { 126 public: V8HeapProfilerConnection(Environment * env)127 explicit V8HeapProfilerConnection(Environment* env) 128 : V8ProfilerConnection(env) {} 129 130 void Start() override; 131 void End() override; 132 type()133 const char* type() const override { return "heap"; } ending()134 bool ending() const override { return ending_; } 135 136 std::string GetDirectory() const override; 137 std::string GetFilename() const override; 138 v8::MaybeLocal<v8::Object> GetProfile(v8::Local<v8::Object> result) override; 139 140 private: 141 std::unique_ptr<inspector::InspectorSession> session_; 142 bool ending_ = false; 143 }; 144 145 } // namespace profiler 146 } // namespace node 147 148 #endif // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS 149 #endif // SRC_INSPECTOR_PROFILER_H_ 150