Skip to content

Commit

Permalink
build: enable perfetto in Chromium
Browse files Browse the repository at this point in the history
(cherry picked from commit b487a46)
  • Loading branch information
codebytere authored and jkleinsc committed Apr 17, 2024
1 parent 6ef7b19 commit 2805523
Show file tree
Hide file tree
Showing 4 changed files with 211 additions and 5 deletions.
4 changes: 0 additions & 4 deletions build/args/all.gn
Original file line number Diff line number Diff line change
Expand Up @@ -50,10 +50,6 @@ is_cfi = false
# TODO: fix this once sysroots have been updated.
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
v8_builtins_profiling_log_file = ""

Expand Down
1 change: 1 addition & 0 deletions patches/node/.patches
Original file line number Diff line number Diff line change
Expand Up @@ -45,3 +45,4 @@ fix_revert_src_lb_reducing_c_calls_of_esm_legacy_main_resolve.patch
src_preload_function_for_environment.patch
deprecate_vector_v8_local_in_v8.patch
fix_remove_deprecated_errno_constants.patch
build_enable_perfetto.patch
206 changes: 206 additions & 0 deletions patches/node/build_enable_perfetto.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,206 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Shelley Vohr <[email protected]>
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/src/tracing/agent.cc b/src/tracing/agent.cc
index 7ce59674356f9743438350949be42fa7ead2afbe..3cd1ebf1688a158f12c926ed9d06ae38d16cf63e 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.
@@ -223,6 +231,7 @@ void Agent::Flush(bool blocking) {
id_writer.second->Flush(blocking);
}

+#ifndef V8_USE_PERFETTO
void TracingController::AddMetadataEvent(
const unsigned char* category_group_enabled,
const char* name,
@@ -246,6 +255,7 @@ 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..e8f3d06d0bd5b3358c4ad46bb36a9ab631141521 100644
--- a/src/tracing/agent.h
+++ b/src/tracing/agent.h
@@ -36,6 +36,7 @@ class TracingController : public v8::platform::tracing::TracingController {
public:
TracingController() : v8::platform::tracing::TracingController() {}

+#if !defined(V8_USE_PERFETTO)
int64_t CurrentTimestampMicroseconds() override {
return uv_hrtime() / 1000;
}
@@ -48,6 +49,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 {
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
5 changes: 4 additions & 1 deletion shell/browser/javascript_environment.cc
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,9 @@ class TracingControllerImpl : public node::tracing::TracingController {
TracingControllerImpl(const TracingControllerImpl&) = delete;
TracingControllerImpl& operator=(const TracingControllerImpl&) = delete;

// TracingController implementation.
// In Perfetto mode, trace events are written using Perfetto's Track Event
// API directly without going through the embedder.
#if !defined(V8_USE_PERFETTO)
const uint8_t* GetCategoryGroupEnabled(const char* name) override {
return TRACE_EVENT_API_GET_CATEGORY_GROUP_ENABLED(name);
}
Expand Down Expand Up @@ -262,6 +264,7 @@ class TracingControllerImpl : public node::tracing::TracingController {
TRACE_EVENT_API_UPDATE_TRACE_EVENT_DURATION(category_enabled_flag, name,
traceEventHandle);
}
#endif // !defined(V8_USE_PERFETTO)

void AddTraceStateObserver(TraceStateObserver* observer) override {
GetObserverDelegate().AddObserver(observer);
Expand Down

0 comments on commit 2805523

Please sign in to comment.