summaryrefslogtreecommitdiff
path: root/src/inspector_profiler.h
blob: 187bc0d1c49a160e38f40c1007bc49b93cb736a1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
#ifndef SRC_INSPECTOR_PROFILER_H_
#define SRC_INSPECTOR_PROFILER_H_

#if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS

#if !HAVE_INSPECTOR
#error("This header can only be used when inspector is enabled")
#endif

#include "inspector_agent.h"

namespace node {
// Forward declaration to break recursive dependency chain with src/env.h.
class Environment;

namespace profiler {

class V8ProfilerConnection {
 public:
  class V8ProfilerSessionDelegate : public inspector::InspectorSessionDelegate {
   public:
    explicit V8ProfilerSessionDelegate(V8ProfilerConnection* connection)
        : connection_(connection) {}

    void SendMessageToFrontend(
        const v8_inspector::StringView& message) override;

   private:
    V8ProfilerConnection* connection_;
  };

  explicit V8ProfilerConnection(Environment* env);
  virtual ~V8ProfilerConnection() = default;

  Environment* env() const { return env_; }

  // Dispatch a protocol message, and returns the id of the message.
  // `method` does not need to be surrounded by quotes.
  // The optional `params` should be formatted in JSON.
  // The strings should be in one byte characters - which is enough for
  // the commands we use here.
  size_t DispatchMessage(const char* method, const char* params = nullptr);

  // Use DispatchMessage() to dispatch necessary inspector messages
  // to start and end the profiling.
  virtual void Start() = 0;
  virtual void End() = 0;

  // Return a descriptive name of the profile for debugging.
  virtual const char* type() const = 0;
  // Return if the profile is ending and the response can be parsed.
  virtual bool ending() const = 0;
  // Return the directory where the profile should be placed.
  virtual std::string GetDirectory() const = 0;
  // Return the filename the profile should be written as.
  virtual std::string GetFilename() const = 0;
  // Return the profile object parsed from `message.result`,
  // which will be then written as a JSON.
  virtual v8::MaybeLocal<v8::Object> GetProfile(
      v8::Local<v8::Object> result) = 0;
  virtual void WriteProfile(v8::Local<v8::String> message);

 private:
  size_t next_id() { return id_++; }
  std::unique_ptr<inspector::InspectorSession> session_;
  size_t id_ = 1;

 protected:
  Environment* env_ = nullptr;
};

class V8CoverageConnection : public V8ProfilerConnection {
 public:
  explicit V8CoverageConnection(Environment* env) : V8ProfilerConnection(env) {}

  void Start() override;
  void End() override;

  const char* type() const override { return "coverage"; }
  bool ending() const override { return ending_; }

  std::string GetDirectory() const override;
  std::string GetFilename() const override;
  v8::MaybeLocal<v8::Object> GetProfile(v8::Local<v8::Object> result) override;
  void WriteProfile(v8::Local<v8::String> message) override;
  void WriteSourceMapCache();

 private:
  std::unique_ptr<inspector::InspectorSession> session_;
  bool ending_ = false;
};

class V8CpuProfilerConnection : public V8ProfilerConnection {
 public:
  explicit V8CpuProfilerConnection(Environment* env)
      : V8ProfilerConnection(env) {}

  void Start() override;
  void End() override;

  const char* type() const override { return "CPU"; }
  bool ending() const override { return ending_; }

  std::string GetDirectory() const override;
  std::string GetFilename() const override;
  v8::MaybeLocal<v8::Object> GetProfile(v8::Local<v8::Object> result) override;

 private:
  std::unique_ptr<inspector::InspectorSession> session_;
  bool ending_ = false;
};

class V8HeapProfilerConnection : public V8ProfilerConnection {
 public:
  explicit V8HeapProfilerConnection(Environment* env)
      : V8ProfilerConnection(env) {}

  void Start() override;
  void End() override;

  const char* type() const override { return "heap"; }
  bool ending() const override { return ending_; }

  std::string GetDirectory() const override;
  std::string GetFilename() const override;
  v8::MaybeLocal<v8::Object> GetProfile(v8::Local<v8::Object> result) override;

 private:
  std::unique_ptr<inspector::InspectorSession> session_;
  bool ending_ = false;
};

}  // namespace profiler
}  // namespace node

#endif  // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
#endif  // SRC_INSPECTOR_PROFILER_H_