comparison src/cpu/sparc/vm/stubGenerator_sparc.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 f95d63e2154a
children 0ac769a57c64
comparison
equal deleted inserted replaced
2262:6bbaedb03534 2313:d89a22843c62
1 /* 1 /*
2 * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved. 2 * Copyright (c) 1997, 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.
966 __ verify_oop_subroutine(); 966 __ verify_oop_subroutine();
967 967
968 return start; 968 return start;
969 } 969 }
970 970
971 static address disjoint_byte_copy_entry;
972 static address disjoint_short_copy_entry;
973 static address disjoint_int_copy_entry;
974 static address disjoint_long_copy_entry;
975 static address disjoint_oop_copy_entry;
976
977 static address byte_copy_entry;
978 static address short_copy_entry;
979 static address int_copy_entry;
980 static address long_copy_entry;
981 static address oop_copy_entry;
982
983 static address checkcast_copy_entry;
984 971
985 // 972 //
986 // Verify that a register contains clean 32-bits positive value 973 // Verify that a register contains clean 32-bits positive value
987 // (high 32-bits are 0) so it could be used in 64-bits shifts (sllx, srax). 974 // (high 32-bits are 0) so it could be used in 64-bits shifts (sllx, srax).
988 // 975 //
1281 // Arguments for generated stub: 1268 // Arguments for generated stub:
1282 // from: O0 1269 // from: O0
1283 // to: O1 1270 // to: O1
1284 // count: O2 treated as signed 1271 // count: O2 treated as signed
1285 // 1272 //
1286 address generate_disjoint_byte_copy(bool aligned, const char * name) { 1273 address generate_disjoint_byte_copy(bool aligned, address *entry, const char *name) {
1287 __ align(CodeEntryAlignment); 1274 __ align(CodeEntryAlignment);
1288 StubCodeMark mark(this, "StubRoutines", name); 1275 StubCodeMark mark(this, "StubRoutines", name);
1289 address start = __ pc(); 1276 address start = __ pc();
1290 1277
1291 Label L_skip_alignment, L_align; 1278 Label L_skip_alignment, L_align;
1297 const Register offset = O5; // offset from start of arrays 1284 const Register offset = O5; // offset from start of arrays
1298 // O3, O4, G3, G4 are used as temp registers 1285 // O3, O4, G3, G4 are used as temp registers
1299 1286
1300 assert_clean_int(count, O3); // Make sure 'count' is clean int. 1287 assert_clean_int(count, O3); // Make sure 'count' is clean int.
1301 1288
1302 if (!aligned) disjoint_byte_copy_entry = __ pc(); 1289 if (entry != NULL) {
1303 // caller can pass a 64-bit byte count here (from Unsafe.copyMemory) 1290 *entry = __ pc();
1304 if (!aligned) BLOCK_COMMENT("Entry:"); 1291 // caller can pass a 64-bit byte count here (from Unsafe.copyMemory)
1292 BLOCK_COMMENT("Entry:");
1293 }
1305 1294
1306 // for short arrays, just do single element copy 1295 // for short arrays, just do single element copy
1307 __ cmp(count, 23); // 16 + 7 1296 __ cmp(count, 23); // 16 + 7
1308 __ brx(Assembler::less, false, Assembler::pn, L_copy_byte); 1297 __ brx(Assembler::less, false, Assembler::pn, L_copy_byte);
1309 __ delayed()->mov(G0, offset); 1298 __ delayed()->mov(G0, offset);
1389 // Arguments for generated stub: 1378 // Arguments for generated stub:
1390 // from: O0 1379 // from: O0
1391 // to: O1 1380 // to: O1
1392 // count: O2 treated as signed 1381 // count: O2 treated as signed
1393 // 1382 //
1394 address generate_conjoint_byte_copy(bool aligned, const char * name) { 1383 address generate_conjoint_byte_copy(bool aligned, address nooverlap_target,
1384 address *entry, const char *name) {
1395 // Do reverse copy. 1385 // Do reverse copy.
1396 1386
1397 __ align(CodeEntryAlignment); 1387 __ align(CodeEntryAlignment);
1398 StubCodeMark mark(this, "StubRoutines", name); 1388 StubCodeMark mark(this, "StubRoutines", name);
1399 address start = __ pc(); 1389 address start = __ pc();
1400 address nooverlap_target = aligned ?
1401 StubRoutines::arrayof_jbyte_disjoint_arraycopy() :
1402 disjoint_byte_copy_entry;
1403 1390
1404 Label L_skip_alignment, L_align, L_aligned_copy; 1391 Label L_skip_alignment, L_align, L_aligned_copy;
1405 Label L_copy_byte, L_copy_byte_loop, L_exit; 1392 Label L_copy_byte, L_copy_byte_loop, L_exit;
1406 1393
1407 const Register from = O0; // source array address 1394 const Register from = O0; // source array address
1410 const Register end_from = from; // source array end address 1397 const Register end_from = from; // source array end address
1411 const Register end_to = to; // destination array end address 1398 const Register end_to = to; // destination array end address
1412 1399
1413 assert_clean_int(count, O3); // Make sure 'count' is clean int. 1400 assert_clean_int(count, O3); // Make sure 'count' is clean int.
1414 1401
1415 if (!aligned) byte_copy_entry = __ pc(); 1402 if (entry != NULL) {
1416 // caller can pass a 64-bit byte count here (from Unsafe.copyMemory) 1403 *entry = __ pc();
1417 if (!aligned) BLOCK_COMMENT("Entry:"); 1404 // caller can pass a 64-bit byte count here (from Unsafe.copyMemory)
1405 BLOCK_COMMENT("Entry:");
1406 }
1418 1407
1419 array_overlap_test(nooverlap_target, 0); 1408 array_overlap_test(nooverlap_target, 0);
1420 1409
1421 __ add(to, count, end_to); // offset after last copied element 1410 __ add(to, count, end_to); // offset after last copied element
1422 1411
1502 // Arguments for generated stub: 1491 // Arguments for generated stub:
1503 // from: O0 1492 // from: O0
1504 // to: O1 1493 // to: O1
1505 // count: O2 treated as signed 1494 // count: O2 treated as signed
1506 // 1495 //
1507 address generate_disjoint_short_copy(bool aligned, const char * name) { 1496 address generate_disjoint_short_copy(bool aligned, address *entry, const char * name) {
1508 __ align(CodeEntryAlignment); 1497 __ align(CodeEntryAlignment);
1509 StubCodeMark mark(this, "StubRoutines", name); 1498 StubCodeMark mark(this, "StubRoutines", name);
1510 address start = __ pc(); 1499 address start = __ pc();
1511 1500
1512 Label L_skip_alignment, L_skip_alignment2; 1501 Label L_skip_alignment, L_skip_alignment2;
1518 const Register offset = O5; // offset from start of arrays 1507 const Register offset = O5; // offset from start of arrays
1519 // O3, O4, G3, G4 are used as temp registers 1508 // O3, O4, G3, G4 are used as temp registers
1520 1509
1521 assert_clean_int(count, O3); // Make sure 'count' is clean int. 1510 assert_clean_int(count, O3); // Make sure 'count' is clean int.
1522 1511
1523 if (!aligned) disjoint_short_copy_entry = __ pc(); 1512 if (entry != NULL) {
1524 // caller can pass a 64-bit byte count here (from Unsafe.copyMemory) 1513 *entry = __ pc();
1525 if (!aligned) BLOCK_COMMENT("Entry:"); 1514 // caller can pass a 64-bit byte count here (from Unsafe.copyMemory)
1515 BLOCK_COMMENT("Entry:");
1516 }
1526 1517
1527 // for short arrays, just do single element copy 1518 // for short arrays, just do single element copy
1528 __ cmp(count, 11); // 8 + 3 (22 bytes) 1519 __ cmp(count, 11); // 8 + 3 (22 bytes)
1529 __ brx(Assembler::less, false, Assembler::pn, L_copy_2_bytes); 1520 __ brx(Assembler::less, false, Assembler::pn, L_copy_2_bytes);
1530 __ delayed()->mov(G0, offset); 1521 __ delayed()->mov(G0, offset);
1840 // Arguments for generated stub: 1831 // Arguments for generated stub:
1841 // from: O0 1832 // from: O0
1842 // to: O1 1833 // to: O1
1843 // count: O2 treated as signed 1834 // count: O2 treated as signed
1844 // 1835 //
1845 address generate_conjoint_short_copy(bool aligned, const char * name) { 1836 address generate_conjoint_short_copy(bool aligned, address nooverlap_target,
1837 address *entry, const char *name) {
1846 // Do reverse copy. 1838 // Do reverse copy.
1847 1839
1848 __ align(CodeEntryAlignment); 1840 __ align(CodeEntryAlignment);
1849 StubCodeMark mark(this, "StubRoutines", name); 1841 StubCodeMark mark(this, "StubRoutines", name);
1850 address start = __ pc(); 1842 address start = __ pc();
1851 address nooverlap_target = aligned ?
1852 StubRoutines::arrayof_jshort_disjoint_arraycopy() :
1853 disjoint_short_copy_entry;
1854 1843
1855 Label L_skip_alignment, L_skip_alignment2, L_aligned_copy; 1844 Label L_skip_alignment, L_skip_alignment2, L_aligned_copy;
1856 Label L_copy_2_bytes, L_copy_2_bytes_loop, L_exit; 1845 Label L_copy_2_bytes, L_copy_2_bytes_loop, L_exit;
1857 1846
1858 const Register from = O0; // source array address 1847 const Register from = O0; // source array address
1863 1852
1864 const Register byte_count = O3; // bytes count to copy 1853 const Register byte_count = O3; // bytes count to copy
1865 1854
1866 assert_clean_int(count, O3); // Make sure 'count' is clean int. 1855 assert_clean_int(count, O3); // Make sure 'count' is clean int.
1867 1856
1868 if (!aligned) short_copy_entry = __ pc(); 1857 if (entry != NULL) {
1869 // caller can pass a 64-bit byte count here (from Unsafe.copyMemory) 1858 *entry = __ pc();
1870 if (!aligned) BLOCK_COMMENT("Entry:"); 1859 // caller can pass a 64-bit byte count here (from Unsafe.copyMemory)
1860 BLOCK_COMMENT("Entry:");
1861 }
1871 1862
1872 array_overlap_test(nooverlap_target, 1); 1863 array_overlap_test(nooverlap_target, 1);
1873 1864
1874 __ sllx(count, LogBytesPerShort, byte_count); 1865 __ sllx(count, LogBytesPerShort, byte_count);
1875 __ add(to, byte_count, end_to); // offset after last copied element 1866 __ add(to, byte_count, end_to); // offset after last copied element
2070 // Arguments for generated stub: 2061 // Arguments for generated stub:
2071 // from: O0 2062 // from: O0
2072 // to: O1 2063 // to: O1
2073 // count: O2 treated as signed 2064 // count: O2 treated as signed
2074 // 2065 //
2075 address generate_disjoint_int_copy(bool aligned, const char * name) { 2066 address generate_disjoint_int_copy(bool aligned, address *entry, const char *name) {
2076 __ align(CodeEntryAlignment); 2067 __ align(CodeEntryAlignment);
2077 StubCodeMark mark(this, "StubRoutines", name); 2068 StubCodeMark mark(this, "StubRoutines", name);
2078 address start = __ pc(); 2069 address start = __ pc();
2079 2070
2080 const Register count = O2; 2071 const Register count = O2;
2081 assert_clean_int(count, O3); // Make sure 'count' is clean int. 2072 assert_clean_int(count, O3); // Make sure 'count' is clean int.
2082 2073
2083 if (!aligned) disjoint_int_copy_entry = __ pc(); 2074 if (entry != NULL) {
2084 // caller can pass a 64-bit byte count here (from Unsafe.copyMemory) 2075 *entry = __ pc();
2085 if (!aligned) BLOCK_COMMENT("Entry:"); 2076 // caller can pass a 64-bit byte count here (from Unsafe.copyMemory)
2077 BLOCK_COMMENT("Entry:");
2078 }
2086 2079
2087 generate_disjoint_int_copy_core(aligned); 2080 generate_disjoint_int_copy_core(aligned);
2088 2081
2089 // O3, O4 are used as temp registers 2082 // O3, O4 are used as temp registers
2090 inc_counter_np(SharedRuntime::_jint_array_copy_ctr, O3, O4); 2083 inc_counter_np(SharedRuntime::_jint_array_copy_ctr, O3, O4);
2202 // Arguments for generated stub: 2195 // Arguments for generated stub:
2203 // from: O0 2196 // from: O0
2204 // to: O1 2197 // to: O1
2205 // count: O2 treated as signed 2198 // count: O2 treated as signed
2206 // 2199 //
2207 address generate_conjoint_int_copy(bool aligned, const char * name) { 2200 address generate_conjoint_int_copy(bool aligned, address nooverlap_target,
2201 address *entry, const char *name) {
2208 __ align(CodeEntryAlignment); 2202 __ align(CodeEntryAlignment);
2209 StubCodeMark mark(this, "StubRoutines", name); 2203 StubCodeMark mark(this, "StubRoutines", name);
2210 address start = __ pc(); 2204 address start = __ pc();
2211 2205
2212 address nooverlap_target = aligned ?
2213 StubRoutines::arrayof_jint_disjoint_arraycopy() :
2214 disjoint_int_copy_entry;
2215
2216 assert_clean_int(O2, O3); // Make sure 'count' is clean int. 2206 assert_clean_int(O2, O3); // Make sure 'count' is clean int.
2217 2207
2218 if (!aligned) int_copy_entry = __ pc(); 2208 if (entry != NULL) {
2219 // caller can pass a 64-bit byte count here (from Unsafe.copyMemory) 2209 *entry = __ pc();
2220 if (!aligned) BLOCK_COMMENT("Entry:"); 2210 // caller can pass a 64-bit byte count here (from Unsafe.copyMemory)
2211 BLOCK_COMMENT("Entry:");
2212 }
2221 2213
2222 array_overlap_test(nooverlap_target, 2); 2214 array_overlap_test(nooverlap_target, 2);
2223 2215
2224 generate_conjoint_int_copy_core(aligned); 2216 generate_conjoint_int_copy_core(aligned);
2225 2217
2334 // Arguments for generated stub: 2326 // Arguments for generated stub:
2335 // from: O0 2327 // from: O0
2336 // to: O1 2328 // to: O1
2337 // count: O2 treated as signed 2329 // count: O2 treated as signed
2338 // 2330 //
2339 address generate_disjoint_long_copy(bool aligned, const char * name) { 2331 address generate_disjoint_long_copy(bool aligned, address *entry, const char *name) {
2340 __ align(CodeEntryAlignment); 2332 __ align(CodeEntryAlignment);
2341 StubCodeMark mark(this, "StubRoutines", name); 2333 StubCodeMark mark(this, "StubRoutines", name);
2342 address start = __ pc(); 2334 address start = __ pc();
2343 2335
2344 assert_clean_int(O2, O3); // Make sure 'count' is clean int. 2336 assert_clean_int(O2, O3); // Make sure 'count' is clean int.
2345 2337
2346 if (!aligned) disjoint_long_copy_entry = __ pc(); 2338 if (entry != NULL) {
2347 // caller can pass a 64-bit byte count here (from Unsafe.copyMemory) 2339 *entry = __ pc();
2348 if (!aligned) BLOCK_COMMENT("Entry:"); 2340 // caller can pass a 64-bit byte count here (from Unsafe.copyMemory)
2341 BLOCK_COMMENT("Entry:");
2342 }
2349 2343
2350 generate_disjoint_long_copy_core(aligned); 2344 generate_disjoint_long_copy_core(aligned);
2351 2345
2352 // O3, O4 are used as temp registers 2346 // O3, O4 are used as temp registers
2353 inc_counter_np(SharedRuntime::_jlong_array_copy_ctr, O3, O4); 2347 inc_counter_np(SharedRuntime::_jlong_array_copy_ctr, O3, O4);
2404 // Arguments for generated stub: 2398 // Arguments for generated stub:
2405 // from: O0 2399 // from: O0
2406 // to: O1 2400 // to: O1
2407 // count: O2 treated as signed 2401 // count: O2 treated as signed
2408 // 2402 //
2409 address generate_conjoint_long_copy(bool aligned, const char * name) { 2403 address generate_conjoint_long_copy(bool aligned, address nooverlap_target,
2404 address *entry, const char *name) {
2410 __ align(CodeEntryAlignment); 2405 __ align(CodeEntryAlignment);
2411 StubCodeMark mark(this, "StubRoutines", name); 2406 StubCodeMark mark(this, "StubRoutines", name);
2412 address start = __ pc(); 2407 address start = __ pc();
2413 2408
2414 assert(!aligned, "usage"); 2409 assert(!aligned, "usage");
2415 address nooverlap_target = disjoint_long_copy_entry;
2416 2410
2417 assert_clean_int(O2, O3); // Make sure 'count' is clean int. 2411 assert_clean_int(O2, O3); // Make sure 'count' is clean int.
2418 2412
2419 if (!aligned) long_copy_entry = __ pc(); 2413 if (entry != NULL) {
2420 // caller can pass a 64-bit byte count here (from Unsafe.copyMemory) 2414 *entry = __ pc();
2421 if (!aligned) BLOCK_COMMENT("Entry:"); 2415 // caller can pass a 64-bit byte count here (from Unsafe.copyMemory)
2416 BLOCK_COMMENT("Entry:");
2417 }
2422 2418
2423 array_overlap_test(nooverlap_target, 3); 2419 array_overlap_test(nooverlap_target, 3);
2424 2420
2425 generate_conjoint_long_copy_core(aligned); 2421 generate_conjoint_long_copy_core(aligned);
2426 2422
2437 // Arguments for generated stub: 2433 // Arguments for generated stub:
2438 // from: O0 2434 // from: O0
2439 // to: O1 2435 // to: O1
2440 // count: O2 treated as signed 2436 // count: O2 treated as signed
2441 // 2437 //
2442 address generate_disjoint_oop_copy(bool aligned, const char * name) { 2438 address generate_disjoint_oop_copy(bool aligned, address *entry, const char *name) {
2443 2439
2444 const Register from = O0; // source array address 2440 const Register from = O0; // source array address
2445 const Register to = O1; // destination array address 2441 const Register to = O1; // destination array address
2446 const Register count = O2; // elements count 2442 const Register count = O2; // elements count
2447 2443
2449 StubCodeMark mark(this, "StubRoutines", name); 2445 StubCodeMark mark(this, "StubRoutines", name);
2450 address start = __ pc(); 2446 address start = __ pc();
2451 2447
2452 assert_clean_int(count, O3); // Make sure 'count' is clean int. 2448 assert_clean_int(count, O3); // Make sure 'count' is clean int.
2453 2449
2454 if (!aligned) disjoint_oop_copy_entry = __ pc(); 2450 if (entry != NULL) {
2455 // caller can pass a 64-bit byte count here 2451 *entry = __ pc();
2456 if (!aligned) BLOCK_COMMENT("Entry:"); 2452 // caller can pass a 64-bit byte count here
2453 BLOCK_COMMENT("Entry:");
2454 }
2457 2455
2458 // save arguments for barrier generation 2456 // save arguments for barrier generation
2459 __ mov(to, G1); 2457 __ mov(to, G1);
2460 __ mov(count, G5); 2458 __ mov(count, G5);
2461 gen_write_ref_array_pre_barrier(G1, G5); 2459 gen_write_ref_array_pre_barrier(G1, G5);
2485 // Arguments for generated stub: 2483 // Arguments for generated stub:
2486 // from: O0 2484 // from: O0
2487 // to: O1 2485 // to: O1
2488 // count: O2 treated as signed 2486 // count: O2 treated as signed
2489 // 2487 //
2490 address generate_conjoint_oop_copy(bool aligned, const char * name) { 2488 address generate_conjoint_oop_copy(bool aligned, address nooverlap_target,
2489 address *entry, const char *name) {
2491 2490
2492 const Register from = O0; // source array address 2491 const Register from = O0; // source array address
2493 const Register to = O1; // destination array address 2492 const Register to = O1; // destination array address
2494 const Register count = O2; // elements count 2493 const Register count = O2; // elements count
2495 2494
2497 StubCodeMark mark(this, "StubRoutines", name); 2496 StubCodeMark mark(this, "StubRoutines", name);
2498 address start = __ pc(); 2497 address start = __ pc();
2499 2498
2500 assert_clean_int(count, O3); // Make sure 'count' is clean int. 2499 assert_clean_int(count, O3); // Make sure 'count' is clean int.
2501 2500
2502 if (!aligned) oop_copy_entry = __ pc(); 2501 if (entry != NULL) {
2503 // caller can pass a 64-bit byte count here 2502 *entry = __ pc();
2504 if (!aligned) BLOCK_COMMENT("Entry:"); 2503 // caller can pass a 64-bit byte count here
2504 BLOCK_COMMENT("Entry:");
2505 }
2506
2507 array_overlap_test(nooverlap_target, LogBytesPerHeapOop);
2505 2508
2506 // save arguments for barrier generation 2509 // save arguments for barrier generation
2507 __ mov(to, G1); 2510 __ mov(to, G1);
2508 __ mov(count, G5); 2511 __ mov(count, G5);
2509
2510 gen_write_ref_array_pre_barrier(G1, G5); 2512 gen_write_ref_array_pre_barrier(G1, G5);
2511
2512 address nooverlap_target = aligned ?
2513 StubRoutines::arrayof_oop_disjoint_arraycopy() :
2514 disjoint_oop_copy_entry;
2515
2516 array_overlap_test(nooverlap_target, LogBytesPerHeapOop);
2517 2513
2518 #ifdef _LP64 2514 #ifdef _LP64
2519 if (UseCompressedOops) { 2515 if (UseCompressedOops) {
2520 generate_conjoint_int_copy_core(aligned); 2516 generate_conjoint_int_copy_core(aligned);
2521 } else { 2517 } else {
2580 // count: O2 treated as signed 2576 // count: O2 treated as signed
2581 // ckoff: O3 (super_check_offset) 2577 // ckoff: O3 (super_check_offset)
2582 // ckval: O4 (super_klass) 2578 // ckval: O4 (super_klass)
2583 // ret: O0 zero for success; (-1^K) where K is partial transfer count 2579 // ret: O0 zero for success; (-1^K) where K is partial transfer count
2584 // 2580 //
2585 address generate_checkcast_copy(const char* name) { 2581 address generate_checkcast_copy(const char *name, address *entry) {
2586 2582
2587 const Register O0_from = O0; // source array address 2583 const Register O0_from = O0; // source array address
2588 const Register O1_to = O1; // destination array address 2584 const Register O1_to = O1; // destination array address
2589 const Register O2_count = O2; // elements count 2585 const Register O2_count = O2; // elements count
2590 const Register O3_ckoff = O3; // super_check_offset 2586 const Register O3_ckoff = O3; // super_check_offset
2597 const Register G5_super = G5; // oop._klass._primary_supers[ckval] 2593 const Register G5_super = G5; // oop._klass._primary_supers[ckval]
2598 2594
2599 __ align(CodeEntryAlignment); 2595 __ align(CodeEntryAlignment);
2600 StubCodeMark mark(this, "StubRoutines", name); 2596 StubCodeMark mark(this, "StubRoutines", name);
2601 address start = __ pc(); 2597 address start = __ pc();
2602
2603 gen_write_ref_array_pre_barrier(O1, O2);
2604 2598
2605 #ifdef ASSERT 2599 #ifdef ASSERT
2606 // We sometimes save a frame (see generate_type_check below). 2600 // We sometimes save a frame (see generate_type_check below).
2607 // If this will cause trouble, let's fail now instead of later. 2601 // If this will cause trouble, let's fail now instead of later.
2608 __ save_frame(0); 2602 __ save_frame(0);
2623 __ mov(G1, O3); 2617 __ mov(G1, O3);
2624 __ mov(G4, O4); 2618 __ mov(G4, O4);
2625 } 2619 }
2626 #endif //ASSERT 2620 #endif //ASSERT
2627 2621
2628 checkcast_copy_entry = __ pc(); 2622 if (entry != NULL) {
2629 // caller can pass a 64-bit byte count here (from generic stub) 2623 *entry = __ pc();
2630 BLOCK_COMMENT("Entry:"); 2624 // caller can pass a 64-bit byte count here (from generic stub)
2625 BLOCK_COMMENT("Entry:");
2626 }
2627
2628 gen_write_ref_array_pre_barrier(O1_to, O2_count);
2631 2629
2632 Label load_element, store_element, do_card_marks, fail, done; 2630 Label load_element, store_element, do_card_marks, fail, done;
2633 __ addcc(O2_count, 0, G1_remain); // initialize loop index, and test it 2631 __ addcc(O2_count, 0, G1_remain); // initialize loop index, and test it
2634 __ brx(Assembler::notZero, false, Assembler::pt, load_element); 2632 __ brx(Assembler::notZero, false, Assembler::pt, load_element);
2635 __ delayed()->mov(G0, O5_offset); // offset from start of arrays 2633 __ delayed()->mov(G0, O5_offset); // offset from start of arrays
2698 // count: O2 byte count, treated as ssize_t, can be zero 2696 // count: O2 byte count, treated as ssize_t, can be zero
2699 // 2697 //
2700 // Examines the alignment of the operands and dispatches 2698 // Examines the alignment of the operands and dispatches
2701 // to a long, int, short, or byte copy loop. 2699 // to a long, int, short, or byte copy loop.
2702 // 2700 //
2703 address generate_unsafe_copy(const char* name) { 2701 address generate_unsafe_copy(const char* name,
2702 address byte_copy_entry,
2703 address short_copy_entry,
2704 address int_copy_entry,
2705 address long_copy_entry) {
2704 2706
2705 const Register O0_from = O0; // source array address 2707 const Register O0_from = O0; // source array address
2706 const Register O1_to = O1; // destination array address 2708 const Register O1_to = O1; // destination array address
2707 const Register O2_count = O2; // elements count 2709 const Register O2_count = O2; // elements count
2708 2710
2794 // 2796 //
2795 // Output: 2797 // Output:
2796 // O0 == 0 - success 2798 // O0 == 0 - success
2797 // O0 == -1 - need to call System.arraycopy 2799 // O0 == -1 - need to call System.arraycopy
2798 // 2800 //
2799 address generate_generic_copy(const char *name) { 2801 address generate_generic_copy(const char *name,
2800 2802 address entry_jbyte_arraycopy,
2803 address entry_jshort_arraycopy,
2804 address entry_jint_arraycopy,
2805 address entry_oop_arraycopy,
2806 address entry_jlong_arraycopy,
2807 address entry_checkcast_arraycopy) {
2801 Label L_failed, L_objArray; 2808 Label L_failed, L_objArray;
2802 2809
2803 // Input registers 2810 // Input registers
2804 const Register src = O0; // source array oop 2811 const Register src = O0; // source array oop
2805 const Register src_pos = O1; // source position 2812 const Register src_pos = O1; // source position
2968 __ add(src, src_pos, from); // src_addr 2975 __ add(src, src_pos, from); // src_addr
2969 __ add(dst, dst_pos, to); // dst_addr 2976 __ add(dst, dst_pos, to); // dst_addr
2970 2977
2971 BLOCK_COMMENT("choose copy loop based on element size"); 2978 BLOCK_COMMENT("choose copy loop based on element size");
2972 __ cmp(G3_elsize, 0); 2979 __ cmp(G3_elsize, 0);
2973 __ br(Assembler::equal,true,Assembler::pt,StubRoutines::_jbyte_arraycopy); 2980 __ br(Assembler::equal, true, Assembler::pt, entry_jbyte_arraycopy);
2974 __ delayed()->signx(length, count); // length 2981 __ delayed()->signx(length, count); // length
2975 2982
2976 __ cmp(G3_elsize, LogBytesPerShort); 2983 __ cmp(G3_elsize, LogBytesPerShort);
2977 __ br(Assembler::equal,true,Assembler::pt,StubRoutines::_jshort_arraycopy); 2984 __ br(Assembler::equal, true, Assembler::pt, entry_jshort_arraycopy);
2978 __ delayed()->signx(length, count); // length 2985 __ delayed()->signx(length, count); // length
2979 2986
2980 __ cmp(G3_elsize, LogBytesPerInt); 2987 __ cmp(G3_elsize, LogBytesPerInt);
2981 __ br(Assembler::equal,true,Assembler::pt,StubRoutines::_jint_arraycopy); 2988 __ br(Assembler::equal, true, Assembler::pt, entry_jint_arraycopy);
2982 __ delayed()->signx(length, count); // length 2989 __ delayed()->signx(length, count); // length
2983 #ifdef ASSERT 2990 #ifdef ASSERT
2984 { Label L; 2991 { Label L;
2985 __ cmp(G3_elsize, LogBytesPerLong); 2992 __ cmp(G3_elsize, LogBytesPerLong);
2986 __ br(Assembler::equal, false, Assembler::pt, L); 2993 __ br(Assembler::equal, false, Assembler::pt, L);
2987 __ delayed()->nop(); 2994 __ delayed()->nop();
2988 __ stop("must be long copy, but elsize is wrong"); 2995 __ stop("must be long copy, but elsize is wrong");
2989 __ bind(L); 2996 __ bind(L);
2990 } 2997 }
2991 #endif 2998 #endif
2992 __ br(Assembler::always,false,Assembler::pt,StubRoutines::_jlong_arraycopy); 2999 __ br(Assembler::always, false, Assembler::pt, entry_jlong_arraycopy);
2993 __ delayed()->signx(length, count); // length 3000 __ delayed()->signx(length, count); // length
2994 3001
2995 // objArrayKlass 3002 // objArrayKlass
2996 __ BIND(L_objArray); 3003 __ BIND(L_objArray);
2997 // live at this point: G3_src_klass, G4_dst_klass, src[_pos], dst[_pos], length 3004 // live at this point: G3_src_klass, G4_dst_klass, src[_pos], dst[_pos], length
3011 __ sll_ptr(src_pos, LogBytesPerHeapOop, src_pos); 3018 __ sll_ptr(src_pos, LogBytesPerHeapOop, src_pos);
3012 __ sll_ptr(dst_pos, LogBytesPerHeapOop, dst_pos); 3019 __ sll_ptr(dst_pos, LogBytesPerHeapOop, dst_pos);
3013 __ add(src, src_pos, from); // src_addr 3020 __ add(src, src_pos, from); // src_addr
3014 __ add(dst, dst_pos, to); // dst_addr 3021 __ add(dst, dst_pos, to); // dst_addr
3015 __ BIND(L_plain_copy); 3022 __ BIND(L_plain_copy);
3016 __ br(Assembler::always, false, Assembler::pt,StubRoutines::_oop_arraycopy); 3023 __ br(Assembler::always, false, Assembler::pt, entry_oop_arraycopy);
3017 __ delayed()->signx(length, count); // length 3024 __ delayed()->signx(length, count); // length
3018 3025
3019 __ BIND(L_checkcast_copy); 3026 __ BIND(L_checkcast_copy);
3020 // live at this point: G3_src_klass, G4_dst_klass 3027 // live at this point: G3_src_klass, G4_dst_klass
3021 { 3028 {
3055 3062
3056 // the checkcast_copy loop needs two extra arguments: 3063 // the checkcast_copy loop needs two extra arguments:
3057 __ ld_ptr(G4_dst_klass, ek_offset, O4); // dest elem klass 3064 __ ld_ptr(G4_dst_klass, ek_offset, O4); // dest elem klass
3058 // lduw(O4, sco_offset, O3); // sco of elem klass 3065 // lduw(O4, sco_offset, O3); // sco of elem klass
3059 3066
3060 __ br(Assembler::always, false, Assembler::pt, checkcast_copy_entry); 3067 __ br(Assembler::always, false, Assembler::pt, entry_checkcast_arraycopy);
3061 __ delayed()->lduw(O4, sco_offset, O3); 3068 __ delayed()->lduw(O4, sco_offset, O3);
3062 } 3069 }
3063 3070
3064 __ BIND(L_failed); 3071 __ BIND(L_failed);
3065 __ retl(); 3072 __ retl();
3066 __ delayed()->sub(G0, 1, O0); // return -1 3073 __ delayed()->sub(G0, 1, O0); // return -1
3067 return start; 3074 return start;
3068 } 3075 }
3069 3076
3070 void generate_arraycopy_stubs() { 3077 void generate_arraycopy_stubs() {
3071 3078 address entry;
3072 // Note: the disjoint stubs must be generated first, some of 3079 address entry_jbyte_arraycopy;
3073 // the conjoint stubs use them. 3080 address entry_jshort_arraycopy;
3074 StubRoutines::_jbyte_disjoint_arraycopy = generate_disjoint_byte_copy(false, "jbyte_disjoint_arraycopy"); 3081 address entry_jint_arraycopy;
3075 StubRoutines::_jshort_disjoint_arraycopy = generate_disjoint_short_copy(false, "jshort_disjoint_arraycopy"); 3082 address entry_oop_arraycopy;
3076 StubRoutines::_jint_disjoint_arraycopy = generate_disjoint_int_copy(false, "jint_disjoint_arraycopy"); 3083 address entry_jlong_arraycopy;
3077 StubRoutines::_jlong_disjoint_arraycopy = generate_disjoint_long_copy(false, "jlong_disjoint_arraycopy"); 3084 address entry_checkcast_arraycopy;
3078 StubRoutines::_oop_disjoint_arraycopy = generate_disjoint_oop_copy(false, "oop_disjoint_arraycopy"); 3085
3079 StubRoutines::_arrayof_jbyte_disjoint_arraycopy = generate_disjoint_byte_copy(true, "arrayof_jbyte_disjoint_arraycopy"); 3086 StubRoutines::_jbyte_disjoint_arraycopy = generate_disjoint_byte_copy(false, &entry,
3080 StubRoutines::_arrayof_jshort_disjoint_arraycopy = generate_disjoint_short_copy(true, "arrayof_jshort_disjoint_arraycopy"); 3087 "jbyte_disjoint_arraycopy");
3081 StubRoutines::_arrayof_jint_disjoint_arraycopy = generate_disjoint_int_copy(true, "arrayof_jint_disjoint_arraycopy"); 3088 StubRoutines::_jbyte_arraycopy = generate_conjoint_byte_copy(false, entry, &entry_jbyte_arraycopy,
3082 StubRoutines::_arrayof_jlong_disjoint_arraycopy = generate_disjoint_long_copy(true, "arrayof_jlong_disjoint_arraycopy"); 3089 "jbyte_arraycopy");
3083 StubRoutines::_arrayof_oop_disjoint_arraycopy = generate_disjoint_oop_copy(true, "arrayof_oop_disjoint_arraycopy"); 3090 StubRoutines::_jshort_disjoint_arraycopy = generate_disjoint_short_copy(false, &entry,
3084 3091 "jshort_disjoint_arraycopy");
3085 StubRoutines::_jbyte_arraycopy = generate_conjoint_byte_copy(false, "jbyte_arraycopy"); 3092 StubRoutines::_jshort_arraycopy = generate_conjoint_short_copy(false, entry, &entry_jshort_arraycopy,
3086 StubRoutines::_jshort_arraycopy = generate_conjoint_short_copy(false, "jshort_arraycopy"); 3093 "jshort_arraycopy");
3087 StubRoutines::_jint_arraycopy = generate_conjoint_int_copy(false, "jint_arraycopy"); 3094 StubRoutines::_jint_disjoint_arraycopy = generate_disjoint_int_copy(false, &entry,
3088 StubRoutines::_jlong_arraycopy = generate_conjoint_long_copy(false, "jlong_arraycopy"); 3095 "jint_disjoint_arraycopy");
3089 StubRoutines::_oop_arraycopy = generate_conjoint_oop_copy(false, "oop_arraycopy"); 3096 StubRoutines::_jint_arraycopy = generate_conjoint_int_copy(false, entry, &entry_jint_arraycopy,
3090 StubRoutines::_arrayof_jbyte_arraycopy = generate_conjoint_byte_copy(true, "arrayof_jbyte_arraycopy"); 3097 "jint_arraycopy");
3091 StubRoutines::_arrayof_jshort_arraycopy = generate_conjoint_short_copy(true, "arrayof_jshort_arraycopy"); 3098 StubRoutines::_jlong_disjoint_arraycopy = generate_disjoint_long_copy(false, &entry,
3099 "jlong_disjoint_arraycopy");
3100 StubRoutines::_jlong_arraycopy = generate_conjoint_long_copy(false, entry, &entry_jlong_arraycopy,
3101 "jlong_arraycopy");
3102 StubRoutines::_oop_disjoint_arraycopy = generate_disjoint_oop_copy(false, &entry,
3103 "oop_disjoint_arraycopy");
3104 StubRoutines::_oop_arraycopy = generate_conjoint_oop_copy(false, entry, &entry_oop_arraycopy,
3105 "oop_arraycopy");
3106
3107
3108 StubRoutines::_arrayof_jbyte_disjoint_arraycopy = generate_disjoint_byte_copy(true, &entry,
3109 "arrayof_jbyte_disjoint_arraycopy");
3110 StubRoutines::_arrayof_jbyte_arraycopy = generate_conjoint_byte_copy(true, entry, NULL,
3111 "arrayof_jbyte_arraycopy");
3112
3113 StubRoutines::_arrayof_jshort_disjoint_arraycopy = generate_disjoint_short_copy(true, &entry,
3114 "arrayof_jshort_disjoint_arraycopy");
3115 StubRoutines::_arrayof_jshort_arraycopy = generate_conjoint_short_copy(true, entry, NULL,
3116 "arrayof_jshort_arraycopy");
3117
3118 StubRoutines::_arrayof_jint_disjoint_arraycopy = generate_disjoint_int_copy(true, &entry,
3119 "arrayof_jint_disjoint_arraycopy");
3092 #ifdef _LP64 3120 #ifdef _LP64
3093 // since sizeof(jint) < sizeof(HeapWord), there's a different flavor: 3121 // since sizeof(jint) < sizeof(HeapWord), there's a different flavor:
3094 StubRoutines::_arrayof_jint_arraycopy = generate_conjoint_int_copy(true, "arrayof_jint_arraycopy"); 3122 StubRoutines::_arrayof_jint_arraycopy = generate_conjoint_int_copy(true, entry, NULL, "arrayof_jint_arraycopy");
3095 #else 3123 #else
3096 StubRoutines::_arrayof_jint_arraycopy = StubRoutines::_jint_arraycopy; 3124 StubRoutines::_arrayof_jint_arraycopy = StubRoutines::_jint_arraycopy;
3097 #endif 3125 #endif
3126
3127 StubRoutines::_arrayof_jlong_disjoint_arraycopy = generate_disjoint_long_copy(true, NULL,
3128 "arrayof_jlong_disjoint_arraycopy");
3129 StubRoutines::_arrayof_oop_disjoint_arraycopy = generate_disjoint_oop_copy(true, NULL,
3130 "arrayof_oop_disjoint_arraycopy");
3131
3098 StubRoutines::_arrayof_jlong_arraycopy = StubRoutines::_jlong_arraycopy; 3132 StubRoutines::_arrayof_jlong_arraycopy = StubRoutines::_jlong_arraycopy;
3099 StubRoutines::_arrayof_oop_arraycopy = StubRoutines::_oop_arraycopy; 3133 StubRoutines::_arrayof_oop_arraycopy = StubRoutines::_oop_arraycopy;
3100 3134
3101 StubRoutines::_checkcast_arraycopy = generate_checkcast_copy("checkcast_arraycopy"); 3135 StubRoutines::_checkcast_arraycopy = generate_checkcast_copy("checkcast_arraycopy", &entry_checkcast_arraycopy);
3102 StubRoutines::_unsafe_arraycopy = generate_unsafe_copy("unsafe_arraycopy"); 3136 StubRoutines::_unsafe_arraycopy = generate_unsafe_copy("unsafe_arraycopy",
3103 StubRoutines::_generic_arraycopy = generate_generic_copy("generic_arraycopy"); 3137 entry_jbyte_arraycopy,
3138 entry_jshort_arraycopy,
3139 entry_jint_arraycopy,
3140 entry_jlong_arraycopy);
3141 StubRoutines::_generic_arraycopy = generate_generic_copy("generic_arraycopy",
3142 entry_jbyte_arraycopy,
3143 entry_jshort_arraycopy,
3144 entry_jint_arraycopy,
3145 entry_oop_arraycopy,
3146 entry_jlong_arraycopy,
3147 entry_checkcast_arraycopy);
3104 3148
3105 StubRoutines::_jbyte_fill = generate_fill(T_BYTE, false, "jbyte_fill"); 3149 StubRoutines::_jbyte_fill = generate_fill(T_BYTE, false, "jbyte_fill");
3106 StubRoutines::_jshort_fill = generate_fill(T_SHORT, false, "jshort_fill"); 3150 StubRoutines::_jshort_fill = generate_fill(T_SHORT, false, "jshort_fill");
3107 StubRoutines::_jint_fill = generate_fill(T_INT, false, "jint_fill"); 3151 StubRoutines::_jint_fill = generate_fill(T_INT, false, "jint_fill");
3108 StubRoutines::_arrayof_jbyte_fill = generate_fill(T_BYTE, true, "arrayof_jbyte_fill"); 3152 StubRoutines::_arrayof_jbyte_fill = generate_fill(T_BYTE, true, "arrayof_jbyte_fill");
3222 } 3266 }
3223 } 3267 }
3224 3268
3225 }; // end class declaration 3269 }; // end class declaration
3226 3270
3227
3228 address StubGenerator::disjoint_byte_copy_entry = NULL;
3229 address StubGenerator::disjoint_short_copy_entry = NULL;
3230 address StubGenerator::disjoint_int_copy_entry = NULL;
3231 address StubGenerator::disjoint_long_copy_entry = NULL;
3232 address StubGenerator::disjoint_oop_copy_entry = NULL;
3233
3234 address StubGenerator::byte_copy_entry = NULL;
3235 address StubGenerator::short_copy_entry = NULL;
3236 address StubGenerator::int_copy_entry = NULL;
3237 address StubGenerator::long_copy_entry = NULL;
3238 address StubGenerator::oop_copy_entry = NULL;
3239
3240 address StubGenerator::checkcast_copy_entry = NULL;
3241
3242 void StubGenerator_generate(CodeBuffer* code, bool all) { 3271 void StubGenerator_generate(CodeBuffer* code, bool all) {
3243 StubGenerator g(code, all); 3272 StubGenerator g(code, all);
3244 } 3273 }