< prev index next >

src/hotspot/cpu/x86/stubGenerator_x86_64_arraycopy.cpp

Print this page

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






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




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


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

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

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











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

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

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