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 12 namespace v8 { 13 namespace internal { 14 15 class Isolate; 16 17 // TickSample captures the information collected for each sample. 18 struct 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 TickSampleTickSample24 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