123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401 |
- 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/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 251f51ec454f9cba4023b8b6729241ee753aac13..1de8cac6e3953ce9cab9db03530da327199acfd5 100644
- --- a/lib/internal/http.js
- +++ b/lib/internal/http.js
- @@ -8,8 +8,8 @@ const {
- const { setUnrefTimeout } = require('internal/timers');
- const { getCategoryEnabledBuffer, trace } = 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/node.gyp b/node.gyp
- index b21cfbf2fad024445e8d1ef8a6781141f788eb1a..55c6e01d9e879ce63524ec1504f8a23e00a2aa29 100644
- --- a/node.gyp
- +++ b/node.gyp
- @@ -174,7 +174,6 @@
- 'src/timers.cc',
- 'src/timer_wrap.cc',
- 'src/tracing/agent.cc',
- - 'src/tracing/node_trace_buffer.cc',
- 'src/tracing/node_trace_writer.cc',
- 'src/tracing/trace_event.cc',
- 'src/tracing/traced_value.cc',
- @@ -302,7 +301,6 @@
- 'src/tcp_wrap.h',
- 'src/timers.h',
- 'src/tracing/agent.h',
- - 'src/tracing/node_trace_buffer.h',
- 'src/tracing/node_trace_writer.h',
- 'src/tracing/trace_event.h',
- 'src/tracing/trace_event_common.h',
- diff --git a/src/inspector/tracing_agent.cc b/src/inspector/tracing_agent.cc
- index e7b6d3b3ea63bdc80e569f56209e958b4fcde328..b52d5b1c7293539315626cd67f794cce4cfd1760 100644
- --- a/src/inspector/tracing_agent.cc
- +++ b/src/inspector/tracing_agent.cc
- @@ -84,14 +84,14 @@ class InspectorTraceWriter : public node::tracing::AsyncTraceWriter {
- explicit InspectorTraceWriter(int frontend_object_id,
- std::shared_ptr<MainThreadHandle> main_thread)
- : frontend_object_id_(frontend_object_id), main_thread_(main_thread) {}
- -
- +#ifndef V8_USE_PERFETTO
- void AppendTraceEvent(
- v8::platform::tracing::TraceObject* trace_event) override {
- if (!json_writer_)
- json_writer_.reset(TraceWriter::CreateJSONTraceWriter(stream_, "value"));
- json_writer_->AppendTraceEvent(trace_event);
- }
- -
- +#endif
- void Flush(bool) override {
- if (!json_writer_)
- return;
- diff --git a/src/tracing/agent.cc b/src/tracing/agent.cc
- index 7ce59674356f9743438350949be42fa7ead2afbe..30bff4272ed8eb5146e3b73a4849c187177fc3bd 100644
- --- a/src/tracing/agent.cc
- +++ b/src/tracing/agent.cc
- @@ -2,7 +2,9 @@
-
- #include <string>
- #include "trace_event.h"
- +#ifndef V8_USE_PERFETTO
- #include "tracing/node_trace_buffer.h"
- +#endif
- #include "debug_utils-inl.h"
- #include "env-inl.h"
-
- @@ -50,7 +52,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 +90,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 +151,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 +212,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 +222,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 +260,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.h b/src/tracing/node_trace_buffer.h
- index 18e4f43efaae3a60b924e697918867e604513194..7cbaf01235750138c680c8ec2ed5d206d638f8b6 100644
- --- a/src/tracing/node_trace_buffer.h
- +++ b/src/tracing/node_trace_buffer.h
- @@ -42,7 +42,9 @@ class InternalTraceBuffer {
- bool flushing_;
- size_t max_chunks_;
- Agent* agent_;
- +#ifndef V8_USE_PERFETTO
- std::vector<std::unique_ptr<TraceBufferChunk>> chunks_;
- +#endif
- size_t total_chunks_ = 0;
- uint32_t current_chunk_seq_ = 1;
- uint32_t id_;
- diff --git a/src/tracing/node_trace_writer.cc b/src/tracing/node_trace_writer.cc
- index 8f053efe93324b9acbb4e85f7b974b4f7712e200..1801594e727ec7a2ef3b89603975f507078b88a1 100644
- --- a/src/tracing/node_trace_writer.cc
- +++ b/src/tracing/node_trace_writer.cc
- @@ -96,6 +96,7 @@ void NodeTraceWriter::OpenNewFileForStreaming() {
- }
- }
-
- +#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,6 +113,7 @@ void NodeTraceWriter::AppendTraceEvent(TraceObject* trace_event) {
- ++total_traces_;
- json_trace_writer_->AppendTraceEvent(trace_event);
- }
- +#endif
-
- void NodeTraceWriter::FlushPrivate() {
- std::string str;
- 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 a662a081dc3bf356bf93e4063fcb043e4d8df07b..c89cdfe2b2681fbf9946200a03d7d1f7bad21226 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,12 +332,15 @@ 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 (controller == nullptr) [[unlikely]] {
- return &disabled;
- }
- return controller->GetCategoryGroupEnabled(group);
- +#endif
- + return 0;
- }
- };
-
- @@ -462,6 +478,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*>(
- @@ -478,6 +495,8 @@ static inline uint64_t AddTraceEventImpl(
- 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(
- @@ -485,6 +504,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_convertibles[2];
- if (num_args > 0 && arg_types[0] == TRACE_VALUE_TYPE_CONVERTABLE) {
- arg_convertibles[0].reset(reinterpret_cast<v8::ConvertableToTraceFormat*>(
- @@ -501,12 +521,15 @@ static V8_INLINE uint64_t AddTraceEventWithTimestampImpl(
- return controller->AddTraceEventWithTimestamp(
- phase, category_group_enabled, name, scope, id, bind_id, num_args,
- arg_names, arg_types, arg_values, arg_convertibles, 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*>(
- @@ -522,6 +545,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
|