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());
|