< prev index next >

src/hotspot/cpu/x86/stubGenerator_x86_64_arraycopy.cpp

Print this page

3062   // Load layout helper (32-bits)
3063   //
3064   //  |array_tag|     | header_size | element_type |     |log2_element_size|
3065   // 32        30    24            16              8     2                 0
3066   //
3067   //   array_tag: typeArray = 0x3, objArray = 0x2, non-array = 0x0
3068   //
3069 
3070   const int lh_offset = in_bytes(Klass::layout_helper_offset());
3071 
3072   // Handle objArrays completely differently...
3073   const jint objArray_lh = Klass::array_layout_helper(T_OBJECT);
3074   __ cmpl(Address(r10_src_klass, lh_offset), objArray_lh);
3075   __ jcc(Assembler::equal, L_objArray);
3076 
3077   //  if (src->klass() != dst->klass()) return -1;
3078   __ load_klass(rax, dst, rklass_tmp);
3079   __ cmpq(r10_src_klass, rax);
3080   __ jcc(Assembler::notEqual, L_failed);
3081 






3082   const Register rax_lh = rax;  // layout helper
3083   __ movl(rax_lh, Address(r10_src_klass, lh_offset));
3084 




3085   //  if (!src->is_Array()) return -1;
3086   __ cmpl(rax_lh, Klass::_lh_neutral_value);
3087   __ jcc(Assembler::greaterEqual, L_failed);
3088 
3089   // At this point, it is known to be a typeArray (array_tag 0x3).
3090 #ifdef ASSERT
3091   {
3092     BLOCK_COMMENT("assert primitive array {");
3093     Label L;
3094     __ cmpl(rax_lh, (Klass::_lh_array_tag_type_value << Klass::_lh_array_tag_shift));
3095     __ jcc(Assembler::greaterEqual, L);


3096     __ stop("must be a primitive array");
3097     __ bind(L);
3098     BLOCK_COMMENT("} assert primitive array done");
3099   }
3100 #endif
3101 
3102   arraycopy_range_checks(src, src_pos, dst, dst_pos, r11_length,
3103                          r10, L_failed);
3104 
3105   // TypeArrayKlass
3106   //
3107   // src_addr = (src + array_header_in_bytes()) + (src_pos << log2elemsize);
3108   // dst_addr = (dst + array_header_in_bytes()) + (dst_pos << log2elemsize);
3109   //
3110 
3111   const Register r10_offset = r10;    // array offset
3112   const Register rax_elsize = rax_lh; // element size
3113 
3114   __ movl(r10_offset, rax_lh);
3115   __ shrl(r10_offset, Klass::_lh_header_size_shift);

3183 
3184   // Identically typed arrays can be copied without element-wise checks.
3185   arraycopy_range_checks(src, src_pos, dst, dst_pos, r11_length,
3186                          r10, L_failed);
3187 
3188   __ lea(from, Address(src, src_pos, TIMES_OOP,
3189                arrayOopDesc::base_offset_in_bytes(T_OBJECT))); // src_addr
3190   __ lea(to,   Address(dst, dst_pos, TIMES_OOP,
3191                arrayOopDesc::base_offset_in_bytes(T_OBJECT))); // dst_addr
3192   __ movl2ptr(count, r11_length); // length
3193 __ BIND(L_plain_copy);
3194 #ifdef _WIN64
3195   __ pop_ppx(rklass_tmp); // Restore callee-save rdi
3196 #endif
3197   __ jump(RuntimeAddress(oop_copy_entry));
3198 
3199 __ BIND(L_checkcast_copy);
3200   // live at this point:  r10_src_klass, r11_length, rax (dst_klass)
3201   {
3202     // Before looking at dst.length, make sure dst is also an objArray.

3203     __ cmpl(Address(rax, lh_offset), objArray_lh);
3204     __ jcc(Assembler::notEqual, L_failed);
3205 











3206     // It is safe to examine both src.length and dst.length.
3207     arraycopy_range_checks(src, src_pos, dst, dst_pos, r11_length,
3208                            rax, L_failed);
3209 
3210     const Register r11_dst_klass = r11;
3211     __ load_klass(r11_dst_klass, dst, rklass_tmp); // reload
3212 
3213     // Marshal the base address arguments now, freeing registers.
3214     __ lea(from, Address(src, src_pos, TIMES_OOP,
3215                  arrayOopDesc::base_offset_in_bytes(T_OBJECT)));
3216     __ lea(to,   Address(dst, dst_pos, TIMES_OOP,
3217                  arrayOopDesc::base_offset_in_bytes(T_OBJECT)));
3218     __ movl(count, length);           // length (reloaded)
3219     Register sco_temp = c_rarg3;      // this register is free now
3220     assert_different_registers(from, to, count, sco_temp,
3221                                r11_dst_klass, r10_src_klass);
3222     assert_clean_int(count, sco_temp);
3223 
3224     // Generate the type check.
3225     const int sco_offset = in_bytes(Klass::super_check_offset_offset());

3062   // Load layout helper (32-bits)
3063   //
3064   //  |array_tag|     | header_size | element_type |     |log2_element_size|
3065   // 32        30    24            16              8     2                 0
3066   //
3067   //   array_tag: typeArray = 0x3, objArray = 0x2, non-array = 0x0
3068   //
3069 
3070   const int lh_offset = in_bytes(Klass::layout_helper_offset());
3071 
3072   // Handle objArrays completely differently...
3073   const jint objArray_lh = Klass::array_layout_helper(T_OBJECT);
3074   __ cmpl(Address(r10_src_klass, lh_offset), objArray_lh);
3075   __ jcc(Assembler::equal, L_objArray);
3076 
3077   //  if (src->klass() != dst->klass()) return -1;
3078   __ load_klass(rax, dst, rklass_tmp);
3079   __ cmpq(r10_src_klass, rax);
3080   __ jcc(Assembler::notEqual, L_failed);
3081 
3082   // Check for flat inline type array -> return -1
3083   __ test_flat_array_oop(src, rax, L_failed);
3084 
3085   // Check for null-free (non-flat) inline type array -> handle as object array
3086   __ test_null_free_array_oop(src, rax, L_objArray);
3087 
3088   const Register rax_lh = rax;  // layout helper
3089   __ movl(rax_lh, Address(r10_src_klass, lh_offset));
3090 
3091   // Check for flat inline type array -> return -1
3092   __ testl(rax_lh, Klass::_lh_array_tag_flat_value_bit_inplace);
3093   __ jcc(Assembler::notZero, L_failed);
3094 
3095   //  if (!src->is_Array()) return -1;
3096   __ cmpl(rax_lh, Klass::_lh_neutral_value);
3097   __ jcc(Assembler::greaterEqual, L_failed);
3098 
3099   // At this point, it is known to be a typeArray (array_tag 0x3).
3100 #ifdef ASSERT
3101   {
3102     BLOCK_COMMENT("assert primitive array {");
3103     Label L;
3104     __ movl(rklass_tmp, rax_lh);
3105     __ sarl(rklass_tmp, Klass::_lh_array_tag_shift);
3106     __ cmpl(rklass_tmp, Klass::_lh_array_tag_type_value);
3107     __ jcc(Assembler::equal, L);
3108     __ stop("must be a primitive array");
3109     __ bind(L);
3110     BLOCK_COMMENT("} assert primitive array done");
3111   }
3112 #endif
3113 
3114   arraycopy_range_checks(src, src_pos, dst, dst_pos, r11_length,
3115                          r10, L_failed);
3116 
3117   // TypeArrayKlass
3118   //
3119   // src_addr = (src + array_header_in_bytes()) + (src_pos << log2elemsize);
3120   // dst_addr = (dst + array_header_in_bytes()) + (dst_pos << log2elemsize);
3121   //
3122 
3123   const Register r10_offset = r10;    // array offset
3124   const Register rax_elsize = rax_lh; // element size
3125 
3126   __ movl(r10_offset, rax_lh);
3127   __ shrl(r10_offset, Klass::_lh_header_size_shift);

3195 
3196   // Identically typed arrays can be copied without element-wise checks.
3197   arraycopy_range_checks(src, src_pos, dst, dst_pos, r11_length,
3198                          r10, L_failed);
3199 
3200   __ lea(from, Address(src, src_pos, TIMES_OOP,
3201                arrayOopDesc::base_offset_in_bytes(T_OBJECT))); // src_addr
3202   __ lea(to,   Address(dst, dst_pos, TIMES_OOP,
3203                arrayOopDesc::base_offset_in_bytes(T_OBJECT))); // dst_addr
3204   __ movl2ptr(count, r11_length); // length
3205 __ BIND(L_plain_copy);
3206 #ifdef _WIN64
3207   __ pop_ppx(rklass_tmp); // Restore callee-save rdi
3208 #endif
3209   __ jump(RuntimeAddress(oop_copy_entry));
3210 
3211 __ BIND(L_checkcast_copy);
3212   // live at this point:  r10_src_klass, r11_length, rax (dst_klass)
3213   {
3214     // Before looking at dst.length, make sure dst is also an objArray.
3215     // This check also fails for flat arrays which are not supported.
3216     __ cmpl(Address(rax, lh_offset), objArray_lh);
3217     __ jcc(Assembler::notEqual, L_failed);
3218 
3219 #ifdef ASSERT
3220     {
3221       BLOCK_COMMENT("assert not null-free array {");
3222       Label L;
3223       __ test_non_null_free_array_oop(dst, rklass_tmp, L);
3224       __ stop("unexpected null-free array");
3225       __ bind(L);
3226       BLOCK_COMMENT("} assert not null-free array");
3227     }
3228 #endif
3229 
3230     // It is safe to examine both src.length and dst.length.
3231     arraycopy_range_checks(src, src_pos, dst, dst_pos, r11_length,
3232                            rax, L_failed);
3233 
3234     const Register r11_dst_klass = r11;
3235     __ load_klass(r11_dst_klass, dst, rklass_tmp); // reload
3236 
3237     // Marshal the base address arguments now, freeing registers.
3238     __ lea(from, Address(src, src_pos, TIMES_OOP,
3239                  arrayOopDesc::base_offset_in_bytes(T_OBJECT)));
3240     __ lea(to,   Address(dst, dst_pos, TIMES_OOP,
3241                  arrayOopDesc::base_offset_in_bytes(T_OBJECT)));
3242     __ movl(count, length);           // length (reloaded)
3243     Register sco_temp = c_rarg3;      // this register is free now
3244     assert_different_registers(from, to, count, sco_temp,
3245                                r11_dst_klass, r10_src_klass);
3246     assert_clean_int(count, sco_temp);
3247 
3248     // Generate the type check.
3249     const int sco_offset = in_bytes(Klass::super_check_offset_offset());
< prev index next >