File indexing completed on 2025-02-22 10:42:27
0001
0002
0003
0004
0005 #ifndef V8_LIBPLATFORM_V8_TRACING_H_
0006 #define V8_LIBPLATFORM_V8_TRACING_H_
0007
0008 #include <atomic>
0009 #include <fstream>
0010 #include <memory>
0011 #include <unordered_set>
0012 #include <vector>
0013
0014 #include "libplatform/libplatform-export.h"
0015 #include "v8-platform.h" // NOLINT(build/include_directory)
0016
0017 namespace perfetto {
0018 namespace trace_processor {
0019 class TraceProcessorStorage;
0020 }
0021 class TracingSession;
0022 }
0023
0024 namespace v8 {
0025
0026 namespace base {
0027 class Mutex;
0028 }
0029
0030 namespace platform {
0031 namespace tracing {
0032
0033 class TraceEventListener;
0034
0035 const int kTraceMaxNumArgs = 2;
0036
0037 class V8_PLATFORM_EXPORT TraceObject {
0038 public:
0039 union ArgValue {
0040 uint64_t as_uint;
0041 int64_t as_int;
0042 double as_double;
0043 const void* as_pointer;
0044 const char* as_string;
0045 };
0046
0047 TraceObject() = default;
0048 ~TraceObject();
0049 void Initialize(
0050 char phase, const uint8_t* category_enabled_flag, const char* name,
0051 const char* scope, uint64_t id, uint64_t bind_id, int num_args,
0052 const char** arg_names, const uint8_t* arg_types,
0053 const uint64_t* arg_values,
0054 std::unique_ptr<v8::ConvertableToTraceFormat>* arg_convertables,
0055 unsigned int flags, int64_t timestamp, int64_t cpu_timestamp);
0056 void UpdateDuration(int64_t timestamp, int64_t cpu_timestamp);
0057 void InitializeForTesting(
0058 char phase, const uint8_t* category_enabled_flag, const char* name,
0059 const char* scope, uint64_t id, uint64_t bind_id, int num_args,
0060 const char** arg_names, const uint8_t* arg_types,
0061 const uint64_t* arg_values,
0062 std::unique_ptr<v8::ConvertableToTraceFormat>* arg_convertables,
0063 unsigned int flags, int pid, int tid, int64_t ts, int64_t tts,
0064 uint64_t duration, uint64_t cpu_duration);
0065
0066 int pid() const { return pid_; }
0067 int tid() const { return tid_; }
0068 char phase() const { return phase_; }
0069 const uint8_t* category_enabled_flag() const {
0070 return category_enabled_flag_;
0071 }
0072 const char* name() const { return name_; }
0073 const char* scope() const { return scope_; }
0074 uint64_t id() const { return id_; }
0075 uint64_t bind_id() const { return bind_id_; }
0076 int num_args() const { return num_args_; }
0077 const char** arg_names() { return arg_names_; }
0078 uint8_t* arg_types() { return arg_types_; }
0079 ArgValue* arg_values() { return arg_values_; }
0080 std::unique_ptr<v8::ConvertableToTraceFormat>* arg_convertables() {
0081 return arg_convertables_;
0082 }
0083 unsigned int flags() const { return flags_; }
0084 int64_t ts() { return ts_; }
0085 int64_t tts() { return tts_; }
0086 uint64_t duration() { return duration_; }
0087 uint64_t cpu_duration() { return cpu_duration_; }
0088
0089 private:
0090 int pid_;
0091 int tid_;
0092 char phase_;
0093 const char* name_;
0094 const char* scope_;
0095 const uint8_t* category_enabled_flag_;
0096 uint64_t id_;
0097 uint64_t bind_id_;
0098 int num_args_ = 0;
0099 const char* arg_names_[kTraceMaxNumArgs];
0100 uint8_t arg_types_[kTraceMaxNumArgs];
0101 ArgValue arg_values_[kTraceMaxNumArgs];
0102 std::unique_ptr<v8::ConvertableToTraceFormat>
0103 arg_convertables_[kTraceMaxNumArgs];
0104 char* parameter_copy_storage_ = nullptr;
0105 unsigned int flags_;
0106 int64_t ts_;
0107 int64_t tts_;
0108 uint64_t duration_;
0109 uint64_t cpu_duration_;
0110
0111
0112 TraceObject(const TraceObject&) = delete;
0113 void operator=(const TraceObject&) = delete;
0114 };
0115
0116 class V8_PLATFORM_EXPORT TraceWriter {
0117 public:
0118 TraceWriter() = default;
0119 virtual ~TraceWriter() = default;
0120 virtual void AppendTraceEvent(TraceObject* trace_event) = 0;
0121 virtual void Flush() = 0;
0122
0123 static TraceWriter* CreateJSONTraceWriter(std::ostream& stream);
0124 static TraceWriter* CreateJSONTraceWriter(std::ostream& stream,
0125 const std::string& tag);
0126
0127 static TraceWriter* CreateSystemInstrumentationTraceWriter();
0128
0129 private:
0130
0131 TraceWriter(const TraceWriter&) = delete;
0132 void operator=(const TraceWriter&) = delete;
0133 };
0134
0135 class V8_PLATFORM_EXPORT TraceBufferChunk {
0136 public:
0137 explicit TraceBufferChunk(uint32_t seq);
0138
0139 void Reset(uint32_t new_seq);
0140 bool IsFull() const { return next_free_ == kChunkSize; }
0141 TraceObject* AddTraceEvent(size_t* event_index);
0142 TraceObject* GetEventAt(size_t index) { return &chunk_[index]; }
0143
0144 uint32_t seq() const { return seq_; }
0145 size_t size() const { return next_free_; }
0146
0147 static const size_t kChunkSize = 64;
0148
0149 private:
0150 size_t next_free_ = 0;
0151 TraceObject chunk_[kChunkSize];
0152 uint32_t seq_;
0153
0154
0155 TraceBufferChunk(const TraceBufferChunk&) = delete;
0156 void operator=(const TraceBufferChunk&) = delete;
0157 };
0158
0159 class V8_PLATFORM_EXPORT TraceBuffer {
0160 public:
0161 TraceBuffer() = default;
0162 virtual ~TraceBuffer() = default;
0163
0164 virtual TraceObject* AddTraceEvent(uint64_t* handle) = 0;
0165 virtual TraceObject* GetEventByHandle(uint64_t handle) = 0;
0166 virtual bool Flush() = 0;
0167
0168 static const size_t kRingBufferChunks = 1024;
0169
0170 static TraceBuffer* CreateTraceBufferRingBuffer(size_t max_chunks,
0171 TraceWriter* trace_writer);
0172
0173 private:
0174
0175 TraceBuffer(const TraceBuffer&) = delete;
0176 void operator=(const TraceBuffer&) = delete;
0177 };
0178
0179
0180 enum TraceRecordMode {
0181
0182 RECORD_UNTIL_FULL,
0183
0184
0185
0186 RECORD_CONTINUOUSLY,
0187
0188
0189 RECORD_AS_MUCH_AS_POSSIBLE,
0190
0191
0192 ECHO_TO_CONSOLE,
0193 };
0194
0195 class V8_PLATFORM_EXPORT TraceConfig {
0196 public:
0197 typedef std::vector<std::string> StringList;
0198
0199 static TraceConfig* CreateDefaultTraceConfig();
0200
0201 TraceConfig() : enable_systrace_(false), enable_argument_filter_(false) {}
0202 TraceRecordMode GetTraceRecordMode() const { return record_mode_; }
0203 const StringList& GetEnabledCategories() const {
0204 return included_categories_;
0205 }
0206 bool IsSystraceEnabled() const { return enable_systrace_; }
0207 bool IsArgumentFilterEnabled() const { return enable_argument_filter_; }
0208
0209 void SetTraceRecordMode(TraceRecordMode mode) { record_mode_ = mode; }
0210 void EnableSystrace() { enable_systrace_ = true; }
0211 void EnableArgumentFilter() { enable_argument_filter_ = true; }
0212
0213 void AddIncludedCategory(const char* included_category);
0214
0215 bool IsCategoryGroupEnabled(const char* category_group) const;
0216
0217 private:
0218 TraceRecordMode record_mode_;
0219 bool enable_systrace_ : 1;
0220 bool enable_argument_filter_ : 1;
0221 StringList included_categories_;
0222
0223
0224 TraceConfig(const TraceConfig&) = delete;
0225 void operator=(const TraceConfig&) = delete;
0226 };
0227
0228 #if defined(_MSC_VER)
0229 #define V8_PLATFORM_NON_EXPORTED_BASE(code) \
0230 __pragma(warning(suppress : 4275)) code
0231 #else
0232 #define V8_PLATFORM_NON_EXPORTED_BASE(code) code
0233 #endif
0234
0235 class V8_PLATFORM_EXPORT TracingController
0236 : public V8_PLATFORM_NON_EXPORTED_BASE(v8::TracingController) {
0237 public:
0238 TracingController();
0239 ~TracingController() override;
0240
0241 #if defined(V8_USE_PERFETTO)
0242
0243
0244 void InitializeForPerfetto(std::ostream* output_stream);
0245
0246
0247 void SetTraceEventListenerForTesting(TraceEventListener* listener);
0248 #else
0249
0250
0251
0252
0253 enum CategoryGroupEnabledFlags {
0254
0255 ENABLED_FOR_RECORDING = 1 << 0,
0256
0257 ENABLED_FOR_EVENT_CALLBACK = 1 << 2,
0258
0259 ENABLED_FOR_ETW_EXPORT = 1 << 3
0260 };
0261
0262
0263 void Initialize(TraceBuffer* trace_buffer);
0264
0265
0266 const uint8_t* GetCategoryGroupEnabled(const char* category_group) override;
0267 uint64_t AddTraceEvent(
0268 char phase, const uint8_t* category_enabled_flag, const char* name,
0269 const char* scope, uint64_t id, uint64_t bind_id, int32_t num_args,
0270 const char** arg_names, const uint8_t* arg_types,
0271 const uint64_t* arg_values,
0272 std::unique_ptr<v8::ConvertableToTraceFormat>* arg_convertables,
0273 unsigned int flags) override;
0274 uint64_t AddTraceEventWithTimestamp(
0275 char phase, const uint8_t* category_enabled_flag, const char* name,
0276 const char* scope, uint64_t id, uint64_t bind_id, int32_t num_args,
0277 const char** arg_names, const uint8_t* arg_types,
0278 const uint64_t* arg_values,
0279 std::unique_ptr<v8::ConvertableToTraceFormat>* arg_convertables,
0280 unsigned int flags, int64_t timestamp) override;
0281 void UpdateTraceEventDuration(const uint8_t* category_enabled_flag,
0282 const char* name, uint64_t handle) override;
0283
0284 static const char* GetCategoryGroupName(const uint8_t* category_enabled_flag);
0285
0286 void AddTraceStateObserver(
0287 v8::TracingController::TraceStateObserver* observer) override;
0288 void RemoveTraceStateObserver(
0289 v8::TracingController::TraceStateObserver* observer) override;
0290 #endif
0291
0292 void StartTracing(TraceConfig* trace_config);
0293 void StopTracing();
0294
0295 protected:
0296 #if !defined(V8_USE_PERFETTO)
0297 virtual int64_t CurrentTimestampMicroseconds();
0298 virtual int64_t CurrentCpuTimestampMicroseconds();
0299 #endif
0300
0301 private:
0302 #if !defined(V8_USE_PERFETTO)
0303 void UpdateCategoryGroupEnabledFlag(size_t category_index);
0304 void UpdateCategoryGroupEnabledFlags();
0305 #endif
0306
0307 std::unique_ptr<base::Mutex> mutex_;
0308 std::unique_ptr<TraceConfig> trace_config_;
0309 std::atomic_bool recording_{false};
0310
0311 #if defined(V8_USE_PERFETTO)
0312 std::ostream* output_stream_ = nullptr;
0313 std::unique_ptr<perfetto::trace_processor::TraceProcessorStorage>
0314 trace_processor_;
0315 TraceEventListener* listener_for_testing_ = nullptr;
0316 std::unique_ptr<perfetto::TracingSession> tracing_session_;
0317 #else
0318 std::unordered_set<v8::TracingController::TraceStateObserver*> observers_;
0319 std::unique_ptr<TraceBuffer> trace_buffer_;
0320 #endif
0321
0322
0323 TracingController(const TracingController&) = delete;
0324 void operator=(const TracingController&) = delete;
0325 };
0326
0327 #undef V8_PLATFORM_NON_EXPORTED_BASE
0328
0329 }
0330 }
0331 }
0332
0333 #endif