diff options
Diffstat (limited to 'deps/v8/src/libplatform/tracing/tracing-controller.cc')
-rw-r--r-- | deps/v8/src/libplatform/tracing/tracing-controller.cc | 147 |
1 files changed, 81 insertions, 66 deletions
diff --git a/deps/v8/src/libplatform/tracing/tracing-controller.cc b/deps/v8/src/libplatform/tracing/tracing-controller.cc index 91d042ba1e..0700e34825 100644 --- a/deps/v8/src/libplatform/tracing/tracing-controller.cc +++ b/deps/v8/src/libplatform/tracing/tracing-controller.cc @@ -16,12 +16,25 @@ #include "base/trace_event/common/trace_event_common.h" #include "perfetto/trace/chrome/chrome_trace_event.pbzero.h" #include "perfetto/trace/trace_packet.pbzero.h" -#include "perfetto/tracing/core/data_source_config.h" -#include "perfetto/tracing/core/trace_config.h" -#include "perfetto/tracing/core/trace_packet.h" -#include "perfetto/tracing/core/trace_writer.h" +#include "perfetto/tracing.h" +#include "src/base/platform/platform.h" +#include "src/base/platform/semaphore.h" #include "src/libplatform/tracing/json-trace-event-listener.h" -#include "src/libplatform/tracing/perfetto-tracing-controller.h" +#endif // V8_USE_PERFETTO + +#ifdef V8_USE_PERFETTO +class V8DataSource : public perfetto::DataSource<V8DataSource> { + public: + void OnSetup(const SetupArgs&) override {} + void OnStart(const StartArgs&) override { started_.Signal(); } + void OnStop(const StopArgs&) override {} + + static v8::base::Semaphore started_; +}; + +v8::base::Semaphore V8DataSource::started_{0}; + +PERFETTO_DEFINE_DATA_SOURCE_STATIC_MEMBERS(V8DataSource); #endif // V8_USE_PERFETTO namespace v8 { @@ -79,6 +92,7 @@ void TracingController::InitializeForPerfetto(std::ostream* output_stream) { output_stream_ = output_stream; DCHECK_NOT_NULL(output_stream); DCHECK(output_stream->good()); + mutex_.reset(new base::Mutex()); } void TracingController::SetTraceEventListenerForTesting( @@ -133,7 +147,9 @@ void AddArgsToTraceProto( case TRACE_VALUE_TYPE_POINTER: arg->set_pointer_value(arg_value.as_uint); break; - // TODO(petermarshall): Treat copy strings specially. + // There is no difference between copy strings and regular strings for + // Perfetto; the set_string_value(const char*) API will copy the string + // into the protobuf by default. case TRACE_VALUE_TYPE_COPY_STRING: case TRACE_VALUE_TYPE_STRING: arg->set_string_value(arg_value.as_string); @@ -171,44 +187,40 @@ uint64_t TracingController::AddTraceEventWithTimestamp( int64_t cpu_now_us = CurrentCpuTimestampMicroseconds(); #ifdef V8_USE_PERFETTO - if (perfetto_recording_.load()) { // Don't use COMPLETE events with perfetto - instead transform them into // BEGIN/END pairs. This avoids the need for a thread-local stack of pending // trace events as perfetto does not support handles into the trace buffer. if (phase == TRACE_EVENT_PHASE_COMPLETE) phase = TRACE_EVENT_PHASE_BEGIN; - ::perfetto::TraceWriter* writer = - perfetto_tracing_controller_->GetOrCreateThreadLocalWriter(); - // TODO(petermarshall): We shouldn't start one packet for each event. - // We should try to bundle them together in one bundle. - auto packet = writer->NewTracePacket(); - auto* trace_event_bundle = packet->set_chrome_events(); - auto* trace_event = trace_event_bundle->add_trace_events(); - - trace_event->set_name(name); - trace_event->set_timestamp(timestamp); - trace_event->set_phase(phase); - trace_event->set_thread_id(base::OS::GetCurrentThreadId()); - trace_event->set_duration(0); - trace_event->set_thread_duration(0); - if (scope) trace_event->set_scope(scope); - trace_event->set_id(id); - trace_event->set_flags(flags); - if (category_enabled_flag) { - const char* category_group_name = - GetCategoryGroupName(category_enabled_flag); - DCHECK_NOT_NULL(category_group_name); - trace_event->set_category_group_name(category_group_name); - } - trace_event->set_process_id(base::OS::GetCurrentProcessId()); - trace_event->set_thread_timestamp(cpu_now_us); - trace_event->set_bind_id(bind_id); - AddArgsToTraceProto(trace_event, num_args, arg_names, arg_types, arg_values, - arg_convertables); + V8DataSource::Trace([&](V8DataSource::TraceContext ctx) { + auto packet = ctx.NewTracePacket(); + auto* trace_event_bundle = packet->set_chrome_events(); + auto* trace_event = trace_event_bundle->add_trace_events(); + + trace_event->set_name(name); + trace_event->set_timestamp(timestamp); + trace_event->set_phase(phase); + trace_event->set_thread_id(base::OS::GetCurrentThreadId()); + trace_event->set_duration(0); + trace_event->set_thread_duration(0); + if (scope) trace_event->set_scope(scope); + trace_event->set_id(id); + trace_event->set_flags(flags); + if (category_enabled_flag) { + const char* category_group_name = + GetCategoryGroupName(category_enabled_flag); + DCHECK_NOT_NULL(category_group_name); + trace_event->set_category_group_name(category_group_name); + } + trace_event->set_process_id(base::OS::GetCurrentProcessId()); + trace_event->set_thread_timestamp(cpu_now_us); + trace_event->set_bind_id(bind_id); - packet->Finalize(); - } -#endif // V8_USE_PERFETTO + AddArgsToTraceProto(trace_event, num_args, arg_names, arg_types, + arg_values, arg_convertables); + }); + return 0; +#else uint64_t handle = 0; if (recording_.load(std::memory_order_acquire)) { @@ -224,6 +236,7 @@ uint64_t TracingController::AddTraceEventWithTimestamp( } } return handle; +#endif // V8_USE_PERFETTO } void TracingController::UpdateTraceEventDuration( @@ -232,15 +245,8 @@ void TracingController::UpdateTraceEventDuration( int64_t cpu_now_us = CurrentCpuTimestampMicroseconds(); #ifdef V8_USE_PERFETTO - // TODO(petermarshall): Should we still record the end of unfinished events - // when tracing has stopped? - if (perfetto_recording_.load()) { - // TODO(petermarshall): We shouldn't start one packet for each event. We - // should try to bundle them together in one bundle. - ::perfetto::TraceWriter* writer = - perfetto_tracing_controller_->GetOrCreateThreadLocalWriter(); - - auto packet = writer->NewTracePacket(); + V8DataSource::Trace([&](V8DataSource::TraceContext ctx) { + auto packet = ctx.NewTracePacket(); auto* trace_event_bundle = packet->set_chrome_events(); auto* trace_event = trace_event_bundle->add_trace_events(); @@ -249,14 +255,13 @@ void TracingController::UpdateTraceEventDuration( trace_event->set_timestamp(now_us); trace_event->set_process_id(base::OS::GetCurrentProcessId()); trace_event->set_thread_timestamp(cpu_now_us); - - packet->Finalize(); - } -#endif // V8_USE_PERFETTO + }); +#else TraceObject* trace_object = trace_buffer_->GetEventByHandle(handle); if (!trace_object) return; trace_object->UpdateDuration(now_us, cpu_now_us); +#endif // V8_USE_PERFETTO } const char* TracingController::GetCategoryGroupName( @@ -277,24 +282,27 @@ const char* TracingController::GetCategoryGroupName( void TracingController::StartTracing(TraceConfig* trace_config) { #ifdef V8_USE_PERFETTO - perfetto_tracing_controller_ = base::make_unique<PerfettoTracingController>(); - - if (listener_for_testing_) { - perfetto_tracing_controller_->AddTraceEventListener(listener_for_testing_); - } DCHECK_NOT_NULL(output_stream_); DCHECK(output_stream_->good()); json_listener_ = base::make_unique<JSONTraceEventListener>(output_stream_); - perfetto_tracing_controller_->AddTraceEventListener(json_listener_.get()); - ::perfetto::TraceConfig perfetto_trace_config; + // TODO(petermarshall): Set other the params for the config. + ::perfetto::TraceConfig perfetto_trace_config; perfetto_trace_config.add_buffers()->set_size_kb(4096); auto* ds_config = perfetto_trace_config.add_data_sources()->mutable_config(); ds_config->set_name("v8.trace_events"); - // TODO(petermarshall): Set all the params from |perfetto_trace_config|. - perfetto_tracing_controller_->StartTracing(perfetto_trace_config); - perfetto_recording_.store(true); + perfetto::DataSourceDescriptor dsd; + dsd.set_name("v8.trace_events"); + V8DataSource::Register(dsd); + + tracing_session_ = + perfetto::Tracing::NewTrace(perfetto::BackendType::kUnspecifiedBackend); + tracing_session_->Setup(perfetto_trace_config); + // TODO(petermarshall): Switch to StartBlocking when available. + tracing_session_->Start(); + V8DataSource::started_.Wait(); + #endif // V8_USE_PERFETTO trace_config_.reset(trace_config); @@ -315,7 +323,6 @@ void TracingController::StopTracing() { if (!recording_.compare_exchange_strong(expected, false)) { return; } - DCHECK(trace_buffer_); UpdateCategoryGroupEnabledFlags(); std::unordered_set<v8::TracingController::TraceStateObserver*> observers_copy; { @@ -327,16 +334,24 @@ void TracingController::StopTracing() { } #ifdef V8_USE_PERFETTO - perfetto_recording_.store(false); - perfetto_tracing_controller_->StopTracing(); - perfetto_tracing_controller_.reset(); + base::Semaphore stopped_{0}; + tracing_session_->SetOnStopCallback([&stopped_]() { stopped_.Signal(); }); + tracing_session_->Stop(); + stopped_.Wait(); + + std::vector<char> trace = tracing_session_->ReadTraceBlocking(); + json_listener_->ParseFromArray(trace); + if (listener_for_testing_) listener_for_testing_->ParseFromArray(trace); + json_listener_.reset(); -#endif // V8_USE_PERFETTO +#else { base::MutexGuard lock(mutex_.get()); + DCHECK(trace_buffer_); trace_buffer_->Flush(); } +#endif // V8_USE_PERFETTO } void TracingController::UpdateCategoryGroupEnabledFlag(size_t category_index) { |