#ifndef V8_PROFILER_TICK_SAMPLE_H_
#define V8_PROFILER_TICK_SAMPLE_H_
#include "include/v8-unwinder.h"
#include "src/base/platform/time.h"
#include "src/common/globals.h"
namespace v8 {
namespace internal {
class Isolate;
struct V8_EXPORT TickSample {
enum RecordCEntryFrame { kIncludeCEntryFrame, kSkipCEntryFrame };
TickSample() {}
* 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(),
const std::optional<uint64_t> trace_id = std::nullopt);
* 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;
static constexpr unsigned kMaxFramesCountLog2 = 8;
static constexpr unsigned kMaxFramesCount = (1 << kMaxFramesCountLog2) - 1;
void* pc = nullptr;
union {
void* tos;
void* external_callback_entry = nullptr;
};
void* context = nullptr;
void* embedder_context = nullptr;
base::TimeTicks timestamp;
base::TimeDelta sampling_interval_;
StateTag state = OTHER;
EmbedderStateTag embedder_state = EmbedderStateTag::EMPTY;
uint16_t frames_count = 0;
static_assert(sizeof(frames_count) * kBitsPerByte >= kMaxFramesCountLog2);
bool has_external_callback = false;
bool update_stats_ = true;
std::optional<uint64_t> trace_id_;
void* stack[kMaxFramesCount];
};
}
}
#endif