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

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

Issue 735543003: Range feedback for binary integer operations. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Address comments Created 6 years 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') | 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) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, 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_MIPS) 6 #if defined(TARGET_ARCH_MIPS)
7 7
8 #include "vm/assembler.h" 8 #include "vm/assembler.h"
9 #include "vm/code_generator.h" 9 #include "vm/code_generator.h"
10 #include "vm/compiler.h" 10 #include "vm/compiler.h"
(...skipping 1406 matching lines...) Expand 10 before | Expand all | Expand 10 after
1417 // - If receiver is null -> jump to IC miss. 1417 // - If receiver is null -> jump to IC miss.
1418 // - If receiver is Smi -> load Smi class. 1418 // - If receiver is Smi -> load Smi class.
1419 // - If receiver is not-Smi -> load receiver's class. 1419 // - If receiver is not-Smi -> load receiver's class.
1420 // - Check if 'num_args' (including receiver) match any IC data group. 1420 // - Check if 'num_args' (including receiver) match any IC data group.
1421 // - Match found -> jump to target. 1421 // - Match found -> jump to target.
1422 // - Match not found -> jump to IC miss. 1422 // - Match not found -> jump to IC miss.
1423 void StubCode::GenerateNArgsCheckInlineCacheStub( 1423 void StubCode::GenerateNArgsCheckInlineCacheStub(
1424 Assembler* assembler, 1424 Assembler* assembler,
1425 intptr_t num_args, 1425 intptr_t num_args,
1426 const RuntimeEntry& handle_ic_miss, 1426 const RuntimeEntry& handle_ic_miss,
1427 Token::Kind kind) { 1427 Token::Kind kind,
1428 RangeCollectionMode range_collection_mode) {
1428 __ TraceSimMsg("NArgsCheckInlineCacheStub"); 1429 __ TraceSimMsg("NArgsCheckInlineCacheStub");
1429 ASSERT(num_args > 0); 1430 ASSERT(num_args > 0);
1430 #if defined(DEBUG) 1431 #if defined(DEBUG)
1431 { Label ok; 1432 { Label ok;
1432 // Check that the IC data array has NumArgsTested() == num_args. 1433 // Check that the IC data array has NumArgsTested() == num_args.
1433 // 'NumArgsTested' is stored in the least significant bits of 'state_bits'. 1434 // 'NumArgsTested' is stored in the least significant bits of 'state_bits'.
1434 __ lw(T0, FieldAddress(S5, ICData::state_bits_offset())); 1435 __ lw(T0, FieldAddress(S5, ICData::state_bits_offset()));
1435 ASSERT(ICData::NumArgsTestedShift() == 0); // No shift needed. 1436 ASSERT(ICData::NumArgsTestedShift() == 0); // No shift needed.
1436 __ andi(T0, T0, Immediate(ICData::NumArgsTestedMask())); 1437 __ andi(T0, T0, Immediate(ICData::NumArgsTestedMask()));
1437 __ BranchEqual(T0, Immediate(num_args), &ok); 1438 __ BranchEqual(T0, Immediate(num_args), &ok);
1438 __ Stop("Incorrect stub for IC data"); 1439 __ Stop("Incorrect stub for IC data");
1439 __ Bind(&ok); 1440 __ Bind(&ok);
1440 } 1441 }
1441 #endif // DEBUG 1442 #endif // DEBUG
1442 1443
1443 1444
1444 // Check single stepping. 1445 // Check single stepping.
1445 Label stepping, done_stepping; 1446 Label stepping, done_stepping;
1446 __ LoadIsolate(T0); 1447 __ LoadIsolate(T0);
1447 __ lbu(T0, Address(T0, Isolate::single_step_offset())); 1448 __ lbu(T0, Address(T0, Isolate::single_step_offset()));
1448 __ BranchNotEqual(T0, Immediate(0), &stepping); 1449 __ BranchNotEqual(T0, Immediate(0), &stepping);
1449 __ Bind(&done_stepping); 1450 __ Bind(&done_stepping);
1450 1451
1452 Label not_smi_or_overflow;
1453 if (range_collection_mode == kCollectRanges) {
1454 ASSERT((num_args == 1) || (num_args == 2));
1455 if (num_args == 2) {
1456 __ lw(T0, Address(SP, 1 * kWordSize));
1457 __ UpdateRangeFeedback(T0, 0, S5, T1, &not_smi_or_overflow);
1458 }
1459
1460 __ lw(T0, Address(SP, 0 * kWordSize));
1461 __ UpdateRangeFeedback(T0, num_args - 1, S5, T1, &not_smi_or_overflow);
1462 }
1451 if (kind != Token::kILLEGAL) { 1463 if (kind != Token::kILLEGAL) {
1452 Label not_smi_or_overflow;
1453 EmitFastSmiOp(assembler, kind, num_args, &not_smi_or_overflow); 1464 EmitFastSmiOp(assembler, kind, num_args, &not_smi_or_overflow);
1454 __ Bind(&not_smi_or_overflow);
1455 } 1465 }
1466 __ Bind(&not_smi_or_overflow);
1456 1467
1457 // Load argument descriptor into S4. 1468 // Load argument descriptor into S4.
1458 __ lw(S4, FieldAddress(S5, ICData::arguments_descriptor_offset())); 1469 __ lw(S4, FieldAddress(S5, ICData::arguments_descriptor_offset()));
1459 // Preserve return address, since RA is needed for subroutine call. 1470 // Preserve return address, since RA is needed for subroutine call.
1460 __ mov(T2, RA); 1471 __ mov(T2, RA);
1461 // Loop that checks if there is an IC data match. 1472 // Loop that checks if there is an IC data match.
1462 Label loop, update, test, found; 1473 Label loop, update, test, found;
1463 // S5: IC data object (preserved). 1474 // S5: IC data object (preserved).
1464 __ lw(T0, FieldAddress(S5, ICData::ic_data_offset())); 1475 __ lw(T0, FieldAddress(S5, ICData::ic_data_offset()));
1465 // T0: ic_data_array with check entries: classes and target functions. 1476 // T0: ic_data_array with check entries: classes and target functions.
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
1578 __ LoadImmediate(T4, Smi::RawValue(Smi::kMaxValue)); 1589 __ LoadImmediate(T4, Smi::RawValue(Smi::kMaxValue));
1579 __ movz(T4, T7, CMPRES1); 1590 __ movz(T4, T7, CMPRES1);
1580 __ sw(T4, Address(T0, count_offset)); 1591 __ sw(T4, Address(T0, count_offset));
1581 1592
1582 __ Bind(&call_target_function); 1593 __ Bind(&call_target_function);
1583 // T0 <- T3: Target function. 1594 // T0 <- T3: Target function.
1584 __ mov(T0, T3); 1595 __ mov(T0, T3);
1585 Label is_compiled; 1596 Label is_compiled;
1586 __ lw(T4, FieldAddress(T0, Function::instructions_offset())); 1597 __ lw(T4, FieldAddress(T0, Function::instructions_offset()));
1587 __ AddImmediate(T4, Instructions::HeaderSize() - kHeapObjectTag); 1598 __ AddImmediate(T4, Instructions::HeaderSize() - kHeapObjectTag);
1588 __ jr(T4); 1599 if (range_collection_mode == kCollectRanges) {
1600 const intptr_t frame_size = num_args + 2;
1601 __ lw(T3, Address(SP, 0 * kWordSize));
1602 if (num_args == 2) {
1603 __ lw(T1, Address(SP, 1 * kWordSize));
1604 }
1605 __ EnterStubFrame();
1606 __ addiu(SP, SP, Immediate(- frame_size * kWordSize));
1607 __ sw(RA, Address(SP, (frame_size - 1) * kWordSize)); // Return address.
1608 __ sw(S5, Address(SP, (frame_size - 2) * kWordSize)); // Preserve IC data.
1609 __ sw(T3, Address(SP, 0 * kWordSize));
1610 if (num_args == 2) {
1611 __ sw(T1, Address(SP, 1 * kWordSize));
1612 }
1613 __ jalr(T4);
1614 __ lw(S5, Address(SP, (frame_size - 2) * kWordSize));
1615 __ lw(RA, Address(SP, (frame_size - 1) * kWordSize));
1616 Label done;
1617 __ UpdateRangeFeedback(V0, 2, S5, T1, &done);
1618 __ Bind(&done);
1619 __ addiu(SP, SP, Immediate(frame_size * kWordSize));
1620 __ LeaveStubFrame();
1621 __ Ret();
1622 } else {
1623 __ jr(T4);
1624 }
1589 1625
1590 // Call single step callback in debugger. 1626 // Call single step callback in debugger.
1591 __ Bind(&stepping); 1627 __ Bind(&stepping);
1592 __ EnterStubFrame(); 1628 __ EnterStubFrame();
1593 __ addiu(SP, SP, Immediate(-2 * kWordSize)); 1629 __ addiu(SP, SP, Immediate(-2 * kWordSize));
1594 __ sw(S5, Address(SP, 1 * kWordSize)); // Preserve IC data. 1630 __ sw(S5, Address(SP, 1 * kWordSize)); // Preserve IC data.
1595 __ sw(RA, Address(SP, 0 * kWordSize)); // Return address. 1631 __ sw(RA, Address(SP, 0 * kWordSize)); // Return address.
1596 __ CallRuntime(kSingleStepHandlerRuntimeEntry, 0); 1632 __ CallRuntime(kSingleStepHandlerRuntimeEntry, 0);
1597 __ lw(RA, Address(SP, 0 * kWordSize)); 1633 __ lw(RA, Address(SP, 0 * kWordSize));
1598 __ lw(S5, Address(SP, 1 * kWordSize)); 1634 __ lw(S5, Address(SP, 1 * kWordSize));
1599 __ addiu(SP, SP, Immediate(2 * kWordSize)); 1635 __ addiu(SP, SP, Immediate(2 * kWordSize));
1600 __ LeaveStubFrame(); 1636 __ LeaveStubFrame();
1601 __ b(&done_stepping); 1637 __ b(&done_stepping);
1602 } 1638 }
1603 1639
1604 1640
1605 // Use inline cache data array to invoke the target or continue in inline 1641 // Use inline cache data array to invoke the target or continue in inline
1606 // cache miss handler. Stub for 1-argument check (receiver class). 1642 // cache miss handler. Stub for 1-argument check (receiver class).
1607 // RA: Return address. 1643 // RA: Return address.
1608 // S5: Inline cache data object. 1644 // S5: Inline cache data object.
1609 // Inline cache data object structure: 1645 // Inline cache data object structure:
1610 // 0: function-name 1646 // 0: function-name
1611 // 1: N, number of arguments checked. 1647 // 1: N, number of arguments checked.
1612 // 2 .. (length - 1): group of checks, each check containing: 1648 // 2 .. (length - 1): group of checks, each check containing:
1613 // - N classes. 1649 // - N classes.
1614 // - 1 target function. 1650 // - 1 target function.
1615 void StubCode::GenerateOneArgCheckInlineCacheStub(Assembler* assembler) { 1651 void StubCode::GenerateOneArgCheckInlineCacheStub(Assembler* assembler) {
1616 GenerateUsageCounterIncrement(assembler, T0); 1652 GenerateUsageCounterIncrement(assembler, T0);
1617 GenerateNArgsCheckInlineCacheStub(assembler, 1, 1653 GenerateNArgsCheckInlineCacheStub(assembler, 1,
1618 kInlineCacheMissHandlerOneArgRuntimeEntry, Token::kILLEGAL); 1654 kInlineCacheMissHandlerOneArgRuntimeEntry, Token::kILLEGAL,
1655 kIgnoreRanges);
1619 } 1656 }
1620 1657
1621 1658
1622 void StubCode::GenerateTwoArgsCheckInlineCacheStub(Assembler* assembler) { 1659 void StubCode::GenerateTwoArgsCheckInlineCacheStub(Assembler* assembler) {
1623 GenerateUsageCounterIncrement(assembler, T0); 1660 GenerateUsageCounterIncrement(assembler, T0);
1624 GenerateNArgsCheckInlineCacheStub(assembler, 2, 1661 GenerateNArgsCheckInlineCacheStub(assembler, 2,
1625 kInlineCacheMissHandlerTwoArgsRuntimeEntry, Token::kILLEGAL); 1662 kInlineCacheMissHandlerTwoArgsRuntimeEntry, Token::kILLEGAL,
1663 kIgnoreRanges);
1626 } 1664 }
1627 1665
1628 1666
1629 void StubCode::GenerateThreeArgsCheckInlineCacheStub(Assembler* assembler) { 1667 void StubCode::GenerateThreeArgsCheckInlineCacheStub(Assembler* assembler) {
1630 GenerateUsageCounterIncrement(assembler, T0); 1668 GenerateUsageCounterIncrement(assembler, T0);
1631 GenerateNArgsCheckInlineCacheStub(assembler, 3, 1669 GenerateNArgsCheckInlineCacheStub(assembler, 3,
1632 kInlineCacheMissHandlerThreeArgsRuntimeEntry, Token::kILLEGAL); 1670 kInlineCacheMissHandlerThreeArgsRuntimeEntry, Token::kILLEGAL,
1671 kIgnoreRanges);
1633 } 1672 }
1634 1673
1635 1674
1636 void StubCode::GenerateSmiAddInlineCacheStub(Assembler* assembler) { 1675 void StubCode::GenerateSmiAddInlineCacheStub(Assembler* assembler) {
1637 GenerateUsageCounterIncrement(assembler, T0); 1676 GenerateUsageCounterIncrement(assembler, T0);
1638 GenerateNArgsCheckInlineCacheStub(assembler, 2, 1677 GenerateNArgsCheckInlineCacheStub(assembler, 2,
1639 kInlineCacheMissHandlerTwoArgsRuntimeEntry, Token::kADD); 1678 kInlineCacheMissHandlerTwoArgsRuntimeEntry, Token::kADD,
1679 kCollectRanges);
1640 } 1680 }
1641 1681
1642 1682
1643 void StubCode::GenerateSmiSubInlineCacheStub(Assembler* assembler) { 1683 void StubCode::GenerateSmiSubInlineCacheStub(Assembler* assembler) {
1644 GenerateUsageCounterIncrement(assembler, T0); 1684 GenerateUsageCounterIncrement(assembler, T0);
1645 GenerateNArgsCheckInlineCacheStub(assembler, 2, 1685 GenerateNArgsCheckInlineCacheStub(assembler, 2,
1646 kInlineCacheMissHandlerTwoArgsRuntimeEntry, Token::kSUB); 1686 kInlineCacheMissHandlerTwoArgsRuntimeEntry, Token::kSUB,
1687 kCollectRanges);
1647 } 1688 }
1648 1689
1649 1690
1650 void StubCode::GenerateSmiEqualInlineCacheStub(Assembler* assembler) { 1691 void StubCode::GenerateSmiEqualInlineCacheStub(Assembler* assembler) {
1651 GenerateUsageCounterIncrement(assembler, T0); 1692 GenerateUsageCounterIncrement(assembler, T0);
1652 GenerateNArgsCheckInlineCacheStub(assembler, 2, 1693 GenerateNArgsCheckInlineCacheStub(assembler, 2,
1653 kInlineCacheMissHandlerTwoArgsRuntimeEntry, Token::kEQ); 1694 kInlineCacheMissHandlerTwoArgsRuntimeEntry, Token::kEQ,
1695 kIgnoreRanges);
1654 } 1696 }
1655 1697
1656 1698
1699 void StubCode::GenerateUnaryRangeCollectingInlineCacheStub(
1700 Assembler* assembler) {
1701 GenerateUsageCounterIncrement(assembler, T0);
1702 GenerateNArgsCheckInlineCacheStub(assembler, 1,
1703 kInlineCacheMissHandlerOneArgRuntimeEntry,
1704 Token::kILLEGAL,
1705 kCollectRanges);
1706 }
1707
1708
1709 void StubCode::GenerateBinaryRangeCollectingInlineCacheStub(
1710 Assembler* assembler) {
1711 GenerateUsageCounterIncrement(assembler, T0);
1712 GenerateNArgsCheckInlineCacheStub(assembler, 2,
1713 kInlineCacheMissHandlerTwoArgsRuntimeEntry,
1714 Token::kILLEGAL,
1715 kCollectRanges);
1716 }
1717
1718
1657 void StubCode::GenerateOneArgOptimizedCheckInlineCacheStub( 1719 void StubCode::GenerateOneArgOptimizedCheckInlineCacheStub(
1658 Assembler* assembler) { 1720 Assembler* assembler) {
1659 GenerateOptimizedUsageCounterIncrement(assembler); 1721 GenerateOptimizedUsageCounterIncrement(assembler);
1660 GenerateNArgsCheckInlineCacheStub(assembler, 1, 1722 GenerateNArgsCheckInlineCacheStub(assembler, 1,
1661 kInlineCacheMissHandlerOneArgRuntimeEntry, Token::kILLEGAL); 1723 kInlineCacheMissHandlerOneArgRuntimeEntry, Token::kILLEGAL,
1724 kIgnoreRanges);
1662 } 1725 }
1663 1726
1664 1727
1665 void StubCode::GenerateTwoArgsOptimizedCheckInlineCacheStub( 1728 void StubCode::GenerateTwoArgsOptimizedCheckInlineCacheStub(
1666 Assembler* assembler) { 1729 Assembler* assembler) {
1667 GenerateOptimizedUsageCounterIncrement(assembler); 1730 GenerateOptimizedUsageCounterIncrement(assembler);
1668 GenerateNArgsCheckInlineCacheStub(assembler, 2, 1731 GenerateNArgsCheckInlineCacheStub(assembler, 2,
1669 kInlineCacheMissHandlerTwoArgsRuntimeEntry, Token::kILLEGAL); 1732 kInlineCacheMissHandlerTwoArgsRuntimeEntry, Token::kILLEGAL,
1733 kIgnoreRanges);
1670 } 1734 }
1671 1735
1672 1736
1673 void StubCode::GenerateThreeArgsOptimizedCheckInlineCacheStub( 1737 void StubCode::GenerateThreeArgsOptimizedCheckInlineCacheStub(
1674 Assembler* assembler) { 1738 Assembler* assembler) {
1675 GenerateOptimizedUsageCounterIncrement(assembler); 1739 GenerateOptimizedUsageCounterIncrement(assembler);
1676 GenerateNArgsCheckInlineCacheStub(assembler, 3, 1740 GenerateNArgsCheckInlineCacheStub(assembler, 3,
1677 kInlineCacheMissHandlerThreeArgsRuntimeEntry, Token::kILLEGAL); 1741 kInlineCacheMissHandlerThreeArgsRuntimeEntry, Token::kILLEGAL,
1742 kIgnoreRanges);
1678 } 1743 }
1679 1744
1680 1745
1681 // Intermediary stub between a static call and its target. ICData contains 1746 // Intermediary stub between a static call and its target. ICData contains
1682 // the target function and the call count. 1747 // the target function and the call count.
1683 // S5: ICData 1748 // S5: ICData
1684 void StubCode::GenerateZeroArgsUnoptimizedStaticCallStub(Assembler* assembler) { 1749 void StubCode::GenerateZeroArgsUnoptimizedStaticCallStub(Assembler* assembler) {
1685 GenerateUsageCounterIncrement(assembler, T0); 1750 GenerateUsageCounterIncrement(assembler, T0);
1686 __ TraceSimMsg("UnoptimizedStaticCallStub"); 1751 __ TraceSimMsg("UnoptimizedStaticCallStub");
1687 #if defined(DEBUG) 1752 #if defined(DEBUG)
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
1742 __ lw(S5, Address(SP, 1 * kWordSize)); 1807 __ lw(S5, Address(SP, 1 * kWordSize));
1743 __ addiu(SP, SP, Immediate(2 * kWordSize)); 1808 __ addiu(SP, SP, Immediate(2 * kWordSize));
1744 __ LeaveStubFrame(); 1809 __ LeaveStubFrame();
1745 __ b(&done_stepping); 1810 __ b(&done_stepping);
1746 } 1811 }
1747 1812
1748 1813
1749 void StubCode::GenerateOneArgUnoptimizedStaticCallStub(Assembler* assembler) { 1814 void StubCode::GenerateOneArgUnoptimizedStaticCallStub(Assembler* assembler) {
1750 GenerateUsageCounterIncrement(assembler, T0); 1815 GenerateUsageCounterIncrement(assembler, T0);
1751 GenerateNArgsCheckInlineCacheStub( 1816 GenerateNArgsCheckInlineCacheStub(
1752 assembler, 1, kStaticCallMissHandlerOneArgRuntimeEntry, Token::kILLEGAL); 1817 assembler, 1, kStaticCallMissHandlerOneArgRuntimeEntry, Token::kILLEGAL,
1818 kIgnoreRanges);
1753 } 1819 }
1754 1820
1755 1821
1756 void StubCode::GenerateTwoArgsUnoptimizedStaticCallStub(Assembler* assembler) { 1822 void StubCode::GenerateTwoArgsUnoptimizedStaticCallStub(Assembler* assembler) {
1757 GenerateUsageCounterIncrement(assembler, T0); 1823 GenerateUsageCounterIncrement(assembler, T0);
1758 GenerateNArgsCheckInlineCacheStub(assembler, 2, 1824 GenerateNArgsCheckInlineCacheStub(assembler, 2,
1759 kStaticCallMissHandlerTwoArgsRuntimeEntry, Token::kILLEGAL); 1825 kStaticCallMissHandlerTwoArgsRuntimeEntry, Token::kILLEGAL,
1826 kIgnoreRanges);
1760 } 1827 }
1761 1828
1762 1829
1763 // Stub for compiling a function and jumping to the compiled code. 1830 // Stub for compiling a function and jumping to the compiled code.
1764 // S5: IC-Data (for methods). 1831 // S5: IC-Data (for methods).
1765 // S4: Arguments descriptor. 1832 // S4: Arguments descriptor.
1766 // T0: Function. 1833 // T0: Function.
1767 void StubCode::GenerateLazyCompileStub(Assembler* assembler) { 1834 void StubCode::GenerateLazyCompileStub(Assembler* assembler) {
1768 __ EnterStubFrame(); 1835 __ EnterStubFrame();
1769 __ addiu(SP, SP, Immediate(-3 * kWordSize)); 1836 __ addiu(SP, SP, Immediate(-3 * kWordSize));
(...skipping 404 matching lines...) Expand 10 before | Expand all | Expand 10 after
2174 const Register right = T0; 2241 const Register right = T0;
2175 __ lw(left, Address(SP, 1 * kWordSize)); 2242 __ lw(left, Address(SP, 1 * kWordSize));
2176 __ lw(right, Address(SP, 0 * kWordSize)); 2243 __ lw(right, Address(SP, 0 * kWordSize));
2177 GenerateIdenticalWithNumberCheckStub(assembler, left, right, temp1, temp2); 2244 GenerateIdenticalWithNumberCheckStub(assembler, left, right, temp1, temp2);
2178 __ Ret(); 2245 __ Ret();
2179 } 2246 }
2180 2247
2181 } // namespace dart 2248 } // namespace dart
2182 2249
2183 #endif // defined TARGET_ARCH_MIPS 2250 #endif // defined TARGET_ARCH_MIPS
OLDNEW
« no previous file with comments | « runtime/vm/stub_code_ia32.cc ('k') | runtime/vm/stub_code_x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698