5 #include "src/profiler/tick-sample.h" 7 #include "include/v8-profiler.h" 8 #include "src/counters.h" 9 #include "src/frames-inl.h" 11 #include "src/simulator.h" 12 #include "src/vm-state-inl.h" 20 return (ptr1 & mask) == (ptr2 & mask);
31 static Pattern patterns[] = {
35 {3, {0x55, 0x89, 0xE5}, {0, 1, -1}},
38 {2, {0x5D, 0xC2}, {0, 1, -1}},
41 {2, {0x5D, 0xC3}, {0, 1, -1}},
42 #elif V8_HOST_ARCH_X64 45 {4, {0x55, 0x48, 0x89, 0xE5}, {0, 1, -1}},
48 {2, {0x5D, 0xC2}, {0, 1, -1}},
51 {2, {0x5D, 0xC3}, {0, 1, -1}},
55 i::byte* pc =
reinterpret_cast<i::byte*
>(address);
56 for (Pattern* pattern = patterns; pattern->bytes_count; ++pattern) {
57 for (
int* offset_ptr = pattern->offsets; *offset_ptr != -1; ++offset_ptr) {
58 int offset = *offset_ptr;
59 if (!offset || IsSamePage(address, address - offset)) {
60 MSAN_MEMORY_IS_INITIALIZED(pc - offset, pattern->bytes_count);
61 if (!memcmp(pc - offset, pattern->bytes, pattern->bytes_count))
68 MSAN_MEMORY_IS_INITIALIZED(pc, pattern->bytes_count - offset);
69 if (!memcmp(pc, pattern->bytes + offset, pattern->bytes_count - offset))
82 #if defined(USE_SIMULATOR) 83 class SimulatorHelper {
90 bool SimulatorHelper::FillRegisters(Isolate* isolate,
92 Simulator* simulator = isolate->thread_local_top()->simulator_;
94 if (simulator ==
nullptr)
return false;
95 #if V8_TARGET_ARCH_ARM 96 if (!simulator->has_bad_pc()) {
97 state->pc =
reinterpret_cast<void*
>(simulator->get_pc());
99 state->sp =
reinterpret_cast<void*
>(simulator->get_register(Simulator::sp));
100 state->fp =
reinterpret_cast<void*
>(simulator->get_register(Simulator::r11));
101 #elif V8_TARGET_ARCH_ARM64 102 state->pc =
reinterpret_cast<void*
>(simulator->pc());
103 state->sp =
reinterpret_cast<void*
>(simulator->sp());
104 state->fp =
reinterpret_cast<void*
>(simulator->fp());
105 #elif V8_TARGET_ARCH_MIPS || V8_TARGET_ARCH_MIPS64 106 if (!simulator->has_bad_pc()) {
107 state->pc =
reinterpret_cast<void*
>(simulator->get_pc());
109 state->sp =
reinterpret_cast<void*
>(simulator->get_register(Simulator::sp));
110 state->fp =
reinterpret_cast<void*
>(simulator->get_register(Simulator::fp));
111 #elif V8_TARGET_ARCH_PPC 112 if (!simulator->has_bad_pc()) {
113 state->pc =
reinterpret_cast<void*
>(simulator->get_pc());
115 state->sp =
reinterpret_cast<void*
>(simulator->get_register(Simulator::sp));
116 state->fp =
reinterpret_cast<void*
>(simulator->get_register(Simulator::fp));
117 #elif V8_TARGET_ARCH_S390 118 if (!simulator->has_bad_pc()) {
119 state->pc =
reinterpret_cast<void*
>(simulator->get_pc());
121 state->sp =
reinterpret_cast<void*
>(simulator->get_register(Simulator::sp));
122 state->fp =
reinterpret_cast<void*
>(simulator->get_register(Simulator::fp));
124 if (state->sp == 0 || state->fp == 0) {
140 #endif // USE_SIMULATOR 150 RecordCEntryFrame record_c_entry_frame,
152 bool use_simulator_reg_state) {
153 this->update_stats = update_stats;
156 if (!
GetStackSample(v8_isolate, ®s, record_c_entry_frame, stack,
157 kMaxFramesCount, &info, use_simulator_reg_state)) {
164 state = info.vm_state;
166 frames_count =
static_cast<unsigned>(info.frames_count);
167 has_external_callback = info.external_callback_entry !=
nullptr;
168 if (has_external_callback) {
169 external_callback_entry = info.external_callback_entry;
170 }
else if (frames_count) {
173 MSAN_MEMORY_IS_INITIALIZED(regs.sp,
sizeof(
void*));
176 tos =
reinterpret_cast<void*
>(
177 i::Memory<i::Address>(
reinterpret_cast<i::Address>(regs.sp)));
184 RecordCEntryFrame record_c_entry_frame,
185 void** frames,
size_t frames_limit,
187 bool use_simulator_reg_state) {
189 sample_info->frames_count = 0;
190 sample_info->vm_state = isolate->current_vm_state();
191 sample_info->external_callback_entry =
nullptr;
192 if (sample_info->vm_state == GC)
return true;
194 i::Address js_entry_sp = isolate->js_entry_sp();
195 if (js_entry_sp == 0)
return true;
197 #if defined(USE_SIMULATOR) 198 if (use_simulator_reg_state) {
199 if (!i::SimulatorHelper::FillRegisters(isolate, regs))
return false;
202 USE(use_simulator_reg_state);
209 isolate->heap()->memory_allocator()->code_range().contains(
210 reinterpret_cast<i::Address>(regs->pc)) &&
211 IsNoFrameRegion(reinterpret_cast<i::Address>(regs->pc))) {
217 i::Address handler = i::Isolate::handler(isolate->thread_local_top());
221 if (scope && scope->scope_address() < handler) {
223 scope->callback_entrypoint_address();
224 sample_info->external_callback_entry =
225 external_callback_entry_ptr ==
nullptr 227 :
reinterpret_cast<void*
>(*external_callback_entry_ptr);
231 reinterpret_cast<i::Address>(regs->sp),
233 if (it.done())
return true;
236 if (record_c_entry_frame == kIncludeCEntryFrame &&
237 (it.top_frame_type() == internal::StackFrame::EXIT ||
238 it.top_frame_type() == internal::StackFrame::BUILTIN_EXIT)) {
239 frames[
i++] =
reinterpret_cast<void*
>(isolate->c_function());
242 isolate->counters()->runtime_call_stats()->current_timer();
243 for (; !it.done() &&
i < frames_limit; it.Advance()) {
244 while (timer && reinterpret_cast<i::Address>(timer) < it.frame()->fp() &&
246 frames[
i++] =
reinterpret_cast<void*
>(timer->counter());
247 timer = timer->parent();
249 if (
i == frames_limit)
break;
250 if (it.frame()->is_interpreted()) {
258 i::Address bytecode_array = i::Memory<i::Address>(
259 frame->fp() + i::InterpreterFrameConstants::kBytecodeArrayFromFp);
260 i::Address bytecode_offset = i::Memory<i::Address>(
261 frame->fp() + i::InterpreterFrameConstants::kBytecodeOffsetFromFp);
265 if (HAS_HEAP_OBJECT_TAG(bytecode_array) && HAS_SMI_TAG(bytecode_offset)) {
266 frames[
i++] =
reinterpret_cast<void*
>(
267 bytecode_array + i::Internals::SmiValue(bytecode_offset));
271 frames[
i++] =
reinterpret_cast<void*
>(it.frame()->pc());
273 sample_info->frames_count =
i;
280 RecordCEntryFrame record_c_entry_frame,
bool update_stats,
281 bool use_simulator_reg_state) {
283 record_c_entry_frame, update_stats,
284 use_simulator_reg_state);
285 if (pc ==
nullptr)
return;
286 timestamp = base::TimeTicks::HighResolutionNow();
void Init(Isolate *isolate, const v8::RegisterState &state, RecordCEntryFrame record_c_entry_frame, bool update_stats, bool use_simulator_reg_state=true)
static bool GetStackSample(Isolate *isolate, v8::RegisterState *state, RecordCEntryFrame record_c_entry_frame, void **frames, size_t frames_limit, v8::SampleInfo *sample_info, bool use_simulator_reg_state=true)