| 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_ARM. | 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_ARM. |
| 6 #if defined(TARGET_ARCH_ARM) | 6 #if defined(TARGET_ARCH_ARM) |
| 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 1162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1173 AddDeoptIndexAtCall(deopt_id_after, token_pos); | 1173 AddDeoptIndexAtCall(deopt_id_after, token_pos); |
| 1174 } else { | 1174 } else { |
| 1175 // Add deoptimization continuation point after the call and before the | 1175 // Add deoptimization continuation point after the call and before the |
| 1176 // arguments are removed. | 1176 // arguments are removed. |
| 1177 AddCurrentDescriptor(RawPcDescriptors::kDeopt, | 1177 AddCurrentDescriptor(RawPcDescriptors::kDeopt, |
| 1178 deopt_id_after, token_pos); | 1178 deopt_id_after, token_pos); |
| 1179 } | 1179 } |
| 1180 } | 1180 } |
| 1181 | 1181 |
| 1182 | 1182 |
| 1183 void FlowGraphCompiler::GenerateStaticDartCall(intptr_t deopt_id, |
| 1184 TokenPosition token_pos, |
| 1185 const StubEntry& stub_entry, |
| 1186 RawPcDescriptors::Kind kind, |
| 1187 LocationSummary* locs, |
| 1188 const Function& target) { |
| 1189 // Call sites to the same target can share object pool entries. These |
| 1190 // call sites are never patched for breakpoints: the function is deoptimized |
| 1191 // and the unoptimized code with IC calls for static calls is patched instead. |
| 1192 ASSERT(is_optimizing()); |
| 1193 __ BranchLinkWithEquivalence(stub_entry, target); |
| 1194 |
| 1195 AddCurrentDescriptor(kind, deopt_id, token_pos); |
| 1196 RecordSafepoint(locs); |
| 1197 // Marks either the continuation point in unoptimized code or the |
| 1198 // deoptimization point in optimized code, after call. |
| 1199 const intptr_t deopt_id_after = Thread::ToDeoptAfter(deopt_id); |
| 1200 if (is_optimizing()) { |
| 1201 AddDeoptIndexAtCall(deopt_id_after, token_pos); |
| 1202 } else { |
| 1203 // Add deoptimization continuation point after the call and before the |
| 1204 // arguments are removed. |
| 1205 AddCurrentDescriptor(RawPcDescriptors::kDeopt, |
| 1206 deopt_id_after, token_pos); |
| 1207 } |
| 1208 AddStaticCallTarget(target); |
| 1209 } |
| 1210 |
| 1211 |
| 1183 void FlowGraphCompiler::GenerateRuntimeCall(TokenPosition token_pos, | 1212 void FlowGraphCompiler::GenerateRuntimeCall(TokenPosition token_pos, |
| 1184 intptr_t deopt_id, | 1213 intptr_t deopt_id, |
| 1185 const RuntimeEntry& entry, | 1214 const RuntimeEntry& entry, |
| 1186 intptr_t argument_count, | 1215 intptr_t argument_count, |
| 1187 LocationSummary* locs) { | 1216 LocationSummary* locs) { |
| 1188 __ CallRuntime(entry, argument_count); | 1217 __ CallRuntime(entry, argument_count); |
| 1189 AddCurrentDescriptor(RawPcDescriptors::kOther, deopt_id, token_pos); | 1218 AddCurrentDescriptor(RawPcDescriptors::kOther, deopt_id, token_pos); |
| 1190 RecordSafepoint(locs); | 1219 RecordSafepoint(locs); |
| 1191 if (deopt_id != Thread::kNoDeoptId) { | 1220 if (deopt_id != Thread::kNoDeoptId) { |
| 1192 // Marks either the continuation point in unoptimized code or the | 1221 // Marks either the continuation point in unoptimized code or the |
| (...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1386 void FlowGraphCompiler::EmitOptimizedStaticCall( | 1415 void FlowGraphCompiler::EmitOptimizedStaticCall( |
| 1387 const Function& function, | 1416 const Function& function, |
| 1388 const Array& arguments_descriptor, | 1417 const Array& arguments_descriptor, |
| 1389 intptr_t argument_count, | 1418 intptr_t argument_count, |
| 1390 intptr_t deopt_id, | 1419 intptr_t deopt_id, |
| 1391 TokenPosition token_pos, | 1420 TokenPosition token_pos, |
| 1392 LocationSummary* locs) { | 1421 LocationSummary* locs) { |
| 1393 __ LoadObject(R4, arguments_descriptor); | 1422 __ LoadObject(R4, arguments_descriptor); |
| 1394 // Do not use the code from the function, but let the code be patched so that | 1423 // Do not use the code from the function, but let the code be patched so that |
| 1395 // we can record the outgoing edges to other code. | 1424 // we can record the outgoing edges to other code. |
| 1396 GenerateDartCall(deopt_id, | 1425 GenerateStaticDartCall(deopt_id, |
| 1397 token_pos, | 1426 token_pos, |
| 1398 *StubCode::CallStaticFunction_entry(), | 1427 *StubCode::CallStaticFunction_entry(), |
| 1399 RawPcDescriptors::kOther, | 1428 RawPcDescriptors::kOther, |
| 1400 locs); | 1429 locs, |
| 1401 AddStaticCallTarget(function); | 1430 function); |
| 1402 __ Drop(argument_count); | 1431 __ Drop(argument_count); |
| 1403 } | 1432 } |
| 1404 | 1433 |
| 1405 | 1434 |
| 1406 Condition FlowGraphCompiler::EmitEqualityRegConstCompare( | 1435 Condition FlowGraphCompiler::EmitEqualityRegConstCompare( |
| 1407 Register reg, | 1436 Register reg, |
| 1408 const Object& obj, | 1437 const Object& obj, |
| 1409 bool needs_number_check, | 1438 bool needs_number_check, |
| 1410 TokenPosition token_pos) { | 1439 TokenPosition token_pos) { |
| 1411 if (needs_number_check) { | 1440 if (needs_number_check) { |
| (...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1584 __ tst(R0, Operand(kSmiTagMask)); | 1613 __ tst(R0, Operand(kSmiTagMask)); |
| 1585 if (kFirstCheckIsSmi) { | 1614 if (kFirstCheckIsSmi) { |
| 1586 // Jump if receiver is not Smi. | 1615 // Jump if receiver is not Smi. |
| 1587 if (kNumChecks == 1) { | 1616 if (kNumChecks == 1) { |
| 1588 __ b(failed, NE); | 1617 __ b(failed, NE); |
| 1589 } else { | 1618 } else { |
| 1590 __ b(&after_smi_test, NE); | 1619 __ b(&after_smi_test, NE); |
| 1591 } | 1620 } |
| 1592 // Do not use the code from the function, but let the code be patched so | 1621 // Do not use the code from the function, but let the code be patched so |
| 1593 // that we can record the outgoing edges to other code. | 1622 // that we can record the outgoing edges to other code. |
| 1594 GenerateDartCall(deopt_id, | |
| 1595 token_index, | |
| 1596 *StubCode::CallStaticFunction_entry(), | |
| 1597 RawPcDescriptors::kOther, | |
| 1598 locs); | |
| 1599 const Function& function = Function::ZoneHandle( | 1623 const Function& function = Function::ZoneHandle( |
| 1600 zone(), ic_data.GetTargetAt(0)); | 1624 zone(), ic_data.GetTargetAt(0)); |
| 1601 AddStaticCallTarget(function); | 1625 GenerateStaticDartCall(deopt_id, |
| 1626 token_index, |
| 1627 *StubCode::CallStaticFunction_entry(), |
| 1628 RawPcDescriptors::kOther, |
| 1629 locs, |
| 1630 function); |
| 1602 __ Drop(argument_count); | 1631 __ Drop(argument_count); |
| 1603 if (kNumChecks > 1) { | 1632 if (kNumChecks > 1) { |
| 1604 __ b(match_found); | 1633 __ b(match_found); |
| 1605 } | 1634 } |
| 1606 } else { | 1635 } else { |
| 1607 // Receiver is Smi, but Smi is not a valid class therefore fail. | 1636 // Receiver is Smi, but Smi is not a valid class therefore fail. |
| 1608 // (Smi class must be first in the list). | 1637 // (Smi class must be first in the list). |
| 1609 __ b(failed, EQ); | 1638 __ b(failed, EQ); |
| 1610 } | 1639 } |
| 1611 __ Bind(&after_smi_test); | 1640 __ Bind(&after_smi_test); |
| (...skipping 14 matching lines...) Expand all Loading... |
| 1626 ASSERT(sorted[i].cid != kSmiCid); | 1655 ASSERT(sorted[i].cid != kSmiCid); |
| 1627 Label next_test; | 1656 Label next_test; |
| 1628 __ CompareImmediate(R2, sorted[i].cid); | 1657 __ CompareImmediate(R2, sorted[i].cid); |
| 1629 if (kIsLastCheck) { | 1658 if (kIsLastCheck) { |
| 1630 __ b(failed, NE); | 1659 __ b(failed, NE); |
| 1631 } else { | 1660 } else { |
| 1632 __ b(&next_test, NE); | 1661 __ b(&next_test, NE); |
| 1633 } | 1662 } |
| 1634 // Do not use the code from the function, but let the code be patched so | 1663 // Do not use the code from the function, but let the code be patched so |
| 1635 // that we can record the outgoing edges to other code. | 1664 // that we can record the outgoing edges to other code. |
| 1636 GenerateDartCall(deopt_id, | |
| 1637 token_index, | |
| 1638 *StubCode::CallStaticFunction_entry(), | |
| 1639 RawPcDescriptors::kOther, | |
| 1640 locs); | |
| 1641 const Function& function = *sorted[i].target; | 1665 const Function& function = *sorted[i].target; |
| 1642 AddStaticCallTarget(function); | 1666 GenerateStaticDartCall(deopt_id, |
| 1667 token_index, |
| 1668 *StubCode::CallStaticFunction_entry(), |
| 1669 RawPcDescriptors::kOther, |
| 1670 locs, |
| 1671 function); |
| 1643 __ Drop(argument_count); | 1672 __ Drop(argument_count); |
| 1644 if (!kIsLastCheck) { | 1673 if (!kIsLastCheck) { |
| 1645 __ b(match_found); | 1674 __ b(match_found); |
| 1646 } | 1675 } |
| 1647 __ Bind(&next_test); | 1676 __ Bind(&next_test); |
| 1648 } | 1677 } |
| 1649 } | 1678 } |
| 1650 | 1679 |
| 1651 | 1680 |
| 1652 #undef __ | 1681 #undef __ |
| (...skipping 292 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1945 DRegister dreg = EvenDRegisterOf(reg); | 1974 DRegister dreg = EvenDRegisterOf(reg); |
| 1946 __ vldrd(dreg, Address(SP, kDoubleSize, Address::PostIndex)); | 1975 __ vldrd(dreg, Address(SP, kDoubleSize, Address::PostIndex)); |
| 1947 } | 1976 } |
| 1948 | 1977 |
| 1949 | 1978 |
| 1950 #undef __ | 1979 #undef __ |
| 1951 | 1980 |
| 1952 } // namespace dart | 1981 } // namespace dart |
| 1953 | 1982 |
| 1954 #endif // defined TARGET_ARCH_ARM | 1983 #endif // defined TARGET_ARCH_ARM |
| OLD | NEW |