• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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