< prev index next >

src/hotspot/cpu/x86/stubGenerator_x86_64_arraycopy.cpp

Print this page

2841   // Load layout helper (32-bits)
2842   //
2843   //  |array_tag|     | header_size | element_type |     |log2_element_size|
2844   // 32        30    24            16              8     2                 0
2845   //
2846   //   array_tag: typeArray = 0x3, objArray = 0x2, non-array = 0x0
2847   //
2848 
2849   const int lh_offset = in_bytes(Klass::layout_helper_offset());
2850 
2851   // Handle objArrays completely differently...
2852   const jint objArray_lh = Klass::array_layout_helper(T_OBJECT);
2853   __ cmpl(Address(r10_src_klass, lh_offset), objArray_lh);
2854   __ jcc(Assembler::equal, L_objArray);
2855 
2856   //  if (src->klass() != dst->klass()) return -1;
2857   __ load_klass(rax, dst, rklass_tmp);
2858   __ cmpq(r10_src_klass, rax);
2859   __ jcc(Assembler::notEqual, L_failed);
2860 






2861   const Register rax_lh = rax;  // layout helper
2862   __ movl(rax_lh, Address(r10_src_klass, lh_offset));
2863 




2864   //  if (!src->is_Array()) return -1;
2865   __ cmpl(rax_lh, Klass::_lh_neutral_value);
2866   __ jcc(Assembler::greaterEqual, L_failed);
2867 
2868   // At this point, it is known to be a typeArray (array_tag 0x3).
2869 #ifdef ASSERT
2870   {
2871     BLOCK_COMMENT("assert primitive array {");
2872     Label L;
2873     __ cmpl(rax_lh, (Klass::_lh_array_tag_type_value << Klass::_lh_array_tag_shift));
2874     __ jcc(Assembler::greaterEqual, L);


2875     __ stop("must be a primitive array");
2876     __ bind(L);
2877     BLOCK_COMMENT("} assert primitive array done");
2878   }
2879 #endif
2880 
2881   arraycopy_range_checks(src, src_pos, dst, dst_pos, r11_length,
2882                          r10, L_failed);
2883 
2884   // TypeArrayKlass
2885   //
2886   // src_addr = (src + array_header_in_bytes()) + (src_pos << log2elemsize);
2887   // dst_addr = (dst + array_header_in_bytes()) + (dst_pos << log2elemsize);
2888   //
2889 
2890   const Register r10_offset = r10;    // array offset
2891   const Register rax_elsize = rax_lh; // element size
2892 
2893   __ movl(r10_offset, rax_lh);
2894   __ shrl(r10_offset, Klass::_lh_header_size_shift);

2962 
2963   // Identically typed arrays can be copied without element-wise checks.
2964   arraycopy_range_checks(src, src_pos, dst, dst_pos, r11_length,
2965                          r10, L_failed);
2966 
2967   __ lea(from, Address(src, src_pos, TIMES_OOP,
2968                arrayOopDesc::base_offset_in_bytes(T_OBJECT))); // src_addr
2969   __ lea(to,   Address(dst, dst_pos, TIMES_OOP,
2970                arrayOopDesc::base_offset_in_bytes(T_OBJECT))); // dst_addr
2971   __ movl2ptr(count, r11_length); // length
2972 __ BIND(L_plain_copy);
2973 #ifdef _WIN64
2974   __ pop(rklass_tmp); // Restore callee-save rdi
2975 #endif
2976   __ jump(RuntimeAddress(oop_copy_entry));
2977 
2978 __ BIND(L_checkcast_copy);
2979   // live at this point:  r10_src_klass, r11_length, rax (dst_klass)
2980   {
2981     // Before looking at dst.length, make sure dst is also an objArray.

2982     __ cmpl(Address(rax, lh_offset), objArray_lh);
2983     __ jcc(Assembler::notEqual, L_failed);
2984 











2985     // It is safe to examine both src.length and dst.length.
2986     arraycopy_range_checks(src, src_pos, dst, dst_pos, r11_length,
2987                            rax, L_failed);
2988 
2989     const Register r11_dst_klass = r11;
2990     __ load_klass(r11_dst_klass, dst, rklass_tmp); // reload
2991 
2992     // Marshal the base address arguments now, freeing registers.
2993     __ lea(from, Address(src, src_pos, TIMES_OOP,
2994                  arrayOopDesc::base_offset_in_bytes(T_OBJECT)));
2995     __ lea(to,   Address(dst, dst_pos, TIMES_OOP,
2996                  arrayOopDesc::base_offset_in_bytes(T_OBJECT)));
2997     __ movl(count, length);           // length (reloaded)
2998     Register sco_temp = c_rarg3;      // this register is free now
2999     assert_different_registers(from, to, count, sco_temp,
3000                                r11_dst_klass, r10_src_klass);
3001     assert_clean_int(count, sco_temp);
3002 
3003     // Generate the type check.
3004     const int sco_offset = in_bytes(Klass::super_check_offset_offset());

2841   // Load layout helper (32-bits)
2842   //
2843   //  |array_tag|     | header_size | element_type |     |log2_element_size|
2844   // 32        30    24            16              8     2                 0
2845   //
2846   //   array_tag: typeArray = 0x3, objArray = 0x2, non-array = 0x0
2847   //
2848 
2849   const int lh_offset = in_bytes(Klass::layout_helper_offset());
2850 
2851   // Handle objArrays completely differently...
2852   const jint objArray_lh = Klass::array_layout_helper(T_OBJECT);
2853   __ cmpl(Address(r10_src_klass, lh_offset), objArray_lh);
2854   __ jcc(Assembler::equal, L_objArray);
2855 
2856   //  if (src->klass() != dst->klass()) return -1;
2857   __ load_klass(rax, dst, rklass_tmp);
2858   __ cmpq(r10_src_klass, rax);
2859   __ jcc(Assembler::notEqual, L_failed);
2860 
2861   // Check for flat inline type array -> return -1
2862   __ test_flat_array_oop(src, rax, L_failed);
2863 
2864   // Check for null-free (non-flat) inline type array -> handle as object array
2865   __ test_null_free_array_oop(src, rax, L_objArray);
2866 
2867   const Register rax_lh = rax;  // layout helper
2868   __ movl(rax_lh, Address(r10_src_klass, lh_offset));
2869 
2870   // Check for flat inline type array -> return -1
2871   __ testl(rax_lh, Klass::_lh_array_tag_flat_value_bit_inplace);
2872   __ jcc(Assembler::notZero, L_failed);
2873 
2874   //  if (!src->is_Array()) return -1;
2875   __ cmpl(rax_lh, Klass::_lh_neutral_value);
2876   __ jcc(Assembler::greaterEqual, L_failed);
2877 
2878   // At this point, it is known to be a typeArray (array_tag 0x3).
2879 #ifdef ASSERT
2880   {
2881     BLOCK_COMMENT("assert primitive array {");
2882     Label L;
2883     __ movl(rklass_tmp, rax_lh);
2884     __ sarl(rklass_tmp, Klass::_lh_array_tag_shift);
2885     __ cmpl(rklass_tmp, Klass::_lh_array_tag_type_value);
2886     __ jcc(Assembler::equal, L);
2887     __ stop("must be a primitive array");
2888     __ bind(L);
2889     BLOCK_COMMENT("} assert primitive array done");
2890   }
2891 #endif
2892 
2893   arraycopy_range_checks(src, src_pos, dst, dst_pos, r11_length,
2894                          r10, L_failed);
2895 
2896   // TypeArrayKlass
2897   //
2898   // src_addr = (src + array_header_in_bytes()) + (src_pos << log2elemsize);
2899   // dst_addr = (dst + array_header_in_bytes()) + (dst_pos << log2elemsize);
2900   //
2901 
2902   const Register r10_offset = r10;    // array offset
2903   const Register rax_elsize = rax_lh; // element size
2904 
2905   __ movl(r10_offset, rax_lh);
2906   __ shrl(r10_offset, Klass::_lh_header_size_shift);

2974 
2975   // Identically typed arrays can be copied without element-wise checks.
2976   arraycopy_range_checks(src, src_pos, dst, dst_pos, r11_length,
2977                          r10, L_failed);
2978 
2979   __ lea(from, Address(src, src_pos, TIMES_OOP,
2980                arrayOopDesc::base_offset_in_bytes(T_OBJECT))); // src_addr
2981   __ lea(to,   Address(dst, dst_pos, TIMES_OOP,
2982                arrayOopDesc::base_offset_in_bytes(T_OBJECT))); // dst_addr
2983   __ movl2ptr(count, r11_length); // length
2984 __ BIND(L_plain_copy);
2985 #ifdef _WIN64
2986   __ pop(rklass_tmp); // Restore callee-save rdi
2987 #endif
2988   __ jump(RuntimeAddress(oop_copy_entry));
2989 
2990 __ BIND(L_checkcast_copy);
2991   // live at this point:  r10_src_klass, r11_length, rax (dst_klass)
2992   {
2993     // Before looking at dst.length, make sure dst is also an objArray.
2994     // This check also fails for flat arrays which are not supported.
2995     __ cmpl(Address(rax, lh_offset), objArray_lh);
2996     __ jcc(Assembler::notEqual, L_failed);
2997 
2998 #ifdef ASSERT
2999     {
3000       BLOCK_COMMENT("assert not null-free array {");
3001       Label L;
3002       __ test_non_null_free_array_oop(dst, rklass_tmp, L);
3003       __ stop("unexpected null-free array");
3004       __ bind(L);
3005       BLOCK_COMMENT("} assert not null-free array");
3006     }
3007 #endif
3008 
3009     // It is safe to examine both src.length and dst.length.
3010     arraycopy_range_checks(src, src_pos, dst, dst_pos, r11_length,
3011                            rax, L_failed);
3012 
3013     const Register r11_dst_klass = r11;
3014     __ load_klass(r11_dst_klass, dst, rklass_tmp); // reload
3015 
3016     // Marshal the base address arguments now, freeing registers.
3017     __ lea(from, Address(src, src_pos, TIMES_OOP,
3018                  arrayOopDesc::base_offset_in_bytes(T_OBJECT)));
3019     __ lea(to,   Address(dst, dst_pos, TIMES_OOP,
3020                  arrayOopDesc::base_offset_in_bytes(T_OBJECT)));
3021     __ movl(count, length);           // length (reloaded)
3022     Register sco_temp = c_rarg3;      // this register is free now
3023     assert_different_registers(from, to, count, sco_temp,
3024                                r11_dst_klass, r10_src_klass);
3025     assert_clean_int(count, sco_temp);
3026 
3027     // Generate the type check.
3028     const int sco_offset = in_bytes(Klass::super_check_offset_offset());
< prev index next >