Chromium Code Reviews| 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 |