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: 66 68 97.1 %
Date: 2019-10-07 22:40:39 Branches: 16 26 61.5 %

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
16
namespace node {
17
18
// Ensures that __metadata trace events are only emitted
19
// when tracing is enabled.
20
class NodeTraceStateObserver
21
    : public v8::TracingController::TraceStateObserver {
22
 public:
23
72
  inline void OnTraceEnabled() override {
24
    char name_buffer[512];
25
72
    if (uv_get_process_title(name_buffer, sizeof(name_buffer)) == 0) {
26
      // Only emit the metadata event if the title can be retrieved
27
      // successfully. Ignore it otherwise.
28

210
      TRACE_EVENT_METADATA1(
29
          "__metadata", "process_name", "name", TRACE_STR_COPY(name_buffer));
30
    }
31

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

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

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