123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370 |
- 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 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
|