< prev index next >

src/hotspot/cpu/x86/stubGenerator_x86_64_arraycopy.cpp

Print this page
*** 2369,21 ***
    __ 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
--- 2369,31 ---
    __ jcc(Assembler::notEqual, L_failed);
  
    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);
+ 
+   // Check for null-free (non-flat) inline type array -> handle as object array
+   __ testl(rax_lh, Klass::_lh_null_free_array_bit_inplace);
+   __ jcc(Assembler::notZero, L_objArray);
+ 
    //  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

*** 2487,13 ***
--- 2497,27 ---
  
  __ 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/null-free 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;
+       __ movl(rklass_tmp, Address(rax, lh_offset));
+       __ testl(rklass_tmp, Klass::_lh_null_free_array_bit_inplace);
+       __ jcc(Assembler::zero, 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 >