| 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_IA32. | 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_IA32. |
| 6 #if defined(TARGET_ARCH_IA32) | 6 #if defined(TARGET_ARCH_IA32) |
| 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 723 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 734 compiler->GenerateCall(token_pos(), | 734 compiler->GenerateCall(token_pos(), |
| 735 try_index(), | 735 try_index(), |
| 736 &StubCode::CallNativeCFunctionLabel(), | 736 &StubCode::CallNativeCFunctionLabel(), |
| 737 PcDescriptors::kOther, | 737 PcDescriptors::kOther, |
| 738 locs()->stack_bitmap()); | 738 locs()->stack_bitmap()); |
| 739 __ popl(result); | 739 __ popl(result); |
| 740 } | 740 } |
| 741 | 741 |
| 742 | 742 |
| 743 LocationSummary* LoadIndexedComp::MakeLocationSummary() const { | 743 LocationSummary* LoadIndexedComp::MakeLocationSummary() const { |
| 744 ASSERT((receiver_type() == kGrowableObjectArrayCid) || |
| 745 (receiver_type() == kArrayCid) || |
| 746 (receiver_type() == kImmutableArrayCid)); |
| 744 const intptr_t kNumInputs = 2; | 747 const intptr_t kNumInputs = 2; |
| 745 if ((receiver_type() == kGrowableObjectArrayCid) || | 748 const intptr_t kNumTemps = 1; |
| 746 (receiver_type() == kArrayCid) || | 749 LocationSummary* locs = |
| 747 (receiver_type() == kImmutableArrayCid)) { | 750 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 748 const intptr_t kNumTemps = 1; | 751 locs->set_in(0, Location::RequiresRegister()); |
| 749 LocationSummary* locs = | 752 locs->set_in(1, Location::RequiresRegister()); |
| 750 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 753 locs->set_temp(0, Location::RequiresRegister()); |
| 751 locs->set_in(0, Location::RequiresRegister()); | 754 locs->set_out(Location::RequiresRegister()); |
| 752 locs->set_in(1, Location::RequiresRegister()); | 755 return locs; |
| 753 locs->set_temp(0, Location::RequiresRegister()); | |
| 754 locs->set_out(Location::RequiresRegister()); | |
| 755 return locs; | |
| 756 } else { | |
| 757 ASSERT(receiver_type() == kIllegalCid); | |
| 758 return MakeCallSummary(); | |
| 759 } | |
| 760 } | |
| 761 | |
| 762 | |
| 763 static void EmitLoadIndexedPolymorphic(FlowGraphCompiler* compiler, | |
| 764 LoadIndexedComp* comp) { | |
| 765 Label* deopt = compiler->AddDeoptStub(comp->deopt_id(), | |
| 766 comp->try_index(), | |
| 767 kDeoptLoadIndexedPolymorphic); | |
| 768 ASSERT(comp->ic_data()->NumberOfChecks() > 0); | |
| 769 ASSERT(comp->HasICData()); | |
| 770 const ICData& ic_data = *comp->ic_data(); | |
| 771 ASSERT(ic_data.num_args_tested() == 1); | |
| 772 // No indexed access on Smi. | |
| 773 ASSERT(ic_data.GetReceiverClassIdAt(0) != kSmiCid); | |
| 774 // Load receiver into EAX. | |
| 775 const intptr_t kNumArguments = 2; | |
| 776 __ movl(EAX, Address(ESP, (kNumArguments - 1) * kWordSize)); | |
| 777 __ testl(EAX, Immediate(kSmiTagMask)); | |
| 778 __ j(ZERO, deopt); | |
| 779 __ LoadClassId(EDI, EAX); | |
| 780 compiler->EmitTestAndCall(ic_data, | |
| 781 EDI, // Class id register. | |
| 782 kNumArguments, | |
| 783 Array::Handle(), // No named arguments. | |
| 784 deopt, // Deoptimize target. | |
| 785 NULL, // Fallthrough when done. | |
| 786 comp->deopt_id(), | |
| 787 comp->token_pos(), | |
| 788 comp->try_index(), | |
| 789 comp->locs()->stack_bitmap()); | |
| 790 } | 756 } |
| 791 | 757 |
| 792 | 758 |
| 793 void LoadIndexedComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 759 void LoadIndexedComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 794 if (receiver_type() == kIllegalCid) { | |
| 795 if (HasICData() && (ic_data()->NumberOfChecks() > 0)) { | |
| 796 EmitLoadIndexedPolymorphic(compiler, this); | |
| 797 } else { | |
| 798 compiler->EmitLoadIndexedGeneric(this); | |
| 799 } | |
| 800 ASSERT(locs()->out().reg() == EAX); | |
| 801 return; | |
| 802 } | |
| 803 | |
| 804 Register receiver = locs()->in(0).reg(); | 760 Register receiver = locs()->in(0).reg(); |
| 805 Register index = locs()->in(1).reg(); | 761 Register index = locs()->in(1).reg(); |
| 806 Register result = locs()->out().reg(); | 762 Register result = locs()->out().reg(); |
| 807 Register temp = locs()->temp(0).reg(); | 763 Register temp = locs()->temp(0).reg(); |
| 808 | 764 |
| 809 const DeoptReasonId deopt_reason = | 765 const DeoptReasonId deopt_reason = |
| 810 (receiver_type() == kGrowableObjectArrayCid) ? | 766 (receiver_type() == kGrowableObjectArrayCid) ? |
| 811 kDeoptLoadIndexedGrowableArray : kDeoptLoadIndexedFixedArray; | 767 kDeoptLoadIndexedGrowableArray : kDeoptLoadIndexedFixedArray; |
| 812 | 768 |
| 813 Label* deopt = compiler->AddDeoptStub(deopt_id(), | 769 Label* deopt = compiler->AddDeoptStub(original()->deopt_id(), |
| 814 try_index(), | 770 original()->try_index(), |
| 815 deopt_reason, | 771 deopt_reason, |
| 816 receiver, | 772 receiver, |
| 817 index); | 773 index); |
| 818 | 774 |
| 819 __ testl(receiver, Immediate(kSmiTagMask)); // Deoptimize if Smi. | 775 __ testl(receiver, Immediate(kSmiTagMask)); // Deoptimize if Smi. |
| 820 __ j(ZERO, deopt); | 776 __ j(ZERO, deopt); |
| 821 __ CompareClassId(receiver, receiver_type(), temp); | 777 __ CompareClassId(receiver, receiver_type(), temp); |
| 822 __ j(NOT_EQUAL, deopt); | 778 __ j(NOT_EQUAL, deopt); |
| 823 | 779 |
| 824 __ testl(index, Immediate(kSmiTagMask)); | 780 __ testl(index, Immediate(kSmiTagMask)); |
| (...skipping 23 matching lines...) Expand all Loading... |
| 848 } | 804 } |
| 849 | 805 |
| 850 default: | 806 default: |
| 851 UNREACHABLE(); | 807 UNREACHABLE(); |
| 852 break; | 808 break; |
| 853 } | 809 } |
| 854 } | 810 } |
| 855 | 811 |
| 856 | 812 |
| 857 LocationSummary* StoreIndexedComp::MakeLocationSummary() const { | 813 LocationSummary* StoreIndexedComp::MakeLocationSummary() const { |
| 814 ASSERT((receiver_type() == kGrowableObjectArrayCid) || |
| 815 (receiver_type() == kArrayCid)); |
| 858 const intptr_t kNumInputs = 3; | 816 const intptr_t kNumInputs = 3; |
| 859 if ((receiver_type() == kGrowableObjectArrayCid) || | 817 const intptr_t kNumTemps = 1; |
| 860 (receiver_type() == kArrayCid)) { | 818 LocationSummary* locs = |
| 861 const intptr_t kNumTemps = 1; | 819 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 862 LocationSummary* locs = | 820 locs->set_in(0, Location::RequiresRegister()); |
| 863 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 821 locs->set_in(1, Location::RequiresRegister()); |
| 864 locs->set_in(0, Location::RequiresRegister()); | 822 locs->set_in(2, Location::RequiresRegister()); |
| 865 locs->set_in(1, Location::RequiresRegister()); | 823 locs->set_temp(0, Location::RequiresRegister()); |
| 866 locs->set_in(2, Location::RequiresRegister()); | 824 locs->set_out(Location::NoLocation()); |
| 867 locs->set_temp(0, Location::RequiresRegister()); | 825 return locs; |
| 868 locs->set_out(Location::NoLocation()); | |
| 869 return locs; | |
| 870 } else { | |
| 871 ASSERT(receiver_type() == kIllegalCid); | |
| 872 return MakeCallSummary(); | |
| 873 } | |
| 874 } | |
| 875 | |
| 876 | |
| 877 static void EmitStoreIndexedGeneric(FlowGraphCompiler* compiler, | |
| 878 StoreIndexedComp* comp) { | |
| 879 const String& function_name = | |
| 880 String::ZoneHandle(Symbols::New(Token::Str(Token::kASSIGN_INDEX))); | |
| 881 | |
| 882 compiler->AddCurrentDescriptor(PcDescriptors::kDeopt, | |
| 883 comp->deopt_id(), | |
| 884 comp->token_pos(), | |
| 885 comp->try_index()); | |
| 886 | |
| 887 const intptr_t kNumArguments = 3; | |
| 888 const intptr_t kNumArgsChecked = 1; // Type-feedback. | |
| 889 compiler->GenerateInstanceCall(comp->deopt_id(), | |
| 890 comp->token_pos(), | |
| 891 comp->try_index(), | |
| 892 function_name, | |
| 893 kNumArguments, | |
| 894 Array::ZoneHandle(), // No named arguments. | |
| 895 kNumArgsChecked, | |
| 896 comp->locs()->stack_bitmap()); | |
| 897 } | |
| 898 | |
| 899 | |
| 900 static void EmitStoreIndexedPolymorphic(FlowGraphCompiler* compiler, | |
| 901 StoreIndexedComp* comp) { | |
| 902 Label* deopt = compiler->AddDeoptStub(comp->deopt_id(), | |
| 903 comp->try_index(), | |
| 904 kDeoptStoreIndexedPolymorphic); | |
| 905 ASSERT(comp->ic_data()->NumberOfChecks() > 0); | |
| 906 ASSERT(comp->HasICData()); | |
| 907 const ICData& ic_data = *comp->ic_data(); | |
| 908 ASSERT(ic_data.num_args_tested() == 1); | |
| 909 // No indexed access on Smi. | |
| 910 ASSERT(ic_data.GetReceiverClassIdAt(0) != kSmiCid); | |
| 911 // Load receiver into EAX. | |
| 912 const intptr_t kNumArguments = 3; | |
| 913 __ movl(EAX, Address(ESP, (kNumArguments - 1) * kWordSize)); | |
| 914 __ testl(EAX, Immediate(kSmiTagMask)); | |
| 915 __ j(ZERO, deopt); | |
| 916 __ LoadClassId(EDI, EAX); | |
| 917 compiler->EmitTestAndCall(ic_data, | |
| 918 EDI, // Class id register. | |
| 919 kNumArguments, | |
| 920 Array::Handle(), // No named arguments. | |
| 921 deopt, // Deoptimize target. | |
| 922 NULL, // Fallthrough when done. | |
| 923 comp->deopt_id(), | |
| 924 comp->token_pos(), | |
| 925 comp->try_index(), | |
| 926 comp->locs()->stack_bitmap()); | |
| 927 } | 826 } |
| 928 | 827 |
| 929 | 828 |
| 930 void StoreIndexedComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 829 void StoreIndexedComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 931 if (receiver_type() == kIllegalCid) { | |
| 932 if (HasICData() && (ic_data()->NumberOfChecks() > 0)) { | |
| 933 EmitStoreIndexedPolymorphic(compiler, this); | |
| 934 } else { | |
| 935 EmitStoreIndexedGeneric(compiler, this); | |
| 936 } | |
| 937 return; | |
| 938 } | |
| 939 | |
| 940 Register receiver = locs()->in(0).reg(); | 830 Register receiver = locs()->in(0).reg(); |
| 941 Register index = locs()->in(1).reg(); | 831 Register index = locs()->in(1).reg(); |
| 942 Register value = locs()->in(2).reg(); | 832 Register value = locs()->in(2).reg(); |
| 943 Register temp = locs()->temp(0).reg(); | 833 Register temp = locs()->temp(0).reg(); |
| 944 | 834 |
| 945 Label* deopt = compiler->AddDeoptStub(deopt_id(), | 835 Label* deopt = compiler->AddDeoptStub(original()->deopt_id(), |
| 946 try_index(), | 836 original()->try_index(), |
| 947 kDeoptStoreIndexed, | 837 kDeoptStoreIndexed, |
| 948 receiver, | 838 receiver, |
| 949 index, | 839 index, |
| 950 value); | 840 value); |
| 951 | 841 |
| 952 __ testl(receiver, Immediate(kSmiTagMask)); // Deoptimize if Smi. | 842 __ testl(receiver, Immediate(kSmiTagMask)); // Deoptimize if Smi. |
| 953 __ j(ZERO, deopt); | 843 __ j(ZERO, deopt); |
| 954 __ CompareClassId(receiver, receiver_type(), temp); | 844 __ CompareClassId(receiver, receiver_type(), temp); |
| 955 __ j(NOT_EQUAL, deopt); | 845 __ j(NOT_EQUAL, deopt); |
| 956 | 846 |
| (...skipping 1246 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2203 locs()->stack_bitmap()); | 2093 locs()->stack_bitmap()); |
| 2204 __ CompareObject(EAX, compiler->bool_true()); | 2094 __ CompareObject(EAX, compiler->bool_true()); |
| 2205 EmitBranchOnCondition(compiler, branch_condition); | 2095 EmitBranchOnCondition(compiler, branch_condition); |
| 2206 } | 2096 } |
| 2207 | 2097 |
| 2208 } // namespace dart | 2098 } // namespace dart |
| 2209 | 2099 |
| 2210 #undef __ | 2100 #undef __ |
| 2211 | 2101 |
| 2212 #endif // defined TARGET_ARCH_X64 | 2102 #endif // defined TARGET_ARCH_X64 |
| OLD | NEW |