< prev index next >

src/hotspot/cpu/x86/stubGenerator_x86_64_arraycopy.cpp

Print this page

2641   // Load layout helper (32-bits)
2642   //
2643   //  |array_tag|     | header_size | element_type |     |log2_element_size|
2644   // 32        30    24            16              8     2                 0
2645   //
2646   //   array_tag: typeArray = 0x3, objArray = 0x2, non-array = 0x0
2647   //
2648 
2649   const int lh_offset = in_bytes(Klass::layout_helper_offset());
2650 
2651   // Handle objArrays completely differently...
2652   const jint objArray_lh = Klass::array_layout_helper(T_OBJECT);
2653   __ cmpl(Address(r10_src_klass, lh_offset), objArray_lh);
2654   __ jcc(Assembler::equal, L_objArray);
2655 
2656   //  if (src->klass() != dst->klass()) return -1;
2657   __ load_klass(rax, dst, rklass_tmp);
2658   __ cmpq(r10_src_klass, rax);
2659   __ jcc(Assembler::notEqual, L_failed);
2660 






2661   const Register rax_lh = rax;  // layout helper
2662   __ movl(rax_lh, Address(r10_src_klass, lh_offset));
2663 




2664   //  if (!src->is_Array()) return -1;
2665   __ cmpl(rax_lh, Klass::_lh_neutral_value);
2666   __ jcc(Assembler::greaterEqual, L_failed);
2667 
2668   // At this point, it is known to be a typeArray (array_tag 0x3).
2669 #ifdef ASSERT
2670   {
2671     BLOCK_COMMENT("assert primitive array {");
2672     Label L;
2673     __ cmpl(rax_lh, (Klass::_lh_array_tag_type_value << Klass::_lh_array_tag_shift));
2674     __ jcc(Assembler::greaterEqual, L);


2675     __ stop("must be a primitive array");
2676     __ bind(L);
2677     BLOCK_COMMENT("} assert primitive array done");
2678   }
2679 #endif
2680 
2681   arraycopy_range_checks(src, src_pos, dst, dst_pos, r11_length,
2682                          r10, L_failed);
2683 
2684   // TypeArrayKlass
2685   //
2686   // src_addr = (src + array_header_in_bytes()) + (src_pos << log2elemsize);
2687   // dst_addr = (dst + array_header_in_bytes()) + (dst_pos << log2elemsize);
2688   //
2689 
2690   const Register r10_offset = r10;    // array offset
2691   const Register rax_elsize = rax_lh; // element size
2692 
2693   __ movl(r10_offset, rax_lh);
2694   __ shrl(r10_offset, Klass::_lh_header_size_shift);

2762 
2763   // Identically typed arrays can be copied without element-wise checks.
2764   arraycopy_range_checks(src, src_pos, dst, dst_pos, r11_length,
2765                          r10, L_failed);
2766 
2767   __ lea(from, Address(src, src_pos, TIMES_OOP,
2768                arrayOopDesc::base_offset_in_bytes(T_OBJECT))); // src_addr
2769   __ lea(to,   Address(dst, dst_pos, TIMES_OOP,
2770                arrayOopDesc::base_offset_in_bytes(T_OBJECT))); // dst_addr
2771   __ movl2ptr(count, r11_length); // length
2772 __ BIND(L_plain_copy);
2773 #ifdef _WIN64
2774   __ pop(rklass_tmp); // Restore callee-save rdi
2775 #endif
2776   __ jump(RuntimeAddress(oop_copy_entry));
2777 
2778 __ BIND(L_checkcast_copy);
2779   // live at this point:  r10_src_klass, r11_length, rax (dst_klass)
2780   {
2781     // Before looking at dst.length, make sure dst is also an objArray.

2782     __ cmpl(Address(rax, lh_offset), objArray_lh);
2783     __ jcc(Assembler::notEqual, L_failed);
2784 











2785     // It is safe to examine both src.length and dst.length.
2786     arraycopy_range_checks(src, src_pos, dst, dst_pos, r11_length,
2787                            rax, L_failed);
2788 
2789     const Register r11_dst_klass = r11;
2790     __ load_klass(r11_dst_klass, dst, rklass_tmp); // reload
2791 
2792     // Marshal the base address arguments now, freeing registers.
2793     __ lea(from, Address(src, src_pos, TIMES_OOP,
2794                  arrayOopDesc::base_offset_in_bytes(T_OBJECT)));
2795     __ lea(to,   Address(dst, dst_pos, TIMES_OOP,
2796                  arrayOopDesc::base_offset_in_bytes(T_OBJECT)));
2797     __ movl(count, length);           // length (reloaded)
2798     Register sco_temp = c_rarg3;      // this register is free now
2799     assert_different_registers(from, to, count, sco_temp,
2800                                r11_dst_klass, r10_src_klass);
2801     assert_clean_int(count, sco_temp);
2802 
2803     // Generate the type check.
2804     const int sco_offset = in_bytes(Klass::super_check_offset_offset());

2641   // Load layout helper (32-bits)
2642   //
2643   //  |array_tag|     | header_size | element_type |     |log2_element_size|
2644   // 32        30    24            16              8     2                 0
2645   //
2646   //   array_tag: typeArray = 0x3, objArray = 0x2, non-array = 0x0
2647   //
2648 
2649   const int lh_offset = in_bytes(Klass::layout_helper_offset());
2650 
2651   // Handle objArrays completely differently...
2652   const jint objArray_lh = Klass::array_layout_helper(T_OBJECT);
2653   __ cmpl(Address(r10_src_klass, lh_offset), objArray_lh);
2654   __ jcc(Assembler::equal, L_objArray);
2655 
2656   //  if (src->klass() != dst->klass()) return -1;
2657   __ load_klass(rax, dst, rklass_tmp);
2658   __ cmpq(r10_src_klass, rax);
2659   __ jcc(Assembler::notEqual, L_failed);
2660 
2661   // Check for flat inline type array -> return -1
2662   __ test_flat_array_oop(src, rax, L_failed);
2663 
2664   // Check for null-free (non-flat) inline type array -> handle as object array
2665   __ test_null_free_array_oop(src, rax, L_objArray);
2666 
2667   const Register rax_lh = rax;  // layout helper
2668   __ movl(rax_lh, Address(r10_src_klass, lh_offset));
2669 
2670   // Check for flat inline type array -> return -1
2671   __ testl(rax_lh, Klass::_lh_array_tag_flat_value_bit_inplace);
2672   __ jcc(Assembler::notZero, L_failed);
2673 
2674   //  if (!src->is_Array()) return -1;
2675   __ cmpl(rax_lh, Klass::_lh_neutral_value);
2676   __ jcc(Assembler::greaterEqual, L_failed);
2677 
2678   // At this point, it is known to be a typeArray (array_tag 0x3).
2679 #ifdef ASSERT
2680   {
2681     BLOCK_COMMENT("assert primitive array {");
2682     Label L;
2683     __ movl(rklass_tmp, rax_lh);
2684     __ sarl(rklass_tmp, Klass::_lh_array_tag_shift);
2685     __ cmpl(rklass_tmp, Klass::_lh_array_tag_type_value);
2686     __ jcc(Assembler::equal, L);
2687     __ stop("must be a primitive array");
2688     __ bind(L);
2689     BLOCK_COMMENT("} assert primitive array done");
2690   }
2691 #endif
2692 
2693   arraycopy_range_checks(src, src_pos, dst, dst_pos, r11_length,
2694                          r10, L_failed);
2695 
2696   // TypeArrayKlass
2697   //
2698   // src_addr = (src + array_header_in_bytes()) + (src_pos << log2elemsize);
2699   // dst_addr = (dst + array_header_in_bytes()) + (dst_pos << log2elemsize);
2700   //
2701 
2702   const Register r10_offset = r10;    // array offset
2703   const Register rax_elsize = rax_lh; // element size
2704 
2705   __ movl(r10_offset, rax_lh);
2706   __ shrl(r10_offset, Klass::_lh_header_size_shift);

2774 
2775   // Identically typed arrays can be copied without element-wise checks.
2776   arraycopy_range_checks(src, src_pos, dst, dst_pos, r11_length,
2777                          r10, L_failed);
2778 
2779   __ lea(from, Address(src, src_pos, TIMES_OOP,
2780                arrayOopDesc::base_offset_in_bytes(T_OBJECT))); // src_addr
2781   __ lea(to,   Address(dst, dst_pos, TIMES_OOP,
2782                arrayOopDesc::base_offset_in_bytes(T_OBJECT))); // dst_addr
2783   __ movl2ptr(count, r11_length); // length
2784 __ BIND(L_plain_copy);
2785 #ifdef _WIN64
2786   __ pop(rklass_tmp); // Restore callee-save rdi
2787 #endif
2788   __ jump(RuntimeAddress(oop_copy_entry));
2789 
2790 __ BIND(L_checkcast_copy);
2791   // live at this point:  r10_src_klass, r11_length, rax (dst_klass)
2792   {
2793     // Before looking at dst.length, make sure dst is also an objArray.
2794     // This check also fails for flat arrays which are not supported.
2795     __ cmpl(Address(rax, lh_offset), objArray_lh);
2796     __ jcc(Assembler::notEqual, L_failed);
2797 
2798 #ifdef ASSERT
2799     {
2800       BLOCK_COMMENT("assert not null-free array {");
2801       Label L;
2802       __ test_non_null_free_array_oop(dst, rklass_tmp, L);
2803       __ stop("unexpected null-free array");
2804       __ bind(L);
2805       BLOCK_COMMENT("} assert not null-free array");
2806     }
2807 #endif
2808 
2809     // It is safe to examine both src.length and dst.length.
2810     arraycopy_range_checks(src, src_pos, dst, dst_pos, r11_length,
2811                            rax, L_failed);
2812 
2813     const Register r11_dst_klass = r11;
2814     __ load_klass(r11_dst_klass, dst, rklass_tmp); // reload
2815 
2816     // Marshal the base address arguments now, freeing registers.
2817     __ lea(from, Address(src, src_pos, TIMES_OOP,
2818                  arrayOopDesc::base_offset_in_bytes(T_OBJECT)));
2819     __ lea(to,   Address(dst, dst_pos, TIMES_OOP,
2820                  arrayOopDesc::base_offset_in_bytes(T_OBJECT)));
2821     __ movl(count, length);           // length (reloaded)
2822     Register sco_temp = c_rarg3;      // this register is free now
2823     assert_different_registers(from, to, count, sco_temp,
2824                                r11_dst_klass, r10_src_klass);
2825     assert_clean_int(count, sco_temp);
2826 
2827     // Generate the type check.
2828     const int sco_offset = in_bytes(Klass::super_check_offset_offset());
< prev index next >