Index: src/profiler/simulator-helper.cc |
diff --git a/src/profiler/tick-sample.h b/src/profiler/simulator-helper.cc |
similarity index 11% |
rename from src/profiler/tick-sample.h |
rename to src/profiler/simulator-helper.cc |
index 0a651aff10c5c36b2665810f68d0f12d7c9b9335..aa90ba9bc8f99aa6d3d705d159226ce03e144612 100644 |
--- a/src/profiler/tick-sample.h |
+++ b/src/profiler/simulator-helper.cc |
@@ -2,73 +2,66 @@ |
// 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 "src/profiler/simulator-helper.h" |
-#include "include/v8.h" |
- |
-#include "src/base/platform/time.h" |
-#include "src/frames.h" |
-#include "src/globals.h" |
+#include "src/simulator.h" |
namespace v8 { |
namespace internal { |
-class Isolate; |
- |
-// ---------------------------------------------------------------------------- |
-// Sampler |
-// |
-// A sampler periodically samples the state of the VM and optionally |
-// (if used for profiling) the program counter and stack pointer for |
-// the thread that created it. |
- |
-// TickSample captures the information collected for each sample. |
-struct 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(NULL), |
- external_callback_entry(NULL), |
- frames_count(0), |
- has_external_callback(false), |
- update_stats(true) {} |
- void Init(Isolate* isolate, const v8::RegisterState& state, |
- RecordCEntryFrame record_c_entry_frame, bool update_stats); |
- static bool GetStackSample(Isolate* isolate, const v8::RegisterState& state, |
- RecordCEntryFrame record_c_entry_frame, |
- void** frames, size_t frames_limit, |
- v8::SampleInfo* sample_info); |
- StateTag state; // The state of the VM. |
- Address pc; // Instruction pointer. |
- union { |
- Address tos; // Top stack value (*sp). |
- Address external_callback_entry; |
- }; |
- static const unsigned kMaxFramesCountLog2 = 8; |
- static const unsigned kMaxFramesCount = (1 << kMaxFramesCountLog2) - 1; |
- Address stack[kMaxFramesCount]; // Call stack. |
- base::TimeTicks timestamp; |
- unsigned frames_count : kMaxFramesCountLog2; // Number of captured frames. |
- bool has_external_callback : 1; |
- bool update_stats : 1; // Whether the sample should update aggregated stats. |
-}; |
- |
- |
#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 internal |
} // namespace v8 |
- |
-#endif // V8_PROFILER_TICK_SAMPLE_H_ |