< prev index next >

src/hotspot/cpu/x86/stubGenerator_x86_64_arraycopy.cpp

Print this page

3019   // Load layout helper (32-bits)
3020   //
3021   //  |array_tag|     | header_size | element_type |     |log2_element_size|
3022   // 32        30    24            16              8     2                 0
3023   //
3024   //   array_tag: typeArray = 0x3, objArray = 0x2, non-array = 0x0
3025   //
3026 
3027   const int lh_offset = in_bytes(Klass::layout_helper_offset());
3028 
3029   // Handle objArrays completely differently...
3030   const jint objArray_lh = Klass::array_layout_helper(T_OBJECT);
3031   __ cmpl(Address(r10_src_klass, lh_offset), objArray_lh);
3032   __ jcc(Assembler::equal, L_objArray);
3033 
3034   //  if (src->klass() != dst->klass()) return -1;
3035   __ load_klass(rax, dst, rklass_tmp);
3036   __ cmpq(r10_src_klass, rax);
3037   __ jcc(Assembler::notEqual, L_failed);
3038 






3039   const Register rax_lh = rax;  // layout helper
3040   __ movl(rax_lh, Address(r10_src_klass, lh_offset));
3041 




3042   //  if (!src->is_Array()) return -1;
3043   __ cmpl(rax_lh, Klass::_lh_neutral_value);
3044   __ jcc(Assembler::greaterEqual, L_failed);
3045 
3046   // At this point, it is known to be a typeArray (array_tag 0x3).
3047 #ifdef ASSERT
3048   {
3049     BLOCK_COMMENT("assert primitive array {");
3050     Label L;
3051     __ cmpl(rax_lh, (Klass::_lh_array_tag_type_value << Klass::_lh_array_tag_shift));
3052     __ jcc(Assembler::greaterEqual, L);


3053     __ stop("must be a primitive array");
3054     __ bind(L);
3055     BLOCK_COMMENT("} assert primitive array done");
3056   }
3057 #endif
3058 
3059   arraycopy_range_checks(src, src_pos, dst, dst_pos, r11_length,
3060                          r10, L_failed);
3061 
3062   // TypeArrayKlass
3063   //
3064   // src_addr = (src + array_header_in_bytes()) + (src_pos << log2elemsize);
3065   // dst_addr = (dst + array_header_in_bytes()) + (dst_pos << log2elemsize);
3066   //
3067 
3068   const Register r10_offset = r10;    // array offset
3069   const Register rax_elsize = rax_lh; // element size
3070 
3071   __ movl(r10_offset, rax_lh);
3072   __ shrl(r10_offset, Klass::_lh_header_size_shift);

3140 
3141   // Identically typed arrays can be copied without element-wise checks.
3142   arraycopy_range_checks(src, src_pos, dst, dst_pos, r11_length,
3143                          r10, L_failed);
3144 
3145   __ lea(from, Address(src, src_pos, TIMES_OOP,
3146                arrayOopDesc::base_offset_in_bytes(T_OBJECT))); // src_addr
3147   __ lea(to,   Address(dst, dst_pos, TIMES_OOP,
3148                arrayOopDesc::base_offset_in_bytes(T_OBJECT))); // dst_addr
3149   __ movl2ptr(count, r11_length); // length
3150 __ BIND(L_plain_copy);
3151 #ifdef _WIN64
3152   __ pop(rklass_tmp); // Restore callee-save rdi
3153 #endif
3154   __ jump(RuntimeAddress(oop_copy_entry));
3155 
3156 __ BIND(L_checkcast_copy);
3157   // live at this point:  r10_src_klass, r11_length, rax (dst_klass)
3158   {
3159     // Before looking at dst.length, make sure dst is also an objArray.

3160     __ cmpl(Address(rax, lh_offset), objArray_lh);
3161     __ jcc(Assembler::notEqual, L_failed);
3162 











3163     // It is safe to examine both src.length and dst.length.
3164     arraycopy_range_checks(src, src_pos, dst, dst_pos, r11_length,
3165                            rax, L_failed);
3166 
3167     const Register r11_dst_klass = r11;
3168     __ load_klass(r11_dst_klass, dst, rklass_tmp); // reload
3169 
3170     // Marshal the base address arguments now, freeing registers.
3171     __ lea(from, Address(src, src_pos, TIMES_OOP,
3172                  arrayOopDesc::base_offset_in_bytes(T_OBJECT)));
3173     __ lea(to,   Address(dst, dst_pos, TIMES_OOP,
3174                  arrayOopDesc::base_offset_in_bytes(T_OBJECT)));
3175     __ movl(count, length);           // length (reloaded)
3176     Register sco_temp = c_rarg3;      // this register is free now
3177     assert_different_registers(from, to, count, sco_temp,
3178                                r11_dst_klass, r10_src_klass);
3179     assert_clean_int(count, sco_temp);
3180 
3181     // Generate the type check.
3182     const int sco_offset = in_bytes(Klass::super_check_offset_offset());

3019   // Load layout helper (32-bits)
3020   //
3021   //  |array_tag|     | header_size | element_type |     |log2_element_size|
3022   // 32        30    24            16              8     2                 0
3023   //
3024   //   array_tag: typeArray = 0x3, objArray = 0x2, non-array = 0x0
3025   //
3026 
3027   const int lh_offset = in_bytes(Klass::layout_helper_offset());
3028 
3029   // Handle objArrays completely differently...
3030   const jint objArray_lh = Klass::array_layout_helper(T_OBJECT);
3031   __ cmpl(Address(r10_src_klass, lh_offset), objArray_lh);
3032   __ jcc(Assembler::equal, L_objArray);
3033 
3034   //  if (src->klass() != dst->klass()) return -1;
3035   __ load_klass(rax, dst, rklass_tmp);
3036   __ cmpq(r10_src_klass, rax);
3037   __ jcc(Assembler::notEqual, L_failed);
3038 
3039   // Check for flat inline type array -> return -1
3040   __ test_flat_array_oop(src, rax, L_failed);
3041 
3042   // Check for null-free (non-flat) inline type array -> handle as object array
3043   __ test_null_free_array_oop(src, rax, L_objArray);
3044 
3045   const Register rax_lh = rax;  // layout helper
3046   __ movl(rax_lh, Address(r10_src_klass, lh_offset));
3047 
3048   // Check for flat inline type array -> return -1
3049   __ testl(rax_lh, Klass::_lh_array_tag_flat_value_bit_inplace);
3050   __ jcc(Assembler::notZero, L_failed);
3051 
3052   //  if (!src->is_Array()) return -1;
3053   __ cmpl(rax_lh, Klass::_lh_neutral_value);
3054   __ jcc(Assembler::greaterEqual, L_failed);
3055 
3056   // At this point, it is known to be a typeArray (array_tag 0x3).
3057 #ifdef ASSERT
3058   {
3059     BLOCK_COMMENT("assert primitive array {");
3060     Label L;
3061     __ movl(rklass_tmp, rax_lh);
3062     __ sarl(rklass_tmp, Klass::_lh_array_tag_shift);
3063     __ cmpl(rklass_tmp, Klass::_lh_array_tag_type_value);
3064     __ jcc(Assembler::equal, L);
3065     __ stop("must be a primitive array");
3066     __ bind(L);
3067     BLOCK_COMMENT("} assert primitive array done");
3068   }
3069 #endif
3070 
3071   arraycopy_range_checks(src, src_pos, dst, dst_pos, r11_length,
3072                          r10, L_failed);
3073 
3074   // TypeArrayKlass
3075   //
3076   // src_addr = (src + array_header_in_bytes()) + (src_pos << log2elemsize);
3077   // dst_addr = (dst + array_header_in_bytes()) + (dst_pos << log2elemsize);
3078   //
3079 
3080   const Register r10_offset = r10;    // array offset
3081   const Register rax_elsize = rax_lh; // element size
3082 
3083   __ movl(r10_offset, rax_lh);
3084   __ shrl(r10_offset, Klass::_lh_header_size_shift);

3152 
3153   // Identically typed arrays can be copied without element-wise checks.
3154   arraycopy_range_checks(src, src_pos, dst, dst_pos, r11_length,
3155                          r10, L_failed);
3156 
3157   __ lea(from, Address(src, src_pos, TIMES_OOP,
3158                arrayOopDesc::base_offset_in_bytes(T_OBJECT))); // src_addr
3159   __ lea(to,   Address(dst, dst_pos, TIMES_OOP,
3160                arrayOopDesc::base_offset_in_bytes(T_OBJECT))); // dst_addr
3161   __ movl2ptr(count, r11_length); // length
3162 __ BIND(L_plain_copy);
3163 #ifdef _WIN64
3164   __ pop(rklass_tmp); // Restore callee-save rdi
3165 #endif
3166   __ jump(RuntimeAddress(oop_copy_entry));
3167 
3168 __ BIND(L_checkcast_copy);
3169   // live at this point:  r10_src_klass, r11_length, rax (dst_klass)
3170   {
3171     // Before looking at dst.length, make sure dst is also an objArray.
3172     // This check also fails for flat arrays which are not supported.
3173     __ cmpl(Address(rax, lh_offset), objArray_lh);
3174     __ jcc(Assembler::notEqual, L_failed);
3175 
3176 #ifdef ASSERT
3177     {
3178       BLOCK_COMMENT("assert not null-free array {");
3179       Label L;
3180       __ test_non_null_free_array_oop(dst, rklass_tmp, L);
3181       __ stop("unexpected null-free array");
3182       __ bind(L);
3183       BLOCK_COMMENT("} assert not null-free array");
3184     }
3185 #endif
3186 
3187     // It is safe to examine both src.length and dst.length.
3188     arraycopy_range_checks(src, src_pos, dst, dst_pos, r11_length,
3189                            rax, L_failed);
3190 
3191     const Register r11_dst_klass = r11;
3192     __ load_klass(r11_dst_klass, dst, rklass_tmp); // reload
3193 
3194     // Marshal the base address arguments now, freeing registers.
3195     __ lea(from, Address(src, src_pos, TIMES_OOP,
3196                  arrayOopDesc::base_offset_in_bytes(T_OBJECT)));
3197     __ lea(to,   Address(dst, dst_pos, TIMES_OOP,
3198                  arrayOopDesc::base_offset_in_bytes(T_OBJECT)));
3199     __ movl(count, length);           // length (reloaded)
3200     Register sco_temp = c_rarg3;      // this register is free now
3201     assert_different_registers(from, to, count, sco_temp,
3202                                r11_dst_klass, r10_src_klass);
3203     assert_clean_int(count, sco_temp);
3204 
3205     // Generate the type check.
3206     const int sco_offset = in_bytes(Klass::super_check_offset_offset());
< prev index next >