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

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

Issue 11359046: For megamorphic calls (IC calls in optimized code), use a stub without attempting to count usage of… (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"
(...skipping 1525 matching lines...) Expand 10 before | Expand all | Expand 10 after
1536 __ popl(EAX); 1536 __ popl(EAX);
1537 __ popl(EAX); 1537 __ popl(EAX);
1538 __ popl(EAX); // Get result into EAX. 1538 __ popl(EAX); // Get result into EAX.
1539 1539
1540 // Remove the stub frame as we are about to return. 1540 // Remove the stub frame as we are about to return.
1541 __ LeaveFrame(); 1541 __ LeaveFrame();
1542 __ ret(); 1542 __ ret();
1543 } 1543 }
1544 1544
1545 1545
1546 // Loads function into 'temp_reg', preserves 'ic_reg'.
1547 void StubCode::GenerateUsageCounterIncrement(Assembler* assembler,
1548 Register ic_reg,
1549 Register temp_reg) {
1550 __ movl(temp_reg, FieldAddress(ic_reg, ICData::function_offset()));
1551 Label is_hot;
1552 if (FlowGraphCompiler::CanOptimize()) {
1553 ASSERT(FLAG_optimization_counter_threshold > 1);
1554 // The usage_counter is always less than FLAG_optimization_counter_threshold
1555 // except when the function gets optimized.
1556 __ cmpl(FieldAddress(temp_reg, Function::usage_counter_offset()),
1557 Immediate(FLAG_optimization_counter_threshold - 1));
1558 // Do not increment to equality with threshold, since a counter greater
1559 // than threshold denotes a function that was already optimized.
1560 // The equality should be reached only at exit of the method
1561 // (return instruction).
1562 __ j(EQUAL, &is_hot, Assembler::kNearJump);
1563 // As long as VM has no OSR do not optimize in the middle of the function
1564 // but only at exit so that we have collected all type feedback before
1565 // optimizing.
1566 }
1567 __ incl(FieldAddress(temp_reg, Function::usage_counter_offset()));
1568 __ Bind(&is_hot);
1569 }
1570
1546 1571
1547 // Generate inline cache check for 'num_args'. 1572 // Generate inline cache check for 'num_args'.
1548 // ECX: Inline cache data object. 1573 // ECX: Inline cache data object.
1549 // EDX: Arguments descriptor array. 1574 // EDX: Arguments descriptor array.
1550 // TOS(0): return address 1575 // TOS(0): return address
1551 // Control flow: 1576 // Control flow:
1552 // - If receiver is null -> jump to IC miss. 1577 // - If receiver is null -> jump to IC miss.
1553 // - If receiver is Smi -> load Smi class. 1578 // - If receiver is Smi -> load Smi class.
1554 // - If receiver is not-Smi -> load receiver's class. 1579 // - If receiver is not-Smi -> load receiver's class.
1555 // - Check if 'num_args' (including receiver) match any IC data group. 1580 // - Check if 'num_args' (including receiver) match any IC data group.
1556 // - Match found -> jump to target. 1581 // - Match found -> jump to target.
1557 // - Match not found -> jump to IC miss. 1582 // - Match not found -> jump to IC miss.
1558 void StubCode::GenerateNArgsCheckInlineCacheStub(Assembler* assembler, 1583 void StubCode::GenerateNArgsCheckInlineCacheStub(Assembler* assembler,
1559 intptr_t num_args) { 1584 intptr_t num_args) {
1560 ASSERT(num_args > 0); 1585 ASSERT(num_args > 0);
1561 #if defined(DEBUG) 1586 #if defined(DEBUG)
1562 { Label ok; 1587 { Label ok;
1563 // Check that the IC data array has NumberOfArgumentsChecked() == num_args. 1588 // Check that the IC data array has NumberOfArgumentsChecked() == num_args.
1564 // 'num_args_tested' is stored as an untagged int. 1589 // 'num_args_tested' is stored as an untagged int.
1565 __ movl(EBX, FieldAddress(ECX, ICData::num_args_tested_offset())); 1590 __ movl(EBX, FieldAddress(ECX, ICData::num_args_tested_offset()));
1566 __ cmpl(EBX, Immediate(num_args)); 1591 __ cmpl(EBX, Immediate(num_args));
1567 __ j(EQUAL, &ok, Assembler::kNearJump); 1592 __ j(EQUAL, &ok, Assembler::kNearJump);
1568 __ Stop("Incorrect stub for IC data"); 1593 __ Stop("Incorrect stub for IC data");
1569 __ Bind(&ok); 1594 __ Bind(&ok);
1570 } 1595 }
1571 #endif // DEBUG 1596 #endif // DEBUG
1572 1597
1573 __ movl(EBX, FieldAddress(ECX, ICData::function_offset()));
1574 Label is_hot;
1575 if (FlowGraphCompiler::CanOptimize()) {
1576 ASSERT(FLAG_optimization_counter_threshold > 1);
1577 // The usage_counter is always less than FLAG_optimization_counter_threshold
1578 // except when the function gets optimized.
1579 __ cmpl(FieldAddress(EBX, Function::usage_counter_offset()),
1580 Immediate(FLAG_optimization_counter_threshold - 1));
1581 // Do not increment to equality with threshold, since a counter greater
1582 // than threshold denotes a function that was already optimized.
1583 // The equality should be reached only at exit of the method
1584 // (return instruction).
1585 __ j(EQUAL, &is_hot, Assembler::kNearJump);
1586 // As long as VM has no OSR do not optimize in the middle of the function
1587 // but only at exit so that we have collected all type feedback before
1588 // optimizing.
1589 }
1590 __ incl(FieldAddress(EBX, Function::usage_counter_offset()));
1591 __ Bind(&is_hot);
1592
1593 // Loop that checks if there is an IC data match. 1598 // Loop that checks if there is an IC data match.
1594 Label loop, update, test, found, get_class_id_as_smi; 1599 Label loop, update, test, found, get_class_id_as_smi;
1595 // ECX: IC data object (preserved). 1600 // ECX: IC data object (preserved).
1596 __ movl(EBX, FieldAddress(ECX, ICData::ic_data_offset())); 1601 __ movl(EBX, FieldAddress(ECX, ICData::ic_data_offset()));
1597 // EBX: ic_data_array with check entries: classes and target functions. 1602 // EBX: ic_data_array with check entries: classes and target functions.
1598 __ leal(EBX, FieldAddress(EBX, Array::data_offset())); 1603 __ leal(EBX, FieldAddress(EBX, Array::data_offset()));
1599 // EBX: points directly to the first ic data array element. 1604 // EBX: points directly to the first ic data array element.
1600 1605
1601 // Get the receiver's class ID (first read number of arguments from 1606 // Get the receiver's class ID (first read number of arguments from
1602 // argument descriptor array and then access the receiver from the stack). 1607 // argument descriptor array and then access the receiver from the stack).
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
1705 1710
1706 __ Bind(&not_smi); 1711 __ Bind(&not_smi);
1707 __ LoadClassId(EAX, EAX); 1712 __ LoadClassId(EAX, EAX);
1708 __ SmiTag(EAX); 1713 __ SmiTag(EAX);
1709 __ ret(); 1714 __ ret();
1710 } 1715 }
1711 1716
1712 1717
1713 // Use inline cache data array to invoke the target or continue in inline 1718 // Use inline cache data array to invoke the target or continue in inline
1714 // cache miss handler. Stub for 1-argument check (receiver class). 1719 // cache miss handler. Stub for 1-argument check (receiver class).
1715 // ECX: Inline cache data array 1720 // ECX: Inline cache data object.
1716 // EDX: Arguments array 1721 // EDX: Arguments array.
1717 // TOS(0): return address 1722 // TOS(0): Return address.
1718 // Inline cache data array structure: 1723 // Inline cache data object structure:
1719 // 0: function-name 1724 // 0: function-name
1720 // 1: N, number of arguments checked. 1725 // 1: N, number of arguments checked.
1721 // 2 .. (length - 1): group of checks, each check containing: 1726 // 2 .. (length - 1): group of checks, each check containing:
1722 // - N classes. 1727 // - N classes.
1723 // - 1 target function. 1728 // - 1 target function.
1724 void StubCode::GenerateOneArgCheckInlineCacheStub(Assembler* assembler) { 1729 void StubCode::GenerateOneArgCheckInlineCacheStub(Assembler* assembler) {
1730 GenerateUsageCounterIncrement(assembler, ECX, EBX);
1725 return GenerateNArgsCheckInlineCacheStub(assembler, 1); 1731 return GenerateNArgsCheckInlineCacheStub(assembler, 1);
1726 } 1732 }
1727 1733
1728 1734
1729 void StubCode::GenerateTwoArgsCheckInlineCacheStub(Assembler* assembler) { 1735 void StubCode::GenerateTwoArgsCheckInlineCacheStub(Assembler* assembler) {
1736 GenerateUsageCounterIncrement(assembler, ECX, EBX);
1730 return GenerateNArgsCheckInlineCacheStub(assembler, 2); 1737 return GenerateNArgsCheckInlineCacheStub(assembler, 2);
1731 } 1738 }
1732 1739
1733 1740
1734 void StubCode::GenerateThreeArgsCheckInlineCacheStub(Assembler* assembler) { 1741 void StubCode::GenerateThreeArgsCheckInlineCacheStub(Assembler* assembler) {
1742 GenerateUsageCounterIncrement(assembler, ECX, EBX);
1735 return GenerateNArgsCheckInlineCacheStub(assembler, 3); 1743 return GenerateNArgsCheckInlineCacheStub(assembler, 3);
1736 } 1744 }
1737 1745
1738 1746
1747 // Megamorphic call is currently implemented as IC call but through a stub
1748 // that does not check/count function invocations.
1749 void StubCode::GenerateMegamorphicCallStub(Assembler* assembler) {
1750 return GenerateNArgsCheckInlineCacheStub(assembler, 1);
1751 }
1752
1753
1739 // ECX: Function object. 1754 // ECX: Function object.
1740 // EDX: Arguments array. 1755 // EDX: Arguments array.
1741 // TOS(0): return address (Dart code). 1756 // TOS(0): return address (Dart code).
1742 void StubCode::GenerateBreakpointStaticStub(Assembler* assembler) { 1757 void StubCode::GenerateBreakpointStaticStub(Assembler* assembler) {
1743 // Create a stub frame as we are pushing some objects on the stack before 1758 // Create a stub frame as we are pushing some objects on the stack before
1744 // calling into the runtime. 1759 // calling into the runtime.
1745 AssemblerMacros::EnterStubFrame(assembler); 1760 AssemblerMacros::EnterStubFrame(assembler);
1746 __ pushl(EDX); 1761 __ pushl(EDX);
1747 __ pushl(ECX); 1762 __ pushl(ECX);
1748 __ CallRuntime(kBreakpointStaticHandlerRuntimeEntry); 1763 __ CallRuntime(kBreakpointStaticHandlerRuntimeEntry);
(...skipping 304 matching lines...) Expand 10 before | Expand all | Expand 10 after
2053 __ Drop(4); 2068 __ Drop(4);
2054 __ LeaveFrame(); 2069 __ LeaveFrame();
2055 2070
2056 __ jmp(&compute_result, Assembler::kNearJump); 2071 __ jmp(&compute_result, Assembler::kNearJump);
2057 } 2072 }
2058 2073
2059 2074
2060 } // namespace dart 2075 } // namespace dart
2061 2076
2062 #endif // defined TARGET_ARCH_IA32 2077 #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