Commit 317b72b2 authored by Peter Marshall's avatar Peter Marshall Committed by Commit Bot

[tracing] Separate tracing implementations and add perfetto tests

Previously both tracing implementations would be run side-by-side when
perfetto was enabled with the V8_USE_PERFETTO build flag. This CL
makes them run separately.

Both implementations now use the trace file provided by the user in D8
or the default v8_trace.json.

Add tests for perfetto events (which must be tested differently
due to the proto output format).

Drive-by fix: Fix pass-by non-const ref in GetJSONStrings.

Remove the TraceEvent struct for testing; we can just store a copy of
the protobuf directly.

Bug: v8:8339
Change-Id: Id50003e0f96e44b99a63a26693da6bdaca989504
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1702619Reviewed-by: 's avatarYang Guo <yangguo@chromium.org>
Reviewed-by: 's avatarJakob Gruber <jgruber@chromium.org>
Commit-Queue: Peter Marshall <petermarshall@chromium.org>
Cr-Commit-Position: refs/heads/master@{#62810}
parent bc33f5ae
...@@ -3323,28 +3323,25 @@ int Shell::Main(int argc, char* argv[]) { ...@@ -3323,28 +3323,25 @@ int Shell::Main(int argc, char* argv[]) {
std::unique_ptr<platform::tracing::TracingController> tracing; std::unique_ptr<platform::tracing::TracingController> tracing;
std::ofstream trace_file; std::ofstream trace_file;
#ifdef V8_USE_PERFETTO
std::ofstream perfetto_trace_file;
#endif // V8_USE_PERFETTO
if (options.trace_enabled && !i::FLAG_verify_predictable) { if (options.trace_enabled && !i::FLAG_verify_predictable) {
tracing = base::make_unique<platform::tracing::TracingController>(); tracing = base::make_unique<platform::tracing::TracingController>();
trace_file.open(options.trace_path ? options.trace_path : "v8_trace.json"); trace_file.open(options.trace_path ? options.trace_path : "v8_trace.json");
DCHECK(trace_file.good()); DCHECK(trace_file.good());
platform::tracing::TraceBuffer* trace_buffer =
platform::tracing::TraceBuffer::CreateTraceBufferRingBuffer(
platform::tracing::TraceBuffer::kRingBufferChunks,
platform::tracing::TraceWriter::CreateJSONTraceWriter(trace_file));
tracing->Initialize(trace_buffer);
#ifdef V8_USE_PERFETTO #ifdef V8_USE_PERFETTO
// Set up the in-process backend that the tracing controller will connect
// to.
perfetto::TracingInitArgs init_args; perfetto::TracingInitArgs init_args;
init_args.backends = perfetto::BackendType::kInProcessBackend; init_args.backends = perfetto::BackendType::kInProcessBackend;
perfetto::Tracing::Initialize(init_args); perfetto::Tracing::Initialize(init_args);
perfetto_trace_file.open("v8_perfetto_trace.json"); tracing->InitializeForPerfetto(&trace_file);
DCHECK(trace_file.good()); #else
tracing->InitializeForPerfetto(&perfetto_trace_file); platform::tracing::TraceBuffer* trace_buffer =
platform::tracing::TraceBuffer::CreateTraceBufferRingBuffer(
platform::tracing::TraceBuffer::kRingBufferChunks,
platform::tracing::TraceWriter::CreateJSONTraceWriter(trace_file));
tracing->Initialize(trace_buffer);
#endif // V8_USE_PERFETTO #endif // V8_USE_PERFETTO
} }
......
...@@ -92,6 +92,7 @@ void TracingController::InitializeForPerfetto(std::ostream* output_stream) { ...@@ -92,6 +92,7 @@ void TracingController::InitializeForPerfetto(std::ostream* output_stream) {
output_stream_ = output_stream; output_stream_ = output_stream;
DCHECK_NOT_NULL(output_stream); DCHECK_NOT_NULL(output_stream);
DCHECK(output_stream->good()); DCHECK(output_stream->good());
mutex_.reset(new base::Mutex());
} }
void TracingController::SetTraceEventListenerForTesting( void TracingController::SetTraceEventListenerForTesting(
...@@ -146,7 +147,9 @@ void AddArgsToTraceProto( ...@@ -146,7 +147,9 @@ void AddArgsToTraceProto(
case TRACE_VALUE_TYPE_POINTER: case TRACE_VALUE_TYPE_POINTER:
arg->set_pointer_value(arg_value.as_uint); arg->set_pointer_value(arg_value.as_uint);
break; 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_COPY_STRING:
case TRACE_VALUE_TYPE_STRING: case TRACE_VALUE_TYPE_STRING:
arg->set_string_value(arg_value.as_string); arg->set_string_value(arg_value.as_string);
...@@ -216,7 +219,8 @@ uint64_t TracingController::AddTraceEventWithTimestamp( ...@@ -216,7 +219,8 @@ uint64_t TracingController::AddTraceEventWithTimestamp(
AddArgsToTraceProto(trace_event, num_args, arg_names, arg_types, AddArgsToTraceProto(trace_event, num_args, arg_names, arg_types,
arg_values, arg_convertables); arg_values, arg_convertables);
}); });
#endif // V8_USE_PERFETTO return 0;
#else
uint64_t handle = 0; uint64_t handle = 0;
if (recording_.load(std::memory_order_acquire)) { if (recording_.load(std::memory_order_acquire)) {
...@@ -232,6 +236,7 @@ uint64_t TracingController::AddTraceEventWithTimestamp( ...@@ -232,6 +236,7 @@ uint64_t TracingController::AddTraceEventWithTimestamp(
} }
} }
return handle; return handle;
#endif // V8_USE_PERFETTO
} }
void TracingController::UpdateTraceEventDuration( void TracingController::UpdateTraceEventDuration(
...@@ -251,11 +256,12 @@ void TracingController::UpdateTraceEventDuration( ...@@ -251,11 +256,12 @@ void TracingController::UpdateTraceEventDuration(
trace_event->set_process_id(base::OS::GetCurrentProcessId()); trace_event->set_process_id(base::OS::GetCurrentProcessId());
trace_event->set_thread_timestamp(cpu_now_us); trace_event->set_thread_timestamp(cpu_now_us);
}); });
#endif // V8_USE_PERFETTO #else
TraceObject* trace_object = trace_buffer_->GetEventByHandle(handle); TraceObject* trace_object = trace_buffer_->GetEventByHandle(handle);
if (!trace_object) return; if (!trace_object) return;
trace_object->UpdateDuration(now_us, cpu_now_us); trace_object->UpdateDuration(now_us, cpu_now_us);
#endif // V8_USE_PERFETTO
} }
const char* TracingController::GetCategoryGroupName( const char* TracingController::GetCategoryGroupName(
...@@ -317,7 +323,6 @@ void TracingController::StopTracing() { ...@@ -317,7 +323,6 @@ void TracingController::StopTracing() {
if (!recording_.compare_exchange_strong(expected, false)) { if (!recording_.compare_exchange_strong(expected, false)) {
return; return;
} }
DCHECK(trace_buffer_);
UpdateCategoryGroupEnabledFlags(); UpdateCategoryGroupEnabledFlags();
std::unordered_set<v8::TracingController::TraceStateObserver*> observers_copy; std::unordered_set<v8::TracingController::TraceStateObserver*> observers_copy;
{ {
...@@ -339,13 +344,14 @@ void TracingController::StopTracing() { ...@@ -339,13 +344,14 @@ void TracingController::StopTracing() {
if (listener_for_testing_) listener_for_testing_->ParseFromArray(trace); if (listener_for_testing_) listener_for_testing_->ParseFromArray(trace);
json_listener_.reset(); json_listener_.reset();
#else
#endif // V8_USE_PERFETTO
{ {
base::MutexGuard lock(mutex_.get()); base::MutexGuard lock(mutex_.get());
DCHECK(trace_buffer_);
trace_buffer_->Flush(); trace_buffer_->Flush();
} }
#endif // V8_USE_PERFETTO
} }
void TracingController::UpdateCategoryGroupEnabledFlag(size_t category_index) { void TracingController::UpdateCategoryGroupEnabledFlag(size_t category_index) {
......
...@@ -32,7 +32,9 @@ enum CategoryGroupEnabledFlags { ...@@ -32,7 +32,9 @@ enum CategoryGroupEnabledFlags {
kEnabledForETWExport_CategoryGroupEnabledFlags = 1 << 3, kEnabledForETWExport_CategoryGroupEnabledFlags = 1 << 3,
}; };
// By default, const char* asrgument values are assumed to have long-lived scope // TODO(petermarshall): Remove with the old tracing implementation - Perfetto
// copies const char* arguments by default.
// By default, const char* argument values are assumed to have long-lived scope
// and will not be copied. Use this macro to force a const char* to be copied. // and will not be copied. Use this macro to force a const char* to be copied.
#define TRACE_STR_COPY(str) v8::internal::tracing::TraceStringWithCopy(str) #define TRACE_STR_COPY(str) v8::internal::tracing::TraceStringWithCopy(str)
......
...@@ -306,6 +306,7 @@ int main(int argc, char* argv[]) { ...@@ -306,6 +306,7 @@ int main(int argc, char* argv[]) {
} }
#ifdef V8_USE_PERFETTO #ifdef V8_USE_PERFETTO
// Set up the in-process backend that the tracing controller will connect to.
perfetto::TracingInitArgs init_args; perfetto::TracingInitArgs init_args;
init_args.backends = perfetto::BackendType::kInProcessBackend; init_args.backends = perfetto::BackendType::kInProcessBackend;
perfetto::Tracing::Initialize(init_args); perfetto::Tracing::Initialize(init_args);
......
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment