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[]) {
std::unique_ptr<platform::tracing::TracingController> tracing;
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) {
tracing = base::make_unique<platform::tracing::TracingController>();
trace_file.open(options.trace_path ? options.trace_path : "v8_trace.json");
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
// Set up the in-process backend that the tracing controller will connect
// to.
perfetto::TracingInitArgs init_args;
init_args.backends = perfetto::BackendType::kInProcessBackend;
perfetto::Tracing::Initialize(init_args);
perfetto_trace_file.open("v8_perfetto_trace.json");
DCHECK(trace_file.good());
tracing->InitializeForPerfetto(&perfetto_trace_file);
tracing->InitializeForPerfetto(&trace_file);
#else
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
}
......
......@@ -92,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(
......@@ -146,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);
......@@ -216,7 +219,8 @@ uint64_t TracingController::AddTraceEventWithTimestamp(
AddArgsToTraceProto(trace_event, num_args, arg_names, arg_types,
arg_values, arg_convertables);
});
#endif // V8_USE_PERFETTO
return 0;
#else
uint64_t handle = 0;
if (recording_.load(std::memory_order_acquire)) {
......@@ -232,6 +236,7 @@ uint64_t TracingController::AddTraceEventWithTimestamp(
}
}
return handle;
#endif // V8_USE_PERFETTO
}
void TracingController::UpdateTraceEventDuration(
......@@ -251,11 +256,12 @@ void TracingController::UpdateTraceEventDuration(
trace_event->set_process_id(base::OS::GetCurrentProcessId());
trace_event->set_thread_timestamp(cpu_now_us);
});
#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(
......@@ -317,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;
{
......@@ -339,13 +344,14 @@ void TracingController::StopTracing() {
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) {
......
......@@ -32,7 +32,9 @@ enum CategoryGroupEnabledFlags {
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.
#define TRACE_STR_COPY(str) v8::internal::tracing::TraceStringWithCopy(str)
......
......@@ -306,6 +306,7 @@ int main(int argc, char* argv[]) {
}
#ifdef V8_USE_PERFETTO
// Set up the in-process backend that the tracing controller will connect to.
perfetto::TracingInitArgs init_args;
init_args.backends = perfetto::BackendType::kInProcessBackend;
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