| 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/dart_entry.h" | 8 #include "vm/dart_entry.h" |
| 9 #include "vm/flow_graph_builder.h" | 9 #include "vm/flow_graph_builder.h" |
| 10 #include "vm/flow_graph_compiler.h" | 10 #include "vm/flow_graph_compiler.h" |
| (...skipping 949 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 960 if (HasTryIndex()) { | 960 if (HasTryIndex()) { |
| 961 compiler->AddExceptionHandler(try_index(), | 961 compiler->AddExceptionHandler(try_index(), |
| 962 compiler->assembler()->CodeSize()); | 962 compiler->assembler()->CodeSize()); |
| 963 } | 963 } |
| 964 } | 964 } |
| 965 | 965 |
| 966 | 966 |
| 967 LocationSummary* StoreInstanceFieldComp::MakeLocationSummary() const { | 967 LocationSummary* StoreInstanceFieldComp::MakeLocationSummary() const { |
| 968 const intptr_t kNumInputs = 2; | 968 const intptr_t kNumInputs = 2; |
| 969 const intptr_t num_temps = HasICData() ? 1 : 0; | 969 const intptr_t num_temps = HasICData() ? 1 : 0; |
| 970 LocationSummary* summary = new LocationSummary(kNumInputs, num_temps); | 970 LocationSummary* summary = |
| 971 new LocationSummary(kNumInputs, num_temps, LocationSummary::kNoCall); |
| 971 summary->set_in(0, Location::RequiresRegister()); | 972 summary->set_in(0, Location::RequiresRegister()); |
| 972 summary->set_in(1, Location::RequiresRegister()); | 973 summary->set_in(1, Location::RequiresRegister()); |
| 973 if (HasICData()) { | 974 if (HasICData()) { |
| 974 summary->set_temp(0, Location::RequiresRegister()); | 975 summary->set_temp(0, Location::RequiresRegister()); |
| 975 } | 976 } |
| 976 return summary; | 977 return summary; |
| 977 } | 978 } |
| 978 | 979 |
| 979 | 980 |
| 980 void StoreInstanceFieldComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 981 void StoreInstanceFieldComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1031 ASSERT(stack_trace()->IsUse()); | 1032 ASSERT(stack_trace()->IsUse()); |
| 1032 compiler->GenerateCallRuntime(cid(), | 1033 compiler->GenerateCallRuntime(cid(), |
| 1033 token_pos(), | 1034 token_pos(), |
| 1034 try_index(), | 1035 try_index(), |
| 1035 kReThrowRuntimeEntry); | 1036 kReThrowRuntimeEntry); |
| 1036 __ int3(); | 1037 __ int3(); |
| 1037 } | 1038 } |
| 1038 | 1039 |
| 1039 | 1040 |
| 1040 LocationSummary* GotoInstr::MakeLocationSummary() const { | 1041 LocationSummary* GotoInstr::MakeLocationSummary() const { |
| 1041 return new LocationSummary(0, 0); | 1042 return new LocationSummary(0, 0, LocationSummary::kNoCall); |
| 1042 } | 1043 } |
| 1043 | 1044 |
| 1044 | 1045 |
| 1045 void GotoInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 1046 void GotoInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 1046 // We can fall through if the successor is the next block in the list. | 1047 // We can fall through if the successor is the next block in the list. |
| 1047 // Otherwise, we need a jump. | 1048 // Otherwise, we need a jump. |
| 1048 if (!compiler->IsNextBlock(successor())) { | 1049 if (!compiler->IsNextBlock(successor())) { |
| 1049 __ jmp(compiler->GetBlockLabel(successor())); | 1050 __ jmp(compiler->GetBlockLabel(successor())); |
| 1050 } | 1051 } |
| 1051 } | 1052 } |
| (...skipping 28 matching lines...) Expand all Loading... |
| 1080 // If the next block is the true successor we negate comparison and fall | 1081 // If the next block is the true successor we negate comparison and fall |
| 1081 // through to it. | 1082 // through to it. |
| 1082 ASSERT(compiler->IsNextBlock(true_successor())); | 1083 ASSERT(compiler->IsNextBlock(true_successor())); |
| 1083 Condition false_condition = NegateCondition(true_condition); | 1084 Condition false_condition = NegateCondition(true_condition); |
| 1084 __ j(false_condition, compiler->GetBlockLabel(false_successor())); | 1085 __ j(false_condition, compiler->GetBlockLabel(false_successor())); |
| 1085 } | 1086 } |
| 1086 } | 1087 } |
| 1087 | 1088 |
| 1088 | 1089 |
| 1089 LocationSummary* CurrentContextComp::MakeLocationSummary() const { | 1090 LocationSummary* CurrentContextComp::MakeLocationSummary() const { |
| 1090 return LocationSummary::Make(0, Location::RequiresRegister()); | 1091 return LocationSummary::Make(0, |
| 1092 Location::RequiresRegister(), |
| 1093 LocationSummary::kNoCall); |
| 1091 } | 1094 } |
| 1092 | 1095 |
| 1093 | 1096 |
| 1094 void CurrentContextComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 1097 void CurrentContextComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 1095 __ MoveRegister(locs()->out().reg(), CTX); | 1098 __ MoveRegister(locs()->out().reg(), CTX); |
| 1096 } | 1099 } |
| 1097 | 1100 |
| 1098 | 1101 |
| 1099 LocationSummary* StoreContextComp::MakeLocationSummary() const { | 1102 LocationSummary* StoreContextComp::MakeLocationSummary() const { |
| 1100 const intptr_t kNumInputs = 1; | 1103 const intptr_t kNumInputs = 1; |
| 1101 const intptr_t kNumTemps = 0; | 1104 const intptr_t kNumTemps = 0; |
| 1102 LocationSummary* summary = new LocationSummary(kNumInputs, kNumTemps); | 1105 LocationSummary* summary = |
| 1106 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 1103 summary->set_in(0, Location::RegisterLocation(CTX)); | 1107 summary->set_in(0, Location::RegisterLocation(CTX)); |
| 1104 return summary; | 1108 return summary; |
| 1105 } | 1109 } |
| 1106 | 1110 |
| 1107 | 1111 |
| 1108 void StoreContextComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 1112 void StoreContextComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 1109 // Nothing to do. Context register were loaded by register allocator. | 1113 // Nothing to do. Context register were loaded by register allocator. |
| 1110 ASSERT(locs()->in(0).reg() == CTX); | 1114 ASSERT(locs()->in(0).reg() == CTX); |
| 1111 } | 1115 } |
| 1112 | 1116 |
| 1113 | 1117 |
| 1114 LocationSummary* StrictCompareComp::MakeLocationSummary() const { | 1118 LocationSummary* StrictCompareComp::MakeLocationSummary() const { |
| 1115 return LocationSummary::Make(2, Location::SameAsFirstInput()); | 1119 return LocationSummary::Make(2, |
| 1120 Location::SameAsFirstInput(), |
| 1121 LocationSummary::kNoCall); |
| 1116 } | 1122 } |
| 1117 | 1123 |
| 1118 | 1124 |
| 1119 void StrictCompareComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 1125 void StrictCompareComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 1120 Register left = locs()->in(0).reg(); | 1126 Register left = locs()->in(0).reg(); |
| 1121 Register right = locs()->in(1).reg(); | 1127 Register right = locs()->in(1).reg(); |
| 1122 | 1128 |
| 1123 ASSERT(kind() == Token::kEQ_STRICT || kind() == Token::kNE_STRICT); | 1129 ASSERT(kind() == Token::kEQ_STRICT || kind() == Token::kNE_STRICT); |
| 1124 Condition true_condition = (kind() == Token::kEQ_STRICT) ? EQUAL : NOT_EQUAL; | 1130 Condition true_condition = (kind() == Token::kEQ_STRICT) ? EQUAL : NOT_EQUAL; |
| 1125 __ CompareRegisters(left, right); | 1131 __ CompareRegisters(left, right); |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1209 compiler->GenerateAssertAssignable(cid(), | 1215 compiler->GenerateAssertAssignable(cid(), |
| 1210 token_pos(), | 1216 token_pos(), |
| 1211 try_index(), | 1217 try_index(), |
| 1212 dst_type(), | 1218 dst_type(), |
| 1213 dst_name()); | 1219 dst_name()); |
| 1214 ASSERT(locs()->in(0).reg() == locs()->out().reg()); | 1220 ASSERT(locs()->in(0).reg() == locs()->out().reg()); |
| 1215 } | 1221 } |
| 1216 | 1222 |
| 1217 | 1223 |
| 1218 LocationSummary* StoreStaticFieldComp::MakeLocationSummary() const { | 1224 LocationSummary* StoreStaticFieldComp::MakeLocationSummary() const { |
| 1219 LocationSummary* locs = new LocationSummary(1, 1); | 1225 LocationSummary* locs = new LocationSummary(1, 1, LocationSummary::kNoCall); |
| 1220 locs->set_in(0, Location::RequiresRegister()); | 1226 locs->set_in(0, Location::RequiresRegister()); |
| 1221 locs->set_temp(0, Location::RequiresRegister()); | 1227 locs->set_temp(0, Location::RequiresRegister()); |
| 1222 locs->set_out(Location::SameAsFirstInput()); | 1228 locs->set_out(Location::SameAsFirstInput()); |
| 1223 return locs; | 1229 return locs; |
| 1224 } | 1230 } |
| 1225 | 1231 |
| 1226 | 1232 |
| 1227 void StoreStaticFieldComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 1233 void StoreStaticFieldComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 1228 Register value = locs()->in(0).reg(); | 1234 Register value = locs()->in(0).reg(); |
| 1229 Register temp = locs()->temp(0).reg(); | 1235 Register temp = locs()->temp(0).reg(); |
| 1230 ASSERT(locs()->out().reg() == value); | 1236 ASSERT(locs()->out().reg() == value); |
| 1231 | 1237 |
| 1232 __ LoadObject(temp, field()); | 1238 __ LoadObject(temp, field()); |
| 1233 __ StoreIntoObject(temp, FieldAddress(temp, Field::value_offset()), value); | 1239 __ StoreIntoObject(temp, FieldAddress(temp, Field::value_offset()), value); |
| 1234 } | 1240 } |
| 1235 | 1241 |
| 1236 | 1242 |
| 1237 LocationSummary* BooleanNegateComp::MakeLocationSummary() const { | 1243 LocationSummary* BooleanNegateComp::MakeLocationSummary() const { |
| 1238 return LocationSummary::Make(1, Location::RequiresRegister()); | 1244 return LocationSummary::Make(1, |
| 1245 Location::RequiresRegister(), |
| 1246 LocationSummary::kNoCall); |
| 1239 } | 1247 } |
| 1240 | 1248 |
| 1241 | 1249 |
| 1242 void BooleanNegateComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 1250 void BooleanNegateComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 1243 Register value = locs()->in(0).reg(); | 1251 Register value = locs()->in(0).reg(); |
| 1244 Register result = locs()->out().reg(); | 1252 Register result = locs()->out().reg(); |
| 1245 | 1253 |
| 1246 Label done; | 1254 Label done; |
| 1247 __ LoadObject(result, compiler->bool_true()); | 1255 __ LoadObject(result, compiler->bool_true()); |
| 1248 __ CompareRegisters(result, value); | 1256 __ CompareRegisters(result, value); |
| 1249 __ j(NOT_EQUAL, &done, Assembler::kNearJump); | 1257 __ j(NOT_EQUAL, &done, Assembler::kNearJump); |
| 1250 __ LoadObject(result, compiler->bool_false()); | 1258 __ LoadObject(result, compiler->bool_false()); |
| 1251 __ Bind(&done); | 1259 __ Bind(&done); |
| 1252 } | 1260 } |
| 1253 | 1261 |
| 1254 | 1262 |
| 1255 LocationSummary* ChainContextComp::MakeLocationSummary() const { | 1263 LocationSummary* ChainContextComp::MakeLocationSummary() const { |
| 1256 return LocationSummary::Make(1, Location::NoLocation()); | 1264 return LocationSummary::Make(1, |
| 1265 Location::NoLocation(), |
| 1266 LocationSummary::kNoCall); |
| 1257 } | 1267 } |
| 1258 | 1268 |
| 1259 | 1269 |
| 1260 void ChainContextComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 1270 void ChainContextComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 1261 Register context_value = locs()->in(0).reg(); | 1271 Register context_value = locs()->in(0).reg(); |
| 1262 | 1272 |
| 1263 // Chain the new context in context_value to its parent in CTX. | 1273 // Chain the new context in context_value to its parent in CTX. |
| 1264 __ StoreIntoObject(context_value, | 1274 __ StoreIntoObject(context_value, |
| 1265 FieldAddress(context_value, Context::parent_offset()), | 1275 FieldAddress(context_value, Context::parent_offset()), |
| 1266 CTX); | 1276 CTX); |
| 1267 // Set new context as current context. | 1277 // Set new context as current context. |
| 1268 __ MoveRegister(CTX, context_value); | 1278 __ MoveRegister(CTX, context_value); |
| 1269 } | 1279 } |
| 1270 | 1280 |
| 1271 | 1281 |
| 1272 LocationSummary* StoreVMFieldComp::MakeLocationSummary() const { | 1282 LocationSummary* StoreVMFieldComp::MakeLocationSummary() const { |
| 1273 return LocationSummary::Make(2, Location::SameAsFirstInput()); | 1283 return LocationSummary::Make(2, |
| 1284 Location::SameAsFirstInput(), |
| 1285 LocationSummary::kNoCall); |
| 1274 } | 1286 } |
| 1275 | 1287 |
| 1276 | 1288 |
| 1277 void StoreVMFieldComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 1289 void StoreVMFieldComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 1278 Register value_reg = locs()->in(0).reg(); | 1290 Register value_reg = locs()->in(0).reg(); |
| 1279 Register dest_reg = locs()->in(1).reg(); | 1291 Register dest_reg = locs()->in(1).reg(); |
| 1280 ASSERT(value_reg == locs()->out().reg()); | 1292 ASSERT(value_reg == locs()->out().reg()); |
| 1281 | 1293 |
| 1282 __ StoreIntoObject(dest_reg, FieldAddress(dest_reg, offset_in_bytes()), | 1294 __ StoreIntoObject(dest_reg, FieldAddress(dest_reg, offset_in_bytes()), |
| 1283 value_reg); | 1295 value_reg); |
| (...skipping 29 matching lines...) Expand all Loading... |
| 1313 const ExternalLabel label(closure_function.ToCString(), stub.EntryPoint()); | 1325 const ExternalLabel label(closure_function.ToCString(), stub.EntryPoint()); |
| 1314 compiler->GenerateCall(token_pos(), try_index(), &label, | 1326 compiler->GenerateCall(token_pos(), try_index(), &label, |
| 1315 PcDescriptors::kOther); | 1327 PcDescriptors::kOther); |
| 1316 __ Drop(2); // Discard type arguments and receiver. | 1328 __ Drop(2); // Discard type arguments and receiver. |
| 1317 } | 1329 } |
| 1318 | 1330 |
| 1319 | 1331 |
| 1320 LocationSummary* PushArgumentInstr::MakeLocationSummary() const { | 1332 LocationSummary* PushArgumentInstr::MakeLocationSummary() const { |
| 1321 const intptr_t kNumInputs = 1; | 1333 const intptr_t kNumInputs = 1; |
| 1322 const intptr_t kNumTemps= 0; | 1334 const intptr_t kNumTemps= 0; |
| 1323 LocationSummary* locs = new LocationSummary(kNumInputs, kNumTemps); | 1335 LocationSummary* locs = |
| 1336 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 1324 // TODO(fschneider): Use Any() once it is supported by all code generators. | 1337 // TODO(fschneider): Use Any() once it is supported by all code generators. |
| 1325 locs->set_in(0, Location::RequiresRegister()); | 1338 locs->set_in(0, Location::RequiresRegister()); |
| 1326 return locs; | 1339 return locs; |
| 1327 } | 1340 } |
| 1328 | 1341 |
| 1329 | 1342 |
| 1330 void PushArgumentInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 1343 void PushArgumentInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 1331 // In SSA mode, we need an explicit push. Nothing to do in non-SSA mode | 1344 // In SSA mode, we need an explicit push. Nothing to do in non-SSA mode |
| 1332 // where PushArgument is handled in FrameRegisterAllocator::AllocateRegisters. | 1345 // where PushArgument is handled in FrameRegisterAllocator::AllocateRegisters. |
| 1333 // Instead of popping the value it is left alone on the simulated frame | 1346 // Instead of popping the value it is left alone on the simulated frame |
| 1334 // and materialized on the physical stack before the call. | 1347 // and materialized on the physical stack before the call. |
| 1335 // TODO(fschneider): Avoid special-casing for SSA mode here. | 1348 // TODO(fschneider): Avoid special-casing for SSA mode here. |
| 1336 if (compiler->is_ssa()) { | 1349 if (compiler->is_ssa()) { |
| 1337 ASSERT(locs()->in(0).IsRegister()); | 1350 ASSERT(locs()->in(0).IsRegister()); |
| 1338 __ PushRegister(locs()->in(0).reg()); | 1351 __ PushRegister(locs()->in(0).reg()); |
| 1339 } | 1352 } |
| 1340 } | 1353 } |
| 1341 | 1354 |
| 1342 | 1355 |
| 1343 #undef __ | 1356 #undef __ |
| 1344 | 1357 |
| 1345 } // namespace dart | 1358 } // namespace dart |
| OLD | NEW |