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

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

Issue 11361225: In optimized code use IC calls for instance calls that have no IC data instead of deoptimizing. The… (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 1 month 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/object.h ('K') | « runtime/vm/stub_code_ia32.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) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, 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/assembler_macros.h" 9 #include "vm/assembler_macros.h"
10 #include "vm/compiler.h" 10 #include "vm/compiler.h"
11 #include "vm/flow_graph_compiler.h" 11 #include "vm/flow_graph_compiler.h"
12 #include "vm/instructions.h" 12 #include "vm/instructions.h"
13 #include "vm/object_store.h" 13 #include "vm/object_store.h"
14 #include "vm/pages.h" 14 #include "vm/pages.h"
15 #include "vm/resolver.h" 15 #include "vm/resolver.h"
16 #include "vm/scavenger.h" 16 #include "vm/scavenger.h"
17 #include "vm/stub_code.h" 17 #include "vm/stub_code.h"
18 18
19 19
20 #define __ assembler-> 20 #define __ assembler->
21 21
22 namespace dart { 22 namespace dart {
23 23
24 DEFINE_FLAG(bool, inline_alloc, true, "Inline allocation of objects."); 24 DEFINE_FLAG(bool, inline_alloc, true, "Inline allocation of objects.");
25 DEFINE_FLAG(bool, use_slow_path, false, 25 DEFINE_FLAG(bool, use_slow_path, false,
26 "Set to true for debugging & verifying the slow paths."); 26 "Set to true for debugging & verifying the slow paths.");
27 DECLARE_FLAG(int, optimization_counter_threshold); 27 DECLARE_FLAG(int, optimization_counter_threshold);
28 DECLARE_FLAG(bool, trace_optimized_ic_calls);
28 29
29 // Input parameters: 30 // Input parameters:
30 // RSP : points to return address. 31 // RSP : points to return address.
31 // RSP + 8 : address of last argument in argument array. 32 // RSP + 8 : address of last argument in argument array.
32 // RSP + 8*R10 : address of first argument in argument array. 33 // RSP + 8*R10 : address of first argument in argument array.
33 // RSP + 8*R10 + 8 : address of return value. 34 // RSP + 8*R10 + 8 : address of return value.
34 // RBX : address of the runtime function to call. 35 // RBX : address of the runtime function to call.
35 // R10 : number of arguments to the call. 36 // R10 : number of arguments to the call.
36 // Must preserve callee saved registers R12 and R13. 37 // Must preserve callee saved registers R12 and R13.
37 void StubCode::GenerateCallToRuntimeStub(Assembler* assembler) { 38 void StubCode::GenerateCallToRuntimeStub(Assembler* assembler) {
(...skipping 1479 matching lines...) Expand 10 before | Expand all | Expand 10 after
1517 __ popq(RAX); 1518 __ popq(RAX);
1518 __ popq(RAX); 1519 __ popq(RAX);
1519 __ popq(RAX); // Get result into RAX. 1520 __ popq(RAX); // Get result into RAX.
1520 1521
1521 // Remove the stub frame as we are about to return. 1522 // Remove the stub frame as we are about to return.
1522 __ LeaveFrame(); 1523 __ LeaveFrame();
1523 __ ret(); 1524 __ ret();
1524 } 1525 }
1525 1526
1526 1527
1528 void StubCode::GenerateOptimizedUsageCounterIncrement(Assembler* assembler) {
1529 Register argdesc_reg = R10;
1530 Register ic_reg = RBX;
1531 Register func_reg = RDI;
1532 if (FLAG_trace_optimized_ic_calls) {
1533 AssemblerMacros::EnterStubFrame(assembler);
1534 __ pushq(func_reg); // Preserve
1535 __ pushq(argdesc_reg); // Preserve.
1536 __ pushq(ic_reg); // Preserve.
1537 __ pushq(ic_reg); // Argument.
1538 __ pushq(func_reg); // Argument.
1539 __ CallRuntime(kTraceICCallRuntimeEntry);
1540 __ popq(RAX); // Discard argument;
1541 __ popq(RAX); // Discard argument;
1542 __ popq(ic_reg); // Restore.
1543 __ popq(argdesc_reg); // Restore.
1544 __ popq(func_reg); // Restore.
1545 __ LeaveFrame();
1546 }
1547 Label is_hot;
1548 if (FlowGraphCompiler::CanOptimize()) {
1549 ASSERT(FLAG_optimization_counter_threshold > 1);
1550 __ cmpq(FieldAddress(func_reg, Function::usage_counter_offset()),
1551 Immediate(FLAG_optimization_counter_threshold));
1552 __ j(GREATER_EQUAL, &is_hot, Assembler::kNearJump);
1553 // As long as VM has no OSR do not optimize in the middle of the function
1554 // but only at exit so that we have collected all type feedback before
1555 // optimizing.
1556 }
1557 __ incq(FieldAddress(func_reg, Function::usage_counter_offset()));
1558 __ Bind(&is_hot);
1559 }
1560
1561
1527 // Loads function into 'temp_reg', preserves 'ic_reg'. 1562 // Loads function into 'temp_reg', preserves 'ic_reg'.
1528 void StubCode::GenerateUsageCounterIncrement(Assembler* assembler, 1563 void StubCode::GenerateUsageCounterIncrement(Assembler* assembler,
1529 Register ic_reg,
1530 Register temp_reg) { 1564 Register temp_reg) {
1531 __ movq(temp_reg, FieldAddress(ic_reg, ICData::function_offset())); 1565 Register ic_reg = RBX;
1566 Register func_reg = temp_reg;
1567 ASSERT(ic_reg != func_reg);
1568 __ movq(func_reg, FieldAddress(ic_reg, ICData::function_offset()));
1532 Label is_hot; 1569 Label is_hot;
1533 if (FlowGraphCompiler::CanOptimize()) { 1570 if (FlowGraphCompiler::CanOptimize()) {
1534 ASSERT(FLAG_optimization_counter_threshold > 1); 1571 ASSERT(FLAG_optimization_counter_threshold > 1);
1535 // The usage_counter is always less than FLAG_optimization_counter_threshold 1572 // The usage_counter is always less than FLAG_optimization_counter_threshold
1536 // except when the function gets optimized. 1573 // except when the function gets optimized.
1537 __ cmpq(FieldAddress(temp_reg, Function::usage_counter_offset()), 1574 __ cmpq(FieldAddress(func_reg, Function::usage_counter_offset()),
1538 Immediate(FLAG_optimization_counter_threshold)); 1575 Immediate(FLAG_optimization_counter_threshold));
1539 __ j(EQUAL, &is_hot, Assembler::kNearJump); 1576 __ j(EQUAL, &is_hot, Assembler::kNearJump);
1540 // As long as VM has no OSR do not optimize in the middle of the function 1577 // As long as VM has no OSR do not optimize in the middle of the function
1541 // but only at exit so that we have collected all type feedback before 1578 // but only at exit so that we have collected all type feedback before
1542 // optimizing. 1579 // optimizing.
1543 } 1580 }
1544 __ incq(FieldAddress(temp_reg, Function::usage_counter_offset())); 1581 __ incq(FieldAddress(func_reg, Function::usage_counter_offset()));
1545 __ Bind(&is_hot); 1582 __ Bind(&is_hot);
1546 } 1583 }
1547 1584
1548 // Generate inline cache check for 'num_args'. 1585 // Generate inline cache check for 'num_args'.
1549 // RBX: Inline cache data object. 1586 // RBX: Inline cache data object.
1550 // R10: Arguments descriptor array. 1587 // R10: Arguments descriptor array.
1551 // TOS(0): return address 1588 // TOS(0): return address
1552 // Control flow: 1589 // Control flow:
1553 // - If receiver is null -> jump to IC miss. 1590 // - If receiver is null -> jump to IC miss.
1554 // - If receiver is Smi -> load Smi class. 1591 // - If receiver is Smi -> load Smi class.
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
1653 __ popq(RAX); 1690 __ popq(RAX);
1654 } 1691 }
1655 __ popq(RAX); // Pop returned code object into RAX (null if not found). 1692 __ popq(RAX); // Pop returned code object into RAX (null if not found).
1656 __ popq(RBX); // Restore IC data array. 1693 __ popq(RBX); // Restore IC data array.
1657 __ popq(R10); // Restore arguments array. 1694 __ popq(R10); // Restore arguments array.
1658 __ LeaveFrame(); 1695 __ LeaveFrame();
1659 Label call_target_function; 1696 Label call_target_function;
1660 __ cmpq(RAX, raw_null); 1697 __ cmpq(RAX, raw_null);
1661 __ j(NOT_EQUAL, &call_target_function, Assembler::kNearJump); 1698 __ j(NOT_EQUAL, &call_target_function, Assembler::kNearJump);
1662 // NoSuchMethod or closure. 1699 // NoSuchMethod or closure.
1700 // Mark IC call that it may be a closure call that does not collect
1701 // type feedback.
1702 __ movb(FieldAddress(RBX, ICData::is_closure_call_offset()), Immediate(1));
1663 __ jmp(&StubCode::InstanceFunctionLookupLabel()); 1703 __ jmp(&StubCode::InstanceFunctionLookupLabel());
1664 1704
1665 __ Bind(&found); 1705 __ Bind(&found);
1666 // R12: Pointer to an IC data check group (classes + target) 1706 // R12: Pointer to an IC data check group (classes + target)
1667 __ movq(RAX, Address(R12, kWordSize * num_args)); // Target function. 1707 __ movq(RAX, Address(R12, kWordSize * num_args)); // Target function.
1668 1708
1669 __ Bind(&call_target_function); 1709 __ Bind(&call_target_function);
1670 // RAX: Target function. 1710 // RAX: Target function.
1671 __ movq(RAX, FieldAddress(RAX, Function::code_offset())); 1711 __ movq(RAX, FieldAddress(RAX, Function::code_offset()));
1672 __ movq(RAX, FieldAddress(RAX, Code::instructions_offset())); 1712 __ movq(RAX, FieldAddress(RAX, Code::instructions_offset()));
(...skipping 20 matching lines...) Expand all
1693 // RBX: Inline cache data object. 1733 // RBX: Inline cache data object.
1694 // RDX: Arguments array. 1734 // RDX: Arguments array.
1695 // TOS(0): Return address. 1735 // TOS(0): Return address.
1696 // Inline cache data object structure: 1736 // Inline cache data object structure:
1697 // 0: function-name 1737 // 0: function-name
1698 // 1: N, number of arguments checked. 1738 // 1: N, number of arguments checked.
1699 // 2 .. (length - 1): group of checks, each check containing: 1739 // 2 .. (length - 1): group of checks, each check containing:
1700 // - N classes. 1740 // - N classes.
1701 // - 1 target function. 1741 // - 1 target function.
1702 void StubCode::GenerateOneArgCheckInlineCacheStub(Assembler* assembler) { 1742 void StubCode::GenerateOneArgCheckInlineCacheStub(Assembler* assembler) {
1703 GenerateUsageCounterIncrement(assembler, RBX, RCX); 1743 GenerateUsageCounterIncrement(assembler, RCX);
1704 return GenerateNArgsCheckInlineCacheStub(assembler, 1); 1744 GenerateNArgsCheckInlineCacheStub(assembler, 1);
1705 } 1745 }
1706 1746
1707 1747
1708 void StubCode::GenerateTwoArgsCheckInlineCacheStub(Assembler* assembler) { 1748 void StubCode::GenerateTwoArgsCheckInlineCacheStub(Assembler* assembler) {
1709 GenerateUsageCounterIncrement(assembler, RBX, RCX); 1749 GenerateUsageCounterIncrement(assembler, RCX);
1710 return GenerateNArgsCheckInlineCacheStub(assembler, 2); 1750 GenerateNArgsCheckInlineCacheStub(assembler, 2);
1711 } 1751 }
1712 1752
1713 1753
1714 void StubCode::GenerateThreeArgsCheckInlineCacheStub(Assembler* assembler) { 1754 void StubCode::GenerateThreeArgsCheckInlineCacheStub(Assembler* assembler) {
1715 GenerateUsageCounterIncrement(assembler, RBX, RCX); 1755 GenerateUsageCounterIncrement(assembler, RCX);
1716 return GenerateNArgsCheckInlineCacheStub(assembler, 3); 1756 GenerateNArgsCheckInlineCacheStub(assembler, 3);
1717 } 1757 }
1718 1758
1759 // Use inline cache data array to invoke the target or continue in inline
1760 // cache miss handler. Stub for 1-argument check (receiver class).
1761 // RDI: function which counter needs to be incremented.
1762 // RBX: Inline cache data object.
1763 // RDX: Arguments array.
1764 // TOS(0): Return address.
1765 // Inline cache data object structure:
1766 // 0: function-name
1767 // 1: N, number of arguments checked.
1768 // 2 .. (length - 1): group of checks, each check containing:
1769 // - N classes.
1770 // - 1 target function.
1771 void StubCode::GenerateOneArgOptimizedCheckInlineCacheStub(
1772 Assembler* assembler) {
1773 GenerateOptimizedUsageCounterIncrement(assembler);
1774 GenerateNArgsCheckInlineCacheStub(assembler, 1);
1775 }
1776
1777
1778 void StubCode::GenerateTwoArgsOptimizedCheckInlineCacheStub(
1779 Assembler* assembler) {
1780 GenerateOptimizedUsageCounterIncrement(assembler);
1781 GenerateNArgsCheckInlineCacheStub(assembler, 2);
1782 }
1783
1784
1785 void StubCode::GenerateThreeArgsOptimizedCheckInlineCacheStub(
1786 Assembler* assembler) {
1787 GenerateOptimizedUsageCounterIncrement(assembler);
1788 GenerateNArgsCheckInlineCacheStub(assembler, 3);
1789 }
1790
1791
1792 // Do not count as no type feedback is collected.
1793 void StubCode::GenerateClosureCallInlineCacheStub(Assembler* assembler) {
1794 GenerateNArgsCheckInlineCacheStub(assembler, 1);
1795 }
1796
1797
1719 // Megamorphic call is currently implemented as IC call but through a stub 1798 // Megamorphic call is currently implemented as IC call but through a stub
1720 // that does not check/count function invocations. 1799 // that does not check/count function invocations.
1721 void StubCode::GenerateMegamorphicCallStub(Assembler* assembler) { 1800 void StubCode::GenerateMegamorphicCallStub(Assembler* assembler) {
1722 return GenerateNArgsCheckInlineCacheStub(assembler, 1); 1801 GenerateNArgsCheckInlineCacheStub(assembler, 1);
1723 } 1802 }
1724 1803
1725 // RBX: Function object. 1804 // RBX: Function object.
1726 // R10: Arguments array. 1805 // R10: Arguments array.
1727 // TOS(0): return address (Dart code). 1806 // TOS(0): return address (Dart code).
1728 void StubCode::GenerateBreakpointStaticStub(Assembler* assembler) { 1807 void StubCode::GenerateBreakpointStaticStub(Assembler* assembler) {
1729 AssemblerMacros::EnterStubFrame(assembler); 1808 AssemblerMacros::EnterStubFrame(assembler);
1730 __ pushq(R10); 1809 __ pushq(R10);
1731 __ pushq(RBX); 1810 __ pushq(RBX);
1732 __ CallRuntime(kBreakpointStaticHandlerRuntimeEntry); 1811 __ CallRuntime(kBreakpointStaticHandlerRuntimeEntry);
(...skipping 307 matching lines...) Expand 10 before | Expand all | Expand 10 after
2040 __ CallRuntime(kOptimizeInvokedFunctionRuntimeEntry); 2119 __ CallRuntime(kOptimizeInvokedFunctionRuntimeEntry);
2041 __ popq(RDX); 2120 __ popq(RDX);
2042 __ popq(RAX); 2121 __ popq(RAX);
2043 __ LeaveFrame(); 2122 __ LeaveFrame();
2044 __ ret(); 2123 __ ret();
2045 } 2124 }
2046 2125
2047 } // namespace dart 2126 } // namespace dart
2048 2127
2049 #endif // defined TARGET_ARCH_X64 2128 #endif // defined TARGET_ARCH_X64
OLDNEW
« runtime/vm/object.h ('K') | « runtime/vm/stub_code_ia32.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698