| 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 742 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 753 __ j(ZERO, ¬_closure); // Not a closure, but a smi. | 753 __ j(ZERO, ¬_closure); // Not a closure, but a smi. |
| 754 // Verify that the class of the object is a closure class by checking that | 754 // Verify that the class of the object is a closure class by checking that |
| 755 // class.signature_function() is not null. | 755 // class.signature_function() is not null. |
| 756 __ LoadClass(RAX, R13); | 756 __ LoadClass(RAX, R13); |
| 757 __ movq(RAX, FieldAddress(RAX, Class::signature_function_offset())); | 757 __ movq(RAX, FieldAddress(RAX, Class::signature_function_offset())); |
| 758 __ cmpq(RAX, R12); | 758 __ cmpq(RAX, R12); |
| 759 // Actual class is not a closure class. | 759 // Actual class is not a closure class. |
| 760 __ j(EQUAL, ¬_closure, Assembler::kNearJump); | 760 __ j(EQUAL, ¬_closure, Assembler::kNearJump); |
| 761 | 761 |
| 762 // RAX is just the signature function. Load the actual closure function. | 762 // RAX is just the signature function. Load the actual closure function. |
| 763 __ movq(RBX, FieldAddress(R13, Closure::function_offset())); | 763 __ movq(RAX, FieldAddress(R13, Closure::function_offset())); |
| 764 | 764 |
| 765 // Load closure context in CTX; note that CTX has already been preserved. | 765 // Load closure context in CTX; note that CTX has already been preserved. |
| 766 __ movq(CTX, FieldAddress(R13, Closure::context_offset())); | 766 __ movq(CTX, FieldAddress(R13, Closure::context_offset())); |
| 767 | 767 |
| 768 // Load closure function code in RAX. | 768 // Load closure function code in RAX. |
| 769 __ movq(RAX, FieldAddress(RBX, Function::code_offset())); | 769 __ movq(RBX, FieldAddress(RAX, Function::code_offset())); |
| 770 __ cmpq(RAX, R12); | |
| 771 Label function_compiled; | |
| 772 __ j(NOT_EQUAL, &function_compiled, Assembler::kNearJump); | |
| 773 | 770 |
| 774 // Create a stub frame as we are pushing some objects on the stack before | 771 // RAX: Function. |
| 775 // calling into the runtime. | |
| 776 __ EnterStubFrame(); | |
| 777 | |
| 778 __ pushq(R10); // Preserve arguments descriptor array. | |
| 779 __ pushq(RBX); // Preserve read-only function object argument. | |
| 780 __ CallRuntime(kCompileFunctionRuntimeEntry, 1); | |
| 781 __ popq(RBX); // Restore read-only function object argument in RBX. | |
| 782 __ popq(R10); // Restore arguments descriptor array. | |
| 783 // Restore RAX. | |
| 784 __ movq(RAX, FieldAddress(RBX, Function::code_offset())); | |
| 785 | |
| 786 // Remove the stub frame as we are about to jump to the closure function. | |
| 787 __ LeaveStubFrame(); | |
| 788 | |
| 789 __ Bind(&function_compiled); | |
| 790 // RAX: Code. | |
| 791 // RBX: Function. | |
| 792 // R10: Arguments descriptor array. | 772 // R10: Arguments descriptor array. |
| 793 | 773 __ movq(RCX, FieldAddress(RBX, Code::instructions_offset())); |
| 794 __ movq(RBX, FieldAddress(RAX, Code::instructions_offset())); | 774 __ addq(RCX, Immediate(Instructions::HeaderSize() - kHeapObjectTag)); |
| 795 __ addq(RBX, Immediate(Instructions::HeaderSize() - kHeapObjectTag)); | 775 __ jmp(RCX); |
| 796 __ jmp(RBX); | |
| 797 | 776 |
| 798 __ Bind(¬_closure); | 777 __ Bind(¬_closure); |
| 799 // Call runtime to attempt to resolve and invoke a call method on a | 778 // Call runtime to attempt to resolve and invoke a call method on a |
| 800 // non-closure object, passing the non-closure object and its arguments array, | 779 // non-closure object, passing the non-closure object and its arguments array, |
| 801 // returning here. | 780 // returning here. |
| 802 // If no call method exists, throw a NoSuchMethodError. | 781 // If no call method exists, throw a NoSuchMethodError. |
| 803 // R13: non-closure object. | 782 // R13: non-closure object. |
| 804 // R10: arguments descriptor array. | 783 // R10: arguments descriptor array. |
| 805 | 784 |
| 806 // Create a stub frame as we are pushing some objects on the stack before | 785 // Create a stub frame as we are pushing some objects on the stack before |
| (...skipping 680 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1487 __ movq(RAX, Address(R12, target_offset)); | 1466 __ movq(RAX, Address(R12, target_offset)); |
| 1488 __ addq(Address(R12, count_offset), Immediate(Smi::RawValue(1))); | 1467 __ addq(Address(R12, count_offset), Immediate(Smi::RawValue(1))); |
| 1489 __ j(NO_OVERFLOW, &call_target_function, Assembler::kNearJump); | 1468 __ j(NO_OVERFLOW, &call_target_function, Assembler::kNearJump); |
| 1490 __ movq(Address(R12, count_offset), | 1469 __ movq(Address(R12, count_offset), |
| 1491 Immediate(Smi::RawValue(Smi::kMaxValue))); | 1470 Immediate(Smi::RawValue(Smi::kMaxValue))); |
| 1492 | 1471 |
| 1493 __ Bind(&call_target_function); | 1472 __ Bind(&call_target_function); |
| 1494 // RAX: Target function. | 1473 // RAX: Target function. |
| 1495 Label is_compiled; | 1474 Label is_compiled; |
| 1496 __ movq(RCX, FieldAddress(RAX, Function::code_offset())); | 1475 __ movq(RCX, FieldAddress(RAX, Function::code_offset())); |
| 1497 if (FLAG_collect_code) { | 1476 __ movq(RCX, FieldAddress(RCX, Code::instructions_offset())); |
| 1498 // If code might be GC'd, then RBX might be null. If it is, recompile. | 1477 __ addq(RCX, Immediate(Instructions::HeaderSize() - kHeapObjectTag)); |
| 1499 __ CompareObject(RCX, Object::null_object(), PP); | 1478 __ jmp(RCX); |
| 1500 __ j(NOT_EQUAL, &is_compiled, Assembler::kNearJump); | |
| 1501 __ EnterStubFrame(); | |
| 1502 __ pushq(R10); // Preserve arguments descriptor array. | |
| 1503 __ pushq(RBX); // Preserve IC data object. | |
| 1504 __ pushq(RAX); // Pass function. | |
| 1505 __ CallRuntime(kCompileFunctionRuntimeEntry, 1); | |
| 1506 __ popq(RAX); // Restore function. | |
| 1507 __ popq(RBX); // Restore IC data array. | |
| 1508 __ popq(R10); // Restore arguments descriptor array. | |
| 1509 __ LeaveStubFrame(); | |
| 1510 __ movq(RCX, FieldAddress(RAX, Function::code_offset())); | |
| 1511 __ Bind(&is_compiled); | |
| 1512 } | |
| 1513 __ movq(RAX, FieldAddress(RCX, Code::instructions_offset())); | |
| 1514 __ addq(RAX, Immediate(Instructions::HeaderSize() - kHeapObjectTag)); | |
| 1515 __ jmp(RAX); | |
| 1516 | 1479 |
| 1517 __ Bind(&get_class_id_as_smi); | 1480 __ Bind(&get_class_id_as_smi); |
| 1518 Label not_smi; | 1481 Label not_smi; |
| 1519 // Test if Smi -> load Smi class for comparison. | 1482 // Test if Smi -> load Smi class for comparison. |
| 1520 __ testq(RAX, Immediate(kSmiTagMask)); | 1483 __ testq(RAX, Immediate(kSmiTagMask)); |
| 1521 __ j(NOT_ZERO, ¬_smi, Assembler::kNearJump); | 1484 __ j(NOT_ZERO, ¬_smi, Assembler::kNearJump); |
| 1522 __ movq(RAX, Immediate(Smi::RawValue(kSmiCid))); | 1485 __ movq(RAX, Immediate(Smi::RawValue(kSmiCid))); |
| 1523 __ ret(); | 1486 __ ret(); |
| 1524 | 1487 |
| 1525 __ Bind(¬_smi); | 1488 __ Bind(¬_smi); |
| (...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1648 const intptr_t count_offset = ICData::CountIndexFor(0) * kWordSize; | 1611 const intptr_t count_offset = ICData::CountIndexFor(0) * kWordSize; |
| 1649 | 1612 |
| 1650 // Increment count for this call. | 1613 // Increment count for this call. |
| 1651 Label increment_done; | 1614 Label increment_done; |
| 1652 __ addq(Address(R12, count_offset), Immediate(Smi::RawValue(1))); | 1615 __ addq(Address(R12, count_offset), Immediate(Smi::RawValue(1))); |
| 1653 __ j(NO_OVERFLOW, &increment_done, Assembler::kNearJump); | 1616 __ j(NO_OVERFLOW, &increment_done, Assembler::kNearJump); |
| 1654 __ movq(Address(R12, count_offset), | 1617 __ movq(Address(R12, count_offset), |
| 1655 Immediate(Smi::RawValue(Smi::kMaxValue))); | 1618 Immediate(Smi::RawValue(Smi::kMaxValue))); |
| 1656 __ Bind(&increment_done); | 1619 __ Bind(&increment_done); |
| 1657 | 1620 |
| 1658 Label target_is_compiled; | |
| 1659 // Get function and call it, if possible. | |
| 1660 __ movq(R13, Address(R12, target_offset)); | |
| 1661 __ movq(RAX, FieldAddress(R13, Function::code_offset())); | |
| 1662 __ LoadObject(R12, Object::null_object(), PP); | |
| 1663 __ cmpq(RAX, R12); | |
| 1664 __ j(NOT_EQUAL, &target_is_compiled, Assembler::kNearJump); | |
| 1665 | |
| 1666 __ EnterStubFrame(); | |
| 1667 __ pushq(R13); // Preserve target function. | |
| 1668 __ pushq(RBX); // Preserve IC data object. | |
| 1669 __ pushq(R13); // Pass function. | |
| 1670 __ CallRuntime(kCompileFunctionRuntimeEntry, 1); | |
| 1671 __ popq(RAX); // Discard argument. | |
| 1672 __ popq(RBX); // Restore IC data object. | |
| 1673 __ popq(R13); // Restore target function. | |
| 1674 __ LeaveStubFrame(); | |
| 1675 __ movq(RAX, FieldAddress(R13, Function::code_offset())); | |
| 1676 | |
| 1677 __ Bind(&target_is_compiled); | |
| 1678 // RAX: Target code. | |
| 1679 __ movq(RAX, FieldAddress(RAX, Code::instructions_offset())); | |
| 1680 __ addq(RAX, Immediate(Instructions::HeaderSize() - kHeapObjectTag)); | |
| 1681 // Load arguments descriptor into R10. | 1621 // Load arguments descriptor into R10. |
| 1682 __ movq(R10, FieldAddress(RBX, ICData::arguments_descriptor_offset())); | 1622 __ movq(R10, FieldAddress(RBX, ICData::arguments_descriptor_offset())); |
| 1683 __ jmp(RAX); | 1623 |
| 1624 // Get function and call it, if possible. |
| 1625 __ movq(RAX, Address(R12, target_offset)); |
| 1626 __ movq(RCX, FieldAddress(RAX, Function::code_offset())); |
| 1627 // RCX: Target code. |
| 1628 __ movq(RCX, FieldAddress(RCX, Code::instructions_offset())); |
| 1629 __ addq(RCX, Immediate(Instructions::HeaderSize() - kHeapObjectTag)); |
| 1630 __ jmp(RCX); |
| 1684 } | 1631 } |
| 1685 | 1632 |
| 1686 | 1633 |
| 1687 void StubCode::GenerateTwoArgsUnoptimizedStaticCallStub(Assembler* assembler) { | 1634 void StubCode::GenerateTwoArgsUnoptimizedStaticCallStub(Assembler* assembler) { |
| 1688 GenerateUsageCounterIncrement(assembler, RCX); | 1635 GenerateUsageCounterIncrement(assembler, RCX); |
| 1689 GenerateNArgsCheckInlineCacheStub( | 1636 GenerateNArgsCheckInlineCacheStub( |
| 1690 assembler, 2, kStaticCallMissHandlerTwoArgsRuntimeEntry); | 1637 assembler, 2, kStaticCallMissHandlerTwoArgsRuntimeEntry); |
| 1691 } | 1638 } |
| 1692 | 1639 |
| 1693 | 1640 |
| 1694 // Stub for calling the CompileFunction runtime call. | 1641 // Stub for compiling a function and jumping to the compiled code. |
| 1695 // RCX: IC-Data. | 1642 // RCX: IC-Data (for methods). |
| 1696 // RDX: Arguments descriptor. | 1643 // R10: Arguments descriptor. |
| 1697 // RAX: Function. | 1644 // RAX: Function. |
| 1698 void StubCode::GenerateCompileFunctionRuntimeCallStub(Assembler* assembler) { | 1645 void StubCode::GenerateLazyCompileStub(Assembler* assembler) { |
| 1699 __ EnterStubFrame(); | 1646 __ EnterStubFrame(); |
| 1700 __ pushq(RDX); // Preserve arguments descriptor array. | 1647 __ pushq(R10); // Preserve arguments descriptor array. |
| 1701 __ pushq(RCX); // Preserve IC data object. | 1648 __ pushq(RBX); // Preserve IC data object. |
| 1702 __ pushq(RAX); // Pass function. | 1649 __ pushq(RAX); // Pass function. |
| 1703 __ CallRuntime(kCompileFunctionRuntimeEntry, 1); | 1650 __ CallRuntime(kCompileFunctionRuntimeEntry, 1); |
| 1704 __ popq(RAX); // Restore function. | 1651 __ popq(RAX); // Restore function. |
| 1705 __ popq(RCX); // Restore IC data array. | 1652 __ popq(RBX); // Restore IC data array. |
| 1706 __ popq(RDX); // Restore arguments descriptor array. | 1653 __ popq(R10); // Restore arguments descriptor array. |
| 1707 __ LeaveStubFrame(); | 1654 __ LeaveStubFrame(); |
| 1708 __ ret(); | 1655 |
| 1656 __ movq(RAX, FieldAddress(RAX, Function::code_offset())); |
| 1657 __ movq(RAX, FieldAddress(RAX, Code::instructions_offset())); |
| 1658 __ addq(RAX, Immediate(Instructions::HeaderSize() - kHeapObjectTag)); |
| 1659 __ jmp(RAX); |
| 1709 } | 1660 } |
| 1710 | 1661 |
| 1711 | 1662 |
| 1712 // RBX, R10: May contain arguments to runtime stub. | 1663 // RBX, R10: May contain arguments to runtime stub. |
| 1713 // TOS(0): return address (Dart code). | 1664 // TOS(0): return address (Dart code). |
| 1714 void StubCode::GenerateBreakpointRuntimeStub(Assembler* assembler) { | 1665 void StubCode::GenerateBreakpointRuntimeStub(Assembler* assembler) { |
| 1715 __ EnterStubFrame(); | 1666 __ EnterStubFrame(); |
| 1716 // Preserve runtime args. | 1667 // Preserve runtime args. |
| 1717 __ pushq(RBX); | 1668 __ pushq(RBX); |
| 1718 __ pushq(R10); | 1669 __ pushq(R10); |
| (...skipping 290 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2009 | 1960 |
| 2010 __ movq(left, Address(RSP, 2 * kWordSize)); | 1961 __ movq(left, Address(RSP, 2 * kWordSize)); |
| 2011 __ movq(right, Address(RSP, 1 * kWordSize)); | 1962 __ movq(right, Address(RSP, 1 * kWordSize)); |
| 2012 GenerateIdenticalWithNumberCheckStub(assembler, left, right); | 1963 GenerateIdenticalWithNumberCheckStub(assembler, left, right); |
| 2013 __ ret(); | 1964 __ ret(); |
| 2014 } | 1965 } |
| 2015 | 1966 |
| 2016 } // namespace dart | 1967 } // namespace dart |
| 2017 | 1968 |
| 2018 #endif // defined TARGET_ARCH_X64 | 1969 #endif // defined TARGET_ARCH_X64 |
| OLD | NEW |