< prev index next >

src/hotspot/cpu/x86/stubGenerator_x86_64_arraycopy.cpp

Print this page

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






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


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

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

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











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

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

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