< prev index next > src/hotspot/cpu/x86/stubGenerator_x86_64_arraycopy.cpp
Print this page
// if (src->klass() != dst->klass()) return -1;
__ load_klass(rax, dst, rklass_tmp);
__ cmpq(r10_src_klass, rax);
__ jcc(Assembler::notEqual, L_failed);
const Register rax_lh = rax; // layout helper
__ movl(rax_lh, Address(r10_src_klass, lh_offset));
// if (!src->is_Array()) return -1;
__ cmpl(rax_lh, Klass::_lh_neutral_value);
__ jcc(Assembler::greaterEqual, L_failed);
// At this point, it is known to be a typeArray (array_tag 0x3).
#ifdef ASSERT
{
BLOCK_COMMENT("assert primitive array {");
Label L;
! __ cmpl(rax_lh, (Klass::_lh_array_tag_type_value << Klass::_lh_array_tag_shift));
! __ jcc(Assembler::greaterEqual, L);
__ stop("must be a primitive array");
__ bind(L);
BLOCK_COMMENT("} assert primitive array done");
}
#endif
// if (src->klass() != dst->klass()) return -1;
__ load_klass(rax, dst, rklass_tmp);
__ cmpq(r10_src_klass, rax);
__ jcc(Assembler::notEqual, L_failed);
+ // Check for flat inline type array -> return -1
+ __ test_flat_array_oop(src, rax, L_failed);
+
+ // Check for null-free (non-flat) inline type array -> handle as object array
+ __ test_null_free_array_oop(src, rax, L_objArray);
+
const Register rax_lh = rax; // layout helper
__ movl(rax_lh, Address(r10_src_klass, lh_offset));
+ // Check for flat inline type array -> return -1
+ __ testl(rax_lh, Klass::_lh_array_tag_flat_value_bit_inplace);
+ __ jcc(Assembler::notZero, L_failed);
+
// if (!src->is_Array()) return -1;
__ cmpl(rax_lh, Klass::_lh_neutral_value);
__ jcc(Assembler::greaterEqual, L_failed);
// At this point, it is known to be a typeArray (array_tag 0x3).
#ifdef ASSERT
{
BLOCK_COMMENT("assert primitive array {");
Label L;
! __ movl(rklass_tmp, rax_lh);
! __ sarl(rklass_tmp, Klass::_lh_array_tag_shift);
+ __ cmpl(rklass_tmp, Klass::_lh_array_tag_type_value);
+ __ jcc(Assembler::equal, L);
__ stop("must be a primitive array");
__ bind(L);
BLOCK_COMMENT("} assert primitive array done");
}
#endif
__ BIND(L_checkcast_copy);
// live at this point: r10_src_klass, r11_length, rax (dst_klass)
{
// Before looking at dst.length, make sure dst is also an objArray.
+ // This check also fails for flat arrays which are not supported.
__ cmpl(Address(rax, lh_offset), objArray_lh);
__ jcc(Assembler::notEqual, L_failed);
+ #ifdef ASSERT
+ {
+ BLOCK_COMMENT("assert not null-free array {");
+ Label L;
+ __ test_non_null_free_array_oop(dst, rklass_tmp, L);
+ __ stop("unexpected null-free array");
+ __ bind(L);
+ BLOCK_COMMENT("} assert not null-free array");
+ }
+ #endif
+
// It is safe to examine both src.length and dst.length.
arraycopy_range_checks(src, src_pos, dst, dst_pos, r11_length,
rax, L_failed);
const Register r11_dst_klass = r11;
< prev index next >