Turn audio into a shareable video. forked from nypublicradio/audiogram

v8-tracing.h 10KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317
  1. // Copyright 2016 the V8 project authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #ifndef V8_LIBPLATFORM_V8_TRACING_H_
  5. #define V8_LIBPLATFORM_V8_TRACING_H_
  6. #include <atomic>
  7. #include <fstream>
  8. #include <memory>
  9. #include <unordered_set>
  10. #include <vector>
  11. #include "libplatform/libplatform-export.h"
  12. #include "v8-platform.h" // NOLINT(build/include)
  13. namespace perfetto {
  14. class TracingSession;
  15. }
  16. namespace v8 {
  17. namespace base {
  18. class Mutex;
  19. } // namespace base
  20. namespace platform {
  21. namespace tracing {
  22. class TraceEventListener;
  23. class JSONTraceEventListener;
  24. const int kTraceMaxNumArgs = 2;
  25. class V8_PLATFORM_EXPORT TraceObject {
  26. public:
  27. union ArgValue {
  28. bool as_bool;
  29. uint64_t as_uint;
  30. int64_t as_int;
  31. double as_double;
  32. const void* as_pointer;
  33. const char* as_string;
  34. };
  35. TraceObject() = default;
  36. ~TraceObject();
  37. void Initialize(
  38. char phase, const uint8_t* category_enabled_flag, const char* name,
  39. const char* scope, uint64_t id, uint64_t bind_id, int num_args,
  40. const char** arg_names, const uint8_t* arg_types,
  41. const uint64_t* arg_values,
  42. std::unique_ptr<v8::ConvertableToTraceFormat>* arg_convertables,
  43. unsigned int flags, int64_t timestamp, int64_t cpu_timestamp);
  44. void UpdateDuration(int64_t timestamp, int64_t cpu_timestamp);
  45. void InitializeForTesting(
  46. char phase, const uint8_t* category_enabled_flag, const char* name,
  47. const char* scope, uint64_t id, uint64_t bind_id, int num_args,
  48. const char** arg_names, const uint8_t* arg_types,
  49. const uint64_t* arg_values,
  50. std::unique_ptr<v8::ConvertableToTraceFormat>* arg_convertables,
  51. unsigned int flags, int pid, int tid, int64_t ts, int64_t tts,
  52. uint64_t duration, uint64_t cpu_duration);
  53. int pid() const { return pid_; }
  54. int tid() const { return tid_; }
  55. char phase() const { return phase_; }
  56. const uint8_t* category_enabled_flag() const {
  57. return category_enabled_flag_;
  58. }
  59. const char* name() const { return name_; }
  60. const char* scope() const { return scope_; }
  61. uint64_t id() const { return id_; }
  62. uint64_t bind_id() const { return bind_id_; }
  63. int num_args() const { return num_args_; }
  64. const char** arg_names() { return arg_names_; }
  65. uint8_t* arg_types() { return arg_types_; }
  66. ArgValue* arg_values() { return arg_values_; }
  67. std::unique_ptr<v8::ConvertableToTraceFormat>* arg_convertables() {
  68. return arg_convertables_;
  69. }
  70. unsigned int flags() const { return flags_; }
  71. int64_t ts() { return ts_; }
  72. int64_t tts() { return tts_; }
  73. uint64_t duration() { return duration_; }
  74. uint64_t cpu_duration() { return cpu_duration_; }
  75. private:
  76. int pid_;
  77. int tid_;
  78. char phase_;
  79. const char* name_;
  80. const char* scope_;
  81. const uint8_t* category_enabled_flag_;
  82. uint64_t id_;
  83. uint64_t bind_id_;
  84. int num_args_ = 0;
  85. const char* arg_names_[kTraceMaxNumArgs];
  86. uint8_t arg_types_[kTraceMaxNumArgs];
  87. ArgValue arg_values_[kTraceMaxNumArgs];
  88. std::unique_ptr<v8::ConvertableToTraceFormat>
  89. arg_convertables_[kTraceMaxNumArgs];
  90. char* parameter_copy_storage_ = nullptr;
  91. unsigned int flags_;
  92. int64_t ts_;
  93. int64_t tts_;
  94. uint64_t duration_;
  95. uint64_t cpu_duration_;
  96. // Disallow copy and assign
  97. TraceObject(const TraceObject&) = delete;
  98. void operator=(const TraceObject&) = delete;
  99. };
  100. class V8_PLATFORM_EXPORT TraceWriter {
  101. public:
  102. TraceWriter() = default;
  103. virtual ~TraceWriter() = default;
  104. virtual void AppendTraceEvent(TraceObject* trace_event) = 0;
  105. virtual void Flush() = 0;
  106. static TraceWriter* CreateJSONTraceWriter(std::ostream& stream);
  107. static TraceWriter* CreateJSONTraceWriter(std::ostream& stream,
  108. const std::string& tag);
  109. private:
  110. // Disallow copy and assign
  111. TraceWriter(const TraceWriter&) = delete;
  112. void operator=(const TraceWriter&) = delete;
  113. };
  114. class V8_PLATFORM_EXPORT TraceBufferChunk {
  115. public:
  116. explicit TraceBufferChunk(uint32_t seq);
  117. void Reset(uint32_t new_seq);
  118. bool IsFull() const { return next_free_ == kChunkSize; }
  119. TraceObject* AddTraceEvent(size_t* event_index);
  120. TraceObject* GetEventAt(size_t index) { return &chunk_[index]; }
  121. uint32_t seq() const { return seq_; }
  122. size_t size() const { return next_free_; }
  123. static const size_t kChunkSize = 64;
  124. private:
  125. size_t next_free_ = 0;
  126. TraceObject chunk_[kChunkSize];
  127. uint32_t seq_;
  128. // Disallow copy and assign
  129. TraceBufferChunk(const TraceBufferChunk&) = delete;
  130. void operator=(const TraceBufferChunk&) = delete;
  131. };
  132. class V8_PLATFORM_EXPORT TraceBuffer {
  133. public:
  134. TraceBuffer() = default;
  135. virtual ~TraceBuffer() = default;
  136. virtual TraceObject* AddTraceEvent(uint64_t* handle) = 0;
  137. virtual TraceObject* GetEventByHandle(uint64_t handle) = 0;
  138. virtual bool Flush() = 0;
  139. static const size_t kRingBufferChunks = 1024;
  140. static TraceBuffer* CreateTraceBufferRingBuffer(size_t max_chunks,
  141. TraceWriter* trace_writer);
  142. private:
  143. // Disallow copy and assign
  144. TraceBuffer(const TraceBuffer&) = delete;
  145. void operator=(const TraceBuffer&) = delete;
  146. };
  147. // Options determines how the trace buffer stores data.
  148. enum TraceRecordMode {
  149. // Record until the trace buffer is full.
  150. RECORD_UNTIL_FULL,
  151. // Record until the user ends the trace. The trace buffer is a fixed size
  152. // and we use it as a ring buffer during recording.
  153. RECORD_CONTINUOUSLY,
  154. // Record until the trace buffer is full, but with a huge buffer size.
  155. RECORD_AS_MUCH_AS_POSSIBLE,
  156. // Echo to console. Events are discarded.
  157. ECHO_TO_CONSOLE,
  158. };
  159. class V8_PLATFORM_EXPORT TraceConfig {
  160. public:
  161. typedef std::vector<std::string> StringList;
  162. static TraceConfig* CreateDefaultTraceConfig();
  163. TraceConfig() : enable_systrace_(false), enable_argument_filter_(false) {}
  164. TraceRecordMode GetTraceRecordMode() const { return record_mode_; }
  165. bool IsSystraceEnabled() const { return enable_systrace_; }
  166. bool IsArgumentFilterEnabled() const { return enable_argument_filter_; }
  167. void SetTraceRecordMode(TraceRecordMode mode) { record_mode_ = mode; }
  168. void EnableSystrace() { enable_systrace_ = true; }
  169. void EnableArgumentFilter() { enable_argument_filter_ = true; }
  170. void AddIncludedCategory(const char* included_category);
  171. bool IsCategoryGroupEnabled(const char* category_group) const;
  172. private:
  173. TraceRecordMode record_mode_;
  174. bool enable_systrace_ : 1;
  175. bool enable_argument_filter_ : 1;
  176. StringList included_categories_;
  177. // Disallow copy and assign
  178. TraceConfig(const TraceConfig&) = delete;
  179. void operator=(const TraceConfig&) = delete;
  180. };
  181. #if defined(_MSC_VER)
  182. #define V8_PLATFORM_NON_EXPORTED_BASE(code) \
  183. __pragma(warning(suppress : 4275)) code
  184. #else
  185. #define V8_PLATFORM_NON_EXPORTED_BASE(code) code
  186. #endif // defined(_MSC_VER)
  187. class V8_PLATFORM_EXPORT TracingController
  188. : public V8_PLATFORM_NON_EXPORTED_BASE(v8::TracingController) {
  189. public:
  190. // The pointer returned from GetCategoryGroupEnabled() points to a value with
  191. // zero or more of the following bits. Used in this class only. The
  192. // TRACE_EVENT macros should only use the value as a bool. These values must
  193. // be in sync with macro values in TraceEvent.h in Blink.
  194. enum CategoryGroupEnabledFlags {
  195. // Category group enabled for the recording mode.
  196. ENABLED_FOR_RECORDING = 1 << 0,
  197. // Category group enabled by SetEventCallbackEnabled().
  198. ENABLED_FOR_EVENT_CALLBACK = 1 << 2,
  199. // Category group enabled to export events to ETW.
  200. ENABLED_FOR_ETW_EXPORT = 1 << 3
  201. };
  202. TracingController();
  203. ~TracingController() override;
  204. void Initialize(TraceBuffer* trace_buffer);
  205. #ifdef V8_USE_PERFETTO
  206. // Must be called before StartTracing() if V8_USE_PERFETTO is true. Provides
  207. // the output stream for the JSON trace data.
  208. void InitializeForPerfetto(std::ostream* output_stream);
  209. // Provide an optional listener for testing that will receive trace events.
  210. // Must be called before StartTracing().
  211. void SetTraceEventListenerForTesting(TraceEventListener* listener);
  212. #endif
  213. // v8::TracingController implementation.
  214. const uint8_t* GetCategoryGroupEnabled(const char* category_group) override;
  215. uint64_t AddTraceEvent(
  216. char phase, const uint8_t* category_enabled_flag, const char* name,
  217. const char* scope, uint64_t id, uint64_t bind_id, int32_t num_args,
  218. const char** arg_names, const uint8_t* arg_types,
  219. const uint64_t* arg_values,
  220. std::unique_ptr<v8::ConvertableToTraceFormat>* arg_convertables,
  221. unsigned int flags) override;
  222. uint64_t AddTraceEventWithTimestamp(
  223. char phase, const uint8_t* category_enabled_flag, const char* name,
  224. const char* scope, uint64_t id, uint64_t bind_id, int32_t num_args,
  225. const char** arg_names, const uint8_t* arg_types,
  226. const uint64_t* arg_values,
  227. std::unique_ptr<v8::ConvertableToTraceFormat>* arg_convertables,
  228. unsigned int flags, int64_t timestamp) override;
  229. void UpdateTraceEventDuration(const uint8_t* category_enabled_flag,
  230. const char* name, uint64_t handle) override;
  231. void AddTraceStateObserver(
  232. v8::TracingController::TraceStateObserver* observer) override;
  233. void RemoveTraceStateObserver(
  234. v8::TracingController::TraceStateObserver* observer) override;
  235. void StartTracing(TraceConfig* trace_config);
  236. void StopTracing();
  237. static const char* GetCategoryGroupName(const uint8_t* category_enabled_flag);
  238. protected:
  239. virtual int64_t CurrentTimestampMicroseconds();
  240. virtual int64_t CurrentCpuTimestampMicroseconds();
  241. private:
  242. void UpdateCategoryGroupEnabledFlag(size_t category_index);
  243. void UpdateCategoryGroupEnabledFlags();
  244. std::unique_ptr<TraceBuffer> trace_buffer_;
  245. std::unique_ptr<TraceConfig> trace_config_;
  246. std::unique_ptr<base::Mutex> mutex_;
  247. std::unordered_set<v8::TracingController::TraceStateObserver*> observers_;
  248. std::atomic_bool recording_{false};
  249. #ifdef V8_USE_PERFETTO
  250. std::ostream* output_stream_ = nullptr;
  251. std::unique_ptr<JSONTraceEventListener> json_listener_;
  252. TraceEventListener* listener_for_testing_ = nullptr;
  253. std::unique_ptr<perfetto::TracingSession> tracing_session_;
  254. #endif
  255. // Disallow copy and assign
  256. TracingController(const TracingController&) = delete;
  257. void operator=(const TracingController&) = delete;
  258. };
  259. #undef V8_PLATFORM_NON_EXPORTED_BASE
  260. } // namespace tracing
  261. } // namespace platform
  262. } // namespace v8
  263. #endif // V8_LIBPLATFORM_V8_TRACING_H_