| 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 1176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1187 } else { | 1187 } else { |
| 1188 // Add deoptimization continuation point after the call and before the | 1188 // Add deoptimization continuation point after the call and before the |
| 1189 // arguments are removed. | 1189 // arguments are removed. |
| 1190 AddCurrentDescriptor(RawPcDescriptors::kDeopt, | 1190 AddCurrentDescriptor(RawPcDescriptors::kDeopt, |
| 1191 deopt_id_after, | 1191 deopt_id_after, |
| 1192 token_pos); | 1192 token_pos); |
| 1193 } | 1193 } |
| 1194 } | 1194 } |
| 1195 | 1195 |
| 1196 | 1196 |
| 1197 void FlowGraphCompiler::GenerateStaticDartCall(intptr_t deopt_id, |
| 1198 TokenPosition token_pos, |
| 1199 const StubEntry& stub_entry, |
| 1200 RawPcDescriptors::Kind kind, |
| 1201 LocationSummary* locs, |
| 1202 const Function& target) { |
| 1203 // Call sites to the same target can share object pool entries. These |
| 1204 // call sites are never patched for breakpoints: the function is deoptimized |
| 1205 // and the unoptimized code with IC calls for static calls is patched instead. |
| 1206 ASSERT(is_optimizing()); |
| 1207 __ BranchLinkWithEquivalence(stub_entry, target); |
| 1208 |
| 1209 AddCurrentDescriptor(kind, deopt_id, token_pos); |
| 1210 RecordSafepoint(locs); |
| 1211 // Marks either the continuation point in unoptimized code or the |
| 1212 // deoptimization point in optimized code, after call. |
| 1213 const intptr_t deopt_id_after = Thread::ToDeoptAfter(deopt_id); |
| 1214 if (is_optimizing()) { |
| 1215 AddDeoptIndexAtCall(deopt_id_after, token_pos); |
| 1216 } else { |
| 1217 // Add deoptimization continuation point after the call and before the |
| 1218 // arguments are removed. |
| 1219 AddCurrentDescriptor(RawPcDescriptors::kDeopt, |
| 1220 deopt_id_after, |
| 1221 token_pos); |
| 1222 } |
| 1223 AddStaticCallTarget(target); |
| 1224 } |
| 1225 |
| 1226 |
| 1197 void FlowGraphCompiler::GenerateRuntimeCall(TokenPosition token_pos, | 1227 void FlowGraphCompiler::GenerateRuntimeCall(TokenPosition token_pos, |
| 1198 intptr_t deopt_id, | 1228 intptr_t deopt_id, |
| 1199 const RuntimeEntry& entry, | 1229 const RuntimeEntry& entry, |
| 1200 intptr_t argument_count, | 1230 intptr_t argument_count, |
| 1201 LocationSummary* locs) { | 1231 LocationSummary* locs) { |
| 1202 __ CallRuntime(entry, argument_count); | 1232 __ CallRuntime(entry, argument_count); |
| 1203 AddCurrentDescriptor(RawPcDescriptors::kOther, deopt_id, token_pos); | 1233 AddCurrentDescriptor(RawPcDescriptors::kOther, deopt_id, token_pos); |
| 1204 RecordSafepoint(locs); | 1234 RecordSafepoint(locs); |
| 1205 if (deopt_id != Thread::kNoDeoptId) { | 1235 if (deopt_id != Thread::kNoDeoptId) { |
| 1206 // Marks either the continuation point in unoptimized code or the | 1236 // Marks either the continuation point in unoptimized code or the |
| (...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1393 const Function& function, | 1423 const Function& function, |
| 1394 const Array& arguments_descriptor, | 1424 const Array& arguments_descriptor, |
| 1395 intptr_t argument_count, | 1425 intptr_t argument_count, |
| 1396 intptr_t deopt_id, | 1426 intptr_t deopt_id, |
| 1397 TokenPosition token_pos, | 1427 TokenPosition token_pos, |
| 1398 LocationSummary* locs) { | 1428 LocationSummary* locs) { |
| 1399 __ Comment("StaticCall"); | 1429 __ Comment("StaticCall"); |
| 1400 __ LoadObject(S4, arguments_descriptor); | 1430 __ LoadObject(S4, arguments_descriptor); |
| 1401 // Do not use the code from the function, but let the code be patched so that | 1431 // Do not use the code from the function, but let the code be patched so that |
| 1402 // we can record the outgoing edges to other code. | 1432 // we can record the outgoing edges to other code. |
| 1403 GenerateDartCall(deopt_id, | 1433 GenerateStaticDartCall(deopt_id, |
| 1404 token_pos, | 1434 token_pos, |
| 1405 *StubCode::CallStaticFunction_entry(), | 1435 *StubCode::CallStaticFunction_entry(), |
| 1406 RawPcDescriptors::kOther, | 1436 RawPcDescriptors::kOther, |
| 1407 locs); | 1437 locs, |
| 1408 AddStaticCallTarget(function); | 1438 function); |
| 1409 __ Drop(argument_count); | 1439 __ Drop(argument_count); |
| 1410 } | 1440 } |
| 1411 | 1441 |
| 1412 | 1442 |
| 1413 Condition FlowGraphCompiler::EmitEqualityRegConstCompare( | 1443 Condition FlowGraphCompiler::EmitEqualityRegConstCompare( |
| 1414 Register reg, | 1444 Register reg, |
| 1415 const Object& obj, | 1445 const Object& obj, |
| 1416 bool needs_number_check, | 1446 bool needs_number_check, |
| 1417 TokenPosition token_pos) { | 1447 TokenPosition token_pos) { |
| 1418 __ Comment("EqualityRegConstCompare"); | 1448 __ Comment("EqualityRegConstCompare"); |
| (...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1607 __ andi(CMPRES1, T0, Immediate(kSmiTagMask)); | 1637 __ andi(CMPRES1, T0, Immediate(kSmiTagMask)); |
| 1608 if (kFirstCheckIsSmi) { | 1638 if (kFirstCheckIsSmi) { |
| 1609 // Jump if receiver is not Smi. | 1639 // Jump if receiver is not Smi. |
| 1610 if (kNumChecks == 1) { | 1640 if (kNumChecks == 1) { |
| 1611 __ bne(CMPRES1, ZR, failed); | 1641 __ bne(CMPRES1, ZR, failed); |
| 1612 } else { | 1642 } else { |
| 1613 __ bne(CMPRES1, ZR, &after_smi_test); | 1643 __ bne(CMPRES1, ZR, &after_smi_test); |
| 1614 } | 1644 } |
| 1615 // Do not use the code from the function, but let the code be patched so | 1645 // Do not use the code from the function, but let the code be patched so |
| 1616 // that we can record the outgoing edges to other code. | 1646 // that we can record the outgoing edges to other code. |
| 1617 GenerateDartCall(deopt_id, | |
| 1618 token_index, | |
| 1619 *StubCode::CallStaticFunction_entry(), | |
| 1620 RawPcDescriptors::kOther, | |
| 1621 locs); | |
| 1622 const Function& function = Function::ZoneHandle( | 1647 const Function& function = Function::ZoneHandle( |
| 1623 zone(), ic_data.GetTargetAt(0)); | 1648 zone(), ic_data.GetTargetAt(0)); |
| 1624 AddStaticCallTarget(function); | 1649 GenerateStaticDartCall(deopt_id, |
| 1650 token_index, |
| 1651 *StubCode::CallStaticFunction_entry(), |
| 1652 RawPcDescriptors::kOther, |
| 1653 locs, |
| 1654 function); |
| 1625 __ Drop(argument_count); | 1655 __ Drop(argument_count); |
| 1626 if (kNumChecks > 1) { | 1656 if (kNumChecks > 1) { |
| 1627 __ b(match_found); | 1657 __ b(match_found); |
| 1628 } | 1658 } |
| 1629 } else { | 1659 } else { |
| 1630 // Receiver is Smi, but Smi is not a valid class therefore fail. | 1660 // Receiver is Smi, but Smi is not a valid class therefore fail. |
| 1631 // (Smi class must be first in the list). | 1661 // (Smi class must be first in the list). |
| 1632 __ beq(CMPRES1, ZR, failed); | 1662 __ beq(CMPRES1, ZR, failed); |
| 1633 } | 1663 } |
| 1634 | 1664 |
| (...skipping 13 matching lines...) Expand all Loading... |
| 1648 const bool kIsLastCheck = (i == (kSortedLen - 1)); | 1678 const bool kIsLastCheck = (i == (kSortedLen - 1)); |
| 1649 ASSERT(sorted[i].cid != kSmiCid); | 1679 ASSERT(sorted[i].cid != kSmiCid); |
| 1650 Label next_test; | 1680 Label next_test; |
| 1651 if (kIsLastCheck) { | 1681 if (kIsLastCheck) { |
| 1652 __ BranchNotEqual(T2, Immediate(sorted[i].cid), failed); | 1682 __ BranchNotEqual(T2, Immediate(sorted[i].cid), failed); |
| 1653 } else { | 1683 } else { |
| 1654 __ BranchNotEqual(T2, Immediate(sorted[i].cid), &next_test); | 1684 __ BranchNotEqual(T2, Immediate(sorted[i].cid), &next_test); |
| 1655 } | 1685 } |
| 1656 // Do not use the code from the function, but let the code be patched so | 1686 // Do not use the code from the function, but let the code be patched so |
| 1657 // that we can record the outgoing edges to other code. | 1687 // that we can record the outgoing edges to other code. |
| 1658 GenerateDartCall(deopt_id, | |
| 1659 token_index, | |
| 1660 *StubCode::CallStaticFunction_entry(), | |
| 1661 RawPcDescriptors::kOther, | |
| 1662 locs); | |
| 1663 const Function& function = *sorted[i].target; | 1688 const Function& function = *sorted[i].target; |
| 1664 AddStaticCallTarget(function); | 1689 GenerateStaticDartCall(deopt_id, |
| 1690 token_index, |
| 1691 *StubCode::CallStaticFunction_entry(), |
| 1692 RawPcDescriptors::kOther, |
| 1693 locs, |
| 1694 function); |
| 1665 __ Drop(argument_count); | 1695 __ Drop(argument_count); |
| 1666 if (!kIsLastCheck) { | 1696 if (!kIsLastCheck) { |
| 1667 __ b(match_found); | 1697 __ b(match_found); |
| 1668 } | 1698 } |
| 1669 __ Bind(&next_test); | 1699 __ Bind(&next_test); |
| 1670 } | 1700 } |
| 1671 } | 1701 } |
| 1672 | 1702 |
| 1673 | 1703 |
| 1674 #undef __ | 1704 #undef __ |
| (...skipping 234 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1909 __ AddImmediate(SP, kDoubleSize); | 1939 __ AddImmediate(SP, kDoubleSize); |
| 1910 } | 1940 } |
| 1911 | 1941 |
| 1912 | 1942 |
| 1913 #undef __ | 1943 #undef __ |
| 1914 | 1944 |
| 1915 | 1945 |
| 1916 } // namespace dart | 1946 } // namespace dart |
| 1917 | 1947 |
| 1918 #endif // defined TARGET_ARCH_MIPS | 1948 #endif // defined TARGET_ARCH_MIPS |
| OLD | NEW |