| 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/growable_array.h" | 12 #include "vm/growable_array.h" |
| 13 #include "vm/object.h" | 13 #include "vm/object.h" |
| 14 | 14 |
| 15 namespace dart { | 15 namespace dart { |
| 16 | 16 |
| 17 class Location; | 17 class Location; |
| 18 class Value; | 18 class Value; |
| 19 class MaterializeObjectInstr; | 19 class MaterializeObjectInstr; |
| 20 class StackFrame; |
| 20 | 21 |
| 21 // Holds all data relevant for execution of deoptimization instructions. | 22 // Holds all data relevant for execution of deoptimization instructions. |
| 22 class DeoptContext { | 23 class DeoptContext { |
| 23 public: | 24 public: |
| 24 // 'num_args' is 0 if there are no arguments or if there are optional | 25 enum DestFrameOptions { |
| 25 // arguments. | 26 kDestIsOriginalFrame, // Replace the original frame with deopt frame. |
| 26 DeoptContext(const Array& object_table, | 27 kDestIsAllocated // Write deopt frame to a buffer. |
| 27 intptr_t num_args, | 28 }; |
| 28 DeoptReasonId deopt_reason); | |
| 29 | 29 |
| 30 DeoptContext(const StackFrame* frame, |
| 31 const Code& code, |
| 32 DestFrameOptions dest_options, |
| 33 fpu_register_t* fpu_registers, |
| 34 intptr_t* cpu_registers); |
| 30 virtual ~DeoptContext(); | 35 virtual ~DeoptContext(); |
| 31 | 36 |
| 32 // Sets the sources (frame and registers) for this deoptimization. | 37 // Returns the offset of the dest fp from the dest sp. Used in |
| 33 // | 38 // runtime code to adjust the stack size before deoptimization. |
| 34 // if 'frame_is_copy' is true, DeoptContext will delete the frame | 39 intptr_t DestStackAdjustment() const; |
| 35 // when it is done. | |
| 36 void SetSourceArgs(intptr_t* frame_start, | |
| 37 intptr_t frame_size, | |
| 38 fpu_register_t* fpu_registers, | |
| 39 intptr_t* cpu_registers, | |
| 40 bool frame_is_copy); | |
| 41 | |
| 42 // Sets the destination fraem for this deoptimization. | |
| 43 // | |
| 44 // 'frame_start' oints to the fixed size portion of the frame under | |
| 45 // sp. | |
| 46 // | |
| 47 // DeoptContext does not claim ownership of the frame memory. | |
| 48 void SetDestArgs(intptr_t* frame_start, intptr_t frame_size); | |
| 49 | 40 |
| 50 intptr_t* GetSourceFrameAddressAt(intptr_t index) const { | 41 intptr_t* GetSourceFrameAddressAt(intptr_t index) const { |
| 51 ASSERT(source_frame_ != NULL); | 42 ASSERT(source_frame_ != NULL); |
| 52 ASSERT((0 <= index) && (index < source_frame_size_)); | 43 ASSERT((0 <= index) && (index < source_frame_size_)); |
| 53 return &source_frame_[index]; | 44 return &source_frame_[index]; |
| 54 } | 45 } |
| 55 | 46 |
| 56 intptr_t* GetDestFrameAddressAt(intptr_t index) const { | |
| 57 ASSERT(dest_frame_ != NULL); | |
| 58 ASSERT((0 <= index) && (index < dest_frame_size_)); | |
| 59 return &dest_frame_[index]; | |
| 60 } | |
| 61 | |
| 62 intptr_t GetSourceFp() const; | 47 intptr_t GetSourceFp() const; |
| 63 intptr_t GetSourcePp() const; | 48 intptr_t GetSourcePp() const; |
| 64 intptr_t GetSourcePc() const; | 49 intptr_t GetSourcePc() const; |
| 65 | 50 |
| 66 intptr_t GetCallerFp() const; | 51 intptr_t GetCallerFp() const; |
| 67 void SetCallerFp(intptr_t callers_fp); | 52 void SetCallerFp(intptr_t callers_fp); |
| 68 | 53 |
| 69 RawObject* ObjectAt(intptr_t index) const { | 54 RawObject* ObjectAt(intptr_t index) const { |
| 70 const Array& object_table = Array::Handle(object_table_); | 55 const Array& object_table = Array::Handle(object_table_); |
| 71 return object_table.At(index); | 56 return object_table.At(index); |
| 72 } | 57 } |
| 73 | 58 |
| 74 intptr_t RegisterValue(Register reg) const { | 59 intptr_t RegisterValue(Register reg) const { |
| 60 ASSERT(cpu_registers_ != NULL); |
| 75 return cpu_registers_[reg]; | 61 return cpu_registers_[reg]; |
| 76 } | 62 } |
| 77 | 63 |
| 78 double FpuRegisterValue(FpuRegister reg) const { | 64 double FpuRegisterValue(FpuRegister reg) const { |
| 65 ASSERT(fpu_registers_ != NULL); |
| 79 return *reinterpret_cast<double*>(&fpu_registers_[reg]); | 66 return *reinterpret_cast<double*>(&fpu_registers_[reg]); |
| 80 } | 67 } |
| 81 | 68 |
| 82 int64_t FpuRegisterValueAsInt64(FpuRegister reg) const { | 69 int64_t FpuRegisterValueAsInt64(FpuRegister reg) const { |
| 70 ASSERT(fpu_registers_ != NULL); |
| 83 return *reinterpret_cast<int64_t*>(&fpu_registers_[reg]); | 71 return *reinterpret_cast<int64_t*>(&fpu_registers_[reg]); |
| 84 } | 72 } |
| 85 | 73 |
| 86 simd128_value_t FpuRegisterValueAsSimd128(FpuRegister reg) const { | 74 simd128_value_t FpuRegisterValueAsSimd128(FpuRegister reg) const { |
| 75 ASSERT(fpu_registers_ != NULL); |
| 87 const float* address = reinterpret_cast<float*>(&fpu_registers_[reg]); | 76 const float* address = reinterpret_cast<float*>(&fpu_registers_[reg]); |
| 88 return simd128_value_t().readFrom(address); | 77 return simd128_value_t().readFrom(address); |
| 89 } | 78 } |
| 90 | 79 |
| 80 void set_dest_frame(intptr_t* dest_frame) { |
| 81 ASSERT(dest_frame != NULL && dest_frame_ == NULL); |
| 82 dest_frame_ = dest_frame; |
| 83 } |
| 84 |
| 91 Isolate* isolate() const { return isolate_; } | 85 Isolate* isolate() const { return isolate_; } |
| 92 | 86 |
| 93 intptr_t source_frame_size() const { return source_frame_size_; } | 87 intptr_t source_frame_size() const { return source_frame_size_; } |
| 88 intptr_t dest_frame_size() const { return dest_frame_size_; } |
| 89 |
| 90 RawCode* code() const { return code_; } |
| 94 | 91 |
| 95 DeoptReasonId deopt_reason() const { return deopt_reason_; } | 92 DeoptReasonId deopt_reason() const { return deopt_reason_; } |
| 96 | 93 |
| 94 RawDeoptInfo* deopt_info() const { return deopt_info_; } |
| 95 |
| 96 // Fills the destination frame but defers materialization of |
| 97 // objects. |
| 98 void FillDestFrame(); |
| 99 |
| 100 // Materializes all deferred objects. Returns the total number of |
| 101 // artificial arguments used during deoptimization. |
| 102 intptr_t MaterializeDeferredObjects(); |
| 103 |
| 104 RawArray* DestFrameAsArray(); |
| 105 |
| 97 void VisitObjectPointers(ObjectPointerVisitor* visitor); | 106 void VisitObjectPointers(ObjectPointerVisitor* visitor); |
| 98 | 107 |
| 99 void PrepareForDeferredMaterialization(intptr_t count) { | |
| 100 if (count > 0) { | |
| 101 deferred_objects_ = new DeferredObject*[count]; | |
| 102 deferred_objects_count_ = count; | |
| 103 } | |
| 104 } | |
| 105 | |
| 106 DeferredObject* GetDeferredObject(intptr_t idx) const { | |
| 107 return deferred_objects_[idx]; | |
| 108 } | |
| 109 | |
| 110 // Sets the materialized value for some deferred object. | |
| 111 // | |
| 112 // Claims ownership of the memory for 'object'. | |
| 113 void SetDeferredObjectAt(intptr_t idx, DeferredObject* object) { | |
| 114 deferred_objects_[idx] = object; | |
| 115 } | |
| 116 | |
| 117 intptr_t DeferredObjectsCount() const { | |
| 118 return deferred_objects_count_; | |
| 119 } | |
| 120 | |
| 121 void DeferMaterializedObjectRef(intptr_t idx, intptr_t* slot) { | 108 void DeferMaterializedObjectRef(intptr_t idx, intptr_t* slot) { |
| 122 deferred_object_refs_ = new DeferredObjectRef( | 109 deferred_object_refs_ = new DeferredObjectRef( |
| 123 idx, | 110 idx, |
| 124 reinterpret_cast<RawInstance**>(slot), | 111 reinterpret_cast<RawInstance**>(slot), |
| 125 deferred_object_refs_); | 112 deferred_object_refs_); |
| 126 } | 113 } |
| 127 | 114 |
| 128 void DeferDoubleMaterialization(double value, RawDouble** slot) { | 115 void DeferDoubleMaterialization(double value, RawDouble** slot) { |
| 129 deferred_boxes_ = new DeferredDouble( | 116 deferred_boxes_ = new DeferredDouble( |
| 130 value, | 117 value, |
| (...skipping 17 matching lines...) Expand all Loading... |
| 148 } | 135 } |
| 149 | 136 |
| 150 void DeferUint32x4Materialization(simd128_value_t value, | 137 void DeferUint32x4Materialization(simd128_value_t value, |
| 151 RawUint32x4** slot) { | 138 RawUint32x4** slot) { |
| 152 deferred_boxes_ = new DeferredUint32x4( | 139 deferred_boxes_ = new DeferredUint32x4( |
| 153 value, | 140 value, |
| 154 reinterpret_cast<RawInstance**>(slot), | 141 reinterpret_cast<RawInstance**>(slot), |
| 155 deferred_boxes_); | 142 deferred_boxes_); |
| 156 } | 143 } |
| 157 | 144 |
| 158 // Materializes all deferred objects. Returns the total number of | 145 DeferredObject* GetDeferredObject(intptr_t idx) const { |
| 159 // artificial arguments used during deoptimization. | 146 return deferred_objects_[idx]; |
| 160 intptr_t MaterializeDeferredObjects(); | 147 } |
| 161 | 148 |
| 162 private: | 149 private: |
| 150 intptr_t* GetDestFrameAddressAt(intptr_t index) const { |
| 151 ASSERT(dest_frame_ != NULL); |
| 152 ASSERT((0 <= index) && (index < dest_frame_size_)); |
| 153 return &dest_frame_[index]; |
| 154 } |
| 155 |
| 156 void PrepareForDeferredMaterialization(intptr_t count) { |
| 157 if (count > 0) { |
| 158 deferred_objects_ = new DeferredObject*[count]; |
| 159 deferred_objects_count_ = count; |
| 160 } |
| 161 } |
| 162 |
| 163 // Sets the materialized value for some deferred object. |
| 164 // |
| 165 // Claims ownership of the memory for 'object'. |
| 166 void SetDeferredObjectAt(intptr_t idx, DeferredObject* object) { |
| 167 deferred_objects_[idx] = object; |
| 168 } |
| 169 |
| 170 intptr_t DeferredObjectsCount() const { |
| 171 return deferred_objects_count_; |
| 172 } |
| 173 |
| 174 RawCode* code_; |
| 163 RawArray* object_table_; | 175 RawArray* object_table_; |
| 176 RawDeoptInfo* deopt_info_; |
| 177 bool dest_frame_is_allocated_; |
| 164 intptr_t* dest_frame_; | 178 intptr_t* dest_frame_; |
| 165 intptr_t dest_frame_size_; | 179 intptr_t dest_frame_size_; |
| 166 bool source_frame_is_copy_; | 180 bool source_frame_is_allocated_; |
| 167 intptr_t* source_frame_; | 181 intptr_t* source_frame_; |
| 168 intptr_t source_frame_size_; | 182 intptr_t source_frame_size_; |
| 169 intptr_t* cpu_registers_; | 183 intptr_t* cpu_registers_; |
| 170 fpu_register_t* fpu_registers_; | 184 fpu_register_t* fpu_registers_; |
| 171 const intptr_t num_args_; | 185 intptr_t num_args_; |
| 172 const DeoptReasonId deopt_reason_; | 186 DeoptReasonId deopt_reason_; |
| 173 intptr_t caller_fp_; | 187 intptr_t caller_fp_; |
| 174 Isolate* isolate_; | 188 Isolate* isolate_; |
| 175 | 189 |
| 176 DeferredSlot* deferred_boxes_; | 190 DeferredSlot* deferred_boxes_; |
| 177 DeferredSlot* deferred_object_refs_; | 191 DeferredSlot* deferred_object_refs_; |
| 178 | 192 |
| 179 intptr_t deferred_objects_count_; | 193 intptr_t deferred_objects_count_; |
| 180 DeferredObject** deferred_objects_; | 194 DeferredObject** deferred_objects_; |
| 181 | 195 |
| 182 DISALLOW_COPY_AND_ASSIGN(DeoptContext); | 196 DISALLOW_COPY_AND_ASSIGN(DeoptContext); |
| (...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 358 DeoptInfo* info, | 372 DeoptInfo* info, |
| 359 Smi* reason); | 373 Smi* reason); |
| 360 | 374 |
| 361 private: | 375 private: |
| 362 static const intptr_t kEntrySize = 3; | 376 static const intptr_t kEntrySize = 3; |
| 363 }; | 377 }; |
| 364 | 378 |
| 365 } // namespace dart | 379 } // namespace dart |
| 366 | 380 |
| 367 #endif // VM_DEOPT_INSTRUCTIONS_H_ | 381 #endif // VM_DEOPT_INSTRUCTIONS_H_ |
| OLD | NEW |