7020521: arraycopy stubs place prebarriers incorrectly

Tue, 22 Feb 2011 15:25:02 -0800

author
iveresov
date
Tue, 22 Feb 2011 15:25:02 -0800
changeset 2595
d89a22843c62
parent 2569
6bbaedb03534
child 2596
d5a078cf7f39

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

src/cpu/sparc/vm/stubGenerator_sparc.cpp file | annotate | diff | comparison | revisions
src/cpu/x86/vm/stubGenerator_x86_32.cpp file | annotate | diff | comparison | revisions
src/cpu/x86/vm/stubGenerator_x86_64.cpp file | annotate | diff | comparison | revisions
     1.1 --- a/src/cpu/sparc/vm/stubGenerator_sparc.cpp	Wed Feb 09 15:02:23 2011 -0800
     1.2 +++ b/src/cpu/sparc/vm/stubGenerator_sparc.cpp	Tue Feb 22 15:25:02 2011 -0800
     1.3 @@ -1,5 +1,5 @@
     1.4  /*
     1.5 - * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
     1.6 + * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
     1.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     1.8   *
     1.9   * This code is free software; you can redistribute it and/or modify it
    1.10 @@ -968,19 +968,6 @@
    1.11      return start;
    1.12    }
    1.13  
    1.14 -  static address disjoint_byte_copy_entry;
    1.15 -  static address disjoint_short_copy_entry;
    1.16 -  static address disjoint_int_copy_entry;
    1.17 -  static address disjoint_long_copy_entry;
    1.18 -  static address disjoint_oop_copy_entry;
    1.19 -
    1.20 -  static address byte_copy_entry;
    1.21 -  static address short_copy_entry;
    1.22 -  static address int_copy_entry;
    1.23 -  static address long_copy_entry;
    1.24 -  static address oop_copy_entry;
    1.25 -
    1.26 -  static address checkcast_copy_entry;
    1.27  
    1.28    //
    1.29    // Verify that a register contains clean 32-bits positive value
    1.30 @@ -1283,7 +1270,7 @@
    1.31    //      to:    O1
    1.32    //      count: O2 treated as signed
    1.33    //
    1.34 -  address generate_disjoint_byte_copy(bool aligned, const char * name) {
    1.35 +  address generate_disjoint_byte_copy(bool aligned, address *entry, const char *name) {
    1.36      __ align(CodeEntryAlignment);
    1.37      StubCodeMark mark(this, "StubRoutines", name);
    1.38      address start = __ pc();
    1.39 @@ -1299,9 +1286,11 @@
    1.40  
    1.41      assert_clean_int(count, O3);     // Make sure 'count' is clean int.
    1.42  
    1.43 -    if (!aligned)  disjoint_byte_copy_entry = __ pc();
    1.44 -    // caller can pass a 64-bit byte count here (from Unsafe.copyMemory)
    1.45 -    if (!aligned)  BLOCK_COMMENT("Entry:");
    1.46 +    if (entry != NULL) {
    1.47 +      *entry = __ pc();
    1.48 +      // caller can pass a 64-bit byte count here (from Unsafe.copyMemory)
    1.49 +      BLOCK_COMMENT("Entry:");
    1.50 +    }
    1.51  
    1.52      // for short arrays, just do single element copy
    1.53      __ cmp(count, 23); // 16 + 7
    1.54 @@ -1391,15 +1380,13 @@
    1.55    //      to:    O1
    1.56    //      count: O2 treated as signed
    1.57    //
    1.58 -  address generate_conjoint_byte_copy(bool aligned, const char * name) {
    1.59 +  address generate_conjoint_byte_copy(bool aligned, address nooverlap_target,
    1.60 +                                      address *entry, const char *name) {
    1.61      // Do reverse copy.
    1.62  
    1.63      __ align(CodeEntryAlignment);
    1.64      StubCodeMark mark(this, "StubRoutines", name);
    1.65      address start = __ pc();
    1.66 -    address nooverlap_target = aligned ?
    1.67 -        StubRoutines::arrayof_jbyte_disjoint_arraycopy() :
    1.68 -        disjoint_byte_copy_entry;
    1.69  
    1.70      Label L_skip_alignment, L_align, L_aligned_copy;
    1.71      Label L_copy_byte, L_copy_byte_loop, L_exit;
    1.72 @@ -1412,9 +1399,11 @@
    1.73  
    1.74      assert_clean_int(count, O3);     // Make sure 'count' is clean int.
    1.75  
    1.76 -    if (!aligned)  byte_copy_entry = __ pc();
    1.77 -    // caller can pass a 64-bit byte count here (from Unsafe.copyMemory)
    1.78 -    if (!aligned)  BLOCK_COMMENT("Entry:");
    1.79 +    if (entry != NULL) {
    1.80 +      *entry = __ pc();
    1.81 +      // caller can pass a 64-bit byte count here (from Unsafe.copyMemory)
    1.82 +      BLOCK_COMMENT("Entry:");
    1.83 +    }
    1.84  
    1.85      array_overlap_test(nooverlap_target, 0);
    1.86  
    1.87 @@ -1504,7 +1493,7 @@
    1.88    //      to:    O1
    1.89    //      count: O2 treated as signed
    1.90    //
    1.91 -  address generate_disjoint_short_copy(bool aligned, const char * name) {
    1.92 +  address generate_disjoint_short_copy(bool aligned, address *entry, const char * name) {
    1.93      __ align(CodeEntryAlignment);
    1.94      StubCodeMark mark(this, "StubRoutines", name);
    1.95      address start = __ pc();
    1.96 @@ -1520,9 +1509,11 @@
    1.97  
    1.98      assert_clean_int(count, O3);     // Make sure 'count' is clean int.
    1.99  
   1.100 -    if (!aligned)  disjoint_short_copy_entry = __ pc();
   1.101 -    // caller can pass a 64-bit byte count here (from Unsafe.copyMemory)
   1.102 -    if (!aligned)  BLOCK_COMMENT("Entry:");
   1.103 +    if (entry != NULL) {
   1.104 +      *entry = __ pc();
   1.105 +      // caller can pass a 64-bit byte count here (from Unsafe.copyMemory)
   1.106 +      BLOCK_COMMENT("Entry:");
   1.107 +    }
   1.108  
   1.109      // for short arrays, just do single element copy
   1.110      __ cmp(count, 11); // 8 + 3  (22 bytes)
   1.111 @@ -1842,15 +1833,13 @@
   1.112    //      to:    O1
   1.113    //      count: O2 treated as signed
   1.114    //
   1.115 -  address generate_conjoint_short_copy(bool aligned, const char * name) {
   1.116 +  address generate_conjoint_short_copy(bool aligned, address nooverlap_target,
   1.117 +                                       address *entry, const char *name) {
   1.118      // Do reverse copy.
   1.119  
   1.120      __ align(CodeEntryAlignment);
   1.121      StubCodeMark mark(this, "StubRoutines", name);
   1.122      address start = __ pc();
   1.123 -    address nooverlap_target = aligned ?
   1.124 -        StubRoutines::arrayof_jshort_disjoint_arraycopy() :
   1.125 -        disjoint_short_copy_entry;
   1.126  
   1.127      Label L_skip_alignment, L_skip_alignment2, L_aligned_copy;
   1.128      Label L_copy_2_bytes, L_copy_2_bytes_loop, L_exit;
   1.129 @@ -1865,9 +1854,11 @@
   1.130  
   1.131      assert_clean_int(count, O3);     // Make sure 'count' is clean int.
   1.132  
   1.133 -    if (!aligned)  short_copy_entry = __ pc();
   1.134 -    // caller can pass a 64-bit byte count here (from Unsafe.copyMemory)
   1.135 -    if (!aligned)  BLOCK_COMMENT("Entry:");
   1.136 +    if (entry != NULL) {
   1.137 +      *entry = __ pc();
   1.138 +      // caller can pass a 64-bit byte count here (from Unsafe.copyMemory)
   1.139 +      BLOCK_COMMENT("Entry:");
   1.140 +    }
   1.141  
   1.142      array_overlap_test(nooverlap_target, 1);
   1.143  
   1.144 @@ -2072,7 +2063,7 @@
   1.145    //      to:    O1
   1.146    //      count: O2 treated as signed
   1.147    //
   1.148 -  address generate_disjoint_int_copy(bool aligned, const char * name) {
   1.149 +  address generate_disjoint_int_copy(bool aligned, address *entry, const char *name) {
   1.150      __ align(CodeEntryAlignment);
   1.151      StubCodeMark mark(this, "StubRoutines", name);
   1.152      address start = __ pc();
   1.153 @@ -2080,9 +2071,11 @@
   1.154      const Register count = O2;
   1.155      assert_clean_int(count, O3);     // Make sure 'count' is clean int.
   1.156  
   1.157 -    if (!aligned)  disjoint_int_copy_entry = __ pc();
   1.158 -    // caller can pass a 64-bit byte count here (from Unsafe.copyMemory)
   1.159 -    if (!aligned)  BLOCK_COMMENT("Entry:");
   1.160 +    if (entry != NULL) {
   1.161 +      *entry = __ pc();
   1.162 +      // caller can pass a 64-bit byte count here (from Unsafe.copyMemory)
   1.163 +      BLOCK_COMMENT("Entry:");
   1.164 +    }
   1.165  
   1.166      generate_disjoint_int_copy_core(aligned);
   1.167  
   1.168 @@ -2204,20 +2197,19 @@
   1.169    //      to:    O1
   1.170    //      count: O2 treated as signed
   1.171    //
   1.172 -  address generate_conjoint_int_copy(bool aligned, const char * name) {
   1.173 +  address generate_conjoint_int_copy(bool aligned, address nooverlap_target,
   1.174 +                                     address *entry, const char *name) {
   1.175      __ align(CodeEntryAlignment);
   1.176      StubCodeMark mark(this, "StubRoutines", name);
   1.177      address start = __ pc();
   1.178  
   1.179 -    address nooverlap_target = aligned ?
   1.180 -        StubRoutines::arrayof_jint_disjoint_arraycopy() :
   1.181 -        disjoint_int_copy_entry;
   1.182 -
   1.183      assert_clean_int(O2, O3);     // Make sure 'count' is clean int.
   1.184  
   1.185 -    if (!aligned)  int_copy_entry = __ pc();
   1.186 -    // caller can pass a 64-bit byte count here (from Unsafe.copyMemory)
   1.187 -    if (!aligned)  BLOCK_COMMENT("Entry:");
   1.188 +    if (entry != NULL) {
   1.189 +      *entry = __ pc();
   1.190 +      // caller can pass a 64-bit byte count here (from Unsafe.copyMemory)
   1.191 +      BLOCK_COMMENT("Entry:");
   1.192 +    }
   1.193  
   1.194      array_overlap_test(nooverlap_target, 2);
   1.195  
   1.196 @@ -2336,16 +2328,18 @@
   1.197    //      to:    O1
   1.198    //      count: O2 treated as signed
   1.199    //
   1.200 -  address generate_disjoint_long_copy(bool aligned, const char * name) {
   1.201 +  address generate_disjoint_long_copy(bool aligned, address *entry, const char *name) {
   1.202      __ align(CodeEntryAlignment);
   1.203      StubCodeMark mark(this, "StubRoutines", name);
   1.204      address start = __ pc();
   1.205  
   1.206      assert_clean_int(O2, O3);     // Make sure 'count' is clean int.
   1.207  
   1.208 -    if (!aligned)  disjoint_long_copy_entry = __ pc();
   1.209 -    // caller can pass a 64-bit byte count here (from Unsafe.copyMemory)
   1.210 -    if (!aligned)  BLOCK_COMMENT("Entry:");
   1.211 +    if (entry != NULL) {
   1.212 +      *entry = __ pc();
   1.213 +      // caller can pass a 64-bit byte count here (from Unsafe.copyMemory)
   1.214 +      BLOCK_COMMENT("Entry:");
   1.215 +    }
   1.216  
   1.217      generate_disjoint_long_copy_core(aligned);
   1.218  
   1.219 @@ -2406,19 +2400,21 @@
   1.220    //      to:    O1
   1.221    //      count: O2 treated as signed
   1.222    //
   1.223 -  address generate_conjoint_long_copy(bool aligned, const char * name) {
   1.224 +  address generate_conjoint_long_copy(bool aligned, address nooverlap_target,
   1.225 +                                      address *entry, const char *name) {
   1.226      __ align(CodeEntryAlignment);
   1.227      StubCodeMark mark(this, "StubRoutines", name);
   1.228      address start = __ pc();
   1.229  
   1.230      assert(!aligned, "usage");
   1.231 -    address nooverlap_target = disjoint_long_copy_entry;
   1.232  
   1.233      assert_clean_int(O2, O3);     // Make sure 'count' is clean int.
   1.234  
   1.235 -    if (!aligned)  long_copy_entry = __ pc();
   1.236 -    // caller can pass a 64-bit byte count here (from Unsafe.copyMemory)
   1.237 -    if (!aligned)  BLOCK_COMMENT("Entry:");
   1.238 +    if (entry != NULL) {
   1.239 +      *entry = __ pc();
   1.240 +      // caller can pass a 64-bit byte count here (from Unsafe.copyMemory)
   1.241 +      BLOCK_COMMENT("Entry:");
   1.242 +    }
   1.243  
   1.244      array_overlap_test(nooverlap_target, 3);
   1.245  
   1.246 @@ -2439,7 +2435,7 @@
   1.247    //      to:    O1
   1.248    //      count: O2 treated as signed
   1.249    //
   1.250 -  address generate_disjoint_oop_copy(bool aligned, const char * name) {
   1.251 +  address generate_disjoint_oop_copy(bool aligned, address *entry, const char *name) {
   1.252  
   1.253      const Register from  = O0;  // source array address
   1.254      const Register to    = O1;  // destination array address
   1.255 @@ -2451,9 +2447,11 @@
   1.256  
   1.257      assert_clean_int(count, O3);     // Make sure 'count' is clean int.
   1.258  
   1.259 -    if (!aligned)  disjoint_oop_copy_entry = __ pc();
   1.260 -    // caller can pass a 64-bit byte count here
   1.261 -    if (!aligned)  BLOCK_COMMENT("Entry:");
   1.262 +    if (entry != NULL) {
   1.263 +      *entry = __ pc();
   1.264 +      // caller can pass a 64-bit byte count here
   1.265 +      BLOCK_COMMENT("Entry:");
   1.266 +    }
   1.267  
   1.268      // save arguments for barrier generation
   1.269      __ mov(to, G1);
   1.270 @@ -2487,7 +2485,8 @@
   1.271    //      to:    O1
   1.272    //      count: O2 treated as signed
   1.273    //
   1.274 -  address generate_conjoint_oop_copy(bool aligned, const char * name) {
   1.275 +  address generate_conjoint_oop_copy(bool aligned, address nooverlap_target,
   1.276 +                                     address *entry, const char *name) {
   1.277  
   1.278      const Register from  = O0;  // source array address
   1.279      const Register to    = O1;  // destination array address
   1.280 @@ -2499,22 +2498,19 @@
   1.281  
   1.282      assert_clean_int(count, O3);     // Make sure 'count' is clean int.
   1.283  
   1.284 -    if (!aligned)  oop_copy_entry = __ pc();
   1.285 -    // caller can pass a 64-bit byte count here
   1.286 -    if (!aligned)  BLOCK_COMMENT("Entry:");
   1.287 +    if (entry != NULL) {
   1.288 +      *entry = __ pc();
   1.289 +      // caller can pass a 64-bit byte count here
   1.290 +      BLOCK_COMMENT("Entry:");
   1.291 +    }
   1.292 +
   1.293 +    array_overlap_test(nooverlap_target, LogBytesPerHeapOop);
   1.294  
   1.295      // save arguments for barrier generation
   1.296      __ mov(to, G1);
   1.297      __ mov(count, G5);
   1.298 -
   1.299      gen_write_ref_array_pre_barrier(G1, G5);
   1.300  
   1.301 -    address nooverlap_target = aligned ?
   1.302 -        StubRoutines::arrayof_oop_disjoint_arraycopy() :
   1.303 -        disjoint_oop_copy_entry;
   1.304 -
   1.305 -    array_overlap_test(nooverlap_target, LogBytesPerHeapOop);
   1.306 -
   1.307    #ifdef _LP64
   1.308      if (UseCompressedOops) {
   1.309        generate_conjoint_int_copy_core(aligned);
   1.310 @@ -2582,7 +2578,7 @@
   1.311    //      ckval: O4 (super_klass)
   1.312    //      ret:   O0 zero for success; (-1^K) where K is partial transfer count
   1.313    //
   1.314 -  address generate_checkcast_copy(const char* name) {
   1.315 +  address generate_checkcast_copy(const char *name, address *entry) {
   1.316  
   1.317      const Register O0_from   = O0;      // source array address
   1.318      const Register O1_to     = O1;      // destination array address
   1.319 @@ -2600,8 +2596,6 @@
   1.320      StubCodeMark mark(this, "StubRoutines", name);
   1.321      address start = __ pc();
   1.322  
   1.323 -    gen_write_ref_array_pre_barrier(O1, O2);
   1.324 -
   1.325  #ifdef ASSERT
   1.326      // We sometimes save a frame (see generate_type_check below).
   1.327      // If this will cause trouble, let's fail now instead of later.
   1.328 @@ -2625,9 +2619,13 @@
   1.329      }
   1.330  #endif //ASSERT
   1.331  
   1.332 -    checkcast_copy_entry = __ pc();
   1.333 -    // caller can pass a 64-bit byte count here (from generic stub)
   1.334 -    BLOCK_COMMENT("Entry:");
   1.335 +    if (entry != NULL) {
   1.336 +      *entry = __ pc();
   1.337 +      // caller can pass a 64-bit byte count here (from generic stub)
   1.338 +      BLOCK_COMMENT("Entry:");
   1.339 +    }
   1.340 +
   1.341 +    gen_write_ref_array_pre_barrier(O1_to, O2_count);
   1.342  
   1.343      Label load_element, store_element, do_card_marks, fail, done;
   1.344      __ addcc(O2_count, 0, G1_remain);   // initialize loop index, and test it
   1.345 @@ -2700,7 +2698,11 @@
   1.346    // Examines the alignment of the operands and dispatches
   1.347    // to a long, int, short, or byte copy loop.
   1.348    //
   1.349 -  address generate_unsafe_copy(const char* name) {
   1.350 +  address generate_unsafe_copy(const char* name,
   1.351 +                               address byte_copy_entry,
   1.352 +                               address short_copy_entry,
   1.353 +                               address int_copy_entry,
   1.354 +                               address long_copy_entry) {
   1.355  
   1.356      const Register O0_from   = O0;      // source array address
   1.357      const Register O1_to     = O1;      // destination array address
   1.358 @@ -2796,8 +2798,13 @@
   1.359    //    O0 ==  0  -  success
   1.360    //    O0 == -1  -  need to call System.arraycopy
   1.361    //
   1.362 -  address generate_generic_copy(const char *name) {
   1.363 -
   1.364 +  address generate_generic_copy(const char *name,
   1.365 +                                address entry_jbyte_arraycopy,
   1.366 +                                address entry_jshort_arraycopy,
   1.367 +                                address entry_jint_arraycopy,
   1.368 +                                address entry_oop_arraycopy,
   1.369 +                                address entry_jlong_arraycopy,
   1.370 +                                address entry_checkcast_arraycopy) {
   1.371      Label L_failed, L_objArray;
   1.372  
   1.373      // Input registers
   1.374 @@ -2970,15 +2977,15 @@
   1.375  
   1.376      BLOCK_COMMENT("choose copy loop based on element size");
   1.377      __ cmp(G3_elsize, 0);
   1.378 -    __ br(Assembler::equal,true,Assembler::pt,StubRoutines::_jbyte_arraycopy);
   1.379 +    __ br(Assembler::equal, true, Assembler::pt, entry_jbyte_arraycopy);
   1.380      __ delayed()->signx(length, count); // length
   1.381  
   1.382      __ cmp(G3_elsize, LogBytesPerShort);
   1.383 -    __ br(Assembler::equal,true,Assembler::pt,StubRoutines::_jshort_arraycopy);
   1.384 +    __ br(Assembler::equal, true, Assembler::pt, entry_jshort_arraycopy);
   1.385      __ delayed()->signx(length, count); // length
   1.386  
   1.387      __ cmp(G3_elsize, LogBytesPerInt);
   1.388 -    __ br(Assembler::equal,true,Assembler::pt,StubRoutines::_jint_arraycopy);
   1.389 +    __ br(Assembler::equal, true, Assembler::pt, entry_jint_arraycopy);
   1.390      __ delayed()->signx(length, count); // length
   1.391  #ifdef ASSERT
   1.392      { Label L;
   1.393 @@ -2989,7 +2996,7 @@
   1.394        __ bind(L);
   1.395      }
   1.396  #endif
   1.397 -    __ br(Assembler::always,false,Assembler::pt,StubRoutines::_jlong_arraycopy);
   1.398 +    __ br(Assembler::always, false, Assembler::pt, entry_jlong_arraycopy);
   1.399      __ delayed()->signx(length, count); // length
   1.400  
   1.401      // objArrayKlass
   1.402 @@ -3013,7 +3020,7 @@
   1.403      __ add(src, src_pos, from);       // src_addr
   1.404      __ add(dst, dst_pos, to);         // dst_addr
   1.405    __ BIND(L_plain_copy);
   1.406 -    __ br(Assembler::always, false, Assembler::pt,StubRoutines::_oop_arraycopy);
   1.407 +    __ br(Assembler::always, false, Assembler::pt, entry_oop_arraycopy);
   1.408      __ delayed()->signx(length, count); // length
   1.409  
   1.410    __ BIND(L_checkcast_copy);
   1.411 @@ -3057,7 +3064,7 @@
   1.412        __ ld_ptr(G4_dst_klass, ek_offset, O4);   // dest elem klass
   1.413        // lduw(O4, sco_offset, O3);              // sco of elem klass
   1.414  
   1.415 -      __ br(Assembler::always, false, Assembler::pt, checkcast_copy_entry);
   1.416 +      __ br(Assembler::always, false, Assembler::pt, entry_checkcast_arraycopy);
   1.417        __ delayed()->lduw(O4, sco_offset, O3);
   1.418      }
   1.419  
   1.420 @@ -3068,39 +3075,76 @@
   1.421    }
   1.422  
   1.423    void generate_arraycopy_stubs() {
   1.424 -
   1.425 -    // Note:  the disjoint stubs must be generated first, some of
   1.426 -    //        the conjoint stubs use them.
   1.427 -    StubRoutines::_jbyte_disjoint_arraycopy  = generate_disjoint_byte_copy(false, "jbyte_disjoint_arraycopy");
   1.428 -    StubRoutines::_jshort_disjoint_arraycopy = generate_disjoint_short_copy(false, "jshort_disjoint_arraycopy");
   1.429 -    StubRoutines::_jint_disjoint_arraycopy   = generate_disjoint_int_copy(false, "jint_disjoint_arraycopy");
   1.430 -    StubRoutines::_jlong_disjoint_arraycopy  = generate_disjoint_long_copy(false, "jlong_disjoint_arraycopy");
   1.431 -    StubRoutines::_oop_disjoint_arraycopy    = generate_disjoint_oop_copy(false, "oop_disjoint_arraycopy");
   1.432 -    StubRoutines::_arrayof_jbyte_disjoint_arraycopy  = generate_disjoint_byte_copy(true, "arrayof_jbyte_disjoint_arraycopy");
   1.433 -    StubRoutines::_arrayof_jshort_disjoint_arraycopy = generate_disjoint_short_copy(true, "arrayof_jshort_disjoint_arraycopy");
   1.434 -    StubRoutines::_arrayof_jint_disjoint_arraycopy   = generate_disjoint_int_copy(true, "arrayof_jint_disjoint_arraycopy");
   1.435 -    StubRoutines::_arrayof_jlong_disjoint_arraycopy  = generate_disjoint_long_copy(true, "arrayof_jlong_disjoint_arraycopy");
   1.436 -    StubRoutines::_arrayof_oop_disjoint_arraycopy    =  generate_disjoint_oop_copy(true, "arrayof_oop_disjoint_arraycopy");
   1.437 -
   1.438 -    StubRoutines::_jbyte_arraycopy  = generate_conjoint_byte_copy(false, "jbyte_arraycopy");
   1.439 -    StubRoutines::_jshort_arraycopy = generate_conjoint_short_copy(false, "jshort_arraycopy");
   1.440 -    StubRoutines::_jint_arraycopy   = generate_conjoint_int_copy(false, "jint_arraycopy");
   1.441 -    StubRoutines::_jlong_arraycopy  = generate_conjoint_long_copy(false, "jlong_arraycopy");
   1.442 -    StubRoutines::_oop_arraycopy    = generate_conjoint_oop_copy(false, "oop_arraycopy");
   1.443 -    StubRoutines::_arrayof_jbyte_arraycopy    = generate_conjoint_byte_copy(true, "arrayof_jbyte_arraycopy");
   1.444 -    StubRoutines::_arrayof_jshort_arraycopy   = generate_conjoint_short_copy(true, "arrayof_jshort_arraycopy");
   1.445 +    address entry;
   1.446 +    address entry_jbyte_arraycopy;
   1.447 +    address entry_jshort_arraycopy;
   1.448 +    address entry_jint_arraycopy;
   1.449 +    address entry_oop_arraycopy;
   1.450 +    address entry_jlong_arraycopy;
   1.451 +    address entry_checkcast_arraycopy;
   1.452 +
   1.453 +    StubRoutines::_jbyte_disjoint_arraycopy  = generate_disjoint_byte_copy(false, &entry,
   1.454 +                                                                           "jbyte_disjoint_arraycopy");
   1.455 +    StubRoutines::_jbyte_arraycopy           = generate_conjoint_byte_copy(false, entry, &entry_jbyte_arraycopy,
   1.456 +                                                                           "jbyte_arraycopy");
   1.457 +    StubRoutines::_jshort_disjoint_arraycopy = generate_disjoint_short_copy(false, &entry,
   1.458 +                                                                            "jshort_disjoint_arraycopy");
   1.459 +    StubRoutines::_jshort_arraycopy          = generate_conjoint_short_copy(false, entry, &entry_jshort_arraycopy,
   1.460 +                                                                            "jshort_arraycopy");
   1.461 +    StubRoutines::_jint_disjoint_arraycopy   = generate_disjoint_int_copy(false, &entry,
   1.462 +                                                                          "jint_disjoint_arraycopy");
   1.463 +    StubRoutines::_jint_arraycopy            = generate_conjoint_int_copy(false, entry, &entry_jint_arraycopy,
   1.464 +                                                                          "jint_arraycopy");
   1.465 +    StubRoutines::_jlong_disjoint_arraycopy  = generate_disjoint_long_copy(false, &entry,
   1.466 +                                                                           "jlong_disjoint_arraycopy");
   1.467 +    StubRoutines::_jlong_arraycopy           = generate_conjoint_long_copy(false, entry, &entry_jlong_arraycopy,
   1.468 +                                                                           "jlong_arraycopy");
   1.469 +    StubRoutines::_oop_disjoint_arraycopy    = generate_disjoint_oop_copy(false, &entry,
   1.470 +                                                                          "oop_disjoint_arraycopy");
   1.471 +    StubRoutines::_oop_arraycopy             = generate_conjoint_oop_copy(false, entry, &entry_oop_arraycopy,
   1.472 +                                                                          "oop_arraycopy");
   1.473 +
   1.474 +
   1.475 +    StubRoutines::_arrayof_jbyte_disjoint_arraycopy  = generate_disjoint_byte_copy(true, &entry,
   1.476 +                                                                                   "arrayof_jbyte_disjoint_arraycopy");
   1.477 +    StubRoutines::_arrayof_jbyte_arraycopy           = generate_conjoint_byte_copy(true, entry, NULL,
   1.478 +                                                                                   "arrayof_jbyte_arraycopy");
   1.479 +
   1.480 +    StubRoutines::_arrayof_jshort_disjoint_arraycopy = generate_disjoint_short_copy(true, &entry,
   1.481 +                                                                                    "arrayof_jshort_disjoint_arraycopy");
   1.482 +    StubRoutines::_arrayof_jshort_arraycopy          = generate_conjoint_short_copy(true, entry, NULL,
   1.483 +                                                                                    "arrayof_jshort_arraycopy");
   1.484 +
   1.485 +    StubRoutines::_arrayof_jint_disjoint_arraycopy   = generate_disjoint_int_copy(true, &entry,
   1.486 +                                                                                  "arrayof_jint_disjoint_arraycopy");
   1.487  #ifdef _LP64
   1.488      // since sizeof(jint) < sizeof(HeapWord), there's a different flavor:
   1.489 -    StubRoutines::_arrayof_jint_arraycopy     = generate_conjoint_int_copy(true, "arrayof_jint_arraycopy");
   1.490 +    StubRoutines::_arrayof_jint_arraycopy     = generate_conjoint_int_copy(true, entry, NULL, "arrayof_jint_arraycopy");
   1.491    #else
   1.492      StubRoutines::_arrayof_jint_arraycopy     = StubRoutines::_jint_arraycopy;
   1.493  #endif
   1.494 +
   1.495 +    StubRoutines::_arrayof_jlong_disjoint_arraycopy  = generate_disjoint_long_copy(true, NULL,
   1.496 +                                                                                   "arrayof_jlong_disjoint_arraycopy");
   1.497 +    StubRoutines::_arrayof_oop_disjoint_arraycopy    =  generate_disjoint_oop_copy(true, NULL,
   1.498 +                                                                                   "arrayof_oop_disjoint_arraycopy");
   1.499 +
   1.500      StubRoutines::_arrayof_jlong_arraycopy    = StubRoutines::_jlong_arraycopy;
   1.501      StubRoutines::_arrayof_oop_arraycopy      = StubRoutines::_oop_arraycopy;
   1.502  
   1.503 -    StubRoutines::_checkcast_arraycopy = generate_checkcast_copy("checkcast_arraycopy");
   1.504 -    StubRoutines::_unsafe_arraycopy    = generate_unsafe_copy("unsafe_arraycopy");
   1.505 -    StubRoutines::_generic_arraycopy   = generate_generic_copy("generic_arraycopy");
   1.506 +    StubRoutines::_checkcast_arraycopy = generate_checkcast_copy("checkcast_arraycopy", &entry_checkcast_arraycopy);
   1.507 +    StubRoutines::_unsafe_arraycopy    = generate_unsafe_copy("unsafe_arraycopy",
   1.508 +                                                              entry_jbyte_arraycopy,
   1.509 +                                                              entry_jshort_arraycopy,
   1.510 +                                                              entry_jint_arraycopy,
   1.511 +                                                              entry_jlong_arraycopy);
   1.512 +    StubRoutines::_generic_arraycopy   = generate_generic_copy("generic_arraycopy",
   1.513 +                                                               entry_jbyte_arraycopy,
   1.514 +                                                               entry_jshort_arraycopy,
   1.515 +                                                               entry_jint_arraycopy,
   1.516 +                                                               entry_oop_arraycopy,
   1.517 +                                                               entry_jlong_arraycopy,
   1.518 +                                                               entry_checkcast_arraycopy);
   1.519  
   1.520      StubRoutines::_jbyte_fill = generate_fill(T_BYTE, false, "jbyte_fill");
   1.521      StubRoutines::_jshort_fill = generate_fill(T_SHORT, false, "jshort_fill");
   1.522 @@ -3224,21 +3268,6 @@
   1.523  
   1.524  }; // end class declaration
   1.525  
   1.526 -
   1.527 -address StubGenerator::disjoint_byte_copy_entry  = NULL;
   1.528 -address StubGenerator::disjoint_short_copy_entry = NULL;
   1.529 -address StubGenerator::disjoint_int_copy_entry   = NULL;
   1.530 -address StubGenerator::disjoint_long_copy_entry  = NULL;
   1.531 -address StubGenerator::disjoint_oop_copy_entry   = NULL;
   1.532 -
   1.533 -address StubGenerator::byte_copy_entry  = NULL;
   1.534 -address StubGenerator::short_copy_entry = NULL;
   1.535 -address StubGenerator::int_copy_entry   = NULL;
   1.536 -address StubGenerator::long_copy_entry  = NULL;
   1.537 -address StubGenerator::oop_copy_entry   = NULL;
   1.538 -
   1.539 -address StubGenerator::checkcast_copy_entry = NULL;
   1.540 -
   1.541  void StubGenerator_generate(CodeBuffer* code, bool all) {
   1.542    StubGenerator g(code, all);
   1.543  }
     2.1 --- a/src/cpu/x86/vm/stubGenerator_x86_32.cpp	Wed Feb 09 15:02:23 2011 -0800
     2.2 +++ b/src/cpu/x86/vm/stubGenerator_x86_32.cpp	Tue Feb 22 15:25:02 2011 -0800
     2.3 @@ -945,6 +945,12 @@
     2.4      __ movptr(from , Address(rsp, 12+ 4));
     2.5      __ movptr(to   , Address(rsp, 12+ 8));
     2.6      __ movl(count, Address(rsp, 12+ 12));
     2.7 +
     2.8 +    if (entry != NULL) {
     2.9 +      *entry = __ pc(); // Entry point from conjoint arraycopy stub.
    2.10 +      BLOCK_COMMENT("Entry:");
    2.11 +    }
    2.12 +
    2.13      if (t == T_OBJECT) {
    2.14        __ testl(count, count);
    2.15        __ jcc(Assembler::zero, L_0_count);
    2.16 @@ -952,9 +958,6 @@
    2.17        __ mov(saved_to, to);          // save 'to'
    2.18      }
    2.19  
    2.20 -    *entry = __ pc(); // Entry point from conjoint arraycopy stub.
    2.21 -    BLOCK_COMMENT("Entry:");
    2.22 -
    2.23      __ subptr(to, from); // to --> to_from
    2.24      __ cmpl(count, 2<<shift); // Short arrays (< 8 bytes) copy by element
    2.25      __ jcc(Assembler::below, L_copy_4_bytes); // use unsigned cmp
    2.26 @@ -1108,23 +1111,17 @@
    2.27      __ movptr(src  , Address(rsp, 12+ 4));   // from
    2.28      __ movptr(dst  , Address(rsp, 12+ 8));   // to
    2.29      __ movl2ptr(count, Address(rsp, 12+12)); // count
    2.30 -    if (t == T_OBJECT) {
    2.31 -       gen_write_ref_array_pre_barrier(dst, count);
    2.32 -    }
    2.33  
    2.34      if (entry != NULL) {
    2.35        *entry = __ pc(); // Entry point from generic arraycopy stub.
    2.36        BLOCK_COMMENT("Entry:");
    2.37      }
    2.38  
    2.39 -    if (t == T_OBJECT) {
    2.40 -      __ testl(count, count);
    2.41 -      __ jcc(Assembler::zero, L_0_count);
    2.42 -    }
    2.43 +    // nooverlap_target expects arguments in rsi and rdi.
    2.44      __ mov(from, src);
    2.45      __ mov(to  , dst);
    2.46  
    2.47 -    // arrays overlap test
    2.48 +    // arrays overlap test: dispatch to disjoint stub if necessary.
    2.49      RuntimeAddress nooverlap(nooverlap_target);
    2.50      __ cmpptr(dst, src);
    2.51      __ lea(end, Address(src, count, sf, 0)); // src + count * elem_size
    2.52 @@ -1132,6 +1129,12 @@
    2.53      __ cmpptr(dst, end);
    2.54      __ jump_cc(Assembler::aboveEqual, nooverlap);
    2.55  
    2.56 +    if (t == T_OBJECT) {
    2.57 +      __ testl(count, count);
    2.58 +      __ jcc(Assembler::zero, L_0_count);
    2.59 +       gen_write_ref_array_pre_barrier(dst, count);
    2.60 +    }
    2.61 +
    2.62      // copy from high to low
    2.63      __ cmpl(count, 2<<shift); // Short arrays (< 8 bytes) copy by element
    2.64      __ jcc(Assembler::below, L_copy_4_bytes); // use unsigned cmp
    2.65 @@ -1451,8 +1454,10 @@
    2.66      __ movptr(to,         to_arg);
    2.67      __ movl2ptr(length, length_arg);
    2.68  
    2.69 -    *entry = __ pc(); // Entry point from generic arraycopy stub.
    2.70 -    BLOCK_COMMENT("Entry:");
    2.71 +    if (entry != NULL) {
    2.72 +      *entry = __ pc(); // Entry point from generic arraycopy stub.
    2.73 +      BLOCK_COMMENT("Entry:");
    2.74 +    }
    2.75  
    2.76      //---------------------------------------------------------------
    2.77      // Assembler stub will be used for this call to arraycopy
     3.1 --- a/src/cpu/x86/vm/stubGenerator_x86_64.cpp	Wed Feb 09 15:02:23 2011 -0800
     3.2 +++ b/src/cpu/x86/vm/stubGenerator_x86_64.cpp	Tue Feb 22 15:25:02 2011 -0800
     3.3 @@ -1,5 +1,5 @@
     3.4  /*
     3.5 - * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
     3.6 + * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
     3.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     3.8   *
     3.9   * This code is free software; you can redistribute it and/or modify it
    3.10 @@ -1057,20 +1057,6 @@
    3.11      return start;
    3.12    }
    3.13  
    3.14 -  static address disjoint_byte_copy_entry;
    3.15 -  static address disjoint_short_copy_entry;
    3.16 -  static address disjoint_int_copy_entry;
    3.17 -  static address disjoint_long_copy_entry;
    3.18 -  static address disjoint_oop_copy_entry;
    3.19 -
    3.20 -  static address byte_copy_entry;
    3.21 -  static address short_copy_entry;
    3.22 -  static address int_copy_entry;
    3.23 -  static address long_copy_entry;
    3.24 -  static address oop_copy_entry;
    3.25 -
    3.26 -  static address checkcast_copy_entry;
    3.27 -
    3.28    //
    3.29    // Verify that a register contains clean 32-bits positive value
    3.30    // (high 32-bits are 0) so it could be used in 64-bits shifts.
    3.31 @@ -1379,7 +1365,7 @@
    3.32    //   disjoint_byte_copy_entry is set to the no-overlap entry point
    3.33    //   used by generate_conjoint_byte_copy().
    3.34    //
    3.35 -  address generate_disjoint_byte_copy(bool aligned, const char *name) {
    3.36 +  address generate_disjoint_byte_copy(bool aligned, address* entry, const char *name) {
    3.37      __ align(CodeEntryAlignment);
    3.38      StubCodeMark mark(this, "StubRoutines", name);
    3.39      address start = __ pc();
    3.40 @@ -1399,9 +1385,11 @@
    3.41      __ enter(); // required for proper stackwalking of RuntimeStub frame
    3.42      assert_clean_int(c_rarg2, rax);    // Make sure 'count' is clean int.
    3.43  
    3.44 -    disjoint_byte_copy_entry = __ pc();
    3.45 -    BLOCK_COMMENT("Entry:");
    3.46 -    // caller can pass a 64-bit byte count here (from Unsafe.copyMemory)
    3.47 +    if (entry != NULL) {
    3.48 +      *entry = __ pc();
    3.49 +       // caller can pass a 64-bit byte count here (from Unsafe.copyMemory)
    3.50 +      BLOCK_COMMENT("Entry:");
    3.51 +    }
    3.52  
    3.53      setup_arg_regs(); // from => rdi, to => rsi, count => rdx
    3.54                        // r9 and r10 may be used to save non-volatile registers
    3.55 @@ -1479,7 +1467,8 @@
    3.56    // dwords or qwords that span cache line boundaries will still be loaded
    3.57    // and stored atomically.
    3.58    //
    3.59 -  address generate_conjoint_byte_copy(bool aligned, const char *name) {
    3.60 +  address generate_conjoint_byte_copy(bool aligned, address nooverlap_target,
    3.61 +                                      address* entry, const char *name) {
    3.62      __ align(CodeEntryAlignment);
    3.63      StubCodeMark mark(this, "StubRoutines", name);
    3.64      address start = __ pc();
    3.65 @@ -1494,11 +1483,13 @@
    3.66      __ enter(); // required for proper stackwalking of RuntimeStub frame
    3.67      assert_clean_int(c_rarg2, rax);    // Make sure 'count' is clean int.
    3.68  
    3.69 -    byte_copy_entry = __ pc();
    3.70 -    BLOCK_COMMENT("Entry:");
    3.71 -    // caller can pass a 64-bit byte count here (from Unsafe.copyMemory)
    3.72 -
    3.73 -    array_overlap_test(disjoint_byte_copy_entry, Address::times_1);
    3.74 +    if (entry != NULL) {
    3.75 +      *entry = __ pc();
    3.76 +      // caller can pass a 64-bit byte count here (from Unsafe.copyMemory)
    3.77 +      BLOCK_COMMENT("Entry:");
    3.78 +    }
    3.79 +
    3.80 +    array_overlap_test(nooverlap_target, Address::times_1);
    3.81      setup_arg_regs(); // from => rdi, to => rsi, count => rdx
    3.82                        // r9 and r10 may be used to save non-volatile registers
    3.83  
    3.84 @@ -1574,7 +1565,7 @@
    3.85    //   disjoint_short_copy_entry is set to the no-overlap entry point
    3.86    //   used by generate_conjoint_short_copy().
    3.87    //
    3.88 -  address generate_disjoint_short_copy(bool aligned, const char *name) {
    3.89 +  address generate_disjoint_short_copy(bool aligned, address *entry, const char *name) {
    3.90      __ align(CodeEntryAlignment);
    3.91      StubCodeMark mark(this, "StubRoutines", name);
    3.92      address start = __ pc();
    3.93 @@ -1593,9 +1584,11 @@
    3.94      __ enter(); // required for proper stackwalking of RuntimeStub frame
    3.95      assert_clean_int(c_rarg2, rax);    // Make sure 'count' is clean int.
    3.96  
    3.97 -    disjoint_short_copy_entry = __ pc();
    3.98 -    BLOCK_COMMENT("Entry:");
    3.99 -    // caller can pass a 64-bit byte count here (from Unsafe.copyMemory)
   3.100 +    if (entry != NULL) {
   3.101 +      *entry = __ pc();
   3.102 +      // caller can pass a 64-bit byte count here (from Unsafe.copyMemory)
   3.103 +      BLOCK_COMMENT("Entry:");
   3.104 +    }
   3.105  
   3.106      setup_arg_regs(); // from => rdi, to => rsi, count => rdx
   3.107                        // r9 and r10 may be used to save non-volatile registers
   3.108 @@ -1686,7 +1679,8 @@
   3.109    // or qwords that span cache line boundaries will still be loaded
   3.110    // and stored atomically.
   3.111    //
   3.112 -  address generate_conjoint_short_copy(bool aligned, const char *name) {
   3.113 +  address generate_conjoint_short_copy(bool aligned, address nooverlap_target,
   3.114 +                                       address *entry, const char *name) {
   3.115      __ align(CodeEntryAlignment);
   3.116      StubCodeMark mark(this, "StubRoutines", name);
   3.117      address start = __ pc();
   3.118 @@ -1701,11 +1695,13 @@
   3.119      __ enter(); // required for proper stackwalking of RuntimeStub frame
   3.120      assert_clean_int(c_rarg2, rax);    // Make sure 'count' is clean int.
   3.121  
   3.122 -    short_copy_entry = __ pc();
   3.123 -    BLOCK_COMMENT("Entry:");
   3.124 -    // caller can pass a 64-bit byte count here (from Unsafe.copyMemory)
   3.125 -
   3.126 -    array_overlap_test(disjoint_short_copy_entry, Address::times_2);
   3.127 +    if (entry != NULL) {
   3.128 +      *entry = __ pc();
   3.129 +      // caller can pass a 64-bit byte count here (from Unsafe.copyMemory)
   3.130 +      BLOCK_COMMENT("Entry:");
   3.131 +    }
   3.132 +
   3.133 +    array_overlap_test(nooverlap_target, Address::times_2);
   3.134      setup_arg_regs(); // from => rdi, to => rsi, count => rdx
   3.135                        // r9 and r10 may be used to save non-volatile registers
   3.136  
   3.137 @@ -1773,7 +1769,7 @@
   3.138    //   disjoint_int_copy_entry is set to the no-overlap entry point
   3.139    //   used by generate_conjoint_int_oop_copy().
   3.140    //
   3.141 -  address generate_disjoint_int_oop_copy(bool aligned, bool is_oop, const char *name) {
   3.142 +  address generate_disjoint_int_oop_copy(bool aligned, bool is_oop, address* entry, const char *name) {
   3.143      __ align(CodeEntryAlignment);
   3.144      StubCodeMark mark(this, "StubRoutines", name);
   3.145      address start = __ pc();
   3.146 @@ -1793,21 +1789,17 @@
   3.147      __ enter(); // required for proper stackwalking of RuntimeStub frame
   3.148      assert_clean_int(c_rarg2, rax);    // Make sure 'count' is clean int.
   3.149  
   3.150 -    (is_oop ? disjoint_oop_copy_entry : disjoint_int_copy_entry) = __ pc();
   3.151 -
   3.152 -    if (is_oop) {
   3.153 -      // no registers are destroyed by this call
   3.154 -      gen_write_ref_array_pre_barrier(/* dest */ c_rarg1, /* count */ c_rarg2);
   3.155 +    if (entry != NULL) {
   3.156 +      *entry = __ pc();
   3.157 +      // caller can pass a 64-bit byte count here (from Unsafe.copyMemory)
   3.158 +      BLOCK_COMMENT("Entry:");
   3.159      }
   3.160  
   3.161 -    BLOCK_COMMENT("Entry:");
   3.162 -    // caller can pass a 64-bit byte count here (from Unsafe.copyMemory)
   3.163 -
   3.164      setup_arg_regs(); // from => rdi, to => rsi, count => rdx
   3.165                        // r9 and r10 may be used to save non-volatile registers
   3.166 -
   3.167      if (is_oop) {
   3.168        __ movq(saved_to, to);
   3.169 +      gen_write_ref_array_pre_barrier(to, count);
   3.170      }
   3.171  
   3.172      // 'from', 'to' and 'count' are now valid
   3.173 @@ -1867,7 +1859,8 @@
   3.174    // the hardware handle it.  The two dwords within qwords that span
   3.175    // cache line boundaries will still be loaded and stored atomicly.
   3.176    //
   3.177 -  address generate_conjoint_int_oop_copy(bool aligned, bool is_oop, const char *name) {
   3.178 +  address generate_conjoint_int_oop_copy(bool aligned, bool is_oop, address nooverlap_target,
   3.179 +                                         address *entry, const char *name) {
   3.180      __ align(CodeEntryAlignment);
   3.181      StubCodeMark mark(this, "StubRoutines", name);
   3.182      address start = __ pc();
   3.183 @@ -1882,20 +1875,21 @@
   3.184      __ enter(); // required for proper stackwalking of RuntimeStub frame
   3.185      assert_clean_int(c_rarg2, rax);    // Make sure 'count' is clean int.
   3.186  
   3.187 +    if (entry != NULL) {
   3.188 +      *entry = __ pc();
   3.189 +       // caller can pass a 64-bit byte count here (from Unsafe.copyMemory)
   3.190 +      BLOCK_COMMENT("Entry:");
   3.191 +    }
   3.192 +
   3.193 +    array_overlap_test(nooverlap_target, Address::times_4);
   3.194 +    setup_arg_regs(); // from => rdi, to => rsi, count => rdx
   3.195 +                      // r9 and r10 may be used to save non-volatile registers
   3.196 +
   3.197      if (is_oop) {
   3.198        // no registers are destroyed by this call
   3.199 -      gen_write_ref_array_pre_barrier(/* dest */ c_rarg1, /* count */ c_rarg2);
   3.200 +      gen_write_ref_array_pre_barrier(to, count);
   3.201      }
   3.202  
   3.203 -    (is_oop ? oop_copy_entry : int_copy_entry) = __ pc();
   3.204 -    BLOCK_COMMENT("Entry:");
   3.205 -    // caller can pass a 64-bit byte count here (from Unsafe.copyMemory)
   3.206 -
   3.207 -    array_overlap_test(is_oop ? disjoint_oop_copy_entry : disjoint_int_copy_entry,
   3.208 -                       Address::times_4);
   3.209 -    setup_arg_regs(); // from => rdi, to => rsi, count => rdx
   3.210 -                      // r9 and r10 may be used to save non-volatile registers
   3.211 -
   3.212      assert_clean_int(count, rax); // Make sure 'count' is clean int.
   3.213      // 'from', 'to' and 'count' are now valid
   3.214      __ movptr(dword_count, count);
   3.215 @@ -1959,7 +1953,7 @@
   3.216    //   disjoint_oop_copy_entry or disjoint_long_copy_entry is set to the
   3.217    //   no-overlap entry point used by generate_conjoint_long_oop_copy().
   3.218    //
   3.219 -  address generate_disjoint_long_oop_copy(bool aligned, bool is_oop, const char *name) {
   3.220 +  address generate_disjoint_long_oop_copy(bool aligned, bool is_oop, address *entry, const char *name) {
   3.221      __ align(CodeEntryAlignment);
   3.222      StubCodeMark mark(this, "StubRoutines", name);
   3.223      address start = __ pc();
   3.224 @@ -1978,20 +1972,19 @@
   3.225      // Save no-overlap entry point for generate_conjoint_long_oop_copy()
   3.226      assert_clean_int(c_rarg2, rax);    // Make sure 'count' is clean int.
   3.227  
   3.228 -    if (is_oop) {
   3.229 -      disjoint_oop_copy_entry  = __ pc();
   3.230 -      // no registers are destroyed by this call
   3.231 -      gen_write_ref_array_pre_barrier(/* dest */ c_rarg1, /* count */ c_rarg2);
   3.232 -    } else {
   3.233 -      disjoint_long_copy_entry = __ pc();
   3.234 +    if (entry != NULL) {
   3.235 +      *entry = __ pc();
   3.236 +      // caller can pass a 64-bit byte count here (from Unsafe.copyMemory)
   3.237 +      BLOCK_COMMENT("Entry:");
   3.238      }
   3.239 -    BLOCK_COMMENT("Entry:");
   3.240 -    // caller can pass a 64-bit byte count here (from Unsafe.copyMemory)
   3.241  
   3.242      setup_arg_regs(); // from => rdi, to => rsi, count => rdx
   3.243                        // r9 and r10 may be used to save non-volatile registers
   3.244 -
   3.245      // 'from', 'to' and 'qword_count' are now valid
   3.246 +    if (is_oop) {
   3.247 +      // no registers are destroyed by this call
   3.248 +      gen_write_ref_array_pre_barrier(to, qword_count);
   3.249 +    }
   3.250  
   3.251      // Copy from low to high addresses.  Use 'to' as scratch.
   3.252      __ lea(end_from, Address(from, qword_count, Address::times_8, -8));
   3.253 @@ -2045,7 +2038,8 @@
   3.254    //   c_rarg1   - destination array address
   3.255    //   c_rarg2   - element count, treated as ssize_t, can be zero
   3.256    //
   3.257 -  address generate_conjoint_long_oop_copy(bool aligned, bool is_oop, const char *name) {
   3.258 +  address generate_conjoint_long_oop_copy(bool aligned, bool is_oop, address nooverlap_target,
   3.259 +                                          address *entry, const char *name) {
   3.260      __ align(CodeEntryAlignment);
   3.261      StubCodeMark mark(this, "StubRoutines", name);
   3.262      address start = __ pc();
   3.263 @@ -2059,26 +2053,16 @@
   3.264      __ enter(); // required for proper stackwalking of RuntimeStub frame
   3.265      assert_clean_int(c_rarg2, rax);    // Make sure 'count' is clean int.
   3.266  
   3.267 -    address disjoint_copy_entry = NULL;
   3.268 -    if (is_oop) {
   3.269 -      assert(!UseCompressedOops, "shouldn't be called for compressed oops");
   3.270 -      disjoint_copy_entry = disjoint_oop_copy_entry;
   3.271 -      oop_copy_entry  = __ pc();
   3.272 -      array_overlap_test(disjoint_oop_copy_entry, Address::times_8);
   3.273 -    } else {
   3.274 -      disjoint_copy_entry = disjoint_long_copy_entry;
   3.275 -      long_copy_entry = __ pc();
   3.276 -      array_overlap_test(disjoint_long_copy_entry, Address::times_8);
   3.277 +    if (entry != NULL) {
   3.278 +      *entry = __ pc();
   3.279 +      // caller can pass a 64-bit byte count here (from Unsafe.copyMemory)
   3.280 +      BLOCK_COMMENT("Entry:");
   3.281      }
   3.282 -    BLOCK_COMMENT("Entry:");
   3.283 -    // caller can pass a 64-bit byte count here (from Unsafe.copyMemory)
   3.284 -
   3.285 -    array_overlap_test(disjoint_copy_entry, Address::times_8);
   3.286 +
   3.287 +    array_overlap_test(nooverlap_target, Address::times_8);
   3.288      setup_arg_regs(); // from => rdi, to => rsi, count => rdx
   3.289                        // r9 and r10 may be used to save non-volatile registers
   3.290 -
   3.291      // 'from', 'to' and 'qword_count' are now valid
   3.292 -
   3.293      if (is_oop) {
   3.294        // Save to and count for store barrier
   3.295        __ movptr(saved_count, qword_count);
   3.296 @@ -2162,7 +2146,7 @@
   3.297    //    rax ==  0  -  success
   3.298    //    rax == -1^K - failure, where K is partial transfer count
   3.299    //
   3.300 -  address generate_checkcast_copy(const char *name) {
   3.301 +  address generate_checkcast_copy(const char *name, address *entry) {
   3.302  
   3.303      Label L_load_element, L_store_element, L_do_card_marks, L_done;
   3.304  
   3.305 @@ -2216,8 +2200,10 @@
   3.306  #endif
   3.307  
   3.308      // Caller of this entry point must set up the argument registers.
   3.309 -    checkcast_copy_entry  = __ pc();
   3.310 -    BLOCK_COMMENT("Entry:");
   3.311 +    if (entry != NULL) {
   3.312 +      *entry = __ pc();
   3.313 +      BLOCK_COMMENT("Entry:");
   3.314 +    }
   3.315  
   3.316      // allocate spill slots for r13, r14
   3.317      enum {
   3.318 @@ -2334,7 +2320,9 @@
   3.319    // Examines the alignment of the operands and dispatches
   3.320    // to a long, int, short, or byte copy loop.
   3.321    //
   3.322 -  address generate_unsafe_copy(const char *name) {
   3.323 +  address generate_unsafe_copy(const char *name,
   3.324 +                               address byte_copy_entry, address short_copy_entry,
   3.325 +                               address int_copy_entry, address long_copy_entry) {
   3.326  
   3.327      Label L_long_aligned, L_int_aligned, L_short_aligned;
   3.328  
   3.329 @@ -2432,7 +2420,10 @@
   3.330    //    rax ==  0  -  success
   3.331    //    rax == -1^K - failure, where K is partial transfer count
   3.332    //
   3.333 -  address generate_generic_copy(const char *name) {
   3.334 +  address generate_generic_copy(const char *name,
   3.335 +                                address byte_copy_entry, address short_copy_entry,
   3.336 +                                address int_copy_entry, address long_copy_entry,
   3.337 +                                address oop_copy_entry, address checkcast_copy_entry) {
   3.338  
   3.339      Label L_failed, L_failed_0, L_objArray;
   3.340      Label L_copy_bytes, L_copy_shorts, L_copy_ints, L_copy_longs;
   3.341 @@ -2725,33 +2716,60 @@
   3.342    }
   3.343  
   3.344    void generate_arraycopy_stubs() {
   3.345 -    // Call the conjoint generation methods immediately after
   3.346 -    // the disjoint ones so that short branches from the former
   3.347 -    // to the latter can be generated.
   3.348 -    StubRoutines::_jbyte_disjoint_arraycopy  = generate_disjoint_byte_copy(false, "jbyte_disjoint_arraycopy");
   3.349 -    StubRoutines::_jbyte_arraycopy           = generate_conjoint_byte_copy(false, "jbyte_arraycopy");
   3.350 -
   3.351 -    StubRoutines::_jshort_disjoint_arraycopy = generate_disjoint_short_copy(false, "jshort_disjoint_arraycopy");
   3.352 -    StubRoutines::_jshort_arraycopy          = generate_conjoint_short_copy(false, "jshort_arraycopy");
   3.353 -
   3.354 -    StubRoutines::_jint_disjoint_arraycopy   = generate_disjoint_int_oop_copy(false, false, "jint_disjoint_arraycopy");
   3.355 -    StubRoutines::_jint_arraycopy            = generate_conjoint_int_oop_copy(false, false, "jint_arraycopy");
   3.356 -
   3.357 -    StubRoutines::_jlong_disjoint_arraycopy  = generate_disjoint_long_oop_copy(false, false, "jlong_disjoint_arraycopy");
   3.358 -    StubRoutines::_jlong_arraycopy           = generate_conjoint_long_oop_copy(false, false, "jlong_arraycopy");
   3.359 +    address entry;
   3.360 +    address entry_jbyte_arraycopy;
   3.361 +    address entry_jshort_arraycopy;
   3.362 +    address entry_jint_arraycopy;
   3.363 +    address entry_oop_arraycopy;
   3.364 +    address entry_jlong_arraycopy;
   3.365 +    address entry_checkcast_arraycopy;
   3.366 +
   3.367 +    StubRoutines::_jbyte_disjoint_arraycopy  = generate_disjoint_byte_copy(false, &entry,
   3.368 +                                                                           "jbyte_disjoint_arraycopy");
   3.369 +    StubRoutines::_jbyte_arraycopy           = generate_conjoint_byte_copy(false, entry, &entry_jbyte_arraycopy,
   3.370 +                                                                           "jbyte_arraycopy");
   3.371 +
   3.372 +    StubRoutines::_jshort_disjoint_arraycopy = generate_disjoint_short_copy(false, &entry,
   3.373 +                                                                            "jshort_disjoint_arraycopy");
   3.374 +    StubRoutines::_jshort_arraycopy          = generate_conjoint_short_copy(false, entry, &entry_jshort_arraycopy,
   3.375 +                                                                            "jshort_arraycopy");
   3.376 +
   3.377 +    StubRoutines::_jint_disjoint_arraycopy   = generate_disjoint_int_oop_copy(false, false, &entry,
   3.378 +                                                                              "jint_disjoint_arraycopy");
   3.379 +    StubRoutines::_jint_arraycopy            = generate_conjoint_int_oop_copy(false, false, entry,
   3.380 +                                                                              &entry_jint_arraycopy, "jint_arraycopy");
   3.381 +
   3.382 +    StubRoutines::_jlong_disjoint_arraycopy  = generate_disjoint_long_oop_copy(false, false, &entry,
   3.383 +                                                                               "jlong_disjoint_arraycopy");
   3.384 +    StubRoutines::_jlong_arraycopy           = generate_conjoint_long_oop_copy(false, false, entry,
   3.385 +                                                                               &entry_jlong_arraycopy, "jlong_arraycopy");
   3.386  
   3.387  
   3.388      if (UseCompressedOops) {
   3.389 -      StubRoutines::_oop_disjoint_arraycopy  = generate_disjoint_int_oop_copy(false, true, "oop_disjoint_arraycopy");
   3.390 -      StubRoutines::_oop_arraycopy           = generate_conjoint_int_oop_copy(false, true, "oop_arraycopy");
   3.391 +      StubRoutines::_oop_disjoint_arraycopy  = generate_disjoint_int_oop_copy(false, true, &entry,
   3.392 +                                                                              "oop_disjoint_arraycopy");
   3.393 +      StubRoutines::_oop_arraycopy           = generate_conjoint_int_oop_copy(false, true, entry,
   3.394 +                                                                              &entry_oop_arraycopy, "oop_arraycopy");
   3.395      } else {
   3.396 -      StubRoutines::_oop_disjoint_arraycopy  = generate_disjoint_long_oop_copy(false, true, "oop_disjoint_arraycopy");
   3.397 -      StubRoutines::_oop_arraycopy           = generate_conjoint_long_oop_copy(false, true, "oop_arraycopy");
   3.398 +      StubRoutines::_oop_disjoint_arraycopy  = generate_disjoint_long_oop_copy(false, true, &entry,
   3.399 +                                                                               "oop_disjoint_arraycopy");
   3.400 +      StubRoutines::_oop_arraycopy           = generate_conjoint_long_oop_copy(false, true, entry,
   3.401 +                                                                               &entry_oop_arraycopy, "oop_arraycopy");
   3.402      }
   3.403  
   3.404 -    StubRoutines::_checkcast_arraycopy = generate_checkcast_copy("checkcast_arraycopy");
   3.405 -    StubRoutines::_unsafe_arraycopy    = generate_unsafe_copy("unsafe_arraycopy");
   3.406 -    StubRoutines::_generic_arraycopy   = generate_generic_copy("generic_arraycopy");
   3.407 +    StubRoutines::_checkcast_arraycopy = generate_checkcast_copy("checkcast_arraycopy", &entry_checkcast_arraycopy);
   3.408 +    StubRoutines::_unsafe_arraycopy    = generate_unsafe_copy("unsafe_arraycopy",
   3.409 +                                                              entry_jbyte_arraycopy,
   3.410 +                                                              entry_jshort_arraycopy,
   3.411 +                                                              entry_jint_arraycopy,
   3.412 +                                                              entry_jlong_arraycopy);
   3.413 +    StubRoutines::_generic_arraycopy   = generate_generic_copy("generic_arraycopy",
   3.414 +                                                               entry_jbyte_arraycopy,
   3.415 +                                                               entry_jshort_arraycopy,
   3.416 +                                                               entry_jint_arraycopy,
   3.417 +                                                               entry_oop_arraycopy,
   3.418 +                                                               entry_jlong_arraycopy,
   3.419 +                                                               entry_checkcast_arraycopy);
   3.420  
   3.421      StubRoutines::_jbyte_fill = generate_fill(T_BYTE, false, "jbyte_fill");
   3.422      StubRoutines::_jshort_fill = generate_fill(T_SHORT, false, "jshort_fill");
   3.423 @@ -3069,20 +3087,6 @@
   3.424    }
   3.425  }; // end class declaration
   3.426  
   3.427 -address StubGenerator::disjoint_byte_copy_entry  = NULL;
   3.428 -address StubGenerator::disjoint_short_copy_entry = NULL;
   3.429 -address StubGenerator::disjoint_int_copy_entry   = NULL;
   3.430 -address StubGenerator::disjoint_long_copy_entry  = NULL;
   3.431 -address StubGenerator::disjoint_oop_copy_entry   = NULL;
   3.432 -
   3.433 -address StubGenerator::byte_copy_entry  = NULL;
   3.434 -address StubGenerator::short_copy_entry = NULL;
   3.435 -address StubGenerator::int_copy_entry   = NULL;
   3.436 -address StubGenerator::long_copy_entry  = NULL;
   3.437 -address StubGenerator::oop_copy_entry   = NULL;
   3.438 -
   3.439 -address StubGenerator::checkcast_copy_entry = NULL;
   3.440 -
   3.441  void StubGenerator_generate(CodeBuffer* code, bool all) {
   3.442    StubGenerator g(code, all);
   3.443  }

mercurial