1679 Label profile_continue; |
1679 Label profile_continue; |
1680 |
1680 |
1681 // If no method data exists, go to profile_continue. |
1681 // If no method data exists, go to profile_continue. |
1682 test_method_data_pointer(profile_continue); |
1682 test_method_data_pointer(profile_continue); |
1683 |
1683 |
1684 // We are making a call. Increment the count. |
|
1685 increment_mdp_data_at(in_bytes(CounterData::count_offset()), scratch); |
|
1686 |
|
1687 // Record the receiver type. |
1684 // Record the receiver type. |
1688 record_klass_in_profile(receiver, scratch); |
1685 record_klass_in_profile(receiver, scratch, true); |
1689 |
1686 |
1690 // The method data pointer needs to be updated to reflect the new target. |
1687 // The method data pointer needs to be updated to reflect the new target. |
1691 update_mdp_by_constant(in_bytes(VirtualCallData::virtual_call_data_size())); |
1688 update_mdp_by_constant(in_bytes(VirtualCallData::virtual_call_data_size())); |
1692 bind (profile_continue); |
1689 bind (profile_continue); |
1693 } |
1690 } |
1694 } |
1691 } |
1695 |
1692 |
1696 void InterpreterMacroAssembler::record_klass_in_profile_helper( |
1693 void InterpreterMacroAssembler::record_klass_in_profile_helper( |
1697 Register receiver, Register scratch, |
1694 Register receiver, Register scratch, |
1698 int start_row, Label& done) { |
1695 int start_row, Label& done, bool is_virtual_call) { |
1699 if (TypeProfileWidth == 0) |
1696 if (TypeProfileWidth == 0) { |
|
1697 if (is_virtual_call) { |
|
1698 increment_mdp_data_at(in_bytes(CounterData::count_offset()), scratch); |
|
1699 } |
1700 return; |
1700 return; |
|
1701 } |
1701 |
1702 |
1702 int last_row = VirtualCallData::row_limit() - 1; |
1703 int last_row = VirtualCallData::row_limit() - 1; |
1703 assert(start_row <= last_row, "must be work left to do"); |
1704 assert(start_row <= last_row, "must be work left to do"); |
1704 // Test this row for both the receiver and for null. |
1705 // Test this row for both the receiver and for null. |
1705 // Take any of three different outcomes: |
1706 // Take any of three different outcomes: |
1712 bool test_for_null_also = (row == start_row); |
1713 bool test_for_null_also = (row == start_row); |
1713 |
1714 |
1714 // See if the receiver is receiver[n]. |
1715 // See if the receiver is receiver[n]. |
1715 int recvr_offset = in_bytes(VirtualCallData::receiver_offset(row)); |
1716 int recvr_offset = in_bytes(VirtualCallData::receiver_offset(row)); |
1716 test_mdp_data_at(recvr_offset, receiver, next_test, scratch); |
1717 test_mdp_data_at(recvr_offset, receiver, next_test, scratch); |
|
1718 // delayed()->tst(scratch); |
1717 |
1719 |
1718 // The receiver is receiver[n]. Increment count[n]. |
1720 // The receiver is receiver[n]. Increment count[n]. |
1719 int count_offset = in_bytes(VirtualCallData::receiver_count_offset(row)); |
1721 int count_offset = in_bytes(VirtualCallData::receiver_count_offset(row)); |
1720 increment_mdp_data_at(count_offset, scratch); |
1722 increment_mdp_data_at(count_offset, scratch); |
1721 ba(false, done); |
1723 ba(false, done); |
1722 delayed()->nop(); |
1724 delayed()->nop(); |
1723 bind(next_test); |
1725 bind(next_test); |
1724 |
1726 |
1725 if (test_for_null_also) { |
1727 if (test_for_null_also) { |
|
1728 Label found_null; |
1726 // Failed the equality check on receiver[n]... Test for null. |
1729 // Failed the equality check on receiver[n]... Test for null. |
1727 if (start_row == last_row) { |
1730 if (start_row == last_row) { |
1728 // The only thing left to do is handle the null case. |
1731 // The only thing left to do is handle the null case. |
1729 brx(Assembler::notZero, false, Assembler::pt, done); |
1732 if (is_virtual_call) { |
1730 delayed()->nop(); |
1733 brx(Assembler::zero, false, Assembler::pn, found_null); |
|
1734 delayed()->nop(); |
|
1735 // Receiver did not match any saved receiver and there is no empty row for it. |
|
1736 // Increment total counter to indicate polimorphic case. |
|
1737 increment_mdp_data_at(in_bytes(CounterData::count_offset()), scratch); |
|
1738 ba(false, done); |
|
1739 delayed()->nop(); |
|
1740 bind(found_null); |
|
1741 } else { |
|
1742 brx(Assembler::notZero, false, Assembler::pt, done); |
|
1743 delayed()->nop(); |
|
1744 } |
1731 break; |
1745 break; |
1732 } |
1746 } |
1733 // Since null is rare, make it be the branch-taken case. |
1747 // Since null is rare, make it be the branch-taken case. |
1734 Label found_null; |
|
1735 brx(Assembler::zero, false, Assembler::pn, found_null); |
1748 brx(Assembler::zero, false, Assembler::pn, found_null); |
1736 delayed()->nop(); |
1749 delayed()->nop(); |
1737 |
1750 |
1738 // Put all the "Case 3" tests here. |
1751 // Put all the "Case 3" tests here. |
1739 record_klass_in_profile_helper(receiver, scratch, start_row + 1, done); |
1752 record_klass_in_profile_helper(receiver, scratch, start_row + 1, done, is_virtual_call); |
1740 |
1753 |
1741 // Found a null. Keep searching for a matching receiver, |
1754 // Found a null. Keep searching for a matching receiver, |
1742 // but remember that this is an empty (unused) slot. |
1755 // but remember that this is an empty (unused) slot. |
1743 bind(found_null); |
1756 bind(found_null); |
1744 } |
1757 } |
1751 int recvr_offset = in_bytes(VirtualCallData::receiver_offset(start_row)); |
1764 int recvr_offset = in_bytes(VirtualCallData::receiver_offset(start_row)); |
1752 set_mdp_data_at(recvr_offset, receiver); |
1765 set_mdp_data_at(recvr_offset, receiver); |
1753 int count_offset = in_bytes(VirtualCallData::receiver_count_offset(start_row)); |
1766 int count_offset = in_bytes(VirtualCallData::receiver_count_offset(start_row)); |
1754 mov(DataLayout::counter_increment, scratch); |
1767 mov(DataLayout::counter_increment, scratch); |
1755 set_mdp_data_at(count_offset, scratch); |
1768 set_mdp_data_at(count_offset, scratch); |
1756 ba(false, done); |
1769 if (start_row > 0) { |
1757 delayed()->nop(); |
1770 ba(false, done); |
|
1771 delayed()->nop(); |
|
1772 } |
1758 } |
1773 } |
1759 |
1774 |
1760 void InterpreterMacroAssembler::record_klass_in_profile(Register receiver, |
1775 void InterpreterMacroAssembler::record_klass_in_profile(Register receiver, |
1761 Register scratch) { |
1776 Register scratch, bool is_virtual_call) { |
1762 assert(ProfileInterpreter, "must be profiling"); |
1777 assert(ProfileInterpreter, "must be profiling"); |
1763 Label done; |
1778 Label done; |
1764 |
1779 |
1765 record_klass_in_profile_helper(receiver, scratch, 0, done); |
1780 record_klass_in_profile_helper(receiver, scratch, 0, done, is_virtual_call); |
1766 |
1781 |
1767 bind (done); |
1782 bind (done); |
1768 } |
1783 } |
1769 |
1784 |
1770 |
1785 |
1838 int mdp_delta = in_bytes(BitData::bit_data_size()); |
1853 int mdp_delta = in_bytes(BitData::bit_data_size()); |
1839 if (TypeProfileCasts) { |
1854 if (TypeProfileCasts) { |
1840 mdp_delta = in_bytes(VirtualCallData::virtual_call_data_size()); |
1855 mdp_delta = in_bytes(VirtualCallData::virtual_call_data_size()); |
1841 |
1856 |
1842 // Record the object type. |
1857 // Record the object type. |
1843 record_klass_in_profile(klass, scratch); |
1858 record_klass_in_profile(klass, scratch, false); |
1844 } |
1859 } |
1845 |
1860 |
1846 // The method data pointer needs to be updated. |
1861 // The method data pointer needs to be updated. |
1847 update_mdp_by_constant(mdp_delta); |
1862 update_mdp_by_constant(mdp_delta); |
1848 |
1863 |