| 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 902 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 913 __ testq(index, Immediate(kSmiTagMask)); | 913 __ testq(index, Immediate(kSmiTagMask)); |
| 914 __ j(NOT_ZERO, deopt); | 914 __ j(NOT_ZERO, deopt); |
| 915 | 915 |
| 916 switch (receiver_type()) { | 916 switch (receiver_type()) { |
| 917 case kArrayCid: | 917 case kArrayCid: |
| 918 case kImmutableArrayCid: | 918 case kImmutableArrayCid: |
| 919 __ cmpq(index, FieldAddress(receiver, Array::length_offset())); | 919 __ cmpq(index, FieldAddress(receiver, Array::length_offset())); |
| 920 __ j(ABOVE_EQUAL, deopt); | 920 __ j(ABOVE_EQUAL, deopt); |
| 921 // Note that index is Smi, i.e, times 4. | 921 // Note that index is Smi, i.e, times 4. |
| 922 ASSERT(kSmiTagShift == 1); | 922 ASSERT(kSmiTagShift == 1); |
| 923 __ StoreIntoObject(receiver, | 923 if (this->value()->BindsToConstant()) { |
| 924 FieldAddress(receiver, index, TIMES_4, sizeof(RawArray)), | 924 // Compile time constants are Smi or allocated in the old space. |
| 925 value); | 925 __ movq(FieldAddress(receiver, index, TIMES_4, sizeof(RawArray)), |
| 926 value); |
| 927 } else { |
| 928 __ StoreIntoObject(receiver, |
| 929 FieldAddress(receiver, index, TIMES_4, sizeof(RawArray)), |
| 930 value); |
| 931 } |
| 926 break; | 932 break; |
| 927 | 933 |
| 928 case kGrowableObjectArrayCid: { | 934 case kGrowableObjectArrayCid: { |
| 929 Register temp = locs()->temp(0).reg(); | 935 Register temp = locs()->temp(0).reg(); |
| 930 __ cmpq(index, | 936 __ cmpq(index, |
| 931 FieldAddress(receiver, GrowableObjectArray::length_offset())); | 937 FieldAddress(receiver, GrowableObjectArray::length_offset())); |
| 932 __ j(ABOVE_EQUAL, deopt); | 938 __ j(ABOVE_EQUAL, deopt); |
| 933 __ movq(temp, FieldAddress(receiver, GrowableObjectArray::data_offset())); | 939 __ movq(temp, FieldAddress(receiver, GrowableObjectArray::data_offset())); |
| 934 // Note that index is Smi, i.e, times 4. | 940 // Note that index is Smi, i.e, times 4. |
| 935 ASSERT(kSmiTagShift == 1); | 941 ASSERT(kSmiTagShift == 1); |
| 936 __ StoreIntoObject(temp, | 942 if (this->value()->BindsToConstant()) { |
| 937 FieldAddress(temp, index, TIMES_4, sizeof(RawArray)), | 943 // Compile time constants are Smi or allocated in the old space. |
| 938 value); | 944 __ movq(FieldAddress(temp, index, TIMES_4, sizeof(RawArray)), |
| 945 value); |
| 946 } else { |
| 947 __ StoreIntoObject(temp, |
| 948 FieldAddress(temp, index, TIMES_4, sizeof(RawArray)), |
| 949 value); |
| 950 } |
| 939 break; | 951 break; |
| 940 } | 952 } |
| 941 | 953 |
| 942 default: | 954 default: |
| 943 UNREACHABLE(); | 955 UNREACHABLE(); |
| 944 break; | 956 break; |
| 945 } | 957 } |
| 946 } | 958 } |
| 947 | 959 |
| 948 | 960 |
| (...skipping 20 matching lines...) Expand all Loading... |
| 969 // Smis do not have instance fields (Smi class is always first). | 981 // Smis do not have instance fields (Smi class is always first). |
| 970 // Use 'result' as temporary register. | 982 // Use 'result' as temporary register. |
| 971 ASSERT(result_reg != instance_reg); | 983 ASSERT(result_reg != instance_reg); |
| 972 ASSERT(ic_data() != NULL); | 984 ASSERT(ic_data() != NULL); |
| 973 compiler->EmitClassChecksNoSmi(*ic_data(), instance_reg, result_reg, deopt); | 985 compiler->EmitClassChecksNoSmi(*ic_data(), instance_reg, result_reg, deopt); |
| 974 } | 986 } |
| 975 __ movq(result_reg, FieldAddress(instance_reg, field().Offset())); | 987 __ movq(result_reg, FieldAddress(instance_reg, field().Offset())); |
| 976 } | 988 } |
| 977 | 989 |
| 978 | 990 |
| 991 LocationSummary* StoreInstanceFieldComp::MakeLocationSummary() const { |
| 992 const intptr_t kNumInputs = 2; |
| 993 const intptr_t num_temps = HasICData() ? 1 : 0; |
| 994 LocationSummary* summary = |
| 995 new LocationSummary(kNumInputs, num_temps, LocationSummary::kNoCall); |
| 996 summary->set_in(0, Location::RequiresRegister()); |
| 997 summary->set_in(1, Location::RequiresRegister()); |
| 998 if (HasICData()) { |
| 999 summary->set_temp(0, Location::RequiresRegister()); |
| 1000 } |
| 1001 return summary; |
| 1002 } |
| 1003 |
| 1004 |
| 1005 void StoreInstanceFieldComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 1006 Register instance_reg = locs()->in(0).reg(); |
| 1007 Register value_reg = locs()->in(1).reg(); |
| 1008 |
| 1009 if (HasICData()) { |
| 1010 ASSERT(original() != NULL); |
| 1011 Label* deopt = compiler->AddDeoptStub(original()->deopt_id(), |
| 1012 original()->try_index(), |
| 1013 kDeoptInstanceGetterSameTarget); |
| 1014 // Smis do not have instance fields (Smi class is always first). |
| 1015 Register temp_reg = locs()->temp(0).reg(); |
| 1016 ASSERT(temp_reg != instance_reg); |
| 1017 ASSERT(temp_reg != value_reg); |
| 1018 ASSERT(ic_data() != NULL); |
| 1019 compiler->EmitClassChecksNoSmi(*ic_data(), instance_reg, temp_reg, deopt); |
| 1020 } |
| 1021 if (this->value()->BindsToConstant()) { |
| 1022 // Compile time constants are Smi or allocated in the old space. |
| 1023 __ movq(FieldAddress(instance_reg, field().Offset()), value_reg); |
| 1024 } else { |
| 1025 __ StoreIntoObject(instance_reg, |
| 1026 FieldAddress(instance_reg, field().Offset()), value_reg); |
| 1027 } |
| 1028 } |
| 1029 |
| 1030 |
| 979 LocationSummary* LoadStaticFieldComp::MakeLocationSummary() const { | 1031 LocationSummary* LoadStaticFieldComp::MakeLocationSummary() const { |
| 980 return LocationSummary::Make(0, | 1032 return LocationSummary::Make(0, |
| 981 Location::RequiresRegister(), | 1033 Location::RequiresRegister(), |
| 982 LocationSummary::kNoCall); | 1034 LocationSummary::kNoCall); |
| 983 } | 1035 } |
| 984 | 1036 |
| 985 | 1037 |
| 986 void LoadStaticFieldComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 1038 void LoadStaticFieldComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 987 Register result = locs()->out().reg(); | 1039 Register result = locs()->out().reg(); |
| 988 __ LoadObject(result, field()); | 1040 __ LoadObject(result, field()); |
| 989 __ movq(result, FieldAddress(result, Field::value_offset())); | 1041 __ movq(result, FieldAddress(result, Field::value_offset())); |
| 990 } | 1042 } |
| 991 | 1043 |
| 992 | 1044 |
| 1045 LocationSummary* StoreStaticFieldComp::MakeLocationSummary() const { |
| 1046 LocationSummary* locs = new LocationSummary(1, 1, LocationSummary::kNoCall); |
| 1047 locs->set_in(0, Location::RequiresRegister()); |
| 1048 locs->set_temp(0, Location::RequiresRegister()); |
| 1049 locs->set_out(Location::SameAsFirstInput()); |
| 1050 return locs; |
| 1051 } |
| 1052 |
| 1053 |
| 1054 void StoreStaticFieldComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 1055 Register value = locs()->in(0).reg(); |
| 1056 Register temp = locs()->temp(0).reg(); |
| 1057 ASSERT(locs()->out().reg() == value); |
| 1058 |
| 1059 __ LoadObject(temp, field()); |
| 1060 if (this->value()->BindsToConstant()) { |
| 1061 // Compile time constants are Smi or allocated in the old space. |
| 1062 __ movq(FieldAddress(temp, Field::value_offset()), value); |
| 1063 } else { |
| 1064 __ StoreIntoObject(temp, FieldAddress(temp, Field::value_offset()), value); |
| 1065 } |
| 1066 } |
| 1067 |
| 1068 |
| 993 LocationSummary* InstanceOfComp::MakeLocationSummary() const { | 1069 LocationSummary* InstanceOfComp::MakeLocationSummary() const { |
| 994 const intptr_t kNumInputs = 3; | 1070 const intptr_t kNumInputs = 3; |
| 995 const intptr_t kNumTemps = 0; | 1071 const intptr_t kNumTemps = 0; |
| 996 LocationSummary* summary = | 1072 LocationSummary* summary = |
| 997 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); | 1073 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); |
| 998 summary->set_in(0, Location::RegisterLocation(RAX)); | 1074 summary->set_in(0, Location::RegisterLocation(RAX)); |
| 999 summary->set_in(1, Location::RegisterLocation(RCX)); | 1075 summary->set_in(1, Location::RegisterLocation(RCX)); |
| 1000 summary->set_in(2, Location::RegisterLocation(RDX)); | 1076 summary->set_in(2, Location::RegisterLocation(RDX)); |
| 1001 summary->set_out(Location::RegisterLocation(RAX)); | 1077 summary->set_out(Location::RegisterLocation(RAX)); |
| 1002 return summary; | 1078 return summary; |
| (...skipping 1363 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2366 __ testq(value, Immediate(kSmiTagMask)); | 2442 __ testq(value, Immediate(kSmiTagMask)); |
| 2367 __ j(NOT_ZERO, deopt); | 2443 __ j(NOT_ZERO, deopt); |
| 2368 } | 2444 } |
| 2369 | 2445 |
| 2370 | 2446 |
| 2371 } // namespace dart | 2447 } // namespace dart |
| 2372 | 2448 |
| 2373 #undef __ | 2449 #undef __ |
| 2374 | 2450 |
| 2375 #endif // defined TARGET_ARCH_X64 | 2451 #endif // defined TARGET_ARCH_X64 |
| OLD | NEW |