comparison src/cpu/x86/vm/stubGenerator_x86_64.cpp @ 2313:d89a22843c62

7020521: arraycopy stubs place prebarriers incorrectly Summary: Rearranged the pre-barrier placement in arraycopy stubs so that they are properly called in case of chained calls. Also refactored the code a little bit so that it looks uniform across the platforms and is more readable. Reviewed-by: never, kvn
author iveresov
date Tue, 22 Feb 2011 15:25:02 -0800
parents bbefa3ca1543
children 0ac769a57c64
comparison
equal deleted inserted replaced
2262:6bbaedb03534 2313:d89a22843c62
1 /* 1 /*
2 * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. 2 * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 * 4 *
5 * This code is free software; you can redistribute it and/or modify it 5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as 6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. 7 * published by the Free Software Foundation.
1055 __ ret(4 * wordSize); // pop caller saved stuff 1055 __ ret(4 * wordSize); // pop caller saved stuff
1056 1056
1057 return start; 1057 return start;
1058 } 1058 }
1059 1059
1060 static address disjoint_byte_copy_entry;
1061 static address disjoint_short_copy_entry;
1062 static address disjoint_int_copy_entry;
1063 static address disjoint_long_copy_entry;
1064 static address disjoint_oop_copy_entry;
1065
1066 static address byte_copy_entry;
1067 static address short_copy_entry;
1068 static address int_copy_entry;
1069 static address long_copy_entry;
1070 static address oop_copy_entry;
1071
1072 static address checkcast_copy_entry;
1073
1074 // 1060 //
1075 // Verify that a register contains clean 32-bits positive value 1061 // Verify that a register contains clean 32-bits positive value
1076 // (high 32-bits are 0) so it could be used in 64-bits shifts. 1062 // (high 32-bits are 0) so it could be used in 64-bits shifts.
1077 // 1063 //
1078 // Input: 1064 // Input:
1377 // 1363 //
1378 // Side Effects: 1364 // Side Effects:
1379 // disjoint_byte_copy_entry is set to the no-overlap entry point 1365 // disjoint_byte_copy_entry is set to the no-overlap entry point
1380 // used by generate_conjoint_byte_copy(). 1366 // used by generate_conjoint_byte_copy().
1381 // 1367 //
1382 address generate_disjoint_byte_copy(bool aligned, const char *name) { 1368 address generate_disjoint_byte_copy(bool aligned, address* entry, const char *name) {
1383 __ align(CodeEntryAlignment); 1369 __ align(CodeEntryAlignment);
1384 StubCodeMark mark(this, "StubRoutines", name); 1370 StubCodeMark mark(this, "StubRoutines", name);
1385 address start = __ pc(); 1371 address start = __ pc();
1386 1372
1387 Label L_copy_32_bytes, L_copy_8_bytes, L_copy_4_bytes, L_copy_2_bytes; 1373 Label L_copy_32_bytes, L_copy_8_bytes, L_copy_4_bytes, L_copy_2_bytes;
1397 // to the last unit copied: end_to[0] := end_from[0] 1383 // to the last unit copied: end_to[0] := end_from[0]
1398 1384
1399 __ enter(); // required for proper stackwalking of RuntimeStub frame 1385 __ enter(); // required for proper stackwalking of RuntimeStub frame
1400 assert_clean_int(c_rarg2, rax); // Make sure 'count' is clean int. 1386 assert_clean_int(c_rarg2, rax); // Make sure 'count' is clean int.
1401 1387
1402 disjoint_byte_copy_entry = __ pc(); 1388 if (entry != NULL) {
1403 BLOCK_COMMENT("Entry:"); 1389 *entry = __ pc();
1404 // caller can pass a 64-bit byte count here (from Unsafe.copyMemory) 1390 // caller can pass a 64-bit byte count here (from Unsafe.copyMemory)
1391 BLOCK_COMMENT("Entry:");
1392 }
1405 1393
1406 setup_arg_regs(); // from => rdi, to => rsi, count => rdx 1394 setup_arg_regs(); // from => rdi, to => rsi, count => rdx
1407 // r9 and r10 may be used to save non-volatile registers 1395 // r9 and r10 may be used to save non-volatile registers
1408 1396
1409 // 'from', 'to' and 'count' are now valid 1397 // 'from', 'to' and 'count' are now valid
1477 // If 'from' and/or 'to' are aligned on 4-, 2-, or 1-byte boundaries, 1465 // If 'from' and/or 'to' are aligned on 4-, 2-, or 1-byte boundaries,
1478 // we let the hardware handle it. The one to eight bytes within words, 1466 // we let the hardware handle it. The one to eight bytes within words,
1479 // dwords or qwords that span cache line boundaries will still be loaded 1467 // dwords or qwords that span cache line boundaries will still be loaded
1480 // and stored atomically. 1468 // and stored atomically.
1481 // 1469 //
1482 address generate_conjoint_byte_copy(bool aligned, const char *name) { 1470 address generate_conjoint_byte_copy(bool aligned, address nooverlap_target,
1471 address* entry, const char *name) {
1483 __ align(CodeEntryAlignment); 1472 __ align(CodeEntryAlignment);
1484 StubCodeMark mark(this, "StubRoutines", name); 1473 StubCodeMark mark(this, "StubRoutines", name);
1485 address start = __ pc(); 1474 address start = __ pc();
1486 1475
1487 Label L_copy_32_bytes, L_copy_8_bytes, L_copy_4_bytes, L_copy_2_bytes; 1476 Label L_copy_32_bytes, L_copy_8_bytes, L_copy_4_bytes, L_copy_2_bytes;
1492 const Register qword_count = count; 1481 const Register qword_count = count;
1493 1482
1494 __ enter(); // required for proper stackwalking of RuntimeStub frame 1483 __ enter(); // required for proper stackwalking of RuntimeStub frame
1495 assert_clean_int(c_rarg2, rax); // Make sure 'count' is clean int. 1484 assert_clean_int(c_rarg2, rax); // Make sure 'count' is clean int.
1496 1485
1497 byte_copy_entry = __ pc(); 1486 if (entry != NULL) {
1498 BLOCK_COMMENT("Entry:"); 1487 *entry = __ pc();
1499 // caller can pass a 64-bit byte count here (from Unsafe.copyMemory) 1488 // caller can pass a 64-bit byte count here (from Unsafe.copyMemory)
1500 1489 BLOCK_COMMENT("Entry:");
1501 array_overlap_test(disjoint_byte_copy_entry, Address::times_1); 1490 }
1491
1492 array_overlap_test(nooverlap_target, Address::times_1);
1502 setup_arg_regs(); // from => rdi, to => rsi, count => rdx 1493 setup_arg_regs(); // from => rdi, to => rsi, count => rdx
1503 // r9 and r10 may be used to save non-volatile registers 1494 // r9 and r10 may be used to save non-volatile registers
1504 1495
1505 // 'from', 'to' and 'count' are now valid 1496 // 'from', 'to' and 'count' are now valid
1506 __ movptr(byte_count, count); 1497 __ movptr(byte_count, count);
1572 // 1563 //
1573 // Side Effects: 1564 // Side Effects:
1574 // disjoint_short_copy_entry is set to the no-overlap entry point 1565 // disjoint_short_copy_entry is set to the no-overlap entry point
1575 // used by generate_conjoint_short_copy(). 1566 // used by generate_conjoint_short_copy().
1576 // 1567 //
1577 address generate_disjoint_short_copy(bool aligned, const char *name) { 1568 address generate_disjoint_short_copy(bool aligned, address *entry, const char *name) {
1578 __ align(CodeEntryAlignment); 1569 __ align(CodeEntryAlignment);
1579 StubCodeMark mark(this, "StubRoutines", name); 1570 StubCodeMark mark(this, "StubRoutines", name);
1580 address start = __ pc(); 1571 address start = __ pc();
1581 1572
1582 Label L_copy_32_bytes, L_copy_8_bytes, L_copy_4_bytes,L_copy_2_bytes,L_exit; 1573 Label L_copy_32_bytes, L_copy_8_bytes, L_copy_4_bytes,L_copy_2_bytes,L_exit;
1591 // to the last unit copied: end_to[0] := end_from[0] 1582 // to the last unit copied: end_to[0] := end_from[0]
1592 1583
1593 __ enter(); // required for proper stackwalking of RuntimeStub frame 1584 __ enter(); // required for proper stackwalking of RuntimeStub frame
1594 assert_clean_int(c_rarg2, rax); // Make sure 'count' is clean int. 1585 assert_clean_int(c_rarg2, rax); // Make sure 'count' is clean int.
1595 1586
1596 disjoint_short_copy_entry = __ pc(); 1587 if (entry != NULL) {
1597 BLOCK_COMMENT("Entry:"); 1588 *entry = __ pc();
1598 // caller can pass a 64-bit byte count here (from Unsafe.copyMemory) 1589 // caller can pass a 64-bit byte count here (from Unsafe.copyMemory)
1590 BLOCK_COMMENT("Entry:");
1591 }
1599 1592
1600 setup_arg_regs(); // from => rdi, to => rsi, count => rdx 1593 setup_arg_regs(); // from => rdi, to => rsi, count => rdx
1601 // r9 and r10 may be used to save non-volatile registers 1594 // r9 and r10 may be used to save non-volatile registers
1602 1595
1603 // 'from', 'to' and 'count' are now valid 1596 // 'from', 'to' and 'count' are now valid
1684 // If 'from' and/or 'to' are aligned on 4- or 2-byte boundaries, we 1677 // If 'from' and/or 'to' are aligned on 4- or 2-byte boundaries, we
1685 // let the hardware handle it. The two or four words within dwords 1678 // let the hardware handle it. The two or four words within dwords
1686 // or qwords that span cache line boundaries will still be loaded 1679 // or qwords that span cache line boundaries will still be loaded
1687 // and stored atomically. 1680 // and stored atomically.
1688 // 1681 //
1689 address generate_conjoint_short_copy(bool aligned, const char *name) { 1682 address generate_conjoint_short_copy(bool aligned, address nooverlap_target,
1683 address *entry, const char *name) {
1690 __ align(CodeEntryAlignment); 1684 __ align(CodeEntryAlignment);
1691 StubCodeMark mark(this, "StubRoutines", name); 1685 StubCodeMark mark(this, "StubRoutines", name);
1692 address start = __ pc(); 1686 address start = __ pc();
1693 1687
1694 Label L_copy_32_bytes, L_copy_8_bytes, L_copy_4_bytes; 1688 Label L_copy_32_bytes, L_copy_8_bytes, L_copy_4_bytes;
1699 const Register qword_count = count; 1693 const Register qword_count = count;
1700 1694
1701 __ enter(); // required for proper stackwalking of RuntimeStub frame 1695 __ enter(); // required for proper stackwalking of RuntimeStub frame
1702 assert_clean_int(c_rarg2, rax); // Make sure 'count' is clean int. 1696 assert_clean_int(c_rarg2, rax); // Make sure 'count' is clean int.
1703 1697
1704 short_copy_entry = __ pc(); 1698 if (entry != NULL) {
1705 BLOCK_COMMENT("Entry:"); 1699 *entry = __ pc();
1706 // caller can pass a 64-bit byte count here (from Unsafe.copyMemory) 1700 // caller can pass a 64-bit byte count here (from Unsafe.copyMemory)
1707 1701 BLOCK_COMMENT("Entry:");
1708 array_overlap_test(disjoint_short_copy_entry, Address::times_2); 1702 }
1703
1704 array_overlap_test(nooverlap_target, Address::times_2);
1709 setup_arg_regs(); // from => rdi, to => rsi, count => rdx 1705 setup_arg_regs(); // from => rdi, to => rsi, count => rdx
1710 // r9 and r10 may be used to save non-volatile registers 1706 // r9 and r10 may be used to save non-volatile registers
1711 1707
1712 // 'from', 'to' and 'count' are now valid 1708 // 'from', 'to' and 'count' are now valid
1713 __ movptr(word_count, count); 1709 __ movptr(word_count, count);
1771 // 1767 //
1772 // Side Effects: 1768 // Side Effects:
1773 // disjoint_int_copy_entry is set to the no-overlap entry point 1769 // disjoint_int_copy_entry is set to the no-overlap entry point
1774 // used by generate_conjoint_int_oop_copy(). 1770 // used by generate_conjoint_int_oop_copy().
1775 // 1771 //
1776 address generate_disjoint_int_oop_copy(bool aligned, bool is_oop, const char *name) { 1772 address generate_disjoint_int_oop_copy(bool aligned, bool is_oop, address* entry, const char *name) {
1777 __ align(CodeEntryAlignment); 1773 __ align(CodeEntryAlignment);
1778 StubCodeMark mark(this, "StubRoutines", name); 1774 StubCodeMark mark(this, "StubRoutines", name);
1779 address start = __ pc(); 1775 address start = __ pc();
1780 1776
1781 Label L_copy_32_bytes, L_copy_8_bytes, L_copy_4_bytes, L_exit; 1777 Label L_copy_32_bytes, L_copy_8_bytes, L_copy_4_bytes, L_exit;
1791 // to the last unit copied: end_to[0] := end_from[0] 1787 // to the last unit copied: end_to[0] := end_from[0]
1792 1788
1793 __ enter(); // required for proper stackwalking of RuntimeStub frame 1789 __ enter(); // required for proper stackwalking of RuntimeStub frame
1794 assert_clean_int(c_rarg2, rax); // Make sure 'count' is clean int. 1790 assert_clean_int(c_rarg2, rax); // Make sure 'count' is clean int.
1795 1791
1796 (is_oop ? disjoint_oop_copy_entry : disjoint_int_copy_entry) = __ pc(); 1792 if (entry != NULL) {
1797 1793 *entry = __ pc();
1798 if (is_oop) { 1794 // caller can pass a 64-bit byte count here (from Unsafe.copyMemory)
1799 // no registers are destroyed by this call 1795 BLOCK_COMMENT("Entry:");
1800 gen_write_ref_array_pre_barrier(/* dest */ c_rarg1, /* count */ c_rarg2); 1796 }
1801 }
1802
1803 BLOCK_COMMENT("Entry:");
1804 // caller can pass a 64-bit byte count here (from Unsafe.copyMemory)
1805 1797
1806 setup_arg_regs(); // from => rdi, to => rsi, count => rdx 1798 setup_arg_regs(); // from => rdi, to => rsi, count => rdx
1807 // r9 and r10 may be used to save non-volatile registers 1799 // r9 and r10 may be used to save non-volatile registers
1808
1809 if (is_oop) { 1800 if (is_oop) {
1810 __ movq(saved_to, to); 1801 __ movq(saved_to, to);
1802 gen_write_ref_array_pre_barrier(to, count);
1811 } 1803 }
1812 1804
1813 // 'from', 'to' and 'count' are now valid 1805 // 'from', 'to' and 'count' are now valid
1814 __ movptr(dword_count, count); 1806 __ movptr(dword_count, count);
1815 __ shrptr(count, 1); // count => qword_count 1807 __ shrptr(count, 1); // count => qword_count
1865 // 1857 //
1866 // If 'from' and/or 'to' are aligned on 4-byte boundaries, we let 1858 // If 'from' and/or 'to' are aligned on 4-byte boundaries, we let
1867 // the hardware handle it. The two dwords within qwords that span 1859 // the hardware handle it. The two dwords within qwords that span
1868 // cache line boundaries will still be loaded and stored atomicly. 1860 // cache line boundaries will still be loaded and stored atomicly.
1869 // 1861 //
1870 address generate_conjoint_int_oop_copy(bool aligned, bool is_oop, const char *name) { 1862 address generate_conjoint_int_oop_copy(bool aligned, bool is_oop, address nooverlap_target,
1863 address *entry, const char *name) {
1871 __ align(CodeEntryAlignment); 1864 __ align(CodeEntryAlignment);
1872 StubCodeMark mark(this, "StubRoutines", name); 1865 StubCodeMark mark(this, "StubRoutines", name);
1873 address start = __ pc(); 1866 address start = __ pc();
1874 1867
1875 Label L_copy_32_bytes, L_copy_8_bytes, L_copy_2_bytes, L_exit; 1868 Label L_copy_32_bytes, L_copy_8_bytes, L_copy_2_bytes, L_exit;
1880 const Register qword_count = count; 1873 const Register qword_count = count;
1881 1874
1882 __ enter(); // required for proper stackwalking of RuntimeStub frame 1875 __ enter(); // required for proper stackwalking of RuntimeStub frame
1883 assert_clean_int(c_rarg2, rax); // Make sure 'count' is clean int. 1876 assert_clean_int(c_rarg2, rax); // Make sure 'count' is clean int.
1884 1877
1878 if (entry != NULL) {
1879 *entry = __ pc();
1880 // caller can pass a 64-bit byte count here (from Unsafe.copyMemory)
1881 BLOCK_COMMENT("Entry:");
1882 }
1883
1884 array_overlap_test(nooverlap_target, Address::times_4);
1885 setup_arg_regs(); // from => rdi, to => rsi, count => rdx
1886 // r9 and r10 may be used to save non-volatile registers
1887
1885 if (is_oop) { 1888 if (is_oop) {
1886 // no registers are destroyed by this call 1889 // no registers are destroyed by this call
1887 gen_write_ref_array_pre_barrier(/* dest */ c_rarg1, /* count */ c_rarg2); 1890 gen_write_ref_array_pre_barrier(to, count);
1888 } 1891 }
1889
1890 (is_oop ? oop_copy_entry : int_copy_entry) = __ pc();
1891 BLOCK_COMMENT("Entry:");
1892 // caller can pass a 64-bit byte count here (from Unsafe.copyMemory)
1893
1894 array_overlap_test(is_oop ? disjoint_oop_copy_entry : disjoint_int_copy_entry,
1895 Address::times_4);
1896 setup_arg_regs(); // from => rdi, to => rsi, count => rdx
1897 // r9 and r10 may be used to save non-volatile registers
1898 1892
1899 assert_clean_int(count, rax); // Make sure 'count' is clean int. 1893 assert_clean_int(count, rax); // Make sure 'count' is clean int.
1900 // 'from', 'to' and 'count' are now valid 1894 // 'from', 'to' and 'count' are now valid
1901 __ movptr(dword_count, count); 1895 __ movptr(dword_count, count);
1902 __ shrptr(count, 1); // count => qword_count 1896 __ shrptr(count, 1); // count => qword_count
1957 // 1951 //
1958 // Side Effects: 1952 // Side Effects:
1959 // disjoint_oop_copy_entry or disjoint_long_copy_entry is set to the 1953 // disjoint_oop_copy_entry or disjoint_long_copy_entry is set to the
1960 // no-overlap entry point used by generate_conjoint_long_oop_copy(). 1954 // no-overlap entry point used by generate_conjoint_long_oop_copy().
1961 // 1955 //
1962 address generate_disjoint_long_oop_copy(bool aligned, bool is_oop, const char *name) { 1956 address generate_disjoint_long_oop_copy(bool aligned, bool is_oop, address *entry, const char *name) {
1963 __ align(CodeEntryAlignment); 1957 __ align(CodeEntryAlignment);
1964 StubCodeMark mark(this, "StubRoutines", name); 1958 StubCodeMark mark(this, "StubRoutines", name);
1965 address start = __ pc(); 1959 address start = __ pc();
1966 1960
1967 Label L_copy_32_bytes, L_copy_8_bytes, L_exit; 1961 Label L_copy_32_bytes, L_copy_8_bytes, L_exit;
1976 1970
1977 __ enter(); // required for proper stackwalking of RuntimeStub frame 1971 __ enter(); // required for proper stackwalking of RuntimeStub frame
1978 // Save no-overlap entry point for generate_conjoint_long_oop_copy() 1972 // Save no-overlap entry point for generate_conjoint_long_oop_copy()
1979 assert_clean_int(c_rarg2, rax); // Make sure 'count' is clean int. 1973 assert_clean_int(c_rarg2, rax); // Make sure 'count' is clean int.
1980 1974
1981 if (is_oop) { 1975 if (entry != NULL) {
1982 disjoint_oop_copy_entry = __ pc(); 1976 *entry = __ pc();
1983 // no registers are destroyed by this call 1977 // caller can pass a 64-bit byte count here (from Unsafe.copyMemory)
1984 gen_write_ref_array_pre_barrier(/* dest */ c_rarg1, /* count */ c_rarg2); 1978 BLOCK_COMMENT("Entry:");
1985 } else { 1979 }
1986 disjoint_long_copy_entry = __ pc();
1987 }
1988 BLOCK_COMMENT("Entry:");
1989 // caller can pass a 64-bit byte count here (from Unsafe.copyMemory)
1990 1980
1991 setup_arg_regs(); // from => rdi, to => rsi, count => rdx 1981 setup_arg_regs(); // from => rdi, to => rsi, count => rdx
1992 // r9 and r10 may be used to save non-volatile registers 1982 // r9 and r10 may be used to save non-volatile registers
1993
1994 // 'from', 'to' and 'qword_count' are now valid 1983 // 'from', 'to' and 'qword_count' are now valid
1984 if (is_oop) {
1985 // no registers are destroyed by this call
1986 gen_write_ref_array_pre_barrier(to, qword_count);
1987 }
1995 1988
1996 // Copy from low to high addresses. Use 'to' as scratch. 1989 // Copy from low to high addresses. Use 'to' as scratch.
1997 __ lea(end_from, Address(from, qword_count, Address::times_8, -8)); 1990 __ lea(end_from, Address(from, qword_count, Address::times_8, -8));
1998 __ lea(end_to, Address(to, qword_count, Address::times_8, -8)); 1991 __ lea(end_to, Address(to, qword_count, Address::times_8, -8));
1999 __ negptr(qword_count); 1992 __ negptr(qword_count);
2043 // Inputs: 2036 // Inputs:
2044 // c_rarg0 - source array address 2037 // c_rarg0 - source array address
2045 // c_rarg1 - destination array address 2038 // c_rarg1 - destination array address
2046 // c_rarg2 - element count, treated as ssize_t, can be zero 2039 // c_rarg2 - element count, treated as ssize_t, can be zero
2047 // 2040 //
2048 address generate_conjoint_long_oop_copy(bool aligned, bool is_oop, const char *name) { 2041 address generate_conjoint_long_oop_copy(bool aligned, bool is_oop, address nooverlap_target,
2042 address *entry, const char *name) {
2049 __ align(CodeEntryAlignment); 2043 __ align(CodeEntryAlignment);
2050 StubCodeMark mark(this, "StubRoutines", name); 2044 StubCodeMark mark(this, "StubRoutines", name);
2051 address start = __ pc(); 2045 address start = __ pc();
2052 2046
2053 Label L_copy_32_bytes, L_copy_8_bytes, L_exit; 2047 Label L_copy_32_bytes, L_copy_8_bytes, L_exit;
2057 const Register saved_count = rcx; 2051 const Register saved_count = rcx;
2058 2052
2059 __ enter(); // required for proper stackwalking of RuntimeStub frame 2053 __ enter(); // required for proper stackwalking of RuntimeStub frame
2060 assert_clean_int(c_rarg2, rax); // Make sure 'count' is clean int. 2054 assert_clean_int(c_rarg2, rax); // Make sure 'count' is clean int.
2061 2055
2062 address disjoint_copy_entry = NULL; 2056 if (entry != NULL) {
2063 if (is_oop) { 2057 *entry = __ pc();
2064 assert(!UseCompressedOops, "shouldn't be called for compressed oops"); 2058 // caller can pass a 64-bit byte count here (from Unsafe.copyMemory)
2065 disjoint_copy_entry = disjoint_oop_copy_entry; 2059 BLOCK_COMMENT("Entry:");
2066 oop_copy_entry = __ pc(); 2060 }
2067 array_overlap_test(disjoint_oop_copy_entry, Address::times_8); 2061
2068 } else { 2062 array_overlap_test(nooverlap_target, Address::times_8);
2069 disjoint_copy_entry = disjoint_long_copy_entry;
2070 long_copy_entry = __ pc();
2071 array_overlap_test(disjoint_long_copy_entry, Address::times_8);
2072 }
2073 BLOCK_COMMENT("Entry:");
2074 // caller can pass a 64-bit byte count here (from Unsafe.copyMemory)
2075
2076 array_overlap_test(disjoint_copy_entry, Address::times_8);
2077 setup_arg_regs(); // from => rdi, to => rsi, count => rdx 2063 setup_arg_regs(); // from => rdi, to => rsi, count => rdx
2078 // r9 and r10 may be used to save non-volatile registers 2064 // r9 and r10 may be used to save non-volatile registers
2079
2080 // 'from', 'to' and 'qword_count' are now valid 2065 // 'from', 'to' and 'qword_count' are now valid
2081
2082 if (is_oop) { 2066 if (is_oop) {
2083 // Save to and count for store barrier 2067 // Save to and count for store barrier
2084 __ movptr(saved_count, qword_count); 2068 __ movptr(saved_count, qword_count);
2085 // No registers are destroyed by this call 2069 // No registers are destroyed by this call
2086 gen_write_ref_array_pre_barrier(to, saved_count); 2070 gen_write_ref_array_pre_barrier(to, saved_count);
2160 // 2144 //
2161 // Output: 2145 // Output:
2162 // rax == 0 - success 2146 // rax == 0 - success
2163 // rax == -1^K - failure, where K is partial transfer count 2147 // rax == -1^K - failure, where K is partial transfer count
2164 // 2148 //
2165 address generate_checkcast_copy(const char *name) { 2149 address generate_checkcast_copy(const char *name, address *entry) {
2166 2150
2167 Label L_load_element, L_store_element, L_do_card_marks, L_done; 2151 Label L_load_element, L_store_element, L_do_card_marks, L_done;
2168 2152
2169 // Input registers (after setup_arg_regs) 2153 // Input registers (after setup_arg_regs)
2170 const Register from = rdi; // source array address 2154 const Register from = rdi; // source array address
2214 // last argument (#4) is on stack on Win64 2198 // last argument (#4) is on stack on Win64
2215 __ movptr(ckval, Address(rsp, 6 * wordSize)); 2199 __ movptr(ckval, Address(rsp, 6 * wordSize));
2216 #endif 2200 #endif
2217 2201
2218 // Caller of this entry point must set up the argument registers. 2202 // Caller of this entry point must set up the argument registers.
2219 checkcast_copy_entry = __ pc(); 2203 if (entry != NULL) {
2220 BLOCK_COMMENT("Entry:"); 2204 *entry = __ pc();
2205 BLOCK_COMMENT("Entry:");
2206 }
2221 2207
2222 // allocate spill slots for r13, r14 2208 // allocate spill slots for r13, r14
2223 enum { 2209 enum {
2224 saved_r13_offset, 2210 saved_r13_offset,
2225 saved_r14_offset, 2211 saved_r14_offset,
2332 // c_rarg2 - byte count, treated as ssize_t, can be zero 2318 // c_rarg2 - byte count, treated as ssize_t, can be zero
2333 // 2319 //
2334 // Examines the alignment of the operands and dispatches 2320 // Examines the alignment of the operands and dispatches
2335 // to a long, int, short, or byte copy loop. 2321 // to a long, int, short, or byte copy loop.
2336 // 2322 //
2337 address generate_unsafe_copy(const char *name) { 2323 address generate_unsafe_copy(const char *name,
2324 address byte_copy_entry, address short_copy_entry,
2325 address int_copy_entry, address long_copy_entry) {
2338 2326
2339 Label L_long_aligned, L_int_aligned, L_short_aligned; 2327 Label L_long_aligned, L_int_aligned, L_short_aligned;
2340 2328
2341 // Input registers (before setup_arg_regs) 2329 // Input registers (before setup_arg_regs)
2342 const Register from = c_rarg0; // source array address 2330 const Register from = c_rarg0; // source array address
2430 // 2418 //
2431 // Output: 2419 // Output:
2432 // rax == 0 - success 2420 // rax == 0 - success
2433 // rax == -1^K - failure, where K is partial transfer count 2421 // rax == -1^K - failure, where K is partial transfer count
2434 // 2422 //
2435 address generate_generic_copy(const char *name) { 2423 address generate_generic_copy(const char *name,
2424 address byte_copy_entry, address short_copy_entry,
2425 address int_copy_entry, address long_copy_entry,
2426 address oop_copy_entry, address checkcast_copy_entry) {
2436 2427
2437 Label L_failed, L_failed_0, L_objArray; 2428 Label L_failed, L_failed_0, L_objArray;
2438 Label L_copy_bytes, L_copy_shorts, L_copy_ints, L_copy_longs; 2429 Label L_copy_bytes, L_copy_shorts, L_copy_ints, L_copy_longs;
2439 2430
2440 // Input registers 2431 // Input registers
2723 2714
2724 return start; 2715 return start;
2725 } 2716 }
2726 2717
2727 void generate_arraycopy_stubs() { 2718 void generate_arraycopy_stubs() {
2728 // Call the conjoint generation methods immediately after 2719 address entry;
2729 // the disjoint ones so that short branches from the former 2720 address entry_jbyte_arraycopy;
2730 // to the latter can be generated. 2721 address entry_jshort_arraycopy;
2731 StubRoutines::_jbyte_disjoint_arraycopy = generate_disjoint_byte_copy(false, "jbyte_disjoint_arraycopy"); 2722 address entry_jint_arraycopy;
2732 StubRoutines::_jbyte_arraycopy = generate_conjoint_byte_copy(false, "jbyte_arraycopy"); 2723 address entry_oop_arraycopy;
2733 2724 address entry_jlong_arraycopy;
2734 StubRoutines::_jshort_disjoint_arraycopy = generate_disjoint_short_copy(false, "jshort_disjoint_arraycopy"); 2725 address entry_checkcast_arraycopy;
2735 StubRoutines::_jshort_arraycopy = generate_conjoint_short_copy(false, "jshort_arraycopy"); 2726
2736 2727 StubRoutines::_jbyte_disjoint_arraycopy = generate_disjoint_byte_copy(false, &entry,
2737 StubRoutines::_jint_disjoint_arraycopy = generate_disjoint_int_oop_copy(false, false, "jint_disjoint_arraycopy"); 2728 "jbyte_disjoint_arraycopy");
2738 StubRoutines::_jint_arraycopy = generate_conjoint_int_oop_copy(false, false, "jint_arraycopy"); 2729 StubRoutines::_jbyte_arraycopy = generate_conjoint_byte_copy(false, entry, &entry_jbyte_arraycopy,
2739 2730 "jbyte_arraycopy");
2740 StubRoutines::_jlong_disjoint_arraycopy = generate_disjoint_long_oop_copy(false, false, "jlong_disjoint_arraycopy"); 2731
2741 StubRoutines::_jlong_arraycopy = generate_conjoint_long_oop_copy(false, false, "jlong_arraycopy"); 2732 StubRoutines::_jshort_disjoint_arraycopy = generate_disjoint_short_copy(false, &entry,
2733 "jshort_disjoint_arraycopy");
2734 StubRoutines::_jshort_arraycopy = generate_conjoint_short_copy(false, entry, &entry_jshort_arraycopy,
2735 "jshort_arraycopy");
2736
2737 StubRoutines::_jint_disjoint_arraycopy = generate_disjoint_int_oop_copy(false, false, &entry,
2738 "jint_disjoint_arraycopy");
2739 StubRoutines::_jint_arraycopy = generate_conjoint_int_oop_copy(false, false, entry,
2740 &entry_jint_arraycopy, "jint_arraycopy");
2741
2742 StubRoutines::_jlong_disjoint_arraycopy = generate_disjoint_long_oop_copy(false, false, &entry,
2743 "jlong_disjoint_arraycopy");
2744 StubRoutines::_jlong_arraycopy = generate_conjoint_long_oop_copy(false, false, entry,
2745 &entry_jlong_arraycopy, "jlong_arraycopy");
2742 2746
2743 2747
2744 if (UseCompressedOops) { 2748 if (UseCompressedOops) {
2745 StubRoutines::_oop_disjoint_arraycopy = generate_disjoint_int_oop_copy(false, true, "oop_disjoint_arraycopy"); 2749 StubRoutines::_oop_disjoint_arraycopy = generate_disjoint_int_oop_copy(false, true, &entry,
2746 StubRoutines::_oop_arraycopy = generate_conjoint_int_oop_copy(false, true, "oop_arraycopy"); 2750 "oop_disjoint_arraycopy");
2751 StubRoutines::_oop_arraycopy = generate_conjoint_int_oop_copy(false, true, entry,
2752 &entry_oop_arraycopy, "oop_arraycopy");
2747 } else { 2753 } else {
2748 StubRoutines::_oop_disjoint_arraycopy = generate_disjoint_long_oop_copy(false, true, "oop_disjoint_arraycopy"); 2754 StubRoutines::_oop_disjoint_arraycopy = generate_disjoint_long_oop_copy(false, true, &entry,
2749 StubRoutines::_oop_arraycopy = generate_conjoint_long_oop_copy(false, true, "oop_arraycopy"); 2755 "oop_disjoint_arraycopy");
2750 } 2756 StubRoutines::_oop_arraycopy = generate_conjoint_long_oop_copy(false, true, entry,
2751 2757 &entry_oop_arraycopy, "oop_arraycopy");
2752 StubRoutines::_checkcast_arraycopy = generate_checkcast_copy("checkcast_arraycopy"); 2758 }
2753 StubRoutines::_unsafe_arraycopy = generate_unsafe_copy("unsafe_arraycopy"); 2759
2754 StubRoutines::_generic_arraycopy = generate_generic_copy("generic_arraycopy"); 2760 StubRoutines::_checkcast_arraycopy = generate_checkcast_copy("checkcast_arraycopy", &entry_checkcast_arraycopy);
2761 StubRoutines::_unsafe_arraycopy = generate_unsafe_copy("unsafe_arraycopy",
2762 entry_jbyte_arraycopy,
2763 entry_jshort_arraycopy,
2764 entry_jint_arraycopy,
2765 entry_jlong_arraycopy);
2766 StubRoutines::_generic_arraycopy = generate_generic_copy("generic_arraycopy",
2767 entry_jbyte_arraycopy,
2768 entry_jshort_arraycopy,
2769 entry_jint_arraycopy,
2770 entry_oop_arraycopy,
2771 entry_jlong_arraycopy,
2772 entry_checkcast_arraycopy);
2755 2773
2756 StubRoutines::_jbyte_fill = generate_fill(T_BYTE, false, "jbyte_fill"); 2774 StubRoutines::_jbyte_fill = generate_fill(T_BYTE, false, "jbyte_fill");
2757 StubRoutines::_jshort_fill = generate_fill(T_SHORT, false, "jshort_fill"); 2775 StubRoutines::_jshort_fill = generate_fill(T_SHORT, false, "jshort_fill");
2758 StubRoutines::_jint_fill = generate_fill(T_INT, false, "jint_fill"); 2776 StubRoutines::_jint_fill = generate_fill(T_INT, false, "jint_fill");
2759 StubRoutines::_arrayof_jbyte_fill = generate_fill(T_BYTE, true, "arrayof_jbyte_fill"); 2777 StubRoutines::_arrayof_jbyte_fill = generate_fill(T_BYTE, true, "arrayof_jbyte_fill");
3067 generate_initial(); 3085 generate_initial();
3068 } 3086 }
3069 } 3087 }
3070 }; // end class declaration 3088 }; // end class declaration
3071 3089
3072 address StubGenerator::disjoint_byte_copy_entry = NULL;
3073 address StubGenerator::disjoint_short_copy_entry = NULL;
3074 address StubGenerator::disjoint_int_copy_entry = NULL;
3075 address StubGenerator::disjoint_long_copy_entry = NULL;
3076 address StubGenerator::disjoint_oop_copy_entry = NULL;
3077
3078 address StubGenerator::byte_copy_entry = NULL;
3079 address StubGenerator::short_copy_entry = NULL;
3080 address StubGenerator::int_copy_entry = NULL;
3081 address StubGenerator::long_copy_entry = NULL;
3082 address StubGenerator::oop_copy_entry = NULL;
3083
3084 address StubGenerator::checkcast_copy_entry = NULL;
3085
3086 void StubGenerator_generate(CodeBuffer* code, bool all) { 3090 void StubGenerator_generate(CodeBuffer* code, bool all) {
3087 StubGenerator g(code, all); 3091 StubGenerator g(code, all);
3088 } 3092 }