Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-02-22 10:42:27

0001 // Copyright 2016 the V8 project authors. All rights reserved.
0002 // Use of this source code is governed by a BSD-style license that can be
0003 // found in the LICENSE file.
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 }  // namespace base
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   // Disallow copy and assign
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   // Disallow copy and assign
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   // Disallow copy and assign
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   // Disallow copy and assign
0175   TraceBuffer(const TraceBuffer&) = delete;
0176   void operator=(const TraceBuffer&) = delete;
0177 };
0178 
0179 // Options determines how the trace buffer stores data.
0180 enum TraceRecordMode {
0181   // Record until the trace buffer is full.
0182   RECORD_UNTIL_FULL,
0183 
0184   // Record until the user ends the trace. The trace buffer is a fixed size
0185   // and we use it as a ring buffer during recording.
0186   RECORD_CONTINUOUSLY,
0187 
0188   // Record until the trace buffer is full, but with a huge buffer size.
0189   RECORD_AS_MUCH_AS_POSSIBLE,
0190 
0191   // Echo to console. Events are discarded.
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   // Disallow copy and assign
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  // defined(_MSC_VER)
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   // Must be called before StartTracing() if V8_USE_PERFETTO is true. Provides
0243   // the output stream for the JSON trace data.
0244   void InitializeForPerfetto(std::ostream* output_stream);
0245   // Provide an optional listener for testing that will receive trace events.
0246   // Must be called before StartTracing().
0247   void SetTraceEventListenerForTesting(TraceEventListener* listener);
0248 #else   // defined(V8_USE_PERFETTO)
0249   // The pointer returned from GetCategoryGroupEnabled() points to a value with
0250   // zero or more of the following bits. Used in this class only. The
0251   // TRACE_EVENT macros should only use the value as a bool. These values must
0252   // be in sync with macro values in TraceEvent.h in Blink.
0253   enum CategoryGroupEnabledFlags {
0254     // Category group enabled for the recording mode.
0255     ENABLED_FOR_RECORDING = 1 << 0,
0256     // Category group enabled by SetEventCallbackEnabled().
0257     ENABLED_FOR_EVENT_CALLBACK = 1 << 2,
0258     // Category group enabled to export events to ETW.
0259     ENABLED_FOR_ETW_EXPORT = 1 << 3
0260   };
0261 
0262   // Takes ownership of |trace_buffer|.
0263   void Initialize(TraceBuffer* trace_buffer);
0264 
0265   // v8::TracingController implementation.
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  // !defined(V8_USE_PERFETTO)
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  // !defined(V8_USE_PERFETTO)
0300 
0301  private:
0302 #if !defined(V8_USE_PERFETTO)
0303   void UpdateCategoryGroupEnabledFlag(size_t category_index);
0304   void UpdateCategoryGroupEnabledFlags();
0305 #endif  // !defined(V8_USE_PERFETTO)
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   // !defined(V8_USE_PERFETTO)
0318   std::unordered_set<v8::TracingController::TraceStateObserver*> observers_;
0319   std::unique_ptr<TraceBuffer> trace_buffer_;
0320 #endif  // !defined(V8_USE_PERFETTO)
0321 
0322   // Disallow copy and assign
0323   TracingController(const TracingController&) = delete;
0324   void operator=(const TracingController&) = delete;
0325 };
0326 
0327 #undef V8_PLATFORM_NON_EXPORTED_BASE
0328 
0329 }  // namespace tracing
0330 }  // namespace platform
0331 }  // namespace v8
0332 
0333 #endif  // V8_LIBPLATFORM_V8_TRACING_H_