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

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
« no previous file with comments | « 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 1459 matching lines...) Expand 10 before | Expand all | Expand 10 after
1497 __ popq(RAX); 1498 __ popq(RAX);
1498 __ popq(RAX); 1499 __ popq(RAX);
1499 __ popq(RAX); // Get result into RAX. 1500 __ popq(RAX); // Get result into RAX.
1500 1501
1501 // Remove the stub frame as we are about to return. 1502 // Remove the stub frame as we are about to return.
1502 __ LeaveFrame(); 1503 __ LeaveFrame();
1503 __ ret(); 1504 __ ret();
1504 } 1505 }
1505 1506
1506 1507
1508 void StubCode::GenerateOptimizedUsageCounterIncrement(Assembler* assembler) {
1509 Register argdesc_reg = R10;
1510 Register ic_reg = RBX;
1511 Register func_reg = RDI;
1512 if (FLAG_trace_optimized_ic_calls) {
1513 AssemblerMacros::EnterStubFrame(assembler);
1514 __ pushq(func_reg); // Preserve
1515 __ pushq(argdesc_reg); // Preserve.
1516 __ pushq(ic_reg); // Preserve.
1517 __ pushq(ic_reg); // Argument.
1518 __ pushq(func_reg); // Argument.
1519 __ CallRuntime(kTraceICCallRuntimeEntry);
1520 __ popq(RAX); // Discard argument;
1521 __ popq(RAX); // Discard argument;
1522 __ popq(ic_reg); // Restore.
1523 __ popq(argdesc_reg); // Restore.
1524 __ popq(func_reg); // Restore.
1525 __ LeaveFrame();
1526 }
1527 Label is_hot;
1528 if (FlowGraphCompiler::CanOptimize()) {
1529 ASSERT(FLAG_optimization_counter_threshold > 1);
1530 __ cmpq(FieldAddress(func_reg, Function::usage_counter_offset()),
1531 Immediate(FLAG_optimization_counter_threshold));
1532 __ j(GREATER_EQUAL, &is_hot, Assembler::kNearJump);
1533 // As long as VM has no OSR do not optimize in the middle of the function
1534 // but only at exit so that we have collected all type feedback before
1535 // optimizing.
1536 }
1537 __ incq(FieldAddress(func_reg, Function::usage_counter_offset()));
1538 __ Bind(&is_hot);
1539 }
1540
1541
1507 // Loads function into 'temp_reg', preserves 'ic_reg'. 1542 // Loads function into 'temp_reg', preserves 'ic_reg'.
1508 void StubCode::GenerateUsageCounterIncrement(Assembler* assembler, 1543 void StubCode::GenerateUsageCounterIncrement(Assembler* assembler,
1509 Register ic_reg,
1510 Register temp_reg) { 1544 Register temp_reg) {
1511 __ movq(temp_reg, FieldAddress(ic_reg, ICData::function_offset())); 1545 Register ic_reg = RBX;
1546 Register func_reg = temp_reg;
1547 ASSERT(ic_reg != func_reg);
1548 __ movq(func_reg, FieldAddress(ic_reg, ICData::function_offset()));
1512 Label is_hot; 1549 Label is_hot;
1513 if (FlowGraphCompiler::CanOptimize()) { 1550 if (FlowGraphCompiler::CanOptimize()) {
1514 ASSERT(FLAG_optimization_counter_threshold > 1); 1551 ASSERT(FLAG_optimization_counter_threshold > 1);
1515 // The usage_counter is always less than FLAG_optimization_counter_threshold 1552 // The usage_counter is always less than FLAG_optimization_counter_threshold
1516 // except when the function gets optimized. 1553 // except when the function gets optimized.
1517 __ cmpq(FieldAddress(temp_reg, Function::usage_counter_offset()), 1554 __ cmpq(FieldAddress(func_reg, Function::usage_counter_offset()),
1518 Immediate(FLAG_optimization_counter_threshold)); 1555 Immediate(FLAG_optimization_counter_threshold));
1519 __ j(EQUAL, &is_hot, Assembler::kNearJump); 1556 __ j(EQUAL, &is_hot, Assembler::kNearJump);
1520 // As long as VM has no OSR do not optimize in the middle of the function 1557 // As long as VM has no OSR do not optimize in the middle of the function
1521 // but only at exit so that we have collected all type feedback before 1558 // but only at exit so that we have collected all type feedback before
1522 // optimizing. 1559 // optimizing.
1523 } 1560 }
1524 __ incq(FieldAddress(temp_reg, Function::usage_counter_offset())); 1561 __ incq(FieldAddress(func_reg, Function::usage_counter_offset()));
1525 __ Bind(&is_hot); 1562 __ Bind(&is_hot);
1526 } 1563 }
1527 1564
1528 // Generate inline cache check for 'num_args'. 1565 // Generate inline cache check for 'num_args'.
1529 // RBX: Inline cache data object. 1566 // RBX: Inline cache data object.
1530 // R10: Arguments descriptor array. 1567 // R10: Arguments descriptor array.
1531 // TOS(0): return address 1568 // TOS(0): return address
1532 // Control flow: 1569 // Control flow:
1533 // - If receiver is null -> jump to IC miss. 1570 // - If receiver is null -> jump to IC miss.
1534 // - If receiver is Smi -> load Smi class. 1571 // - If receiver is Smi -> load Smi class.
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
1633 __ popq(RAX); 1670 __ popq(RAX);
1634 } 1671 }
1635 __ popq(RAX); // Pop returned code object into RAX (null if not found). 1672 __ popq(RAX); // Pop returned code object into RAX (null if not found).
1636 __ popq(RBX); // Restore IC data array. 1673 __ popq(RBX); // Restore IC data array.
1637 __ popq(R10); // Restore arguments array. 1674 __ popq(R10); // Restore arguments array.
1638 __ LeaveFrame(); 1675 __ LeaveFrame();
1639 Label call_target_function; 1676 Label call_target_function;
1640 __ cmpq(RAX, raw_null); 1677 __ cmpq(RAX, raw_null);
1641 __ j(NOT_EQUAL, &call_target_function, Assembler::kNearJump); 1678 __ j(NOT_EQUAL, &call_target_function, Assembler::kNearJump);
1642 // NoSuchMethod or closure. 1679 // NoSuchMethod or closure.
1680 // Mark IC call that it may be a closure call that does not collect
1681 // type feedback.
1682 __ movb(FieldAddress(RBX, ICData::is_closure_call_offset()), Immediate(1));
1643 __ jmp(&StubCode::InstanceFunctionLookupLabel()); 1683 __ jmp(&StubCode::InstanceFunctionLookupLabel());
1644 1684
1645 __ Bind(&found); 1685 __ Bind(&found);
1646 // R12: Pointer to an IC data check group (classes + target) 1686 // R12: Pointer to an IC data check group (classes + target)
1647 __ movq(RAX, Address(R12, kWordSize * num_args)); // Target function. 1687 __ movq(RAX, Address(R12, kWordSize * num_args)); // Target function.
1648 1688
1649 __ Bind(&call_target_function); 1689 __ Bind(&call_target_function);
1650 // RAX: Target function. 1690 // RAX: Target function.
1651 __ movq(RAX, FieldAddress(RAX, Function::code_offset())); 1691 __ movq(RAX, FieldAddress(RAX, Function::code_offset()));
1652 __ movq(RAX, FieldAddress(RAX, Code::instructions_offset())); 1692 __ movq(RAX, FieldAddress(RAX, Code::instructions_offset()));
(...skipping 20 matching lines...) Expand all
1673 // RBX: Inline cache data object. 1713 // RBX: Inline cache data object.
1674 // RDX: Arguments array. 1714 // RDX: Arguments array.
1675 // TOS(0): Return address. 1715 // TOS(0): Return address.
1676 // Inline cache data object structure: 1716 // Inline cache data object structure:
1677 // 0: function-name 1717 // 0: function-name
1678 // 1: N, number of arguments checked. 1718 // 1: N, number of arguments checked.
1679 // 2 .. (length - 1): group of checks, each check containing: 1719 // 2 .. (length - 1): group of checks, each check containing:
1680 // - N classes. 1720 // - N classes.
1681 // - 1 target function. 1721 // - 1 target function.
1682 void StubCode::GenerateOneArgCheckInlineCacheStub(Assembler* assembler) { 1722 void StubCode::GenerateOneArgCheckInlineCacheStub(Assembler* assembler) {
1683 GenerateUsageCounterIncrement(assembler, RBX, RCX); 1723 GenerateUsageCounterIncrement(assembler, RCX);
1684 return GenerateNArgsCheckInlineCacheStub(assembler, 1); 1724 GenerateNArgsCheckInlineCacheStub(assembler, 1);
1685 } 1725 }
1686 1726
1687 1727
1688 void StubCode::GenerateTwoArgsCheckInlineCacheStub(Assembler* assembler) { 1728 void StubCode::GenerateTwoArgsCheckInlineCacheStub(Assembler* assembler) {
1689 GenerateUsageCounterIncrement(assembler, RBX, RCX); 1729 GenerateUsageCounterIncrement(assembler, RCX);
1690 return GenerateNArgsCheckInlineCacheStub(assembler, 2); 1730 GenerateNArgsCheckInlineCacheStub(assembler, 2);
1691 } 1731 }
1692 1732
1693 1733
1694 void StubCode::GenerateThreeArgsCheckInlineCacheStub(Assembler* assembler) { 1734 void StubCode::GenerateThreeArgsCheckInlineCacheStub(Assembler* assembler) {
1695 GenerateUsageCounterIncrement(assembler, RBX, RCX); 1735 GenerateUsageCounterIncrement(assembler, RCX);
1696 return GenerateNArgsCheckInlineCacheStub(assembler, 3); 1736 GenerateNArgsCheckInlineCacheStub(assembler, 3);
1697 } 1737 }
1698 1738
1739 // Use inline cache data array to invoke the target or continue in inline
1740 // cache miss handler. Stub for 1-argument check (receiver class).
1741 // RDI: function which counter needs to be incremented.
1742 // RBX: Inline cache data object.
1743 // RDX: Arguments array.
1744 // TOS(0): Return address.
1745 // Inline cache data object structure:
1746 // 0: function-name
1747 // 1: N, number of arguments checked.
1748 // 2 .. (length - 1): group of checks, each check containing:
1749 // - N classes.
1750 // - 1 target function.
1751 void StubCode::GenerateOneArgOptimizedCheckInlineCacheStub(
1752 Assembler* assembler) {
1753 GenerateOptimizedUsageCounterIncrement(assembler);
1754 GenerateNArgsCheckInlineCacheStub(assembler, 1);
1755 }
1756
1757
1758 void StubCode::GenerateTwoArgsOptimizedCheckInlineCacheStub(
1759 Assembler* assembler) {
1760 GenerateOptimizedUsageCounterIncrement(assembler);
1761 GenerateNArgsCheckInlineCacheStub(assembler, 2);
1762 }
1763
1764
1765 void StubCode::GenerateThreeArgsOptimizedCheckInlineCacheStub(
1766 Assembler* assembler) {
1767 GenerateOptimizedUsageCounterIncrement(assembler);
1768 GenerateNArgsCheckInlineCacheStub(assembler, 3);
1769 }
1770
1771
1772 // Do not count as no type feedback is collected.
1773 void StubCode::GenerateClosureCallInlineCacheStub(Assembler* assembler) {
1774 GenerateNArgsCheckInlineCacheStub(assembler, 1);
1775 }
1776
1777
1699 // Megamorphic call is currently implemented as IC call but through a stub 1778 // Megamorphic call is currently implemented as IC call but through a stub
1700 // that does not check/count function invocations. 1779 // that does not check/count function invocations.
1701 void StubCode::GenerateMegamorphicCallStub(Assembler* assembler) { 1780 void StubCode::GenerateMegamorphicCallStub(Assembler* assembler) {
1702 return GenerateNArgsCheckInlineCacheStub(assembler, 1); 1781 GenerateNArgsCheckInlineCacheStub(assembler, 1);
1703 } 1782 }
1704 1783
1705 // RBX: Function object. 1784 // RBX: Function object.
1706 // R10: Arguments array. 1785 // R10: Arguments array.
1707 // TOS(0): return address (Dart code). 1786 // TOS(0): return address (Dart code).
1708 void StubCode::GenerateBreakpointStaticStub(Assembler* assembler) { 1787 void StubCode::GenerateBreakpointStaticStub(Assembler* assembler) {
1709 AssemblerMacros::EnterStubFrame(assembler); 1788 AssemblerMacros::EnterStubFrame(assembler);
1710 __ pushq(R10); 1789 __ pushq(R10);
1711 __ pushq(RBX); 1790 __ pushq(RBX);
1712 __ CallRuntime(kBreakpointStaticHandlerRuntimeEntry); 1791 __ CallRuntime(kBreakpointStaticHandlerRuntimeEntry);
(...skipping 307 matching lines...) Expand 10 before | Expand all | Expand 10 after
2020 __ CallRuntime(kOptimizeInvokedFunctionRuntimeEntry); 2099 __ CallRuntime(kOptimizeInvokedFunctionRuntimeEntry);
2021 __ popq(RDX); 2100 __ popq(RDX);
2022 __ popq(RAX); 2101 __ popq(RAX);
2023 __ LeaveFrame(); 2102 __ LeaveFrame();
2024 __ ret(); 2103 __ ret();
2025 } 2104 }
2026 2105
2027 } // namespace dart 2106 } // namespace dart
2028 2107
2029 #endif // defined TARGET_ARCH_X64 2108 #endif // defined TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « runtime/vm/stub_code_ia32.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698