Print this page


Split Close
Expand all
Collapse all
          --- old/src/cpu/sparc/vm/stubGenerator_sparc.cpp
          +++ new/src/cpu/sparc/vm/stubGenerator_sparc.cpp
   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    3   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4    4   *
   5    5   * This code is free software; you can redistribute it and/or modify it
   6    6   * under the terms of the GNU General Public License version 2 only, as
   7    7   * published by the Free Software Foundation.
   8    8   *
   9    9   * This code is distributed in the hope that it will be useful, but WITHOUT
  10   10   * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11   11   * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12   12   * version 2 for more details (a copy is included in the LICENSE file that
↓ open down ↓ 948 lines elided ↑ open up ↑
 961  961    address generate_verify_oop_subroutine() {
 962  962      StubCodeMark mark(this, "StubRoutines", "verify_oop_stub");
 963  963  
 964  964      address start = __ pc();
 965  965  
 966  966      __ verify_oop_subroutine();
 967  967  
 968  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  973    // Verify that a register contains clean 32-bits positive value
 987  974    // (high 32-bits are 0) so it could be used in 64-bits shifts (sllx, srax).
 988  975    //
 989  976    //  Input:
 990  977    //    Rint  -  32-bits value
 991  978    //    Rtmp  -  scratch
 992  979    //
 993  980    void assert_clean_int(Register Rint, Register Rtmp) {
↓ open down ↓ 282 lines elided ↑ open up ↑
1276 1263  
1277 1264    //
1278 1265    //  Generate stub for disjoint byte copy.  If "aligned" is true, the
1279 1266    //  "from" and "to" addresses are assumed to be heapword aligned.
1280 1267    //
1281 1268    // Arguments for generated stub:
1282 1269    //      from:  O0
1283 1270    //      to:    O1
1284 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 1274      __ align(CodeEntryAlignment);
1288 1275      StubCodeMark mark(this, "StubRoutines", name);
1289 1276      address start = __ pc();
1290 1277  
1291 1278      Label L_skip_alignment, L_align;
1292 1279      Label L_copy_byte, L_copy_byte_loop, L_exit;
1293 1280  
1294 1281      const Register from      = O0;   // source array address
1295 1282      const Register to        = O1;   // destination array address
1296 1283      const Register count     = O2;   // elements count
1297 1284      const Register offset    = O5;   // offset from start of arrays
1298 1285      // O3, O4, G3, G4 are used as temp registers
1299 1286  
1300 1287      assert_clean_int(count, O3);     // Make sure 'count' is clean int.
1301 1288  
1302      -    if (!aligned)  disjoint_byte_copy_entry = __ pc();
1303      -    // caller can pass a 64-bit byte count here (from Unsafe.copyMemory)
1304      -    if (!aligned)  BLOCK_COMMENT("Entry:");
     1289 +    if (entry != NULL) {
     1290 +      *entry = __ pc();
     1291 +      // caller can pass a 64-bit byte count here (from Unsafe.copyMemory)
     1292 +      BLOCK_COMMENT("Entry:");
     1293 +    }
1305 1294  
1306 1295      // for short arrays, just do single element copy
1307 1296      __ cmp(count, 23); // 16 + 7
1308 1297      __ brx(Assembler::less, false, Assembler::pn, L_copy_byte);
1309 1298      __ delayed()->mov(G0, offset);
1310 1299  
1311 1300      if (aligned) {
1312 1301        // 'aligned' == true when it is known statically during compilation
1313 1302        // of this arraycopy call site that both 'from' and 'to' addresses
1314 1303        // are HeapWordSize aligned (see LibraryCallKit::basictype2arraycopy()).
↓ open down ↓ 69 lines elided ↑ open up ↑
1384 1373  
1385 1374    //
1386 1375    //  Generate stub for conjoint byte copy.  If "aligned" is true, the
1387 1376    //  "from" and "to" addresses are assumed to be heapword aligned.
1388 1377    //
1389 1378    // Arguments for generated stub:
1390 1379    //      from:  O0
1391 1380    //      to:    O1
1392 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 1385      // Do reverse copy.
1396 1386  
1397 1387      __ align(CodeEntryAlignment);
1398 1388      StubCodeMark mark(this, "StubRoutines", name);
1399 1389      address start = __ pc();
1400      -    address nooverlap_target = aligned ?
1401      -        StubRoutines::arrayof_jbyte_disjoint_arraycopy() :
1402      -        disjoint_byte_copy_entry;
1403 1390  
1404 1391      Label L_skip_alignment, L_align, L_aligned_copy;
1405 1392      Label L_copy_byte, L_copy_byte_loop, L_exit;
1406 1393  
1407 1394      const Register from      = O0;   // source array address
1408 1395      const Register to        = O1;   // destination array address
1409 1396      const Register count     = O2;   // elements count
1410 1397      const Register end_from  = from; // source array end address
1411 1398      const Register end_to    = to;   // destination array end address
1412 1399  
1413 1400      assert_clean_int(count, O3);     // Make sure 'count' is clean int.
1414 1401  
1415      -    if (!aligned)  byte_copy_entry = __ pc();
1416      -    // caller can pass a 64-bit byte count here (from Unsafe.copyMemory)
1417      -    if (!aligned)  BLOCK_COMMENT("Entry:");
     1402 +    if (entry != NULL) {
     1403 +      *entry = __ pc();
     1404 +      // caller can pass a 64-bit byte count here (from Unsafe.copyMemory)
     1405 +      BLOCK_COMMENT("Entry:");
     1406 +    }
1418 1407  
1419 1408      array_overlap_test(nooverlap_target, 0);
1420 1409  
1421 1410      __ add(to, count, end_to);       // offset after last copied element
1422 1411  
1423 1412      // for short arrays, just do single element copy
1424 1413      __ cmp(count, 23); // 16 + 7
1425 1414      __ brx(Assembler::less, false, Assembler::pn, L_copy_byte);
1426 1415      __ delayed()->add(from, count, end_from);
1427 1416  
↓ open down ↓ 69 lines elided ↑ open up ↑
1497 1486  
1498 1487    //
1499 1488    //  Generate stub for disjoint short copy.  If "aligned" is true, the
1500 1489    //  "from" and "to" addresses are assumed to be heapword aligned.
1501 1490    //
1502 1491    // Arguments for generated stub:
1503 1492    //      from:  O0
1504 1493    //      to:    O1
1505 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 1497      __ align(CodeEntryAlignment);
1509 1498      StubCodeMark mark(this, "StubRoutines", name);
1510 1499      address start = __ pc();
1511 1500  
1512 1501      Label L_skip_alignment, L_skip_alignment2;
1513 1502      Label L_copy_2_bytes, L_copy_2_bytes_loop, L_exit;
1514 1503  
1515 1504      const Register from      = O0;   // source array address
1516 1505      const Register to        = O1;   // destination array address
1517 1506      const Register count     = O2;   // elements count
1518 1507      const Register offset    = O5;   // offset from start of arrays
1519 1508      // O3, O4, G3, G4 are used as temp registers
1520 1509  
1521 1510      assert_clean_int(count, O3);     // Make sure 'count' is clean int.
1522 1511  
1523      -    if (!aligned)  disjoint_short_copy_entry = __ pc();
1524      -    // caller can pass a 64-bit byte count here (from Unsafe.copyMemory)
1525      -    if (!aligned)  BLOCK_COMMENT("Entry:");
     1512 +    if (entry != NULL) {
     1513 +      *entry = __ pc();
     1514 +      // caller can pass a 64-bit byte count here (from Unsafe.copyMemory)
     1515 +      BLOCK_COMMENT("Entry:");
     1516 +    }
1526 1517  
1527 1518      // for short arrays, just do single element copy
1528 1519      __ cmp(count, 11); // 8 + 3  (22 bytes)
1529 1520      __ brx(Assembler::less, false, Assembler::pn, L_copy_2_bytes);
1530 1521      __ delayed()->mov(G0, offset);
1531 1522  
1532 1523      if (aligned) {
1533 1524        // 'aligned' == true when it is known statically during compilation
1534 1525        // of this arraycopy call site that both 'from' and 'to' addresses
1535 1526        // are HeapWordSize aligned (see LibraryCallKit::basictype2arraycopy()).
↓ open down ↓ 299 lines elided ↑ open up ↑
1835 1826  
1836 1827    //
1837 1828    //  Generate stub for conjoint short copy.  If "aligned" is true, the
1838 1829    //  "from" and "to" addresses are assumed to be heapword aligned.
1839 1830    //
1840 1831    // Arguments for generated stub:
1841 1832    //      from:  O0
1842 1833    //      to:    O1
1843 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 1838      // Do reverse copy.
1847 1839  
1848 1840      __ align(CodeEntryAlignment);
1849 1841      StubCodeMark mark(this, "StubRoutines", name);
1850 1842      address start = __ pc();
1851      -    address nooverlap_target = aligned ?
1852      -        StubRoutines::arrayof_jshort_disjoint_arraycopy() :
1853      -        disjoint_short_copy_entry;
1854 1843  
1855 1844      Label L_skip_alignment, L_skip_alignment2, L_aligned_copy;
1856 1845      Label L_copy_2_bytes, L_copy_2_bytes_loop, L_exit;
1857 1846  
1858 1847      const Register from      = O0;   // source array address
1859 1848      const Register to        = O1;   // destination array address
1860 1849      const Register count     = O2;   // elements count
1861 1850      const Register end_from  = from; // source array end address
1862 1851      const Register end_to    = to;   // destination array end address
1863 1852  
1864 1853      const Register byte_count = O3;  // bytes count to copy
1865 1854  
1866 1855      assert_clean_int(count, O3);     // Make sure 'count' is clean int.
1867 1856  
1868      -    if (!aligned)  short_copy_entry = __ pc();
1869      -    // caller can pass a 64-bit byte count here (from Unsafe.copyMemory)
1870      -    if (!aligned)  BLOCK_COMMENT("Entry:");
     1857 +    if (entry != NULL) {
     1858 +      *entry = __ pc();
     1859 +      // caller can pass a 64-bit byte count here (from Unsafe.copyMemory)
     1860 +      BLOCK_COMMENT("Entry:");
     1861 +    }
1871 1862  
1872 1863      array_overlap_test(nooverlap_target, 1);
1873 1864  
1874 1865      __ sllx(count, LogBytesPerShort, byte_count);
1875 1866      __ add(to, byte_count, end_to);  // offset after last copied element
1876 1867  
1877 1868      // for short arrays, just do single element copy
1878 1869      __ cmp(count, 11); // 8 + 3  (22 bytes)
1879 1870      __ brx(Assembler::less, false, Assembler::pn, L_copy_2_bytes);
1880 1871      __ delayed()->add(from, byte_count, end_from);
↓ open down ↓ 184 lines elided ↑ open up ↑
2065 2056  
2066 2057    //
2067 2058    //  Generate stub for disjoint int copy.  If "aligned" is true, the
2068 2059    //  "from" and "to" addresses are assumed to be heapword aligned.
2069 2060    //
2070 2061    // Arguments for generated stub:
2071 2062    //      from:  O0
2072 2063    //      to:    O1
2073 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 2067      __ align(CodeEntryAlignment);
2077 2068      StubCodeMark mark(this, "StubRoutines", name);
2078 2069      address start = __ pc();
2079 2070  
2080 2071      const Register count = O2;
2081 2072      assert_clean_int(count, O3);     // Make sure 'count' is clean int.
2082 2073  
2083      -    if (!aligned)  disjoint_int_copy_entry = __ pc();
2084      -    // caller can pass a 64-bit byte count here (from Unsafe.copyMemory)
2085      -    if (!aligned)  BLOCK_COMMENT("Entry:");
     2074 +    if (entry != NULL) {
     2075 +      *entry = __ pc();
     2076 +      // caller can pass a 64-bit byte count here (from Unsafe.copyMemory)
     2077 +      BLOCK_COMMENT("Entry:");
     2078 +    }
2086 2079  
2087 2080      generate_disjoint_int_copy_core(aligned);
2088 2081  
2089 2082      // O3, O4 are used as temp registers
2090 2083      inc_counter_np(SharedRuntime::_jint_array_copy_ctr, O3, O4);
2091 2084      __ retl();
2092 2085      __ delayed()->mov(G0, O0); // return 0
2093 2086      return start;
2094 2087    }
2095 2088  
↓ open down ↓ 101 lines elided ↑ open up ↑
2197 2190  
2198 2191    //
2199 2192    //  Generate stub for conjoint int copy.  If "aligned" is true, the
2200 2193    //  "from" and "to" addresses are assumed to be heapword aligned.
2201 2194    //
2202 2195    // Arguments for generated stub:
2203 2196    //      from:  O0
2204 2197    //      to:    O1
2205 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 2202      __ align(CodeEntryAlignment);
2209 2203      StubCodeMark mark(this, "StubRoutines", name);
2210 2204      address start = __ pc();
2211 2205  
2212      -    address nooverlap_target = aligned ?
2213      -        StubRoutines::arrayof_jint_disjoint_arraycopy() :
2214      -        disjoint_int_copy_entry;
2215      -
2216 2206      assert_clean_int(O2, O3);     // Make sure 'count' is clean int.
2217 2207  
2218      -    if (!aligned)  int_copy_entry = __ pc();
2219      -    // caller can pass a 64-bit byte count here (from Unsafe.copyMemory)
2220      -    if (!aligned)  BLOCK_COMMENT("Entry:");
     2208 +    if (entry != NULL) {
     2209 +      *entry = __ pc();
     2210 +      // caller can pass a 64-bit byte count here (from Unsafe.copyMemory)
     2211 +      BLOCK_COMMENT("Entry:");
     2212 +    }
2221 2213  
2222 2214      array_overlap_test(nooverlap_target, 2);
2223 2215  
2224 2216      generate_conjoint_int_copy_core(aligned);
2225 2217  
2226 2218      // O3, O4 are used as temp registers
2227 2219      inc_counter_np(SharedRuntime::_jint_array_copy_ctr, O3, O4);
2228 2220      __ retl();
2229 2221      __ delayed()->mov(G0, O0); // return 0
2230 2222      return start;
↓ open down ↓ 98 lines elided ↑ open up ↑
2329 2321    //
2330 2322    //  Generate stub for disjoint long copy.
2331 2323    //  "aligned" is ignored, because we must make the stronger
2332 2324    //  assumption that both addresses are always 64-bit aligned.
2333 2325    //
2334 2326    // Arguments for generated stub:
2335 2327    //      from:  O0
2336 2328    //      to:    O1
2337 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 2332      __ align(CodeEntryAlignment);
2341 2333      StubCodeMark mark(this, "StubRoutines", name);
2342 2334      address start = __ pc();
2343 2335  
2344 2336      assert_clean_int(O2, O3);     // Make sure 'count' is clean int.
2345 2337  
2346      -    if (!aligned)  disjoint_long_copy_entry = __ pc();
2347      -    // caller can pass a 64-bit byte count here (from Unsafe.copyMemory)
2348      -    if (!aligned)  BLOCK_COMMENT("Entry:");
     2338 +    if (entry != NULL) {
     2339 +      *entry = __ pc();
     2340 +      // caller can pass a 64-bit byte count here (from Unsafe.copyMemory)
     2341 +      BLOCK_COMMENT("Entry:");
     2342 +    }
2349 2343  
2350 2344      generate_disjoint_long_copy_core(aligned);
2351 2345  
2352 2346      // O3, O4 are used as temp registers
2353 2347      inc_counter_np(SharedRuntime::_jlong_array_copy_ctr, O3, O4);
2354 2348      __ retl();
2355 2349      __ delayed()->mov(G0, O0); // return 0
2356 2350      return start;
2357 2351    }
2358 2352  
↓ open down ↓ 40 lines elided ↑ open up ↑
2399 2393  
2400 2394    //  Generate stub for conjoint long copy.
2401 2395    //  "aligned" is ignored, because we must make the stronger
2402 2396    //  assumption that both addresses are always 64-bit aligned.
2403 2397    //
2404 2398    // Arguments for generated stub:
2405 2399    //      from:  O0
2406 2400    //      to:    O1
2407 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 2405      __ align(CodeEntryAlignment);
2411 2406      StubCodeMark mark(this, "StubRoutines", name);
2412 2407      address start = __ pc();
2413 2408  
2414 2409      assert(!aligned, "usage");
2415      -    address nooverlap_target = disjoint_long_copy_entry;
2416 2410  
2417 2411      assert_clean_int(O2, O3);     // Make sure 'count' is clean int.
2418 2412  
2419      -    if (!aligned)  long_copy_entry = __ pc();
2420      -    // caller can pass a 64-bit byte count here (from Unsafe.copyMemory)
2421      -    if (!aligned)  BLOCK_COMMENT("Entry:");
     2413 +    if (entry != NULL) {
     2414 +      *entry = __ pc();
     2415 +      // caller can pass a 64-bit byte count here (from Unsafe.copyMemory)
     2416 +      BLOCK_COMMENT("Entry:");
     2417 +    }
2422 2418  
2423 2419      array_overlap_test(nooverlap_target, 3);
2424 2420  
2425 2421      generate_conjoint_long_copy_core(aligned);
2426 2422  
2427 2423      // O3, O4 are used as temp registers
2428 2424      inc_counter_np(SharedRuntime::_jlong_array_copy_ctr, O3, O4);
2429 2425      __ retl();
2430 2426      __ delayed()->mov(G0, O0); // return 0
2431 2427      return start;
2432 2428    }
2433 2429  
2434 2430    //  Generate stub for disjoint oop copy.  If "aligned" is true, the
2435 2431    //  "from" and "to" addresses are assumed to be heapword aligned.
2436 2432    //
2437 2433    // Arguments for generated stub:
2438 2434    //      from:  O0
2439 2435    //      to:    O1
2440 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 2440      const Register from  = O0;  // source array address
2445 2441      const Register to    = O1;  // destination array address
2446 2442      const Register count = O2;  // elements count
2447 2443  
2448 2444      __ align(CodeEntryAlignment);
2449 2445      StubCodeMark mark(this, "StubRoutines", name);
2450 2446      address start = __ pc();
2451 2447  
2452 2448      assert_clean_int(count, O3);     // Make sure 'count' is clean int.
2453 2449  
2454      -    if (!aligned)  disjoint_oop_copy_entry = __ pc();
2455      -    // caller can pass a 64-bit byte count here
2456      -    if (!aligned)  BLOCK_COMMENT("Entry:");
     2450 +    if (entry != NULL) {
     2451 +      *entry = __ pc();
     2452 +      // caller can pass a 64-bit byte count here
     2453 +      BLOCK_COMMENT("Entry:");
     2454 +    }
2457 2455  
2458 2456      // save arguments for barrier generation
2459 2457      __ mov(to, G1);
2460 2458      __ mov(count, G5);
2461 2459      gen_write_ref_array_pre_barrier(G1, G5);
2462 2460    #ifdef _LP64
2463 2461      assert_clean_int(count, O3);     // Make sure 'count' is clean int.
2464 2462      if (UseCompressedOops) {
2465 2463        generate_disjoint_int_copy_core(aligned);
2466 2464      } else {
↓ open down ↓ 13 lines elided ↑ open up ↑
2480 2478    }
2481 2479  
2482 2480    //  Generate stub for conjoint oop copy.  If "aligned" is true, the
2483 2481    //  "from" and "to" addresses are assumed to be heapword aligned.
2484 2482    //
2485 2483    // Arguments for generated stub:
2486 2484    //      from:  O0
2487 2485    //      to:    O1
2488 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 2491      const Register from  = O0;  // source array address
2493 2492      const Register to    = O1;  // destination array address
2494 2493      const Register count = O2;  // elements count
2495 2494  
2496 2495      __ align(CodeEntryAlignment);
2497 2496      StubCodeMark mark(this, "StubRoutines", name);
2498 2497      address start = __ pc();
2499 2498  
2500 2499      assert_clean_int(count, O3);     // Make sure 'count' is clean int.
2501 2500  
2502      -    if (!aligned)  oop_copy_entry = __ pc();
2503      -    // caller can pass a 64-bit byte count here
2504      -    if (!aligned)  BLOCK_COMMENT("Entry:");
     2501 +    if (entry != NULL) {
     2502 +      *entry = __ pc();
     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 2509      // save arguments for barrier generation
2507 2510      __ mov(to, G1);
2508 2511      __ mov(count, G5);
2509      -
2510 2512      gen_write_ref_array_pre_barrier(G1, G5);
2511 2513  
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      -
2518 2514    #ifdef _LP64
2519 2515      if (UseCompressedOops) {
2520 2516        generate_conjoint_int_copy_core(aligned);
2521 2517      } else {
2522 2518        generate_conjoint_long_copy_core(aligned);
2523 2519      }
2524 2520    #else
2525 2521      generate_conjoint_int_copy_core(aligned);
2526 2522    #endif
2527 2523  
↓ open down ↓ 47 lines elided ↑ open up ↑
2575 2571    //  Generate stub for checked oop copy.
2576 2572    //
2577 2573    // Arguments for generated stub:
2578 2574    //      from:  O0
2579 2575    //      to:    O1
2580 2576    //      count: O2 treated as signed
2581 2577    //      ckoff: O3 (super_check_offset)
2582 2578    //      ckval: O4 (super_klass)
2583 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 2583      const Register O0_from   = O0;      // source array address
2588 2584      const Register O1_to     = O1;      // destination array address
2589 2585      const Register O2_count  = O2;      // elements count
2590 2586      const Register O3_ckoff  = O3;      // super_check_offset
2591 2587      const Register O4_ckval  = O4;      // super_klass
2592 2588  
2593 2589      const Register O5_offset = O5;      // loop var, with stride wordSize
2594 2590      const Register G1_remain = G1;      // loop var, with stride -1
2595 2591      const Register G3_oop    = G3;      // actual oop copied
2596 2592      const Register G4_klass  = G4;      // oop._klass
2597 2593      const Register G5_super  = G5;      // oop._klass._primary_supers[ckval]
2598 2594  
2599 2595      __ align(CodeEntryAlignment);
2600 2596      StubCodeMark mark(this, "StubRoutines", name);
2601 2597      address start = __ pc();
2602 2598  
2603      -    gen_write_ref_array_pre_barrier(O1, O2);
2604      -
2605 2599  #ifdef ASSERT
2606 2600      // We sometimes save a frame (see generate_type_check below).
2607 2601      // If this will cause trouble, let's fail now instead of later.
2608 2602      __ save_frame(0);
2609 2603      __ restore();
2610 2604  #endif
2611 2605  
2612 2606      assert_clean_int(O2_count, G1);     // Make sure 'count' is clean int.
2613 2607  
2614 2608  #ifdef ASSERT
↓ open down ↓ 3 lines elided ↑ open up ↑
2618 2612        __ mov(O3, G1);           // spill: overlap test smashes O3
2619 2613        __ mov(O4, G4);           // spill: overlap test smashes O4
2620 2614        array_overlap_test(L, LogBytesPerHeapOop);
2621 2615        __ stop("checkcast_copy within a single array");
2622 2616        __ bind(L);
2623 2617        __ mov(G1, O3);
2624 2618        __ mov(G4, O4);
2625 2619      }
2626 2620  #endif //ASSERT
2627 2621  
2628      -    checkcast_copy_entry = __ pc();
2629      -    // caller can pass a 64-bit byte count here (from generic stub)
2630      -    BLOCK_COMMENT("Entry:");
     2622 +    if (entry != NULL) {
     2623 +      *entry = __ pc();
     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 2630      Label load_element, store_element, do_card_marks, fail, done;
2633 2631      __ addcc(O2_count, 0, G1_remain);   // initialize loop index, and test it
2634 2632      __ brx(Assembler::notZero, false, Assembler::pt, load_element);
2635 2633      __ delayed()->mov(G0, O5_offset);   // offset from start of arrays
2636 2634  
2637 2635      // Empty array:  Nothing to do.
2638 2636      inc_counter_np(SharedRuntime::_checkcast_array_copy_ctr, O3, O4);
2639 2637      __ retl();
2640 2638      __ delayed()->set(0, O0);           // return 0 on (trivial) success
↓ open down ↓ 52 lines elided ↑ open up ↑
2693 2691    //  size_t argument instead of an element count.
2694 2692    //
2695 2693    // Arguments for generated stub:
2696 2694    //      from:  O0
2697 2695    //      to:    O1
2698 2696    //      count: O2 byte count, treated as ssize_t, can be zero
2699 2697    //
2700 2698    // Examines the alignment of the operands and dispatches
2701 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 2707      const Register O0_from   = O0;      // source array address
2706 2708      const Register O1_to     = O1;      // destination array address
2707 2709      const Register O2_count  = O2;      // elements count
2708 2710  
2709 2711      const Register G1_bits   = G1;      // test copy of low bits
2710 2712  
2711 2713      __ align(CodeEntryAlignment);
2712 2714      StubCodeMark mark(this, "StubRoutines", name);
2713 2715      address start = __ pc();
↓ open down ↓ 75 lines elided ↑ open up ↑
2789 2791    //    O0    -  src oop
2790 2792    //    O1    -  src_pos
2791 2793    //    O2    -  dst oop
2792 2794    //    O3    -  dst_pos
2793 2795    //    O4    -  element count
2794 2796    //
2795 2797    //  Output:
2796 2798    //    O0 ==  0  -  success
2797 2799    //    O0 == -1  -  need to call System.arraycopy
2798 2800    //
2799      -  address generate_generic_copy(const char *name) {
2800      -
     2801 +  address generate_generic_copy(const char *name,
     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 2808      Label L_failed, L_objArray;
2802 2809  
2803 2810      // Input registers
2804 2811      const Register src      = O0;  // source array oop
2805 2812      const Register src_pos  = O1;  // source position
2806 2813      const Register dst      = O2;  // destination array oop
2807 2814      const Register dst_pos  = O3;  // destination position
2808 2815      const Register length   = O4;  // elements count
2809 2816  
2810 2817      // registers used as temp
↓ open down ↓ 152 lines elided ↑ open up ↑
2963 2970      // since they are the same as 'src', 'src_pos', 'dst'.
2964 2971  
2965 2972      BLOCK_COMMENT("scale indexes to element size");
2966 2973      __ sll_ptr(src_pos, G3_elsize, src_pos);
2967 2974      __ sll_ptr(dst_pos, G3_elsize, dst_pos);
2968 2975      __ add(src, src_pos, from);       // src_addr
2969 2976      __ add(dst, dst_pos, to);         // dst_addr
2970 2977  
2971 2978      BLOCK_COMMENT("choose copy loop based on element size");
2972 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 2981      __ delayed()->signx(length, count); // length
2975 2982  
2976 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 2985      __ delayed()->signx(length, count); // length
2979 2986  
2980 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 2989      __ delayed()->signx(length, count); // length
2983 2990  #ifdef ASSERT
2984 2991      { Label L;
2985 2992        __ cmp(G3_elsize, LogBytesPerLong);
2986 2993        __ br(Assembler::equal, false, Assembler::pt, L);
2987 2994        __ delayed()->nop();
2988 2995        __ stop("must be long copy, but elsize is wrong");
2989 2996        __ bind(L);
2990 2997      }
2991 2998  #endif
2992      -    __ br(Assembler::always,false,Assembler::pt,StubRoutines::_jlong_arraycopy);
     2999 +    __ br(Assembler::always, false, Assembler::pt, entry_jlong_arraycopy);
2993 3000      __ delayed()->signx(length, count); // length
2994 3001  
2995 3002      // objArrayKlass
2996 3003    __ BIND(L_objArray);
2997 3004      // live at this point:  G3_src_klass, G4_dst_klass, src[_pos], dst[_pos], length
2998 3005  
2999 3006      Label L_plain_copy, L_checkcast_copy;
3000 3007      //  test array classes for subtyping
3001 3008      __ cmp(G3_src_klass, G4_dst_klass);         // usual case is exact equality
3002 3009      __ brx(Assembler::notEqual, true, Assembler::pn, L_checkcast_copy);
↓ open down ↓ 3 lines elided ↑ open up ↑
3006 3013      arraycopy_range_checks(src, src_pos, dst, dst_pos, length,
3007 3014                             O5_temp, G5_lh, L_failed);
3008 3015  
3009 3016      __ add(src, arrayOopDesc::base_offset_in_bytes(T_OBJECT), src); //src offset
3010 3017      __ add(dst, arrayOopDesc::base_offset_in_bytes(T_OBJECT), dst); //dst offset
3011 3018      __ sll_ptr(src_pos, LogBytesPerHeapOop, src_pos);
3012 3019      __ sll_ptr(dst_pos, LogBytesPerHeapOop, dst_pos);
3013 3020      __ add(src, src_pos, from);       // src_addr
3014 3021      __ add(dst, dst_pos, to);         // dst_addr
3015 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 3024      __ delayed()->signx(length, count); // length
3018 3025  
3019 3026    __ BIND(L_checkcast_copy);
3020 3027      // live at this point:  G3_src_klass, G4_dst_klass
3021 3028      {
3022 3029        // Before looking at dst.length, make sure dst is also an objArray.
3023 3030        // lduw(G4_dst_klass, lh_offset, O5_temp); // hoisted to delay slot
3024 3031        __ cmp(G5_lh,                    O5_temp);
3025 3032        __ br(Assembler::notEqual, false, Assembler::pn, L_failed);
3026 3033  
↓ open down ↓ 23 lines elided ↑ open up ↑
3050 3057                            O5_temp, L_plain_copy);
3051 3058  
3052 3059        // Fetch destination element klass from the objArrayKlass header.
3053 3060        int ek_offset = (klassOopDesc::header_size() * HeapWordSize +
3054 3061                         objArrayKlass::element_klass_offset_in_bytes());
3055 3062  
3056 3063        // the checkcast_copy loop needs two extra arguments:
3057 3064        __ ld_ptr(G4_dst_klass, ek_offset, O4);   // dest elem klass
3058 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 3068        __ delayed()->lduw(O4, sco_offset, O3);
3062 3069      }
3063 3070  
3064 3071    __ BIND(L_failed);
3065 3072      __ retl();
3066 3073      __ delayed()->sub(G0, 1, O0); // return -1
3067 3074      return start;
3068 3075    }
3069 3076  
3070 3077    void generate_arraycopy_stubs() {
     3078 +    address entry;
     3079 +    address entry_jbyte_arraycopy;
     3080 +    address entry_jshort_arraycopy;
     3081 +    address entry_jint_arraycopy;
     3082 +    address entry_oop_arraycopy;
     3083 +    address entry_jlong_arraycopy;
     3084 +    address entry_checkcast_arraycopy;
     3085 +
     3086 +    StubRoutines::_jbyte_disjoint_arraycopy  = generate_disjoint_byte_copy(false, &entry,
     3087 +                                                                           "jbyte_disjoint_arraycopy");
     3088 +    StubRoutines::_jbyte_arraycopy           = generate_conjoint_byte_copy(false, entry, &entry_jbyte_arraycopy,
     3089 +                                                                           "jbyte_arraycopy");
     3090 +    StubRoutines::_jshort_disjoint_arraycopy = generate_disjoint_short_copy(false, &entry,
     3091 +                                                                            "jshort_disjoint_arraycopy");
     3092 +    StubRoutines::_jshort_arraycopy          = generate_conjoint_short_copy(false, entry, &entry_jshort_arraycopy,
     3093 +                                                                            "jshort_arraycopy");
     3094 +    StubRoutines::_jint_disjoint_arraycopy   = generate_disjoint_int_copy(false, &entry,
     3095 +                                                                          "jint_disjoint_arraycopy");
     3096 +    StubRoutines::_jint_arraycopy            = generate_conjoint_int_copy(false, entry, &entry_jint_arraycopy,
     3097 +                                                                          "jint_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");
3071 3117  
3072      -    // Note:  the disjoint stubs must be generated first, some of
3073      -    //        the conjoint stubs use them.
3074      -    StubRoutines::_jbyte_disjoint_arraycopy  = generate_disjoint_byte_copy(false, "jbyte_disjoint_arraycopy");
3075      -    StubRoutines::_jshort_disjoint_arraycopy = generate_disjoint_short_copy(false, "jshort_disjoint_arraycopy");
3076      -    StubRoutines::_jint_disjoint_arraycopy   = generate_disjoint_int_copy(false, "jint_disjoint_arraycopy");
3077      -    StubRoutines::_jlong_disjoint_arraycopy  = generate_disjoint_long_copy(false, "jlong_disjoint_arraycopy");
3078      -    StubRoutines::_oop_disjoint_arraycopy    = generate_disjoint_oop_copy(false, "oop_disjoint_arraycopy");
3079      -    StubRoutines::_arrayof_jbyte_disjoint_arraycopy  = generate_disjoint_byte_copy(true, "arrayof_jbyte_disjoint_arraycopy");
3080      -    StubRoutines::_arrayof_jshort_disjoint_arraycopy = generate_disjoint_short_copy(true, "arrayof_jshort_disjoint_arraycopy");
3081      -    StubRoutines::_arrayof_jint_disjoint_arraycopy   = generate_disjoint_int_copy(true, "arrayof_jint_disjoint_arraycopy");
3082      -    StubRoutines::_arrayof_jlong_disjoint_arraycopy  = generate_disjoint_long_copy(true, "arrayof_jlong_disjoint_arraycopy");
3083      -    StubRoutines::_arrayof_oop_disjoint_arraycopy    =  generate_disjoint_oop_copy(true, "arrayof_oop_disjoint_arraycopy");
3084      -
3085      -    StubRoutines::_jbyte_arraycopy  = generate_conjoint_byte_copy(false, "jbyte_arraycopy");
3086      -    StubRoutines::_jshort_arraycopy = generate_conjoint_short_copy(false, "jshort_arraycopy");
3087      -    StubRoutines::_jint_arraycopy   = generate_conjoint_int_copy(false, "jint_arraycopy");
3088      -    StubRoutines::_jlong_arraycopy  = generate_conjoint_long_copy(false, "jlong_arraycopy");
3089      -    StubRoutines::_oop_arraycopy    = generate_conjoint_oop_copy(false, "oop_arraycopy");
3090      -    StubRoutines::_arrayof_jbyte_arraycopy    = generate_conjoint_byte_copy(true, "arrayof_jbyte_arraycopy");
3091      -    StubRoutines::_arrayof_jshort_arraycopy   = generate_conjoint_short_copy(true, "arrayof_jshort_arraycopy");
     3118 +    StubRoutines::_arrayof_jint_disjoint_arraycopy   = generate_disjoint_int_copy(true, &entry,
     3119 +                                                                                  "arrayof_jint_disjoint_arraycopy");
3092 3120  #ifdef _LP64
3093 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 3123    #else
3096 3124      StubRoutines::_arrayof_jint_arraycopy     = StubRoutines::_jint_arraycopy;
3097 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 3132      StubRoutines::_arrayof_jlong_arraycopy    = StubRoutines::_jlong_arraycopy;
3099 3133      StubRoutines::_arrayof_oop_arraycopy      = StubRoutines::_oop_arraycopy;
3100 3134  
3101      -    StubRoutines::_checkcast_arraycopy = generate_checkcast_copy("checkcast_arraycopy");
3102      -    StubRoutines::_unsafe_arraycopy    = generate_unsafe_copy("unsafe_arraycopy");
3103      -    StubRoutines::_generic_arraycopy   = generate_generic_copy("generic_arraycopy");
     3135 +    StubRoutines::_checkcast_arraycopy = generate_checkcast_copy("checkcast_arraycopy", &entry_checkcast_arraycopy);
     3136 +    StubRoutines::_unsafe_arraycopy    = generate_unsafe_copy("unsafe_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 3149      StubRoutines::_jbyte_fill = generate_fill(T_BYTE, false, "jbyte_fill");
3106 3150      StubRoutines::_jshort_fill = generate_fill(T_SHORT, false, "jshort_fill");
3107 3151      StubRoutines::_jint_fill = generate_fill(T_INT, false, "jint_fill");
3108 3152      StubRoutines::_arrayof_jbyte_fill = generate_fill(T_BYTE, true, "arrayof_jbyte_fill");
3109 3153      StubRoutines::_arrayof_jshort_fill = generate_fill(T_SHORT, true, "arrayof_jshort_fill");
3110 3154      StubRoutines::_arrayof_jint_fill = generate_fill(T_INT, true, "arrayof_jint_fill");
3111 3155    }
3112 3156  
3113 3157    void generate_initial() {
↓ open down ↓ 103 lines elided ↑ open up ↑
3217 3261        }
3218 3262      } else {
3219 3263        while ((intptr_t)(__ pc()) % icache_half_line_size != 0) {
3220 3264          __ nop();
3221 3265        }
3222 3266      }
3223 3267    }
3224 3268  
3225 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 3271  void StubGenerator_generate(CodeBuffer* code, bool all) {
3243 3272    StubGenerator g(code, all);
3244 3273  }
    
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX