9 #include "include/libplatform/v8-tracing.h" 11 #include "src/base/atomicops.h" 12 #include "src/base/platform/mutex.h" 13 #include "src/base/platform/time.h" 19 #define MAX_CATEGORY_GROUPS 200 27 const char* g_category_groups[MAX_CATEGORY_GROUPS] = {
29 "tracing categories exhausted; must increase MAX_CATEGORY_GROUPS",
33 unsigned char g_category_group_enabled[MAX_CATEGORY_GROUPS] = {0};
35 const int g_category_categories_exhausted = 1;
38 const int g_num_builtin_categories = 3;
41 v8::base::AtomicWord g_category_index = g_num_builtin_categories;
43 TracingController::TracingController() =
default;
45 TracingController::~TracingController() {
50 base::MutexGuard lock(mutex_.get());
51 for (
size_t i = g_category_index - 1;
i >= g_num_builtin_categories; --
i) {
52 const char* group = g_category_groups[
i];
53 g_category_groups[
i] =
nullptr;
54 free(const_cast<char*>(group));
56 g_category_index = g_num_builtin_categories;
60 void TracingController::Initialize(TraceBuffer* trace_buffer) {
61 trace_buffer_.reset(trace_buffer);
62 mutex_.reset(
new base::Mutex());
65 int64_t TracingController::CurrentTimestampMicroseconds() {
66 return base::TimeTicks::HighResolutionNow().ToInternalValue();
69 int64_t TracingController::CurrentCpuTimestampMicroseconds() {
70 return base::ThreadTicks::Now().ToInternalValue();
73 uint64_t TracingController::AddTraceEvent(
74 char phase,
const uint8_t* category_enabled_flag,
const char* name,
75 const char* scope, uint64_t
id, uint64_t bind_id,
int num_args,
76 const char** arg_names,
const uint8_t* arg_types,
77 const uint64_t* arg_values,
78 std::unique_ptr<v8::ConvertableToTraceFormat>* arg_convertables,
81 if (mode_ != DISABLED) {
82 TraceObject* trace_object = trace_buffer_->AddTraceEvent(&handle);
84 trace_object->Initialize(
85 phase, category_enabled_flag, name, scope,
id, bind_id, num_args,
86 arg_names, arg_types, arg_values, arg_convertables, flags,
87 CurrentTimestampMicroseconds(), CurrentCpuTimestampMicroseconds());
93 uint64_t TracingController::AddTraceEventWithTimestamp(
94 char phase,
const uint8_t* category_enabled_flag,
const char* name,
95 const char* scope, uint64_t
id, uint64_t bind_id,
int num_args,
96 const char** arg_names,
const uint8_t* arg_types,
97 const uint64_t* arg_values,
98 std::unique_ptr<v8::ConvertableToTraceFormat>* arg_convertables,
99 unsigned int flags,
int64_t timestamp) {
101 if (mode_ != DISABLED) {
102 TraceObject* trace_object = trace_buffer_->AddTraceEvent(&handle);
104 trace_object->Initialize(phase, category_enabled_flag, name, scope,
id,
105 bind_id, num_args, arg_names, arg_types,
106 arg_values, arg_convertables, flags, timestamp,
107 CurrentCpuTimestampMicroseconds());
113 void TracingController::UpdateTraceEventDuration(
114 const uint8_t* category_enabled_flag,
const char* name, uint64_t handle) {
115 TraceObject* trace_object = trace_buffer_->GetEventByHandle(handle);
116 if (!trace_object)
return;
117 trace_object->UpdateDuration(CurrentTimestampMicroseconds(),
118 CurrentCpuTimestampMicroseconds());
121 const uint8_t* TracingController::GetCategoryGroupEnabled(
122 const char* category_group) {
123 return GetCategoryGroupEnabledInternal(category_group);
126 const char* TracingController::GetCategoryGroupName(
127 const uint8_t* category_group_enabled) {
131 reinterpret_cast<uintptr_t>(g_category_group_enabled);
134 DCHECK(category_ptr >= category_begin &&
135 category_ptr < reinterpret_cast<uintptr_t>(g_category_group_enabled +
136 MAX_CATEGORY_GROUPS));
138 (category_ptr - category_begin) /
sizeof(g_category_group_enabled[0]);
139 return g_category_groups[category_index];
142 void TracingController::StartTracing(TraceConfig* trace_config) {
143 trace_config_.reset(trace_config);
144 std::unordered_set<v8::TracingController::TraceStateObserver*> observers_copy;
146 base::MutexGuard lock(mutex_.get());
147 mode_ = RECORDING_MODE;
148 UpdateCategoryGroupEnabledFlags();
149 observers_copy = observers_;
151 for (
auto o : observers_copy) {
156 void TracingController::StopTracing() {
157 if (mode_ == DISABLED) {
160 DCHECK(trace_buffer_);
162 UpdateCategoryGroupEnabledFlags();
163 std::unordered_set<v8::TracingController::TraceStateObserver*> observers_copy;
165 base::MutexGuard lock(mutex_.get());
166 observers_copy = observers_;
168 for (
auto o : observers_copy) {
169 o->OnTraceDisabled();
171 trace_buffer_->Flush();
174 void TracingController::UpdateCategoryGroupEnabledFlag(
size_t category_index) {
175 unsigned char enabled_flag = 0;
176 const char* category_group = g_category_groups[category_index];
177 if (mode_ == RECORDING_MODE &&
178 trace_config_->IsCategoryGroupEnabled(category_group)) {
179 enabled_flag |= ENABLED_FOR_RECORDING;
186 if (mode_ == RECORDING_MODE && !strcmp(category_group,
"__metadata")) {
187 enabled_flag |= ENABLED_FOR_RECORDING;
190 base::Relaxed_Store(reinterpret_cast<base::Atomic8*>(
191 g_category_group_enabled + category_index),
195 void TracingController::UpdateCategoryGroupEnabledFlags() {
196 size_t category_index = base::Relaxed_Load(&g_category_index);
197 for (
size_t i = 0;
i < category_index;
i++) UpdateCategoryGroupEnabledFlag(
i);
200 const uint8_t* TracingController::GetCategoryGroupEnabledInternal(
201 const char* category_group) {
203 DCHECK(!strchr(category_group,
'"'));
206 size_t category_index = base::Acquire_Load(&g_category_index);
209 for (
size_t i = 0;
i < category_index; ++
i) {
210 if (strcmp(g_category_groups[
i], category_group) == 0) {
211 return &g_category_group_enabled[
i];
216 base::MutexGuard lock(mutex_.get());
219 unsigned char* category_group_enabled =
nullptr;
220 category_index = base::Acquire_Load(&g_category_index);
221 for (
size_t i = 0;
i < category_index; ++
i) {
222 if (strcmp(g_category_groups[
i], category_group) == 0) {
223 return &g_category_group_enabled[
i];
229 DCHECK(category_index < MAX_CATEGORY_GROUPS);
230 if (category_index < MAX_CATEGORY_GROUPS) {
234 const char* new_group = strdup(category_group);
235 g_category_groups[category_index] = new_group;
236 DCHECK(!g_category_group_enabled[category_index]);
240 UpdateCategoryGroupEnabledFlag(category_index);
241 category_group_enabled = &g_category_group_enabled[category_index];
243 base::Release_Store(&g_category_index, category_index + 1);
245 category_group_enabled =
246 &g_category_group_enabled[g_category_categories_exhausted];
248 return category_group_enabled;
251 void TracingController::AddTraceStateObserver(
254 base::MutexGuard lock(mutex_.get());
255 observers_.insert(observer);
256 if (mode_ != RECORDING_MODE)
return;
259 observer->OnTraceEnabled();
262 void TracingController::RemoveTraceStateObserver(
264 base::MutexGuard lock(mutex_.get());
265 DCHECK(observers_.find(observer) != observers_.end());
266 observers_.erase(observer);