1// Copyright 2013 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
5#ifndef V8_PROFILER_TICK_SAMPLE_H_
6#define V8_PROFILER_TICK_SAMPLE_H_
7
8#include "include/v8-unwinder.h"
9#include "src/base/platform/time.h"
10#include "src/common/globals.h"
11
12namespace v8 {
13namespace internal {
14
15class Isolate;
16
17// TickSample captures the information collected for each sample.
18struct V8_EXPORT TickSample {
19  // Internal profiling (with --prof + tools/$OS-tick-processor) wants to
20  // include the runtime function we're calling. Externally exposed tick
21  // samples don't care.
22  enum RecordCEntryFrame { kIncludeCEntryFrame, kSkipCEntryFrame };
23
24  TickSample()
25      : state(OTHER),
26        embedder_state(EmbedderStateTag::EMPTY),
27        pc(nullptr),
28        external_callback_entry(nullptr),
29        frames_count(0),
30        has_external_callback(false),
31        update_stats_(true) {}
32
33  /**
34   * Initialize a tick sample from the isolate.
35   * \param isolate The isolate.
36   * \param state Execution state.
37   * \param record_c_entry_frame Include or skip the runtime function.
38   * \param update_stats Whether update the sample to the aggregated stats.
39   * \param use_simulator_reg_state When set to true and V8 is running under a
40   *                                simulator, the method will use the simulator
41   *                                register state rather than the one provided
42   *                                with |state| argument. Otherwise the method
43   *                                will use provided register |state| as is.
44   */
45  void Init(Isolate* isolate, const v8::RegisterState& state,
46            RecordCEntryFrame record_c_entry_frame, bool update_stats,
47            bool use_simulator_reg_state = true,
48            base::TimeDelta sampling_interval = base::TimeDelta());
49  /**
50   * Get a call stack sample from the isolate.
51   * \param isolate The isolate.
52   * \param state Register state.
53   * \param record_c_entry_frame Include or skip the runtime function.
54   * \param frames Caller allocated buffer to store stack frames.
55   * \param frames_limit Maximum number of frames to capture. The buffer must
56   *                     be large enough to hold the number of frames.
57   * \param sample_info The sample info is filled up by the function
58   *                    provides number of actual captured stack frames and
59   *                    the current VM state.
60   * \param out_state Output parameter. If non-nullptr pointer is provided,
61   *                  and the execution is currently in a fast API call,
62   *                  records StateTag::EXTERNAL to it. The caller could then
63   *                  use this as a marker to not take into account the actual
64   *                  VM state recorded in |sample_info|. In the case of fast
65   *                  API calls, the VM state must be EXTERNAL, as the callback
66   *                  is always an external C++ function.
67   * \param use_simulator_reg_state When set to true and V8 is running under a
68   *                                simulator, the method will use the simulator
69   *                                register state rather than the one provided
70   *                                with |state| argument. Otherwise the method
71   *                                will use provided register |state| as is.
72   * \note GetStackSample is thread and signal safe and should only be called
73   *                      when the JS thread is paused or interrupted.
74   *                      Otherwise the behavior is undefined.
75   */
76  static bool GetStackSample(Isolate* isolate, v8::RegisterState* state,
77                             RecordCEntryFrame record_c_entry_frame,
78                             void** frames, size_t frames_limit,
79                             v8::SampleInfo* sample_info,
80                             StateTag* out_state = nullptr,
81                             bool use_simulator_reg_state = true);
82
83  void print() const;
84
85  StateTag state;  // The state of the VM.
86  EmbedderStateTag embedder_state;
87  void* pc;        // Instruction pointer.
88  union {
89    void* tos;  // Top stack value (*sp).
90    void* external_callback_entry;
91  };
92  static const unsigned kMaxFramesCountLog2 = 8;
93  static const unsigned kMaxFramesCount = (1 << kMaxFramesCountLog2) - 1;
94  void* stack[kMaxFramesCount];     // Call stack.
95  void* context = nullptr;          // Address of the incumbent native context.
96  void* embedder_context = nullptr;  // Address of the embedder native context.
97  unsigned frames_count : kMaxFramesCountLog2;  // Number of captured frames.
98  bool has_external_callback : 1;
99  bool update_stats_ : 1;  // Whether the sample should update aggregated stats.
100
101  base::TimeTicks timestamp;
102  base::TimeDelta sampling_interval_;  // Sampling interval used to capture.
103};
104
105}  // namespace internal
106}  // namespace v8
107
108#endif  // V8_PROFILER_TICK_SAMPLE_H_
109