| 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 | 
|---|