OLD | NEW |
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 #ifndef VM_DEOPT_INSTRUCTIONS_H_ | 5 #ifndef VM_DEOPT_INSTRUCTIONS_H_ |
6 #define VM_DEOPT_INSTRUCTIONS_H_ | 6 #define VM_DEOPT_INSTRUCTIONS_H_ |
7 | 7 |
8 #include "vm/allocation.h" | 8 #include "vm/allocation.h" |
9 #include "vm/assembler.h" | 9 #include "vm/assembler.h" |
10 #include "vm/code_generator.h" | 10 #include "vm/code_generator.h" |
11 #include "vm/deferred_objects.h" | 11 #include "vm/deferred_objects.h" |
| 12 #include "vm/flow_graph_compiler.h" |
12 #include "vm/growable_array.h" | 13 #include "vm/growable_array.h" |
13 #include "vm/locations.h" | 14 #include "vm/locations.h" |
14 #include "vm/object.h" | 15 #include "vm/object.h" |
| 16 #include "vm/stack_frame.h" |
15 #include "vm/thread.h" | 17 #include "vm/thread.h" |
16 | 18 |
17 namespace dart { | 19 namespace dart { |
18 | 20 |
19 class Location; | 21 class Location; |
20 class Value; | 22 class Value; |
21 class MaterializeObjectInstr; | 23 class MaterializeObjectInstr; |
22 class StackFrame; | 24 class StackFrame; |
23 class TimelineEvent; | 25 class TimelineEvent; |
24 | 26 |
(...skipping 16 matching lines...) Expand all Loading... |
41 bool deoptimizing_code); | 43 bool deoptimizing_code); |
42 virtual ~DeoptContext(); | 44 virtual ~DeoptContext(); |
43 | 45 |
44 // Returns the offset of the dest fp from the dest sp. Used in | 46 // Returns the offset of the dest fp from the dest sp. Used in |
45 // runtime code to adjust the stack size before deoptimization. | 47 // runtime code to adjust the stack size before deoptimization. |
46 intptr_t DestStackAdjustment() const; | 48 intptr_t DestStackAdjustment() const; |
47 | 49 |
48 intptr_t* GetSourceFrameAddressAt(intptr_t index) const { | 50 intptr_t* GetSourceFrameAddressAt(intptr_t index) const { |
49 ASSERT(source_frame_ != NULL); | 51 ASSERT(source_frame_ != NULL); |
50 ASSERT((0 <= index) && (index < source_frame_size_)); | 52 ASSERT((0 <= index) && (index < source_frame_size_)); |
| 53 #if !defined(TARGET_ARCH_DBC) |
| 54 // Convert FP relative index to SP relative one. |
| 55 index = source_frame_size_ - 1 - index; |
| 56 #endif // !defined(TARGET_ARCH_DBC) |
51 return &source_frame_[index]; | 57 return &source_frame_[index]; |
52 } | 58 } |
53 | 59 |
54 intptr_t GetSourceFp() const; | 60 intptr_t GetSourceFp() const; |
55 intptr_t GetSourcePp() const; | 61 intptr_t GetSourcePp() const; |
56 intptr_t GetSourcePc() const; | 62 intptr_t GetSourcePc() const; |
57 | 63 |
58 intptr_t GetCallerFp() const; | 64 intptr_t GetCallerFp() const; |
59 void SetCallerFp(intptr_t callers_fp); | 65 void SetCallerFp(intptr_t callers_fp); |
60 | 66 |
61 RawObject* ObjectAt(intptr_t index) const { | 67 RawObject* ObjectAt(intptr_t index) const { |
62 const ObjectPool& object_pool = ObjectPool::Handle(object_pool_); | 68 const ObjectPool& object_pool = ObjectPool::Handle(object_pool_); |
63 return object_pool.ObjectAt(index); | 69 return object_pool.ObjectAt(index); |
64 } | 70 } |
65 | 71 |
66 intptr_t RegisterValue(Register reg) const { | 72 intptr_t RegisterValue(Register reg) const { |
67 ASSERT(cpu_registers_ != NULL); | |
68 ASSERT(reg >= 0); | 73 ASSERT(reg >= 0); |
69 ASSERT(reg < kNumberOfCpuRegisters); | 74 ASSERT(reg < kNumberOfCpuRegisters); |
| 75 #if !defined(TARGET_ARCH_DBC) |
| 76 ASSERT(cpu_registers_ != NULL); |
70 return cpu_registers_[reg]; | 77 return cpu_registers_[reg]; |
| 78 #else |
| 79 // On DBC registers and stack slots are the same. |
| 80 const intptr_t stack_index = num_args_ + kDartFrameFixedSize + reg; |
| 81 return *GetSourceFrameAddressAt(stack_index); |
| 82 #endif // !defined(TARGET_ARCH_DBC) |
71 } | 83 } |
72 | 84 |
73 double FpuRegisterValue(FpuRegister reg) const { | 85 double FpuRegisterValue(FpuRegister reg) const { |
| 86 ASSERT(FlowGraphCompiler::SupportsUnboxedDoubles()); |
74 ASSERT(fpu_registers_ != NULL); | 87 ASSERT(fpu_registers_ != NULL); |
75 ASSERT(reg >= 0); | 88 ASSERT(reg >= 0); |
76 ASSERT(reg < kNumberOfFpuRegisters); | 89 ASSERT(reg < kNumberOfFpuRegisters); |
77 return *reinterpret_cast<double*>(&fpu_registers_[reg]); | 90 return *reinterpret_cast<double*>(&fpu_registers_[reg]); |
78 } | 91 } |
79 | 92 |
80 simd128_value_t FpuRegisterValueAsSimd128(FpuRegister reg) const { | 93 simd128_value_t FpuRegisterValueAsSimd128(FpuRegister reg) const { |
| 94 ASSERT(FlowGraphCompiler::SupportsUnboxedSimd128()); |
81 ASSERT(fpu_registers_ != NULL); | 95 ASSERT(fpu_registers_ != NULL); |
82 ASSERT(reg >= 0); | 96 ASSERT(reg >= 0); |
83 ASSERT(reg < kNumberOfFpuRegisters); | 97 ASSERT(reg < kNumberOfFpuRegisters); |
84 const float* address = reinterpret_cast<float*>(&fpu_registers_[reg]); | 98 const float* address = reinterpret_cast<float*>(&fpu_registers_[reg]); |
85 return simd128_value_t().readFrom(address); | 99 return simd128_value_t().readFrom(address); |
86 } | 100 } |
87 | 101 |
88 void set_dest_frame(intptr_t* dest_frame) { | 102 // Return base pointer for the given frame (either source or destination). |
89 ASSERT(dest_frame != NULL && dest_frame_ == NULL); | 103 // Base pointer points to the slot with the lowest address in the frame |
90 dest_frame_ = dest_frame; | 104 // including incoming arguments and artificial deoptimization frame |
| 105 // on top of it. |
| 106 // Note: artificial frame created by the deoptimization stub is considered |
| 107 // part of the frame because it contains saved caller PC and FP that |
| 108 // deoptimization will fill in. |
| 109 intptr_t* FrameBase(const StackFrame* frame) { |
| 110 #if !defined(TARGET_ARCH_DBC) |
| 111 // SP of the deoptimization frame is the lowest slot because |
| 112 // stack is growing downwards. |
| 113 return reinterpret_cast<intptr_t*>( |
| 114 frame->sp() - (kDartFrameFixedSize * kWordSize)); |
| 115 #else |
| 116 // First argument is the lowest slot because stack is growing upwards. |
| 117 return reinterpret_cast<intptr_t*>( |
| 118 frame->fp() - (kDartFrameFixedSize + num_args_) * kWordSize); |
| 119 #endif // !defined(TARGET_ARCH_DBC) |
| 120 } |
| 121 |
| 122 void set_dest_frame(const StackFrame* frame) { |
| 123 ASSERT(frame != NULL && dest_frame_ == NULL); |
| 124 dest_frame_ = FrameBase(frame); |
91 } | 125 } |
92 | 126 |
93 Thread* thread() const { return thread_; } | 127 Thread* thread() const { return thread_; } |
94 Zone* zone() const { return thread_->zone(); } | 128 Zone* zone() const { return thread_->zone(); } |
95 | 129 |
96 intptr_t source_frame_size() const { return source_frame_size_; } | 130 intptr_t source_frame_size() const { return source_frame_size_; } |
97 intptr_t dest_frame_size() const { return dest_frame_size_; } | 131 intptr_t dest_frame_size() const { return dest_frame_size_; } |
98 | 132 |
99 RawCode* code() const { return code_; } | 133 RawCode* code() const { return code_; } |
100 | 134 |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
181 } | 215 } |
182 | 216 |
183 void DeferPpMaterialization(intptr_t index, RawObject** slot) { | 217 void DeferPpMaterialization(intptr_t index, RawObject** slot) { |
184 deferred_slots_ = new DeferredPp(index, slot, deferred_slots_); | 218 deferred_slots_ = new DeferredPp(index, slot, deferred_slots_); |
185 } | 219 } |
186 | 220 |
187 DeferredObject* GetDeferredObject(intptr_t idx) const { | 221 DeferredObject* GetDeferredObject(intptr_t idx) const { |
188 return deferred_objects_[idx]; | 222 return deferred_objects_[idx]; |
189 } | 223 } |
190 | 224 |
| 225 intptr_t num_args() const { return num_args_; } |
| 226 |
191 private: | 227 private: |
192 intptr_t* GetDestFrameAddressAt(intptr_t index) const { | 228 intptr_t* GetDestFrameAddressAt(intptr_t index) const { |
193 ASSERT(dest_frame_ != NULL); | 229 ASSERT(dest_frame_ != NULL); |
194 ASSERT((0 <= index) && (index < dest_frame_size_)); | 230 ASSERT((0 <= index) && (index < dest_frame_size_)); |
| 231 #if defined(TARGET_ARCH_DBC) |
| 232 // Stack on DBC is growing upwards but we record deopt commands |
| 233 // in the same order we record them on other architectures as if |
| 234 // the stack was growing downwards. |
| 235 index = dest_frame_size_ - 1 - index; |
| 236 #endif // defined(TARGET_ARCH_DBC) |
195 return &dest_frame_[index]; | 237 return &dest_frame_[index]; |
196 } | 238 } |
197 | 239 |
198 void PrepareForDeferredMaterialization(intptr_t count) { | 240 void PrepareForDeferredMaterialization(intptr_t count) { |
199 if (count > 0) { | 241 if (count > 0) { |
200 deferred_objects_ = new DeferredObject*[count]; | 242 deferred_objects_ = new DeferredObject*[count]; |
201 deferred_objects_count_ = count; | 243 deferred_objects_count_ = count; |
202 } | 244 } |
203 } | 245 } |
204 | 246 |
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
376 : source_index_(KindField::encode(kind) | RawIndexField::encode(index)) { | 418 : source_index_(KindField::encode(kind) | RawIndexField::encode(index)) { |
377 } | 419 } |
378 | 420 |
379 template<typename T> | 421 template<typename T> |
380 T Value(DeoptContext* context) const { | 422 T Value(DeoptContext* context) const { |
381 if (is_register()) { | 423 if (is_register()) { |
382 return static_cast<T>(RegisterReader<RegisterType, T>::Read( | 424 return static_cast<T>(RegisterReader<RegisterType, T>::Read( |
383 context, reg())); | 425 context, reg())); |
384 } else { | 426 } else { |
385 return *reinterpret_cast<T*>(context->GetSourceFrameAddressAt( | 427 return *reinterpret_cast<T*>(context->GetSourceFrameAddressAt( |
386 context->source_frame_size() - raw_index() - 1)); | 428 raw_index())); |
387 } | 429 } |
388 } | 430 } |
389 | 431 |
390 intptr_t source_index() const { return source_index_; } | 432 intptr_t source_index() const { return source_index_; } |
391 | 433 |
392 const char* ToCString() const { | 434 const char* ToCString() const { |
393 if (is_register()) { | 435 if (is_register()) { |
394 return Name(reg()); | 436 return Name(reg()); |
395 } else { | 437 } else { |
396 return Thread::Current()->zone()->PrintToString( | 438 return Thread::Current()->zone()->PrintToString( |
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
551 public BitField<intptr_t, ICData::DeoptReasonId, 0, 8> { }; | 593 public BitField<intptr_t, ICData::DeoptReasonId, 0, 8> { }; |
552 class FlagsField : public BitField<intptr_t, uint32_t, 8, 8> { }; | 594 class FlagsField : public BitField<intptr_t, uint32_t, 8, 8> { }; |
553 | 595 |
554 private: | 596 private: |
555 static const intptr_t kEntrySize = 3; | 597 static const intptr_t kEntrySize = 3; |
556 }; | 598 }; |
557 | 599 |
558 } // namespace dart | 600 } // namespace dart |
559 | 601 |
560 #endif // VM_DEOPT_INSTRUCTIONS_H_ | 602 #endif // VM_DEOPT_INSTRUCTIONS_H_ |
OLD | NEW |