< prev index next >

src/hotspot/cpu/x86/stubGenerator_x86_64_arraycopy.cpp

Print this page

3584   // Load layout helper (32-bits)
3585   //
3586   //  |array_tag|     | header_size | element_type |     |log2_element_size|
3587   // 32        30    24            16              8     2                 0
3588   //
3589   //   array_tag: typeArray = 0x3, objArray = 0x2, non-array = 0x0
3590   //
3591 
3592   const int lh_offset = in_bytes(Klass::layout_helper_offset());
3593 
3594   // Handle objArrays completely differently...
3595   const jint objArray_lh = Klass::array_layout_helper(T_OBJECT);
3596   __ cmpl(Address(r10_src_klass, lh_offset), objArray_lh);
3597   __ jcc(Assembler::equal, L_objArray);
3598 
3599   //  if (src->klass() != dst->klass()) return -1;
3600   __ load_klass(rax, dst, rklass_tmp);
3601   __ cmpq(r10_src_klass, rax);
3602   __ jcc(Assembler::notEqual, L_failed);
3603 






3604   const Register rax_lh = rax;  // layout helper
3605   __ movl(rax_lh, Address(r10_src_klass, lh_offset));
3606 




3607   //  if (!src->is_Array()) return -1;
3608   __ cmpl(rax_lh, Klass::_lh_neutral_value);
3609   __ jcc(Assembler::greaterEqual, L_failed);
3610 
3611   // At this point, it is known to be a typeArray (array_tag 0x3).
3612 #ifdef ASSERT
3613   {
3614     BLOCK_COMMENT("assert primitive array {");
3615     Label L;
3616     __ cmpl(rax_lh, (Klass::_lh_array_tag_type_value << Klass::_lh_array_tag_shift));
3617     __ jcc(Assembler::greaterEqual, L);


3618     __ stop("must be a primitive array");
3619     __ bind(L);
3620     BLOCK_COMMENT("} assert primitive array done");
3621   }
3622 #endif
3623 
3624   arraycopy_range_checks(src, src_pos, dst, dst_pos, r11_length,
3625                          r10, L_failed);
3626 
3627   // TypeArrayKlass
3628   //
3629   // src_addr = (src + array_header_in_bytes()) + (src_pos << log2elemsize);
3630   // dst_addr = (dst + array_header_in_bytes()) + (dst_pos << log2elemsize);
3631   //
3632 
3633   const Register r10_offset = r10;    // array offset
3634   const Register rax_elsize = rax_lh; // element size
3635 
3636   __ movl(r10_offset, rax_lh);
3637   __ shrl(r10_offset, Klass::_lh_header_size_shift);

3705 
3706   // Identically typed arrays can be copied without element-wise checks.
3707   arraycopy_range_checks(src, src_pos, dst, dst_pos, r11_length,
3708                          r10, L_failed);
3709 
3710   __ lea(from, Address(src, src_pos, TIMES_OOP,
3711                arrayOopDesc::base_offset_in_bytes(T_OBJECT))); // src_addr
3712   __ lea(to,   Address(dst, dst_pos, TIMES_OOP,
3713                arrayOopDesc::base_offset_in_bytes(T_OBJECT))); // dst_addr
3714   __ movl2ptr(count, r11_length); // length
3715 __ BIND(L_plain_copy);
3716 #ifdef _WIN64
3717   __ pop_ppx(rklass_tmp); // Restore callee-save rdi
3718 #endif
3719   __ jump(RuntimeAddress(oop_copy_entry));
3720 
3721 __ BIND(L_checkcast_copy);
3722   // live at this point:  r10_src_klass, r11_length, rax (dst_klass)
3723   {
3724     // Before looking at dst.length, make sure dst is also an objArray.

3725     __ cmpl(Address(rax, lh_offset), objArray_lh);
3726     __ jcc(Assembler::notEqual, L_failed);
3727 











3728     // It is safe to examine both src.length and dst.length.
3729     arraycopy_range_checks(src, src_pos, dst, dst_pos, r11_length,
3730                            rax, L_failed);
3731 
3732     const Register r11_dst_klass = r11;
3733     __ load_klass(r11_dst_klass, dst, rklass_tmp); // reload
3734 
3735     // Marshal the base address arguments now, freeing registers.
3736     __ lea(from, Address(src, src_pos, TIMES_OOP,
3737                  arrayOopDesc::base_offset_in_bytes(T_OBJECT)));
3738     __ lea(to,   Address(dst, dst_pos, TIMES_OOP,
3739                  arrayOopDesc::base_offset_in_bytes(T_OBJECT)));
3740     __ movl(count, length);           // length (reloaded)
3741     Register sco_temp = c_rarg3;      // this register is free now
3742     assert_different_registers(from, to, count, sco_temp,
3743                                r11_dst_klass, r10_src_klass);
3744     assert_clean_int(count, sco_temp);
3745 
3746     // Generate the type check.
3747     const int sco_offset = in_bytes(Klass::super_check_offset_offset());

3584   // Load layout helper (32-bits)
3585   //
3586   //  |array_tag|     | header_size | element_type |     |log2_element_size|
3587   // 32        30    24            16              8     2                 0
3588   //
3589   //   array_tag: typeArray = 0x3, objArray = 0x2, non-array = 0x0
3590   //
3591 
3592   const int lh_offset = in_bytes(Klass::layout_helper_offset());
3593 
3594   // Handle objArrays completely differently...
3595   const jint objArray_lh = Klass::array_layout_helper(T_OBJECT);
3596   __ cmpl(Address(r10_src_klass, lh_offset), objArray_lh);
3597   __ jcc(Assembler::equal, L_objArray);
3598 
3599   //  if (src->klass() != dst->klass()) return -1;
3600   __ load_klass(rax, dst, rklass_tmp);
3601   __ cmpq(r10_src_klass, rax);
3602   __ jcc(Assembler::notEqual, L_failed);
3603 
3604   // Check for flat inline type array -> return -1
3605   __ test_flat_array_oop(src, rax, L_failed);
3606 
3607   // Check for null-free (non-flat) inline type array -> handle as object array
3608   __ test_null_free_array_oop(src, rax, L_objArray);
3609 
3610   const Register rax_lh = rax;  // layout helper
3611   __ movl(rax_lh, Address(r10_src_klass, lh_offset));
3612 
3613   // Check for flat inline type array -> return -1
3614   __ testl(rax_lh, Klass::_lh_array_tag_flat_value_bit_inplace);
3615   __ jcc(Assembler::notZero, L_failed);
3616 
3617   //  if (!src->is_Array()) return -1;
3618   __ cmpl(rax_lh, Klass::_lh_neutral_value);
3619   __ jcc(Assembler::greaterEqual, L_failed);
3620 
3621   // At this point, it is known to be a typeArray (array_tag 0x3).
3622 #ifdef ASSERT
3623   {
3624     BLOCK_COMMENT("assert primitive array {");
3625     Label L;
3626     __ movl(rklass_tmp, rax_lh);
3627     __ sarl(rklass_tmp, Klass::_lh_array_tag_shift);
3628     __ cmpl(rklass_tmp, Klass::_lh_array_tag_type_value);
3629     __ jcc(Assembler::equal, L);
3630     __ stop("must be a primitive array");
3631     __ bind(L);
3632     BLOCK_COMMENT("} assert primitive array done");
3633   }
3634 #endif
3635 
3636   arraycopy_range_checks(src, src_pos, dst, dst_pos, r11_length,
3637                          r10, L_failed);
3638 
3639   // TypeArrayKlass
3640   //
3641   // src_addr = (src + array_header_in_bytes()) + (src_pos << log2elemsize);
3642   // dst_addr = (dst + array_header_in_bytes()) + (dst_pos << log2elemsize);
3643   //
3644 
3645   const Register r10_offset = r10;    // array offset
3646   const Register rax_elsize = rax_lh; // element size
3647 
3648   __ movl(r10_offset, rax_lh);
3649   __ shrl(r10_offset, Klass::_lh_header_size_shift);

3717 
3718   // Identically typed arrays can be copied without element-wise checks.
3719   arraycopy_range_checks(src, src_pos, dst, dst_pos, r11_length,
3720                          r10, L_failed);
3721 
3722   __ lea(from, Address(src, src_pos, TIMES_OOP,
3723                arrayOopDesc::base_offset_in_bytes(T_OBJECT))); // src_addr
3724   __ lea(to,   Address(dst, dst_pos, TIMES_OOP,
3725                arrayOopDesc::base_offset_in_bytes(T_OBJECT))); // dst_addr
3726   __ movl2ptr(count, r11_length); // length
3727 __ BIND(L_plain_copy);
3728 #ifdef _WIN64
3729   __ pop_ppx(rklass_tmp); // Restore callee-save rdi
3730 #endif
3731   __ jump(RuntimeAddress(oop_copy_entry));
3732 
3733 __ BIND(L_checkcast_copy);
3734   // live at this point:  r10_src_klass, r11_length, rax (dst_klass)
3735   {
3736     // Before looking at dst.length, make sure dst is also an objArray.
3737     // This check also fails for flat arrays which are not supported.
3738     __ cmpl(Address(rax, lh_offset), objArray_lh);
3739     __ jcc(Assembler::notEqual, L_failed);
3740 
3741 #ifdef ASSERT
3742     {
3743       BLOCK_COMMENT("assert not null-free array {");
3744       Label L;
3745       __ test_non_null_free_array_oop(dst, rklass_tmp, L);
3746       __ stop("unexpected null-free array");
3747       __ bind(L);
3748       BLOCK_COMMENT("} assert not null-free array");
3749     }
3750 #endif
3751 
3752     // It is safe to examine both src.length and dst.length.
3753     arraycopy_range_checks(src, src_pos, dst, dst_pos, r11_length,
3754                            rax, L_failed);
3755 
3756     const Register r11_dst_klass = r11;
3757     __ load_klass(r11_dst_klass, dst, rklass_tmp); // reload
3758 
3759     // Marshal the base address arguments now, freeing registers.
3760     __ lea(from, Address(src, src_pos, TIMES_OOP,
3761                  arrayOopDesc::base_offset_in_bytes(T_OBJECT)));
3762     __ lea(to,   Address(dst, dst_pos, TIMES_OOP,
3763                  arrayOopDesc::base_offset_in_bytes(T_OBJECT)));
3764     __ movl(count, length);           // length (reloaded)
3765     Register sco_temp = c_rarg3;      // this register is free now
3766     assert_different_registers(from, to, count, sco_temp,
3767                                r11_dst_klass, r10_src_klass);
3768     assert_clean_int(count, sco_temp);
3769 
3770     // Generate the type check.
3771     const int sco_offset = in_bytes(Klass::super_check_offset_offset());
< prev index next >