| 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/growable_array.h" | 12 #include "vm/growable_array.h" |
| 12 #include "vm/object.h" | 13 #include "vm/object.h" |
| 13 | 14 |
| 14 namespace dart { | 15 namespace dart { |
| 15 | 16 |
| 16 class Location; | 17 class Location; |
| 17 class Value; | 18 class Value; |
| 18 class MaterializeObjectInstr; | 19 class MaterializeObjectInstr; |
| 19 | 20 |
| 20 // Holds all data relevant for execution of deoptimization instructions. | 21 // Holds all data relevant for execution of deoptimization instructions. |
| 21 class DeoptimizationContext : public ValueObject { | 22 class DeoptContext { |
| 22 public: | 23 public: |
| 23 // 'to_frame_start' points to the fixed size portion of the frame under sp. | |
| 24 // 'num_args' is 0 if there are no arguments or if there are optional | 24 // 'num_args' is 0 if there are no arguments or if there are optional |
| 25 // arguments. | 25 // arguments. |
| 26 DeoptimizationContext(intptr_t* to_frame_start, | 26 DeoptContext(const Array& object_table, |
| 27 intptr_t to_frame_size, | 27 intptr_t num_args, |
| 28 const Array& object_table, | 28 DeoptReasonId deopt_reason); |
| 29 intptr_t num_args, | 29 |
| 30 DeoptReasonId deopt_reason); | 30 ~DeoptContext(); |
| 31 |
| 32 // 'start' points to the fixed size portion of the frame under sp. |
| 33 // |
| 34 // DeoptContext does not claim ownership of the frame memory. |
| 35 void SetToFrame(intptr_t* start, intptr_t size); |
| 36 |
| 37 // DeoptContext does not claim ownership of the frame memory. |
| 38 void SetFromFrame(intptr_t* start, intptr_t size); |
| 39 |
| 40 // DeoptContext does not claim ownership of the memory used for the |
| 41 // saved registers. |
| 42 void SetSavedRegisters(fpu_register_t* fpu_registers, |
| 43 intptr_t* cpu_registers); |
| 44 |
| 45 intptr_t* from_frame() const { return from_frame_; } |
| 46 fpu_register_t* fpu_registers() const { return fpu_registers_; } |
| 47 intptr_t* cpu_registers() const { return cpu_registers_; } |
| 31 | 48 |
| 32 intptr_t* GetFromFrameAddressAt(intptr_t index) const { | 49 intptr_t* GetFromFrameAddressAt(intptr_t index) const { |
| 50 ASSERT(from_frame_ != NULL); |
| 33 ASSERT((0 <= index) && (index < from_frame_size_)); | 51 ASSERT((0 <= index) && (index < from_frame_size_)); |
| 34 return &from_frame_[index]; | 52 return &from_frame_[index]; |
| 35 } | 53 } |
| 36 | 54 |
| 37 intptr_t* GetToFrameAddressAt(intptr_t index) const { | 55 intptr_t* GetToFrameAddressAt(intptr_t index) const { |
| 56 ASSERT(to_frame_ != NULL); |
| 38 ASSERT((0 <= index) && (index < to_frame_size_)); | 57 ASSERT((0 <= index) && (index < to_frame_size_)); |
| 39 return &to_frame_[index]; | 58 return &to_frame_[index]; |
| 40 } | 59 } |
| 41 | 60 |
| 42 intptr_t GetFromFp() const; | 61 intptr_t GetFromFp() const; |
| 43 intptr_t GetFromPp() const; | 62 intptr_t GetFromPp() const; |
| 44 intptr_t GetFromPc() const; | 63 intptr_t GetFromPc() const; |
| 45 | 64 |
| 46 intptr_t GetCallerFp() const; | 65 intptr_t GetCallerFp() const; |
| 47 void SetCallerFp(intptr_t callers_fp); | 66 void SetCallerFp(intptr_t callers_fp); |
| 48 | 67 |
| 49 RawObject* ObjectAt(intptr_t index) const { | 68 RawObject* ObjectAt(intptr_t index) const { |
| 50 return object_table_.At(index); | 69 const Array& object_table = Array::Handle(object_table_); |
| 70 return object_table.At(index); |
| 51 } | 71 } |
| 52 | 72 |
| 53 intptr_t RegisterValue(Register reg) const { | 73 intptr_t RegisterValue(Register reg) const { |
| 54 return registers_copy_[reg]; | 74 return cpu_registers_[reg]; |
| 55 } | 75 } |
| 56 | 76 |
| 57 double FpuRegisterValue(FpuRegister reg) const { | 77 double FpuRegisterValue(FpuRegister reg) const { |
| 58 return *reinterpret_cast<double*>(&fpu_registers_copy_[reg]); | 78 return *reinterpret_cast<double*>(&fpu_registers_[reg]); |
| 59 } | 79 } |
| 60 | 80 |
| 61 int64_t FpuRegisterValueAsInt64(FpuRegister reg) const { | 81 int64_t FpuRegisterValueAsInt64(FpuRegister reg) const { |
| 62 return *reinterpret_cast<int64_t*>(&fpu_registers_copy_[reg]); | 82 return *reinterpret_cast<int64_t*>(&fpu_registers_[reg]); |
| 63 } | 83 } |
| 64 | 84 |
| 65 simd128_value_t FpuRegisterValueAsSimd128(FpuRegister reg) const { | 85 simd128_value_t FpuRegisterValueAsSimd128(FpuRegister reg) const { |
| 66 const float* address = reinterpret_cast<float*>(&fpu_registers_copy_[reg]); | 86 const float* address = reinterpret_cast<float*>(&fpu_registers_[reg]); |
| 67 return simd128_value_t().readFrom(address); | 87 return simd128_value_t().readFrom(address); |
| 68 } | 88 } |
| 69 | 89 |
| 70 Isolate* isolate() const { return isolate_; } | 90 Isolate* isolate() const { return isolate_; } |
| 71 | 91 |
| 72 intptr_t from_frame_size() const { return from_frame_size_; } | 92 intptr_t from_frame_size() const { return from_frame_size_; } |
| 73 | 93 |
| 74 DeoptReasonId deopt_reason() const { return deopt_reason_; } | 94 DeoptReasonId deopt_reason() const { return deopt_reason_; } |
| 75 | 95 |
| 96 void VisitObjectPointers(ObjectPointerVisitor* visitor); |
| 97 |
| 98 void PrepareForDeferredMaterialization(intptr_t count) { |
| 99 if (count > 0) { |
| 100 deferred_objects_ = new DeferredObject*[count]; |
| 101 deferred_objects_count_ = count; |
| 102 } |
| 103 } |
| 104 |
| 105 DeferredObject* GetDeferredObject(intptr_t idx) const { |
| 106 return deferred_objects_[idx]; |
| 107 } |
| 108 |
| 109 // Sets the materialized value for some deferred object. |
| 110 // |
| 111 // Claims ownership of the memory for 'object'. |
| 112 void SetDeferredObjectAt(intptr_t idx, DeferredObject* object) { |
| 113 deferred_objects_[idx] = object; |
| 114 } |
| 115 |
| 116 intptr_t DeferredObjectsCount() const { |
| 117 return deferred_objects_count_; |
| 118 } |
| 119 |
| 120 void DeferMaterializedObjectRef(intptr_t idx, intptr_t* slot) { |
| 121 deferred_object_refs_ = new DeferredObjectRef( |
| 122 idx, |
| 123 reinterpret_cast<RawInstance**>(slot), |
| 124 deferred_object_refs_); |
| 125 } |
| 126 |
| 127 void DeferDoubleMaterialization(double value, RawDouble** slot) { |
| 128 deferred_boxes_ = new DeferredDouble( |
| 129 value, |
| 130 reinterpret_cast<RawInstance**>(slot), |
| 131 deferred_boxes_); |
| 132 } |
| 133 |
| 134 void DeferMintMaterialization(int64_t value, RawMint** slot) { |
| 135 deferred_boxes_ = new DeferredMint( |
| 136 value, |
| 137 reinterpret_cast<RawInstance**>(slot), |
| 138 deferred_boxes_); |
| 139 } |
| 140 |
| 141 void DeferFloat32x4Materialization(simd128_value_t value, |
| 142 RawFloat32x4** slot) { |
| 143 deferred_boxes_ = new DeferredFloat32x4( |
| 144 value, |
| 145 reinterpret_cast<RawInstance**>(slot), |
| 146 deferred_boxes_); |
| 147 } |
| 148 |
| 149 void DeferUint32x4Materialization(simd128_value_t value, |
| 150 RawUint32x4** slot) { |
| 151 deferred_boxes_ = new DeferredUint32x4( |
| 152 value, |
| 153 reinterpret_cast<RawInstance**>(slot), |
| 154 deferred_boxes_); |
| 155 } |
| 156 |
| 157 // Materializes all deferred objects. Returns the total number of |
| 158 // artificial arguments used during deoptimization. |
| 159 intptr_t MaterializeDeferredObjects(); |
| 160 |
| 76 private: | 161 private: |
| 77 const Array& object_table_; | 162 RawArray* object_table_; |
| 78 intptr_t* to_frame_; | 163 intptr_t* to_frame_; |
| 79 const intptr_t to_frame_size_; | 164 intptr_t to_frame_size_; |
| 80 intptr_t* from_frame_; | 165 intptr_t* from_frame_; |
| 81 intptr_t from_frame_size_; | 166 intptr_t from_frame_size_; |
| 82 intptr_t* registers_copy_; | 167 intptr_t* cpu_registers_; |
| 83 fpu_register_t* fpu_registers_copy_; | 168 fpu_register_t* fpu_registers_; |
| 84 const intptr_t num_args_; | 169 const intptr_t num_args_; |
| 85 const DeoptReasonId deopt_reason_; | 170 const DeoptReasonId deopt_reason_; |
| 86 intptr_t caller_fp_; | 171 intptr_t caller_fp_; |
| 87 Isolate* isolate_; | 172 Isolate* isolate_; |
| 88 | 173 |
| 89 DISALLOW_COPY_AND_ASSIGN(DeoptimizationContext); | 174 DeferredSlot* deferred_boxes_; |
| 175 DeferredSlot* deferred_object_refs_; |
| 176 |
| 177 intptr_t deferred_objects_count_; |
| 178 DeferredObject** deferred_objects_; |
| 179 |
| 180 DISALLOW_COPY_AND_ASSIGN(DeoptContext); |
| 90 }; | 181 }; |
| 91 | 182 |
| 92 | 183 |
| 93 | 184 |
| 94 // Represents one deopt instruction, e.g, setup return address, store object, | 185 // Represents one deopt instruction, e.g, setup return address, store object, |
| 95 // store register, etc. The target is defined by instruction's position in | 186 // store register, etc. The target is defined by instruction's position in |
| 96 // the deopt-info array. | 187 // the deopt-info array. |
| 97 class DeoptInstr : public ZoneAllocated { | 188 class DeoptInstr : public ZoneAllocated { |
| 98 public: | 189 public: |
| 99 enum Kind { | 190 enum Kind { |
| (...skipping 19 matching lines...) Expand all Loading... |
| 119 kMaterializeObject | 210 kMaterializeObject |
| 120 }; | 211 }; |
| 121 | 212 |
| 122 static DeoptInstr* Create(intptr_t kind_as_int, intptr_t from_index); | 213 static DeoptInstr* Create(intptr_t kind_as_int, intptr_t from_index); |
| 123 | 214 |
| 124 DeoptInstr() {} | 215 DeoptInstr() {} |
| 125 virtual ~DeoptInstr() {} | 216 virtual ~DeoptInstr() {} |
| 126 | 217 |
| 127 virtual const char* ToCString() const = 0; | 218 virtual const char* ToCString() const = 0; |
| 128 | 219 |
| 129 virtual void Execute(DeoptimizationContext* deopt_context, | 220 virtual void Execute(DeoptContext* deopt_context, intptr_t* to_addr) = 0; |
| 130 intptr_t* to_addr) = 0; | |
| 131 | 221 |
| 132 virtual DeoptInstr::Kind kind() const = 0; | 222 virtual DeoptInstr::Kind kind() const = 0; |
| 133 | 223 |
| 134 bool Equals(const DeoptInstr& other) const { | 224 bool Equals(const DeoptInstr& other) const { |
| 135 return (kind() == other.kind()) && (from_index() == other.from_index()); | 225 return (kind() == other.kind()) && (from_index() == other.from_index()); |
| 136 } | 226 } |
| 137 | 227 |
| 138 // Decode the payload of a suffix command. Return the suffix length and | 228 // Decode the payload of a suffix command. Return the suffix length and |
| 139 // set the output parameter info_number to the index of the shared suffix. | 229 // set the output parameter info_number to the index of the shared suffix. |
| 140 static intptr_t DecodeSuffix(intptr_t from_index, intptr_t* info_number); | 230 static intptr_t DecodeSuffix(intptr_t from_index, intptr_t* info_number); |
| (...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 266 DeoptInfo* info, | 356 DeoptInfo* info, |
| 267 Smi* reason); | 357 Smi* reason); |
| 268 | 358 |
| 269 private: | 359 private: |
| 270 static const intptr_t kEntrySize = 3; | 360 static const intptr_t kEntrySize = 3; |
| 271 }; | 361 }; |
| 272 | 362 |
| 273 } // namespace dart | 363 } // namespace dart |
| 274 | 364 |
| 275 #endif // VM_DEOPT_INSTRUCTIONS_H_ | 365 #endif // VM_DEOPT_INSTRUCTIONS_H_ |
| OLD | NEW |