Chromium Code Reviews| Index: runtime/vm/deopt_instructions.h |
| diff --git a/runtime/vm/deopt_instructions.h b/runtime/vm/deopt_instructions.h |
| index 229a0aaec1c985cd2221ef60bf7a3624408b91f8..aa50a7bdf1f76627d69422e5811116dff5105a29 100644 |
| --- a/runtime/vm/deopt_instructions.h |
| +++ b/runtime/vm/deopt_instructions.h |
| @@ -12,6 +12,7 @@ |
| #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 +49,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,30 +69,66 @@ class DeoptContext { |
| } |
| intptr_t RegisterValue(Register reg) const { |
| +#if !defined(TARGET_ARCH_DBC) |
| ASSERT(cpu_registers_ != NULL); |
|
zra
2016/05/20 16:56:05
Would it make sense to keep any of these asserts?
Vyacheslav Egorov (Google)
2016/05/24 12:42:20
Done.
|
| ASSERT(reg >= 0); |
| ASSERT(reg < kNumberOfCpuRegisters); |
| 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 { |
| +#if !defined(TARGET_ARCH_DBC) |
| ASSERT(fpu_registers_ != NULL); |
| ASSERT(reg >= 0); |
| ASSERT(reg < kNumberOfFpuRegisters); |
| return *reinterpret_cast<double*>(&fpu_registers_[reg]); |
| +#else |
| + UNREACHABLE(); |
|
zra
2016/05/20 16:56:05
Maybe instead of this #ifdef do ASSERT(FlowGraphCo
Vyacheslav Egorov (Google)
2016/05/24 12:42:20
Done.
|
| + return 0.0; |
| +#endif // !defined(TARGET_ARCH_DBC) |
| } |
| simd128_value_t FpuRegisterValueAsSimd128(FpuRegister reg) const { |
| +#if !defined(TARGET_ARCH_DBC) |
| ASSERT(fpu_registers_ != NULL); |
| ASSERT(reg >= 0); |
| ASSERT(reg < kNumberOfFpuRegisters); |
| const float* address = reinterpret_cast<float*>(&fpu_registers_[reg]); |
| 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; |
| +#else |
| + UNREACHABLE(); |
|
zra
2016/05/20 16:56:05
ditto with FlowGraphCompiler::SupportsUnboxedSimd1
Vyacheslav Egorov (Google)
2016/05/24 12:42:20
Done.
|
| + return simd128_value_t(); |
| +#endif |
| + } |
| + |
| + // 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) { |
|
Florian Schneider
2016/05/25 11:28:40
static?
Florian Schneider
2016/05/25 11:29:46
Never mind... num_args_ is used.
|
| +#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 +229,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 +432,7 @@ class RegisterSource { |
| context, reg())); |
| } else { |
| return *reinterpret_cast<T*>(context->GetSourceFrameAddressAt( |
| - context->source_frame_size() - raw_index() - 1)); |
| + raw_index())); |
| } |
| } |