< prev index next >

src/hotspot/cpu/x86/stubGenerator_x86_64_arraycopy.cpp

Print this page

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






3601   const Register rax_lh = rax;  // layout helper
3602   __ movl(rax_lh, Address(r10_src_klass, lh_offset));
3603 




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


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

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

3722     __ cmpl(Address(rax, lh_offset), objArray_lh);
3723     __ jcc(Assembler::notEqual, L_failed);
3724 











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

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

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