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