2683 }
2684
2685 #ifdef ASSERT
2686 // assert(src->klass() != NULL);
2687 BLOCK_COMMENT("assert klasses not null");
2688 { Label L_a, L_b;
2689 __ br_notnull(G3_src_klass, false, Assembler::pt, L_b); // it is broken if klass is NULL
2690 __ delayed()->nop();
2691 __ bind(L_a);
2692 __ stop("broken null klass");
2693 __ bind(L_b);
2694 __ load_klass(dst, G4_dst_klass);
2695 __ br_null(G4_dst_klass, false, Assembler::pn, L_a); // this would be broken also
2696 __ delayed()->mov(G0, G4_dst_klass); // scribble the temp
2697 BLOCK_COMMENT("assert done");
2698 }
2699 #endif
2700
2701 // Load layout helper
2702 //
2703 // |array_tag| | header_size | element_type | |log2_element_size|
2704 // 32 30 24 16 8 2 0
2705 //
2706 // array_tag: typeArray = 0x3, objArray = 0x2, non-array = 0x0
2707 //
2708
2709 int lh_offset = klassOopDesc::header_size() * HeapWordSize +
2710 Klass::layout_helper_offset_in_bytes();
2711
2712 // Load 32-bits signed value. Use br() instruction with it to check icc.
2713 __ lduw(G3_src_klass, lh_offset, G5_lh);
2714
2715 if (UseCompressedOops) {
2716 __ load_klass(dst, G4_dst_klass);
2717 }
2718 // Handle objArrays completely differently...
2719 juint objArray_lh = Klass::array_layout_helper(T_OBJECT);
2720 __ set(objArray_lh, O5_temp);
2721 __ cmp(G5_lh, O5_temp);
2722 __ br(Assembler::equal, false, Assembler::pt, L_objArray);
2723 if (UseCompressedOops) {
2724 __ delayed()->nop();
2725 } else {
2726 __ delayed()->ld_ptr(dst, oopDesc::klass_offset_in_bytes(), G4_dst_klass);
2727 }
2728
2729 // if (src->klass() != dst->klass()) return -1;
2730 __ cmp(G3_src_klass, G4_dst_klass);
2731 __ brx(Assembler::notEqual, false, Assembler::pn, L_failed);
2732 __ delayed()->nop();
2733
2734 // if (!src->is_Array()) return -1;
2735 __ cmp(G5_lh, Klass::_lh_neutral_value); // < 0
2736 __ br(Assembler::greaterEqual, false, Assembler::pn, L_failed);
2737
2738 // At this point, it is known to be a typeArray (array_tag 0x3).
2739 #ifdef ASSERT
2740 __ delayed()->nop();
2741 { Label L;
2742 jint lh_prim_tag_in_place = (Klass::_lh_array_tag_type_value << Klass::_lh_array_tag_shift);
2743 __ set(lh_prim_tag_in_place, O5_temp);
2744 __ cmp(G5_lh, O5_temp);
2745 __ br(Assembler::greaterEqual, false, Assembler::pt, L);
2746 __ delayed()->nop();
2747 __ stop("must be a primitive array");
2748 __ bind(L);
2749 }
2750 #else
2751 __ delayed(); // match next insn to prev branch
2752 #endif
2753
2754 arraycopy_range_checks(src, src_pos, dst, dst_pos, length,
2755 O5_temp, G4_dst_klass, L_failed);
2756
2757 // typeArrayKlass
2758 //
2759 // src_addr = (src + array_header_in_bytes()) + (src_pos << log2elemsize);
2760 // dst_addr = (dst + array_header_in_bytes()) + (dst_pos << log2elemsize);
2761 //
2762
2763 const Register G4_offset = G4_dst_klass; // array offset
2764 const Register G3_elsize = G3_src_klass; // log2 element size
2765
2766 __ srl(G5_lh, Klass::_lh_header_size_shift, G4_offset);
2767 __ and3(G4_offset, Klass::_lh_header_size_mask, G4_offset); // array_offset
2768 __ add(src, G4_offset, src); // src array offset
2769 __ add(dst, G4_offset, dst); // dst array offset
2770 __ and3(G5_lh, Klass::_lh_log2_element_size_mask, G3_elsize); // log2 element size
2771
2772 // next registers should be set before the jump to corresponding stub
2773 const Register from = O0; // source array address
2774 const Register to = O1; // destination array address
2775 const Register count = O2; // elements count
2776
2777 // 'from', 'to', 'count' registers should be set in this order
2778 // since they are the same as 'src', 'src_pos', 'dst'.
2779
2780 BLOCK_COMMENT("scale indexes to element size");
2781 __ sll_ptr(src_pos, G3_elsize, src_pos);
2782 __ sll_ptr(dst_pos, G3_elsize, dst_pos);
2783 __ add(src, src_pos, from); // src_addr
2784 __ add(dst, dst_pos, to); // dst_addr
2785
2786 BLOCK_COMMENT("choose copy loop based on element size");
2787 __ cmp(G3_elsize, 0);
2788 __ br(Assembler::equal,true,Assembler::pt,StubRoutines::_jbyte_arraycopy);
2789 __ delayed()->signx(length, count); // length
2790
2791 __ cmp(G3_elsize, LogBytesPerShort);
2792 __ br(Assembler::equal,true,Assembler::pt,StubRoutines::_jshort_arraycopy);
2793 __ delayed()->signx(length, count); // length
2794
2795 __ cmp(G3_elsize, LogBytesPerInt);
2796 __ br(Assembler::equal,true,Assembler::pt,StubRoutines::_jint_arraycopy);
2797 __ delayed()->signx(length, count); // length
2798 #ifdef ASSERT
2799 { Label L;
2800 __ cmp(G3_elsize, LogBytesPerLong);
2801 __ br(Assembler::equal, false, Assembler::pt, L);
2802 __ delayed()->nop();
2803 __ stop("must be long copy, but elsize is wrong");
2804 __ bind(L);
2805 }
2806 #endif
2807 __ br(Assembler::always,false,Assembler::pt,StubRoutines::_jlong_arraycopy);
2808 __ delayed()->signx(length, count); // length
2809
2810 // objArrayKlass
2811 __ BIND(L_objArray);
2812 // live at this point: G3_src_klass, G4_dst_klass, src[_pos], dst[_pos], length
2813
2814 Label L_plain_copy, L_checkcast_copy;
2815 // test array classes for subtyping
2816 __ cmp(G3_src_klass, G4_dst_klass); // usual case is exact equality
2817 __ brx(Assembler::notEqual, true, Assembler::pn, L_checkcast_copy);
2818 __ delayed()->lduw(G4_dst_klass, lh_offset, O5_temp); // hoisted from below
2819
2820 // Identically typed arrays can be copied without element-wise checks.
2821 arraycopy_range_checks(src, src_pos, dst, dst_pos, length,
2822 O5_temp, G5_lh, L_failed);
2823
2824 __ add(src, arrayOopDesc::base_offset_in_bytes(T_OBJECT), src); //src offset
2825 __ add(dst, arrayOopDesc::base_offset_in_bytes(T_OBJECT), dst); //dst offset
2826 __ sll_ptr(src_pos, LogBytesPerHeapOop, src_pos);
2827 __ sll_ptr(dst_pos, LogBytesPerHeapOop, dst_pos);
2828 __ add(src, src_pos, from); // src_addr
2829 __ add(dst, dst_pos, to); // dst_addr
2830 __ BIND(L_plain_copy);
2831 __ br(Assembler::always, false, Assembler::pt,StubRoutines::_oop_arraycopy);
2832 __ delayed()->signx(length, count); // length
2833
2834 __ BIND(L_checkcast_copy);
2835 // live at this point: G3_src_klass, G4_dst_klass
2836 {
2837 // Before looking at dst.length, make sure dst is also an objArray.
2838 // lduw(G4_dst_klass, lh_offset, O5_temp); // hoisted to delay slot
2839 __ cmp(G5_lh, O5_temp);
2840 __ br(Assembler::notEqual, false, Assembler::pn, L_failed);
2841
2842 // It is safe to examine both src.length and dst.length.
2843 __ delayed(); // match next insn to prev branch
2844 arraycopy_range_checks(src, src_pos, dst, dst_pos, length,
2845 O5_temp, G5_lh, L_failed);
2846
2847 // Marshal the base address arguments now, freeing registers.
2848 __ add(src, arrayOopDesc::base_offset_in_bytes(T_OBJECT), src); //src offset
2849 __ add(dst, arrayOopDesc::base_offset_in_bytes(T_OBJECT), dst); //dst offset
2850 __ sll_ptr(src_pos, LogBytesPerHeapOop, src_pos);
2851 __ sll_ptr(dst_pos, LogBytesPerHeapOop, dst_pos);
2852 __ add(src, src_pos, from); // src_addr
2853 __ add(dst, dst_pos, to); // dst_addr
2854 __ signx(length, count); // length (reloaded)
|
2683 }
2684
2685 #ifdef ASSERT
2686 // assert(src->klass() != NULL);
2687 BLOCK_COMMENT("assert klasses not null");
2688 { Label L_a, L_b;
2689 __ br_notnull(G3_src_klass, false, Assembler::pt, L_b); // it is broken if klass is NULL
2690 __ delayed()->nop();
2691 __ bind(L_a);
2692 __ stop("broken null klass");
2693 __ bind(L_b);
2694 __ load_klass(dst, G4_dst_klass);
2695 __ br_null(G4_dst_klass, false, Assembler::pn, L_a); // this would be broken also
2696 __ delayed()->mov(G0, G4_dst_klass); // scribble the temp
2697 BLOCK_COMMENT("assert done");
2698 }
2699 #endif
2700
2701 // Load layout helper
2702 //
2703 // | array_tag | element_type | log2_element_size | header_size |
2704 // 32 28 24 16 0
2705 //
2706 // array_tag: typeArray = 0xF, objArray = 0xD, normal instance = 0x0
2707 //
2708
2709 int lh_offset = klassOopDesc::header_size() * HeapWordSize +
2710 Klass::layout_helper_offset_in_bytes();
2711
2712 // Load 32-bits signed value. Use br() instruction with it to check icc.
2713 __ lduw(G3_src_klass, lh_offset, G5_lh);
2714
2715 if (UseCompressedOops) {
2716 __ load_klass(dst, G4_dst_klass);
2717 }
2718 // Handle objArrays completely differently...
2719 // This is necessary because they have covariant element types.
2720 // The next type check (for src.klass == dst.klass), can get a
2721 // false negative in the case of object arrays.
2722 jint objArray_lh = LayoutHelper::for_array(T_OBJECT).as_int();
2723 __ set(objArray_lh, O5_temp);
2724 __ cmp(G5_lh, O5_temp);
2725 __ br(Assembler::equal, false, Assembler::pt, L_objArray);
2726 if (UseCompressedOops) {
2727 __ delayed()->nop();
2728 } else {
2729 __ delayed()->ld_ptr(dst, oopDesc::klass_offset_in_bytes(), G4_dst_klass);
2730 }
2731
2732 // if (src->klass() != dst->klass()) return -1;
2733 __ cmp(G3_src_klass, G4_dst_klass);
2734 __ brx(Assembler::notEqual, false, Assembler::pn, L_failed);
2735 __ delayed()->nop();
2736
2737 // if (!src->has_length_field()) return -1;
2738 __ cmp(G5_lh, LayoutHelper::_neutral_value); // < 0
2739 __ br(Assembler::greaterEqual, false, Assembler::pn, L_failed);
2740
2741 __ delayed(); // match next insn to prev branch
2742
2743 arraycopy_range_checks(src, src_pos, dst, dst_pos, length,
2744 O5_temp, G4_dst_klass, L_failed);
2745
2746 // typeArrayKlass
2747 //
2748 // src_addr = (src + array_header_in_bytes()) + (src_pos << log2elemsize);
2749 // dst_addr = (dst + array_header_in_bytes()) + (dst_pos << log2elemsize);
2750 //
2751
2752 const Register G4_offset = G4_dst_klass; // array offset
2753 const Register G3_elsize = G3_src_klass; // log2 element size
2754
2755 assert(LayoutHelper::_header_size_shift == 0, "");
2756 __ set(LayoutHelper::_header_size_mask, G4_offset);
2757 __ and3(G5_lh, G4_offset, G4_offset); // array_offset
2758 __ add(src, G4_offset, src); // src array offset
2759 __ add(dst, G4_offset, dst); // dst array offset
2760 __ srl( G5_lh, LayoutHelper::_element_size_shift, G3_elsize);
2761 __ and3(G3_elsize, LayoutHelper::_element_size_mask, G3_elsize); // log2 element size
2762
2763 // next registers should be set before the jump to corresponding stub
2764 const Register from = O0; // source array address
2765 const Register to = O1; // destination array address
2766 const Register count = O2; // elements count
2767
2768 // 'from', 'to', 'count' registers should be set in this order
2769 // since they are the same as 'src', 'src_pos', 'dst'.
2770
2771 BLOCK_COMMENT("scale indexes to element size");
2772 __ sll_ptr(src_pos, G3_elsize, src_pos);
2773 __ sll_ptr(dst_pos, G3_elsize, dst_pos);
2774 __ add(src, src_pos, from); // src_addr
2775 __ add(dst, dst_pos, to); // dst_addr
2776
2777 BLOCK_COMMENT("choose copy loop based on element size");
2778 __ cmp(G3_elsize, 0);
2779 __ br(Assembler::equal,true,Assembler::pt,StubRoutines::_jbyte_arraycopy);
2780 __ delayed()->signx(length, count); // length
2781
2782 __ cmp(G3_elsize, LogBytesPerShort);
2783 __ br(Assembler::equal,true,Assembler::pt,StubRoutines::_jshort_arraycopy);
2784 __ delayed()->signx(length, count); // length
2785
2786 __ cmp(G3_elsize, LogBytesPerInt);
2787 __ br(Assembler::equal,true,Assembler::pt,StubRoutines::_jint_arraycopy);
2788 __ delayed()->signx(length, count); // length
2789 #ifdef ASSERT
2790 { Label L;
2791 __ cmp(G3_elsize, LogBytesPerLong);
2792 __ br(Assembler::equal, false, Assembler::pt, L);
2793 __ delayed()->nop();
2794 __ stop("must be long copy, but elsize is wrong");
2795 __ bind(L);
2796 }
2797 #endif
2798 __ br(Assembler::always,false,Assembler::pt,StubRoutines::_jlong_arraycopy);
2799 __ delayed()->signx(length, count); // length
2800
2801 Label L_different_objArray, L_plain_copy, L_checkcast_copy;
2802
2803 // objArrayKlass
2804 __ BIND(L_objArray);
2805 // live at this point: G3_src_klass, G4_dst_klass, src[_pos], dst[_pos], length
2806
2807 // test array classes for subtyping
2808 __ cmp(G3_src_klass, G4_dst_klass); // usual case is exact equality
2809 __ brx(Assembler::notEqual, true, Assembler::pn, L_different_objArray);
2810 __ delayed()->lduw(G4_dst_klass, lh_offset, O5_temp); // hoisted from below
2811
2812 // Identically typed arrays can be copied without element-wise checks.
2813 arraycopy_range_checks(src, src_pos, dst, dst_pos, length,
2814 O5_temp, G5_lh, L_failed);
2815
2816 __ add(src, arrayOopDesc::base_offset_in_bytes(T_OBJECT), src); //src offset
2817 __ add(dst, arrayOopDesc::base_offset_in_bytes(T_OBJECT), dst); //dst offset
2818 __ sll_ptr(src_pos, LogBytesPerHeapOop, src_pos);
2819 __ sll_ptr(dst_pos, LogBytesPerHeapOop, dst_pos);
2820 __ add(src, src_pos, from); // src_addr
2821 __ add(dst, dst_pos, to); // dst_addr
2822 __ BIND(L_plain_copy);
2823 __ br(Assembler::always, false, Assembler::pt,StubRoutines::_oop_arraycopy);
2824 __ delayed()->signx(length, count); // length
2825
2826 __ BIND(L_different_objArray);
2827 // live at this point: G3_src_klass, G4_dst_klass
2828 {
2829 // Before looking at dst.length, make sure dst is also an objArray.
2830 // lduw(G4_dst_klass, lh_offset, O5_temp); // hoisted to delay slot
2831 __ cmp(G5_lh, O5_temp);
2832 __ br(Assembler::notEqual, false, Assembler::pn, L_failed);
2833
2834 // It is safe to examine both src.length and dst.length.
2835 __ delayed(); // match next insn to prev branch
2836 arraycopy_range_checks(src, src_pos, dst, dst_pos, length,
2837 O5_temp, G5_lh, L_failed);
2838
2839 // Marshal the base address arguments now, freeing registers.
2840 __ add(src, arrayOopDesc::base_offset_in_bytes(T_OBJECT), src); //src offset
2841 __ add(dst, arrayOopDesc::base_offset_in_bytes(T_OBJECT), dst); //dst offset
2842 __ sll_ptr(src_pos, LogBytesPerHeapOop, src_pos);
2843 __ sll_ptr(dst_pos, LogBytesPerHeapOop, dst_pos);
2844 __ add(src, src_pos, from); // src_addr
2845 __ add(dst, dst_pos, to); // dst_addr
2846 __ signx(length, count); // length (reloaded)
|