< prev index next >

src/hotspot/cpu/x86/stubGenerator_x86_64_arraycopy.cpp

Print this page
@@ -2856,24 +2856,36 @@
    //  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;
-     __ cmpl(rax_lh, (Klass::_lh_array_tag_type_value << Klass::_lh_array_tag_shift));
-     __ jcc(Assembler::greaterEqual, 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

@@ -2977,13 +2989,25 @@
  
  __ 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 >