Index: runtime/vm/deopt_instructions.h |
diff --git a/runtime/vm/deopt_instructions.h b/runtime/vm/deopt_instructions.h |
index 229a0aaec1c985cd2221ef60bf7a3624408b91f8..5dfab383bd48070ee969b7d12e0344cc9351c761 100644 |
--- a/runtime/vm/deopt_instructions.h |
+++ b/runtime/vm/deopt_instructions.h |
@@ -9,9 +9,11 @@ |
#include "vm/assembler.h" |
#include "vm/code_generator.h" |
#include "vm/deferred_objects.h" |
+#include "vm/flow_graph_compiler.h" |
#include "vm/growable_array.h" |
#include "vm/locations.h" |
#include "vm/object.h" |
+#include "vm/stack_frame.h" |
#include "vm/thread.h" |
namespace dart { |
@@ -48,6 +50,10 @@ class DeoptContext { |
intptr_t* GetSourceFrameAddressAt(intptr_t index) const { |
ASSERT(source_frame_ != NULL); |
ASSERT((0 <= index) && (index < source_frame_size_)); |
+#if !defined(TARGET_ARCH_DBC) |
+ // Convert FP relative index to SP relative one. |
+ index = source_frame_size_ - 1 - index; |
+#endif // !defined(TARGET_ARCH_DBC) |
return &source_frame_[index]; |
} |
@@ -64,13 +70,20 @@ class DeoptContext { |
} |
intptr_t RegisterValue(Register reg) const { |
- ASSERT(cpu_registers_ != NULL); |
ASSERT(reg >= 0); |
ASSERT(reg < kNumberOfCpuRegisters); |
+#if !defined(TARGET_ARCH_DBC) |
+ ASSERT(cpu_registers_ != NULL); |
return cpu_registers_[reg]; |
+#else |
+ // On DBC registers and stack slots are the same. |
+ const intptr_t stack_index = num_args_ + kDartFrameFixedSize + reg; |
+ return *GetSourceFrameAddressAt(stack_index); |
+#endif // !defined(TARGET_ARCH_DBC) |
} |
double FpuRegisterValue(FpuRegister reg) const { |
+ ASSERT(FlowGraphCompiler::SupportsUnboxedDoubles()); |
ASSERT(fpu_registers_ != NULL); |
ASSERT(reg >= 0); |
ASSERT(reg < kNumberOfFpuRegisters); |
@@ -78,6 +91,7 @@ class DeoptContext { |
} |
simd128_value_t FpuRegisterValueAsSimd128(FpuRegister reg) const { |
+ ASSERT(FlowGraphCompiler::SupportsUnboxedSimd128()); |
ASSERT(fpu_registers_ != NULL); |
ASSERT(reg >= 0); |
ASSERT(reg < kNumberOfFpuRegisters); |
@@ -85,9 +99,29 @@ class DeoptContext { |
return simd128_value_t().readFrom(address); |
} |
- void set_dest_frame(intptr_t* dest_frame) { |
- ASSERT(dest_frame != NULL && dest_frame_ == NULL); |
- dest_frame_ = dest_frame; |
+ // Return base pointer for the given frame (either source or destination). |
+ // Base pointer points to the slot with the lowest address in the frame |
+ // including incoming arguments and artificial deoptimization frame |
+ // on top of it. |
+ // Note: artificial frame created by the deoptimization stub is considered |
+ // part of the frame because it contains saved caller PC and FP that |
+ // deoptimization will fill in. |
+ intptr_t* FrameBase(const StackFrame* frame) { |
+#if !defined(TARGET_ARCH_DBC) |
+ // SP of the deoptimization frame is the lowest slot because |
+ // stack is growing downwards. |
+ return reinterpret_cast<intptr_t*>( |
+ frame->sp() - (kDartFrameFixedSize * kWordSize)); |
+#else |
+ // First argument is the lowest slot because stack is growing upwards. |
+ return reinterpret_cast<intptr_t*>( |
+ frame->fp() - (kDartFrameFixedSize + num_args_) * kWordSize); |
+#endif // !defined(TARGET_ARCH_DBC) |
+ } |
+ |
+ void set_dest_frame(const StackFrame* frame) { |
+ ASSERT(frame != NULL && dest_frame_ == NULL); |
+ dest_frame_ = FrameBase(frame); |
} |
Thread* thread() const { return thread_; } |
@@ -188,10 +222,18 @@ class DeoptContext { |
return deferred_objects_[idx]; |
} |
+ intptr_t num_args() const { return num_args_; } |
+ |
private: |
intptr_t* GetDestFrameAddressAt(intptr_t index) const { |
ASSERT(dest_frame_ != NULL); |
ASSERT((0 <= index) && (index < dest_frame_size_)); |
+#if defined(TARGET_ARCH_DBC) |
+ // Stack on DBC is growing upwards but we record deopt commands |
+ // in the same order we record them on other architectures as if |
+ // the stack was growing downwards. |
+ index = dest_frame_size_ - 1 - index; |
+#endif // defined(TARGET_ARCH_DBC) |
return &dest_frame_[index]; |
} |
@@ -383,7 +425,7 @@ class RegisterSource { |
context, reg())); |
} else { |
return *reinterpret_cast<T*>(context->GetSourceFrameAddressAt( |
- context->source_frame_size() - raw_index() - 1)); |
+ raw_index())); |
} |
} |