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

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

Issue 17554003: Change static calls in unoptimized code to always call via a stub. Using ICData, the call count of … (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 6 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
« runtime/vm/stub_code_mips.cc ('K') | « 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 1544 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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
OLDNEW
« runtime/vm/stub_code_mips.cc ('K') | « runtime/vm/stub_code_mips.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698