summaryrefslogtreecommitdiff
path: root/chromium/v8/src/profiler/tick-sample.h
blob: 1bfcb7d0971965e98419e573c827f42a2c28875f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
// Copyright 2013 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef V8_PROFILER_TICK_SAMPLE_H_
#define V8_PROFILER_TICK_SAMPLE_H_

#include "include/v8.h"
#include "src/base/platform/time.h"
#include "src/common/globals.h"

namespace v8 {
namespace internal {

class Isolate;

// TickSample captures the information collected for each sample.
struct V8_EXPORT TickSample {
  // Internal profiling (with --prof + tools/$OS-tick-processor) wants to
  // include the runtime function we're calling. Externally exposed tick
  // samples don't care.
  enum RecordCEntryFrame { kIncludeCEntryFrame, kSkipCEntryFrame };

  TickSample()
      : state(OTHER),
        pc(nullptr),
        external_callback_entry(nullptr),
        frames_count(0),
        has_external_callback(false),
        update_stats(true) {}

  /**
   * Initialize a tick sample from the isolate.
   * \param isolate The isolate.
   * \param state Execution state.
   * \param record_c_entry_frame Include or skip the runtime function.
   * \param update_stats Whether update the sample to the aggregated stats.
   * \param use_simulator_reg_state When set to true and V8 is running under a
   *                                simulator, the method will use the simulator
   *                                register state rather than the one provided
   *                                with |state| argument. Otherwise the method
   *                                will use provided register |state| as is.
   */
  void Init(Isolate* isolate, const v8::RegisterState& state,
            RecordCEntryFrame record_c_entry_frame, bool update_stats,
            bool use_simulator_reg_state = true,
            base::TimeDelta sampling_interval = base::TimeDelta());
  /**
   * Get a call stack sample from the isolate.
   * \param isolate The isolate.
   * \param state Register state.
   * \param record_c_entry_frame Include or skip the runtime function.
   * \param frames Caller allocated buffer to store stack frames.
   * \param frames_limit Maximum number of frames to capture. The buffer must
   *                     be large enough to hold the number of frames.
   * \param sample_info The sample info is filled up by the function
   *                    provides number of actual captured stack frames and
   *                    the current VM state.
   * \param out_state Output parameter. If non-nullptr pointer is provided,
   *                  and the execution is currently in a fast API call,
   *                  records StateTag::EXTERNAL to it. The caller could then
   *                  use this as a marker to not take into account the actual
   *                  VM state recorded in |sample_info|. In the case of fast
   *                  API calls, the VM state must be EXTERNAL, as the callback
   *                  is always an external C++ function.
   * \param use_simulator_reg_state When set to true and V8 is running under a
   *                                simulator, the method will use the simulator
   *                                register state rather than the one provided
   *                                with |state| argument. Otherwise the method
   *                                will use provided register |state| as is.
   * \note GetStackSample is thread and signal safe and should only be called
   *                      when the JS thread is paused or interrupted.
   *                      Otherwise the behavior is undefined.
   */
  static bool GetStackSample(Isolate* isolate, v8::RegisterState* state,
                             RecordCEntryFrame record_c_entry_frame,
                             void** frames, size_t frames_limit,
                             v8::SampleInfo* sample_info,
                             StateTag* out_state = nullptr,
                             bool use_simulator_reg_state = true);

  void print() const;

  StateTag state;  // The state of the VM.
  void* pc;        // Instruction pointer.
  union {
    void* tos;  // Top stack value (*sp).
    void* external_callback_entry;
  };
  static const unsigned kMaxFramesCountLog2 = 8;
  static const unsigned kMaxFramesCount = (1 << kMaxFramesCountLog2) - 1;
  void* stack[kMaxFramesCount];     // Call stack.
  void* context = nullptr;          // Address of the incumbent native context.
  unsigned frames_count : kMaxFramesCountLog2;  // Number of captured frames.
  bool has_external_callback : 1;
  bool update_stats : 1;  // Whether the sample should update aggregated stats.

  base::TimeTicks timestamp;
  base::TimeDelta sampling_interval;  // Sampling interval used to capture.
};

}  // namespace internal
}  // namespace v8

#endif  // V8_PROFILER_TICK_SAMPLE_H_