OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 | 5 |
6 #ifndef BASE_DEBUG_TRACE_EVENT_IMPL_H_ | 6 #ifndef BASE_DEBUG_TRACE_EVENT_IMPL_H_ |
7 #define BASE_DEBUG_TRACE_EVENT_IMPL_H_ | 7 #define BASE_DEBUG_TRACE_EVENT_IMPL_H_ |
8 | 8 |
9 #include "build/build_config.h" | 9 #include "build/build_config.h" |
10 | 10 |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
58 long long as_int; | 58 long long as_int; |
59 double as_double; | 59 double as_double; |
60 const void* as_pointer; | 60 const void* as_pointer; |
61 const char* as_string; | 61 const char* as_string; |
62 }; | 62 }; |
63 | 63 |
64 TraceEvent(); | 64 TraceEvent(); |
65 TraceEvent(int thread_id, | 65 TraceEvent(int thread_id, |
66 TimeTicks timestamp, | 66 TimeTicks timestamp, |
67 char phase, | 67 char phase, |
68 const unsigned char* category_enabled, | 68 const unsigned char* category_group_enabled, |
69 const char* name, | 69 const char* name, |
70 unsigned long long id, | 70 unsigned long long id, |
71 int num_args, | 71 int num_args, |
72 const char** arg_names, | 72 const char** arg_names, |
73 const unsigned char* arg_types, | 73 const unsigned char* arg_types, |
74 const unsigned long long* arg_values, | 74 const unsigned long long* arg_values, |
75 unsigned char flags); | 75 unsigned char flags); |
76 ~TraceEvent(); | 76 ~TraceEvent(); |
77 | 77 |
78 // Serialize event data to JSON | 78 // Serialize event data to JSON |
79 static void AppendEventsAsJSON(const std::vector<TraceEvent>& events, | 79 static void AppendEventsAsJSON(const std::vector<TraceEvent>& events, |
80 size_t start, | 80 size_t start, |
81 size_t count, | 81 size_t count, |
82 std::string* out); | 82 std::string* out); |
83 void AppendAsJSON(std::string* out) const; | 83 void AppendAsJSON(std::string* out) const; |
84 | 84 |
85 static void AppendValueAsJSON(unsigned char type, | 85 static void AppendValueAsJSON(unsigned char type, |
86 TraceValue value, | 86 TraceValue value, |
87 std::string* out); | 87 std::string* out); |
88 | 88 |
89 TimeTicks timestamp() const { return timestamp_; } | 89 TimeTicks timestamp() const { return timestamp_; } |
90 | 90 |
91 // Exposed for unittesting: | 91 // Exposed for unittesting: |
92 | 92 |
93 const base::RefCountedString* parameter_copy_storage() const { | 93 const base::RefCountedString* parameter_copy_storage() const { |
94 return parameter_copy_storage_.get(); | 94 return parameter_copy_storage_.get(); |
95 } | 95 } |
96 | 96 |
97 const unsigned char* category_enabled() const { return category_enabled_; } | 97 const unsigned char* category_group_enabled() const { |
98 return category_group_enabled_; | |
99 } | |
100 | |
98 const char* name() const { return name_; } | 101 const char* name() const { return name_; } |
99 | 102 |
100 private: | 103 private: |
101 // Note: these are ordered by size (largest first) for optimal packing. | 104 // Note: these are ordered by size (largest first) for optimal packing. |
102 TimeTicks timestamp_; | 105 TimeTicks timestamp_; |
103 // id_ can be used to store phase-specific data. | 106 // id_ can be used to store phase-specific data. |
104 unsigned long long id_; | 107 unsigned long long id_; |
105 TraceValue arg_values_[kTraceMaxNumArgs]; | 108 TraceValue arg_values_[kTraceMaxNumArgs]; |
106 const char* arg_names_[kTraceMaxNumArgs]; | 109 const char* arg_names_[kTraceMaxNumArgs]; |
107 const unsigned char* category_enabled_; | 110 const unsigned char* category_group_enabled_; |
108 const char* name_; | 111 const char* name_; |
109 scoped_refptr<base::RefCountedString> parameter_copy_storage_; | 112 scoped_refptr<base::RefCountedString> parameter_copy_storage_; |
110 int thread_id_; | 113 int thread_id_; |
111 char phase_; | 114 char phase_; |
112 unsigned char flags_; | 115 unsigned char flags_; |
113 unsigned char arg_types_[kTraceMaxNumArgs]; | 116 unsigned char arg_types_[kTraceMaxNumArgs]; |
114 }; | 117 }; |
115 | 118 |
116 | 119 |
117 // TraceResultBuffer collects and converts trace fragments returned by TraceLog | 120 // TraceResultBuffer collects and converts trace fragments returned by TraceLog |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
150 | 153 |
151 // When all fragments have been added, call Finish to complete the JSON | 154 // When all fragments have been added, call Finish to complete the JSON |
152 // formatted output. | 155 // formatted output. |
153 void Finish(); | 156 void Finish(); |
154 | 157 |
155 private: | 158 private: |
156 OutputCallback output_callback_; | 159 OutputCallback output_callback_; |
157 bool append_comma_; | 160 bool append_comma_; |
158 }; | 161 }; |
159 | 162 |
163 class BASE_EXPORT CategoryFilter { | |
164 // The default category filter, used when none is provided. | |
165 // Allows all categories through, except if they end in the suffix 'Debug' or | |
166 // 'Test'. | |
167 static const char* kDefaultCategoryFilterString; | |
168 | |
169 public: | |
dsinclair
2013/02/22 21:13:44
nit: public should be indented 1 instead of 2.
rterrazas
2013/02/25 05:55:02
Done.
| |
170 // Constructs the default category filter. This is equivalent to | |
171 // CategoryFilter(CategoryFilter::kDefaultCategoryFilterString); | |
172 CategoryFilter(); | |
173 | |
174 // |filter_string| is a comma-delimited list of category wildcards. | |
175 // A category can have an optional '-' prefix to make it an excluded category. | |
176 // All the same rules apply above, so for example, having both included and | |
177 // excluded categories in the same list would not be supported. | |
178 // | |
179 // Example: SetEnabled("test_MyTest*"); | |
180 // Example: SetEnabled("test_MyTest*,test_OtherStuff"); | |
181 // Example: SetEnabled("-excluded_category1,-excluded_category2"); | |
nduca
2013/02/21 06:02:36
can you add an example of how to disable everythin
dsinclair
2013/02/22 21:13:44
Should these be s/SetEnabled/CategoryFilter/?
rterrazas
2013/02/25 05:55:02
Done.
rterrazas
2013/02/25 05:55:02
Done.
| |
182 CategoryFilter(const std::string& filter_string); | |
183 | |
184 // Writes the string representation of the CategoryFilter. This is a comma | |
185 // separated string, similar in nature to the one used to determine | |
186 // enabled/disabled category patterns, except here there is an arbitrary | |
187 // order, included categories go first, then excluded categories. Excluded | |
188 // categories are distinguished from included categories by the prefix '-'. | |
189 void ToString(std::string* filter_string) const; | |
dsinclair
2013/02/22 21:13:44
Why write to an input parameter instead of just re
rterrazas
2013/02/25 05:55:02
Did that to be consistent with the approach used w
| |
190 | |
191 // Determines whether category group would be enabled or | |
192 // disabled by this filter. | |
193 bool IsCategoryGroupEnabled(const char* category_group) const; | |
194 | |
195 // Merges nested_filter with the current CategoryFilter | |
196 void Merge(const CategoryFilter& nested_filter); | |
197 | |
198 // Determines whether or not we have included category patterns. | |
199 bool HasIncludedCategories() const; | |
nduca
2013/02/21 06:02:36
Not sure I get what this function does by its name
rterrazas
2013/02/25 05:55:02
Done.
| |
200 | |
201 // Clears both included/excluded pattern lists. | |
nduca
2013/02/21 06:02:36
So then what does it default to? kDefaultCategoryF
rterrazas
2013/02/25 05:55:02
Done.
| |
202 void Clear(); | |
203 | |
204 private: | |
dsinclair
2013/02/22 21:13:44
private should be indented 1.
rterrazas
2013/02/25 05:55:02
Done.
| |
205 void Initialize(const std::string& filter_string); | |
206 void WriteString(std::string* out, bool included) const; | |
207 | |
208 std::vector<std::string> included_; | |
209 std::vector<std::string> excluded_; | |
210 | |
211 }; | |
dsinclair
2013/02/22 21:13:44
Does this need a DISALLOW_COPY_AND_ASSIGN(Category
rterrazas
2013/02/25 05:55:02
Nope, we can't do that as we do assign to copy the
rterrazas
2013/02/25 06:05:44
However, I did overload = and provided an explicit
| |
160 | 212 |
161 class BASE_EXPORT TraceLog { | 213 class BASE_EXPORT TraceLog { |
162 public: | 214 public: |
163 // Notification is a mask of one or more of the following events. | 215 // Notification is a mask of one or more of the following events. |
164 enum Notification { | 216 enum Notification { |
165 // The trace buffer does not flush dynamically, so when it fills up, | 217 // The trace buffer does not flush dynamically, so when it fills up, |
166 // subsequent trace events will be dropped. This callback is generated when | 218 // subsequent trace events will be dropped. This callback is generated when |
167 // the trace buffer is full. The callback must be thread safe. | 219 // the trace buffer is full. The callback must be thread safe. |
168 TRACE_BUFFER_FULL = 1 << 0, | 220 TRACE_BUFFER_FULL = 1 << 0, |
169 // A subscribed trace-event occurred. | 221 // A subscribed trace-event occurred. |
170 EVENT_WATCH_NOTIFICATION = 1 << 1 | 222 EVENT_WATCH_NOTIFICATION = 1 << 1 |
171 }; | 223 }; |
172 | 224 |
173 static TraceLog* GetInstance(); | 225 static TraceLog* GetInstance(); |
174 | 226 |
175 // Get set of known categories. This can change as new code paths are reached. | 227 // Get set of known category groups. This can change as new code paths are |
176 // The known categories are inserted into |categories|. | 228 // reached. The known category groups are inserted into |category_groups|. |
177 void GetKnownCategories(std::vector<std::string>* categories); | 229 void GetKnownCategoryGroups(std::vector<std::string>* category_groups); |
178 | 230 |
179 // Enable tracing for provided list of categories. If tracing is already | 231 // Enables tracing. See CategoryFilter comments for details |
180 // enabled, this method does nothing -- changing categories during trace is | 232 // on how to control what categories will be traced. |
181 // not supported. | 233 void SetEnabled(const CategoryFilter& category_filter); |
182 // If both included_categories and excluded_categories are empty, | |
183 // all categories are traced. | |
184 // Else if included_categories is non-empty, only those are traced. | |
185 // Else if excluded_categories is non-empty, everything but those are traced. | |
186 // Wildcards * and ? are supported (see MatchPattern in string_util.h). | |
187 void SetEnabled(const std::vector<std::string>& included_categories, | |
188 const std::vector<std::string>& excluded_categories); | |
189 | |
190 // |categories| is a comma-delimited list of category wildcards. | |
191 // A category can have an optional '-' prefix to make it an excluded category. | |
192 // All the same rules apply above, so for example, having both included and | |
193 // excluded categories in the same list would not be supported. | |
194 // | |
195 // Example: SetEnabled("test_MyTest*"); | |
196 // Example: SetEnabled("test_MyTest*,test_OtherStuff"); | |
197 // Example: SetEnabled("-excluded_category1,-excluded_category2"); | |
198 void SetEnabled(const std::string& categories); | |
199 | |
200 // Retieves the categories set via a prior call to SetEnabled(). Only | |
201 // meaningful if |IsEnabled()| is true. | |
202 void GetEnabledTraceCategories(std::vector<std::string>* included_out, | |
203 std::vector<std::string>* excluded_out); | |
204 | 234 |
205 // Disable tracing for all categories. | 235 // Disable tracing for all categories. |
206 void SetDisabled(); | 236 void SetDisabled(); |
237 | |
238 // Retieves the current filter used to enable categories. Only | |
239 // meaningful if |IsEnabled()| is true. | |
nduca
2013/02/21 06:02:36
Dont like that this returns a non-const reference.
rterrazas
2013/02/25 05:55:02
Right, that wasn't by design, that was a mistake I
| |
240 CategoryFilter& GetCurrentCategoryFilter(); | |
241 | |
207 // Helper method to enable/disable tracing for all categories. | 242 // Helper method to enable/disable tracing for all categories. |
208 void SetEnabled(bool enabled); | |
209 bool IsEnabled() { return !!enable_count_; } | 243 bool IsEnabled() { return !!enable_count_; } |
210 | 244 |
211 #if defined(OS_ANDROID) | 245 #if defined(OS_ANDROID) |
212 void StartATrace(); | 246 void StartATrace(); |
213 void StopATrace(); | 247 void StopATrace(); |
214 #endif | 248 #endif |
215 | 249 |
216 // Enabled state listeners give a callback when tracing is enabled or | 250 // Enabled state listeners give a callback when tracing is enabled or |
217 // disabled. This can be used to tie into other library's tracing systems | 251 // disabled. This can be used to tie into other library's tracing systems |
218 // on-demand. | 252 // on-demand. |
(...skipping 25 matching lines...) Expand all Loading... | |
244 | 278 |
245 // Flush all collected events to the given output callback. The callback will | 279 // Flush all collected events to the given output callback. The callback will |
246 // be called one or more times with IPC-bite-size chunks. The string format is | 280 // be called one or more times with IPC-bite-size chunks. The string format is |
247 // undefined. Use TraceResultBuffer to convert one or more trace strings to | 281 // undefined. Use TraceResultBuffer to convert one or more trace strings to |
248 // JSON. | 282 // JSON. |
249 typedef base::Callback<void(const scoped_refptr<base::RefCountedString>&)> | 283 typedef base::Callback<void(const scoped_refptr<base::RefCountedString>&)> |
250 OutputCallback; | 284 OutputCallback; |
251 void Flush(const OutputCallback& cb); | 285 void Flush(const OutputCallback& cb); |
252 | 286 |
253 // Called by TRACE_EVENT* macros, don't call this directly. | 287 // Called by TRACE_EVENT* macros, don't call this directly. |
254 static const unsigned char* GetCategoryEnabled(const char* name); | 288 // The name parameter is a category group for example: |
255 static const char* GetCategoryName(const unsigned char* category_enabled); | 289 // TRACE_EVENT0("renderer,webkit", "WebViewImpl::HandleInputEvent") |
290 static const unsigned char* GetCategoryGroupEnabled(const char* name); | |
291 static const char* GetCategoryGroupName( | |
292 const unsigned char* category_group_enabled); | |
dsinclair
2013/02/22 21:13:44
nit: This should be indented 4 from static on the
rterrazas
2013/02/25 05:55:02
Done.
| |
256 | 293 |
257 // Called by TRACE_EVENT* macros, don't call this directly. | 294 // Called by TRACE_EVENT* macros, don't call this directly. |
258 // If |copy| is set, |name|, |arg_name1| and |arg_name2| will be deep copied | 295 // If |copy| is set, |name|, |arg_name1| and |arg_name2| will be deep copied |
259 // into the event; see "Memory scoping note" and TRACE_EVENT_COPY_XXX above. | 296 // into the event; see "Memory scoping note" and TRACE_EVENT_COPY_XXX above. |
260 void AddTraceEvent(char phase, | 297 void AddTraceEvent(char phase, |
261 const unsigned char* category_enabled, | 298 const unsigned char* category_group_enabled, |
262 const char* name, | 299 const char* category_group, |
dsinclair
2013/02/22 21:13:44
nit: indenting.
rterrazas
2013/02/25 05:55:02
Done.
| |
263 unsigned long long id, | 300 unsigned long long id, |
264 int num_args, | 301 int num_args, |
265 const char** arg_names, | 302 const char** arg_names, |
266 const unsigned char* arg_types, | 303 const unsigned char* arg_types, |
267 const unsigned long long* arg_values, | 304 const unsigned long long* arg_values, |
268 unsigned char flags); | 305 unsigned char flags); |
269 void AddTraceEventWithThreadIdAndTimestamp( | 306 void AddTraceEventWithThreadIdAndTimestamp( |
270 char phase, | 307 char phase, |
271 const unsigned char* category_enabled, | 308 const unsigned char* category_enabled, |
272 const char* name, | 309 const char* name, |
273 unsigned long long id, | 310 unsigned long long id, |
274 int thread_id, | 311 int thread_id, |
275 const TimeTicks& timestamp, | 312 const TimeTicks& timestamp, |
276 int num_args, | 313 int num_args, |
277 const char** arg_names, | 314 const char** arg_names, |
278 const unsigned char* arg_types, | 315 const unsigned char* arg_types, |
279 const unsigned long long* arg_values, | 316 const unsigned long long* arg_values, |
280 unsigned char flags); | 317 unsigned char flags); |
281 static void AddTraceEventEtw(char phase, | 318 static void AddTraceEventEtw(char phase, |
282 const char* name, | 319 const char* category_group, |
283 const void* id, | 320 const void* id, |
284 const char* extra); | 321 const char* extra); |
285 static void AddTraceEventEtw(char phase, | 322 static void AddTraceEventEtw(char phase, |
286 const char* name, | 323 const char* category_group, |
287 const void* id, | 324 const void* id, |
288 const std::string& extra); | 325 const std::string& extra); |
289 | 326 |
290 // For every matching event, a notification will be fired. NOTE: the | 327 // For every matching event, a notification will be fired. NOTE: the |
291 // notification will fire for each matching event that has already occurred | 328 // notification will fire for each matching event that has already occurred |
292 // since tracing was started (including before tracing if the process was | 329 // since tracing was started (including before tracing if the process was |
293 // started with tracing turned on). | 330 // started with tracing turned on). |
294 void SetWatchEvent(const std::string& category_name, | 331 void SetWatchEvent(const std::string& category_name, |
295 const std::string& event_name); | 332 const std::string& event_name); |
296 // Cancel the watch event. If tracing is enabled, this may race with the | 333 // Cancel the watch event. If tracing is enabled, this may race with the |
(...skipping 21 matching lines...) Expand all Loading... | |
318 | 355 |
319 // Allow setting an offset between the current TimeTicks time and the time | 356 // Allow setting an offset between the current TimeTicks time and the time |
320 // that should be reported. | 357 // that should be reported. |
321 void SetTimeOffset(TimeDelta offset); | 358 void SetTimeOffset(TimeDelta offset); |
322 | 359 |
323 private: | 360 private: |
324 // This allows constructor and destructor to be private and usable only | 361 // This allows constructor and destructor to be private and usable only |
325 // by the Singleton class. | 362 // by the Singleton class. |
326 friend struct StaticMemorySingletonTraits<TraceLog>; | 363 friend struct StaticMemorySingletonTraits<TraceLog>; |
327 | 364 |
328 // The pointer returned from GetCategoryEnabledInternal() points to a value | 365 // Enable/disable each category group based on the given |category_filter|. |
329 // with zero or more of the following bits. Used in this class only. | 366 // If the category group contains a category that matches an included category |
367 // pattern, that category group will be enabled. | |
368 static void EnableIncludedCategoryGroups( | |
369 const CategoryFilter& category_filter); | |
nduca
2013/02/21 06:02:36
indent is funky here. Indent to 4 lines when you w
rterrazas
2013/02/25 05:55:02
Done.
| |
370 static void EnableIncludedCategoryGroup(int category_index, | |
371 const CategoryFilter& category_filter); | |
372 | |
373 // The pointer returned from GetCategoryGroupEnabledInternal() points to a | |
374 // value with zero or more of the following bits. Used in this class only. | |
330 // The TRACE_EVENT macros should only use the value as a bool. | 375 // The TRACE_EVENT macros should only use the value as a bool. |
331 enum CategoryEnabledFlags { | 376 enum CategoryEnabledFlags { |
332 // Normal enabled flag for categories enabled with Enable(). | 377 // Normal enabled flag for categories enabled with Enable(). |
333 CATEGORY_ENABLED = 1 << 0, | 378 CATEGORY_ENABLED = 1 << 0, |
334 // On Android if ATrace is enabled, all categories will have this bit. | 379 // On Android if ATrace is enabled, all categories will have this bit. |
335 // Not used on other platforms. | 380 // Not used on other platforms. |
336 ATRACE_ENABLED = 1 << 1 | 381 ATRACE_ENABLED = 1 << 1 |
337 }; | 382 }; |
338 | 383 |
339 // Helper class for managing notification_thread_count_ and running | 384 // Helper class for managing notification_thread_count_ and running |
(...skipping 14 matching lines...) Expand all Loading... | |
354 inline void SendNotificationIfAny(); | 399 inline void SendNotificationIfAny(); |
355 | 400 |
356 private: | 401 private: |
357 TraceLog* trace_log_; | 402 TraceLog* trace_log_; |
358 NotificationCallback callback_copy_; | 403 NotificationCallback callback_copy_; |
359 int notification_; | 404 int notification_; |
360 }; | 405 }; |
361 | 406 |
362 TraceLog(); | 407 TraceLog(); |
363 ~TraceLog(); | 408 ~TraceLog(); |
364 const unsigned char* GetCategoryEnabledInternal(const char* name); | 409 const unsigned char* GetCategoryGroupEnabledInternal(const char* name); |
365 void AddThreadNameMetadataEvents(); | 410 void AddThreadNameMetadataEvents(); |
366 | 411 |
367 #if defined(OS_ANDROID) | 412 #if defined(OS_ANDROID) |
368 void SendToATrace(char phase, | 413 void SendToATrace(char phase, |
369 const char* category, | 414 const char* category_group, |
370 const char* name, | 415 const char* name, |
371 int num_args, | 416 int num_args, |
372 const char** arg_names, | 417 const char** arg_names, |
373 const unsigned char* arg_types, | 418 const unsigned char* arg_types, |
374 const unsigned long long* arg_values); | 419 const unsigned long long* arg_values); |
375 static void ApplyATraceEnabledFlag(unsigned char* category_enabled); | 420 static void ApplyATraceEnabledFlag(unsigned char* category_group_enabled); |
376 #endif | 421 #endif |
377 | 422 |
378 // TODO(nduca): switch to per-thread trace buffers to reduce thread | 423 // TODO(nduca): switch to per-thread trace buffers to reduce thread |
379 // synchronization. | 424 // synchronization. |
380 // This lock protects TraceLog member accesses from arbitrary threads. | 425 // This lock protects TraceLog member accesses from arbitrary threads. |
381 Lock lock_; | 426 Lock lock_; |
382 int enable_count_; | 427 int enable_count_; |
383 NotificationCallback notification_callback_; | 428 NotificationCallback notification_callback_; |
384 std::vector<TraceEvent> logged_events_; | 429 std::vector<TraceEvent> logged_events_; |
385 std::vector<std::string> included_categories_; | 430 CategoryFilter category_filter_; |
386 std::vector<std::string> excluded_categories_; | |
387 bool dispatching_to_observer_list_; | 431 bool dispatching_to_observer_list_; |
388 ObserverList<EnabledStateChangedObserver> enabled_state_observer_list_; | 432 ObserverList<EnabledStateChangedObserver> enabled_state_observer_list_; |
389 | 433 |
390 base::hash_map<int, std::string> thread_names_; | 434 base::hash_map<int, std::string> thread_names_; |
391 | 435 |
392 // XORed with TraceID to make it unlikely to collide with other processes. | 436 // XORed with TraceID to make it unlikely to collide with other processes. |
393 unsigned long long process_id_hash_; | 437 unsigned long long process_id_hash_; |
394 | 438 |
395 int process_id_; | 439 int process_id_; |
396 | 440 |
397 TimeDelta time_offset_; | 441 TimeDelta time_offset_; |
398 | 442 |
399 // Allow tests to wake up when certain events occur. | 443 // Allow tests to wake up when certain events occur. |
400 const unsigned char* watch_category_; | 444 const unsigned char* watch_category_; |
401 std::string watch_event_name_; | 445 std::string watch_event_name_; |
402 | 446 |
403 DISALLOW_COPY_AND_ASSIGN(TraceLog); | 447 DISALLOW_COPY_AND_ASSIGN(TraceLog); |
404 }; | 448 }; |
405 | 449 |
406 } // namespace debug | 450 } // namespace debug |
407 } // namespace base | 451 } // namespace base |
408 | 452 |
409 #endif // BASE_DEBUG_TRACE_EVENT_IMPL_H_ | 453 #endif // BASE_DEBUG_TRACE_EVENT_IMPL_H_ |
OLD | NEW |