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

Side by Side Diff: runtime/vm/stub_code_ia32.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.h ('k') | runtime/vm/stub_code_x64.cc » ('j') | 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_IA32) 6 #if defined(TARGET_ARCH_IA32)
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 // ESP : points to return address. 31 // ESP : points to return address.
31 // ESP + 4 : address of last argument in argument array. 32 // ESP + 4 : address of last argument in argument array.
32 // ESP + 4*EDX : address of first argument in argument array. 33 // ESP + 4*EDX : address of first argument in argument array.
33 // ESP + 4*EDX + 4 : address of return value. 34 // ESP + 4*EDX + 4 : address of return value.
34 // ECX : address of the runtime function to call. 35 // ECX : address of the runtime function to call.
35 // EDX : number of arguments to the call. 36 // EDX : number of arguments to the call.
36 // Must preserve callee saved registers EDI and EBX. 37 // Must preserve callee saved registers EDI and EBX.
37 void StubCode::GenerateCallToRuntimeStub(Assembler* assembler) { 38 void StubCode::GenerateCallToRuntimeStub(Assembler* assembler) {
(...skipping 1480 matching lines...) Expand 10 before | Expand all | Expand 10 after
1518 __ popl(EAX); 1519 __ popl(EAX);
1519 __ popl(EAX); 1520 __ popl(EAX);
1520 __ popl(EAX); // Get result into EAX. 1521 __ popl(EAX); // Get result into EAX.
1521 1522
1522 // Remove the stub frame as we are about to return. 1523 // Remove the stub frame as we are about to return.
1523 __ LeaveFrame(); 1524 __ LeaveFrame();
1524 __ ret(); 1525 __ ret();
1525 } 1526 }
1526 1527
1527 1528
1528 // Loads function into 'temp_reg', preserves 'ic_reg'. 1529 void StubCode::GenerateOptimizedUsageCounterIncrement(Assembler* assembler) {
1530 Register argdesc_reg = EDX;
1531 Register ic_reg = ECX;
1532 Register func_reg = EDI;
1533 if (FLAG_trace_optimized_ic_calls) {
1534 AssemblerMacros::EnterStubFrame(assembler);
1535 __ pushl(func_reg); // Preserve
1536 __ pushl(argdesc_reg); // Preserve.
1537 __ pushl(ic_reg); // Preserve.
1538 __ pushl(ic_reg); // Argument.
1539 __ pushl(func_reg); // Argument.
1540 __ CallRuntime(kTraceICCallRuntimeEntry);
1541 __ popl(EAX); // Discard argument;
1542 __ popl(EAX); // Discard argument;
1543 __ popl(ic_reg); // Restore.
1544 __ popl(argdesc_reg); // Restore.
1545 __ popl(func_reg); // Restore.
1546 __ LeaveFrame();
1547 }
1548 Label is_hot;
1549 if (FlowGraphCompiler::CanOptimize()) {
1550 ASSERT(FLAG_optimization_counter_threshold > 1);
1551 __ cmpl(FieldAddress(func_reg, Function::usage_counter_offset()),
1552 Immediate(FLAG_optimization_counter_threshold));
1553 __ j(GREATER_EQUAL, &is_hot, Assembler::kNearJump);
1554 // As long as VM has no OSR do not optimize in the middle of the function
1555 // but only at exit so that we have collected all type feedback before
1556 // optimizing.
1557 }
1558 __ incl(FieldAddress(func_reg, Function::usage_counter_offset()));
1559 __ Bind(&is_hot);
1560 }
1561
1562
1563
1564 // Loads function into 'temp_reg'.
1529 void StubCode::GenerateUsageCounterIncrement(Assembler* assembler, 1565 void StubCode::GenerateUsageCounterIncrement(Assembler* assembler,
1530 Register ic_reg,
1531 Register temp_reg) { 1566 Register temp_reg) {
1532 __ movl(temp_reg, FieldAddress(ic_reg, ICData::function_offset())); 1567 Register ic_reg = ECX;
1568 Register func_reg = temp_reg;
1569 ASSERT(ic_reg != func_reg);
1570 __ movl(func_reg, FieldAddress(ic_reg, ICData::function_offset()));
1533 Label is_hot; 1571 Label is_hot;
1534 if (FlowGraphCompiler::CanOptimize()) { 1572 if (FlowGraphCompiler::CanOptimize()) {
1535 ASSERT(FLAG_optimization_counter_threshold > 1); 1573 ASSERT(FLAG_optimization_counter_threshold > 1);
1536 // The usage_counter is always less than FLAG_optimization_counter_threshold 1574 // The usage_counter is always less than FLAG_optimization_counter_threshold
1537 // except when the function gets optimized. 1575 // except when the function gets optimized.
1538 __ cmpl(FieldAddress(temp_reg, Function::usage_counter_offset()), 1576 __ cmpl(FieldAddress(func_reg, Function::usage_counter_offset()),
1539 Immediate(FLAG_optimization_counter_threshold)); 1577 Immediate(FLAG_optimization_counter_threshold));
1540 __ j(EQUAL, &is_hot, Assembler::kNearJump); 1578 __ j(EQUAL, &is_hot, Assembler::kNearJump);
1541 // As long as VM has no OSR do not optimize in the middle of the function 1579 // As long as VM has no OSR do not optimize in the middle of the function
1542 // but only at exit so that we have collected all type feedback before 1580 // but only at exit so that we have collected all type feedback before
1543 // optimizing. 1581 // optimizing.
1544 } 1582 }
1545 __ incl(FieldAddress(temp_reg, Function::usage_counter_offset())); 1583 __ incl(FieldAddress(func_reg, Function::usage_counter_offset()));
1546 __ Bind(&is_hot); 1584 __ Bind(&is_hot);
1547 } 1585 }
1548 1586
1549 1587
1550 // Generate inline cache check for 'num_args'. 1588 // Generate inline cache check for 'num_args'.
1551 // ECX: Inline cache data object. 1589 // ECX: Inline cache data object.
1552 // EDX: Arguments descriptor array. 1590 // EDX: Arguments descriptor array.
1553 // TOS(0): return address 1591 // TOS(0): return address
1554 // Control flow: 1592 // Control flow:
1555 // - If receiver is null -> jump to IC miss. 1593 // - If receiver is null -> jump to IC miss.
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
1657 __ popl(EAX); 1695 __ popl(EAX);
1658 } 1696 }
1659 __ popl(EAX); // Pop returned code object into EAX (null if not found). 1697 __ popl(EAX); // Pop returned code object into EAX (null if not found).
1660 __ popl(ECX); // Restore IC data array. 1698 __ popl(ECX); // Restore IC data array.
1661 __ popl(EDX); // Restore arguments array. 1699 __ popl(EDX); // Restore arguments array.
1662 __ LeaveFrame(); 1700 __ LeaveFrame();
1663 Label call_target_function; 1701 Label call_target_function;
1664 __ cmpl(EAX, raw_null); 1702 __ cmpl(EAX, raw_null);
1665 __ j(NOT_EQUAL, &call_target_function, Assembler::kNearJump); 1703 __ j(NOT_EQUAL, &call_target_function, Assembler::kNearJump);
1666 // NoSuchMethod or closure. 1704 // NoSuchMethod or closure.
1705 // Mark IC call that it may be a closure call that does not collect
1706 // type feedback.
1707 __ movb(FieldAddress(ECX, ICData::is_closure_call_offset()), Immediate(1));
1667 __ jmp(&StubCode::InstanceFunctionLookupLabel()); 1708 __ jmp(&StubCode::InstanceFunctionLookupLabel());
1668 1709
1669 __ Bind(&found); 1710 __ Bind(&found);
1670 // EBX: Pointer to an IC data check group (classes + target) 1711 // EBX: Pointer to an IC data check group (classes + target)
1671 __ movl(EAX, Address(EBX, kWordSize * num_args)); // Target function. 1712 __ movl(EAX, Address(EBX, kWordSize * num_args)); // Target function.
1672 1713
1673 __ Bind(&call_target_function); 1714 __ Bind(&call_target_function);
1674 // EAX: Target function. 1715 // EAX: Target function.
1675 __ movl(EAX, FieldAddress(EAX, Function::code_offset())); 1716 __ movl(EAX, FieldAddress(EAX, Function::code_offset()));
1676 __ movl(EAX, FieldAddress(EAX, Code::instructions_offset())); 1717 __ movl(EAX, FieldAddress(EAX, Code::instructions_offset()));
(...skipping 21 matching lines...) Expand all
1698 // ECX: Inline cache data object. 1739 // ECX: Inline cache data object.
1699 // EDX: Arguments array. 1740 // EDX: Arguments array.
1700 // TOS(0): Return address. 1741 // TOS(0): Return address.
1701 // Inline cache data object structure: 1742 // Inline cache data object structure:
1702 // 0: function-name 1743 // 0: function-name
1703 // 1: N, number of arguments checked. 1744 // 1: N, number of arguments checked.
1704 // 2 .. (length - 1): group of checks, each check containing: 1745 // 2 .. (length - 1): group of checks, each check containing:
1705 // - N classes. 1746 // - N classes.
1706 // - 1 target function. 1747 // - 1 target function.
1707 void StubCode::GenerateOneArgCheckInlineCacheStub(Assembler* assembler) { 1748 void StubCode::GenerateOneArgCheckInlineCacheStub(Assembler* assembler) {
1708 GenerateUsageCounterIncrement(assembler, ECX, EBX); 1749 GenerateUsageCounterIncrement(assembler, EBX);
1709 return GenerateNArgsCheckInlineCacheStub(assembler, 1); 1750 GenerateNArgsCheckInlineCacheStub(assembler, 1);
1710 } 1751 }
1711 1752
1712 1753
1713 void StubCode::GenerateTwoArgsCheckInlineCacheStub(Assembler* assembler) { 1754 void StubCode::GenerateTwoArgsCheckInlineCacheStub(Assembler* assembler) {
1714 GenerateUsageCounterIncrement(assembler, ECX, EBX); 1755 GenerateUsageCounterIncrement(assembler, EBX);
1715 return GenerateNArgsCheckInlineCacheStub(assembler, 2); 1756 GenerateNArgsCheckInlineCacheStub(assembler, 2);
1716 } 1757 }
1717 1758
1718 1759
1719 void StubCode::GenerateThreeArgsCheckInlineCacheStub(Assembler* assembler) { 1760 void StubCode::GenerateThreeArgsCheckInlineCacheStub(Assembler* assembler) {
1720 GenerateUsageCounterIncrement(assembler, ECX, EBX); 1761 GenerateUsageCounterIncrement(assembler, EBX);
1721 return GenerateNArgsCheckInlineCacheStub(assembler, 3); 1762 GenerateNArgsCheckInlineCacheStub(assembler, 3);
1763 }
1764
1765
1766
1767 // Use inline cache data array to invoke the target or continue in inline
1768 // cache miss handler. Stub for 1-argument check (receiver class).
1769 // EDI: function which counter needs to be incremented.
1770 // ECX: Inline cache data object.
1771 // EDX: Arguments array.
1772 // TOS(0): Return address.
1773 // Inline cache data object structure:
1774 // 0: function-name
1775 // 1: N, number of arguments checked.
1776 // 2 .. (length - 1): group of checks, each check containing:
1777 // - N classes.
1778 // - 1 target function.
1779 void StubCode::GenerateOneArgOptimizedCheckInlineCacheStub(
1780 Assembler* assembler) {
1781 GenerateOptimizedUsageCounterIncrement(assembler);
1782 GenerateNArgsCheckInlineCacheStub(assembler, 1);
1783 }
1784
1785
1786 void StubCode::GenerateTwoArgsOptimizedCheckInlineCacheStub(
1787 Assembler* assembler) {
1788 GenerateOptimizedUsageCounterIncrement(assembler);
1789 GenerateNArgsCheckInlineCacheStub(assembler, 2);
1790 }
1791
1792
1793 void StubCode::GenerateThreeArgsOptimizedCheckInlineCacheStub(
1794 Assembler* assembler) {
1795 GenerateOptimizedUsageCounterIncrement(assembler);
1796 GenerateNArgsCheckInlineCacheStub(assembler, 3);
1797 }
1798
1799
1800 // Do not count as no type feedback is collected.
1801 void StubCode::GenerateClosureCallInlineCacheStub(Assembler* assembler) {
1802 GenerateNArgsCheckInlineCacheStub(assembler, 1);
1722 } 1803 }
1723 1804
1724 1805
1725 // Megamorphic call is currently implemented as IC call but through a stub 1806 // Megamorphic call is currently implemented as IC call but through a stub
1726 // that does not check/count function invocations. 1807 // that does not check/count function invocations.
1727 void StubCode::GenerateMegamorphicCallStub(Assembler* assembler) { 1808 void StubCode::GenerateMegamorphicCallStub(Assembler* assembler) {
1728 return GenerateNArgsCheckInlineCacheStub(assembler, 1); 1809 GenerateNArgsCheckInlineCacheStub(assembler, 1);
1729 } 1810 }
1730 1811
1731 1812
1732 // ECX: Function object. 1813 // ECX: Function object.
1733 // EDX: Arguments array. 1814 // EDX: Arguments array.
1734 // TOS(0): return address (Dart code). 1815 // TOS(0): return address (Dart code).
1735 void StubCode::GenerateBreakpointStaticStub(Assembler* assembler) { 1816 void StubCode::GenerateBreakpointStaticStub(Assembler* assembler) {
1736 // Create a stub frame as we are pushing some objects on the stack before 1817 // Create a stub frame as we are pushing some objects on the stack before
1737 // calling into the runtime. 1818 // calling into the runtime.
1738 AssemblerMacros::EnterStubFrame(assembler); 1819 AssemblerMacros::EnterStubFrame(assembler);
(...skipping 321 matching lines...) Expand 10 before | Expand all | Expand 10 after
2060 __ CallRuntime(kOptimizeInvokedFunctionRuntimeEntry); 2141 __ CallRuntime(kOptimizeInvokedFunctionRuntimeEntry);
2061 __ popl(EDX); 2142 __ popl(EDX);
2062 __ popl(EAX); 2143 __ popl(EAX);
2063 __ LeaveFrame(); 2144 __ LeaveFrame();
2064 __ ret(); 2145 __ ret();
2065 } 2146 }
2066 2147
2067 } // namespace dart 2148 } // namespace dart
2068 2149
2069 #endif // defined TARGET_ARCH_IA32 2150 #endif // defined TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « runtime/vm/stub_code.h ('k') | runtime/vm/stub_code_x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698