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" |
(...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
183 } | 183 } |
184 | 184 |
185 | 185 |
186 static bool IsObjectInstruction(DeoptInstr::Kind kind) { | 186 static bool IsObjectInstruction(DeoptInstr::Kind kind) { |
187 switch (kind) { | 187 switch (kind) { |
188 case DeoptInstr::kConstant: | 188 case DeoptInstr::kConstant: |
189 case DeoptInstr::kStackSlot: | 189 case DeoptInstr::kStackSlot: |
190 case DeoptInstr::kDoubleStackSlot: | 190 case DeoptInstr::kDoubleStackSlot: |
191 case DeoptInstr::kInt64StackSlot: | 191 case DeoptInstr::kInt64StackSlot: |
192 case DeoptInstr::kFloat32x4StackSlot: | 192 case DeoptInstr::kFloat32x4StackSlot: |
193 case DeoptInstr::kUint32x4StackSlot: | 193 case DeoptInstr::kInt32x4StackSlot: |
194 case DeoptInstr::kPp: | 194 case DeoptInstr::kPp: |
195 case DeoptInstr::kCallerPp: | 195 case DeoptInstr::kCallerPp: |
196 case DeoptInstr::kMaterializedObjectRef: | 196 case DeoptInstr::kMaterializedObjectRef: |
197 return true; | 197 return true; |
198 | 198 |
199 case DeoptInstr::kRegister: | 199 case DeoptInstr::kRegister: |
200 case DeoptInstr::kFpuRegister: | 200 case DeoptInstr::kFpuRegister: |
201 case DeoptInstr::kInt64FpuRegister: | 201 case DeoptInstr::kInt64FpuRegister: |
202 case DeoptInstr::kFloat32x4FpuRegister: | 202 case DeoptInstr::kFloat32x4FpuRegister: |
203 case DeoptInstr::kUint32x4FpuRegister: | 203 case DeoptInstr::kInt32x4FpuRegister: |
204 // TODO(turnidge): Sometimes we encounter a deopt instruction | 204 // TODO(turnidge): Sometimes we encounter a deopt instruction |
205 // with a register source while deoptimizing frames during | 205 // with a register source while deoptimizing frames during |
206 // debugging but we haven't saved our register set. This | 206 // debugging but we haven't saved our register set. This |
207 // happens specifically when using the VMService to inspect the | 207 // happens specifically when using the VMService to inspect the |
208 // stack. In that case, the register values will have been | 208 // stack. In that case, the register values will have been |
209 // saved before the StackOverflow runtime call but we do not | 209 // saved before the StackOverflow runtime call but we do not |
210 // actually keep track of which registers were saved and | 210 // actually keep track of which registers were saved and |
211 // restored. | 211 // restored. |
212 // | 212 // |
213 // It is possible to save this information at the point of the | 213 // It is possible to save this information at the point of the |
(...skipping 285 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
499 *source_addr, reinterpret_cast<RawFloat32x4**>(dest_addr)); | 499 *source_addr, reinterpret_cast<RawFloat32x4**>(dest_addr)); |
500 } | 500 } |
501 | 501 |
502 private: | 502 private: |
503 const intptr_t stack_slot_index_; // First argument is 0, always >= 0. | 503 const intptr_t stack_slot_index_; // First argument is 0, always >= 0. |
504 | 504 |
505 DISALLOW_COPY_AND_ASSIGN(DeoptFloat32x4StackSlotInstr); | 505 DISALLOW_COPY_AND_ASSIGN(DeoptFloat32x4StackSlotInstr); |
506 }; | 506 }; |
507 | 507 |
508 | 508 |
509 class DeoptUint32x4StackSlotInstr : public DeoptInstr { | 509 class DeoptInt32x4StackSlotInstr : public DeoptInstr { |
510 public: | 510 public: |
511 explicit DeoptUint32x4StackSlotInstr(intptr_t source_index) | 511 explicit DeoptInt32x4StackSlotInstr(intptr_t source_index) |
512 : stack_slot_index_(source_index) { | 512 : stack_slot_index_(source_index) { |
513 ASSERT(stack_slot_index_ >= 0); | 513 ASSERT(stack_slot_index_ >= 0); |
514 } | 514 } |
515 | 515 |
516 virtual intptr_t source_index() const { return stack_slot_index_; } | 516 virtual intptr_t source_index() const { return stack_slot_index_; } |
517 virtual DeoptInstr::Kind kind() const { return kUint32x4StackSlot; } | 517 virtual DeoptInstr::Kind kind() const { return kInt32x4StackSlot; } |
518 | 518 |
519 virtual const char* ToCString() const { | 519 virtual const char* ToCString() const { |
520 return Isolate::Current()->current_zone()->PrintToString( | 520 return Isolate::Current()->current_zone()->PrintToString( |
521 "ui32x4s%" Pd "", stack_slot_index_); | 521 "ui32x4s%" Pd "", stack_slot_index_); |
522 } | 522 } |
523 | 523 |
524 void Execute(DeoptContext* deopt_context, intptr_t* dest_addr) { | 524 void Execute(DeoptContext* deopt_context, intptr_t* dest_addr) { |
525 intptr_t source_index = | 525 intptr_t source_index = |
526 deopt_context->source_frame_size() - stack_slot_index_ - 1; | 526 deopt_context->source_frame_size() - stack_slot_index_ - 1; |
527 simd128_value_t* source_addr = reinterpret_cast<simd128_value_t*>( | 527 simd128_value_t* source_addr = reinterpret_cast<simd128_value_t*>( |
528 deopt_context->GetSourceFrameAddressAt(source_index)); | 528 deopt_context->GetSourceFrameAddressAt(source_index)); |
529 *reinterpret_cast<RawSmi**>(dest_addr) = Smi::New(0); | 529 *reinterpret_cast<RawSmi**>(dest_addr) = Smi::New(0); |
530 deopt_context->DeferUint32x4Materialization( | 530 deopt_context->DeferInt32x4Materialization( |
531 *source_addr, reinterpret_cast<RawUint32x4**>(dest_addr)); | 531 *source_addr, reinterpret_cast<RawInt32x4**>(dest_addr)); |
532 } | 532 } |
533 | 533 |
534 private: | 534 private: |
535 const intptr_t stack_slot_index_; // First argument is 0, always >= 0. | 535 const intptr_t stack_slot_index_; // First argument is 0, always >= 0. |
536 | 536 |
537 DISALLOW_COPY_AND_ASSIGN(DeoptUint32x4StackSlotInstr); | 537 DISALLOW_COPY_AND_ASSIGN(DeoptInt32x4StackSlotInstr); |
538 }; | 538 }; |
539 | 539 |
540 | 540 |
541 // Deoptimization instruction creating return address using function and | 541 // Deoptimization instruction creating return address using function and |
542 // deopt-id stored at 'object_table_index'. | 542 // deopt-id stored at 'object_table_index'. |
543 class DeoptRetAddressInstr : public DeoptInstr { | 543 class DeoptRetAddressInstr : public DeoptInstr { |
544 public: | 544 public: |
545 DeoptRetAddressInstr(intptr_t object_table_index, intptr_t deopt_id) | 545 DeoptRetAddressInstr(intptr_t object_table_index, intptr_t deopt_id) |
546 : object_table_index_(object_table_index), deopt_id_(deopt_id) { | 546 : object_table_index_(object_table_index), deopt_id_(deopt_id) { |
547 ASSERT(object_table_index >= 0); | 547 ASSERT(object_table_index >= 0); |
(...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
737 } | 737 } |
738 | 738 |
739 private: | 739 private: |
740 const FpuRegister reg_; | 740 const FpuRegister reg_; |
741 | 741 |
742 DISALLOW_COPY_AND_ASSIGN(DeoptFloat32x4FpuRegisterInstr); | 742 DISALLOW_COPY_AND_ASSIGN(DeoptFloat32x4FpuRegisterInstr); |
743 }; | 743 }; |
744 | 744 |
745 | 745 |
746 // Deoptimization instruction moving an XMM register. | 746 // Deoptimization instruction moving an XMM register. |
747 class DeoptUint32x4FpuRegisterInstr: public DeoptInstr { | 747 class DeoptInt32x4FpuRegisterInstr: public DeoptInstr { |
748 public: | 748 public: |
749 explicit DeoptUint32x4FpuRegisterInstr(intptr_t reg_as_int) | 749 explicit DeoptInt32x4FpuRegisterInstr(intptr_t reg_as_int) |
750 : reg_(static_cast<FpuRegister>(reg_as_int)) {} | 750 : reg_(static_cast<FpuRegister>(reg_as_int)) {} |
751 | 751 |
752 virtual intptr_t source_index() const { return static_cast<intptr_t>(reg_); } | 752 virtual intptr_t source_index() const { return static_cast<intptr_t>(reg_); } |
753 virtual DeoptInstr::Kind kind() const { return kUint32x4FpuRegister; } | 753 virtual DeoptInstr::Kind kind() const { return kInt32x4FpuRegister; } |
754 | 754 |
755 virtual const char* ToCString() const { | 755 virtual const char* ToCString() const { |
756 return Isolate::Current()->current_zone()->PrintToString( | 756 return Isolate::Current()->current_zone()->PrintToString( |
757 "%s(f32x4)", Assembler::FpuRegisterName(reg_)); | 757 "%s(f32x4)", Assembler::FpuRegisterName(reg_)); |
758 } | 758 } |
759 | 759 |
760 void Execute(DeoptContext* deopt_context, intptr_t* dest_addr) { | 760 void Execute(DeoptContext* deopt_context, intptr_t* dest_addr) { |
761 simd128_value_t value = deopt_context->FpuRegisterValueAsSimd128(reg_); | 761 simd128_value_t value = deopt_context->FpuRegisterValueAsSimd128(reg_); |
762 *reinterpret_cast<RawSmi**>(dest_addr) = Smi::New(0); | 762 *reinterpret_cast<RawSmi**>(dest_addr) = Smi::New(0); |
763 deopt_context->DeferUint32x4Materialization( | 763 deopt_context->DeferInt32x4Materialization( |
764 value, reinterpret_cast<RawUint32x4**>(dest_addr)); | 764 value, reinterpret_cast<RawInt32x4**>(dest_addr)); |
765 } | 765 } |
766 | 766 |
767 private: | 767 private: |
768 const FpuRegister reg_; | 768 const FpuRegister reg_; |
769 | 769 |
770 DISALLOW_COPY_AND_ASSIGN(DeoptUint32x4FpuRegisterInstr); | 770 DISALLOW_COPY_AND_ASSIGN(DeoptInt32x4FpuRegisterInstr); |
771 }; | 771 }; |
772 | 772 |
773 | 773 |
774 // Deoptimization instruction creating a PC marker for the code of | 774 // Deoptimization instruction creating a PC marker for the code of |
775 // function at 'object_table_index'. | 775 // function at 'object_table_index'. |
776 class DeoptPcMarkerInstr : public DeoptInstr { | 776 class DeoptPcMarkerInstr : public DeoptInstr { |
777 public: | 777 public: |
778 explicit DeoptPcMarkerInstr(intptr_t object_table_index) | 778 explicit DeoptPcMarkerInstr(intptr_t object_table_index) |
779 : object_table_index_(object_table_index) { | 779 : object_table_index_(object_table_index) { |
780 ASSERT(object_table_index >= 0); | 780 ASSERT(object_table_index >= 0); |
(...skipping 281 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1062 | 1062 |
1063 | 1063 |
1064 DeoptInstr* DeoptInstr::Create(intptr_t kind_as_int, intptr_t source_index) { | 1064 DeoptInstr* DeoptInstr::Create(intptr_t kind_as_int, intptr_t source_index) { |
1065 Kind kind = static_cast<Kind>(kind_as_int); | 1065 Kind kind = static_cast<Kind>(kind_as_int); |
1066 switch (kind) { | 1066 switch (kind) { |
1067 case kStackSlot: return new DeoptStackSlotInstr(source_index); | 1067 case kStackSlot: return new DeoptStackSlotInstr(source_index); |
1068 case kDoubleStackSlot: return new DeoptDoubleStackSlotInstr(source_index); | 1068 case kDoubleStackSlot: return new DeoptDoubleStackSlotInstr(source_index); |
1069 case kInt64StackSlot: return new DeoptInt64StackSlotInstr(source_index); | 1069 case kInt64StackSlot: return new DeoptInt64StackSlotInstr(source_index); |
1070 case kFloat32x4StackSlot: | 1070 case kFloat32x4StackSlot: |
1071 return new DeoptFloat32x4StackSlotInstr(source_index); | 1071 return new DeoptFloat32x4StackSlotInstr(source_index); |
1072 case kUint32x4StackSlot: | 1072 case kInt32x4StackSlot: |
1073 return new DeoptUint32x4StackSlotInstr(source_index); | 1073 return new DeoptInt32x4StackSlotInstr(source_index); |
1074 case kRetAddress: return new DeoptRetAddressInstr(source_index); | 1074 case kRetAddress: return new DeoptRetAddressInstr(source_index); |
1075 case kConstant: return new DeoptConstantInstr(source_index); | 1075 case kConstant: return new DeoptConstantInstr(source_index); |
1076 case kRegister: return new DeoptRegisterInstr(source_index); | 1076 case kRegister: return new DeoptRegisterInstr(source_index); |
1077 case kFpuRegister: return new DeoptFpuRegisterInstr(source_index); | 1077 case kFpuRegister: return new DeoptFpuRegisterInstr(source_index); |
1078 case kInt64FpuRegister: return new DeoptInt64FpuRegisterInstr(source_index); | 1078 case kInt64FpuRegister: return new DeoptInt64FpuRegisterInstr(source_index); |
1079 case kFloat32x4FpuRegister: | 1079 case kFloat32x4FpuRegister: |
1080 return new DeoptFloat32x4FpuRegisterInstr(source_index); | 1080 return new DeoptFloat32x4FpuRegisterInstr(source_index); |
1081 case kUint32x4FpuRegister: | 1081 case kInt32x4FpuRegister: |
1082 return new DeoptUint32x4FpuRegisterInstr(source_index); | 1082 return new DeoptInt32x4FpuRegisterInstr(source_index); |
1083 case kPcMarker: return new DeoptPcMarkerInstr(source_index); | 1083 case kPcMarker: return new DeoptPcMarkerInstr(source_index); |
1084 case kPp: return new DeoptPpInstr(source_index); | 1084 case kPp: return new DeoptPpInstr(source_index); |
1085 case kCallerFp: return new DeoptCallerFpInstr(); | 1085 case kCallerFp: return new DeoptCallerFpInstr(); |
1086 case kCallerPp: return new DeoptCallerPpInstr(); | 1086 case kCallerPp: return new DeoptCallerPpInstr(); |
1087 case kCallerPc: return new DeoptCallerPcInstr(); | 1087 case kCallerPc: return new DeoptCallerPcInstr(); |
1088 case kSuffix: return new DeoptSuffixInstr(source_index); | 1088 case kSuffix: return new DeoptSuffixInstr(source_index); |
1089 case kMaterializedObjectRef: | 1089 case kMaterializedObjectRef: |
1090 return new DeoptMaterializedObjectRefInstr(source_index); | 1090 return new DeoptMaterializedObjectRefInstr(source_index); |
1091 case kMaterializeObject: | 1091 case kMaterializeObject: |
1092 return new DeoptMaterializeObjectInstr(source_index); | 1092 return new DeoptMaterializeObjectInstr(source_index); |
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1207 ASSERT(value->definition()->representation() == kTagged); | 1207 ASSERT(value->definition()->representation() == kTagged); |
1208 deopt_instr = new DeoptRegisterInstr(source_loc.reg()); | 1208 deopt_instr = new DeoptRegisterInstr(source_loc.reg()); |
1209 } else if (source_loc.IsFpuRegister()) { | 1209 } else if (source_loc.IsFpuRegister()) { |
1210 if (value->definition()->representation() == kUnboxedDouble) { | 1210 if (value->definition()->representation() == kUnboxedDouble) { |
1211 deopt_instr = new DeoptFpuRegisterInstr(source_loc.fpu_reg()); | 1211 deopt_instr = new DeoptFpuRegisterInstr(source_loc.fpu_reg()); |
1212 } else if (value->definition()->representation() == kUnboxedMint) { | 1212 } else if (value->definition()->representation() == kUnboxedMint) { |
1213 deopt_instr = new DeoptInt64FpuRegisterInstr(source_loc.fpu_reg()); | 1213 deopt_instr = new DeoptInt64FpuRegisterInstr(source_loc.fpu_reg()); |
1214 } else if (value->definition()->representation() == kUnboxedFloat32x4) { | 1214 } else if (value->definition()->representation() == kUnboxedFloat32x4) { |
1215 deopt_instr = new DeoptFloat32x4FpuRegisterInstr(source_loc.fpu_reg()); | 1215 deopt_instr = new DeoptFloat32x4FpuRegisterInstr(source_loc.fpu_reg()); |
1216 } else { | 1216 } else { |
1217 ASSERT(value->definition()->representation() == kUnboxedUint32x4); | 1217 ASSERT(value->definition()->representation() == kUnboxedInt32x4); |
1218 deopt_instr = new DeoptUint32x4FpuRegisterInstr(source_loc.fpu_reg()); | 1218 deopt_instr = new DeoptInt32x4FpuRegisterInstr(source_loc.fpu_reg()); |
1219 } | 1219 } |
1220 } else if (source_loc.IsStackSlot()) { | 1220 } else if (source_loc.IsStackSlot()) { |
1221 ASSERT(value->definition()->representation() == kTagged); | 1221 ASSERT(value->definition()->representation() == kTagged); |
1222 intptr_t source_index = CalculateStackIndex(source_loc); | 1222 intptr_t source_index = CalculateStackIndex(source_loc); |
1223 deopt_instr = new DeoptStackSlotInstr(source_index); | 1223 deopt_instr = new DeoptStackSlotInstr(source_index); |
1224 } else if (source_loc.IsDoubleStackSlot()) { | 1224 } else if (source_loc.IsDoubleStackSlot()) { |
1225 intptr_t source_index = CalculateStackIndex(source_loc); | 1225 intptr_t source_index = CalculateStackIndex(source_loc); |
1226 if (value->definition()->representation() == kUnboxedDouble) { | 1226 if (value->definition()->representation() == kUnboxedDouble) { |
1227 deopt_instr = new DeoptDoubleStackSlotInstr(source_index); | 1227 deopt_instr = new DeoptDoubleStackSlotInstr(source_index); |
1228 } else { | 1228 } else { |
1229 ASSERT(value->definition()->representation() == kUnboxedMint); | 1229 ASSERT(value->definition()->representation() == kUnboxedMint); |
1230 deopt_instr = new DeoptInt64StackSlotInstr(source_index); | 1230 deopt_instr = new DeoptInt64StackSlotInstr(source_index); |
1231 } | 1231 } |
1232 } else if (source_loc.IsQuadStackSlot()) { | 1232 } else if (source_loc.IsQuadStackSlot()) { |
1233 intptr_t source_index = CalculateStackIndex(source_loc); | 1233 intptr_t source_index = CalculateStackIndex(source_loc); |
1234 if (value->definition()->representation() == kUnboxedFloat32x4) { | 1234 if (value->definition()->representation() == kUnboxedFloat32x4) { |
1235 deopt_instr = new DeoptFloat32x4StackSlotInstr(source_index); | 1235 deopt_instr = new DeoptFloat32x4StackSlotInstr(source_index); |
1236 } else { | 1236 } else { |
1237 ASSERT(value->definition()->representation() == kUnboxedUint32x4); | 1237 ASSERT(value->definition()->representation() == kUnboxedInt32x4); |
1238 deopt_instr = new DeoptUint32x4StackSlotInstr(source_index); | 1238 deopt_instr = new DeoptInt32x4StackSlotInstr(source_index); |
1239 } | 1239 } |
1240 } else if (source_loc.IsInvalid() && | 1240 } else if (source_loc.IsInvalid() && |
1241 value->definition()->IsMaterializeObject()) { | 1241 value->definition()->IsMaterializeObject()) { |
1242 const intptr_t index = FindMaterialization( | 1242 const intptr_t index = FindMaterialization( |
1243 value->definition()->AsMaterializeObject()); | 1243 value->definition()->AsMaterializeObject()); |
1244 ASSERT(index >= 0); | 1244 ASSERT(index >= 0); |
1245 deopt_instr = new DeoptMaterializedObjectRefInstr(index); | 1245 deopt_instr = new DeoptMaterializedObjectRefInstr(index); |
1246 } else { | 1246 } else { |
1247 UNREACHABLE(); | 1247 UNREACHABLE(); |
1248 } | 1248 } |
(...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1411 Smi* offset, | 1411 Smi* offset, |
1412 DeoptInfo* info, | 1412 DeoptInfo* info, |
1413 Smi* reason) { | 1413 Smi* reason) { |
1414 intptr_t i = index * kEntrySize; | 1414 intptr_t i = index * kEntrySize; |
1415 *offset ^= table.At(i); | 1415 *offset ^= table.At(i); |
1416 *info ^= table.At(i + 1); | 1416 *info ^= table.At(i + 1); |
1417 *reason ^= table.At(i + 2); | 1417 *reason ^= table.At(i + 2); |
1418 } | 1418 } |
1419 | 1419 |
1420 } // namespace dart | 1420 } // namespace dart |
OLD | NEW |