| 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/intermediate_language.h" | 5 #include "vm/intermediate_language.h" |
| 6 | 6 |
| 7 #include "vm/bit_vector.h" | 7 #include "vm/bit_vector.h" |
| 8 #include "vm/flow_graph_builder.h" | 8 #include "vm/flow_graph_builder.h" |
| 9 #include "vm/flow_graph_compiler.h" | 9 #include "vm/flow_graph_compiler.h" |
| 10 #include "vm/locations.h" | 10 #include "vm/locations.h" |
| (...skipping 911 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 922 | 922 |
| 923 | 923 |
| 924 void StoreInstanceFieldComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 924 void StoreInstanceFieldComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 925 ASSERT(VerifyValues(instance(), value())); | 925 ASSERT(VerifyValues(instance(), value())); |
| 926 Register instance_reg = locs()->in(0).reg(); | 926 Register instance_reg = locs()->in(0).reg(); |
| 927 Register value_reg = locs()->in(1).reg(); | 927 Register value_reg = locs()->in(1).reg(); |
| 928 | 928 |
| 929 if (HasICData()) { | 929 if (HasICData()) { |
| 930 ASSERT(original() != NULL); | 930 ASSERT(original() != NULL); |
| 931 Label* deopt = compiler->AddDeoptStub(original()->cid(), | 931 Label* deopt = compiler->AddDeoptStub(original()->cid(), |
| 932 original()->token_index(), | 932 original()->token_pos(), |
| 933 original()->try_index(), | 933 original()->try_index(), |
| 934 kDeoptInstanceGetterSameTarget, | 934 kDeoptInstanceGetterSameTarget, |
| 935 instance_reg, | 935 instance_reg, |
| 936 value_reg); | 936 value_reg); |
| 937 // Smis do not have instance fields (Smi class is always first). | 937 // Smis do not have instance fields (Smi class is always first). |
| 938 Register temp_reg = locs()->temp(0).reg(); | 938 Register temp_reg = locs()->temp(0).reg(); |
| 939 ASSERT(temp_reg != instance_reg); | 939 ASSERT(temp_reg != instance_reg); |
| 940 ASSERT(temp_reg != value_reg); | 940 ASSERT(temp_reg != value_reg); |
| 941 ASSERT(ic_data() != NULL); | 941 ASSERT(ic_data() != NULL); |
| 942 compiler->EmitClassChecksNoSmi(*ic_data(), instance_reg, temp_reg, deopt); | 942 compiler->EmitClassChecksNoSmi(*ic_data(), instance_reg, temp_reg, deopt); |
| 943 } | 943 } |
| 944 __ StoreIntoObject(instance_reg, FieldAddress(instance_reg, field().Offset()), | 944 __ StoreIntoObject(instance_reg, FieldAddress(instance_reg, field().Offset()), |
| 945 value_reg); | 945 value_reg); |
| 946 } | 946 } |
| 947 | 947 |
| 948 | 948 |
| 949 LocationSummary* ThrowInstr::MakeLocationSummary() const { | 949 LocationSummary* ThrowInstr::MakeLocationSummary() const { |
| 950 const int kNumInputs = 0; | 950 const int kNumInputs = 0; |
| 951 const int kNumTemps = 0; | 951 const int kNumTemps = 0; |
| 952 return new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); | 952 return new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); |
| 953 } | 953 } |
| 954 | 954 |
| 955 | 955 |
| 956 | 956 |
| 957 void ThrowInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 957 void ThrowInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 958 ASSERT(exception()->IsUse()); | 958 ASSERT(exception()->IsUse()); |
| 959 compiler->GenerateCallRuntime(cid(), | 959 compiler->GenerateCallRuntime(cid(), |
| 960 token_index(), | 960 token_pos(), |
| 961 try_index(), | 961 try_index(), |
| 962 kThrowRuntimeEntry); | 962 kThrowRuntimeEntry); |
| 963 __ int3(); | 963 __ int3(); |
| 964 } | 964 } |
| 965 | 965 |
| 966 | 966 |
| 967 LocationSummary* ReThrowInstr::MakeLocationSummary() const { | 967 LocationSummary* ReThrowInstr::MakeLocationSummary() const { |
| 968 const int kNumInputs = 0; | 968 const int kNumInputs = 0; |
| 969 const int kNumTemps = 0; | 969 const int kNumTemps = 0; |
| 970 return new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); | 970 return new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); |
| 971 } | 971 } |
| 972 | 972 |
| 973 | 973 |
| 974 void ReThrowInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 974 void ReThrowInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 975 ASSERT(exception()->IsUse()); | 975 ASSERT(exception()->IsUse()); |
| 976 ASSERT(stack_trace()->IsUse()); | 976 ASSERT(stack_trace()->IsUse()); |
| 977 compiler->GenerateCallRuntime(cid(), | 977 compiler->GenerateCallRuntime(cid(), |
| 978 token_index(), | 978 token_pos(), |
| 979 try_index(), | 979 try_index(), |
| 980 kReThrowRuntimeEntry); | 980 kReThrowRuntimeEntry); |
| 981 __ int3(); | 981 __ int3(); |
| 982 } | 982 } |
| 983 | 983 |
| 984 | 984 |
| 985 LocationSummary* BranchInstr::MakeLocationSummary() const { | 985 LocationSummary* BranchInstr::MakeLocationSummary() const { |
| 986 if (is_fused_with_comparison()) { | 986 if (is_fused_with_comparison()) { |
| 987 return LocationSummary::Make(0, | 987 return LocationSummary::Make(0, |
| 988 Location::NoLocation(), | 988 Location::NoLocation(), |
| (...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1119 // The arguments to the stub include the closure. The arguments | 1119 // The arguments to the stub include the closure. The arguments |
| 1120 // descriptor describes the closure's arguments (and so does not include | 1120 // descriptor describes the closure's arguments (and so does not include |
| 1121 // the closure). | 1121 // the closure). |
| 1122 Register temp_reg = locs()->temp(0).reg(); | 1122 Register temp_reg = locs()->temp(0).reg(); |
| 1123 int argument_count = ArgumentCount(); | 1123 int argument_count = ArgumentCount(); |
| 1124 const Array& arguments_descriptor = | 1124 const Array& arguments_descriptor = |
| 1125 CodeGenerator::ArgumentsDescriptor(argument_count - 1, | 1125 CodeGenerator::ArgumentsDescriptor(argument_count - 1, |
| 1126 argument_names()); | 1126 argument_names()); |
| 1127 __ LoadObject(temp_reg, arguments_descriptor); | 1127 __ LoadObject(temp_reg, arguments_descriptor); |
| 1128 | 1128 |
| 1129 compiler->GenerateCall(token_index(), | 1129 compiler->GenerateCall(token_pos(), |
| 1130 try_index(), | 1130 try_index(), |
| 1131 &StubCode::CallClosureFunctionLabel(), | 1131 &StubCode::CallClosureFunctionLabel(), |
| 1132 PcDescriptors::kOther); | 1132 PcDescriptors::kOther); |
| 1133 __ Drop(argument_count); | 1133 __ Drop(argument_count); |
| 1134 } | 1134 } |
| 1135 | 1135 |
| 1136 | 1136 |
| 1137 LocationSummary* InstanceCallComp::MakeLocationSummary() const { | 1137 LocationSummary* InstanceCallComp::MakeLocationSummary() const { |
| 1138 return MakeCallSummary(); | 1138 return MakeCallSummary(); |
| 1139 } | 1139 } |
| 1140 | 1140 |
| 1141 | 1141 |
| 1142 void InstanceCallComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 1142 void InstanceCallComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 1143 ASSERT(VerifyCallComputation(this)); | 1143 ASSERT(VerifyCallComputation(this)); |
| 1144 compiler->AddCurrentDescriptor(PcDescriptors::kDeopt, | 1144 compiler->AddCurrentDescriptor(PcDescriptors::kDeopt, |
| 1145 cid(), | 1145 cid(), |
| 1146 token_index(), | 1146 token_pos(), |
| 1147 try_index()); | 1147 try_index()); |
| 1148 compiler->GenerateInstanceCall(cid(), | 1148 compiler->GenerateInstanceCall(cid(), |
| 1149 token_index(), | 1149 token_pos(), |
| 1150 try_index(), | 1150 try_index(), |
| 1151 function_name(), | 1151 function_name(), |
| 1152 ArgumentCount(), | 1152 ArgumentCount(), |
| 1153 argument_names(), | 1153 argument_names(), |
| 1154 checked_argument_count()); | 1154 checked_argument_count()); |
| 1155 } | 1155 } |
| 1156 | 1156 |
| 1157 | 1157 |
| 1158 bool InstanceCallComp::VerifyComputation() { | 1158 bool InstanceCallComp::VerifyComputation() { |
| 1159 return VerifyCallComputation(this); | 1159 return VerifyCallComputation(this); |
| 1160 } | 1160 } |
| 1161 | 1161 |
| 1162 | 1162 |
| 1163 LocationSummary* StaticCallComp::MakeLocationSummary() const { | 1163 LocationSummary* StaticCallComp::MakeLocationSummary() const { |
| 1164 return MakeCallSummary(); | 1164 return MakeCallSummary(); |
| 1165 } | 1165 } |
| 1166 | 1166 |
| 1167 | 1167 |
| 1168 void StaticCallComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 1168 void StaticCallComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 1169 ASSERT(VerifyCallComputation(this)); | 1169 ASSERT(VerifyCallComputation(this)); |
| 1170 Label done; | 1170 Label done; |
| 1171 if (recognized() == MethodRecognizer::kMathSqrt) { | 1171 if (recognized() == MethodRecognizer::kMathSqrt) { |
| 1172 compiler->GenerateInlinedMathSqrt(&done); | 1172 compiler->GenerateInlinedMathSqrt(&done); |
| 1173 // Falls through to static call when operand type is not double or smi. | 1173 // Falls through to static call when operand type is not double or smi. |
| 1174 } | 1174 } |
| 1175 compiler->GenerateStaticCall(cid(), | 1175 compiler->GenerateStaticCall(cid(), |
| 1176 token_index(), | 1176 token_pos(), |
| 1177 try_index(), | 1177 try_index(), |
| 1178 function(), | 1178 function(), |
| 1179 ArgumentCount(), | 1179 ArgumentCount(), |
| 1180 argument_names()); | 1180 argument_names()); |
| 1181 __ Bind(&done); | 1181 __ Bind(&done); |
| 1182 } | 1182 } |
| 1183 | 1183 |
| 1184 | 1184 |
| 1185 LocationSummary* UseVal::MakeLocationSummary() const { | 1185 LocationSummary* UseVal::MakeLocationSummary() const { |
| 1186 return NULL; | 1186 return NULL; |
| 1187 } | 1187 } |
| 1188 | 1188 |
| 1189 | 1189 |
| 1190 void UseVal::EmitNativeCode(FlowGraphCompiler* compiler) { | 1190 void UseVal::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 1191 UNIMPLEMENTED(); | 1191 UNIMPLEMENTED(); |
| 1192 } | 1192 } |
| 1193 | 1193 |
| 1194 | 1194 |
| 1195 void AssertAssignableComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 1195 void AssertAssignableComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 1196 compiler->GenerateAssertAssignable(cid(), | 1196 compiler->GenerateAssertAssignable(cid(), |
| 1197 token_index(), | 1197 token_pos(), |
| 1198 try_index(), | 1198 try_index(), |
| 1199 dst_type(), | 1199 dst_type(), |
| 1200 dst_name()); | 1200 dst_name()); |
| 1201 ASSERT(locs()->in(0).reg() == locs()->out().reg()); | 1201 ASSERT(locs()->in(0).reg() == locs()->out().reg()); |
| 1202 } | 1202 } |
| 1203 | 1203 |
| 1204 | 1204 |
| 1205 LocationSummary* AssertBooleanComp::MakeLocationSummary() const { | 1205 LocationSummary* AssertBooleanComp::MakeLocationSummary() const { |
| 1206 return LocationSummary::Make(1, | 1206 return LocationSummary::Make(1, |
| 1207 Location::SameAsFirstInput(), | 1207 Location::SameAsFirstInput(), |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1280 | 1280 |
| 1281 LocationSummary* AllocateObjectComp::MakeLocationSummary() const { | 1281 LocationSummary* AllocateObjectComp::MakeLocationSummary() const { |
| 1282 return MakeCallSummary(); | 1282 return MakeCallSummary(); |
| 1283 } | 1283 } |
| 1284 | 1284 |
| 1285 | 1285 |
| 1286 void AllocateObjectComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 1286 void AllocateObjectComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 1287 const Class& cls = Class::ZoneHandle(constructor().owner()); | 1287 const Class& cls = Class::ZoneHandle(constructor().owner()); |
| 1288 const Code& stub = Code::Handle(StubCode::GetAllocationStubForClass(cls)); | 1288 const Code& stub = Code::Handle(StubCode::GetAllocationStubForClass(cls)); |
| 1289 const ExternalLabel label(cls.ToCString(), stub.EntryPoint()); | 1289 const ExternalLabel label(cls.ToCString(), stub.EntryPoint()); |
| 1290 compiler->GenerateCall(token_index(), | 1290 compiler->GenerateCall(token_pos(), |
| 1291 try_index(), | 1291 try_index(), |
| 1292 &label, | 1292 &label, |
| 1293 PcDescriptors::kOther); | 1293 PcDescriptors::kOther); |
| 1294 __ Drop(arguments().length()); // Discard arguments. | 1294 __ Drop(arguments().length()); // Discard arguments. |
| 1295 } | 1295 } |
| 1296 | 1296 |
| 1297 | 1297 |
| 1298 LocationSummary* CreateClosureComp::MakeLocationSummary() const { | 1298 LocationSummary* CreateClosureComp::MakeLocationSummary() const { |
| 1299 return MakeCallSummary(); | 1299 return MakeCallSummary(); |
| 1300 } | 1300 } |
| 1301 | 1301 |
| 1302 | 1302 |
| 1303 void CreateClosureComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 1303 void CreateClosureComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 1304 const Function& closure_function = function(); | 1304 const Function& closure_function = function(); |
| 1305 const Code& stub = Code::Handle( | 1305 const Code& stub = Code::Handle( |
| 1306 StubCode::GetAllocationStubForClosure(closure_function)); | 1306 StubCode::GetAllocationStubForClosure(closure_function)); |
| 1307 const ExternalLabel label(closure_function.ToCString(), stub.EntryPoint()); | 1307 const ExternalLabel label(closure_function.ToCString(), stub.EntryPoint()); |
| 1308 compiler->GenerateCall(token_index(), try_index(), &label, | 1308 compiler->GenerateCall(token_pos(), try_index(), &label, |
| 1309 PcDescriptors::kOther); | 1309 PcDescriptors::kOther); |
| 1310 __ Drop(2); // Discard type arguments and receiver. | 1310 __ Drop(2); // Discard type arguments and receiver. |
| 1311 } | 1311 } |
| 1312 | 1312 |
| 1313 | 1313 |
| 1314 #undef __ | 1314 #undef __ |
| 1315 | 1315 |
| 1316 } // namespace dart | 1316 } // namespace dart |
| OLD | NEW |