summaryrefslogtreecommitdiff
path: root/deps/v8/src/libplatform/tracing/tracing-controller.cc
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/src/libplatform/tracing/tracing-controller.cc')
-rw-r--r--deps/v8/src/libplatform/tracing/tracing-controller.cc147
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) {