Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(26)

Unified Diff: src/profiler/tick-sample.cc

Issue 2189513002: Move SimulatorHelper into V8 out of profiler clients. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Update Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/profiler/tick-sample.h ('k') | test/cctest/libsampler/test-sampler.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/profiler/tick-sample.cc
diff --git a/src/profiler/tick-sample.cc b/src/profiler/tick-sample.cc
index 533f34f85216f2ffaa8241d6b2dd071b4f48e434..e51f939e835e8cc616f26c7664c2bd77ac8c8997 100644
--- a/src/profiler/tick-sample.cc
+++ b/src/profiler/tick-sample.cc
@@ -11,7 +11,6 @@
#include "src/vm-state-inl.h"
namespace v8 {
-
namespace {
bool IsSamePage(i::byte* ptr1, i::byte* ptr2) {
@@ -77,46 +76,115 @@ bool IsNoFrameRegion(i::Address address) {
} // namespace
+namespace internal {
+namespace {
+
+#if defined(USE_SIMULATOR)
+class SimulatorHelper {
+ public:
+ // Returns true if register values were successfully retrieved
+ // from the simulator, otherwise returns false.
+ static bool FillRegisters(Isolate* isolate, v8::RegisterState* state);
+};
+
+bool SimulatorHelper::FillRegisters(Isolate* isolate,
+ v8::RegisterState* state) {
+ Simulator* simulator = isolate->thread_local_top()->simulator_;
+ // Check if there is active simulator.
+ if (simulator == NULL) return false;
+#if V8_TARGET_ARCH_ARM
+ if (!simulator->has_bad_pc()) {
+ state->pc = reinterpret_cast<Address>(simulator->get_pc());
+ }
+ state->sp = reinterpret_cast<Address>(simulator->get_register(Simulator::sp));
+ state->fp =
+ reinterpret_cast<Address>(simulator->get_register(Simulator::r11));
+#elif V8_TARGET_ARCH_ARM64
+ state->pc = reinterpret_cast<Address>(simulator->pc());
+ state->sp = reinterpret_cast<Address>(simulator->sp());
+ state->fp = reinterpret_cast<Address>(simulator->fp());
+#elif V8_TARGET_ARCH_MIPS || V8_TARGET_ARCH_MIPS64
+ if (!simulator->has_bad_pc()) {
+ state->pc = reinterpret_cast<Address>(simulator->get_pc());
+ }
+ state->sp = reinterpret_cast<Address>(simulator->get_register(Simulator::sp));
+ state->fp = reinterpret_cast<Address>(simulator->get_register(Simulator::fp));
+#elif V8_TARGET_ARCH_PPC
+ if (!simulator->has_bad_pc()) {
+ state->pc = reinterpret_cast<Address>(simulator->get_pc());
+ }
+ state->sp = reinterpret_cast<Address>(simulator->get_register(Simulator::sp));
+ state->fp = reinterpret_cast<Address>(simulator->get_register(Simulator::fp));
+#elif V8_TARGET_ARCH_S390
+ if (!simulator->has_bad_pc()) {
+ state->pc = reinterpret_cast<Address>(simulator->get_pc());
+ }
+ state->sp = reinterpret_cast<Address>(simulator->get_register(Simulator::sp));
+ state->fp = reinterpret_cast<Address>(simulator->get_register(Simulator::fp));
+#endif
+ if (state->sp == 0 || state->fp == 0) {
+ // It possible that the simulator is interrupted while it is updating
+ // the sp or fp register. ARM64 simulator does this in two steps:
+ // first setting it to zero and then setting it to the new value.
+ // Bailout if sp/fp doesn't contain the new value.
+ //
+ // FIXME: The above doesn't really solve the issue.
+ // If a 64-bit target is executed on a 32-bit host even the final
+ // write is non-atomic, so it might obtain a half of the result.
+ // Moreover as long as the register set code uses memcpy (as of now),
+ // it is not guaranteed to be atomic even when both host and target
+ // are of same bitness.
+ return false;
+ }
+ return true;
+}
+#endif // USE_SIMULATOR
+
+} // namespace
+} // namespace internal
+
//
// StackTracer implementation
//
DISABLE_ASAN void TickSample::Init(Isolate* v8_isolate,
- const RegisterState& regs,
+ const RegisterState& reg_state,
RecordCEntryFrame record_c_entry_frame,
- bool update_stats) {
+ bool update_stats,
+ bool use_simulator_reg_state) {
this->update_stats = update_stats;
-
SampleInfo info;
- if (GetStackSample(v8_isolate, const_cast<RegisterState&>(regs),
- record_c_entry_frame, reinterpret_cast<void**>(&stack[0]),
- kMaxFramesCount, &info)) {
- state = info.vm_state;
- pc = regs.pc;
- frames_count = static_cast<unsigned>(info.frames_count);
- has_external_callback = info.external_callback_entry != nullptr;
- if (has_external_callback) {
- external_callback_entry = info.external_callback_entry;
- } else if (frames_count) {
- // sp register may point at an arbitrary place in memory, make
- // sure MSAN doesn't complain about it.
- MSAN_MEMORY_IS_INITIALIZED(regs.sp, sizeof(void*));
- // Sample potential return address value for frameless invocation of
- // stubs (we'll figure out later, if this value makes sense).
- tos = i::Memory::Address_at(reinterpret_cast<i::Address>(regs.sp));
- } else {
- tos = nullptr;
- }
- } else {
+ RegisterState regs = reg_state;
+ if (!GetStackSample(v8_isolate, &regs, record_c_entry_frame, stack,
+ kMaxFramesCount, &info, use_simulator_reg_state)) {
// It is executing JS but failed to collect a stack trace.
// Mark the sample as spoiled.
pc = nullptr;
+ return;
+ }
+
+ state = info.vm_state;
+ pc = regs.pc;
+ frames_count = static_cast<unsigned>(info.frames_count);
+ has_external_callback = info.external_callback_entry != nullptr;
+ if (has_external_callback) {
+ external_callback_entry = info.external_callback_entry;
+ } else if (frames_count) {
+ // sp register may point at an arbitrary place in memory, make
+ // sure MSAN doesn't complain about it.
+ MSAN_MEMORY_IS_INITIALIZED(regs.sp, sizeof(void*));
+ // Sample potential return address value for frameless invocation of
+ // stubs (we'll figure out later, if this value makes sense).
+ tos = i::Memory::Address_at(reinterpret_cast<i::Address>(regs.sp));
+ } else {
+ tos = nullptr;
}
}
-bool TickSample::GetStackSample(Isolate* v8_isolate, const RegisterState& regs,
+bool TickSample::GetStackSample(Isolate* v8_isolate, RegisterState* regs,
RecordCEntryFrame record_c_entry_frame,
void** frames, size_t frames_limit,
- v8::SampleInfo* sample_info) {
+ v8::SampleInfo* sample_info,
+ bool use_simulator_reg_state) {
i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
sample_info->frames_count = 0;
sample_info->vm_state = isolate->current_vm_state();
@@ -125,10 +193,18 @@ bool TickSample::GetStackSample(Isolate* v8_isolate, const RegisterState& regs,
i::Address js_entry_sp = isolate->js_entry_sp();
if (js_entry_sp == nullptr) return true; // Not executing JS now.
- DCHECK(regs.sp);
- if (regs.pc && IsNoFrameRegion(static_cast<i::Address>(regs.pc))) {
- // Can't collect stack.
+#if defined(USE_SIMULATOR)
+ if (use_simulator_reg_state) {
+ if (!i::SimulatorHelper::FillRegisters(isolate, regs)) return false;
+ }
+#else
+ USE(use_simulator_reg_state);
+#endif
+ DCHECK(regs->sp);
+
+ if (regs->pc && IsNoFrameRegion(static_cast<i::Address>(regs->pc))) {
+ // The frame is not setup, so it'd be hard to iterate the stack. Bailout.
return false;
}
@@ -142,8 +218,8 @@ bool TickSample::GetStackSample(Isolate* v8_isolate, const RegisterState& regs,
*scope->callback_entrypoint_address();
}
- i::SafeStackFrameIterator it(isolate, reinterpret_cast<i::Address>(regs.fp),
- reinterpret_cast<i::Address>(regs.sp),
+ i::SafeStackFrameIterator it(isolate, reinterpret_cast<i::Address>(regs->fp),
+ reinterpret_cast<i::Address>(regs->sp),
js_entry_sp);
// If at this point iterator does not see any frames,
@@ -180,67 +256,14 @@ bool TickSample::GetStackSample(Isolate* v8_isolate, const RegisterState& regs,
namespace internal {
void TickSample::Init(Isolate* isolate, const v8::RegisterState& state,
- RecordCEntryFrame record_c_entry_frame,
- bool update_stats) {
+ RecordCEntryFrame record_c_entry_frame, bool update_stats,
+ bool use_simulator_reg_state) {
v8::TickSample::Init(reinterpret_cast<v8::Isolate*>(isolate), state,
- record_c_entry_frame, update_stats);
+ record_c_entry_frame, update_stats,
+ use_simulator_reg_state);
if (pc == nullptr) return;
timestamp = base::TimeTicks::HighResolutionNow();
}
-#if defined(USE_SIMULATOR)
-bool SimulatorHelper::FillRegisters(Isolate* isolate,
- v8::RegisterState* state) {
- Simulator* simulator = isolate->thread_local_top()->simulator_;
- // Check if there is active simulator.
- if (simulator == NULL) return false;
-#if V8_TARGET_ARCH_ARM
- if (!simulator->has_bad_pc()) {
- state->pc = reinterpret_cast<Address>(simulator->get_pc());
- }
- state->sp = reinterpret_cast<Address>(simulator->get_register(Simulator::sp));
- state->fp =
- reinterpret_cast<Address>(simulator->get_register(Simulator::r11));
-#elif V8_TARGET_ARCH_ARM64
- state->pc = reinterpret_cast<Address>(simulator->pc());
- state->sp = reinterpret_cast<Address>(simulator->sp());
- state->fp = reinterpret_cast<Address>(simulator->fp());
-#elif V8_TARGET_ARCH_MIPS || V8_TARGET_ARCH_MIPS64
- if (!simulator->has_bad_pc()) {
- state->pc = reinterpret_cast<Address>(simulator->get_pc());
- }
- state->sp = reinterpret_cast<Address>(simulator->get_register(Simulator::sp));
- state->fp = reinterpret_cast<Address>(simulator->get_register(Simulator::fp));
-#elif V8_TARGET_ARCH_PPC
- if (!simulator->has_bad_pc()) {
- state->pc = reinterpret_cast<Address>(simulator->get_pc());
- }
- state->sp = reinterpret_cast<Address>(simulator->get_register(Simulator::sp));
- state->fp = reinterpret_cast<Address>(simulator->get_register(Simulator::fp));
-#elif V8_TARGET_ARCH_S390
- if (!simulator->has_bad_pc()) {
- state->pc = reinterpret_cast<Address>(simulator->get_pc());
- }
- state->sp = reinterpret_cast<Address>(simulator->get_register(Simulator::sp));
- state->fp = reinterpret_cast<Address>(simulator->get_register(Simulator::fp));
-#endif
- if (state->sp == 0 || state->fp == 0) {
- // It possible that the simulator is interrupted while it is updating
- // the sp or fp register. ARM64 simulator does this in two steps:
- // first setting it to zero and then setting it to the new value.
- // Bailout if sp/fp doesn't contain the new value.
- //
- // FIXME: The above doesn't really solve the issue.
- // If a 64-bit target is executed on a 32-bit host even the final
- // write is non-atomic, so it might obtain a half of the result.
- // Moreover as long as the register set code uses memcpy (as of now),
- // it is not guaranteed to be atomic even when both host and target
- // are of same bitness.
- return false;
- }
- return true;
-}
-#endif // USE_SIMULATOR
-
} // namespace internal
} // namespace v8
« no previous file with comments | « src/profiler/tick-sample.h ('k') | test/cctest/libsampler/test-sampler.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698