Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(224)

Side by Side Diff: runtime/vm/stub_code_x64.cc

Issue 203523011: Introduce a lazy-compile stub for functions. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: rebased Created 6 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « runtime/vm/stub_code_mips.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
753 __ j(ZERO, &not_closure); // Not a closure, but a smi. 753 __ j(ZERO, &not_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, &not_closure, Assembler::kNearJump); 760 __ j(EQUAL, &not_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(&not_closure); 777 __ Bind(&not_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
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, &not_smi, Assembler::kNearJump); 1484 __ j(NOT_ZERO, &not_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(&not_smi); 1488 __ Bind(&not_smi);
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
OLDNEW
« no previous file with comments | « runtime/vm/stub_code_mips.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698