| 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" | 5 #include "vm/globals.h" |
| 6 #if defined(TARGET_ARCH_X64) | 6 #if defined(TARGET_ARCH_X64) |
| 7 | 7 |
| 8 #include "vm/assembler.h" | 8 #include "vm/assembler.h" |
| 9 #include "vm/compiler.h" | 9 #include "vm/compiler.h" |
| 10 #include "vm/dart_entry.h" | 10 #include "vm/dart_entry.h" |
| (...skipping 1544 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1555 // type feedback. | 1555 // type feedback. |
| 1556 __ movb(FieldAddress(RBX, ICData::is_closure_call_offset()), Immediate(1)); | 1556 __ movb(FieldAddress(RBX, ICData::is_closure_call_offset()), Immediate(1)); |
| 1557 __ jmp(&StubCode::InstanceFunctionLookupLabel()); | 1557 __ jmp(&StubCode::InstanceFunctionLookupLabel()); |
| 1558 | 1558 |
| 1559 __ Bind(&found); | 1559 __ Bind(&found); |
| 1560 // R12: Pointer to an IC data check group. | 1560 // R12: Pointer to an IC data check group. |
| 1561 const intptr_t target_offset = ICData::TargetIndexFor(num_args) * kWordSize; | 1561 const intptr_t target_offset = ICData::TargetIndexFor(num_args) * kWordSize; |
| 1562 const intptr_t count_offset = ICData::CountIndexFor(num_args) * kWordSize; | 1562 const intptr_t count_offset = ICData::CountIndexFor(num_args) * kWordSize; |
| 1563 __ movq(RAX, Address(R12, target_offset)); | 1563 __ movq(RAX, Address(R12, target_offset)); |
| 1564 __ addq(Address(R12, count_offset), Immediate(Smi::RawValue(1))); | 1564 __ addq(Address(R12, count_offset), Immediate(Smi::RawValue(1))); |
| 1565 __ j(NO_OVERFLOW, &call_target_function); | 1565 __ j(NO_OVERFLOW, &call_target_function, Assembler::kNearJump); |
| 1566 __ movq(Address(R12, count_offset), | 1566 __ movq(Address(R12, count_offset), |
| 1567 Immediate(Smi::RawValue(Smi::kMaxValue))); | 1567 Immediate(Smi::RawValue(Smi::kMaxValue))); |
| 1568 | 1568 |
| 1569 __ Bind(&call_target_function); | 1569 __ Bind(&call_target_function); |
| 1570 // RAX: Target function. | 1570 // RAX: Target function. |
| 1571 __ movq(RAX, FieldAddress(RAX, Function::code_offset())); | 1571 __ movq(RAX, FieldAddress(RAX, Function::code_offset())); |
| 1572 __ movq(RAX, FieldAddress(RAX, Code::instructions_offset())); | 1572 __ movq(RAX, FieldAddress(RAX, Code::instructions_offset())); |
| 1573 __ addq(RAX, Immediate(Instructions::HeaderSize() - kHeapObjectTag)); | 1573 __ addq(RAX, Immediate(Instructions::HeaderSize() - kHeapObjectTag)); |
| 1574 __ jmp(RAX); | 1574 __ jmp(RAX); |
| 1575 | 1575 |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1653 } | 1653 } |
| 1654 | 1654 |
| 1655 | 1655 |
| 1656 // Megamorphic call is currently implemented as IC call but through a stub | 1656 // Megamorphic call is currently implemented as IC call but through a stub |
| 1657 // that does not check/count function invocations. | 1657 // that does not check/count function invocations. |
| 1658 void StubCode::GenerateMegamorphicCallStub(Assembler* assembler) { | 1658 void StubCode::GenerateMegamorphicCallStub(Assembler* assembler) { |
| 1659 GenerateNArgsCheckInlineCacheStub(assembler, 1); | 1659 GenerateNArgsCheckInlineCacheStub(assembler, 1); |
| 1660 } | 1660 } |
| 1661 | 1661 |
| 1662 | 1662 |
| 1663 // Intermediary stub between a static call and its target. ICData contains |
| 1664 // the target function and the call count. |
| 1665 // RBX: ICData |
| 1666 void StubCode::GenerateUnoptimizedStaticCallStub(Assembler* assembler) { |
| 1667 GenerateUsageCounterIncrement(assembler, RCX); |
| 1668 #if defined(DEBUG) |
| 1669 { Label ok; |
| 1670 // Check that the IC data array has NumberOfArgumentsChecked() == 0. |
| 1671 // 'num_args_tested' is stored as an untagged int. |
| 1672 __ movq(RCX, FieldAddress(RBX, ICData::num_args_tested_offset())); |
| 1673 __ cmpq(RCX, Immediate(0)); |
| 1674 __ j(EQUAL, &ok, Assembler::kNearJump); |
| 1675 __ Stop("Incorrect IC data for unoptimized static call"); |
| 1676 __ Bind(&ok); |
| 1677 } |
| 1678 #endif // DEBUG |
| 1679 |
| 1680 // RBX: IC data object (preserved). |
| 1681 __ movq(R12, FieldAddress(RBX, ICData::ic_data_offset())); |
| 1682 // R12: ic_data_array with entries: target functions and count. |
| 1683 __ leaq(R12, FieldAddress(R12, Array::data_offset())); |
| 1684 // R12: points directly to the first ic data array element. |
| 1685 const intptr_t target_offset = ICData::TargetIndexFor(0) * kWordSize; |
| 1686 const intptr_t count_offset = ICData::CountIndexFor(0) * kWordSize; |
| 1687 |
| 1688 // Increment count for this call. |
| 1689 Label increment_done; |
| 1690 __ addq(Address(R12, count_offset), Immediate(Smi::RawValue(1))); |
| 1691 __ j(NO_OVERFLOW, &increment_done, Assembler::kNearJump); |
| 1692 __ movq(Address(R12, count_offset), |
| 1693 Immediate(Smi::RawValue(Smi::kMaxValue))); |
| 1694 __ Bind(&increment_done); |
| 1695 |
| 1696 const Immediate& raw_null = |
| 1697 Immediate(reinterpret_cast<intptr_t>(Object::null())); |
| 1698 Label target_is_compiled; |
| 1699 // Get function and call it, if possible. |
| 1700 __ movq(R13, Address(R12, target_offset)); |
| 1701 __ movq(RAX, FieldAddress(R13, Function::code_offset())); |
| 1702 __ cmpq(RAX, raw_null); |
| 1703 __ j(NOT_EQUAL, &target_is_compiled, Assembler::kNearJump); |
| 1704 |
| 1705 __ EnterStubFrame(); |
| 1706 __ pushq(R13); // Preserve target function. |
| 1707 __ pushq(RBX); // Preserve IC data object. |
| 1708 __ pushq(R13); // Pass function. |
| 1709 __ CallRuntime(kCompileFunctionRuntimeEntry); |
| 1710 __ popq(RAX); // Discard argument. |
| 1711 __ popq(RBX); // Restore IC data object. |
| 1712 __ popq(R13); // Restore target function. |
| 1713 __ LeaveFrame(); |
| 1714 __ movq(RAX, FieldAddress(R13, Function::code_offset())); |
| 1715 |
| 1716 __ Bind(&target_is_compiled); |
| 1717 // RAX: Target code. |
| 1718 __ movq(RAX, FieldAddress(RAX, Code::instructions_offset())); |
| 1719 __ addq(RAX, Immediate(Instructions::HeaderSize() - kHeapObjectTag)); |
| 1720 // Load arguments descriptor into R10. |
| 1721 __ movq(R10, FieldAddress(RBX, ICData::arguments_descriptor_offset())); |
| 1722 __ jmp(RAX); |
| 1723 } |
| 1724 |
| 1725 |
| 1663 // RBX, R10: May contain arguments to runtime stub. | 1726 // RBX, R10: May contain arguments to runtime stub. |
| 1664 // TOS(0): return address (Dart code). | 1727 // TOS(0): return address (Dart code). |
| 1665 void StubCode::GenerateBreakpointRuntimeStub(Assembler* assembler) { | 1728 void StubCode::GenerateBreakpointRuntimeStub(Assembler* assembler) { |
| 1666 __ EnterStubFrame(); | 1729 __ EnterStubFrame(); |
| 1667 // Preserve runtime args. | 1730 // Preserve runtime args. |
| 1668 __ pushq(RBX); | 1731 __ pushq(RBX); |
| 1669 __ pushq(R10); | 1732 __ pushq(R10); |
| 1670 // Room for result. Debugger stub returns address of the | 1733 // Room for result. Debugger stub returns address of the |
| 1671 // unpatched runtime stub. | 1734 // unpatched runtime stub. |
| 1672 const Immediate& raw_null = | 1735 const Immediate& raw_null = |
| 1673 Immediate(reinterpret_cast<intptr_t>(Object::null())); | 1736 Immediate(reinterpret_cast<intptr_t>(Object::null())); |
| 1674 __ pushq(raw_null); // Room for result. | 1737 __ pushq(raw_null); // Room for result. |
| 1675 __ CallRuntime(kBreakpointRuntimeHandlerRuntimeEntry); | 1738 __ CallRuntime(kBreakpointRuntimeHandlerRuntimeEntry); |
| 1676 __ popq(RAX); // Address of original. | 1739 __ popq(RAX); // Address of original. |
| 1677 __ popq(R10); // Restore arguments. | 1740 __ popq(R10); // Restore arguments. |
| 1678 __ popq(RBX); | 1741 __ popq(RBX); |
| 1679 __ LeaveFrame(); | 1742 __ LeaveFrame(); |
| 1680 __ jmp(RAX); // Jump to original stub. | 1743 __ jmp(RAX); // Jump to original stub. |
| 1681 } | 1744 } |
| 1682 | 1745 |
| 1683 | 1746 |
| 1747 // RBX: ICData (unoptimized static call) |
| 1684 // TOS(0): return address (Dart code). | 1748 // TOS(0): return address (Dart code). |
| 1685 void StubCode::GenerateBreakpointStaticStub(Assembler* assembler) { | 1749 void StubCode::GenerateBreakpointStaticStub(Assembler* assembler) { |
| 1686 const Immediate& raw_null = | 1750 const Immediate& raw_null = |
| 1687 Immediate(reinterpret_cast<intptr_t>(Object::null())); | 1751 Immediate(reinterpret_cast<intptr_t>(Object::null())); |
| 1688 __ EnterStubFrame(); | 1752 __ EnterStubFrame(); |
| 1689 __ pushq(R10); // Preserve arguments descriptor. | 1753 __ pushq(RBX); // Preserve IC data for unoptimized call. |
| 1690 __ pushq(raw_null); // Room for result. | 1754 __ pushq(raw_null); // Room for result. |
| 1691 __ CallRuntime(kBreakpointStaticHandlerRuntimeEntry); | 1755 __ CallRuntime(kBreakpointStaticHandlerRuntimeEntry); |
| 1692 __ popq(RAX); // Code object. | 1756 __ popq(RAX); // Code object. |
| 1693 __ popq(R10); // Restore arguments descriptor. | 1757 __ popq(RBX); // Restore IC data. |
| 1694 __ LeaveFrame(); | 1758 __ LeaveFrame(); |
| 1695 | 1759 |
| 1760 // Load arguments descriptor into R10. |
| 1761 __ movq(R10, FieldAddress(RBX, ICData::arguments_descriptor_offset())); |
| 1696 // Now call the static function. The breakpoint handler function | 1762 // Now call the static function. The breakpoint handler function |
| 1697 // ensures that the call target is compiled. | 1763 // ensures that the call target is compiled. |
| 1698 __ movq(RBX, FieldAddress(RAX, Code::instructions_offset())); | 1764 __ movq(RBX, FieldAddress(RAX, Code::instructions_offset())); |
| 1699 __ addq(RBX, Immediate(Instructions::HeaderSize() - kHeapObjectTag)); | 1765 __ addq(RBX, Immediate(Instructions::HeaderSize() - kHeapObjectTag)); |
| 1700 __ jmp(RBX); | 1766 __ jmp(RBX); |
| 1701 } | 1767 } |
| 1702 | 1768 |
| 1703 | 1769 |
| 1704 // TOS(0): return address (Dart code). | 1770 // TOS(0): return address (Dart code). |
| 1705 void StubCode::GenerateBreakpointReturnStub(Assembler* assembler) { | 1771 void StubCode::GenerateBreakpointReturnStub(Assembler* assembler) { |
| (...skipping 366 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2072 __ cmpq(left, right); | 2138 __ cmpq(left, right); |
| 2073 __ Bind(&done); | 2139 __ Bind(&done); |
| 2074 __ popq(right); | 2140 __ popq(right); |
| 2075 __ popq(left); | 2141 __ popq(left); |
| 2076 __ ret(); | 2142 __ ret(); |
| 2077 } | 2143 } |
| 2078 | 2144 |
| 2079 } // namespace dart | 2145 } // namespace dart |
| 2080 | 2146 |
| 2081 #endif // defined TARGET_ARCH_X64 | 2147 #endif // defined TARGET_ARCH_X64 |
| OLD | NEW |