|
4 | 4 | #if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS |
5 | 5 |
|
6 | 6 | #include <memory> |
7 | | -#include <string_view> |
8 | 7 |
|
9 | 8 | #include "env-inl.h" |
10 | 9 | #include "node.h" |
11 | | -#include "node_metadata.h" |
12 | | -#include "node_platform.h" |
13 | 10 | #include "node_options.h" |
14 | | -#include "tracing/node_trace_writer.h" |
15 | | -#include "tracing/trace_event.h" |
16 | | -#include "tracing/traced_value.h" |
17 | | -#include "util.h" |
| 11 | +#include "node_platform.h" |
| 12 | +#include "tracing/agent.h" |
18 | 13 |
|
19 | 14 | namespace node { |
20 | 15 |
|
21 | | -// Ensures that __metadata trace events are only emitted |
22 | | -// when tracing is enabled. |
23 | | -class NodeTraceStateObserver |
24 | | - : public v8::TracingController::TraceStateObserver { |
25 | | - public: |
26 | | - inline void OnTraceEnabled() override { |
27 | | - std::string title = GetProcessTitle(""); |
28 | | - if (!title.empty()) { |
29 | | - // Only emit the metadata event if the title can be retrieved |
30 | | - // successfully. Ignore it otherwise. |
31 | | - TRACE_EVENT_METADATA1( |
32 | | - "__metadata", "process_name", "name", TRACE_STR_COPY(title.c_str())); |
33 | | - } |
34 | | - TRACE_EVENT_METADATA1("__metadata", |
35 | | - "version", |
36 | | - "node", |
37 | | - per_process::metadata.versions.node.c_str()); |
38 | | - TRACE_EVENT_METADATA1( |
39 | | - "__metadata", "thread_name", "name", "JavaScriptMainThread"); |
40 | | - |
41 | | - tracing::ProcessMeta trace_process; |
42 | | - TRACE_EVENT_METADATA1("__metadata", |
43 | | - "node", |
44 | | - "process", |
45 | | - tracing::CastTracedValue(trace_process)); |
46 | | - // This only runs the first time tracing is enabled |
47 | | - controller_->RemoveTraceStateObserver(this); |
48 | | - } |
49 | | - |
50 | | - inline void OnTraceDisabled() override { |
51 | | - // Do nothing here. This should never be called because the |
52 | | - // observer removes itself when OnTraceEnabled() is called. |
53 | | - UNREACHABLE(); |
54 | | - } |
55 | | - |
56 | | - explicit NodeTraceStateObserver(v8::TracingController* controller) |
57 | | - : controller_(controller) {} |
58 | | - ~NodeTraceStateObserver() override = default; |
59 | | - |
60 | | - private: |
61 | | - v8::TracingController* controller_; |
62 | | -}; |
63 | | - |
64 | 16 | struct V8Platform { |
65 | 17 | bool initialized_ = false; |
66 | 18 |
|
67 | 19 | #if NODE_USE_V8_PLATFORM |
68 | 20 | inline void Initialize(int thread_pool_size) { |
69 | 21 | CHECK(!initialized_); |
70 | 22 | initialized_ = true; |
71 | | - tracing_agent_ = std::make_unique<tracing::Agent>(); |
72 | | - node::tracing::TraceEventHelper::SetAgent(tracing_agent_.get()); |
73 | | - node::tracing::TracingController* controller = |
74 | | - tracing_agent_->GetTracingController(); |
75 | | - trace_state_observer_ = |
76 | | - std::make_unique<NodeTraceStateObserver>(controller); |
77 | | - controller->AddTraceStateObserver(trace_state_observer_.get()); |
78 | | - tracing_file_writer_ = tracing_agent_->DefaultHandle(); |
| 23 | + tracing_agent_ = tracing::Agent::CreateDefault(); |
79 | 24 | // Only start the tracing agent if we enabled any tracing categories. |
80 | 25 | if (!per_process::cli_options->trace_event_categories.empty()) { |
81 | 26 | StartTracingAgent(); |
82 | 27 | } |
83 | 28 | // Tracing must be initialized before platform threads are created. |
84 | | - platform_ = new NodePlatform(thread_pool_size, controller); |
| 29 | + platform_ = new NodePlatform(thread_pool_size, |
| 30 | + tracing_agent_->GetTracingController()); |
85 | 31 | v8::V8::InitializePlatform(platform_); |
86 | 32 | } |
87 | 33 | // Make sure V8Platform don not call into Libuv threadpool, |
@@ -90,58 +36,33 @@ struct V8Platform { |
90 | 36 | if (!initialized_) |
91 | 37 | return; |
92 | 38 | initialized_ = false; |
93 | | - node::tracing::TraceEventHelper::SetAgent(nullptr); |
94 | 39 | StopTracingAgent(); |
95 | 40 | platform_->Shutdown(); |
96 | 41 | delete platform_; |
97 | 42 | platform_ = nullptr; |
98 | 43 | // Destroy tracing after the platform (and platform threads) have been |
99 | 44 | // stopped. |
100 | 45 | tracing_agent_.reset(nullptr); |
101 | | - // The observer remove itself in OnTraceEnabled |
102 | | - trace_state_observer_.reset(nullptr); |
103 | 46 | } |
104 | 47 |
|
105 | 48 | inline void DrainVMTasks(v8::Isolate* isolate) { |
106 | 49 | platform_->DrainTasks(isolate); |
107 | 50 | } |
108 | 51 |
|
109 | 52 | inline void StartTracingAgent() { |
110 | | - constexpr auto convert_to_set = |
111 | | - [](auto& categories) -> std::set<std::string> { |
112 | | - std::set<std::string> out; |
113 | | - for (const auto& s : categories) { |
114 | | - out.emplace(std::string(s.data(), s.size())); |
115 | | - } |
116 | | - return out; |
117 | | - }; |
118 | | - // Attach a new NodeTraceWriter only if this function hasn't been called |
119 | | - // before. |
120 | | - if (tracing_file_writer_.IsDefaultHandle()) { |
121 | | - using std::operator""sv; |
122 | | - auto categories = std::views::split( |
123 | | - per_process::cli_options->trace_event_categories, ","sv); |
124 | | - |
125 | | - tracing_file_writer_ = tracing_agent_->AddClient( |
126 | | - convert_to_set(categories), |
127 | | - std::unique_ptr<tracing::AsyncTraceWriter>( |
128 | | - new tracing::NodeTraceWriter( |
129 | | - per_process::cli_options->trace_event_file_pattern)), |
130 | | - tracing::Agent::kUseDefaultCategories); |
131 | | - } |
| 53 | + if (!initialized_) return; |
| 54 | + tracing_agent_->StartTracing( |
| 55 | + per_process::cli_options->trace_event_categories); |
132 | 56 | } |
133 | 57 |
|
134 | | - inline void StopTracingAgent() { tracing_file_writer_.reset(); } |
135 | | - |
136 | | - inline tracing::AgentWriterHandle* GetTracingAgentWriter() { |
137 | | - return &tracing_file_writer_; |
| 58 | + inline void StopTracingAgent() { |
| 59 | + if (!initialized_) return; |
| 60 | + tracing_agent_->StopTracing(); |
138 | 61 | } |
139 | 62 |
|
140 | 63 | inline NodePlatform* Platform() { return platform_; } |
141 | 64 |
|
142 | | - std::unique_ptr<NodeTraceStateObserver> trace_state_observer_; |
143 | | - std::unique_ptr<tracing::Agent> tracing_agent_; |
144 | | - tracing::AgentWriterHandle tracing_file_writer_; |
| 65 | + std::unique_ptr<tracing::Agent, tracing::Agent::Deleter> tracing_agent_; |
145 | 66 | NodePlatform* platform_; |
146 | 67 | #else // !NODE_USE_V8_PLATFORM |
147 | 68 | inline void Initialize(int thread_pool_size) {} |
@@ -156,8 +77,6 @@ struct V8Platform { |
156 | 77 | } |
157 | 78 | inline void StopTracingAgent() {} |
158 | 79 |
|
159 | | - inline tracing::AgentWriterHandle* GetTracingAgentWriter() { return nullptr; } |
160 | | - |
161 | 80 | inline NodePlatform* Platform() { return nullptr; } |
162 | 81 | #endif // !NODE_USE_V8_PLATFORM |
163 | 82 | }; |
@@ -166,14 +85,6 @@ namespace per_process { |
166 | 85 | extern struct V8Platform v8_platform; |
167 | 86 | } |
168 | 87 |
|
169 | | -inline void StartTracingAgent() { |
170 | | - return per_process::v8_platform.StartTracingAgent(); |
171 | | -} |
172 | | - |
173 | | -inline tracing::AgentWriterHandle* GetTracingAgentWriter() { |
174 | | - return per_process::v8_platform.GetTracingAgentWriter(); |
175 | | -} |
176 | | - |
177 | 88 | inline void DisposePlatform() { |
178 | 89 | per_process::v8_platform.Dispose(); |
179 | 90 | } |
|