comparison src/cpu/ppc/vm/interp_masm_ppc_64.cpp @ 20710:c5e86c5cd22e

8066964: ppc64: argument and return type profiling, fix problem with popframe Reviewed-by: roland, kvn
author goetz
date Fri, 12 Dec 2014 08:48:56 +0100
parents f6bde7889409
children
comparison
equal deleted inserted replaced
20709:28f116adb50c 20710:c5e86c5cd22e
543 // Index check 543 // Index check
544 lwz(Rlength, arrayOopDesc::length_offset_in_bytes(), Rarray); 544 lwz(Rlength, arrayOopDesc::length_offset_in_bytes(), Rarray);
545 cmplw(CCR0, Rindex, Rlength); 545 cmplw(CCR0, Rindex, Rlength);
546 sldi(RsxtIndex, RsxtIndex, index_shift); 546 sldi(RsxtIndex, RsxtIndex, index_shift);
547 blt(CCR0, LnotOOR); 547 blt(CCR0, LnotOOR);
548 // Index should be in R17_tos, array should be in R4_ARG2.
549 mr(R17_tos, Rindex);
550 mr(R4_ARG2, Rarray);
548 load_dispatch_table(Rtmp, (address*)Interpreter::_throw_ArrayIndexOutOfBoundsException_entry); 551 load_dispatch_table(Rtmp, (address*)Interpreter::_throw_ArrayIndexOutOfBoundsException_entry);
549 mtctr(Rtmp); 552 mtctr(Rtmp);
550 bctr(); 553 bctr();
551 554
552 if (!ImplicitNullChecks) { 555 if (!ImplicitNullChecks) {
1677 if (start_row > 0) { 1680 if (start_row > 0) {
1678 b(done); 1681 b(done);
1679 } 1682 }
1680 } 1683 }
1681 1684
1685 // Argument and return type profilig.
1686 // kills: tmp, tmp2, R0, CR0, CR1
1687 void InterpreterMacroAssembler::profile_obj_type(Register obj, Register mdo_addr_base,
1688 RegisterOrConstant mdo_addr_offs, Register tmp, Register tmp2) {
1689 Label do_nothing, do_update;
1690
1691 // tmp2 = obj is allowed
1692 assert_different_registers(obj, mdo_addr_base, tmp, R0);
1693 assert_different_registers(tmp2, mdo_addr_base, tmp, R0);
1694 const Register klass = tmp2;
1695
1696 verify_oop(obj);
1697
1698 ld(tmp, mdo_addr_offs, mdo_addr_base);
1699
1700 // Set null_seen if obj is 0.
1701 cmpdi(CCR0, obj, 0);
1702 ori(R0, tmp, TypeEntries::null_seen);
1703 beq(CCR0, do_update);
1704
1705 load_klass(klass, obj);
1706
1707 clrrdi(R0, tmp, exact_log2(-TypeEntries::type_klass_mask));
1708 // Basically same as andi(R0, tmp, TypeEntries::type_klass_mask);
1709 cmpd(CCR1, R0, klass);
1710 // Klass seen before, nothing to do (regardless of unknown bit).
1711 //beq(CCR1, do_nothing);
1712
1713 andi_(R0, klass, TypeEntries::type_unknown);
1714 // Already unknown. Nothing to do anymore.
1715 //bne(CCR0, do_nothing);
1716 crorc(/*CCR0 eq*/2, /*CCR1 eq*/4+2, /*CCR0 eq*/2); // cr0 eq = cr1 eq or cr0 ne
1717 beq(CCR0, do_nothing);
1718
1719 clrrdi_(R0, tmp, exact_log2(-TypeEntries::type_mask));
1720 orr(R0, klass, tmp); // Combine klass and null_seen bit (only used if (tmp & type_mask)==0).
1721 beq(CCR0, do_update); // First time here. Set profile type.
1722
1723 // Different than before. Cannot keep accurate profile.
1724 ori(R0, tmp, TypeEntries::type_unknown);
1725
1726 bind(do_update);
1727 // update profile
1728 std(R0, mdo_addr_offs, mdo_addr_base);
1729
1730 align(32, 12);
1731 bind(do_nothing);
1732 }
1733
1734 void InterpreterMacroAssembler::profile_arguments_type(Register callee, Register tmp1, Register tmp2, bool is_virtual) {
1735 if (!ProfileInterpreter) {
1736 return;
1737 }
1738
1739 assert_different_registers(callee, tmp1, tmp2, R28_mdx);
1740
1741 if (MethodData::profile_arguments() || MethodData::profile_return()) {
1742 Label profile_continue;
1743
1744 test_method_data_pointer(profile_continue);
1745
1746 int off_to_start = is_virtual ? in_bytes(VirtualCallData::virtual_call_data_size()) : in_bytes(CounterData::counter_data_size());
1747
1748 lbz(tmp1, in_bytes(DataLayout::tag_offset()) - off_to_start, R28_mdx);
1749 cmpwi(CCR0, tmp1, is_virtual ? DataLayout::virtual_call_type_data_tag : DataLayout::call_type_data_tag);
1750 bne(CCR0, profile_continue);
1751
1752 if (MethodData::profile_arguments()) {
1753 Label done;
1754 int off_to_args = in_bytes(TypeEntriesAtCall::args_data_offset());
1755 add(R28_mdx, off_to_args, R28_mdx);
1756
1757 for (int i = 0; i < TypeProfileArgsLimit; i++) {
1758 if (i > 0 || MethodData::profile_return()) {
1759 // If return value type is profiled we may have no argument to profile.
1760 ld(tmp1, in_bytes(TypeEntriesAtCall::cell_count_offset())-off_to_args, R28_mdx);
1761 cmpdi(CCR0, tmp1, (i+1)*TypeStackSlotEntries::per_arg_count());
1762 addi(tmp1, tmp1, -i*TypeStackSlotEntries::per_arg_count());
1763 blt(CCR0, done);
1764 }
1765 ld(tmp1, in_bytes(Method::const_offset()), callee);
1766 lhz(tmp1, in_bytes(ConstMethod::size_of_parameters_offset()), tmp1);
1767 // Stack offset o (zero based) from the start of the argument
1768 // list, for n arguments translates into offset n - o - 1 from
1769 // the end of the argument list. But there's an extra slot at
1770 // the top of the stack. So the offset is n - o from Lesp.
1771 ld(tmp2, in_bytes(TypeEntriesAtCall::stack_slot_offset(i))-off_to_args, R28_mdx);
1772 subf(tmp1, tmp2, tmp1);
1773
1774 sldi(tmp1, tmp1, Interpreter::logStackElementSize);
1775 ldx(tmp1, tmp1, R15_esp);
1776
1777 profile_obj_type(tmp1, R28_mdx, in_bytes(TypeEntriesAtCall::argument_type_offset(i))-off_to_args, tmp2, tmp1);
1778
1779 int to_add = in_bytes(TypeStackSlotEntries::per_arg_size());
1780 addi(R28_mdx, R28_mdx, to_add);
1781 off_to_args += to_add;
1782 }
1783
1784 if (MethodData::profile_return()) {
1785 ld(tmp1, in_bytes(TypeEntriesAtCall::cell_count_offset())-off_to_args, R28_mdx);
1786 addi(tmp1, tmp1, -TypeProfileArgsLimit*TypeStackSlotEntries::per_arg_count());
1787 }
1788
1789 bind(done);
1790
1791 if (MethodData::profile_return()) {
1792 // We're right after the type profile for the last
1793 // argument. tmp1 is the number of cells left in the
1794 // CallTypeData/VirtualCallTypeData to reach its end. Non null
1795 // if there's a return to profile.
1796 assert(ReturnTypeEntry::static_cell_count() < TypeStackSlotEntries::per_arg_count(), "can't move past ret type");
1797 sldi(tmp1, tmp1, exact_log2(DataLayout::cell_size));
1798 add(R28_mdx, tmp1, R28_mdx);
1799 }
1800 } else {
1801 assert(MethodData::profile_return(), "either profile call args or call ret");
1802 update_mdp_by_constant(in_bytes(TypeEntriesAtCall::return_only_size()));
1803 }
1804
1805 // Mdp points right after the end of the
1806 // CallTypeData/VirtualCallTypeData, right after the cells for the
1807 // return value type if there's one.
1808 align(32, 12);
1809 bind(profile_continue);
1810 }
1811 }
1812
1813 void InterpreterMacroAssembler::profile_return_type(Register ret, Register tmp1, Register tmp2) {
1814 assert_different_registers(ret, tmp1, tmp2);
1815 if (ProfileInterpreter && MethodData::profile_return()) {
1816 Label profile_continue;
1817
1818 test_method_data_pointer(profile_continue);
1819
1820 if (MethodData::profile_return_jsr292_only()) {
1821 // If we don't profile all invoke bytecodes we must make sure
1822 // it's a bytecode we indeed profile. We can't go back to the
1823 // begining of the ProfileData we intend to update to check its
1824 // type because we're right after it and we don't known its
1825 // length.
1826 lbz(tmp1, 0, R14_bcp);
1827 lbz(tmp2, Method::intrinsic_id_offset_in_bytes(), R19_method);
1828 cmpwi(CCR0, tmp1, Bytecodes::_invokedynamic);
1829 cmpwi(CCR1, tmp1, Bytecodes::_invokehandle);
1830 cror(/*CR0 eq*/2, /*CR1 eq*/4+2, /*CR0 eq*/2);
1831 cmpwi(CCR1, tmp2, vmIntrinsics::_compiledLambdaForm);
1832 cror(/*CR0 eq*/2, /*CR1 eq*/4+2, /*CR0 eq*/2);
1833 bne(CCR0, profile_continue);
1834 }
1835
1836 profile_obj_type(ret, R28_mdx, -in_bytes(ReturnTypeEntry::size()), tmp1, tmp2);
1837
1838 align(32, 12);
1839 bind(profile_continue);
1840 }
1841 }
1842
1843 void InterpreterMacroAssembler::profile_parameters_type(Register tmp1, Register tmp2, Register tmp3, Register tmp4) {
1844 if (ProfileInterpreter && MethodData::profile_parameters()) {
1845 Label profile_continue, done;
1846
1847 test_method_data_pointer(profile_continue);
1848
1849 // Load the offset of the area within the MDO used for
1850 // parameters. If it's negative we're not profiling any parameters.
1851 lwz(tmp1, in_bytes(MethodData::parameters_type_data_di_offset()) - in_bytes(MethodData::data_offset()), R28_mdx);
1852 cmpwi(CCR0, tmp1, 0);
1853 blt(CCR0, profile_continue);
1854
1855 // Compute a pointer to the area for parameters from the offset
1856 // and move the pointer to the slot for the last
1857 // parameters. Collect profiling from last parameter down.
1858 // mdo start + parameters offset + array length - 1
1859
1860 // Pointer to the parameter area in the MDO.
1861 const Register mdp = tmp1;
1862 add(mdp, tmp1, R28_mdx);
1863
1864 // Pffset of the current profile entry to update.
1865 const Register entry_offset = tmp2;
1866 // entry_offset = array len in number of cells
1867 ld(entry_offset, in_bytes(ArrayData::array_len_offset()), mdp);
1868
1869 int off_base = in_bytes(ParametersTypeData::stack_slot_offset(0));
1870 assert(off_base % DataLayout::cell_size == 0, "should be a number of cells");
1871
1872 // entry_offset (number of cells) = array len - size of 1 entry + offset of the stack slot field
1873 addi(entry_offset, entry_offset, -TypeStackSlotEntries::per_arg_count() + (off_base / DataLayout::cell_size));
1874 // entry_offset in bytes
1875 sldi(entry_offset, entry_offset, exact_log2(DataLayout::cell_size));
1876
1877 Label loop;
1878 align(32, 12);
1879 bind(loop);
1880
1881 // Load offset on the stack from the slot for this parameter.
1882 ld(tmp3, entry_offset, mdp);
1883 sldi(tmp3, tmp3, Interpreter::logStackElementSize);
1884 neg(tmp3, tmp3);
1885 // Read the parameter from the local area.
1886 ldx(tmp3, tmp3, R18_locals);
1887
1888 // Make entry_offset now point to the type field for this parameter.
1889 int type_base = in_bytes(ParametersTypeData::type_offset(0));
1890 assert(type_base > off_base, "unexpected");
1891 addi(entry_offset, entry_offset, type_base - off_base);
1892
1893 // Profile the parameter.
1894 profile_obj_type(tmp3, mdp, entry_offset, tmp4, tmp3);
1895
1896 // Go to next parameter.
1897 int delta = TypeStackSlotEntries::per_arg_count() * DataLayout::cell_size + (type_base - off_base);
1898 cmpdi(CCR0, entry_offset, off_base + delta);
1899 addi(entry_offset, entry_offset, -delta);
1900 bge(CCR0, loop);
1901
1902 align(32, 12);
1903 bind(profile_continue);
1904 }
1905 }
1906
1682 // Add a InterpMonitorElem to stack (see frame_sparc.hpp). 1907 // Add a InterpMonitorElem to stack (see frame_sparc.hpp).
1683 void InterpreterMacroAssembler::add_monitor_to_stack(bool stack_is_empty, Register Rtemp1, Register Rtemp2) { 1908 void InterpreterMacroAssembler::add_monitor_to_stack(bool stack_is_empty, Register Rtemp1, Register Rtemp2) {
1684 1909
1685 // Very-local scratch registers. 1910 // Very-local scratch registers.
1686 const Register esp = Rtemp1; 1911 const Register esp = Rtemp1;
2038 const int log2_bytecode_size_limit = 16; 2263 const int log2_bytecode_size_limit = 16;
2039 srdi_(Rtmp, reg, log2_bytecode_size_limit); 2264 srdi_(Rtmp, reg, log2_bytecode_size_limit);
2040 bne(CCR0, test); 2265 bne(CCR0, test);
2041 2266
2042 address fd = CAST_FROM_FN_PTR(address, verify_return_address); 2267 address fd = CAST_FROM_FN_PTR(address, verify_return_address);
2043 unsigned int nbytes_save = 10*8; // 10 volatile gprs 2268 const int nbytes_save = 11*8; // volatile gprs except R0
2044 2269 save_volatile_gprs(R1_SP, -nbytes_save); // except R0
2045 save_LR_CR(Rtmp); 2270 save_LR_CR(Rtmp); // Save in old frame.
2046 push_frame_reg_args(nbytes_save, Rtmp); 2271 push_frame_reg_args(nbytes_save, Rtmp);
2047 save_volatile_gprs(R1_SP, 112); // except R0
2048 2272
2049 load_const_optimized(Rtmp, fd, R0); 2273 load_const_optimized(Rtmp, fd, R0);
2050 mr_if_needed(R4_ARG2, reg); 2274 mr_if_needed(R4_ARG2, reg);
2051 mr(R3_ARG1, R19_method); 2275 mr(R3_ARG1, R19_method);
2052 call_c(Rtmp); // call C 2276 call_c(Rtmp); // call C
2053 2277
2054 restore_volatile_gprs(R1_SP, 112); // except R0
2055 pop_frame(); 2278 pop_frame();
2056 restore_LR_CR(Rtmp); 2279 restore_LR_CR(Rtmp);
2280 restore_volatile_gprs(R1_SP, -nbytes_save); // except R0
2057 b(skip); 2281 b(skip);
2058 2282
2059 // Perform a more elaborate out-of-line call. 2283 // Perform a more elaborate out-of-line call.
2060 // Not an address; verify it: 2284 // Not an address; verify it:
2061 bind(test); 2285 bind(test);