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