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: 65 67 97.0 %
Date: 2019-02-23 22:23:05 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 "env-inl.h"
7
#include "node.h"
8
#include "node_metadata.h"
9
#include "node_options.h"
10
#include "tracing/node_trace_writer.h"
11
#include "tracing/trace_event.h"
12
#include "tracing/traced_value.h"
13
14
namespace node {
15
16
// Ensures that __metadata trace events are only emitted
17
// when tracing is enabled.
18
class NodeTraceStateObserver
19
    : public v8::TracingController::TraceStateObserver {
20
 public:
21
72
  inline void OnTraceEnabled() override {
22
    char name_buffer[512];
23
72
    if (uv_get_process_title(name_buffer, sizeof(name_buffer)) == 0) {
24
      // Only emit the metadata event if the title can be retrieved
25
      // successfully. Ignore it otherwise.
26

213
      TRACE_EVENT_METADATA1(
27
          "__metadata", "process_name", "name", TRACE_STR_COPY(name_buffer));
28
    }
29

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

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

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