| 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 #include "vm/deopt_instructions.h" | 5 #include "vm/deopt_instructions.h" |
| 6 | 6 |
| 7 #include "vm/assembler.h" | 7 #include "vm/assembler.h" |
| 8 #include "vm/code_patcher.h" | 8 #include "vm/code_patcher.h" |
| 9 #include "vm/intermediate_language.h" | 9 #include "vm/intermediate_language.h" |
| 10 #include "vm/locations.h" | 10 #include "vm/locations.h" |
| 11 #include "vm/parser.h" | 11 #include "vm/parser.h" |
| 12 #include "vm/stack_frame.h" | 12 #include "vm/stack_frame.h" |
| 13 | 13 |
| 14 namespace dart { | 14 namespace dart { |
| 15 | 15 |
| 16 DEFINE_FLAG(bool, compress_deopt_info, true, | 16 DEFINE_FLAG(bool, compress_deopt_info, true, |
| 17 "Compress the size of the deoptimization info for optimized code."); | 17 "Compress the size of the deoptimization info for optimized code."); |
| 18 DECLARE_FLAG(bool, trace_deoptimization); | 18 DECLARE_FLAG(bool, trace_deoptimization); |
| 19 DECLARE_FLAG(bool, trace_deoptimization_verbose); | 19 DECLARE_FLAG(bool, trace_deoptimization_verbose); |
| 20 | 20 |
| 21 DeoptimizationContext::DeoptimizationContext(intptr_t* to_frame_start, | 21 DeoptContext::DeoptContext(const Array& object_table, |
| 22 intptr_t to_frame_size, | 22 intptr_t num_args, |
| 23 const Array& object_table, | 23 DeoptReasonId deopt_reason) |
| 24 intptr_t num_args, | 24 : object_table_(object_table.raw()), |
| 25 DeoptReasonId deopt_reason) | 25 to_frame_(NULL), |
| 26 : object_table_(object_table), | 26 to_frame_size_(0), |
| 27 to_frame_(to_frame_start), | |
| 28 to_frame_size_(to_frame_size), | |
| 29 from_frame_(NULL), | 27 from_frame_(NULL), |
| 30 from_frame_size_(0), | 28 from_frame_size_(0), |
| 31 registers_copy_(NULL), | 29 cpu_registers_(NULL), |
| 32 fpu_registers_copy_(NULL), | 30 fpu_registers_(NULL), |
| 33 num_args_(num_args), | 31 num_args_(num_args), |
| 34 deopt_reason_(deopt_reason), | 32 deopt_reason_(deopt_reason), |
| 35 isolate_(Isolate::Current()) { | 33 isolate_(Isolate::Current()), |
| 36 from_frame_ = isolate_->deopt_frame_copy(); | 34 deferred_boxes_(NULL), |
| 37 from_frame_size_ = isolate_->deopt_frame_copy_size(); | 35 deferred_object_refs_(NULL), |
| 38 registers_copy_ = isolate_->deopt_cpu_registers_copy(); | 36 deferred_objects_count_(0), |
| 39 fpu_registers_copy_ = isolate_->deopt_fpu_registers_copy(); | 37 deferred_objects_(NULL) { |
| 40 // The deoptimized frame is filled starting just below the sp of its caller | 38 } |
| 41 // down to kDartFrameFixedSize words below its own sp. | 39 |
| 42 // The chain of frame pointers is recreated from the fp of the caller. | 40 |
| 41 DeoptContext::~DeoptContext() { |
| 42 // Delete all deferred objects. |
| 43 for (intptr_t i = 0; i < deferred_objects_count_; i++) { |
| 44 delete deferred_objects_[i]; |
| 45 } |
| 46 delete[] deferred_objects_; |
| 47 deferred_objects_ = NULL; |
| 48 deferred_objects_count_ = 0; |
| 49 } |
| 50 |
| 51 |
| 52 void DeoptContext::SetToFrame(intptr_t* start, |
| 53 intptr_t size) { |
| 54 ASSERT(start != NULL); |
| 55 ASSERT(size >= 0); |
| 56 ASSERT(to_frame_ == NULL); |
| 57 to_frame_ = start; |
| 58 to_frame_size_ = size; |
| 59 } |
| 60 |
| 61 |
| 62 void DeoptContext::SetFromFrame(intptr_t* start, |
| 63 intptr_t size) { |
| 64 ASSERT(start != NULL); |
| 65 ASSERT(size >= 0); |
| 66 ASSERT(from_frame_ == NULL); |
| 67 from_frame_ = start; |
| 68 from_frame_size_ = size; |
| 43 caller_fp_ = GetFromFp(); | 69 caller_fp_ = GetFromFp(); |
| 44 } | 70 } |
| 45 | 71 |
| 46 | 72 |
| 47 intptr_t DeoptimizationContext::GetFromFp() const { | 73 void DeoptContext::SetSavedRegisters(fpu_register_t* fpu_registers, |
| 74 intptr_t* cpu_registers) { |
| 75 ASSERT(cpu_registers_ == NULL && fpu_registers_ == NULL); |
| 76 cpu_registers_ = cpu_registers; |
| 77 fpu_registers_ = fpu_registers; |
| 78 } |
| 79 |
| 80 |
| 81 void DeoptContext::VisitObjectPointers(ObjectPointerVisitor* visitor) { |
| 82 visitor->VisitPointer(reinterpret_cast<RawObject**>(&object_table_)); |
| 83 } |
| 84 |
| 85 |
| 86 intptr_t DeoptContext::GetFromFp() const { |
| 48 return from_frame_[from_frame_size_ - 1 - num_args_ - kParamEndSlotFromFp]; | 87 return from_frame_[from_frame_size_ - 1 - num_args_ - kParamEndSlotFromFp]; |
| 49 } | 88 } |
| 50 | 89 |
| 51 | 90 |
| 52 intptr_t DeoptimizationContext::GetFromPp() const { | 91 intptr_t DeoptContext::GetFromPp() const { |
| 53 return from_frame_[from_frame_size_ - 1 - num_args_ - kParamEndSlotFromFp + | 92 return from_frame_[from_frame_size_ - 1 - num_args_ - kParamEndSlotFromFp + |
| 54 StackFrame::SavedCallerPpSlotFromFp()]; | 93 StackFrame::SavedCallerPpSlotFromFp()]; |
| 55 } | 94 } |
| 56 | 95 |
| 57 | 96 |
| 58 intptr_t DeoptimizationContext::GetFromPc() const { | 97 intptr_t DeoptContext::GetFromPc() const { |
| 59 return from_frame_[from_frame_size_ - num_args_ + kSavedPcSlotFromSp]; | 98 return from_frame_[from_frame_size_ - num_args_ + kSavedPcSlotFromSp]; |
| 60 } | 99 } |
| 61 | 100 |
| 62 | 101 |
| 63 intptr_t DeoptimizationContext::GetCallerFp() const { | 102 intptr_t DeoptContext::GetCallerFp() const { |
| 64 return caller_fp_; | 103 return caller_fp_; |
| 65 } | 104 } |
| 66 | 105 |
| 67 | 106 |
| 68 void DeoptimizationContext::SetCallerFp(intptr_t caller_fp) { | 107 void DeoptContext::SetCallerFp(intptr_t caller_fp) { |
| 69 caller_fp_ = caller_fp; | 108 caller_fp_ = caller_fp; |
| 70 } | 109 } |
| 71 | 110 |
| 72 | 111 |
| 112 static void FillDeferredSlots(DeferredSlot** slot_list) { |
| 113 DeferredSlot* slot = *slot_list; |
| 114 *slot_list = NULL; |
| 115 |
| 116 while (slot != NULL) { |
| 117 DeferredSlot* current = slot; |
| 118 slot = slot->next(); |
| 119 |
| 120 current->Materialize(); |
| 121 |
| 122 delete current; |
| 123 } |
| 124 } |
| 125 |
| 126 |
| 127 // Materializes all deferred objects. Returns the total number of |
| 128 // artificial arguments used during deoptimization. |
| 129 intptr_t DeoptContext::MaterializeDeferredObjects() { |
| 130 // First materialize all unboxed "primitive" values (doubles, mints, simd) |
| 131 // then materialize objects. The order is important: objects might be |
| 132 // referencing boxes allocated on the first step. At the same time |
| 133 // objects can't be referencing other deferred objects because storing |
| 134 // an object into a field is always conservatively treated as escaping by |
| 135 // allocation sinking and load forwarding. |
| 136 FillDeferredSlots(&deferred_boxes_); |
| 137 FillDeferredSlots(&deferred_object_refs_); |
| 138 |
| 139 // Compute total number of artificial arguments used during deoptimization. |
| 140 intptr_t deopt_arguments = 0; |
| 141 for (intptr_t i = 0; i < DeferredObjectsCount(); i++) { |
| 142 deopt_arguments += GetDeferredObject(i)->ArgumentCount(); |
| 143 } |
| 144 return deopt_arguments; |
| 145 } |
| 146 |
| 147 |
| 73 // Deoptimization instruction moving value from optimized frame at | 148 // Deoptimization instruction moving value from optimized frame at |
| 74 // 'from_index' to specified slots in the unoptimized frame. | 149 // 'from_index' to specified slots in the unoptimized frame. |
| 75 // 'from_index' represents the slot index of the frame (0 being first argument) | 150 // 'from_index' represents the slot index of the frame (0 being first argument) |
| 76 // and accounts for saved return address, frame pointer, pool pointer and pc | 151 // and accounts for saved return address, frame pointer, pool pointer and pc |
| 77 // marker. | 152 // marker. |
| 78 class DeoptStackSlotInstr : public DeoptInstr { | 153 class DeoptStackSlotInstr : public DeoptInstr { |
| 79 public: | 154 public: |
| 80 explicit DeoptStackSlotInstr(intptr_t from_index) | 155 explicit DeoptStackSlotInstr(intptr_t from_index) |
| 81 : stack_slot_index_(from_index) { | 156 : stack_slot_index_(from_index) { |
| 82 ASSERT(stack_slot_index_ >= 0); | 157 ASSERT(stack_slot_index_ >= 0); |
| 83 } | 158 } |
| 84 | 159 |
| 85 virtual intptr_t from_index() const { return stack_slot_index_; } | 160 virtual intptr_t from_index() const { return stack_slot_index_; } |
| 86 virtual DeoptInstr::Kind kind() const { return kStackSlot; } | 161 virtual DeoptInstr::Kind kind() const { return kStackSlot; } |
| 87 | 162 |
| 88 virtual const char* ToCString() const { | 163 virtual const char* ToCString() const { |
| 89 return Isolate::Current()->current_zone()->PrintToString( | 164 return Isolate::Current()->current_zone()->PrintToString( |
| 90 "s%" Pd "", stack_slot_index_); | 165 "s%" Pd "", stack_slot_index_); |
| 91 } | 166 } |
| 92 | 167 |
| 93 void Execute(DeoptimizationContext* deopt_context, intptr_t* to_addr) { | 168 void Execute(DeoptContext* deopt_context, intptr_t* to_addr) { |
| 94 intptr_t from_index = | 169 intptr_t from_index = |
| 95 deopt_context->from_frame_size() - stack_slot_index_ - 1; | 170 deopt_context->from_frame_size() - stack_slot_index_ - 1; |
| 96 intptr_t* from_addr = deopt_context->GetFromFrameAddressAt(from_index); | 171 intptr_t* from_addr = deopt_context->GetFromFrameAddressAt(from_index); |
| 97 *to_addr = *from_addr; | 172 *to_addr = *from_addr; |
| 98 } | 173 } |
| 99 | 174 |
| 100 private: | 175 private: |
| 101 const intptr_t stack_slot_index_; // First argument is 0, always >= 0. | 176 const intptr_t stack_slot_index_; // First argument is 0, always >= 0. |
| 102 | 177 |
| 103 DISALLOW_COPY_AND_ASSIGN(DeoptStackSlotInstr); | 178 DISALLOW_COPY_AND_ASSIGN(DeoptStackSlotInstr); |
| 104 }; | 179 }; |
| 105 | 180 |
| 106 | 181 |
| 107 class DeoptDoubleStackSlotInstr : public DeoptInstr { | 182 class DeoptDoubleStackSlotInstr : public DeoptInstr { |
| 108 public: | 183 public: |
| 109 explicit DeoptDoubleStackSlotInstr(intptr_t from_index) | 184 explicit DeoptDoubleStackSlotInstr(intptr_t from_index) |
| 110 : stack_slot_index_(from_index) { | 185 : stack_slot_index_(from_index) { |
| 111 ASSERT(stack_slot_index_ >= 0); | 186 ASSERT(stack_slot_index_ >= 0); |
| 112 } | 187 } |
| 113 | 188 |
| 114 virtual intptr_t from_index() const { return stack_slot_index_; } | 189 virtual intptr_t from_index() const { return stack_slot_index_; } |
| 115 virtual DeoptInstr::Kind kind() const { return kDoubleStackSlot; } | 190 virtual DeoptInstr::Kind kind() const { return kDoubleStackSlot; } |
| 116 | 191 |
| 117 virtual const char* ToCString() const { | 192 virtual const char* ToCString() const { |
| 118 return Isolate::Current()->current_zone()->PrintToString( | 193 return Isolate::Current()->current_zone()->PrintToString( |
| 119 "ds%" Pd "", stack_slot_index_); | 194 "ds%" Pd "", stack_slot_index_); |
| 120 } | 195 } |
| 121 | 196 |
| 122 void Execute(DeoptimizationContext* deopt_context, intptr_t* to_addr) { | 197 void Execute(DeoptContext* deopt_context, intptr_t* to_addr) { |
| 123 intptr_t from_index = | 198 intptr_t from_index = |
| 124 deopt_context->from_frame_size() - stack_slot_index_ - 1; | 199 deopt_context->from_frame_size() - stack_slot_index_ - 1; |
| 125 double* from_addr = reinterpret_cast<double*>( | 200 double* from_addr = reinterpret_cast<double*>( |
| 126 deopt_context->GetFromFrameAddressAt(from_index)); | 201 deopt_context->GetFromFrameAddressAt(from_index)); |
| 127 *reinterpret_cast<RawSmi**>(to_addr) = Smi::New(0); | 202 *reinterpret_cast<RawSmi**>(to_addr) = Smi::New(0); |
| 128 Isolate::Current()->DeferDoubleMaterialization( | 203 deopt_context->DeferDoubleMaterialization( |
| 129 *from_addr, reinterpret_cast<RawDouble**>(to_addr)); | 204 *from_addr, reinterpret_cast<RawDouble**>(to_addr)); |
| 130 } | 205 } |
| 131 | 206 |
| 132 private: | 207 private: |
| 133 const intptr_t stack_slot_index_; // First argument is 0, always >= 0. | 208 const intptr_t stack_slot_index_; // First argument is 0, always >= 0. |
| 134 | 209 |
| 135 DISALLOW_COPY_AND_ASSIGN(DeoptDoubleStackSlotInstr); | 210 DISALLOW_COPY_AND_ASSIGN(DeoptDoubleStackSlotInstr); |
| 136 }; | 211 }; |
| 137 | 212 |
| 138 | 213 |
| 139 class DeoptInt64StackSlotInstr : public DeoptInstr { | 214 class DeoptInt64StackSlotInstr : public DeoptInstr { |
| 140 public: | 215 public: |
| 141 explicit DeoptInt64StackSlotInstr(intptr_t from_index) | 216 explicit DeoptInt64StackSlotInstr(intptr_t from_index) |
| 142 : stack_slot_index_(from_index) { | 217 : stack_slot_index_(from_index) { |
| 143 ASSERT(stack_slot_index_ >= 0); | 218 ASSERT(stack_slot_index_ >= 0); |
| 144 } | 219 } |
| 145 | 220 |
| 146 virtual intptr_t from_index() const { return stack_slot_index_; } | 221 virtual intptr_t from_index() const { return stack_slot_index_; } |
| 147 virtual DeoptInstr::Kind kind() const { return kInt64StackSlot; } | 222 virtual DeoptInstr::Kind kind() const { return kInt64StackSlot; } |
| 148 | 223 |
| 149 virtual const char* ToCString() const { | 224 virtual const char* ToCString() const { |
| 150 return Isolate::Current()->current_zone()->PrintToString( | 225 return Isolate::Current()->current_zone()->PrintToString( |
| 151 "ms%" Pd "", stack_slot_index_); | 226 "ms%" Pd "", stack_slot_index_); |
| 152 } | 227 } |
| 153 | 228 |
| 154 void Execute(DeoptimizationContext* deopt_context, intptr_t* to_addr) { | 229 void Execute(DeoptContext* deopt_context, intptr_t* to_addr) { |
| 155 intptr_t from_index = | 230 intptr_t from_index = |
| 156 deopt_context->from_frame_size() - stack_slot_index_ - 1; | 231 deopt_context->from_frame_size() - stack_slot_index_ - 1; |
| 157 int64_t* from_addr = reinterpret_cast<int64_t*>( | 232 int64_t* from_addr = reinterpret_cast<int64_t*>( |
| 158 deopt_context->GetFromFrameAddressAt(from_index)); | 233 deopt_context->GetFromFrameAddressAt(from_index)); |
| 159 *reinterpret_cast<RawSmi**>(to_addr) = Smi::New(0); | 234 *reinterpret_cast<RawSmi**>(to_addr) = Smi::New(0); |
| 160 if (Smi::IsValid64(*from_addr)) { | 235 if (Smi::IsValid64(*from_addr)) { |
| 161 *to_addr = reinterpret_cast<intptr_t>( | 236 *to_addr = reinterpret_cast<intptr_t>( |
| 162 Smi::New(static_cast<intptr_t>(*from_addr))); | 237 Smi::New(static_cast<intptr_t>(*from_addr))); |
| 163 } else { | 238 } else { |
| 164 Isolate::Current()->DeferMintMaterialization( | 239 deopt_context->DeferMintMaterialization( |
| 165 *from_addr, reinterpret_cast<RawMint**>(to_addr)); | 240 *from_addr, reinterpret_cast<RawMint**>(to_addr)); |
| 166 } | 241 } |
| 167 } | 242 } |
| 168 | 243 |
| 169 private: | 244 private: |
| 170 const intptr_t stack_slot_index_; // First argument is 0, always >= 0. | 245 const intptr_t stack_slot_index_; // First argument is 0, always >= 0. |
| 171 | 246 |
| 172 DISALLOW_COPY_AND_ASSIGN(DeoptInt64StackSlotInstr); | 247 DISALLOW_COPY_AND_ASSIGN(DeoptInt64StackSlotInstr); |
| 173 }; | 248 }; |
| 174 | 249 |
| 175 | 250 |
| 176 class DeoptFloat32x4StackSlotInstr : public DeoptInstr { | 251 class DeoptFloat32x4StackSlotInstr : public DeoptInstr { |
| 177 public: | 252 public: |
| 178 explicit DeoptFloat32x4StackSlotInstr(intptr_t from_index) | 253 explicit DeoptFloat32x4StackSlotInstr(intptr_t from_index) |
| 179 : stack_slot_index_(from_index) { | 254 : stack_slot_index_(from_index) { |
| 180 ASSERT(stack_slot_index_ >= 0); | 255 ASSERT(stack_slot_index_ >= 0); |
| 181 } | 256 } |
| 182 | 257 |
| 183 virtual intptr_t from_index() const { return stack_slot_index_; } | 258 virtual intptr_t from_index() const { return stack_slot_index_; } |
| 184 virtual DeoptInstr::Kind kind() const { return kFloat32x4StackSlot; } | 259 virtual DeoptInstr::Kind kind() const { return kFloat32x4StackSlot; } |
| 185 | 260 |
| 186 virtual const char* ToCString() const { | 261 virtual const char* ToCString() const { |
| 187 return Isolate::Current()->current_zone()->PrintToString( | 262 return Isolate::Current()->current_zone()->PrintToString( |
| 188 "f32x4s%" Pd "", stack_slot_index_); | 263 "f32x4s%" Pd "", stack_slot_index_); |
| 189 } | 264 } |
| 190 | 265 |
| 191 void Execute(DeoptimizationContext* deopt_context, intptr_t* to_addr) { | 266 void Execute(DeoptContext* deopt_context, intptr_t* to_addr) { |
| 192 intptr_t from_index = | 267 intptr_t from_index = |
| 193 deopt_context->from_frame_size() - stack_slot_index_ - 1; | 268 deopt_context->from_frame_size() - stack_slot_index_ - 1; |
| 194 simd128_value_t* from_addr = reinterpret_cast<simd128_value_t*>( | 269 simd128_value_t* from_addr = reinterpret_cast<simd128_value_t*>( |
| 195 deopt_context->GetFromFrameAddressAt(from_index)); | 270 deopt_context->GetFromFrameAddressAt(from_index)); |
| 196 *reinterpret_cast<RawSmi**>(to_addr) = Smi::New(0); | 271 *reinterpret_cast<RawSmi**>(to_addr) = Smi::New(0); |
| 197 Isolate::Current()->DeferFloat32x4Materialization( | 272 deopt_context->DeferFloat32x4Materialization( |
| 198 *from_addr, reinterpret_cast<RawFloat32x4**>(to_addr)); | 273 *from_addr, reinterpret_cast<RawFloat32x4**>(to_addr)); |
| 199 } | 274 } |
| 200 | 275 |
| 201 private: | 276 private: |
| 202 const intptr_t stack_slot_index_; // First argument is 0, always >= 0. | 277 const intptr_t stack_slot_index_; // First argument is 0, always >= 0. |
| 203 | 278 |
| 204 DISALLOW_COPY_AND_ASSIGN(DeoptFloat32x4StackSlotInstr); | 279 DISALLOW_COPY_AND_ASSIGN(DeoptFloat32x4StackSlotInstr); |
| 205 }; | 280 }; |
| 206 | 281 |
| 207 | 282 |
| 208 class DeoptUint32x4StackSlotInstr : public DeoptInstr { | 283 class DeoptUint32x4StackSlotInstr : public DeoptInstr { |
| 209 public: | 284 public: |
| 210 explicit DeoptUint32x4StackSlotInstr(intptr_t from_index) | 285 explicit DeoptUint32x4StackSlotInstr(intptr_t from_index) |
| 211 : stack_slot_index_(from_index) { | 286 : stack_slot_index_(from_index) { |
| 212 ASSERT(stack_slot_index_ >= 0); | 287 ASSERT(stack_slot_index_ >= 0); |
| 213 } | 288 } |
| 214 | 289 |
| 215 virtual intptr_t from_index() const { return stack_slot_index_; } | 290 virtual intptr_t from_index() const { return stack_slot_index_; } |
| 216 virtual DeoptInstr::Kind kind() const { return kUint32x4StackSlot; } | 291 virtual DeoptInstr::Kind kind() const { return kUint32x4StackSlot; } |
| 217 | 292 |
| 218 virtual const char* ToCString() const { | 293 virtual const char* ToCString() const { |
| 219 return Isolate::Current()->current_zone()->PrintToString( | 294 return Isolate::Current()->current_zone()->PrintToString( |
| 220 "ui32x4s%" Pd "", stack_slot_index_); | 295 "ui32x4s%" Pd "", stack_slot_index_); |
| 221 } | 296 } |
| 222 | 297 |
| 223 void Execute(DeoptimizationContext* deopt_context, intptr_t* to_addr) { | 298 void Execute(DeoptContext* deopt_context, intptr_t* to_addr) { |
| 224 intptr_t from_index = | 299 intptr_t from_index = |
| 225 deopt_context->from_frame_size() - stack_slot_index_ - 1; | 300 deopt_context->from_frame_size() - stack_slot_index_ - 1; |
| 226 simd128_value_t* from_addr = reinterpret_cast<simd128_value_t*>( | 301 simd128_value_t* from_addr = reinterpret_cast<simd128_value_t*>( |
| 227 deopt_context->GetFromFrameAddressAt(from_index)); | 302 deopt_context->GetFromFrameAddressAt(from_index)); |
| 228 *reinterpret_cast<RawSmi**>(to_addr) = Smi::New(0); | 303 *reinterpret_cast<RawSmi**>(to_addr) = Smi::New(0); |
| 229 Isolate::Current()->DeferUint32x4Materialization( | 304 deopt_context->DeferUint32x4Materialization( |
| 230 *from_addr, reinterpret_cast<RawUint32x4**>(to_addr)); | 305 *from_addr, reinterpret_cast<RawUint32x4**>(to_addr)); |
| 231 } | 306 } |
| 232 | 307 |
| 233 private: | 308 private: |
| 234 const intptr_t stack_slot_index_; // First argument is 0, always >= 0. | 309 const intptr_t stack_slot_index_; // First argument is 0, always >= 0. |
| 235 | 310 |
| 236 DISALLOW_COPY_AND_ASSIGN(DeoptUint32x4StackSlotInstr); | 311 DISALLOW_COPY_AND_ASSIGN(DeoptUint32x4StackSlotInstr); |
| 237 }; | 312 }; |
| 238 | 313 |
| 239 | 314 |
| (...skipping 17 matching lines...) Expand all Loading... |
| 257 DeoptId::encode(deopt_id_); | 332 DeoptId::encode(deopt_id_); |
| 258 } | 333 } |
| 259 | 334 |
| 260 virtual DeoptInstr::Kind kind() const { return kRetAddress; } | 335 virtual DeoptInstr::Kind kind() const { return kRetAddress; } |
| 261 | 336 |
| 262 virtual const char* ToCString() const { | 337 virtual const char* ToCString() const { |
| 263 return Isolate::Current()->current_zone()->PrintToString( | 338 return Isolate::Current()->current_zone()->PrintToString( |
| 264 "ret oti:%" Pd "(%" Pd ")", object_table_index_, deopt_id_); | 339 "ret oti:%" Pd "(%" Pd ")", object_table_index_, deopt_id_); |
| 265 } | 340 } |
| 266 | 341 |
| 267 void Execute(DeoptimizationContext* deopt_context, intptr_t* to_addr) { | 342 void Execute(DeoptContext* deopt_context, intptr_t* to_addr) { |
| 268 Function& function = Function::Handle(deopt_context->isolate()); | 343 Function& function = Function::Handle(deopt_context->isolate()); |
| 269 function ^= deopt_context->ObjectAt(object_table_index_); | 344 function ^= deopt_context->ObjectAt(object_table_index_); |
| 270 const Code& code = | 345 const Code& code = |
| 271 Code::Handle(deopt_context->isolate(), function.unoptimized_code()); | 346 Code::Handle(deopt_context->isolate(), function.unoptimized_code()); |
| 272 ASSERT(!code.IsNull()); | 347 ASSERT(!code.IsNull()); |
| 273 uword continue_at_pc = code.GetPcForDeoptId(deopt_id_, | 348 uword continue_at_pc = code.GetPcForDeoptId(deopt_id_, |
| 274 PcDescriptors::kDeopt); | 349 PcDescriptors::kDeopt); |
| 275 ASSERT(continue_at_pc != 0); | 350 ASSERT(continue_at_pc != 0); |
| 276 *to_addr = continue_at_pc; | 351 *to_addr = continue_at_pc; |
| 277 | 352 |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 311 } | 386 } |
| 312 | 387 |
| 313 virtual intptr_t from_index() const { return object_table_index_; } | 388 virtual intptr_t from_index() const { return object_table_index_; } |
| 314 virtual DeoptInstr::Kind kind() const { return kConstant; } | 389 virtual DeoptInstr::Kind kind() const { return kConstant; } |
| 315 | 390 |
| 316 virtual const char* ToCString() const { | 391 virtual const char* ToCString() const { |
| 317 return Isolate::Current()->current_zone()->PrintToString( | 392 return Isolate::Current()->current_zone()->PrintToString( |
| 318 "const oti:%" Pd "", object_table_index_); | 393 "const oti:%" Pd "", object_table_index_); |
| 319 } | 394 } |
| 320 | 395 |
| 321 void Execute(DeoptimizationContext* deopt_context, intptr_t* to_addr) { | 396 void Execute(DeoptContext* deopt_context, intptr_t* to_addr) { |
| 322 const Object& obj = Object::Handle( | 397 const Object& obj = Object::Handle( |
| 323 deopt_context->isolate(), deopt_context->ObjectAt(object_table_index_)); | 398 deopt_context->isolate(), deopt_context->ObjectAt(object_table_index_)); |
| 324 *reinterpret_cast<RawObject**>(to_addr) = obj.raw(); | 399 *reinterpret_cast<RawObject**>(to_addr) = obj.raw(); |
| 325 } | 400 } |
| 326 | 401 |
| 327 private: | 402 private: |
| 328 const intptr_t object_table_index_; | 403 const intptr_t object_table_index_; |
| 329 | 404 |
| 330 DISALLOW_COPY_AND_ASSIGN(DeoptConstantInstr); | 405 DISALLOW_COPY_AND_ASSIGN(DeoptConstantInstr); |
| 331 }; | 406 }; |
| 332 | 407 |
| 333 | 408 |
| 334 // Deoptimization instruction moving a CPU register. | 409 // Deoptimization instruction moving a CPU register. |
| 335 class DeoptRegisterInstr: public DeoptInstr { | 410 class DeoptRegisterInstr: public DeoptInstr { |
| 336 public: | 411 public: |
| 337 explicit DeoptRegisterInstr(intptr_t reg_as_int) | 412 explicit DeoptRegisterInstr(intptr_t reg_as_int) |
| 338 : reg_(static_cast<Register>(reg_as_int)) {} | 413 : reg_(static_cast<Register>(reg_as_int)) {} |
| 339 | 414 |
| 340 virtual intptr_t from_index() const { return static_cast<intptr_t>(reg_); } | 415 virtual intptr_t from_index() const { return static_cast<intptr_t>(reg_); } |
| 341 virtual DeoptInstr::Kind kind() const { return kRegister; } | 416 virtual DeoptInstr::Kind kind() const { return kRegister; } |
| 342 | 417 |
| 343 virtual const char* ToCString() const { | 418 virtual const char* ToCString() const { |
| 344 return Assembler::RegisterName(reg_); | 419 return Assembler::RegisterName(reg_); |
| 345 } | 420 } |
| 346 | 421 |
| 347 void Execute(DeoptimizationContext* deopt_context, intptr_t* to_addr) { | 422 void Execute(DeoptContext* deopt_context, intptr_t* to_addr) { |
| 348 *to_addr = deopt_context->RegisterValue(reg_); | 423 *to_addr = deopt_context->RegisterValue(reg_); |
| 349 } | 424 } |
| 350 | 425 |
| 351 private: | 426 private: |
| 352 const Register reg_; | 427 const Register reg_; |
| 353 | 428 |
| 354 DISALLOW_COPY_AND_ASSIGN(DeoptRegisterInstr); | 429 DISALLOW_COPY_AND_ASSIGN(DeoptRegisterInstr); |
| 355 }; | 430 }; |
| 356 | 431 |
| 357 | 432 |
| 358 // Deoptimization instruction moving an XMM register. | 433 // Deoptimization instruction moving an XMM register. |
| 359 class DeoptFpuRegisterInstr: public DeoptInstr { | 434 class DeoptFpuRegisterInstr: public DeoptInstr { |
| 360 public: | 435 public: |
| 361 explicit DeoptFpuRegisterInstr(intptr_t reg_as_int) | 436 explicit DeoptFpuRegisterInstr(intptr_t reg_as_int) |
| 362 : reg_(static_cast<FpuRegister>(reg_as_int)) {} | 437 : reg_(static_cast<FpuRegister>(reg_as_int)) {} |
| 363 | 438 |
| 364 virtual intptr_t from_index() const { return static_cast<intptr_t>(reg_); } | 439 virtual intptr_t from_index() const { return static_cast<intptr_t>(reg_); } |
| 365 virtual DeoptInstr::Kind kind() const { return kFpuRegister; } | 440 virtual DeoptInstr::Kind kind() const { return kFpuRegister; } |
| 366 | 441 |
| 367 virtual const char* ToCString() const { | 442 virtual const char* ToCString() const { |
| 368 return Assembler::FpuRegisterName(reg_); | 443 return Assembler::FpuRegisterName(reg_); |
| 369 } | 444 } |
| 370 | 445 |
| 371 void Execute(DeoptimizationContext* deopt_context, intptr_t* to_addr) { | 446 void Execute(DeoptContext* deopt_context, intptr_t* to_addr) { |
| 372 double value = deopt_context->FpuRegisterValue(reg_); | 447 double value = deopt_context->FpuRegisterValue(reg_); |
| 373 *reinterpret_cast<RawSmi**>(to_addr) = Smi::New(0); | 448 *reinterpret_cast<RawSmi**>(to_addr) = Smi::New(0); |
| 374 Isolate::Current()->DeferDoubleMaterialization( | 449 deopt_context->DeferDoubleMaterialization( |
| 375 value, reinterpret_cast<RawDouble**>(to_addr)); | 450 value, reinterpret_cast<RawDouble**>(to_addr)); |
| 376 } | 451 } |
| 377 | 452 |
| 378 private: | 453 private: |
| 379 const FpuRegister reg_; | 454 const FpuRegister reg_; |
| 380 | 455 |
| 381 DISALLOW_COPY_AND_ASSIGN(DeoptFpuRegisterInstr); | 456 DISALLOW_COPY_AND_ASSIGN(DeoptFpuRegisterInstr); |
| 382 }; | 457 }; |
| 383 | 458 |
| 384 | 459 |
| 385 class DeoptInt64FpuRegisterInstr: public DeoptInstr { | 460 class DeoptInt64FpuRegisterInstr: public DeoptInstr { |
| 386 public: | 461 public: |
| 387 explicit DeoptInt64FpuRegisterInstr(intptr_t reg_as_int) | 462 explicit DeoptInt64FpuRegisterInstr(intptr_t reg_as_int) |
| 388 : reg_(static_cast<FpuRegister>(reg_as_int)) {} | 463 : reg_(static_cast<FpuRegister>(reg_as_int)) {} |
| 389 | 464 |
| 390 virtual intptr_t from_index() const { return static_cast<intptr_t>(reg_); } | 465 virtual intptr_t from_index() const { return static_cast<intptr_t>(reg_); } |
| 391 virtual DeoptInstr::Kind kind() const { return kInt64FpuRegister; } | 466 virtual DeoptInstr::Kind kind() const { return kInt64FpuRegister; } |
| 392 | 467 |
| 393 virtual const char* ToCString() const { | 468 virtual const char* ToCString() const { |
| 394 return Isolate::Current()->current_zone()->PrintToString( | 469 return Isolate::Current()->current_zone()->PrintToString( |
| 395 "%s(m)", Assembler::FpuRegisterName(reg_)); | 470 "%s(m)", Assembler::FpuRegisterName(reg_)); |
| 396 } | 471 } |
| 397 | 472 |
| 398 void Execute(DeoptimizationContext* deopt_context, intptr_t* to_addr) { | 473 void Execute(DeoptContext* deopt_context, intptr_t* to_addr) { |
| 399 int64_t value = deopt_context->FpuRegisterValueAsInt64(reg_); | 474 int64_t value = deopt_context->FpuRegisterValueAsInt64(reg_); |
| 400 *reinterpret_cast<RawSmi**>(to_addr) = Smi::New(0); | 475 *reinterpret_cast<RawSmi**>(to_addr) = Smi::New(0); |
| 401 if (Smi::IsValid64(value)) { | 476 if (Smi::IsValid64(value)) { |
| 402 *to_addr = reinterpret_cast<intptr_t>( | 477 *to_addr = reinterpret_cast<intptr_t>( |
| 403 Smi::New(static_cast<intptr_t>(value))); | 478 Smi::New(static_cast<intptr_t>(value))); |
| 404 } else { | 479 } else { |
| 405 Isolate::Current()->DeferMintMaterialization( | 480 deopt_context->DeferMintMaterialization( |
| 406 value, reinterpret_cast<RawMint**>(to_addr)); | 481 value, reinterpret_cast<RawMint**>(to_addr)); |
| 407 } | 482 } |
| 408 } | 483 } |
| 409 | 484 |
| 410 private: | 485 private: |
| 411 const FpuRegister reg_; | 486 const FpuRegister reg_; |
| 412 | 487 |
| 413 DISALLOW_COPY_AND_ASSIGN(DeoptInt64FpuRegisterInstr); | 488 DISALLOW_COPY_AND_ASSIGN(DeoptInt64FpuRegisterInstr); |
| 414 }; | 489 }; |
| 415 | 490 |
| 416 | 491 |
| 417 // Deoptimization instruction moving an XMM register. | 492 // Deoptimization instruction moving an XMM register. |
| 418 class DeoptFloat32x4FpuRegisterInstr: public DeoptInstr { | 493 class DeoptFloat32x4FpuRegisterInstr: public DeoptInstr { |
| 419 public: | 494 public: |
| 420 explicit DeoptFloat32x4FpuRegisterInstr(intptr_t reg_as_int) | 495 explicit DeoptFloat32x4FpuRegisterInstr(intptr_t reg_as_int) |
| 421 : reg_(static_cast<FpuRegister>(reg_as_int)) {} | 496 : reg_(static_cast<FpuRegister>(reg_as_int)) {} |
| 422 | 497 |
| 423 virtual intptr_t from_index() const { return static_cast<intptr_t>(reg_); } | 498 virtual intptr_t from_index() const { return static_cast<intptr_t>(reg_); } |
| 424 virtual DeoptInstr::Kind kind() const { return kFloat32x4FpuRegister; } | 499 virtual DeoptInstr::Kind kind() const { return kFloat32x4FpuRegister; } |
| 425 | 500 |
| 426 virtual const char* ToCString() const { | 501 virtual const char* ToCString() const { |
| 427 return Isolate::Current()->current_zone()->PrintToString( | 502 return Isolate::Current()->current_zone()->PrintToString( |
| 428 "%s(f32x4)", Assembler::FpuRegisterName(reg_)); | 503 "%s(f32x4)", Assembler::FpuRegisterName(reg_)); |
| 429 } | 504 } |
| 430 | 505 |
| 431 void Execute(DeoptimizationContext* deopt_context, intptr_t* to_addr) { | 506 void Execute(DeoptContext* deopt_context, intptr_t* to_addr) { |
| 432 simd128_value_t value = deopt_context->FpuRegisterValueAsSimd128(reg_); | 507 simd128_value_t value = deopt_context->FpuRegisterValueAsSimd128(reg_); |
| 433 *reinterpret_cast<RawSmi**>(to_addr) = Smi::New(0); | 508 *reinterpret_cast<RawSmi**>(to_addr) = Smi::New(0); |
| 434 Isolate::Current()->DeferFloat32x4Materialization( | 509 deopt_context->DeferFloat32x4Materialization( |
| 435 value, reinterpret_cast<RawFloat32x4**>(to_addr)); | 510 value, reinterpret_cast<RawFloat32x4**>(to_addr)); |
| 436 } | 511 } |
| 437 | 512 |
| 438 private: | 513 private: |
| 439 const FpuRegister reg_; | 514 const FpuRegister reg_; |
| 440 | 515 |
| 441 DISALLOW_COPY_AND_ASSIGN(DeoptFloat32x4FpuRegisterInstr); | 516 DISALLOW_COPY_AND_ASSIGN(DeoptFloat32x4FpuRegisterInstr); |
| 442 }; | 517 }; |
| 443 | 518 |
| 444 | 519 |
| 445 // Deoptimization instruction moving an XMM register. | 520 // Deoptimization instruction moving an XMM register. |
| 446 class DeoptUint32x4FpuRegisterInstr: public DeoptInstr { | 521 class DeoptUint32x4FpuRegisterInstr: public DeoptInstr { |
| 447 public: | 522 public: |
| 448 explicit DeoptUint32x4FpuRegisterInstr(intptr_t reg_as_int) | 523 explicit DeoptUint32x4FpuRegisterInstr(intptr_t reg_as_int) |
| 449 : reg_(static_cast<FpuRegister>(reg_as_int)) {} | 524 : reg_(static_cast<FpuRegister>(reg_as_int)) {} |
| 450 | 525 |
| 451 virtual intptr_t from_index() const { return static_cast<intptr_t>(reg_); } | 526 virtual intptr_t from_index() const { return static_cast<intptr_t>(reg_); } |
| 452 virtual DeoptInstr::Kind kind() const { return kUint32x4FpuRegister; } | 527 virtual DeoptInstr::Kind kind() const { return kUint32x4FpuRegister; } |
| 453 | 528 |
| 454 virtual const char* ToCString() const { | 529 virtual const char* ToCString() const { |
| 455 return Isolate::Current()->current_zone()->PrintToString( | 530 return Isolate::Current()->current_zone()->PrintToString( |
| 456 "%s(f32x4)", Assembler::FpuRegisterName(reg_)); | 531 "%s(f32x4)", Assembler::FpuRegisterName(reg_)); |
| 457 } | 532 } |
| 458 | 533 |
| 459 void Execute(DeoptimizationContext* deopt_context, intptr_t* to_addr) { | 534 void Execute(DeoptContext* deopt_context, intptr_t* to_addr) { |
| 460 simd128_value_t value = deopt_context->FpuRegisterValueAsSimd128(reg_); | 535 simd128_value_t value = deopt_context->FpuRegisterValueAsSimd128(reg_); |
| 461 *reinterpret_cast<RawSmi**>(to_addr) = Smi::New(0); | 536 *reinterpret_cast<RawSmi**>(to_addr) = Smi::New(0); |
| 462 Isolate::Current()->DeferUint32x4Materialization( | 537 deopt_context->DeferUint32x4Materialization( |
| 463 value, reinterpret_cast<RawUint32x4**>(to_addr)); | 538 value, reinterpret_cast<RawUint32x4**>(to_addr)); |
| 464 } | 539 } |
| 465 | 540 |
| 466 private: | 541 private: |
| 467 const FpuRegister reg_; | 542 const FpuRegister reg_; |
| 468 | 543 |
| 469 DISALLOW_COPY_AND_ASSIGN(DeoptUint32x4FpuRegisterInstr); | 544 DISALLOW_COPY_AND_ASSIGN(DeoptUint32x4FpuRegisterInstr); |
| 470 }; | 545 }; |
| 471 | 546 |
| 472 | 547 |
| 473 // Deoptimization instruction creating a PC marker for the code of | 548 // Deoptimization instruction creating a PC marker for the code of |
| 474 // function at 'object_table_index'. | 549 // function at 'object_table_index'. |
| 475 class DeoptPcMarkerInstr : public DeoptInstr { | 550 class DeoptPcMarkerInstr : public DeoptInstr { |
| 476 public: | 551 public: |
| 477 explicit DeoptPcMarkerInstr(intptr_t object_table_index) | 552 explicit DeoptPcMarkerInstr(intptr_t object_table_index) |
| 478 : object_table_index_(object_table_index) { | 553 : object_table_index_(object_table_index) { |
| 479 ASSERT(object_table_index >= 0); | 554 ASSERT(object_table_index >= 0); |
| 480 } | 555 } |
| 481 | 556 |
| 482 virtual intptr_t from_index() const { return object_table_index_; } | 557 virtual intptr_t from_index() const { return object_table_index_; } |
| 483 virtual DeoptInstr::Kind kind() const { return kPcMarker; } | 558 virtual DeoptInstr::Kind kind() const { return kPcMarker; } |
| 484 | 559 |
| 485 virtual const char* ToCString() const { | 560 virtual const char* ToCString() const { |
| 486 return Isolate::Current()->current_zone()->PrintToString( | 561 return Isolate::Current()->current_zone()->PrintToString( |
| 487 "pcmark oti:%" Pd "", object_table_index_); | 562 "pcmark oti:%" Pd "", object_table_index_); |
| 488 } | 563 } |
| 489 | 564 |
| 490 void Execute(DeoptimizationContext* deopt_context, intptr_t* to_addr) { | 565 void Execute(DeoptContext* deopt_context, intptr_t* to_addr) { |
| 491 Function& function = Function::Handle(deopt_context->isolate()); | 566 Function& function = Function::Handle(deopt_context->isolate()); |
| 492 function ^= deopt_context->ObjectAt(object_table_index_); | 567 function ^= deopt_context->ObjectAt(object_table_index_); |
| 493 if (function.IsNull()) { | 568 if (function.IsNull()) { |
| 494 // Callee's PC marker is not used (pc of Deoptimize stub). Set to 0. | 569 // Callee's PC marker is not used (pc of Deoptimize stub). Set to 0. |
| 495 *to_addr = 0; | 570 *to_addr = 0; |
| 496 return; | 571 return; |
| 497 } | 572 } |
| 498 const Code& code = | 573 const Code& code = |
| 499 Code::Handle(deopt_context->isolate(), function.unoptimized_code()); | 574 Code::Handle(deopt_context->isolate(), function.unoptimized_code()); |
| 500 ASSERT(!code.IsNull()); | 575 ASSERT(!code.IsNull()); |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 532 } | 607 } |
| 533 | 608 |
| 534 virtual intptr_t from_index() const { return object_table_index_; } | 609 virtual intptr_t from_index() const { return object_table_index_; } |
| 535 virtual DeoptInstr::Kind kind() const { return kPp; } | 610 virtual DeoptInstr::Kind kind() const { return kPp; } |
| 536 | 611 |
| 537 virtual const char* ToCString() const { | 612 virtual const char* ToCString() const { |
| 538 return Isolate::Current()->current_zone()->PrintToString( | 613 return Isolate::Current()->current_zone()->PrintToString( |
| 539 "pp oti:%" Pd "", object_table_index_); | 614 "pp oti:%" Pd "", object_table_index_); |
| 540 } | 615 } |
| 541 | 616 |
| 542 void Execute(DeoptimizationContext* deopt_context, intptr_t* to_addr) { | 617 void Execute(DeoptContext* deopt_context, intptr_t* to_addr) { |
| 543 Function& function = Function::Handle(deopt_context->isolate()); | 618 Function& function = Function::Handle(deopt_context->isolate()); |
| 544 function ^= deopt_context->ObjectAt(object_table_index_); | 619 function ^= deopt_context->ObjectAt(object_table_index_); |
| 545 const Code& code = | 620 const Code& code = |
| 546 Code::Handle(deopt_context->isolate(), function.unoptimized_code()); | 621 Code::Handle(deopt_context->isolate(), function.unoptimized_code()); |
| 547 ASSERT(!code.IsNull()); | 622 ASSERT(!code.IsNull()); |
| 548 const intptr_t pp = reinterpret_cast<intptr_t>(code.ObjectPool()); | 623 const intptr_t pp = reinterpret_cast<intptr_t>(code.ObjectPool()); |
| 549 *to_addr = pp; | 624 *to_addr = pp; |
| 550 } | 625 } |
| 551 | 626 |
| 552 private: | 627 private: |
| 553 intptr_t object_table_index_; | 628 intptr_t object_table_index_; |
| 554 | 629 |
| 555 DISALLOW_COPY_AND_ASSIGN(DeoptPpInstr); | 630 DISALLOW_COPY_AND_ASSIGN(DeoptPpInstr); |
| 556 }; | 631 }; |
| 557 | 632 |
| 558 | 633 |
| 559 // Deoptimization instruction copying the caller saved FP from optimized frame. | 634 // Deoptimization instruction copying the caller saved FP from optimized frame. |
| 560 class DeoptCallerFpInstr : public DeoptInstr { | 635 class DeoptCallerFpInstr : public DeoptInstr { |
| 561 public: | 636 public: |
| 562 DeoptCallerFpInstr() {} | 637 DeoptCallerFpInstr() {} |
| 563 | 638 |
| 564 virtual intptr_t from_index() const { return 0; } | 639 virtual intptr_t from_index() const { return 0; } |
| 565 virtual DeoptInstr::Kind kind() const { return kCallerFp; } | 640 virtual DeoptInstr::Kind kind() const { return kCallerFp; } |
| 566 | 641 |
| 567 virtual const char* ToCString() const { | 642 virtual const char* ToCString() const { |
| 568 return "callerfp"; | 643 return "callerfp"; |
| 569 } | 644 } |
| 570 | 645 |
| 571 void Execute(DeoptimizationContext* deopt_context, intptr_t* to_addr) { | 646 void Execute(DeoptContext* deopt_context, intptr_t* to_addr) { |
| 572 *to_addr = deopt_context->GetCallerFp(); | 647 *to_addr = deopt_context->GetCallerFp(); |
| 573 deopt_context->SetCallerFp(reinterpret_cast<intptr_t>( | 648 deopt_context->SetCallerFp(reinterpret_cast<intptr_t>( |
| 574 to_addr - (kSavedCallerFpSlotFromFp * kWordSize))); | 649 to_addr - (kSavedCallerFpSlotFromFp * kWordSize))); |
| 575 } | 650 } |
| 576 | 651 |
| 577 private: | 652 private: |
| 578 DISALLOW_COPY_AND_ASSIGN(DeoptCallerFpInstr); | 653 DISALLOW_COPY_AND_ASSIGN(DeoptCallerFpInstr); |
| 579 }; | 654 }; |
| 580 | 655 |
| 581 | 656 |
| 582 // Deoptimization instruction copying the caller saved PP from optimized frame. | 657 // Deoptimization instruction copying the caller saved PP from optimized frame. |
| 583 class DeoptCallerPpInstr : public DeoptInstr { | 658 class DeoptCallerPpInstr : public DeoptInstr { |
| 584 public: | 659 public: |
| 585 DeoptCallerPpInstr() {} | 660 DeoptCallerPpInstr() {} |
| 586 | 661 |
| 587 virtual intptr_t from_index() const { return 0; } | 662 virtual intptr_t from_index() const { return 0; } |
| 588 virtual DeoptInstr::Kind kind() const { return kCallerPp; } | 663 virtual DeoptInstr::Kind kind() const { return kCallerPp; } |
| 589 | 664 |
| 590 virtual const char* ToCString() const { | 665 virtual const char* ToCString() const { |
| 591 return "callerpp"; | 666 return "callerpp"; |
| 592 } | 667 } |
| 593 | 668 |
| 594 void Execute(DeoptimizationContext* deopt_context, intptr_t* to_addr) { | 669 void Execute(DeoptContext* deopt_context, intptr_t* to_addr) { |
| 595 *to_addr = deopt_context->GetFromPp(); | 670 *to_addr = deopt_context->GetFromPp(); |
| 596 } | 671 } |
| 597 | 672 |
| 598 private: | 673 private: |
| 599 DISALLOW_COPY_AND_ASSIGN(DeoptCallerPpInstr); | 674 DISALLOW_COPY_AND_ASSIGN(DeoptCallerPpInstr); |
| 600 }; | 675 }; |
| 601 | 676 |
| 602 | 677 |
| 603 // Deoptimization instruction copying the caller return address from optimized | 678 // Deoptimization instruction copying the caller return address from optimized |
| 604 // frame. | 679 // frame. |
| 605 class DeoptCallerPcInstr : public DeoptInstr { | 680 class DeoptCallerPcInstr : public DeoptInstr { |
| 606 public: | 681 public: |
| 607 DeoptCallerPcInstr() {} | 682 DeoptCallerPcInstr() {} |
| 608 | 683 |
| 609 virtual intptr_t from_index() const { return 0; } | 684 virtual intptr_t from_index() const { return 0; } |
| 610 virtual DeoptInstr::Kind kind() const { return kCallerPc; } | 685 virtual DeoptInstr::Kind kind() const { return kCallerPc; } |
| 611 | 686 |
| 612 virtual const char* ToCString() const { | 687 virtual const char* ToCString() const { |
| 613 return "callerpc"; | 688 return "callerpc"; |
| 614 } | 689 } |
| 615 | 690 |
| 616 void Execute(DeoptimizationContext* deopt_context, intptr_t* to_addr) { | 691 void Execute(DeoptContext* deopt_context, intptr_t* to_addr) { |
| 617 *to_addr = deopt_context->GetFromPc(); | 692 *to_addr = deopt_context->GetFromPc(); |
| 618 } | 693 } |
| 619 | 694 |
| 620 private: | 695 private: |
| 621 DISALLOW_COPY_AND_ASSIGN(DeoptCallerPcInstr); | 696 DISALLOW_COPY_AND_ASSIGN(DeoptCallerPcInstr); |
| 622 }; | 697 }; |
| 623 | 698 |
| 624 | 699 |
| 625 // Deoptimization instruction that indicates the rest of this DeoptInfo is a | 700 // Deoptimization instruction that indicates the rest of this DeoptInfo is a |
| 626 // suffix of another one. The suffix contains the info number (0 based | 701 // suffix of another one. The suffix contains the info number (0 based |
| (...skipping 16 matching lines...) Expand all Loading... |
| 643 return InfoNumber::encode(info_number_) | | 718 return InfoNumber::encode(info_number_) | |
| 644 SuffixLength::encode(suffix_length_); | 719 SuffixLength::encode(suffix_length_); |
| 645 } | 720 } |
| 646 virtual DeoptInstr::Kind kind() const { return kSuffix; } | 721 virtual DeoptInstr::Kind kind() const { return kSuffix; } |
| 647 | 722 |
| 648 virtual const char* ToCString() const { | 723 virtual const char* ToCString() const { |
| 649 return Isolate::Current()->current_zone()->PrintToString( | 724 return Isolate::Current()->current_zone()->PrintToString( |
| 650 "suffix %" Pd ":%" Pd, info_number_, suffix_length_); | 725 "suffix %" Pd ":%" Pd, info_number_, suffix_length_); |
| 651 } | 726 } |
| 652 | 727 |
| 653 void Execute(DeoptimizationContext* deopt_context, intptr_t* to_addr) { | 728 void Execute(DeoptContext* deopt_context, intptr_t* to_addr) { |
| 654 // The deoptimization info is uncompressed by translating away suffixes | 729 // The deoptimization info is uncompressed by translating away suffixes |
| 655 // before executing the instructions. | 730 // before executing the instructions. |
| 656 UNREACHABLE(); | 731 UNREACHABLE(); |
| 657 } | 732 } |
| 658 | 733 |
| 659 private: | 734 private: |
| 660 // Static decoder functions in DeoptInstr have access to the bitfield | 735 // Static decoder functions in DeoptInstr have access to the bitfield |
| 661 // definitions. | 736 // definitions. |
| 662 friend class DeoptInstr; | 737 friend class DeoptInstr; |
| 663 | 738 |
| (...skipping 18 matching lines...) Expand all Loading... |
| 682 } | 757 } |
| 683 | 758 |
| 684 virtual intptr_t from_index() const { return index_; } | 759 virtual intptr_t from_index() const { return index_; } |
| 685 virtual DeoptInstr::Kind kind() const { return kMaterializedObjectRef; } | 760 virtual DeoptInstr::Kind kind() const { return kMaterializedObjectRef; } |
| 686 | 761 |
| 687 virtual const char* ToCString() const { | 762 virtual const char* ToCString() const { |
| 688 return Isolate::Current()->current_zone()->PrintToString( | 763 return Isolate::Current()->current_zone()->PrintToString( |
| 689 "mat ref #%" Pd "", index_); | 764 "mat ref #%" Pd "", index_); |
| 690 } | 765 } |
| 691 | 766 |
| 692 void Execute(DeoptimizationContext* deopt_context, intptr_t* to_addr) { | 767 void Execute(DeoptContext* deopt_context, intptr_t* to_addr) { |
| 693 *reinterpret_cast<RawSmi**>(to_addr) = Smi::New(0); | 768 *reinterpret_cast<RawSmi**>(to_addr) = Smi::New(0); |
| 694 Isolate::Current()->DeferMaterializedObjectRef( | 769 deopt_context->DeferMaterializedObjectRef( |
| 695 index_, to_addr); | 770 index_, to_addr); |
| 696 } | 771 } |
| 697 | 772 |
| 698 private: | 773 private: |
| 699 intptr_t index_; | 774 intptr_t index_; |
| 700 | 775 |
| 701 DISALLOW_COPY_AND_ASSIGN(DeoptMaterializedObjectRefInstr); | 776 DISALLOW_COPY_AND_ASSIGN(DeoptMaterializedObjectRefInstr); |
| 702 }; | 777 }; |
| 703 | 778 |
| 704 | 779 |
| 705 // Materialize object with the given number of fields. | 780 // Materialize object with the given number of fields. |
| 706 // Arguments for materialization (class and field-value pairs) are pushed | 781 // Arguments for materialization (class and field-value pairs) are pushed |
| 707 // to the expression stack of the bottom-most frame. | 782 // to the expression stack of the bottom-most frame. |
| 708 class DeoptMaterializeObjectInstr : public DeoptInstr { | 783 class DeoptMaterializeObjectInstr : public DeoptInstr { |
| 709 public: | 784 public: |
| 710 explicit DeoptMaterializeObjectInstr(intptr_t field_count) | 785 explicit DeoptMaterializeObjectInstr(intptr_t field_count) |
| 711 : field_count_(field_count) { | 786 : field_count_(field_count) { |
| 712 ASSERT(field_count >= 0); | 787 ASSERT(field_count >= 0); |
| 713 } | 788 } |
| 714 | 789 |
| 715 virtual intptr_t from_index() const { return field_count_; } | 790 virtual intptr_t from_index() const { return field_count_; } |
| 716 virtual DeoptInstr::Kind kind() const { return kMaterializeObject; } | 791 virtual DeoptInstr::Kind kind() const { return kMaterializeObject; } |
| 717 | 792 |
| 718 virtual const char* ToCString() const { | 793 virtual const char* ToCString() const { |
| 719 return Isolate::Current()->current_zone()->PrintToString( | 794 return Isolate::Current()->current_zone()->PrintToString( |
| 720 "mat obj len:%" Pd "", field_count_); | 795 "mat obj len:%" Pd "", field_count_); |
| 721 } | 796 } |
| 722 | 797 |
| 723 void Execute(DeoptimizationContext* deopt_context, intptr_t* to_addr) { | 798 void Execute(DeoptContext* deopt_context, intptr_t* to_addr) { |
| 724 // This instructions are executed manually by the DeoptimizeWithDeoptInfo. | 799 // This instructions are executed manually by the DeoptimizeWithDeoptInfo. |
| 725 UNREACHABLE(); | 800 UNREACHABLE(); |
| 726 } | 801 } |
| 727 | 802 |
| 728 private: | 803 private: |
| 729 intptr_t field_count_; | 804 intptr_t field_count_; |
| 730 | 805 |
| 731 DISALLOW_COPY_AND_ASSIGN(DeoptMaterializeObjectInstr); | 806 DISALLOW_COPY_AND_ASSIGN(DeoptMaterializeObjectInstr); |
| 732 }; | 807 }; |
| 733 | 808 |
| (...skipping 368 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1102 Smi* offset, | 1177 Smi* offset, |
| 1103 DeoptInfo* info, | 1178 DeoptInfo* info, |
| 1104 Smi* reason) { | 1179 Smi* reason) { |
| 1105 intptr_t i = index * kEntrySize; | 1180 intptr_t i = index * kEntrySize; |
| 1106 *offset ^= table.At(i); | 1181 *offset ^= table.At(i); |
| 1107 *info ^= table.At(i + 1); | 1182 *info ^= table.At(i + 1); |
| 1108 *reason ^= table.At(i + 2); | 1183 *reason ^= table.At(i + 2); |
| 1109 } | 1184 } |
| 1110 | 1185 |
| 1111 } // namespace dart | 1186 } // namespace dart |
| OLD | NEW |