build: enable Perfetto in Chromium (#41910)
* build: enable perfetto in Chromium Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com> * refactor: delete TracingControllerImpl Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com> * fix: TraceObject isn't present when v8_use_perfetto is true Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com> * fix: update lib/internal/http for perfetto Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com> * chore: remove stray log Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com> --------- Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com> Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
This commit is contained in:
parent
7ef5402599
commit
0a8ed258da
4 changed files with 372 additions and 152 deletions
|
@ -50,10 +50,6 @@ is_cfi = false
|
||||||
# TODO: fix this once sysroots have been updated.
|
# TODO: fix this once sysroots have been updated.
|
||||||
use_qt = false
|
use_qt = false
|
||||||
|
|
||||||
# https://chromium-review.googlesource.com/c/chromium/src/+/4365718
|
|
||||||
# TODO(codebytere): fix perfetto incompatibility with Node.js.
|
|
||||||
use_perfetto_client_library = false
|
|
||||||
|
|
||||||
# Disables the builtins PGO for V8
|
# Disables the builtins PGO for V8
|
||||||
v8_builtins_profiling_log_file = ""
|
v8_builtins_profiling_log_file = ""
|
||||||
|
|
||||||
|
|
|
@ -45,3 +45,4 @@ fix_revert_src_lb_reducing_c_calls_of_esm_legacy_main_resolve.patch
|
||||||
src_preload_function_for_environment.patch
|
src_preload_function_for_environment.patch
|
||||||
deprecate_vector_v8_local_in_v8.patch
|
deprecate_vector_v8_local_in_v8.patch
|
||||||
fix_remove_deprecated_errno_constants.patch
|
fix_remove_deprecated_errno_constants.patch
|
||||||
|
build_enable_perfetto.patch
|
||||||
|
|
370
patches/node/build_enable_perfetto.patch
Normal file
370
patches/node/build_enable_perfetto.patch
Normal file
|
@ -0,0 +1,370 @@
|
||||||
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Shelley Vohr <shelley.vohr@gmail.com>
|
||||||
|
Date: Wed, 17 Apr 2024 08:17:49 -0400
|
||||||
|
Subject: build: enable perfetto
|
||||||
|
|
||||||
|
Enable perfetto by default in Node.js. Node.js disables perfetto by
|
||||||
|
default but is broken on build - they don't currently add guards for
|
||||||
|
`V8_USE_PERFETTO` and upstream only defines certain functions
|
||||||
|
on `v8::TracingController` if perfetto is disabled. Electron already
|
||||||
|
had minimal to no support for Node.js trace events, so the impact of
|
||||||
|
adding associated guards there should be relatively small.
|
||||||
|
|
||||||
|
We should upstream this as it will eventually impact Node.js as well.
|
||||||
|
|
||||||
|
diff --git a/lib/internal/constants.js b/lib/internal/constants.js
|
||||||
|
index 8d7204f6cb48f783adc4d1c1eb2de0c83b7fffe2..a154559a56bf383d3c26af523c9bb07b564ef600 100644
|
||||||
|
--- a/lib/internal/constants.js
|
||||||
|
+++ b/lib/internal/constants.js
|
||||||
|
@@ -5,12 +5,15 @@ const isWindows = process.platform === 'win32';
|
||||||
|
module.exports = {
|
||||||
|
// Alphabet chars.
|
||||||
|
CHAR_UPPERCASE_A: 65, /* A */
|
||||||
|
+ CHAR_UPPERCASE_B: 66, /* B */
|
||||||
|
CHAR_LOWERCASE_A: 97, /* a */
|
||||||
|
CHAR_UPPERCASE_Z: 90, /* Z */
|
||||||
|
CHAR_LOWERCASE_Z: 122, /* z */
|
||||||
|
CHAR_UPPERCASE_C: 67, /* C */
|
||||||
|
CHAR_LOWERCASE_B: 98, /* b */
|
||||||
|
+ CHAR_UPPERCASE_E: 69, /* E */
|
||||||
|
CHAR_LOWERCASE_E: 101, /* e */
|
||||||
|
+
|
||||||
|
CHAR_LOWERCASE_N: 110, /* n */
|
||||||
|
|
||||||
|
// Non-alphabetic chars.
|
||||||
|
diff --git a/lib/internal/http.js b/lib/internal/http.js
|
||||||
|
index b20b3cd229efcd9701791309361b7d106f315900..6b2820c9dcce5e658b694f53e75d93707c4320d7 100644
|
||||||
|
--- a/lib/internal/http.js
|
||||||
|
+++ b/lib/internal/http.js
|
||||||
|
@@ -10,8 +10,8 @@ const {
|
||||||
|
const { setUnrefTimeout } = require('internal/timers');
|
||||||
|
const { trace, isTraceCategoryEnabled } = internalBinding('trace_events');
|
||||||
|
const {
|
||||||
|
- CHAR_LOWERCASE_B,
|
||||||
|
- CHAR_LOWERCASE_E,
|
||||||
|
+ CHAR_UPPERCASE_B,
|
||||||
|
+ CHAR_UPPERCASE_E,
|
||||||
|
} = require('internal/constants');
|
||||||
|
|
||||||
|
let utcCache;
|
||||||
|
@@ -44,11 +44,13 @@ function isTraceHTTPEnabled() {
|
||||||
|
const traceEventCategory = 'node,node.http';
|
||||||
|
|
||||||
|
function traceBegin(...args) {
|
||||||
|
- trace(CHAR_LOWERCASE_B, traceEventCategory, ...args);
|
||||||
|
+ // See v8/src/builtins/builtins-trace.cc - must be uppercase for perfetto
|
||||||
|
+ trace(CHAR_UPPERCASE_B, traceEventCategory, ...args);
|
||||||
|
}
|
||||||
|
|
||||||
|
function traceEnd(...args) {
|
||||||
|
- trace(CHAR_LOWERCASE_E, traceEventCategory, ...args);
|
||||||
|
+ // See v8/src/builtins/builtins-trace.cc - must be uppercase for perfetto
|
||||||
|
+ trace(CHAR_UPPERCASE_E, traceEventCategory, ...args);
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
diff --git a/src/tracing/agent.cc b/src/tracing/agent.cc
|
||||||
|
index 7ce59674356f9743438350949be42fa7ead2afbe..c5fedc3be86a77730c57321b9c73cc8e94a001d7 100644
|
||||||
|
--- a/src/tracing/agent.cc
|
||||||
|
+++ b/src/tracing/agent.cc
|
||||||
|
@@ -50,7 +50,9 @@ using v8::platform::tracing::TraceWriter;
|
||||||
|
using std::string;
|
||||||
|
|
||||||
|
Agent::Agent() : tracing_controller_(new TracingController()) {
|
||||||
|
+#ifndef V8_USE_PERFETTO
|
||||||
|
tracing_controller_->Initialize(nullptr);
|
||||||
|
+#endif
|
||||||
|
|
||||||
|
CHECK_EQ(uv_loop_init(&tracing_loop_), 0);
|
||||||
|
CHECK_EQ(uv_async_init(&tracing_loop_,
|
||||||
|
@@ -86,10 +88,14 @@ Agent::~Agent() {
|
||||||
|
void Agent::Start() {
|
||||||
|
if (started_)
|
||||||
|
return;
|
||||||
|
-
|
||||||
|
+#ifdef V8_USE_PERFETTO
|
||||||
|
+ std::ostringstream perfetto_output;
|
||||||
|
+ tracing_controller_->InitializeForPerfetto(&perfetto_output);
|
||||||
|
+#else
|
||||||
|
NodeTraceBuffer* trace_buffer_ = new NodeTraceBuffer(
|
||||||
|
NodeTraceBuffer::kBufferChunks, this, &tracing_loop_);
|
||||||
|
tracing_controller_->Initialize(trace_buffer_);
|
||||||
|
+#endif
|
||||||
|
|
||||||
|
// This thread should be created *after* async handles are created
|
||||||
|
// (within NodeTraceWriter and NodeTraceBuffer constructors).
|
||||||
|
@@ -143,8 +149,10 @@ void Agent::StopTracing() {
|
||||||
|
return;
|
||||||
|
// Perform final Flush on TraceBuffer. We don't want the tracing controller
|
||||||
|
// to flush the buffer again on destruction of the V8::Platform.
|
||||||
|
- tracing_controller_->StopTracing();
|
||||||
|
+#ifndef V8_USE_PERFETTO
|
||||||
|
tracing_controller_->Initialize(nullptr);
|
||||||
|
+#endif
|
||||||
|
+ tracing_controller_->StopTracing();
|
||||||
|
started_ = false;
|
||||||
|
|
||||||
|
// Thread should finish when the tracing loop is stopped.
|
||||||
|
@@ -202,6 +210,7 @@ std::string Agent::GetEnabledCategories() const {
|
||||||
|
return categories;
|
||||||
|
}
|
||||||
|
|
||||||
|
+#ifndef V8_USE_PERFETTO
|
||||||
|
void Agent::AppendTraceEvent(TraceObject* trace_event) {
|
||||||
|
for (const auto& id_writer : writers_)
|
||||||
|
id_writer.second->AppendTraceEvent(trace_event);
|
||||||
|
@@ -211,18 +220,21 @@ void Agent::AddMetadataEvent(std::unique_ptr<TraceObject> event) {
|
||||||
|
Mutex::ScopedLock lock(metadata_events_mutex_);
|
||||||
|
metadata_events_.push_back(std::move(event));
|
||||||
|
}
|
||||||
|
+#endif
|
||||||
|
|
||||||
|
void Agent::Flush(bool blocking) {
|
||||||
|
+#ifndef V8_USE_PERFETTO
|
||||||
|
{
|
||||||
|
Mutex::ScopedLock lock(metadata_events_mutex_);
|
||||||
|
for (const auto& event : metadata_events_)
|
||||||
|
AppendTraceEvent(event.get());
|
||||||
|
}
|
||||||
|
-
|
||||||
|
+#endif
|
||||||
|
for (const auto& id_writer : writers_)
|
||||||
|
id_writer.second->Flush(blocking);
|
||||||
|
}
|
||||||
|
|
||||||
|
+#ifndef V8_USE_PERFETTO
|
||||||
|
void TracingController::AddMetadataEvent(
|
||||||
|
const unsigned char* category_group_enabled,
|
||||||
|
const char* name,
|
||||||
|
@@ -246,6 +258,6 @@ void TracingController::AddMetadataEvent(
|
||||||
|
if (node_agent != nullptr)
|
||||||
|
node_agent->AddMetadataEvent(std::move(trace_event));
|
||||||
|
}
|
||||||
|
-
|
||||||
|
+#endif
|
||||||
|
} // namespace tracing
|
||||||
|
} // namespace node
|
||||||
|
diff --git a/src/tracing/agent.h b/src/tracing/agent.h
|
||||||
|
index b542a849fe8da7e8bbbcca7067b73dc32b18d6d3..059ce6f6ea17199ead09c6c13bcc680f18f8c4d0 100644
|
||||||
|
--- a/src/tracing/agent.h
|
||||||
|
+++ b/src/tracing/agent.h
|
||||||
|
@@ -27,7 +27,9 @@ class Agent;
|
||||||
|
class AsyncTraceWriter {
|
||||||
|
public:
|
||||||
|
virtual ~AsyncTraceWriter() = default;
|
||||||
|
+#ifndef V8_USE_PERFETTO
|
||||||
|
virtual void AppendTraceEvent(TraceObject* trace_event) = 0;
|
||||||
|
+#endif
|
||||||
|
virtual void Flush(bool blocking) = 0;
|
||||||
|
virtual void InitializeOnThread(uv_loop_t* loop) {}
|
||||||
|
};
|
||||||
|
@@ -36,6 +38,7 @@ class TracingController : public v8::platform::tracing::TracingController {
|
||||||
|
public:
|
||||||
|
TracingController() : v8::platform::tracing::TracingController() {}
|
||||||
|
|
||||||
|
+#ifndef V8_USE_PERFETTO
|
||||||
|
int64_t CurrentTimestampMicroseconds() override {
|
||||||
|
return uv_hrtime() / 1000;
|
||||||
|
}
|
||||||
|
@@ -48,6 +51,7 @@ class TracingController : public v8::platform::tracing::TracingController {
|
||||||
|
const uint64_t* arg_values,
|
||||||
|
std::unique_ptr<v8::ConvertableToTraceFormat>* convertable_values,
|
||||||
|
unsigned int flags);
|
||||||
|
+#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
class AgentWriterHandle {
|
||||||
|
@@ -108,11 +112,12 @@ class Agent {
|
||||||
|
|
||||||
|
// Returns a comma-separated list of enabled categories.
|
||||||
|
std::string GetEnabledCategories() const;
|
||||||
|
-
|
||||||
|
+#ifndef V8_USE_PERFETTO
|
||||||
|
// Writes to all writers registered through AddClient().
|
||||||
|
void AppendTraceEvent(TraceObject* trace_event);
|
||||||
|
|
||||||
|
void AddMetadataEvent(std::unique_ptr<TraceObject> event);
|
||||||
|
+#endif
|
||||||
|
// Flushes all writers registered through AddClient().
|
||||||
|
void Flush(bool blocking);
|
||||||
|
|
||||||
|
@@ -152,7 +157,9 @@ class Agent {
|
||||||
|
std::set<AsyncTraceWriter*> to_be_initialized_;
|
||||||
|
|
||||||
|
Mutex metadata_events_mutex_;
|
||||||
|
+#ifndef V8_USE_PERFETTO
|
||||||
|
std::list<std::unique_ptr<TraceObject>> metadata_events_;
|
||||||
|
+#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
void AgentWriterHandle::reset() {
|
||||||
|
diff --git a/src/tracing/node_trace_buffer.cc b/src/tracing/node_trace_buffer.cc
|
||||||
|
index e187a1d78c81972b69cd4e03f7079cdb727956ad..3256c6326a08c6cafd83f1e49e3350193e813b51 100644
|
||||||
|
--- a/src/tracing/node_trace_buffer.cc
|
||||||
|
+++ b/src/tracing/node_trace_buffer.cc
|
||||||
|
@@ -55,6 +55,7 @@ TraceObject* InternalTraceBuffer::GetEventByHandle(uint64_t handle) {
|
||||||
|
}
|
||||||
|
|
||||||
|
void InternalTraceBuffer::Flush(bool blocking) {
|
||||||
|
+#ifndef V8_USE_PERFETTO
|
||||||
|
{
|
||||||
|
Mutex::ScopedLock scoped_lock(mutex_);
|
||||||
|
if (total_chunks_ > 0) {
|
||||||
|
@@ -75,6 +76,7 @@ void InternalTraceBuffer::Flush(bool blocking) {
|
||||||
|
flushing_ = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
+#endif
|
||||||
|
agent_->Flush(blocking);
|
||||||
|
}
|
||||||
|
|
||||||
|
diff --git a/src/tracing/node_trace_writer.cc b/src/tracing/node_trace_writer.cc
|
||||||
|
index 8f053efe93324b9acbb4e85f7b974b4f7712e200..e331ed5567caa39ade90ce28cea69f1d10533812 100644
|
||||||
|
--- a/src/tracing/node_trace_writer.cc
|
||||||
|
+++ b/src/tracing/node_trace_writer.cc
|
||||||
|
@@ -95,7 +95,7 @@ void NodeTraceWriter::OpenNewFileForStreaming() {
|
||||||
|
fd_ = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
-
|
||||||
|
+#ifndef V8_USE_PERFETTO
|
||||||
|
void NodeTraceWriter::AppendTraceEvent(TraceObject* trace_event) {
|
||||||
|
Mutex::ScopedLock scoped_lock(stream_mutex_);
|
||||||
|
// If this is the first trace event, open a new file for streaming.
|
||||||
|
@@ -112,7 +112,7 @@ void NodeTraceWriter::AppendTraceEvent(TraceObject* trace_event) {
|
||||||
|
++total_traces_;
|
||||||
|
json_trace_writer_->AppendTraceEvent(trace_event);
|
||||||
|
}
|
||||||
|
-
|
||||||
|
+#endif
|
||||||
|
void NodeTraceWriter::FlushPrivate() {
|
||||||
|
std::string str;
|
||||||
|
int highest_request_id;
|
||||||
|
diff --git a/src/tracing/node_trace_writer.h b/src/tracing/node_trace_writer.h
|
||||||
|
index cd965d77b7859ff2edcf781a934594b5a9b6d251..fe1714ba77fddef693d37eeb8c7a196ddfd15c26 100644
|
||||||
|
--- a/src/tracing/node_trace_writer.h
|
||||||
|
+++ b/src/tracing/node_trace_writer.h
|
||||||
|
@@ -20,7 +20,9 @@ class NodeTraceWriter : public AsyncTraceWriter {
|
||||||
|
~NodeTraceWriter() override;
|
||||||
|
|
||||||
|
void InitializeOnThread(uv_loop_t* loop) override;
|
||||||
|
+#ifndef V8_USE_PERFETTO
|
||||||
|
void AppendTraceEvent(TraceObject* trace_event) override;
|
||||||
|
+#endif
|
||||||
|
void Flush(bool blocking) override;
|
||||||
|
|
||||||
|
static const int kTracesPerFile = 1 << 19;
|
||||||
|
diff --git a/src/tracing/trace_event.h b/src/tracing/trace_event.h
|
||||||
|
index be0f55a409a71bf9c1763c36fdc252857228742e..827b5330b2f8c545338a46c548f8abf4aab7f50c 100644
|
||||||
|
--- a/src/tracing/trace_event.h
|
||||||
|
+++ b/src/tracing/trace_event.h
|
||||||
|
@@ -69,8 +69,16 @@ enum CategoryGroupEnabledFlags {
|
||||||
|
// for best performance when tracing is disabled.
|
||||||
|
// const uint8_t*
|
||||||
|
// TRACE_EVENT_API_GET_CATEGORY_GROUP_ENABLED(const char* category_group)
|
||||||
|
+#ifndef V8_USE_PERFETTO
|
||||||
|
#define TRACE_EVENT_API_GET_CATEGORY_GROUP_ENABLED \
|
||||||
|
node::tracing::TraceEventHelper::GetCategoryGroupEnabled
|
||||||
|
+#else
|
||||||
|
+#define TRACE_EVENT_API_GET_CATEGORY_GROUP_ENABLED(category_group) \
|
||||||
|
+ ([](const char*) -> const uint8_t* { \
|
||||||
|
+ static uint8_t no = 0; \
|
||||||
|
+ return &no; \
|
||||||
|
+ })(category_group)
|
||||||
|
+#endif
|
||||||
|
|
||||||
|
// Get the number of times traces have been recorded. This is used to implement
|
||||||
|
// the TRACE_EVENT_IS_NEW_TRACE facility.
|
||||||
|
@@ -114,10 +122,15 @@ enum CategoryGroupEnabledFlags {
|
||||||
|
// const uint8_t* category_group_enabled,
|
||||||
|
// const char* name,
|
||||||
|
// uint64_t id)
|
||||||
|
+#ifndef V8_USE_PERFETTO
|
||||||
|
#define TRACE_EVENT_API_UPDATE_TRACE_EVENT_DURATION \
|
||||||
|
if (auto controller = \
|
||||||
|
node::tracing::TraceEventHelper::GetTracingController()) \
|
||||||
|
controller->UpdateTraceEventDuration
|
||||||
|
+#else
|
||||||
|
+#define TRACE_EVENT_API_UPDATE_TRACE_EVENT_DURATION(category_group_enabled, name, event_handle) \
|
||||||
|
+ (void)(category_group_enabled), (void)(name), (void)(event_handle)
|
||||||
|
+#endif
|
||||||
|
|
||||||
|
// Adds a metadata event to the trace log. The |AppendValueAsTraceFormat| method
|
||||||
|
// on the convertable value will be called at flush time.
|
||||||
|
@@ -319,10 +332,13 @@ class TraceEventHelper {
|
||||||
|
static void SetAgent(Agent* agent);
|
||||||
|
|
||||||
|
static inline const uint8_t* GetCategoryGroupEnabled(const char* group) {
|
||||||
|
+#ifndef V8_USE_PERFETTO
|
||||||
|
v8::TracingController* controller = GetTracingController();
|
||||||
|
static const uint8_t disabled = 0;
|
||||||
|
if (UNLIKELY(controller == nullptr)) return &disabled;
|
||||||
|
return controller->GetCategoryGroupEnabled(group);
|
||||||
|
+#endif
|
||||||
|
+ return 0;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
@@ -460,6 +476,7 @@ static inline uint64_t AddTraceEventImpl(
|
||||||
|
const char* scope, uint64_t id, uint64_t bind_id, int32_t num_args,
|
||||||
|
const char** arg_names, const uint8_t* arg_types,
|
||||||
|
const uint64_t* arg_values, unsigned int flags) {
|
||||||
|
+#ifndef V8_USE_PERFETTO
|
||||||
|
std::unique_ptr<v8::ConvertableToTraceFormat> arg_convertibles[2];
|
||||||
|
if (num_args > 0 && arg_types[0] == TRACE_VALUE_TYPE_CONVERTABLE) {
|
||||||
|
arg_convertibles[0].reset(reinterpret_cast<v8::ConvertableToTraceFormat*>(
|
||||||
|
@@ -469,13 +486,14 @@ static inline uint64_t AddTraceEventImpl(
|
||||||
|
arg_convertibles[1].reset(reinterpret_cast<v8::ConvertableToTraceFormat*>(
|
||||||
|
static_cast<intptr_t>(arg_values[1])));
|
||||||
|
}
|
||||||
|
- // DCHECK(num_args, 2);
|
||||||
|
v8::TracingController* controller =
|
||||||
|
node::tracing::TraceEventHelper::GetTracingController();
|
||||||
|
if (controller == nullptr) return 0;
|
||||||
|
return controller->AddTraceEvent(phase, category_group_enabled, name, scope, id,
|
||||||
|
bind_id, num_args, arg_names, arg_types,
|
||||||
|
arg_values, arg_convertibles, flags);
|
||||||
|
+#endif
|
||||||
|
+ return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static V8_INLINE uint64_t AddTraceEventWithTimestampImpl(
|
||||||
|
@@ -483,6 +501,7 @@ static V8_INLINE uint64_t AddTraceEventWithTimestampImpl(
|
||||||
|
const char* scope, uint64_t id, uint64_t bind_id, int32_t num_args,
|
||||||
|
const char** arg_names, const uint8_t* arg_types,
|
||||||
|
const uint64_t* arg_values, unsigned int flags, int64_t timestamp) {
|
||||||
|
+#ifndef V8_USE_PERFETTO
|
||||||
|
std::unique_ptr<v8::ConvertableToTraceFormat> arg_convertables[2];
|
||||||
|
if (num_args > 0 && arg_types[0] == TRACE_VALUE_TYPE_CONVERTABLE) {
|
||||||
|
arg_convertables[0].reset(reinterpret_cast<v8::ConvertableToTraceFormat*>(
|
||||||
|
@@ -492,19 +511,21 @@ static V8_INLINE uint64_t AddTraceEventWithTimestampImpl(
|
||||||
|
arg_convertables[1].reset(reinterpret_cast<v8::ConvertableToTraceFormat*>(
|
||||||
|
static_cast<intptr_t>(arg_values[1])));
|
||||||
|
}
|
||||||
|
- // DCHECK_LE(num_args, 2);
|
||||||
|
v8::TracingController* controller =
|
||||||
|
node::tracing::TraceEventHelper::GetTracingController();
|
||||||
|
if (controller == nullptr) return 0;
|
||||||
|
return controller->AddTraceEventWithTimestamp(
|
||||||
|
phase, category_group_enabled, name, scope, id, bind_id, num_args,
|
||||||
|
arg_names, arg_types, arg_values, arg_convertables, flags, timestamp);
|
||||||
|
+#endif
|
||||||
|
+ return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static V8_INLINE void AddMetadataEventImpl(
|
||||||
|
const uint8_t* category_group_enabled, const char* name, int32_t num_args,
|
||||||
|
const char** arg_names, const uint8_t* arg_types,
|
||||||
|
const uint64_t* arg_values, unsigned int flags) {
|
||||||
|
+#ifndef V8_USE_PERFETTO
|
||||||
|
std::unique_ptr<v8::ConvertableToTraceFormat> arg_convertibles[2];
|
||||||
|
if (num_args > 0 && arg_types[0] == TRACE_VALUE_TYPE_CONVERTABLE) {
|
||||||
|
arg_convertibles[0].reset(reinterpret_cast<v8::ConvertableToTraceFormat*>(
|
||||||
|
@@ -520,6 +541,7 @@ static V8_INLINE void AddMetadataEventImpl(
|
||||||
|
return agent->GetTracingController()->AddMetadataEvent(
|
||||||
|
category_group_enabled, name, num_args, arg_names, arg_types, arg_values,
|
||||||
|
arg_convertibles, flags);
|
||||||
|
+#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
// Define SetTraceValue for each allowed type. It stores the type and
|
|
@ -131,153 +131,6 @@ JavascriptEnvironment::~JavascriptEnvironment() {
|
||||||
platform_->UnregisterIsolate(isolate_);
|
platform_->UnregisterIsolate(isolate_);
|
||||||
}
|
}
|
||||||
|
|
||||||
class EnabledStateObserverImpl final
|
|
||||||
: public base::trace_event::TraceLog::EnabledStateObserver {
|
|
||||||
public:
|
|
||||||
EnabledStateObserverImpl() {
|
|
||||||
base::trace_event::TraceLog::GetInstance()->AddEnabledStateObserver(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
~EnabledStateObserverImpl() override {
|
|
||||||
base::trace_event::TraceLog::GetInstance()->RemoveEnabledStateObserver(
|
|
||||||
this);
|
|
||||||
}
|
|
||||||
|
|
||||||
// disable copy
|
|
||||||
EnabledStateObserverImpl(const EnabledStateObserverImpl&) = delete;
|
|
||||||
EnabledStateObserverImpl& operator=(const EnabledStateObserverImpl&) = delete;
|
|
||||||
|
|
||||||
void OnTraceLogEnabled() final {
|
|
||||||
base::AutoLock lock(mutex_);
|
|
||||||
for (auto* o : observers_) {
|
|
||||||
o->OnTraceEnabled();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void OnTraceLogDisabled() final {
|
|
||||||
base::AutoLock lock(mutex_);
|
|
||||||
for (auto* o : observers_) {
|
|
||||||
o->OnTraceDisabled();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void AddObserver(v8::TracingController::TraceStateObserver* observer) {
|
|
||||||
{
|
|
||||||
base::AutoLock lock(mutex_);
|
|
||||||
DCHECK(!observers_.count(observer));
|
|
||||||
observers_.insert(observer);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fire the observer if recording is already in progress.
|
|
||||||
if (base::trace_event::TraceLog::GetInstance()->IsEnabled())
|
|
||||||
observer->OnTraceEnabled();
|
|
||||||
}
|
|
||||||
|
|
||||||
void RemoveObserver(v8::TracingController::TraceStateObserver* observer) {
|
|
||||||
base::AutoLock lock(mutex_);
|
|
||||||
DCHECK_EQ(observers_.count(observer), 1lu);
|
|
||||||
observers_.erase(observer);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
base::Lock mutex_;
|
|
||||||
std::unordered_set<v8::TracingController::TraceStateObserver*> observers_;
|
|
||||||
};
|
|
||||||
|
|
||||||
class TracingControllerImpl : public node::tracing::TracingController {
|
|
||||||
public:
|
|
||||||
TracingControllerImpl() = default;
|
|
||||||
~TracingControllerImpl() override = default;
|
|
||||||
|
|
||||||
// disable copy
|
|
||||||
TracingControllerImpl(const TracingControllerImpl&) = delete;
|
|
||||||
TracingControllerImpl& operator=(const TracingControllerImpl&) = delete;
|
|
||||||
|
|
||||||
// TracingController implementation.
|
|
||||||
const uint8_t* GetCategoryGroupEnabled(const char* name) override {
|
|
||||||
return TRACE_EVENT_API_GET_CATEGORY_GROUP_ENABLED(name);
|
|
||||||
}
|
|
||||||
uint64_t AddTraceEvent(
|
|
||||||
char phase,
|
|
||||||
const uint8_t* category_enabled_flag,
|
|
||||||
const char* name,
|
|
||||||
const char* scope,
|
|
||||||
uint64_t id,
|
|
||||||
uint64_t bind_id,
|
|
||||||
int32_t num_args,
|
|
||||||
const char** arg_names,
|
|
||||||
const uint8_t* arg_types,
|
|
||||||
const uint64_t* arg_values,
|
|
||||||
std::unique_ptr<v8::ConvertableToTraceFormat>* arg_convertables,
|
|
||||||
unsigned int flags) override {
|
|
||||||
base::trace_event::TraceArguments args(
|
|
||||||
num_args, arg_names, arg_types,
|
|
||||||
reinterpret_cast<const unsigned long long*>( // NOLINT(runtime/int)
|
|
||||||
arg_values),
|
|
||||||
arg_convertables);
|
|
||||||
DCHECK_LE(num_args, 2);
|
|
||||||
base::trace_event::TraceEventHandle handle =
|
|
||||||
TRACE_EVENT_API_ADD_TRACE_EVENT_WITH_BIND_ID(
|
|
||||||
phase, category_enabled_flag, name, scope, id, bind_id, &args,
|
|
||||||
flags);
|
|
||||||
uint64_t result;
|
|
||||||
memcpy(&result, &handle, sizeof(result));
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
uint64_t AddTraceEventWithTimestamp(
|
|
||||||
char phase,
|
|
||||||
const uint8_t* category_enabled_flag,
|
|
||||||
const char* name,
|
|
||||||
const char* scope,
|
|
||||||
uint64_t id,
|
|
||||||
uint64_t bind_id,
|
|
||||||
int32_t num_args,
|
|
||||||
const char** arg_names,
|
|
||||||
const uint8_t* arg_types,
|
|
||||||
const uint64_t* arg_values,
|
|
||||||
std::unique_ptr<v8::ConvertableToTraceFormat>* arg_convertables,
|
|
||||||
unsigned int flags,
|
|
||||||
int64_t timestampMicroseconds) override {
|
|
||||||
base::trace_event::TraceArguments args(
|
|
||||||
num_args, arg_names, arg_types,
|
|
||||||
reinterpret_cast<const unsigned long long*>( // NOLINT(runtime/int)
|
|
||||||
arg_values),
|
|
||||||
arg_convertables);
|
|
||||||
DCHECK_LE(num_args, 2);
|
|
||||||
base::TimeTicks timestamp =
|
|
||||||
base::TimeTicks() + base::Microseconds(timestampMicroseconds);
|
|
||||||
base::trace_event::TraceEventHandle handle =
|
|
||||||
TRACE_EVENT_API_ADD_TRACE_EVENT_WITH_THREAD_ID_AND_TIMESTAMP(
|
|
||||||
phase, category_enabled_flag, name, scope, id, bind_id,
|
|
||||||
TRACE_EVENT_API_CURRENT_THREAD_ID, timestamp, &args, flags);
|
|
||||||
uint64_t result;
|
|
||||||
memcpy(&result, &handle, sizeof(result));
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
void UpdateTraceEventDuration(const uint8_t* category_enabled_flag,
|
|
||||||
const char* name,
|
|
||||||
uint64_t handle) override {
|
|
||||||
base::trace_event::TraceEventHandle traceEventHandle;
|
|
||||||
memcpy(&traceEventHandle, &handle, sizeof(handle));
|
|
||||||
TRACE_EVENT_API_UPDATE_TRACE_EVENT_DURATION(category_enabled_flag, name,
|
|
||||||
traceEventHandle);
|
|
||||||
}
|
|
||||||
|
|
||||||
void AddTraceStateObserver(TraceStateObserver* observer) override {
|
|
||||||
GetObserverDelegate().AddObserver(observer);
|
|
||||||
}
|
|
||||||
|
|
||||||
void RemoveTraceStateObserver(TraceStateObserver* observer) override {
|
|
||||||
GetObserverDelegate().RemoveObserver(observer);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
static EnabledStateObserverImpl& GetObserverDelegate() {
|
|
||||||
static base::NoDestructor<EnabledStateObserverImpl> instance;
|
|
||||||
return *instance;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
v8::Isolate* JavascriptEnvironment::Initialize(uv_loop_t* event_loop,
|
v8::Isolate* JavascriptEnvironment::Initialize(uv_loop_t* event_loop,
|
||||||
bool setup_wasm_streaming) {
|
bool setup_wasm_streaming) {
|
||||||
auto* cmd = base::CommandLine::ForCurrentProcess();
|
auto* cmd = base::CommandLine::ForCurrentProcess();
|
||||||
|
@ -292,7 +145,7 @@ v8::Isolate* JavascriptEnvironment::Initialize(uv_loop_t* event_loop,
|
||||||
// The V8Platform of gin relies on Chromium's task schedule, which has not
|
// The V8Platform of gin relies on Chromium's task schedule, which has not
|
||||||
// been started at this point, so we have to rely on Node's V8Platform.
|
// been started at this point, so we have to rely on Node's V8Platform.
|
||||||
auto* tracing_agent = node::CreateAgent();
|
auto* tracing_agent = node::CreateAgent();
|
||||||
auto* tracing_controller = new TracingControllerImpl();
|
auto* tracing_controller = tracing_agent->GetTracingController();
|
||||||
node::tracing::TraceEventHelper::SetAgent(tracing_agent);
|
node::tracing::TraceEventHelper::SetAgent(tracing_agent);
|
||||||
platform_ = node::MultiIsolatePlatform::Create(
|
platform_ = node::MultiIsolatePlatform::Create(
|
||||||
base::RecommendedMaxNumberOfThreadsInThreadGroup(3, 8, 0.1, 0),
|
base::RecommendedMaxNumberOfThreadsInThreadGroup(3, 8, 0.1, 0),
|
||||||
|
|
Loading…
Reference in a new issue