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