| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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/globals.h" // Needed here to get TARGET_ARCH_X64. | 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_X64. |
| 6 #if defined(TARGET_ARCH_X64) | 6 #if defined(TARGET_ARCH_X64) |
| 7 | 7 |
| 8 #include "vm/intermediate_language.h" | 8 #include "vm/intermediate_language.h" |
| 9 | 9 |
| 10 #include "lib/error.h" | 10 #include "lib/error.h" |
| (...skipping 743 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 754 const intptr_t kNumInputs = 2; | 754 const intptr_t kNumInputs = 2; |
| 755 if (receiver_type() == kGrowableObjectArrayCid) { | 755 if (receiver_type() == kGrowableObjectArrayCid) { |
| 756 const intptr_t kNumTemps = 1; | 756 const intptr_t kNumTemps = 1; |
| 757 LocationSummary* locs = | 757 LocationSummary* locs = |
| 758 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 758 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 759 locs->set_in(0, Location::RequiresRegister()); | 759 locs->set_in(0, Location::RequiresRegister()); |
| 760 locs->set_in(1, Location::RequiresRegister()); | 760 locs->set_in(1, Location::RequiresRegister()); |
| 761 locs->set_temp(0, Location::RequiresRegister()); | 761 locs->set_temp(0, Location::RequiresRegister()); |
| 762 locs->set_out(Location::RequiresRegister()); | 762 locs->set_out(Location::RequiresRegister()); |
| 763 return locs; | 763 return locs; |
| 764 } else if ((receiver_type() == kArrayCid) || | 764 } else { |
| 765 (receiver_type() == kImmutableArrayCid)) { | 765 ASSERT((receiver_type() == kArrayCid) || |
| 766 (receiver_type() == kImmutableArrayCid)); |
| 766 return LocationSummary::Make(kNumInputs, | 767 return LocationSummary::Make(kNumInputs, |
| 767 Location::RequiresRegister(), | 768 Location::RequiresRegister(), |
| 768 LocationSummary::kNoCall); | 769 LocationSummary::kNoCall); |
| 769 } else { | |
| 770 ASSERT(receiver_type() == kIllegalCid); | |
| 771 return MakeCallSummary(); | |
| 772 } | 770 } |
| 773 } | 771 } |
| 774 | 772 |
| 775 | 773 |
| 776 static void EmitLoadIndexedPolymorphic(FlowGraphCompiler* compiler, | |
| 777 LoadIndexedComp* comp) { | |
| 778 Label* deopt = compiler->AddDeoptStub(comp->deopt_id(), | |
| 779 comp->try_index(), | |
| 780 kDeoptLoadIndexedPolymorphic); | |
| 781 ASSERT(comp->ic_data()->NumberOfChecks() > 0); | |
| 782 ASSERT(comp->HasICData()); | |
| 783 const ICData& ic_data = *comp->ic_data(); | |
| 784 ASSERT(ic_data.num_args_tested() == 1); | |
| 785 // No indexed access on Smi. | |
| 786 ASSERT(ic_data.GetReceiverClassIdAt(0) != kSmiCid); | |
| 787 // Load receiver into RAX. | |
| 788 const intptr_t kNumArguments = 2; | |
| 789 __ movq(RAX, Address(RSP, (kNumArguments - 1) * kWordSize)); | |
| 790 __ testq(RAX, Immediate(kSmiTagMask)); | |
| 791 __ j(ZERO, deopt); | |
| 792 __ LoadClassId(RDI, RAX); | |
| 793 compiler->EmitTestAndCall(ic_data, | |
| 794 RDI, // Class id register. | |
| 795 kNumArguments, | |
| 796 Array::Handle(), // No named arguments. | |
| 797 deopt, // Deoptimize target. | |
| 798 NULL, // Fallthrough when done. | |
| 799 comp->deopt_id(), | |
| 800 comp->token_pos(), | |
| 801 comp->try_index(), | |
| 802 comp->locs()->stack_bitmap()); | |
| 803 } | |
| 804 | |
| 805 | |
| 806 void LoadIndexedComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 774 void LoadIndexedComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 807 if (receiver_type() == kIllegalCid) { | |
| 808 if (HasICData() && (ic_data()->NumberOfChecks() > 0)) { | |
| 809 EmitLoadIndexedPolymorphic(compiler, this); | |
| 810 } else { | |
| 811 compiler->EmitLoadIndexedGeneric(this); | |
| 812 } | |
| 813 ASSERT(locs()->out().reg() == RAX); | |
| 814 return; | |
| 815 } | |
| 816 | |
| 817 Register receiver = locs()->in(0).reg(); | 775 Register receiver = locs()->in(0).reg(); |
| 818 Register index = locs()->in(1).reg(); | 776 Register index = locs()->in(1).reg(); |
| 819 Register result = locs()->out().reg(); | 777 Register result = locs()->out().reg(); |
| 820 | 778 |
| 821 const DeoptReasonId deopt_reason = | 779 const DeoptReasonId deopt_reason = |
| 822 (receiver_type() == kGrowableObjectArrayCid) ? | 780 (receiver_type() == kGrowableObjectArrayCid) ? |
| 823 kDeoptLoadIndexedGrowableArray : kDeoptLoadIndexedFixedArray; | 781 kDeoptLoadIndexedGrowableArray : kDeoptLoadIndexedFixedArray; |
| 824 | 782 |
| 825 Label* deopt = compiler->AddDeoptStub(deopt_id(), | 783 Label* deopt = compiler->AddDeoptStub(original()->deopt_id(), |
| 826 try_index(), | 784 original()->try_index(), |
| 827 deopt_reason, | 785 deopt_reason, |
| 828 receiver, | 786 receiver, |
| 829 index); | 787 index); |
| 830 | 788 |
| 831 __ testq(receiver, Immediate(kSmiTagMask)); // Deoptimize if Smi. | 789 __ testq(receiver, Immediate(kSmiTagMask)); // Deoptimize if Smi. |
| 832 __ j(ZERO, deopt); | 790 __ j(ZERO, deopt); |
| 833 __ CompareClassId(receiver, receiver_type()); | 791 __ CompareClassId(receiver, receiver_type()); |
| 834 __ j(NOT_EQUAL, deopt); | 792 __ j(NOT_EQUAL, deopt); |
| 835 | 793 |
| 836 __ testq(index, Immediate(kSmiTagMask)); | 794 __ testq(index, Immediate(kSmiTagMask)); |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 871 if (receiver_type() == kGrowableObjectArrayCid) { | 829 if (receiver_type() == kGrowableObjectArrayCid) { |
| 872 const intptr_t kNumTemps = 1; | 830 const intptr_t kNumTemps = 1; |
| 873 LocationSummary* locs = | 831 LocationSummary* locs = |
| 874 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 832 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 875 locs->set_in(0, Location::RequiresRegister()); | 833 locs->set_in(0, Location::RequiresRegister()); |
| 876 locs->set_in(1, Location::RequiresRegister()); | 834 locs->set_in(1, Location::RequiresRegister()); |
| 877 locs->set_in(2, Location::RequiresRegister()); | 835 locs->set_in(2, Location::RequiresRegister()); |
| 878 locs->set_temp(0, Location::RequiresRegister()); | 836 locs->set_temp(0, Location::RequiresRegister()); |
| 879 locs->set_out(Location::NoLocation()); | 837 locs->set_out(Location::NoLocation()); |
| 880 return locs; | 838 return locs; |
| 881 } else if (receiver_type() == kArrayCid) { | 839 } else { |
| 840 ASSERT(receiver_type() == kArrayCid); |
| 882 return LocationSummary::Make(kNumInputs, | 841 return LocationSummary::Make(kNumInputs, |
| 883 Location::NoLocation(), | 842 Location::NoLocation(), |
| 884 LocationSummary::kNoCall); | 843 LocationSummary::kNoCall); |
| 885 } else { | |
| 886 ASSERT(receiver_type() == kIllegalCid); | |
| 887 return MakeCallSummary(); | |
| 888 } | 844 } |
| 889 } | 845 } |
| 890 | 846 |
| 891 | 847 |
| 892 static void EmitStoreIndexedGeneric(FlowGraphCompiler* compiler, | |
| 893 StoreIndexedComp* comp) { | |
| 894 const String& function_name = | |
| 895 String::ZoneHandle(Symbols::New(Token::Str(Token::kASSIGN_INDEX))); | |
| 896 | |
| 897 compiler->AddCurrentDescriptor(PcDescriptors::kDeopt, | |
| 898 comp->deopt_id(), | |
| 899 comp->token_pos(), | |
| 900 comp->try_index()); | |
| 901 | |
| 902 const intptr_t kNumArguments = 3; | |
| 903 const intptr_t kNumArgsChecked = 1; // Type-feedback. | |
| 904 compiler->GenerateInstanceCall(comp->deopt_id(), | |
| 905 comp->token_pos(), | |
| 906 comp->try_index(), | |
| 907 function_name, | |
| 908 kNumArguments, | |
| 909 Array::ZoneHandle(), // No named arguments. | |
| 910 kNumArgsChecked, | |
| 911 comp->locs()->stack_bitmap()); | |
| 912 } | |
| 913 | |
| 914 | |
| 915 static void EmitStoreIndexedPolymorphic(FlowGraphCompiler* compiler, | |
| 916 StoreIndexedComp* comp) { | |
| 917 Label* deopt = compiler->AddDeoptStub(comp->deopt_id(), | |
| 918 comp->try_index(), | |
| 919 kDeoptStoreIndexedPolymorphic); | |
| 920 ASSERT(comp->ic_data()->NumberOfChecks() > 0); | |
| 921 ASSERT(comp->HasICData()); | |
| 922 const ICData& ic_data = *comp->ic_data(); | |
| 923 ASSERT(ic_data.num_args_tested() == 1); | |
| 924 // No indexed access on Smi. | |
| 925 ASSERT(ic_data.GetReceiverClassIdAt(0) != kSmiCid); | |
| 926 // Load receiver into RAX. | |
| 927 const intptr_t kNumArguments = 3; | |
| 928 __ movq(RAX, Address(RSP, (kNumArguments - 1) * kWordSize)); | |
| 929 __ testq(RAX, Immediate(kSmiTagMask)); | |
| 930 __ j(ZERO, deopt); | |
| 931 __ LoadClassId(RDI, RAX); | |
| 932 compiler->EmitTestAndCall(ic_data, | |
| 933 RDI, // Class id register. | |
| 934 kNumArguments, | |
| 935 Array::Handle(), // No named arguments. | |
| 936 deopt, // deoptimize label. | |
| 937 NULL, // fallthrough when done. | |
| 938 comp->deopt_id(), | |
| 939 comp->token_pos(), | |
| 940 comp->try_index(), | |
| 941 comp->locs()->stack_bitmap()); | |
| 942 } | |
| 943 | |
| 944 | |
| 945 void StoreIndexedComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 848 void StoreIndexedComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 946 if (receiver_type() == kIllegalCid) { | |
| 947 if (HasICData() && (ic_data()->NumberOfChecks() > 0)) { | |
| 948 EmitStoreIndexedPolymorphic(compiler, this); | |
| 949 } else { | |
| 950 EmitStoreIndexedGeneric(compiler, this); | |
| 951 } | |
| 952 return; | |
| 953 } | |
| 954 | |
| 955 Register receiver = locs()->in(0).reg(); | 849 Register receiver = locs()->in(0).reg(); |
| 956 Register index = locs()->in(1).reg(); | 850 Register index = locs()->in(1).reg(); |
| 957 Register value = locs()->in(2).reg(); | 851 Register value = locs()->in(2).reg(); |
| 958 | 852 |
| 959 Label* deopt = compiler->AddDeoptStub(deopt_id(), | 853 Label* deopt = compiler->AddDeoptStub(original()->deopt_id(), |
| 960 try_index(), | 854 original()->try_index(), |
| 961 kDeoptStoreIndexed, | 855 kDeoptStoreIndexed, |
| 962 receiver, | 856 receiver, |
| 963 index, | 857 index, |
| 964 value); | 858 value); |
| 965 | 859 |
| 966 __ testq(receiver, Immediate(kSmiTagMask)); // Deoptimize if Smi. | 860 __ testq(receiver, Immediate(kSmiTagMask)); // Deoptimize if Smi. |
| 967 __ j(ZERO, deopt); | 861 __ j(ZERO, deopt); |
| 968 __ CompareClassId(receiver, receiver_type()); | 862 __ CompareClassId(receiver, receiver_type()); |
| 969 __ j(NOT_EQUAL, deopt); | 863 __ j(NOT_EQUAL, deopt); |
| 970 | 864 |
| (...skipping 1239 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2210 locs()->stack_bitmap()); | 2104 locs()->stack_bitmap()); |
| 2211 __ CompareObject(RAX, compiler->bool_true()); | 2105 __ CompareObject(RAX, compiler->bool_true()); |
| 2212 EmitBranchOnCondition(compiler, branch_condition); | 2106 EmitBranchOnCondition(compiler, branch_condition); |
| 2213 } | 2107 } |
| 2214 | 2108 |
| 2215 } // namespace dart | 2109 } // namespace dart |
| 2216 | 2110 |
| 2217 #undef __ | 2111 #undef __ |
| 2218 | 2112 |
| 2219 #endif // defined TARGET_ARCH_X64 | 2113 #endif // defined TARGET_ARCH_X64 |
| OLD | NEW |