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

Side by Side Diff: runtime/vm/stub_code_x64.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_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"
(...skipping 1505 matching lines...) Expand 10 before | Expand all | Expand 10 after
1516 __ popq(RAX); 1516 __ popq(RAX);
1517 __ popq(RAX); 1517 __ popq(RAX);
1518 __ popq(RAX); // Get result into RAX. 1518 __ popq(RAX); // Get result into RAX.
1519 1519
1520 // Remove the stub frame as we are about to return. 1520 // Remove the stub frame as we are about to return.
1521 __ LeaveFrame(); 1521 __ LeaveFrame();
1522 __ ret(); 1522 __ ret();
1523 } 1523 }
1524 1524
1525 1525
1526 // Loads function into 'temp_reg', preserves 'ic_reg'.
1527 void StubCode::GenerateUsageCounterIncrement(Assembler* assembler,
1528 Register ic_reg,
1529 Register temp_reg) {
1530 __ movq(temp_reg, FieldAddress(ic_reg, ICData::function_offset()));
1531 Label is_hot;
1532 if (FlowGraphCompiler::CanOptimize()) {
1533 ASSERT(FLAG_optimization_counter_threshold > 1);
1534 // The usage_counter is always less than FLAG_optimization_counter_threshold
1535 // except when the function gets optimized.
1536 __ cmpq(FieldAddress(temp_reg, Function::usage_counter_offset()),
1537 Immediate(FLAG_optimization_counter_threshold - 1));
1538 // Do not increment to equality with threshold, since a counter greater
1539 // than threshold denotes a function that was already optimized.
1540 // The equality should be reached only at exit of the method
1541 // (return instruction).
1542 __ j(EQUAL, &is_hot, Assembler::kNearJump);
1543 // As long as VM has no OSR do not optimize in the middle of the function
1544 // but only at exit so that we have collected all type feedback before
1545 // optimizing.
1546 }
1547 __ incq(FieldAddress(temp_reg, Function::usage_counter_offset()));
1548 __ Bind(&is_hot);
1549 }
1526 1550
1527 // Generate inline cache check for 'num_args'. 1551 // Generate inline cache check for 'num_args'.
1528 // RBX: Inline cache data object. 1552 // RBX: Inline cache data object.
1529 // R10: Arguments descriptor array. 1553 // R10: Arguments descriptor array.
1530 // TOS(0): return address 1554 // TOS(0): return address
1531 // Control flow: 1555 // Control flow:
1532 // - If receiver is null -> jump to IC miss. 1556 // - If receiver is null -> jump to IC miss.
1533 // - If receiver is Smi -> load Smi class. 1557 // - If receiver is Smi -> load Smi class.
1534 // - If receiver is not-Smi -> load receiver's class. 1558 // - If receiver is not-Smi -> load receiver's class.
1535 // - Check if 'num_args' (including receiver) match any IC data group. 1559 // - Check if 'num_args' (including receiver) match any IC data group.
1536 // - Match found -> jump to target. 1560 // - Match found -> jump to target.
1537 // - Match not found -> jump to IC miss. 1561 // - Match not found -> jump to IC miss.
1538 void StubCode::GenerateNArgsCheckInlineCacheStub(Assembler* assembler, 1562 void StubCode::GenerateNArgsCheckInlineCacheStub(Assembler* assembler,
1539 intptr_t num_args) { 1563 intptr_t num_args) {
1540 ASSERT(num_args > 0); 1564 ASSERT(num_args > 0);
1541 #if defined(DEBUG) 1565 #if defined(DEBUG)
1542 { Label ok; 1566 { Label ok;
1543 // Check that the IC data array has NumberOfArgumentsChecked() == num_args. 1567 // Check that the IC data array has NumberOfArgumentsChecked() == num_args.
1544 // 'num_args_tested' is stored as an untagged int. 1568 // 'num_args_tested' is stored as an untagged int.
1545 __ movq(RCX, FieldAddress(RBX, ICData::num_args_tested_offset())); 1569 __ movq(RCX, FieldAddress(RBX, ICData::num_args_tested_offset()));
1546 __ cmpq(RCX, Immediate(num_args)); 1570 __ cmpq(RCX, Immediate(num_args));
1547 __ j(EQUAL, &ok, Assembler::kNearJump); 1571 __ j(EQUAL, &ok, Assembler::kNearJump);
1548 __ Stop("Incorrect stub for IC data"); 1572 __ Stop("Incorrect stub for IC data");
1549 __ Bind(&ok); 1573 __ Bind(&ok);
1550 } 1574 }
1551 #endif // DEBUG 1575 #endif // DEBUG
1552 1576
1553 __ movq(RCX, FieldAddress(RBX, ICData::function_offset()));
1554 Label is_hot;
1555 if (FlowGraphCompiler::CanOptimize()) {
1556 ASSERT(FLAG_optimization_counter_threshold > 1);
1557 // The usage_counter is always less than FLAG_optimization_counter_threshold
1558 // except when the function gets optimized.
1559 __ cmpq(FieldAddress(RCX, Function::usage_counter_offset()),
1560 Immediate(FLAG_optimization_counter_threshold - 1));
1561 // Do not increment to equality with threshold, since a counter greater
1562 // than threshold denotes a function that was already optimized.
1563 // The equality should be reached only at exit of the method
1564 // (return instruction).
1565 __ j(EQUAL, &is_hot, Assembler::kNearJump);
1566 // As long as VM has no OSR do not optimize in the middle of the function
1567 // but only at exit so that we have collected all type feedback before
1568 // optimizing.
1569 }
1570 __ incq(FieldAddress(RCX, Function::usage_counter_offset()));
1571 __ Bind(&is_hot);
1572
1573 // Loop that checks if there is an IC data match. 1577 // Loop that checks if there is an IC data match.
1574 Label loop, update, test, found, get_class_id_as_smi; 1578 Label loop, update, test, found, get_class_id_as_smi;
1575 // RBX: IC data object (preserved). 1579 // RBX: IC data object (preserved).
1576 __ movq(R12, FieldAddress(RBX, ICData::ic_data_offset())); 1580 __ movq(R12, FieldAddress(RBX, ICData::ic_data_offset()));
1577 // R12: ic_data_array with check entries: classes and target functions. 1581 // R12: ic_data_array with check entries: classes and target functions.
1578 __ leaq(R12, FieldAddress(R12, Array::data_offset())); 1582 __ leaq(R12, FieldAddress(R12, Array::data_offset()));
1579 // R12: points directly to the first ic data array element. 1583 // R12: points directly to the first ic data array element.
1580 1584
1581 // Get the receiver's class ID (first read number of arguments from 1585 // Get the receiver's class ID (first read number of arguments from
1582 // argument descriptor array and then access the receiver from the stack). 1586 // argument descriptor array and then access the receiver from the stack).
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
1682 1686
1683 __ Bind(&not_smi); 1687 __ Bind(&not_smi);
1684 __ LoadClassId(RAX, RAX); 1688 __ LoadClassId(RAX, RAX);
1685 __ SmiTag(RAX); 1689 __ SmiTag(RAX);
1686 __ ret(); 1690 __ ret();
1687 } 1691 }
1688 1692
1689 1693
1690 // Use inline cache data array to invoke the target or continue in inline 1694 // Use inline cache data array to invoke the target or continue in inline
1691 // cache miss handler. Stub for 1-argument check (receiver class). 1695 // cache miss handler. Stub for 1-argument check (receiver class).
1692 // RCX: Inline cache data array 1696 // RBX: Inline cache data object.
1693 // RDX: Arguments array 1697 // RDX: Arguments array.
1694 // TOS(0): return address 1698 // TOS(0): Return address.
1695 // Inline cache data array structure: 1699 // Inline cache data object structure:
1696 // 0: function-name 1700 // 0: function-name
1697 // 1: N, number of arguments checked. 1701 // 1: N, number of arguments checked.
1698 // 2 .. (length - 1): group of checks, each check containing: 1702 // 2 .. (length - 1): group of checks, each check containing:
1699 // - N classes. 1703 // - N classes.
1700 // - 1 target function. 1704 // - 1 target function.
1701 void StubCode::GenerateOneArgCheckInlineCacheStub(Assembler* assembler) { 1705 void StubCode::GenerateOneArgCheckInlineCacheStub(Assembler* assembler) {
1706 GenerateUsageCounterIncrement(assembler, RBX, RCX);
1702 return GenerateNArgsCheckInlineCacheStub(assembler, 1); 1707 return GenerateNArgsCheckInlineCacheStub(assembler, 1);
1703 } 1708 }
1704 1709
1705 1710
1706 void StubCode::GenerateTwoArgsCheckInlineCacheStub(Assembler* assembler) { 1711 void StubCode::GenerateTwoArgsCheckInlineCacheStub(Assembler* assembler) {
1712 GenerateUsageCounterIncrement(assembler, RBX, RCX);
1707 return GenerateNArgsCheckInlineCacheStub(assembler, 2); 1713 return GenerateNArgsCheckInlineCacheStub(assembler, 2);
1708 } 1714 }
1709 1715
1710 1716
1711 void StubCode::GenerateThreeArgsCheckInlineCacheStub(Assembler* assembler) { 1717 void StubCode::GenerateThreeArgsCheckInlineCacheStub(Assembler* assembler) {
1718 GenerateUsageCounterIncrement(assembler, RBX, RCX);
1712 return GenerateNArgsCheckInlineCacheStub(assembler, 3); 1719 return GenerateNArgsCheckInlineCacheStub(assembler, 3);
1713 } 1720 }
1714 1721
1722 // Megamorphic call is currently implemented as IC call but through a stub
1723 // that does not check/count function invocations.
1724 void StubCode::GenerateMegamorphicCallStub(Assembler* assembler) {
1725 return GenerateNArgsCheckInlineCacheStub(assembler, 1);
1726 }
1715 1727
1716 // RBX: Function object. 1728 // RBX: Function object.
1717 // R10: Arguments array. 1729 // R10: Arguments array.
1718 // TOS(0): return address (Dart code). 1730 // TOS(0): return address (Dart code).
1719 void StubCode::GenerateBreakpointStaticStub(Assembler* assembler) { 1731 void StubCode::GenerateBreakpointStaticStub(Assembler* assembler) {
1720 AssemblerMacros::EnterStubFrame(assembler); 1732 AssemblerMacros::EnterStubFrame(assembler);
1721 __ pushq(R10); 1733 __ pushq(R10);
1722 __ pushq(RBX); 1734 __ pushq(RBX);
1723 __ CallRuntime(kBreakpointStaticHandlerRuntimeEntry); 1735 __ CallRuntime(kBreakpointStaticHandlerRuntimeEntry);
1724 __ popq(RBX); 1736 __ popq(RBX);
(...skipping 292 matching lines...) Expand 10 before | Expand all | Expand 10 after
2017 __ CallRuntime(kUpdateICDataTwoArgsRuntimeEntry); 2029 __ CallRuntime(kUpdateICDataTwoArgsRuntimeEntry);
2018 __ Drop(4); 2030 __ Drop(4);
2019 __ LeaveFrame(); 2031 __ LeaveFrame();
2020 2032
2021 __ jmp(&compute_result, Assembler::kNearJump); 2033 __ jmp(&compute_result, Assembler::kNearJump);
2022 } 2034 }
2023 2035
2024 } // namespace dart 2036 } // namespace dart
2025 2037
2026 #endif // defined TARGET_ARCH_X64 2038 #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