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 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
182 caller_fp_ = caller_fp; | 182 caller_fp_ = caller_fp; |
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::kInt64StackSlotPair: |
192 case DeoptInstr::kFloat32x4StackSlot: | 193 case DeoptInstr::kFloat32x4StackSlot: |
193 case DeoptInstr::kInt32x4StackSlot: | 194 case DeoptInstr::kInt32x4StackSlot: |
194 case DeoptInstr::kFloat64x2StackSlot: | 195 case DeoptInstr::kFloat64x2StackSlot: |
195 case DeoptInstr::kPp: | 196 case DeoptInstr::kPp: |
196 case DeoptInstr::kCallerPp: | 197 case DeoptInstr::kCallerPp: |
197 case DeoptInstr::kMaterializedObjectRef: | 198 case DeoptInstr::kMaterializedObjectRef: |
198 return true; | 199 return true; |
199 | 200 |
200 case DeoptInstr::kRegister: | 201 case DeoptInstr::kRegister: |
201 case DeoptInstr::kFpuRegister: | 202 case DeoptInstr::kFpuRegister: |
202 case DeoptInstr::kInt64FpuRegister: | 203 case DeoptInstr::kInt64RegisterPair: |
| 204 case DeoptInstr::kInt64StackSlotRegister: |
203 case DeoptInstr::kFloat32x4FpuRegister: | 205 case DeoptInstr::kFloat32x4FpuRegister: |
204 case DeoptInstr::kInt32x4FpuRegister: | 206 case DeoptInstr::kInt32x4FpuRegister: |
205 case DeoptInstr::kFloat64x2FpuRegister: | 207 case DeoptInstr::kFloat64x2FpuRegister: |
206 // TODO(turnidge): Sometimes we encounter a deopt instruction | 208 // TODO(turnidge): Sometimes we encounter a deopt instruction |
207 // with a register source while deoptimizing frames during | 209 // with a register source while deoptimizing frames during |
208 // debugging but we haven't saved our register set. This | 210 // debugging but we haven't saved our register set. This |
209 // happens specifically when using the VMService to inspect the | 211 // happens specifically when using the VMService to inspect the |
210 // stack. In that case, the register values will have been | 212 // stack. In that case, the register values will have been |
211 // saved before the StackOverflow runtime call but we do not | 213 // saved before the StackOverflow runtime call but we do not |
212 // actually keep track of which registers were saved and | 214 // actually keep track of which registers were saved and |
(...skipping 231 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
444 explicit DeoptInt64StackSlotInstr(intptr_t source_index) | 446 explicit DeoptInt64StackSlotInstr(intptr_t source_index) |
445 : stack_slot_index_(source_index) { | 447 : stack_slot_index_(source_index) { |
446 ASSERT(stack_slot_index_ >= 0); | 448 ASSERT(stack_slot_index_ >= 0); |
447 } | 449 } |
448 | 450 |
449 virtual intptr_t source_index() const { return stack_slot_index_; } | 451 virtual intptr_t source_index() const { return stack_slot_index_; } |
450 virtual DeoptInstr::Kind kind() const { return kInt64StackSlot; } | 452 virtual DeoptInstr::Kind kind() const { return kInt64StackSlot; } |
451 | 453 |
452 virtual const char* ToCString() const { | 454 virtual const char* ToCString() const { |
453 return Isolate::Current()->current_zone()->PrintToString( | 455 return Isolate::Current()->current_zone()->PrintToString( |
454 "ms%" Pd "", stack_slot_index_); | 456 "int64 stack slot:%" Pd "", stack_slot_index_); |
455 } | 457 } |
456 | 458 |
457 void Execute(DeoptContext* deopt_context, intptr_t* dest_addr) { | 459 void Execute(DeoptContext* deopt_context, intptr_t* dest_addr) { |
458 intptr_t source_index = | 460 intptr_t source_index = |
459 deopt_context->source_frame_size() - stack_slot_index_ - 1; | 461 deopt_context->source_frame_size() - stack_slot_index_ - 1; |
460 int64_t* source_addr = reinterpret_cast<int64_t*>( | 462 int64_t* source_addr = reinterpret_cast<int64_t*>( |
461 deopt_context->GetSourceFrameAddressAt(source_index)); | 463 deopt_context->GetSourceFrameAddressAt(source_index)); |
462 *reinterpret_cast<RawSmi**>(dest_addr) = Smi::New(0); | 464 *reinterpret_cast<RawSmi**>(dest_addr) = Smi::New(0); |
463 if (Smi::IsValid64(*source_addr)) { | 465 if (Smi::IsValid64(*source_addr)) { |
464 *dest_addr = reinterpret_cast<intptr_t>( | 466 *dest_addr = reinterpret_cast<intptr_t>( |
(...skipping 247 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
712 value, reinterpret_cast<RawDouble**>(dest_addr)); | 714 value, reinterpret_cast<RawDouble**>(dest_addr)); |
713 } | 715 } |
714 | 716 |
715 private: | 717 private: |
716 const FpuRegister reg_; | 718 const FpuRegister reg_; |
717 | 719 |
718 DISALLOW_COPY_AND_ASSIGN(DeoptFpuRegisterInstr); | 720 DISALLOW_COPY_AND_ASSIGN(DeoptFpuRegisterInstr); |
719 }; | 721 }; |
720 | 722 |
721 | 723 |
722 class DeoptInt64FpuRegisterInstr: public DeoptInstr { | 724 class DeoptInt64RegisterPairInstr: public DeoptInstr { |
723 public: | 725 public: |
724 explicit DeoptInt64FpuRegisterInstr(intptr_t reg_as_int) | 726 DeoptInt64RegisterPairInstr(intptr_t lo_reg_as_int, intptr_t hi_reg_as_int) |
725 : reg_(static_cast<FpuRegister>(reg_as_int)) {} | 727 : lo_reg_(static_cast<Register>(lo_reg_as_int)), |
| 728 hi_reg_(static_cast<Register>(hi_reg_as_int)) {} |
726 | 729 |
727 virtual intptr_t source_index() const { return static_cast<intptr_t>(reg_); } | 730 virtual intptr_t source_index() const { |
728 virtual DeoptInstr::Kind kind() const { return kInt64FpuRegister; } | 731 return EncodeRegisters(static_cast<intptr_t>(lo_reg_), |
| 732 static_cast<intptr_t>(hi_reg_)); |
| 733 } |
| 734 virtual DeoptInstr::Kind kind() const { return kInt64RegisterPair; } |
729 | 735 |
730 virtual const char* ToCString() const { | 736 virtual const char* ToCString() const { |
731 return Isolate::Current()->current_zone()->PrintToString( | 737 return Isolate::Current()->current_zone()->PrintToString( |
732 "%s(m)", Assembler::FpuRegisterName(reg_)); | 738 "int64 register pair: %s,%s", Assembler::RegisterName(hi_reg_), |
| 739 Assembler::RegisterName(lo_reg_)); |
733 } | 740 } |
734 | 741 |
735 void Execute(DeoptContext* deopt_context, intptr_t* dest_addr) { | 742 void Execute(DeoptContext* deopt_context, intptr_t* dest_addr) { |
736 int64_t value = deopt_context->FpuRegisterValueAsInt64(reg_); | 743 uint32_t lo_value = deopt_context->RegisterValue(lo_reg_); |
| 744 int32_t hi_value = deopt_context->RegisterValue(hi_reg_); |
| 745 int64_t value = Utils::LowHighTo64Bits(lo_value, hi_value); |
737 *reinterpret_cast<RawSmi**>(dest_addr) = Smi::New(0); | 746 *reinterpret_cast<RawSmi**>(dest_addr) = Smi::New(0); |
738 if (Smi::IsValid64(value)) { | 747 if (Smi::IsValid64(value)) { |
739 *dest_addr = reinterpret_cast<intptr_t>( | 748 *dest_addr = reinterpret_cast<intptr_t>( |
740 Smi::New(static_cast<intptr_t>(value))); | 749 Smi::New(static_cast<intptr_t>(value))); |
741 } else { | 750 } else { |
742 deopt_context->DeferMintMaterialization( | 751 deopt_context->DeferMintMaterialization( |
743 value, reinterpret_cast<RawMint**>(dest_addr)); | 752 value, reinterpret_cast<RawMint**>(dest_addr)); |
744 } | 753 } |
745 } | 754 } |
746 | 755 |
| 756 static const intptr_t kFieldWidth = kBitsPerWord / 2; |
| 757 class LoRegister : public BitField<intptr_t, 0, kFieldWidth> { }; |
| 758 class HiRegister : public BitField<intptr_t, kFieldWidth, kFieldWidth> { }; |
| 759 static intptr_t EncodeRegisters(intptr_t lo_reg_as_int, |
| 760 intptr_t hi_reg_as_int) { |
| 761 return LoRegister::encode(lo_reg_as_int) | |
| 762 HiRegister::encode(hi_reg_as_int); |
| 763 } |
| 764 |
| 765 static intptr_t DecodeLoRegister(intptr_t v) { |
| 766 return LoRegister::decode(v); |
| 767 } |
| 768 |
| 769 static intptr_t DecodeHiRegister(intptr_t v) { |
| 770 return HiRegister::decode(v); |
| 771 } |
| 772 |
747 private: | 773 private: |
748 const FpuRegister reg_; | 774 const Register lo_reg_; |
| 775 const Register hi_reg_; |
749 | 776 |
750 DISALLOW_COPY_AND_ASSIGN(DeoptInt64FpuRegisterInstr); | 777 DISALLOW_COPY_AND_ASSIGN(DeoptInt64RegisterPairInstr); |
751 }; | 778 }; |
752 | 779 |
753 | 780 |
| 781 class DeoptInt64StackSlotPairInstr: public DeoptInstr { |
| 782 public: |
| 783 DeoptInt64StackSlotPairInstr(intptr_t lo_slot, intptr_t hi_slot) |
| 784 : lo_slot_(static_cast<Register>(lo_slot)), |
| 785 hi_slot_(static_cast<Register>(hi_slot)) {} |
| 786 |
| 787 virtual intptr_t source_index() const { |
| 788 return EncodeSlots(static_cast<intptr_t>(lo_slot_), |
| 789 static_cast<intptr_t>(hi_slot_)); |
| 790 } |
| 791 virtual DeoptInstr::Kind kind() const { return kInt64StackSlotPair; } |
| 792 |
| 793 virtual const char* ToCString() const { |
| 794 return Isolate::Current()->current_zone()->PrintToString( |
| 795 "int64 stack slots: %" Pd", %" Pd "", lo_slot_, hi_slot_); |
| 796 } |
| 797 |
| 798 void Execute(DeoptContext* deopt_context, intptr_t* dest_addr) { |
| 799 intptr_t lo_source_index = |
| 800 deopt_context->source_frame_size() - lo_slot_ - 1; |
| 801 int32_t* lo_source_addr = reinterpret_cast<int32_t*>( |
| 802 deopt_context->GetSourceFrameAddressAt(lo_source_index)); |
| 803 intptr_t hi_source_index = |
| 804 deopt_context->source_frame_size() - hi_slot_ - 1; |
| 805 int32_t* hi_source_addr = reinterpret_cast<int32_t*>( |
| 806 deopt_context->GetSourceFrameAddressAt(hi_source_index)); |
| 807 int64_t value = Utils::LowHighTo64Bits(*lo_source_addr, *hi_source_addr); |
| 808 *reinterpret_cast<RawSmi**>(dest_addr) = Smi::New(0); |
| 809 if (Smi::IsValid64(value)) { |
| 810 *dest_addr = reinterpret_cast<intptr_t>( |
| 811 Smi::New(static_cast<intptr_t>(value))); |
| 812 } else { |
| 813 deopt_context->DeferMintMaterialization( |
| 814 value, reinterpret_cast<RawMint**>(dest_addr)); |
| 815 } |
| 816 } |
| 817 |
| 818 static const intptr_t kFieldWidth = kBitsPerWord / 2; |
| 819 class LoSlot : public BitField<intptr_t, 0, kFieldWidth> { }; |
| 820 class HiSlot : public BitField<intptr_t, kFieldWidth, kFieldWidth> { }; |
| 821 static intptr_t EncodeSlots(intptr_t lo_slot, |
| 822 intptr_t hi_slot) { |
| 823 return LoSlot::encode(lo_slot) | |
| 824 HiSlot::encode(hi_slot); |
| 825 } |
| 826 |
| 827 static intptr_t DecodeLoSlot(intptr_t v) { |
| 828 return LoSlot::decode(v); |
| 829 } |
| 830 |
| 831 static intptr_t DecodeHiSlot(intptr_t v) { |
| 832 return HiSlot::decode(v); |
| 833 } |
| 834 |
| 835 private: |
| 836 const intptr_t lo_slot_; |
| 837 const intptr_t hi_slot_; |
| 838 |
| 839 DISALLOW_COPY_AND_ASSIGN(DeoptInt64StackSlotPairInstr); |
| 840 }; |
| 841 |
| 842 |
| 843 class DeoptInt64StackSlotRegisterInstr : public DeoptInstr { |
| 844 public: |
| 845 DeoptInt64StackSlotRegisterInstr(intptr_t source_index, |
| 846 intptr_t reg_as_int, |
| 847 bool flip) |
| 848 : slot_(source_index), |
| 849 reg_(static_cast<Register>(reg_as_int)), |
| 850 flip_(flip) { |
| 851 // when flip_ is false, stack slot is low bits and reg is high bits. |
| 852 // when flip_ is true, stack slot is high bits and reg is low bits. |
| 853 } |
| 854 |
| 855 virtual intptr_t source_index() const { |
| 856 return Encode(static_cast<intptr_t>(slot_), |
| 857 static_cast<intptr_t>(reg_), |
| 858 flip_ ? 1 : 0); |
| 859 } |
| 860 virtual DeoptInstr::Kind kind() const { return kInt64StackSlotRegister; } |
| 861 |
| 862 virtual const char* ToCString() const { |
| 863 if (flip_) { |
| 864 return Isolate::Current()->current_zone()->PrintToString( |
| 865 "int64 reg: %s, stack slot: %" Pd "", Assembler::RegisterName(reg_), |
| 866 slot_); |
| 867 } else { |
| 868 return Isolate::Current()->current_zone()->PrintToString( |
| 869 "int64 stack slot: %" Pd", reg: %s", slot_, |
| 870 Assembler::RegisterName(reg_)); |
| 871 } |
| 872 } |
| 873 |
| 874 void Execute(DeoptContext* deopt_context, intptr_t* dest_addr) { |
| 875 intptr_t slot_source_index = |
| 876 deopt_context->source_frame_size() - slot_ - 1; |
| 877 int32_t* slot_source_addr = reinterpret_cast<int32_t*>( |
| 878 deopt_context->GetSourceFrameAddressAt(slot_source_index)); |
| 879 int32_t slot_value = *slot_source_addr; |
| 880 int32_t reg_value = deopt_context->RegisterValue(reg_); |
| 881 int64_t value; |
| 882 if (flip_) { |
| 883 value = Utils::LowHighTo64Bits(reg_value, slot_value); |
| 884 } else { |
| 885 value = Utils::LowHighTo64Bits(slot_value, reg_value); |
| 886 } |
| 887 *reinterpret_cast<RawSmi**>(dest_addr) = Smi::New(0); |
| 888 if (Smi::IsValid64(value)) { |
| 889 *dest_addr = reinterpret_cast<intptr_t>( |
| 890 Smi::New(static_cast<intptr_t>(value))); |
| 891 } else { |
| 892 deopt_context->DeferMintMaterialization( |
| 893 value, reinterpret_cast<RawMint**>(dest_addr)); |
| 894 } |
| 895 } |
| 896 |
| 897 static const intptr_t kFieldWidth = kBitsPerWord / 2; |
| 898 class Slot : public BitField<intptr_t, 0, kFieldWidth> { }; |
| 899 class Reg : public BitField<intptr_t, kFieldWidth, kFieldWidth - 1> { }; |
| 900 // 1 bit for the flip. |
| 901 class Flip : public BitField<intptr_t, kFieldWidth * 2 - 1, 1> { }; |
| 902 |
| 903 static intptr_t Encode(intptr_t slot, |
| 904 intptr_t reg_as_int, |
| 905 bool flip) { |
| 906 return Slot::encode(slot) | |
| 907 Reg::encode(reg_as_int) | |
| 908 Flip::encode(flip ? 1 : 0); |
| 909 } |
| 910 |
| 911 static intptr_t DecodeSlot(intptr_t v) { |
| 912 return Slot::decode(v); |
| 913 } |
| 914 |
| 915 static intptr_t DecodeReg(intptr_t v) { |
| 916 return Reg::decode(v); |
| 917 } |
| 918 |
| 919 static bool DecodeFlip(intptr_t v) { |
| 920 return Flip::decode(v); |
| 921 } |
| 922 |
| 923 private: |
| 924 const intptr_t slot_; |
| 925 const Register reg_; |
| 926 const bool flip_; |
| 927 DISALLOW_COPY_AND_ASSIGN(DeoptInt64StackSlotRegisterInstr); |
| 928 }; |
| 929 |
| 930 |
754 // Deoptimization instruction moving an XMM register. | 931 // Deoptimization instruction moving an XMM register. |
755 class DeoptFloat32x4FpuRegisterInstr: public DeoptInstr { | 932 class DeoptFloat32x4FpuRegisterInstr: public DeoptInstr { |
756 public: | 933 public: |
757 explicit DeoptFloat32x4FpuRegisterInstr(intptr_t reg_as_int) | 934 explicit DeoptFloat32x4FpuRegisterInstr(intptr_t reg_as_int) |
758 : reg_(static_cast<FpuRegister>(reg_as_int)) {} | 935 : reg_(static_cast<FpuRegister>(reg_as_int)) {} |
759 | 936 |
760 virtual intptr_t source_index() const { return static_cast<intptr_t>(reg_); } | 937 virtual intptr_t source_index() const { return static_cast<intptr_t>(reg_); } |
761 virtual DeoptInstr::Kind kind() const { return kFloat32x4FpuRegister; } | 938 virtual DeoptInstr::Kind kind() const { return kFloat32x4FpuRegister; } |
762 | 939 |
763 virtual const char* ToCString() const { | 940 virtual const char* ToCString() const { |
(...skipping 368 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1132 case kFloat32x4StackSlot: | 1309 case kFloat32x4StackSlot: |
1133 return new DeoptFloat32x4StackSlotInstr(source_index); | 1310 return new DeoptFloat32x4StackSlotInstr(source_index); |
1134 case kFloat64x2StackSlot: | 1311 case kFloat64x2StackSlot: |
1135 return new DeoptFloat64x2StackSlotInstr(source_index); | 1312 return new DeoptFloat64x2StackSlotInstr(source_index); |
1136 case kInt32x4StackSlot: | 1313 case kInt32x4StackSlot: |
1137 return new DeoptInt32x4StackSlotInstr(source_index); | 1314 return new DeoptInt32x4StackSlotInstr(source_index); |
1138 case kRetAddress: return new DeoptRetAddressInstr(source_index); | 1315 case kRetAddress: return new DeoptRetAddressInstr(source_index); |
1139 case kConstant: return new DeoptConstantInstr(source_index); | 1316 case kConstant: return new DeoptConstantInstr(source_index); |
1140 case kRegister: return new DeoptRegisterInstr(source_index); | 1317 case kRegister: return new DeoptRegisterInstr(source_index); |
1141 case kFpuRegister: return new DeoptFpuRegisterInstr(source_index); | 1318 case kFpuRegister: return new DeoptFpuRegisterInstr(source_index); |
1142 case kInt64FpuRegister: return new DeoptInt64FpuRegisterInstr(source_index); | 1319 case kInt64RegisterPair: { |
| 1320 intptr_t lo_reg_as_int = |
| 1321 DeoptInt64RegisterPairInstr::LoRegister::decode(source_index); |
| 1322 intptr_t hi_reg_as_int = |
| 1323 DeoptInt64RegisterPairInstr::HiRegister::decode(source_index); |
| 1324 return new DeoptInt64RegisterPairInstr(lo_reg_as_int, hi_reg_as_int); |
| 1325 } |
| 1326 case kInt64StackSlotPair: { |
| 1327 intptr_t lo_slot = |
| 1328 DeoptInt64StackSlotPairInstr::LoSlot::decode(source_index); |
| 1329 intptr_t hi_slot = |
| 1330 DeoptInt64StackSlotPairInstr::HiSlot::decode(source_index); |
| 1331 return new DeoptInt64StackSlotPairInstr(lo_slot, hi_slot); |
| 1332 } |
| 1333 case kInt64StackSlotRegister: { |
| 1334 intptr_t slot = |
| 1335 DeoptInt64StackSlotRegisterInstr::Slot::decode(source_index); |
| 1336 intptr_t reg_as_int = |
| 1337 DeoptInt64StackSlotRegisterInstr::Reg::decode(source_index); |
| 1338 bool flip = DeoptInt64StackSlotRegisterInstr::Flip::decode(source_index); |
| 1339 return new DeoptInt64StackSlotRegisterInstr(slot, reg_as_int, flip); |
| 1340 } |
1143 case kFloat32x4FpuRegister: | 1341 case kFloat32x4FpuRegister: |
1144 return new DeoptFloat32x4FpuRegisterInstr(source_index); | 1342 return new DeoptFloat32x4FpuRegisterInstr(source_index); |
1145 case kFloat64x2FpuRegister: | 1343 case kFloat64x2FpuRegister: |
1146 return new DeoptFloat64x2FpuRegisterInstr(source_index); | 1344 return new DeoptFloat64x2FpuRegisterInstr(source_index); |
1147 case kInt32x4FpuRegister: | 1345 case kInt32x4FpuRegister: |
1148 return new DeoptInt32x4FpuRegisterInstr(source_index); | 1346 return new DeoptInt32x4FpuRegisterInstr(source_index); |
1149 case kPcMarker: return new DeoptPcMarkerInstr(source_index); | 1347 case kPcMarker: return new DeoptPcMarkerInstr(source_index); |
1150 case kPp: return new DeoptPpInstr(source_index); | 1348 case kPp: return new DeoptPpInstr(source_index); |
1151 case kCallerFp: return new DeoptCallerFpInstr(); | 1349 case kCallerFp: return new DeoptCallerFpInstr(); |
1152 case kCallerPp: return new DeoptCallerPpInstr(); | 1350 case kCallerPp: return new DeoptCallerPpInstr(); |
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1264 DeoptInstr* deopt_instr = NULL; | 1462 DeoptInstr* deopt_instr = NULL; |
1265 if (source_loc.IsConstant()) { | 1463 if (source_loc.IsConstant()) { |
1266 intptr_t object_table_index = FindOrAddObjectInTable(source_loc.constant()); | 1464 intptr_t object_table_index = FindOrAddObjectInTable(source_loc.constant()); |
1267 deopt_instr = new DeoptConstantInstr(object_table_index); | 1465 deopt_instr = new DeoptConstantInstr(object_table_index); |
1268 } else if (source_loc.IsRegister()) { | 1466 } else if (source_loc.IsRegister()) { |
1269 ASSERT(value->definition()->representation() == kTagged); | 1467 ASSERT(value->definition()->representation() == kTagged); |
1270 deopt_instr = new DeoptRegisterInstr(source_loc.reg()); | 1468 deopt_instr = new DeoptRegisterInstr(source_loc.reg()); |
1271 } else if (source_loc.IsFpuRegister()) { | 1469 } else if (source_loc.IsFpuRegister()) { |
1272 if (value->definition()->representation() == kUnboxedDouble) { | 1470 if (value->definition()->representation() == kUnboxedDouble) { |
1273 deopt_instr = new DeoptFpuRegisterInstr(source_loc.fpu_reg()); | 1471 deopt_instr = new DeoptFpuRegisterInstr(source_loc.fpu_reg()); |
1274 } else if (value->definition()->representation() == kUnboxedMint) { | |
1275 deopt_instr = new DeoptInt64FpuRegisterInstr(source_loc.fpu_reg()); | |
1276 } else if (value->definition()->representation() == kUnboxedFloat32x4) { | 1472 } else if (value->definition()->representation() == kUnboxedFloat32x4) { |
1277 deopt_instr = new DeoptFloat32x4FpuRegisterInstr(source_loc.fpu_reg()); | 1473 deopt_instr = new DeoptFloat32x4FpuRegisterInstr(source_loc.fpu_reg()); |
1278 } else if (value->definition()->representation() == kUnboxedInt32x4) { | 1474 } else if (value->definition()->representation() == kUnboxedInt32x4) { |
1279 deopt_instr = new DeoptInt32x4FpuRegisterInstr(source_loc.fpu_reg()); | 1475 deopt_instr = new DeoptInt32x4FpuRegisterInstr(source_loc.fpu_reg()); |
1280 } else { | 1476 } else { |
1281 ASSERT(value->definition()->representation() == kUnboxedFloat64x2); | 1477 ASSERT(value->definition()->representation() == kUnboxedFloat64x2); |
1282 deopt_instr = new DeoptFloat64x2FpuRegisterInstr(source_loc.fpu_reg()); | 1478 deopt_instr = new DeoptFloat64x2FpuRegisterInstr(source_loc.fpu_reg()); |
1283 } | 1479 } |
1284 } else if (source_loc.IsStackSlot()) { | 1480 } else if (source_loc.IsStackSlot()) { |
1285 ASSERT(value->definition()->representation() == kTagged); | 1481 ASSERT(value->definition()->representation() == kTagged); |
(...skipping 10 matching lines...) Expand all Loading... |
1296 } else if (source_loc.IsQuadStackSlot()) { | 1492 } else if (source_loc.IsQuadStackSlot()) { |
1297 intptr_t source_index = CalculateStackIndex(source_loc); | 1493 intptr_t source_index = CalculateStackIndex(source_loc); |
1298 if (value->definition()->representation() == kUnboxedFloat32x4) { | 1494 if (value->definition()->representation() == kUnboxedFloat32x4) { |
1299 deopt_instr = new DeoptFloat32x4StackSlotInstr(source_index); | 1495 deopt_instr = new DeoptFloat32x4StackSlotInstr(source_index); |
1300 } else if (value->definition()->representation() == kUnboxedInt32x4) { | 1496 } else if (value->definition()->representation() == kUnboxedInt32x4) { |
1301 deopt_instr = new DeoptInt32x4StackSlotInstr(source_index); | 1497 deopt_instr = new DeoptInt32x4StackSlotInstr(source_index); |
1302 } else { | 1498 } else { |
1303 ASSERT(value->definition()->representation() == kUnboxedFloat64x2); | 1499 ASSERT(value->definition()->representation() == kUnboxedFloat64x2); |
1304 deopt_instr = new DeoptFloat64x2StackSlotInstr(source_index); | 1500 deopt_instr = new DeoptFloat64x2StackSlotInstr(source_index); |
1305 } | 1501 } |
| 1502 } else if (source_loc.IsPairLocation()) { |
| 1503 ASSERT(value->definition()->representation() == kUnboxedMint); |
| 1504 // There are four cases to consider here: |
| 1505 // (R = Register, S = Stack slot). |
| 1506 // 1) R, R. |
| 1507 // 2) S, S. |
| 1508 // 3) R, S. |
| 1509 // 4) S, R. |
| 1510 PairLocation* pair = source_loc.AsPairLocation(); |
| 1511 if (pair->At(0).IsRegister() && pair->At(1).IsRegister()) { |
| 1512 deopt_instr = new DeoptInt64RegisterPairInstr(pair->At(0).reg(), |
| 1513 pair->At(1).reg()); |
| 1514 } else if (pair->At(0).IsStackSlot() && pair->At(1).IsStackSlot()) { |
| 1515 deopt_instr = new DeoptInt64StackSlotPairInstr( |
| 1516 CalculateStackIndex(pair->At(0)), |
| 1517 CalculateStackIndex(pair->At(1))); |
| 1518 } else if (pair->At(0).IsRegister() && pair->At(1).IsStackSlot()) { |
| 1519 deopt_instr = new DeoptInt64StackSlotRegisterInstr( |
| 1520 CalculateStackIndex(pair->At(1)), |
| 1521 pair->At(0).reg(), |
| 1522 true); |
| 1523 } else { |
| 1524 ASSERT(pair->At(0).IsStackSlot() && pair->At(1).IsRegister()); |
| 1525 deopt_instr = new DeoptInt64StackSlotRegisterInstr( |
| 1526 CalculateStackIndex(pair->At(0)), |
| 1527 pair->At(1).reg(), |
| 1528 false); |
| 1529 } |
1306 } else if (source_loc.IsInvalid() && | 1530 } else if (source_loc.IsInvalid() && |
1307 value->definition()->IsMaterializeObject()) { | 1531 value->definition()->IsMaterializeObject()) { |
1308 const intptr_t index = FindMaterialization( | 1532 const intptr_t index = FindMaterialization( |
1309 value->definition()->AsMaterializeObject()); | 1533 value->definition()->AsMaterializeObject()); |
1310 ASSERT(index >= 0); | 1534 ASSERT(index >= 0); |
1311 deopt_instr = new DeoptMaterializedObjectRefInstr(index); | 1535 deopt_instr = new DeoptMaterializedObjectRefInstr(index); |
1312 } else { | 1536 } else { |
1313 UNREACHABLE(); | 1537 UNREACHABLE(); |
1314 } | 1538 } |
1315 ASSERT(dest_index == FrameSize()); | 1539 ASSERT(dest_index == FrameSize()); |
(...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1478 Smi* offset, | 1702 Smi* offset, |
1479 DeoptInfo* info, | 1703 DeoptInfo* info, |
1480 Smi* reason) { | 1704 Smi* reason) { |
1481 intptr_t i = index * kEntrySize; | 1705 intptr_t i = index * kEntrySize; |
1482 *offset ^= table.At(i); | 1706 *offset ^= table.At(i); |
1483 *info ^= table.At(i + 1); | 1707 *info ^= table.At(i + 1); |
1484 *reason ^= table.At(i + 2); | 1708 *reason ^= table.At(i + 2); |
1485 } | 1709 } |
1486 | 1710 |
1487 } // namespace dart | 1711 } // namespace dart |
OLD | NEW |