1694 // something that's actually doing something.
1695 static void fake_arraycopy_stub(address src, address dst, int count) {
1696 assert(count == 0, "huh?");
1697 }
1698
1699
1700 //
1701 // Generate 'unsafe' array copy stub
1702 // Though just as safe as the other stubs, it takes an unscaled
1703 // size_t argument instead of an element count.
1704 //
1705 // Input:
1706 // c_rarg0 - source array address
1707 // c_rarg1 - destination array address
1708 // c_rarg2 - byte count, treated as ssize_t, can be zero
1709 //
1710 // Examines the alignment of the operands and dispatches
1711 // to a long, int, short, or byte copy loop.
1712 //
1713 address generate_unsafe_copy(const char *name,
1714 address byte_copy_entry) {
1715 #ifdef PRODUCT
1716 return StubRoutines::_jbyte_arraycopy;
1717 #else
1718 __ align(CodeEntryAlignment);
1719 StubCodeMark mark(this, "StubRoutines", name);
1720 address start = __ pc();
1721 __ enter(); // required for proper stackwalking of RuntimeStub frame
1722 // bump this on entry, not on exit:
1723 __ lea(rscratch2, ExternalAddress((address)&SharedRuntime::_unsafe_array_copy_ctr));
1724 __ incrementw(Address(rscratch2));
1725 __ b(RuntimeAddress(byte_copy_entry));
1726 return start;
1727 #endif
1728 }
1729
1730 //
1731 // Generate generic array copy stubs
1732 //
1733 // Input:
1734 // c_rarg0 - src oop
1735 // c_rarg1 - src_pos (32-bits)
1736 // c_rarg2 - dst oop
1737 // c_rarg3 - dst_pos (32-bits)
1738 // c_rarg4 - element count (32-bits)
1739 //
1740 // Output:
1741 // r0 == 0 - success
1742 // r0 == -1^K - failure, where K is partial transfer count
1743 //
1744 address generate_generic_copy(const char *name,
1745 address byte_copy_entry, address short_copy_entry,
1746 address int_copy_entry, address oop_copy_entry,
1747 address long_copy_entry, address checkcast_copy_entry) {
2073 /*dest_uninitialized*/false);
2074 // Aligned versions without pre-barriers
2075 StubRoutines::_arrayof_oop_disjoint_arraycopy_uninit
2076 = generate_disjoint_oop_copy(aligned, &entry, "arrayof_oop_disjoint_arraycopy_uninit",
2077 /*dest_uninitialized*/true);
2078 StubRoutines::_arrayof_oop_arraycopy_uninit
2079 = generate_conjoint_oop_copy(aligned, entry, NULL, "arrayof_oop_arraycopy_uninit",
2080 /*dest_uninitialized*/true);
2081 }
2082
2083 StubRoutines::_oop_disjoint_arraycopy = StubRoutines::_arrayof_oop_disjoint_arraycopy;
2084 StubRoutines::_oop_arraycopy = StubRoutines::_arrayof_oop_arraycopy;
2085 StubRoutines::_oop_disjoint_arraycopy_uninit = StubRoutines::_arrayof_oop_disjoint_arraycopy_uninit;
2086 StubRoutines::_oop_arraycopy_uninit = StubRoutines::_arrayof_oop_arraycopy_uninit;
2087
2088 StubRoutines::_checkcast_arraycopy = generate_checkcast_copy("checkcast_arraycopy", &entry_checkcast_arraycopy);
2089 StubRoutines::_checkcast_arraycopy_uninit = generate_checkcast_copy("checkcast_arraycopy_uninit", NULL,
2090 /*dest_uninitialized*/true);
2091
2092 StubRoutines::_unsafe_arraycopy = generate_unsafe_copy("unsafe_arraycopy",
2093 entry_jbyte_arraycopy);
2094
2095 StubRoutines::_generic_arraycopy = generate_generic_copy("generic_arraycopy",
2096 entry_jbyte_arraycopy,
2097 entry_jshort_arraycopy,
2098 entry_jint_arraycopy,
2099 entry_oop_arraycopy,
2100 entry_jlong_arraycopy,
2101 entry_checkcast_arraycopy);
2102
2103 }
2104
2105 void generate_math_stubs() { Unimplemented(); }
2106
2107 // Arguments:
2108 //
2109 // Inputs:
2110 // c_rarg0 - source byte array address
2111 // c_rarg1 - destination byte array address
2112 // c_rarg2 - K (key) in little endian int array
2113 //
|
1694 // something that's actually doing something.
1695 static void fake_arraycopy_stub(address src, address dst, int count) {
1696 assert(count == 0, "huh?");
1697 }
1698
1699
1700 //
1701 // Generate 'unsafe' array copy stub
1702 // Though just as safe as the other stubs, it takes an unscaled
1703 // size_t argument instead of an element count.
1704 //
1705 // Input:
1706 // c_rarg0 - source array address
1707 // c_rarg1 - destination array address
1708 // c_rarg2 - byte count, treated as ssize_t, can be zero
1709 //
1710 // Examines the alignment of the operands and dispatches
1711 // to a long, int, short, or byte copy loop.
1712 //
1713 address generate_unsafe_copy(const char *name,
1714 address byte_copy_entry,
1715 address short_copy_entry,
1716 address int_copy_entry,
1717 address long_copy_entry) {
1718 Label L_long_aligned, L_int_aligned, L_short_aligned;
1719 Register s = c_rarg0, d = c_rarg1, count = c_rarg2;
1720
1721 __ align(CodeEntryAlignment);
1722 StubCodeMark mark(this, "StubRoutines", name);
1723 address start = __ pc();
1724 __ enter(); // required for proper stackwalking of RuntimeStub frame
1725
1726 // bump this on entry, not on exit:
1727 inc_counter_np(SharedRuntime::_unsafe_array_copy_ctr);
1728
1729 __ orr(rscratch1, s, d);
1730 __ orr(rscratch1, rscratch1, count);
1731
1732 __ andr(rscratch1, rscratch1, BytesPerLong-1);
1733 __ cbz(rscratch1, L_long_aligned);
1734 __ andr(rscratch1, rscratch1, BytesPerInt-1);
1735 __ cbz(rscratch1, L_int_aligned);
1736 __ tbz(rscratch1, 0, L_short_aligned);
1737 __ b(RuntimeAddress(byte_copy_entry));
1738
1739 __ BIND(L_short_aligned);
1740 __ lsr(count, count, LogBytesPerShort); // size => short_count
1741 __ b(RuntimeAddress(short_copy_entry));
1742 __ BIND(L_int_aligned);
1743 __ lsr(count, count, LogBytesPerInt); // size => int_count
1744 __ b(RuntimeAddress(int_copy_entry));
1745 __ BIND(L_long_aligned);
1746 __ lsr(count, count, LogBytesPerLong); // size => long_count
1747 __ b(RuntimeAddress(long_copy_entry));
1748
1749 return start;
1750 }
1751
1752 //
1753 // Generate generic array copy stubs
1754 //
1755 // Input:
1756 // c_rarg0 - src oop
1757 // c_rarg1 - src_pos (32-bits)
1758 // c_rarg2 - dst oop
1759 // c_rarg3 - dst_pos (32-bits)
1760 // c_rarg4 - element count (32-bits)
1761 //
1762 // Output:
1763 // r0 == 0 - success
1764 // r0 == -1^K - failure, where K is partial transfer count
1765 //
1766 address generate_generic_copy(const char *name,
1767 address byte_copy_entry, address short_copy_entry,
1768 address int_copy_entry, address oop_copy_entry,
1769 address long_copy_entry, address checkcast_copy_entry) {
2095 /*dest_uninitialized*/false);
2096 // Aligned versions without pre-barriers
2097 StubRoutines::_arrayof_oop_disjoint_arraycopy_uninit
2098 = generate_disjoint_oop_copy(aligned, &entry, "arrayof_oop_disjoint_arraycopy_uninit",
2099 /*dest_uninitialized*/true);
2100 StubRoutines::_arrayof_oop_arraycopy_uninit
2101 = generate_conjoint_oop_copy(aligned, entry, NULL, "arrayof_oop_arraycopy_uninit",
2102 /*dest_uninitialized*/true);
2103 }
2104
2105 StubRoutines::_oop_disjoint_arraycopy = StubRoutines::_arrayof_oop_disjoint_arraycopy;
2106 StubRoutines::_oop_arraycopy = StubRoutines::_arrayof_oop_arraycopy;
2107 StubRoutines::_oop_disjoint_arraycopy_uninit = StubRoutines::_arrayof_oop_disjoint_arraycopy_uninit;
2108 StubRoutines::_oop_arraycopy_uninit = StubRoutines::_arrayof_oop_arraycopy_uninit;
2109
2110 StubRoutines::_checkcast_arraycopy = generate_checkcast_copy("checkcast_arraycopy", &entry_checkcast_arraycopy);
2111 StubRoutines::_checkcast_arraycopy_uninit = generate_checkcast_copy("checkcast_arraycopy_uninit", NULL,
2112 /*dest_uninitialized*/true);
2113
2114 StubRoutines::_unsafe_arraycopy = generate_unsafe_copy("unsafe_arraycopy",
2115 entry_jbyte_arraycopy,
2116 entry_jshort_arraycopy,
2117 entry_jint_arraycopy,
2118 entry_jlong_arraycopy);
2119
2120 StubRoutines::_generic_arraycopy = generate_generic_copy("generic_arraycopy",
2121 entry_jbyte_arraycopy,
2122 entry_jshort_arraycopy,
2123 entry_jint_arraycopy,
2124 entry_oop_arraycopy,
2125 entry_jlong_arraycopy,
2126 entry_checkcast_arraycopy);
2127
2128 }
2129
2130 void generate_math_stubs() { Unimplemented(); }
2131
2132 // Arguments:
2133 //
2134 // Inputs:
2135 // c_rarg0 - source byte array address
2136 // c_rarg1 - destination byte array address
2137 // c_rarg2 - K (key) in little endian int array
2138 //
|