| 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 683 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 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 if (FLAG_collect_code) { |
| 1498 // If code might be GC'd, then RBX might be null. If it is, recompile. | 1477 // If code might be GC'd, then RBX might be null. If it is, recompile. |
| 1499 __ CompareObject(RCX, Object::null_object(), PP); | 1478 __ CompareObject(RCX, Object::null_object(), PP); |
| 1500 __ j(NOT_EQUAL, &is_compiled, Assembler::kNearJump); | 1479 __ j(EQUAL, &StubCode::LazyCompileLabel()); |
| 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 } | 1480 } |
| 1513 __ movq(RAX, FieldAddress(RCX, Code::instructions_offset())); | 1481 __ movq(RAX, FieldAddress(RCX, Code::instructions_offset())); |
| 1514 __ addq(RAX, Immediate(Instructions::HeaderSize() - kHeapObjectTag)); | 1482 __ addq(RAX, Immediate(Instructions::HeaderSize() - kHeapObjectTag)); |
| 1515 __ jmp(RAX); | 1483 __ jmp(RAX); |
| 1516 | 1484 |
| 1517 __ Bind(&get_class_id_as_smi); | 1485 __ Bind(&get_class_id_as_smi); |
| 1518 Label not_smi; | 1486 Label not_smi; |
| 1519 // Test if Smi -> load Smi class for comparison. | 1487 // Test if Smi -> load Smi class for comparison. |
| 1520 __ testq(RAX, Immediate(kSmiTagMask)); | 1488 __ testq(RAX, Immediate(kSmiTagMask)); |
| 1521 __ j(NOT_ZERO, ¬_smi, Assembler::kNearJump); | 1489 __ j(NOT_ZERO, ¬_smi, Assembler::kNearJump); |
| (...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1648 const intptr_t count_offset = ICData::CountIndexFor(0) * kWordSize; | 1616 const intptr_t count_offset = ICData::CountIndexFor(0) * kWordSize; |
| 1649 | 1617 |
| 1650 // Increment count for this call. | 1618 // Increment count for this call. |
| 1651 Label increment_done; | 1619 Label increment_done; |
| 1652 __ addq(Address(R12, count_offset), Immediate(Smi::RawValue(1))); | 1620 __ addq(Address(R12, count_offset), Immediate(Smi::RawValue(1))); |
| 1653 __ j(NO_OVERFLOW, &increment_done, Assembler::kNearJump); | 1621 __ j(NO_OVERFLOW, &increment_done, Assembler::kNearJump); |
| 1654 __ movq(Address(R12, count_offset), | 1622 __ movq(Address(R12, count_offset), |
| 1655 Immediate(Smi::RawValue(Smi::kMaxValue))); | 1623 Immediate(Smi::RawValue(Smi::kMaxValue))); |
| 1656 __ Bind(&increment_done); | 1624 __ Bind(&increment_done); |
| 1657 | 1625 |
| 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. | 1626 // Load arguments descriptor into R10. |
| 1682 __ movq(R10, FieldAddress(RBX, ICData::arguments_descriptor_offset())); | 1627 __ movq(R10, FieldAddress(RBX, ICData::arguments_descriptor_offset())); |
| 1628 |
| 1629 // Get function and call it, if possible. |
| 1630 __ movq(RAX, Address(R12, target_offset)); |
| 1631 __ movq(RCX, FieldAddress(RAX, Function::code_offset())); |
| 1632 __ CompareObject(RCX, Object::null_object(), PP); |
| 1633 __ j(EQUAL, &StubCode::LazyCompileLabel()); |
| 1634 |
| 1635 // RCX: Target code. |
| 1636 __ movq(RAX, FieldAddress(RCX, Code::instructions_offset())); |
| 1637 __ addq(RAX, Immediate(Instructions::HeaderSize() - kHeapObjectTag)); |
| 1683 __ jmp(RAX); | 1638 __ jmp(RAX); |
| 1684 } | 1639 } |
| 1685 | 1640 |
| 1686 | 1641 |
| 1687 void StubCode::GenerateTwoArgsUnoptimizedStaticCallStub(Assembler* assembler) { | 1642 void StubCode::GenerateTwoArgsUnoptimizedStaticCallStub(Assembler* assembler) { |
| 1688 GenerateUsageCounterIncrement(assembler, RCX); | 1643 GenerateUsageCounterIncrement(assembler, RCX); |
| 1689 GenerateNArgsCheckInlineCacheStub( | 1644 GenerateNArgsCheckInlineCacheStub( |
| 1690 assembler, 2, kStaticCallMissHandlerTwoArgsRuntimeEntry); | 1645 assembler, 2, kStaticCallMissHandlerTwoArgsRuntimeEntry); |
| 1691 } | 1646 } |
| 1692 | 1647 |
| 1693 | 1648 |
| 1649 // Stub for compiling a function and jumping to the compiled code. |
| 1650 // RCX: IC-Data. |
| 1651 // R10: Arguments descriptor. |
| 1652 // RAX: Function. |
| 1653 void StubCode::GenerateLazyCompileStub(Assembler* assembler) { |
| 1654 __ EnterStubFrame(); |
| 1655 __ pushq(R10); // Preserve arguments descriptor array. |
| 1656 __ pushq(RBX); // Preserve IC data object. |
| 1657 __ pushq(RAX); // Pass function. |
| 1658 __ CallRuntime(kCompileFunctionRuntimeEntry, 1); |
| 1659 __ popq(RAX); // Restore function. |
| 1660 __ popq(RBX); // Restore IC data array. |
| 1661 __ popq(R10); // Restore arguments descriptor array. |
| 1662 __ LeaveStubFrame(); |
| 1663 |
| 1664 __ movq(RAX, FieldAddress(RAX, Function::code_offset())); |
| 1665 __ movq(RAX, FieldAddress(RAX, Code::instructions_offset())); |
| 1666 __ addq(RAX, Immediate(Instructions::HeaderSize() - kHeapObjectTag)); |
| 1667 __ jmp(RAX); |
| 1668 } |
| 1669 |
| 1670 |
| 1671 // Stub for compiling a closure and jumping to the compiled code. |
| 1672 // R10: Arguments descriptor. |
| 1673 // RAX: Function. |
| 1674 void StubCode::GenerateLazyCompileClosureStub(Assembler* assembler) { |
| 1675 __ EnterStubFrame(); |
| 1676 __ pushq(R10); // Preserve arguments descriptor array. |
| 1677 __ pushq(RAX); // Pass function. |
| 1678 __ CallRuntime(kCompileFunctionRuntimeEntry, 1); |
| 1679 __ popq(RAX); // Restore function. |
| 1680 __ popq(R10); // Restore arguments descriptor array. |
| 1681 __ LeaveStubFrame(); |
| 1682 |
| 1683 __ movq(RAX, FieldAddress(RAX, Function::code_offset())); |
| 1684 __ movq(RAX, FieldAddress(RAX, Code::instructions_offset())); |
| 1685 __ addq(RAX, Immediate(Instructions::HeaderSize() - kHeapObjectTag)); |
| 1686 __ jmp(RAX); |
| 1687 } |
| 1688 |
| 1689 |
| 1694 // Stub for calling the CompileFunction runtime call. | 1690 // Stub for calling the CompileFunction runtime call. |
| 1695 // RCX: IC-Data. | |
| 1696 // RDX: Arguments descriptor. | |
| 1697 // RAX: Function. | 1691 // RAX: Function. |
| 1698 void StubCode::GenerateCompileFunctionRuntimeCallStub(Assembler* assembler) { | 1692 void StubCode::GenerateCompileFunctionRuntimeCallStub(Assembler* assembler) { |
| 1699 __ EnterStubFrame(); | 1693 __ EnterStubFrame(); |
| 1700 __ pushq(RDX); // Preserve arguments descriptor array. | |
| 1701 __ pushq(RCX); // Preserve IC data object. | |
| 1702 __ pushq(RAX); // Pass function. | 1694 __ pushq(RAX); // Pass function. |
| 1703 __ CallRuntime(kCompileFunctionRuntimeEntry, 1); | 1695 __ CallRuntime(kCompileFunctionRuntimeEntry, 1); |
| 1704 __ popq(RAX); // Restore function. | 1696 __ popq(RAX); // Restore function. |
| 1705 __ popq(RCX); // Restore IC data array. | |
| 1706 __ popq(RDX); // Restore arguments descriptor array. | |
| 1707 __ LeaveStubFrame(); | 1697 __ LeaveStubFrame(); |
| 1708 __ ret(); | 1698 __ ret(); |
| 1709 } | 1699 } |
| 1710 | 1700 |
| 1711 | 1701 |
| 1712 // RBX, R10: May contain arguments to runtime stub. | 1702 // RBX, R10: May contain arguments to runtime stub. |
| 1713 // TOS(0): return address (Dart code). | 1703 // TOS(0): return address (Dart code). |
| 1714 void StubCode::GenerateBreakpointRuntimeStub(Assembler* assembler) { | 1704 void StubCode::GenerateBreakpointRuntimeStub(Assembler* assembler) { |
| 1715 __ EnterStubFrame(); | 1705 __ EnterStubFrame(); |
| 1716 // Preserve runtime args. | 1706 // Preserve runtime args. |
| (...skipping 292 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2009 | 1999 |
| 2010 __ movq(left, Address(RSP, 2 * kWordSize)); | 2000 __ movq(left, Address(RSP, 2 * kWordSize)); |
| 2011 __ movq(right, Address(RSP, 1 * kWordSize)); | 2001 __ movq(right, Address(RSP, 1 * kWordSize)); |
| 2012 GenerateIdenticalWithNumberCheckStub(assembler, left, right); | 2002 GenerateIdenticalWithNumberCheckStub(assembler, left, right); |
| 2013 __ ret(); | 2003 __ ret(); |
| 2014 } | 2004 } |
| 2015 | 2005 |
| 2016 } // namespace dart | 2006 } // namespace dart |
| 2017 | 2007 |
| 2018 #endif // defined TARGET_ARCH_X64 | 2008 #endif // defined TARGET_ARCH_X64 |
| OLD | NEW |