< prev index next >

src/hotspot/cpu/x86/stubGenerator_x86_64_arraycopy.cpp

Print this page

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






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




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


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

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

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











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

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

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