GCC Code Coverage Report
Directory: ../ Exec Total Coverage
File: /home/iojs/build/workspace/node-test-commit-linux-coverage-daily/nodes/benchmark/out/../src/node_v8_platform-inl.h Lines: 71 73 97.3 %
Date: 2020-05-27 22:15:15 Branches: 17 28 60.7 %

Line Branch Exec Source
1
#ifndef SRC_NODE_V8_PLATFORM_INL_H_
2
#define SRC_NODE_V8_PLATFORM_INL_H_
3
4
#if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
5
6
#include <memory>
7
8
#include "env-inl.h"
9
#include "node.h"
10
#include "node_metadata.h"
11
#include "node_options.h"
12
#include "tracing/node_trace_writer.h"
13
#include "tracing/trace_event.h"
14
#include "tracing/traced_value.h"
15
#include "util.h"
16
17
namespace node {
18
19
// Ensures that __metadata trace events are only emitted
20
// when tracing is enabled.
21
class NodeTraceStateObserver
22
    : public v8::TracingController::TraceStateObserver {
23
 public:
24
57
  inline void OnTraceEnabled() override {
25
114
    std::string title = GetProcessTitle("");
26
57
    if (!title.empty()) {
27
      // Only emit the metadata event if the title can be retrieved
28
      // successfully. Ignore it otherwise.
29

171
      TRACE_EVENT_METADATA1(
30
          "__metadata", "process_name", "name", TRACE_STR_COPY(title.c_str()));
31
    }
32

171
    TRACE_EVENT_METADATA1("__metadata",
33
                          "version",
34
                          "node",
35
                          per_process::metadata.versions.node.c_str());
36

114
    TRACE_EVENT_METADATA1(
37
        "__metadata", "thread_name", "name", "JavaScriptMainThread");
38
39
114
    auto trace_process = tracing::TracedValue::Create();
40
57
    trace_process->BeginDictionary("versions");
41
42
#define V(key)                                                                 \
43
  trace_process->SetString(#key, per_process::metadata.versions.key.c_str());
44
45
57
    NODE_VERSIONS_KEYS(V)
46
#undef V
47
48
57
    trace_process->EndDictionary();
49
50
57
    trace_process->SetString("arch", per_process::metadata.arch.c_str());
51
57
    trace_process->SetString("platform",
52
57
                             per_process::metadata.platform.c_str());
53
54
57
    trace_process->BeginDictionary("release");
55
57
    trace_process->SetString("name",
56
57
                             per_process::metadata.release.name.c_str());
57
#if NODE_VERSION_IS_LTS
58
    trace_process->SetString("lts", per_process::metadata.release.lts.c_str());
59
#endif
60
57
    trace_process->EndDictionary();
61

114
    TRACE_EVENT_METADATA1(
62
        "__metadata", "node", "process", std::move(trace_process));
63
64
    // This only runs the first time tracing is enabled
65
57
    controller_->RemoveTraceStateObserver(this);
66
57
  }
67
68
  inline void OnTraceDisabled() override {
69
    // Do nothing here. This should never be called because the
70
    // observer removes itself when OnTraceEnabled() is called.
71
    UNREACHABLE();
72
  }
73
74
4259
  explicit NodeTraceStateObserver(v8::TracingController* controller)
75
4259
      : controller_(controller) {}
76
8518
  ~NodeTraceStateObserver() override = default;
77
78
 private:
79
  v8::TracingController* controller_;
80
};
81
82
8652
struct V8Platform {
83
  bool initialized_ = false;
84
85
#if NODE_USE_V8_PLATFORM
86
4259
  inline void Initialize(int thread_pool_size) {
87
4259
    CHECK(!initialized_);
88
4259
    initialized_ = true;
89
4259
    tracing_agent_ = std::make_unique<tracing::Agent>();
90
4259
    node::tracing::TraceEventHelper::SetAgent(tracing_agent_.get());
91
    node::tracing::TracingController* controller =
92
4259
        tracing_agent_->GetTracingController();
93
    trace_state_observer_ =
94
4259
        std::make_unique<NodeTraceStateObserver>(controller);
95
4259
    controller->AddTraceStateObserver(trace_state_observer_.get());
96
4259
    tracing_file_writer_ = tracing_agent_->DefaultHandle();
97
    // Only start the tracing agent if we enabled any tracing categories.
98
4259
    if (!per_process::cli_options->trace_event_categories.empty()) {
99
52
      StartTracingAgent();
100
    }
101
    // Tracing must be initialized before platform threads are created.
102
4259
    platform_ = new NodePlatform(thread_pool_size, controller);
103
4259
    v8::V8::InitializePlatform(platform_);
104
4259
  }
105
106
4256
  inline void Dispose() {
107
4256
    if (!initialized_)
108
2
      return;
109
4254
    initialized_ = false;
110
111
4254
    StopTracingAgent();
112
4254
    platform_->Shutdown();
113
4254
    delete platform_;
114
4254
    platform_ = nullptr;
115
    // Destroy tracing after the platform (and platform threads) have been
116
    // stopped.
117
4254
    tracing_agent_.reset(nullptr);
118
4254
    trace_state_observer_.reset(nullptr);
119
  }
120
121
3856
  inline void DrainVMTasks(v8::Isolate* isolate) {
122
3856
    platform_->DrainTasks(isolate);
123
3855
  }
124
125
72
  inline void StartTracingAgent() {
126
    // Attach a new NodeTraceWriter only if this function hasn't been called
127
    // before.
128
72
    if (tracing_file_writer_.IsDefaultHandle()) {
129
      std::vector<std::string> categories =
130
110
          SplitString(per_process::cli_options->trace_event_categories, ',');
131
132
110
      tracing_file_writer_ = tracing_agent_->AddClient(
133
110
          std::set<std::string>(std::make_move_iterator(categories.begin()),
134
                                std::make_move_iterator(categories.end())),
135
165
          std::unique_ptr<tracing::AsyncTraceWriter>(
136
              new tracing::NodeTraceWriter(
137
110
                  per_process::cli_options->trace_event_file_pattern)),
138
55
          tracing::Agent::kUseDefaultCategories);
139
    }
140
72
  }
141
142
4254
  inline void StopTracingAgent() { tracing_file_writer_.reset(); }
143
144
8821
  inline tracing::AgentWriterHandle* GetTracingAgentWriter() {
145
8821
    return &tracing_file_writer_;
146
  }
147
148
4261
  inline NodePlatform* Platform() { return platform_; }
149
150
  std::unique_ptr<NodeTraceStateObserver> trace_state_observer_;
151
  std::unique_ptr<tracing::Agent> tracing_agent_;
152
  tracing::AgentWriterHandle tracing_file_writer_;
153
  NodePlatform* platform_;
154
#else   // !NODE_USE_V8_PLATFORM
155
  inline void Initialize(int thread_pool_size) {}
156
  inline void Dispose() {}
157
  inline void DrainVMTasks(v8::Isolate* isolate) {}
158
  inline void StartTracingAgent() {
159
    if (!per_process::cli_options->trace_event_categories.empty()) {
160
      fprintf(stderr,
161
              "Node compiled with NODE_USE_V8_PLATFORM=0, "
162
              "so event tracing is not available.\n");
163
    }
164
  }
165
  inline void StopTracingAgent() {}
166
167
  inline tracing::AgentWriterHandle* GetTracingAgentWriter() { return nullptr; }
168
169
  inline NodePlatform* Platform() { return nullptr; }
170
#endif  // !NODE_USE_V8_PLATFORM
171
};
172
173
namespace per_process {
174
extern struct V8Platform v8_platform;
175
}
176
177
20
inline void StartTracingAgent() {
178
20
  return per_process::v8_platform.StartTracingAgent();
179
}
180
181
8820
inline tracing::AgentWriterHandle* GetTracingAgentWriter() {
182
8820
  return per_process::v8_platform.GetTracingAgentWriter();
183
}
184
185
426
inline void DisposePlatform() {
186
426
  per_process::v8_platform.Dispose();
187
426
}
188
189
}  // namespace node
190
191
#endif  // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
192
193
#endif  // SRC_NODE_V8_PLATFORM_INL_H_