| OLD | NEW |
| 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2014, 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_ARM64. | 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_ARM64. |
| 6 #if defined(TARGET_ARCH_ARM64) | 6 #if defined(TARGET_ARCH_ARM64) |
| 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 1154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1165 if (is_optimizing()) { | 1165 if (is_optimizing()) { |
| 1166 AddDeoptIndexAtCall(deopt_id_after, token_pos); | 1166 AddDeoptIndexAtCall(deopt_id_after, token_pos); |
| 1167 } else { | 1167 } else { |
| 1168 // Add deoptimization continuation point after the call and before the | 1168 // Add deoptimization continuation point after the call and before the |
| 1169 // arguments are removed. | 1169 // arguments are removed. |
| 1170 AddCurrentDescriptor(RawPcDescriptors::kDeopt, deopt_id_after, token_pos); | 1170 AddCurrentDescriptor(RawPcDescriptors::kDeopt, deopt_id_after, token_pos); |
| 1171 } | 1171 } |
| 1172 } | 1172 } |
| 1173 | 1173 |
| 1174 | 1174 |
| 1175 void FlowGraphCompiler::GenerateStaticDartCall(intptr_t deopt_id, |
| 1176 TokenPosition token_pos, |
| 1177 const StubEntry& stub_entry, |
| 1178 RawPcDescriptors::Kind kind, |
| 1179 LocationSummary* locs, |
| 1180 const Function& target) { |
| 1181 // Call sites to the same target can share object pool entries. These |
| 1182 // call sites are never patched for breakpoints: the function is deoptimized |
| 1183 // and the unoptimized code with IC calls for static calls is patched instead. |
| 1184 ASSERT(is_optimizing()); |
| 1185 __ BranchLinkWithEquivalence(stub_entry, target); |
| 1186 |
| 1187 AddCurrentDescriptor(kind, deopt_id, token_pos); |
| 1188 RecordSafepoint(locs); |
| 1189 // Marks either the continuation point in unoptimized code or the |
| 1190 // deoptimization point in optimized code, after call. |
| 1191 const intptr_t deopt_id_after = Thread::ToDeoptAfter(deopt_id); |
| 1192 if (is_optimizing()) { |
| 1193 AddDeoptIndexAtCall(deopt_id_after, token_pos); |
| 1194 } else { |
| 1195 // Add deoptimization continuation point after the call and before the |
| 1196 // arguments are removed. |
| 1197 AddCurrentDescriptor(RawPcDescriptors::kDeopt, deopt_id_after, token_pos); |
| 1198 } |
| 1199 AddStaticCallTarget(target); |
| 1200 } |
| 1201 |
| 1202 |
| 1175 void FlowGraphCompiler::GenerateRuntimeCall(TokenPosition token_pos, | 1203 void FlowGraphCompiler::GenerateRuntimeCall(TokenPosition token_pos, |
| 1176 intptr_t deopt_id, | 1204 intptr_t deopt_id, |
| 1177 const RuntimeEntry& entry, | 1205 const RuntimeEntry& entry, |
| 1178 intptr_t argument_count, | 1206 intptr_t argument_count, |
| 1179 LocationSummary* locs) { | 1207 LocationSummary* locs) { |
| 1180 __ CallRuntime(entry, argument_count); | 1208 __ CallRuntime(entry, argument_count); |
| 1181 AddCurrentDescriptor(RawPcDescriptors::kOther, deopt_id, token_pos); | 1209 AddCurrentDescriptor(RawPcDescriptors::kOther, deopt_id, token_pos); |
| 1182 RecordSafepoint(locs); | 1210 RecordSafepoint(locs); |
| 1183 if (deopt_id != Thread::kNoDeoptId) { | 1211 if (deopt_id != Thread::kNoDeoptId) { |
| 1184 // Marks either the continuation point in unoptimized code or the | 1212 // Marks either the continuation point in unoptimized code or the |
| (...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1367 void FlowGraphCompiler::EmitOptimizedStaticCall( | 1395 void FlowGraphCompiler::EmitOptimizedStaticCall( |
| 1368 const Function& function, | 1396 const Function& function, |
| 1369 const Array& arguments_descriptor, | 1397 const Array& arguments_descriptor, |
| 1370 intptr_t argument_count, | 1398 intptr_t argument_count, |
| 1371 intptr_t deopt_id, | 1399 intptr_t deopt_id, |
| 1372 TokenPosition token_pos, | 1400 TokenPosition token_pos, |
| 1373 LocationSummary* locs) { | 1401 LocationSummary* locs) { |
| 1374 __ LoadObject(R4, arguments_descriptor); | 1402 __ LoadObject(R4, arguments_descriptor); |
| 1375 // Do not use the code from the function, but let the code be patched so that | 1403 // Do not use the code from the function, but let the code be patched so that |
| 1376 // we can record the outgoing edges to other code. | 1404 // we can record the outgoing edges to other code. |
| 1377 GenerateDartCall(deopt_id, | 1405 GenerateStaticDartCall(deopt_id, |
| 1378 token_pos, | 1406 token_pos, |
| 1379 *StubCode::CallStaticFunction_entry(), | 1407 *StubCode::CallStaticFunction_entry(), |
| 1380 RawPcDescriptors::kOther, | 1408 RawPcDescriptors::kOther, |
| 1381 locs); | 1409 locs, |
| 1382 AddStaticCallTarget(function); | 1410 function); |
| 1383 __ Drop(argument_count); | 1411 __ Drop(argument_count); |
| 1384 } | 1412 } |
| 1385 | 1413 |
| 1386 | 1414 |
| 1387 Condition FlowGraphCompiler::EmitEqualityRegConstCompare( | 1415 Condition FlowGraphCompiler::EmitEqualityRegConstCompare( |
| 1388 Register reg, | 1416 Register reg, |
| 1389 const Object& obj, | 1417 const Object& obj, |
| 1390 bool needs_number_check, | 1418 bool needs_number_check, |
| 1391 TokenPosition token_pos) { | 1419 TokenPosition token_pos) { |
| 1392 if (needs_number_check) { | 1420 if (needs_number_check) { |
| (...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1541 __ tsti(R0, Immediate(kSmiTagMask)); | 1569 __ tsti(R0, Immediate(kSmiTagMask)); |
| 1542 if (kFirstCheckIsSmi) { | 1570 if (kFirstCheckIsSmi) { |
| 1543 // Jump if receiver is not Smi. | 1571 // Jump if receiver is not Smi. |
| 1544 if (kNumChecks == 1) { | 1572 if (kNumChecks == 1) { |
| 1545 __ b(failed, NE); | 1573 __ b(failed, NE); |
| 1546 } else { | 1574 } else { |
| 1547 __ b(&after_smi_test, NE); | 1575 __ b(&after_smi_test, NE); |
| 1548 } | 1576 } |
| 1549 // Do not use the code from the function, but let the code be patched so | 1577 // Do not use the code from the function, but let the code be patched so |
| 1550 // that we can record the outgoing edges to other code. | 1578 // that we can record the outgoing edges to other code. |
| 1551 GenerateDartCall(deopt_id, | |
| 1552 token_index, | |
| 1553 *StubCode::CallStaticFunction_entry(), | |
| 1554 RawPcDescriptors::kOther, | |
| 1555 locs); | |
| 1556 const Function& function = Function::ZoneHandle( | 1579 const Function& function = Function::ZoneHandle( |
| 1557 zone(), ic_data.GetTargetAt(0)); | 1580 zone(), ic_data.GetTargetAt(0)); |
| 1558 AddStaticCallTarget(function); | 1581 GenerateStaticDartCall(deopt_id, |
| 1582 token_index, |
| 1583 *StubCode::CallStaticFunction_entry(), |
| 1584 RawPcDescriptors::kOther, |
| 1585 locs, |
| 1586 function); |
| 1559 __ Drop(argument_count); | 1587 __ Drop(argument_count); |
| 1560 if (kNumChecks > 1) { | 1588 if (kNumChecks > 1) { |
| 1561 __ b(match_found); | 1589 __ b(match_found); |
| 1562 } | 1590 } |
| 1563 } else { | 1591 } else { |
| 1564 // Receiver is Smi, but Smi is not a valid class therefore fail. | 1592 // Receiver is Smi, but Smi is not a valid class therefore fail. |
| 1565 // (Smi class must be first in the list). | 1593 // (Smi class must be first in the list). |
| 1566 __ b(failed, EQ); | 1594 __ b(failed, EQ); |
| 1567 } | 1595 } |
| 1568 __ Bind(&after_smi_test); | 1596 __ Bind(&after_smi_test); |
| (...skipping 14 matching lines...) Expand all Loading... |
| 1583 ASSERT(sorted[i].cid != kSmiCid); | 1611 ASSERT(sorted[i].cid != kSmiCid); |
| 1584 Label next_test; | 1612 Label next_test; |
| 1585 __ CompareImmediate(R2, sorted[i].cid); | 1613 __ CompareImmediate(R2, sorted[i].cid); |
| 1586 if (kIsLastCheck) { | 1614 if (kIsLastCheck) { |
| 1587 __ b(failed, NE); | 1615 __ b(failed, NE); |
| 1588 } else { | 1616 } else { |
| 1589 __ b(&next_test, NE); | 1617 __ b(&next_test, NE); |
| 1590 } | 1618 } |
| 1591 // Do not use the code from the function, but let the code be patched so | 1619 // Do not use the code from the function, but let the code be patched so |
| 1592 // that we can record the outgoing edges to other code. | 1620 // that we can record the outgoing edges to other code. |
| 1593 GenerateDartCall(deopt_id, | |
| 1594 token_index, | |
| 1595 *StubCode::CallStaticFunction_entry(), | |
| 1596 RawPcDescriptors::kOther, | |
| 1597 locs); | |
| 1598 const Function& function = *sorted[i].target; | 1621 const Function& function = *sorted[i].target; |
| 1599 AddStaticCallTarget(function); | 1622 GenerateStaticDartCall(deopt_id, |
| 1623 token_index, |
| 1624 *StubCode::CallStaticFunction_entry(), |
| 1625 RawPcDescriptors::kOther, |
| 1626 locs, |
| 1627 function); |
| 1600 __ Drop(argument_count); | 1628 __ Drop(argument_count); |
| 1601 if (!kIsLastCheck) { | 1629 if (!kIsLastCheck) { |
| 1602 __ b(match_found); | 1630 __ b(match_found); |
| 1603 } | 1631 } |
| 1604 __ Bind(&next_test); | 1632 __ Bind(&next_test); |
| 1605 } | 1633 } |
| 1606 } | 1634 } |
| 1607 | 1635 |
| 1608 | 1636 |
| 1609 #undef __ | 1637 #undef __ |
| (...skipping 273 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1883 void ParallelMoveResolver::RestoreFpuScratch(FpuRegister reg) { | 1911 void ParallelMoveResolver::RestoreFpuScratch(FpuRegister reg) { |
| 1884 __ PopDouble(reg); | 1912 __ PopDouble(reg); |
| 1885 } | 1913 } |
| 1886 | 1914 |
| 1887 | 1915 |
| 1888 #undef __ | 1916 #undef __ |
| 1889 | 1917 |
| 1890 } // namespace dart | 1918 } // namespace dart |
| 1891 | 1919 |
| 1892 #endif // defined TARGET_ARCH_ARM64 | 1920 #endif // defined TARGET_ARCH_ARM64 |
| OLD | NEW |