15#include "perfetto/ext/trace_processor/export_json.h"
16#include "perfetto/trace_processor/trace_processor.h"
17#include "perfetto/tracing/tracing.h"
18#include "protos/perfetto/config/data_source_config.gen.h"
19#include "protos/perfetto/config/trace_config.gen.h"
20#include "protos/perfetto/config/track_event/track_event_config.gen.h"
27class JsonOutputWriter :
public perfetto::trace_processor::json::OutputWriter {
29 explicit JsonOutputWriter(std::ostream* stream) : stream_(stream) {}
31 perfetto::trace_processor::util::Status AppendString(
32 const std::string&
string)
override {
34 return perfetto::trace_processor::util::OkStatus();
38 std::ostream* stream_;
46#if !defined(V8_USE_PERFETTO)
57 "tracing categories exhausted; must increase kMaxCategoryGroups",
77#if !defined(V8_USE_PERFETTO)
84 free(
const_cast<char*
>(group));
92void TracingController::InitializeForPerfetto(std::ostream* output_stream) {
93 output_stream_ = output_stream;
95 DCHECK(output_stream->good());
98void TracingController::SetTraceEventListenerForTesting(
99 TraceEventListener* listener) {
100 listener_for_testing_ = listener;
116 char phase,
const uint8_t* category_enabled_flag,
const char* name,
117 const char* scope, uint64_t
id, uint64_t bind_id,
int num_args,
118 const char** arg_names,
const uint8_t* arg_types,
119 const uint64_t* arg_values,
120 std::unique_ptr<v8::ConvertableToTraceFormat>* arg_convertables,
121 unsigned int flags) {
125 phase, category_enabled_flag, name, scope,
id, bind_id, num_args,
126 arg_names, arg_types, arg_values, arg_convertables, flags, now_us);
130 char phase,
const uint8_t* category_enabled_flag,
const char* name,
131 const char* scope, uint64_t
id, uint64_t bind_id,
int num_args,
132 const char** arg_names,
const uint8_t* arg_types,
133 const uint64_t* arg_values,
134 std::unique_ptr<v8::ConvertableToTraceFormat>* arg_convertables,
135 unsigned int flags, int64_t timestamp) {
139 if (
recording_.load(std::memory_order_acquire)) {
140 TraceObject* trace_object =
trace_buffer_->AddTraceEvent(&handle);
144 trace_object->Initialize(phase, category_enabled_flag, name, scope,
id,
145 bind_id, num_args, arg_names, arg_types,
146 arg_values, arg_convertables, flags, timestamp,
155 const uint8_t* category_enabled_flag,
const char* name, uint64_t handle) {
160 if (!trace_object)
return;
165 const uint8_t* category_group_enabled) {
168 uintptr_t category_begin =
170 uintptr_t category_ptr =
reinterpret_cast<uintptr_t
>(category_group_enabled);
172 DCHECK(category_ptr >= category_begin &&
175 uintptr_t category_index =
182#ifdef V8_USE_PERFETTO
184 DCHECK(output_stream_->good());
185 perfetto::trace_processor::Config processor_config;
187 perfetto::trace_processor::TraceProcessorStorage::CreateInstance(
190 ::perfetto::TraceConfig perfetto_trace_config;
191 perfetto_trace_config.add_buffers()->set_size_kb(4096);
192 auto ds_config = perfetto_trace_config.add_data_sources()->mutable_config();
193 ds_config->set_name(
"track_event");
194 perfetto::protos::gen::TrackEventConfig te_config;
195 te_config.add_disabled_categories(
"*");
197 te_config.add_enabled_categories(category);
198 ds_config->set_track_event_config_raw(te_config.SerializeAsString());
201 perfetto::Tracing::NewTrace(perfetto::BackendType::kUnspecifiedBackend);
202 tracing_session_->Setup(perfetto_trace_config);
203 tracing_session_->StartBlocking();
208 recording_.store(
true, std::memory_order_release);
210#ifndef V8_USE_PERFETTO
211 std::unordered_set<v8::TracingController::TraceStateObserver*> observers_copy;
217 for (
auto o : observers_copy) {
224 bool expected =
true;
225 if (!
recording_.compare_exchange_strong(expected,
false)) {
228#ifndef V8_USE_PERFETTO
230 std::unordered_set<v8::TracingController::TraceStateObserver*> observers_copy;
235 for (
auto o : observers_copy) {
236 o->OnTraceDisabled();
240#ifdef V8_USE_PERFETTO
241 tracing_session_->StopBlocking();
243 std::vector<char> trace = tracing_session_->ReadTraceBlocking();
244 std::unique_ptr<uint8_t[]> trace_bytes(
new uint8_t[trace.size()]);
245 std::copy(&trace[0], &trace[0] + trace.size(), &trace_bytes[0]);
246 trace_processor_->Parse(std::move(trace_bytes), trace.size());
247 trace_processor_->NotifyEndOfFile();
248 JsonOutputWriter output_writer(output_stream_);
249 auto status = perfetto::trace_processor::json::ExportJson(
250 trace_processor_.get(), &output_writer,
nullptr,
nullptr,
nullptr);
253 if (listener_for_testing_) listener_for_testing_->ParseFromArray(trace);
255 trace_processor_.reset();
266#if !defined(V8_USE_PERFETTO)
268 unsigned char enabled_flag = 0;
270 if (
recording_.load(std::memory_order_acquire) &&
279 if (
recording_.load(std::memory_order_acquire) &&
280 !strcmp(category_group,
"__metadata")) {
295 const char* category_group) {
297 DCHECK(!strchr(category_group,
'"'));
303 for (
size_t i = 0;
i < category_index; ++
i) {
313 unsigned char* category_group_enabled =
nullptr;
315 for (
size_t i = 0;
i < category_index; ++
i) {
328 const char* new_group = strdup(category_group);
339 category_group_enabled =
342 return category_group_enabled;
350 if (!
recording_.load(std::memory_order_acquire))
return;
virtual void OnTraceEnabled()=0
int64_t ToInternalValue() const
void Relaxed_Store(volatile Atomic8 *ptr, Atomic8 value)
Atomic8 Acquire_Load(volatile const Atomic8 *ptr)
void Release_Store(volatile Atomic8 *ptr, Atomic8 value)
V8_INLINE IndirectHandle< T > handle(Tagged< T > object, Isolate *isolate)
#define DCHECK_NOT_NULL(val)
#define DCHECK(condition)