OLD | NEW |
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, 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_MIPS. | 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_MIPS. |
6 #if defined(TARGET_ARCH_MIPS) | 6 #if defined(TARGET_ARCH_MIPS) |
7 | 7 |
8 #include "vm/flow_graph_compiler.h" | 8 #include "vm/flow_graph_compiler.h" |
9 | 9 |
10 #include "vm/ast_printer.h" | 10 #include "vm/ast_printer.h" |
(...skipping 1124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1135 | 1135 |
1136 if (is_optimizing()) { | 1136 if (is_optimizing()) { |
1137 lazy_deopt_pc_offset_ = assembler()->CodeSize(); | 1137 lazy_deopt_pc_offset_ = assembler()->CodeSize(); |
1138 __ Branch(&StubCode::DeoptimizeLazyLabel()); | 1138 __ Branch(&StubCode::DeoptimizeLazyLabel()); |
1139 } | 1139 } |
1140 } | 1140 } |
1141 | 1141 |
1142 | 1142 |
1143 void FlowGraphCompiler::GenerateCall(intptr_t token_pos, | 1143 void FlowGraphCompiler::GenerateCall(intptr_t token_pos, |
1144 const ExternalLabel* label, | 1144 const ExternalLabel* label, |
1145 PcDescriptors::Kind kind, | 1145 RawPcDescriptors::Kind kind, |
1146 LocationSummary* locs) { | 1146 LocationSummary* locs) { |
1147 __ BranchLinkPatchable(label); | 1147 __ BranchLinkPatchable(label); |
1148 AddCurrentDescriptor(kind, Isolate::kNoDeoptId, token_pos); | 1148 AddCurrentDescriptor(kind, Isolate::kNoDeoptId, token_pos); |
1149 RecordSafepoint(locs); | 1149 RecordSafepoint(locs); |
1150 } | 1150 } |
1151 | 1151 |
1152 | 1152 |
1153 void FlowGraphCompiler::GenerateDartCall(intptr_t deopt_id, | 1153 void FlowGraphCompiler::GenerateDartCall(intptr_t deopt_id, |
1154 intptr_t token_pos, | 1154 intptr_t token_pos, |
1155 const ExternalLabel* label, | 1155 const ExternalLabel* label, |
1156 PcDescriptors::Kind kind, | 1156 RawPcDescriptors::Kind kind, |
1157 LocationSummary* locs) { | 1157 LocationSummary* locs) { |
1158 __ BranchLinkPatchable(label); | 1158 __ BranchLinkPatchable(label); |
1159 AddCurrentDescriptor(kind, deopt_id, token_pos); | 1159 AddCurrentDescriptor(kind, deopt_id, token_pos); |
1160 RecordSafepoint(locs); | 1160 RecordSafepoint(locs); |
1161 // Marks either the continuation point in unoptimized code or the | 1161 // Marks either the continuation point in unoptimized code or the |
1162 // deoptimization point in optimized code, after call. | 1162 // deoptimization point in optimized code, after call. |
1163 const intptr_t deopt_id_after = Isolate::ToDeoptAfter(deopt_id); | 1163 const intptr_t deopt_id_after = Isolate::ToDeoptAfter(deopt_id); |
1164 if (is_optimizing()) { | 1164 if (is_optimizing()) { |
1165 AddDeoptIndexAtCall(deopt_id_after, token_pos); | 1165 AddDeoptIndexAtCall(deopt_id_after, token_pos); |
1166 } else { | 1166 } else { |
1167 // Add deoptimization continuation point after the call and before the | 1167 // Add deoptimization continuation point after the call and before the |
1168 // arguments are removed. | 1168 // arguments are removed. |
1169 AddCurrentDescriptor(PcDescriptors::kDeopt, | 1169 AddCurrentDescriptor(RawPcDescriptors::kDeopt, |
1170 deopt_id_after, | 1170 deopt_id_after, |
1171 token_pos); | 1171 token_pos); |
1172 } | 1172 } |
1173 } | 1173 } |
1174 | 1174 |
1175 | 1175 |
1176 void FlowGraphCompiler::GenerateRuntimeCall(intptr_t token_pos, | 1176 void FlowGraphCompiler::GenerateRuntimeCall(intptr_t token_pos, |
1177 intptr_t deopt_id, | 1177 intptr_t deopt_id, |
1178 const RuntimeEntry& entry, | 1178 const RuntimeEntry& entry, |
1179 intptr_t argument_count, | 1179 intptr_t argument_count, |
1180 LocationSummary* locs) { | 1180 LocationSummary* locs) { |
1181 __ CallRuntime(entry, argument_count); | 1181 __ CallRuntime(entry, argument_count); |
1182 AddCurrentDescriptor(PcDescriptors::kOther, deopt_id, token_pos); | 1182 AddCurrentDescriptor(RawPcDescriptors::kOther, deopt_id, token_pos); |
1183 RecordSafepoint(locs); | 1183 RecordSafepoint(locs); |
1184 if (deopt_id != Isolate::kNoDeoptId) { | 1184 if (deopt_id != Isolate::kNoDeoptId) { |
1185 // Marks either the continuation point in unoptimized code or the | 1185 // Marks either the continuation point in unoptimized code or the |
1186 // deoptimization point in optimized code, after call. | 1186 // deoptimization point in optimized code, after call. |
1187 const intptr_t deopt_id_after = Isolate::ToDeoptAfter(deopt_id); | 1187 const intptr_t deopt_id_after = Isolate::ToDeoptAfter(deopt_id); |
1188 if (is_optimizing()) { | 1188 if (is_optimizing()) { |
1189 AddDeoptIndexAtCall(deopt_id_after, token_pos); | 1189 AddDeoptIndexAtCall(deopt_id_after, token_pos); |
1190 } else { | 1190 } else { |
1191 // Add deoptimization continuation point after the call and before the | 1191 // Add deoptimization continuation point after the call and before the |
1192 // arguments are removed. | 1192 // arguments are removed. |
1193 AddCurrentDescriptor(PcDescriptors::kDeopt, | 1193 AddCurrentDescriptor(RawPcDescriptors::kDeopt, |
1194 deopt_id_after, | 1194 deopt_id_after, |
1195 token_pos); | 1195 token_pos); |
1196 } | 1196 } |
1197 } | 1197 } |
1198 } | 1198 } |
1199 | 1199 |
1200 | 1200 |
1201 void FlowGraphCompiler::EmitEdgeCounter() { | 1201 void FlowGraphCompiler::EmitEdgeCounter() { |
1202 // We do not check for overflow when incrementing the edge counter. The | 1202 // We do not check for overflow when incrementing the edge counter. The |
1203 // function should normally be optimized long before the counter can | 1203 // function should normally be optimized long before the counter can |
(...skipping 23 matching lines...) Expand all Loading... |
1227 // to inlining in optimized code, that function may not correspond to the | 1227 // to inlining in optimized code, that function may not correspond to the |
1228 // top-level function (parsed_function().function()) which could be | 1228 // top-level function (parsed_function().function()) which could be |
1229 // reoptimized and which counter needs to be incremented. | 1229 // reoptimized and which counter needs to be incremented. |
1230 // Pass the function explicitly, it is used in IC stub. | 1230 // Pass the function explicitly, it is used in IC stub. |
1231 __ TraceSimMsg("OptimizedInstanceCall"); | 1231 __ TraceSimMsg("OptimizedInstanceCall"); |
1232 __ LoadObject(T0, parsed_function().function()); | 1232 __ LoadObject(T0, parsed_function().function()); |
1233 __ LoadObject(S5, ic_data); | 1233 __ LoadObject(S5, ic_data); |
1234 GenerateDartCall(deopt_id, | 1234 GenerateDartCall(deopt_id, |
1235 token_pos, | 1235 token_pos, |
1236 target_label, | 1236 target_label, |
1237 PcDescriptors::kIcCall, | 1237 RawPcDescriptors::kIcCall, |
1238 locs); | 1238 locs); |
1239 __ Drop(argument_count); | 1239 __ Drop(argument_count); |
1240 } | 1240 } |
1241 | 1241 |
1242 | 1242 |
1243 void FlowGraphCompiler::EmitInstanceCall(ExternalLabel* target_label, | 1243 void FlowGraphCompiler::EmitInstanceCall(ExternalLabel* target_label, |
1244 const ICData& ic_data, | 1244 const ICData& ic_data, |
1245 intptr_t argument_count, | 1245 intptr_t argument_count, |
1246 intptr_t deopt_id, | 1246 intptr_t deopt_id, |
1247 intptr_t token_pos, | 1247 intptr_t token_pos, |
1248 LocationSummary* locs) { | 1248 LocationSummary* locs) { |
1249 ASSERT(Array::Handle(ic_data.arguments_descriptor()).Length() > 0); | 1249 ASSERT(Array::Handle(ic_data.arguments_descriptor()).Length() > 0); |
1250 __ TraceSimMsg("InstanceCall"); | 1250 __ TraceSimMsg("InstanceCall"); |
1251 __ LoadImmediate(S4, 0); | 1251 __ LoadImmediate(S4, 0); |
1252 __ LoadObject(S5, ic_data); | 1252 __ LoadObject(S5, ic_data); |
1253 GenerateDartCall(deopt_id, | 1253 GenerateDartCall(deopt_id, |
1254 token_pos, | 1254 token_pos, |
1255 target_label, | 1255 target_label, |
1256 PcDescriptors::kIcCall, | 1256 RawPcDescriptors::kIcCall, |
1257 locs); | 1257 locs); |
1258 __ TraceSimMsg("InstanceCall return"); | 1258 __ TraceSimMsg("InstanceCall return"); |
1259 __ Drop(argument_count); | 1259 __ Drop(argument_count); |
1260 #if defined(DEBUG) | 1260 #if defined(DEBUG) |
1261 __ LoadImmediate(S4, kInvalidObjectPointer); | 1261 __ LoadImmediate(S4, kInvalidObjectPointer); |
1262 #endif | 1262 #endif |
1263 } | 1263 } |
1264 | 1264 |
1265 | 1265 |
1266 void FlowGraphCompiler::EmitMegamorphicInstanceCall( | 1266 void FlowGraphCompiler::EmitMegamorphicInstanceCall( |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1312 // be invoked as a normal Dart function. | 1312 // be invoked as a normal Dart function. |
1313 __ sll(T1, T3, 2); | 1313 __ sll(T1, T3, 2); |
1314 __ addu(T1, T2, T1); | 1314 __ addu(T1, T2, T1); |
1315 __ lw(T0, FieldAddress(T1, base + kWordSize)); | 1315 __ lw(T0, FieldAddress(T1, base + kWordSize)); |
1316 | 1316 |
1317 __ lw(T1, FieldAddress(T0, Function::instructions_offset())); | 1317 __ lw(T1, FieldAddress(T0, Function::instructions_offset())); |
1318 __ LoadObject(S5, ic_data); | 1318 __ LoadObject(S5, ic_data); |
1319 __ LoadObject(S4, arguments_descriptor); | 1319 __ LoadObject(S4, arguments_descriptor); |
1320 __ AddImmediate(T1, Instructions::HeaderSize() - kHeapObjectTag); | 1320 __ AddImmediate(T1, Instructions::HeaderSize() - kHeapObjectTag); |
1321 __ jalr(T1); | 1321 __ jalr(T1); |
1322 AddCurrentDescriptor(PcDescriptors::kOther, Isolate::kNoDeoptId, token_pos); | 1322 AddCurrentDescriptor(RawPcDescriptors::kOther, |
| 1323 Isolate::kNoDeoptId, token_pos); |
1323 RecordSafepoint(locs); | 1324 RecordSafepoint(locs); |
1324 AddDeoptIndexAtCall(Isolate::ToDeoptAfter(deopt_id), token_pos); | 1325 AddDeoptIndexAtCall(Isolate::ToDeoptAfter(deopt_id), token_pos); |
1325 __ Drop(argument_count); | 1326 __ Drop(argument_count); |
1326 } | 1327 } |
1327 | 1328 |
1328 | 1329 |
1329 void FlowGraphCompiler::EmitUnoptimizedStaticCall( | 1330 void FlowGraphCompiler::EmitUnoptimizedStaticCall( |
1330 intptr_t argument_count, | 1331 intptr_t argument_count, |
1331 intptr_t deopt_id, | 1332 intptr_t deopt_id, |
1332 intptr_t token_pos, | 1333 intptr_t token_pos, |
1333 LocationSummary* locs, | 1334 LocationSummary* locs, |
1334 const ICData& ic_data) { | 1335 const ICData& ic_data) { |
1335 uword label_address = 0; | 1336 uword label_address = 0; |
1336 if (ic_data.NumArgsTested() == 0) { | 1337 if (ic_data.NumArgsTested() == 0) { |
1337 label_address = StubCode::ZeroArgsUnoptimizedStaticCallEntryPoint(); | 1338 label_address = StubCode::ZeroArgsUnoptimizedStaticCallEntryPoint(); |
1338 } else if (ic_data.NumArgsTested() == 2) { | 1339 } else if (ic_data.NumArgsTested() == 2) { |
1339 label_address = StubCode::TwoArgsUnoptimizedStaticCallEntryPoint(); | 1340 label_address = StubCode::TwoArgsUnoptimizedStaticCallEntryPoint(); |
1340 } else { | 1341 } else { |
1341 UNIMPLEMENTED(); | 1342 UNIMPLEMENTED(); |
1342 } | 1343 } |
1343 ExternalLabel target_label(label_address); | 1344 ExternalLabel target_label(label_address); |
1344 __ LoadImmediate(S4, 0); | 1345 __ LoadImmediate(S4, 0); |
1345 __ LoadObject(S5, ic_data); | 1346 __ LoadObject(S5, ic_data); |
1346 GenerateDartCall(deopt_id, | 1347 GenerateDartCall(deopt_id, |
1347 token_pos, | 1348 token_pos, |
1348 &target_label, | 1349 &target_label, |
1349 PcDescriptors::kUnoptStaticCall, | 1350 RawPcDescriptors::kUnoptStaticCall, |
1350 locs); | 1351 locs); |
1351 #if defined(DEBUG) | 1352 #if defined(DEBUG) |
1352 __ LoadImmediate(S4, kInvalidObjectPointer); | 1353 __ LoadImmediate(S4, kInvalidObjectPointer); |
1353 #endif | 1354 #endif |
1354 __ Drop(argument_count); | 1355 __ Drop(argument_count); |
1355 } | 1356 } |
1356 | 1357 |
1357 | 1358 |
1358 void FlowGraphCompiler::EmitOptimizedStaticCall( | 1359 void FlowGraphCompiler::EmitOptimizedStaticCall( |
1359 const Function& function, | 1360 const Function& function, |
1360 const Array& arguments_descriptor, | 1361 const Array& arguments_descriptor, |
1361 intptr_t argument_count, | 1362 intptr_t argument_count, |
1362 intptr_t deopt_id, | 1363 intptr_t deopt_id, |
1363 intptr_t token_pos, | 1364 intptr_t token_pos, |
1364 LocationSummary* locs) { | 1365 LocationSummary* locs) { |
1365 __ TraceSimMsg("StaticCall"); | 1366 __ TraceSimMsg("StaticCall"); |
1366 __ LoadObject(S4, arguments_descriptor); | 1367 __ LoadObject(S4, arguments_descriptor); |
1367 // Do not use the code from the function, but let the code be patched so that | 1368 // Do not use the code from the function, but let the code be patched so that |
1368 // we can record the outgoing edges to other code. | 1369 // we can record the outgoing edges to other code. |
1369 GenerateDartCall(deopt_id, | 1370 GenerateDartCall(deopt_id, |
1370 token_pos, | 1371 token_pos, |
1371 &StubCode::CallStaticFunctionLabel(), | 1372 &StubCode::CallStaticFunctionLabel(), |
1372 PcDescriptors::kOptStaticCall, | 1373 RawPcDescriptors::kOptStaticCall, |
1373 locs); | 1374 locs); |
1374 AddStaticCallTarget(function); | 1375 AddStaticCallTarget(function); |
1375 __ Drop(argument_count); | 1376 __ Drop(argument_count); |
1376 } | 1377 } |
1377 | 1378 |
1378 | 1379 |
1379 void FlowGraphCompiler::EmitEqualityRegConstCompare(Register reg, | 1380 void FlowGraphCompiler::EmitEqualityRegConstCompare(Register reg, |
1380 const Object& obj, | 1381 const Object& obj, |
1381 bool needs_number_check, | 1382 bool needs_number_check, |
1382 intptr_t token_pos) { | 1383 intptr_t token_pos) { |
1383 __ TraceSimMsg("EqualityRegConstCompare"); | 1384 __ TraceSimMsg("EqualityRegConstCompare"); |
1384 if (needs_number_check) { | 1385 if (needs_number_check) { |
1385 ASSERT(!obj.IsMint() && !obj.IsDouble() && !obj.IsBigint()); | 1386 ASSERT(!obj.IsMint() && !obj.IsDouble() && !obj.IsBigint()); |
1386 __ addiu(SP, SP, Immediate(-2 * kWordSize)); | 1387 __ addiu(SP, SP, Immediate(-2 * kWordSize)); |
1387 __ sw(reg, Address(SP, 1 * kWordSize)); | 1388 __ sw(reg, Address(SP, 1 * kWordSize)); |
1388 __ LoadObject(TMP, obj); | 1389 __ LoadObject(TMP, obj); |
1389 __ sw(TMP, Address(SP, 0 * kWordSize)); | 1390 __ sw(TMP, Address(SP, 0 * kWordSize)); |
1390 if (is_optimizing()) { | 1391 if (is_optimizing()) { |
1391 __ BranchLinkPatchable( | 1392 __ BranchLinkPatchable( |
1392 &StubCode::OptimizedIdenticalWithNumberCheckLabel()); | 1393 &StubCode::OptimizedIdenticalWithNumberCheckLabel()); |
1393 } else { | 1394 } else { |
1394 __ BranchLinkPatchable( | 1395 __ BranchLinkPatchable( |
1395 &StubCode::UnoptimizedIdenticalWithNumberCheckLabel()); | 1396 &StubCode::UnoptimizedIdenticalWithNumberCheckLabel()); |
1396 } | 1397 } |
1397 if (token_pos != Scanner::kNoSourcePos) { | 1398 if (token_pos != Scanner::kNoSourcePos) { |
1398 AddCurrentDescriptor(PcDescriptors::kRuntimeCall, | 1399 AddCurrentDescriptor(RawPcDescriptors::kRuntimeCall, |
1399 Isolate::kNoDeoptId, | 1400 Isolate::kNoDeoptId, |
1400 token_pos); | 1401 token_pos); |
1401 } | 1402 } |
1402 __ TraceSimMsg("EqualityRegConstCompare return"); | 1403 __ TraceSimMsg("EqualityRegConstCompare return"); |
1403 __ lw(reg, Address(SP, 1 * kWordSize)); // Restore 'reg'. | 1404 __ lw(reg, Address(SP, 1 * kWordSize)); // Restore 'reg'. |
1404 __ addiu(SP, SP, Immediate(2 * kWordSize)); // Discard constant. | 1405 __ addiu(SP, SP, Immediate(2 * kWordSize)); // Discard constant. |
1405 return; | 1406 return; |
1406 } | 1407 } |
1407 __ CompareObject(CMPRES1, CMPRES2, reg, obj); | 1408 __ CompareObject(CMPRES1, CMPRES2, reg, obj); |
1408 } | 1409 } |
(...skipping 12 matching lines...) Expand all Loading... |
1421 if (is_optimizing()) { | 1422 if (is_optimizing()) { |
1422 __ BranchLinkPatchable( | 1423 __ BranchLinkPatchable( |
1423 &StubCode::OptimizedIdenticalWithNumberCheckLabel()); | 1424 &StubCode::OptimizedIdenticalWithNumberCheckLabel()); |
1424 } else { | 1425 } else { |
1425 __ LoadImmediate(S4, 0); | 1426 __ LoadImmediate(S4, 0); |
1426 __ LoadImmediate(S5, 0); | 1427 __ LoadImmediate(S5, 0); |
1427 __ BranchLinkPatchable( | 1428 __ BranchLinkPatchable( |
1428 &StubCode::UnoptimizedIdenticalWithNumberCheckLabel()); | 1429 &StubCode::UnoptimizedIdenticalWithNumberCheckLabel()); |
1429 } | 1430 } |
1430 if (token_pos != Scanner::kNoSourcePos) { | 1431 if (token_pos != Scanner::kNoSourcePos) { |
1431 AddCurrentDescriptor(PcDescriptors::kRuntimeCall, | 1432 AddCurrentDescriptor(RawPcDescriptors::kRuntimeCall, |
1432 Isolate::kNoDeoptId, | 1433 Isolate::kNoDeoptId, |
1433 token_pos); | 1434 token_pos); |
1434 } | 1435 } |
1435 #if defined(DEBUG) | 1436 #if defined(DEBUG) |
1436 if (!is_optimizing()) { | 1437 if (!is_optimizing()) { |
1437 // Do this *after* adding the pc descriptor! | 1438 // Do this *after* adding the pc descriptor! |
1438 __ LoadImmediate(S4, kInvalidObjectPointer); | 1439 __ LoadImmediate(S4, kInvalidObjectPointer); |
1439 __ LoadImmediate(S5, kInvalidObjectPointer); | 1440 __ LoadImmediate(S5, kInvalidObjectPointer); |
1440 } | 1441 } |
1441 #endif | 1442 #endif |
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1554 if (is_last_check) { | 1555 if (is_last_check) { |
1555 __ BranchNotEqual(class_id_reg, sorted[i].cid, deopt); | 1556 __ BranchNotEqual(class_id_reg, sorted[i].cid, deopt); |
1556 } else { | 1557 } else { |
1557 __ BranchNotEqual(class_id_reg, sorted[i].cid, &next_test); | 1558 __ BranchNotEqual(class_id_reg, sorted[i].cid, &next_test); |
1558 } | 1559 } |
1559 // Do not use the code from the function, but let the code be patched so | 1560 // Do not use the code from the function, but let the code be patched so |
1560 // that we can record the outgoing edges to other code. | 1561 // that we can record the outgoing edges to other code. |
1561 GenerateDartCall(deopt_id, | 1562 GenerateDartCall(deopt_id, |
1562 token_index, | 1563 token_index, |
1563 &StubCode::CallStaticFunctionLabel(), | 1564 &StubCode::CallStaticFunctionLabel(), |
1564 PcDescriptors::kOptStaticCall, | 1565 RawPcDescriptors::kOptStaticCall, |
1565 locs); | 1566 locs); |
1566 const Function& function = *sorted[i].target; | 1567 const Function& function = *sorted[i].target; |
1567 AddStaticCallTarget(function); | 1568 AddStaticCallTarget(function); |
1568 __ Drop(argument_count); | 1569 __ Drop(argument_count); |
1569 if (!is_last_check) { | 1570 if (!is_last_check) { |
1570 __ b(&match_found); | 1571 __ b(&match_found); |
1571 } | 1572 } |
1572 __ Bind(&next_test); | 1573 __ Bind(&next_test); |
1573 } | 1574 } |
1574 __ Bind(&match_found); | 1575 __ Bind(&match_found); |
(...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1807 __ AddImmediate(SP, kDoubleSize); | 1808 __ AddImmediate(SP, kDoubleSize); |
1808 } | 1809 } |
1809 | 1810 |
1810 | 1811 |
1811 #undef __ | 1812 #undef __ |
1812 | 1813 |
1813 | 1814 |
1814 } // namespace dart | 1815 } // namespace dart |
1815 | 1816 |
1816 #endif // defined TARGET_ARCH_MIPS | 1817 #endif // defined TARGET_ARCH_MIPS |
OLD | NEW |