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 static int64_t CombineLoAndHi(int32_t* lo, int32_t* hi) { |
srdjan
2014/04/30 18:46:01
Use utils.h LowHighTo64Bits
Cutch
2014/05/21 17:00:03
Done.
| |
725 ASSERT(lo != NULL); | |
726 ASSERT(hi != NULL); | |
727 uint64_t lo64 = *reinterpret_cast<uint32_t*>(lo); | |
728 uint64_t hi64 = *reinterpret_cast<uint32_t*>(hi); | |
729 uint64_t value = (hi64 << 32) | lo64; | |
730 return *reinterpret_cast<int64_t*>(&value); | |
731 } | |
732 | |
733 class DeoptInt64RegisterPairInstr: public DeoptInstr { | |
723 public: | 734 public: |
724 explicit DeoptInt64FpuRegisterInstr(intptr_t reg_as_int) | 735 DeoptInt64RegisterPairInstr(intptr_t lo_reg_as_int, intptr_t hi_reg_as_int) |
725 : reg_(static_cast<FpuRegister>(reg_as_int)) {} | 736 : lo_reg_(static_cast<Register>(lo_reg_as_int)), |
737 hi_reg_(static_cast<Register>(hi_reg_as_int)) {} | |
srdjan
2014/04/30 18:46:01
Assert int values are valid registers
Cutch
2014/05/21 17:00:03
I have added asserts to the DeoptContext so that a
| |
726 | 738 |
727 virtual intptr_t source_index() const { return static_cast<intptr_t>(reg_); } | 739 virtual intptr_t source_index() const { |
728 virtual DeoptInstr::Kind kind() const { return kInt64FpuRegister; } | 740 return EncodeRegisters(static_cast<intptr_t>(lo_reg_), |
741 static_cast<intptr_t>(hi_reg_)); | |
742 } | |
743 virtual DeoptInstr::Kind kind() const { return kInt64RegisterPair; } | |
729 | 744 |
730 virtual const char* ToCString() const { | 745 virtual const char* ToCString() const { |
731 return Isolate::Current()->current_zone()->PrintToString( | 746 return Isolate::Current()->current_zone()->PrintToString( |
732 "%s(m)", Assembler::FpuRegisterName(reg_)); | 747 "int64 register pair: %s,%s", Assembler::RegisterName(hi_reg_), |
748 Assembler::RegisterName(lo_reg_)); | |
733 } | 749 } |
734 | 750 |
735 void Execute(DeoptContext* deopt_context, intptr_t* dest_addr) { | 751 void Execute(DeoptContext* deopt_context, intptr_t* dest_addr) { |
736 int64_t value = deopt_context->FpuRegisterValueAsInt64(reg_); | 752 int32_t lo_value = deopt_context->RegisterValue(lo_reg_); |
753 int32_t hi_value = deopt_context->RegisterValue(hi_reg_); | |
754 int64_t value = CombineLoAndHi(&lo_value, &hi_value); | |
737 *reinterpret_cast<RawSmi**>(dest_addr) = Smi::New(0); | 755 *reinterpret_cast<RawSmi**>(dest_addr) = Smi::New(0); |
738 if (Smi::IsValid64(value)) { | 756 if (Smi::IsValid64(value)) { |
739 *dest_addr = reinterpret_cast<intptr_t>( | 757 *dest_addr = reinterpret_cast<intptr_t>( |
740 Smi::New(static_cast<intptr_t>(value))); | 758 Smi::New(static_cast<intptr_t>(value))); |
741 } else { | 759 } else { |
742 deopt_context->DeferMintMaterialization( | 760 deopt_context->DeferMintMaterialization( |
743 value, reinterpret_cast<RawMint**>(dest_addr)); | 761 value, reinterpret_cast<RawMint**>(dest_addr)); |
744 } | 762 } |
745 } | 763 } |
746 | 764 |
765 static const intptr_t kFieldWidth = kBitsPerWord / 2; | |
766 class LoRegister : public BitField<intptr_t, 0, kFieldWidth> { }; | |
767 class HiRegister : public BitField<intptr_t, kFieldWidth, kFieldWidth> { }; | |
768 static intptr_t EncodeRegisters(intptr_t lo_reg_as_int, | |
769 intptr_t hi_reg_as_int) { | |
770 return LoRegister::encode(lo_reg_as_int) | | |
771 HiRegister::encode(hi_reg_as_int); | |
772 } | |
773 | |
774 static intptr_t DecodeLoRegister(intptr_t v) { | |
775 return LoRegister::decode(v); | |
776 } | |
777 | |
778 static intptr_t DecodeHiRegister(intptr_t v) { | |
779 return HiRegister::decode(v); | |
780 } | |
781 | |
747 private: | 782 private: |
748 const FpuRegister reg_; | 783 const Register lo_reg_; |
784 const Register hi_reg_; | |
749 | 785 |
750 DISALLOW_COPY_AND_ASSIGN(DeoptInt64FpuRegisterInstr); | 786 DISALLOW_COPY_AND_ASSIGN(DeoptInt64RegisterPairInstr); |
751 }; | 787 }; |
752 | 788 |
753 | 789 |
790 class DeoptInt64StackSlotPairInstr: public DeoptInstr { | |
791 public: | |
792 DeoptInt64StackSlotPairInstr(intptr_t lo_slot, intptr_t hi_slot) | |
793 : lo_slot_(static_cast<Register>(lo_slot)), | |
794 hi_slot_(static_cast<Register>(hi_slot)) {} | |
795 | |
796 virtual intptr_t source_index() const { | |
797 return EncodeSlots(static_cast<intptr_t>(lo_slot_), | |
798 static_cast<intptr_t>(hi_slot_)); | |
799 } | |
800 virtual DeoptInstr::Kind kind() const { return kInt64StackSlotPair; } | |
801 | |
802 virtual const char* ToCString() const { | |
803 return Isolate::Current()->current_zone()->PrintToString( | |
804 "int64 stack slots: %" Pd", %" Pd "", lo_slot_, hi_slot_); | |
805 } | |
806 | |
807 void Execute(DeoptContext* deopt_context, intptr_t* dest_addr) { | |
808 intptr_t lo_source_index = | |
809 deopt_context->source_frame_size() - lo_slot_ - 1; | |
810 int32_t* lo_source_addr = reinterpret_cast<int32_t*>( | |
811 deopt_context->GetSourceFrameAddressAt(lo_source_index)); | |
812 intptr_t hi_source_index = | |
813 deopt_context->source_frame_size() - hi_slot_ - 1; | |
814 int32_t* hi_source_addr = reinterpret_cast<int32_t*>( | |
815 deopt_context->GetSourceFrameAddressAt(hi_source_index)); | |
816 int64_t value = CombineLoAndHi(lo_source_addr, hi_source_addr); | |
817 *reinterpret_cast<RawSmi**>(dest_addr) = Smi::New(0); | |
818 if (Smi::IsValid64(value)) { | |
819 *dest_addr = reinterpret_cast<intptr_t>( | |
820 Smi::New(static_cast<intptr_t>(value))); | |
821 } else { | |
822 deopt_context->DeferMintMaterialization( | |
823 value, reinterpret_cast<RawMint**>(dest_addr)); | |
824 } | |
825 } | |
826 | |
827 static const intptr_t kFieldWidth = kBitsPerWord / 2; | |
828 class LoSlot : public BitField<intptr_t, 0, kFieldWidth> { }; | |
829 class HiSlot : public BitField<intptr_t, kFieldWidth, kFieldWidth> { }; | |
830 static intptr_t EncodeSlots(intptr_t lo_slot, | |
831 intptr_t hi_slot) { | |
832 return LoSlot::encode(lo_slot) | | |
833 HiSlot::encode(hi_slot); | |
834 } | |
835 | |
836 static intptr_t DecodeLoSlot(intptr_t v) { | |
837 return LoSlot::decode(v); | |
838 } | |
839 | |
840 static intptr_t DecodeHiSlot(intptr_t v) { | |
841 return HiSlot::decode(v); | |
842 } | |
843 | |
844 private: | |
845 const intptr_t lo_slot_; | |
846 const intptr_t hi_slot_; | |
847 | |
848 DISALLOW_COPY_AND_ASSIGN(DeoptInt64StackSlotPairInstr); | |
849 }; | |
850 | |
851 | |
852 class DeoptInt64StackSlotRegisterInstr : public DeoptInstr { | |
853 public: | |
854 DeoptInt64StackSlotRegisterInstr(intptr_t source_index, | |
855 intptr_t reg_as_int, | |
856 bool flip) | |
857 : slot_(source_index), | |
858 reg_(static_cast<Register>(reg_as_int)), | |
859 flip_(flip) { | |
srdjan
2014/04/30 18:46:01
ASSERT reg_as_int is a valid value.
Cutch
2014/05/21 17:00:03
As above, all accesses to registers in the deopt c
| |
860 // when flip_ is false, stack slot is low bits and reg is high bits. | |
861 // when flip_ is true, stack slot is high bits and reg is low bits. | |
862 } | |
863 | |
864 virtual intptr_t source_index() const { | |
865 return Encode(static_cast<intptr_t>(slot_), | |
866 static_cast<intptr_t>(reg_), | |
867 flip_ ? 1 : 0); | |
868 } | |
869 virtual DeoptInstr::Kind kind() const { return kInt64StackSlotRegister; } | |
870 | |
871 virtual const char* ToCString() const { | |
872 if (flip_) { | |
873 return Isolate::Current()->current_zone()->PrintToString( | |
874 "int64 reg: %s, stack slot: %" Pd "", Assembler::RegisterName(reg_), | |
875 slot_); | |
876 } else { | |
877 return Isolate::Current()->current_zone()->PrintToString( | |
878 "int64 stack slot: %" Pd", reg: %s", slot_, | |
879 Assembler::RegisterName(reg_)); | |
880 } | |
881 } | |
882 | |
883 void Execute(DeoptContext* deopt_context, intptr_t* dest_addr) { | |
884 intptr_t slot_source_index = | |
885 deopt_context->source_frame_size() - slot_ - 1; | |
886 int32_t* slot_source_addr = reinterpret_cast<int32_t*>( | |
887 deopt_context->GetSourceFrameAddressAt(slot_source_index)); | |
888 int32_t slot_value = *slot_source_addr; | |
889 int32_t reg_value = deopt_context->RegisterValue(reg_); | |
890 int64_t value; | |
891 if (flip_) { | |
892 value = CombineLoAndHi(®_value, &slot_value); | |
893 } else { | |
894 value = CombineLoAndHi(&slot_value, ®_value); | |
895 } | |
896 *reinterpret_cast<RawSmi**>(dest_addr) = Smi::New(0); | |
897 if (Smi::IsValid64(value)) { | |
898 *dest_addr = reinterpret_cast<intptr_t>( | |
899 Smi::New(static_cast<intptr_t>(value))); | |
900 } else { | |
901 deopt_context->DeferMintMaterialization( | |
902 value, reinterpret_cast<RawMint**>(dest_addr)); | |
903 } | |
904 } | |
905 | |
906 static const intptr_t kFieldWidth = kBitsPerWord / 2; | |
907 class Slot : public BitField<intptr_t, 0, kFieldWidth> { }; | |
908 class Reg : public BitField<intptr_t, kFieldWidth, kFieldWidth - 1> { }; | |
909 // 1 bit for the flip. | |
910 class Flip : public BitField<intptr_t, kFieldWidth * 2 - 1, 1> { }; | |
911 | |
912 static intptr_t Encode(intptr_t slot, | |
913 intptr_t reg_as_int, | |
914 bool flip) { | |
915 return Slot::encode(slot) | | |
916 Reg::encode(reg_as_int) | | |
917 Flip::encode(flip ? 1 : 0); | |
918 } | |
919 | |
920 static intptr_t DecodeSlot(intptr_t v) { | |
921 return Slot::decode(v); | |
922 } | |
923 | |
924 static intptr_t DecodeReg(intptr_t v) { | |
925 return Reg::decode(v); | |
926 } | |
927 | |
928 static bool DecodeFlip(intptr_t v) { | |
929 return Flip::decode(v); | |
930 } | |
931 | |
932 private: | |
933 const intptr_t slot_; | |
934 const Register reg_; | |
935 const bool flip_; | |
936 DISALLOW_COPY_AND_ASSIGN(DeoptInt64StackSlotRegisterInstr); | |
937 }; | |
938 | |
939 | |
754 // Deoptimization instruction moving an XMM register. | 940 // Deoptimization instruction moving an XMM register. |
755 class DeoptFloat32x4FpuRegisterInstr: public DeoptInstr { | 941 class DeoptFloat32x4FpuRegisterInstr: public DeoptInstr { |
756 public: | 942 public: |
757 explicit DeoptFloat32x4FpuRegisterInstr(intptr_t reg_as_int) | 943 explicit DeoptFloat32x4FpuRegisterInstr(intptr_t reg_as_int) |
758 : reg_(static_cast<FpuRegister>(reg_as_int)) {} | 944 : reg_(static_cast<FpuRegister>(reg_as_int)) {} |
759 | 945 |
760 virtual intptr_t source_index() const { return static_cast<intptr_t>(reg_); } | 946 virtual intptr_t source_index() const { return static_cast<intptr_t>(reg_); } |
761 virtual DeoptInstr::Kind kind() const { return kFloat32x4FpuRegister; } | 947 virtual DeoptInstr::Kind kind() const { return kFloat32x4FpuRegister; } |
762 | 948 |
763 virtual const char* ToCString() const { | 949 virtual const char* ToCString() const { |
(...skipping 368 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1132 case kFloat32x4StackSlot: | 1318 case kFloat32x4StackSlot: |
1133 return new DeoptFloat32x4StackSlotInstr(source_index); | 1319 return new DeoptFloat32x4StackSlotInstr(source_index); |
1134 case kFloat64x2StackSlot: | 1320 case kFloat64x2StackSlot: |
1135 return new DeoptFloat64x2StackSlotInstr(source_index); | 1321 return new DeoptFloat64x2StackSlotInstr(source_index); |
1136 case kInt32x4StackSlot: | 1322 case kInt32x4StackSlot: |
1137 return new DeoptInt32x4StackSlotInstr(source_index); | 1323 return new DeoptInt32x4StackSlotInstr(source_index); |
1138 case kRetAddress: return new DeoptRetAddressInstr(source_index); | 1324 case kRetAddress: return new DeoptRetAddressInstr(source_index); |
1139 case kConstant: return new DeoptConstantInstr(source_index); | 1325 case kConstant: return new DeoptConstantInstr(source_index); |
1140 case kRegister: return new DeoptRegisterInstr(source_index); | 1326 case kRegister: return new DeoptRegisterInstr(source_index); |
1141 case kFpuRegister: return new DeoptFpuRegisterInstr(source_index); | 1327 case kFpuRegister: return new DeoptFpuRegisterInstr(source_index); |
1142 case kInt64FpuRegister: return new DeoptInt64FpuRegisterInstr(source_index); | 1328 case kInt64RegisterPair: { |
1329 intptr_t lo_reg_as_int = | |
1330 DeoptInt64RegisterPairInstr::LoRegister::decode(source_index); | |
1331 intptr_t hi_reg_as_int = | |
1332 DeoptInt64RegisterPairInstr::HiRegister::decode(source_index); | |
1333 return new DeoptInt64RegisterPairInstr(lo_reg_as_int, hi_reg_as_int); | |
1334 } | |
1335 case kInt64StackSlotPair: { | |
1336 intptr_t lo_slot = | |
1337 DeoptInt64StackSlotPairInstr::LoSlot::decode(source_index); | |
1338 intptr_t hi_slot = | |
1339 DeoptInt64StackSlotPairInstr::HiSlot::decode(source_index); | |
1340 return new DeoptInt64StackSlotPairInstr(lo_slot, hi_slot); | |
1341 } | |
1342 case kInt64StackSlotRegister: { | |
1343 intptr_t slot = | |
1344 DeoptInt64StackSlotRegisterInstr::Slot::decode(source_index); | |
1345 intptr_t reg_as_int = | |
1346 DeoptInt64StackSlotRegisterInstr::Reg::decode(source_index); | |
1347 bool flip = DeoptInt64StackSlotRegisterInstr::Flip::decode(source_index); | |
1348 return new DeoptInt64StackSlotRegisterInstr(slot, reg_as_int, flip); | |
1349 } | |
1143 case kFloat32x4FpuRegister: | 1350 case kFloat32x4FpuRegister: |
1144 return new DeoptFloat32x4FpuRegisterInstr(source_index); | 1351 return new DeoptFloat32x4FpuRegisterInstr(source_index); |
1145 case kFloat64x2FpuRegister: | 1352 case kFloat64x2FpuRegister: |
1146 return new DeoptFloat64x2FpuRegisterInstr(source_index); | 1353 return new DeoptFloat64x2FpuRegisterInstr(source_index); |
1147 case kInt32x4FpuRegister: | 1354 case kInt32x4FpuRegister: |
1148 return new DeoptInt32x4FpuRegisterInstr(source_index); | 1355 return new DeoptInt32x4FpuRegisterInstr(source_index); |
1149 case kPcMarker: return new DeoptPcMarkerInstr(source_index); | 1356 case kPcMarker: return new DeoptPcMarkerInstr(source_index); |
1150 case kPp: return new DeoptPpInstr(source_index); | 1357 case kPp: return new DeoptPpInstr(source_index); |
1151 case kCallerFp: return new DeoptCallerFpInstr(); | 1358 case kCallerFp: return new DeoptCallerFpInstr(); |
1152 case kCallerPp: return new DeoptCallerPpInstr(); | 1359 case kCallerPp: return new DeoptCallerPpInstr(); |
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1264 DeoptInstr* deopt_instr = NULL; | 1471 DeoptInstr* deopt_instr = NULL; |
1265 if (source_loc.IsConstant()) { | 1472 if (source_loc.IsConstant()) { |
1266 intptr_t object_table_index = FindOrAddObjectInTable(source_loc.constant()); | 1473 intptr_t object_table_index = FindOrAddObjectInTable(source_loc.constant()); |
1267 deopt_instr = new DeoptConstantInstr(object_table_index); | 1474 deopt_instr = new DeoptConstantInstr(object_table_index); |
1268 } else if (source_loc.IsRegister()) { | 1475 } else if (source_loc.IsRegister()) { |
1269 ASSERT(value->definition()->representation() == kTagged); | 1476 ASSERT(value->definition()->representation() == kTagged); |
1270 deopt_instr = new DeoptRegisterInstr(source_loc.reg()); | 1477 deopt_instr = new DeoptRegisterInstr(source_loc.reg()); |
1271 } else if (source_loc.IsFpuRegister()) { | 1478 } else if (source_loc.IsFpuRegister()) { |
1272 if (value->definition()->representation() == kUnboxedDouble) { | 1479 if (value->definition()->representation() == kUnboxedDouble) { |
1273 deopt_instr = new DeoptFpuRegisterInstr(source_loc.fpu_reg()); | 1480 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) { | 1481 } else if (value->definition()->representation() == kUnboxedFloat32x4) { |
1277 deopt_instr = new DeoptFloat32x4FpuRegisterInstr(source_loc.fpu_reg()); | 1482 deopt_instr = new DeoptFloat32x4FpuRegisterInstr(source_loc.fpu_reg()); |
1278 } else if (value->definition()->representation() == kUnboxedInt32x4) { | 1483 } else if (value->definition()->representation() == kUnboxedInt32x4) { |
1279 deopt_instr = new DeoptInt32x4FpuRegisterInstr(source_loc.fpu_reg()); | 1484 deopt_instr = new DeoptInt32x4FpuRegisterInstr(source_loc.fpu_reg()); |
1280 } else { | 1485 } else { |
1281 ASSERT(value->definition()->representation() == kUnboxedFloat64x2); | 1486 ASSERT(value->definition()->representation() == kUnboxedFloat64x2); |
1282 deopt_instr = new DeoptFloat64x2FpuRegisterInstr(source_loc.fpu_reg()); | 1487 deopt_instr = new DeoptFloat64x2FpuRegisterInstr(source_loc.fpu_reg()); |
1283 } | 1488 } |
1284 } else if (source_loc.IsStackSlot()) { | 1489 } else if (source_loc.IsStackSlot()) { |
1285 ASSERT(value->definition()->representation() == kTagged); | 1490 ASSERT(value->definition()->representation() == kTagged); |
(...skipping 10 matching lines...) Expand all Loading... | |
1296 } else if (source_loc.IsQuadStackSlot()) { | 1501 } else if (source_loc.IsQuadStackSlot()) { |
1297 intptr_t source_index = CalculateStackIndex(source_loc); | 1502 intptr_t source_index = CalculateStackIndex(source_loc); |
1298 if (value->definition()->representation() == kUnboxedFloat32x4) { | 1503 if (value->definition()->representation() == kUnboxedFloat32x4) { |
1299 deopt_instr = new DeoptFloat32x4StackSlotInstr(source_index); | 1504 deopt_instr = new DeoptFloat32x4StackSlotInstr(source_index); |
1300 } else if (value->definition()->representation() == kUnboxedInt32x4) { | 1505 } else if (value->definition()->representation() == kUnboxedInt32x4) { |
1301 deopt_instr = new DeoptInt32x4StackSlotInstr(source_index); | 1506 deopt_instr = new DeoptInt32x4StackSlotInstr(source_index); |
1302 } else { | 1507 } else { |
1303 ASSERT(value->definition()->representation() == kUnboxedFloat64x2); | 1508 ASSERT(value->definition()->representation() == kUnboxedFloat64x2); |
1304 deopt_instr = new DeoptFloat64x2StackSlotInstr(source_index); | 1509 deopt_instr = new DeoptFloat64x2StackSlotInstr(source_index); |
1305 } | 1510 } |
1511 } else if (source_loc.IsPairLocation()) { | |
1512 ASSERT(value->definition()->representation() == kUnboxedMint); | |
1513 // There are four cases to consider here: | |
srdjan
2014/04/30 18:46:01
Say R: Register, S: Stack-slot
Cutch
2014/05/21 17:00:03
Done.
| |
1514 // 1) R, R. | |
1515 // 2) S, S. | |
1516 // 3) R, S. | |
1517 // 4) S, R. | |
1518 PairLocation* pair = source_loc.AsPairLocation(); | |
1519 if (pair->At(0).IsRegister() && pair->At(1).IsRegister()) { | |
1520 deopt_instr = new DeoptInt64RegisterPairInstr(pair->At(0).reg(), | |
1521 pair->At(1).reg()); | |
1522 } else if (pair->At(0).IsStackSlot() && pair->At(1).IsStackSlot()) { | |
1523 deopt_instr = new DeoptInt64StackSlotPairInstr( | |
1524 CalculateStackIndex(pair->At(0)), | |
1525 CalculateStackIndex(pair->At(1))); | |
1526 } else if (pair->At(0).IsRegister() && pair->At(1).IsStackSlot()) { | |
1527 deopt_instr = new DeoptInt64StackSlotRegisterInstr( | |
1528 CalculateStackIndex(pair->At(1)), | |
1529 pair->At(0).reg(), | |
1530 true); | |
1531 } else { | |
1532 ASSERT(pair->At(0).IsStackSlot() && pair->At(1).IsRegister()); | |
1533 deopt_instr = new DeoptInt64StackSlotRegisterInstr( | |
1534 CalculateStackIndex(pair->At(0)), | |
1535 pair->At(1).reg(), | |
1536 false); | |
1537 } | |
1306 } else if (source_loc.IsInvalid() && | 1538 } else if (source_loc.IsInvalid() && |
1307 value->definition()->IsMaterializeObject()) { | 1539 value->definition()->IsMaterializeObject()) { |
1308 const intptr_t index = FindMaterialization( | 1540 const intptr_t index = FindMaterialization( |
1309 value->definition()->AsMaterializeObject()); | 1541 value->definition()->AsMaterializeObject()); |
1310 ASSERT(index >= 0); | 1542 ASSERT(index >= 0); |
1311 deopt_instr = new DeoptMaterializedObjectRefInstr(index); | 1543 deopt_instr = new DeoptMaterializedObjectRefInstr(index); |
1312 } else { | 1544 } else { |
1313 UNREACHABLE(); | 1545 UNREACHABLE(); |
1314 } | 1546 } |
1315 ASSERT(dest_index == FrameSize()); | 1547 ASSERT(dest_index == FrameSize()); |
(...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1478 Smi* offset, | 1710 Smi* offset, |
1479 DeoptInfo* info, | 1711 DeoptInfo* info, |
1480 Smi* reason) { | 1712 Smi* reason) { |
1481 intptr_t i = index * kEntrySize; | 1713 intptr_t i = index * kEntrySize; |
1482 *offset ^= table.At(i); | 1714 *offset ^= table.At(i); |
1483 *info ^= table.At(i + 1); | 1715 *info ^= table.At(i + 1); |
1484 *reason ^= table.At(i + 2); | 1716 *reason ^= table.At(i + 2); |
1485 } | 1717 } |
1486 | 1718 |
1487 } // namespace dart | 1719 } // namespace dart |
OLD | NEW |