--- old/src/cpu/sparc/vm/stubGenerator_sparc.cpp	2008-07-12 17:47:10.000000000 -0700
+++ new/src/cpu/sparc/vm/stubGenerator_sparc.cpp	2008-07-12 17:47:09.000000000 -0700
@@ -2700,10 +2700,10 @@
 
     // Load layout helper
     //
-    //  |array_tag|     | header_size | element_type |     |log2_element_size|
-    // 32        30    24            16              8     2                 0
+    //  | array_tag | element_type | log2_element_size | header_size |
+    // 32          28             24                  16             0
     //
-    //   array_tag: typeArray = 0x3, objArray = 0x2, non-array = 0x0
+    //   array_tag: typeArray = 0xF, objArray = 0xD, normal instance = 0x0
     //
 
     int lh_offset = klassOopDesc::header_size() * HeapWordSize +
@@ -2716,7 +2716,10 @@
       __ load_klass(dst, G4_dst_klass);
     }
     // Handle objArrays completely differently...
-    juint objArray_lh = Klass::array_layout_helper(T_OBJECT);
+    // This is necessary because they have covariant element types.
+    // The next type check (for src.klass == dst.klass), can get a
+    // false negative in the case of object arrays.
+    jint objArray_lh = LayoutHelper::for_array(T_OBJECT).as_int();
     __ set(objArray_lh, O5_temp);
     __ cmp(G5_lh,       O5_temp);
     __ br(Assembler::equal, false, Assembler::pt, L_objArray);
@@ -2731,25 +2734,11 @@
     __ brx(Assembler::notEqual, false, Assembler::pn, L_failed);
     __ delayed()->nop();
 
-    //  if (!src->is_Array()) return -1;
-    __ cmp(G5_lh, Klass::_lh_neutral_value); // < 0
+    //  if (!src->has_length_field()) return -1;
+    __ cmp(G5_lh, LayoutHelper::_neutral_value); // < 0
     __ br(Assembler::greaterEqual, false, Assembler::pn, L_failed);
 
-    // At this point, it is known to be a typeArray (array_tag 0x3).
-#ifdef ASSERT
-    __ delayed()->nop();
-    { Label L;
-      jint lh_prim_tag_in_place = (Klass::_lh_array_tag_type_value << Klass::_lh_array_tag_shift);
-      __ set(lh_prim_tag_in_place, O5_temp);
-      __ cmp(G5_lh,                O5_temp);
-      __ br(Assembler::greaterEqual, false, Assembler::pt, L);
-      __ delayed()->nop();
-      __ stop("must be a primitive array");
-      __ bind(L);
-    }
-#else
     __ delayed();                               // match next insn to prev branch
-#endif
 
     arraycopy_range_checks(src, src_pos, dst, dst_pos, length,
                            O5_temp, G4_dst_klass, L_failed);
@@ -2763,11 +2752,13 @@
     const Register G4_offset = G4_dst_klass;    // array offset
     const Register G3_elsize = G3_src_klass;    // log2 element size
 
-    __ srl(G5_lh, Klass::_lh_header_size_shift, G4_offset);
-    __ and3(G4_offset, Klass::_lh_header_size_mask, G4_offset); // array_offset
+    assert(LayoutHelper::_header_size_shift == 0, "");
+    __ set(LayoutHelper::_header_size_mask, G4_offset);
+    __ and3(G5_lh, G4_offset, G4_offset); // array_offset
     __ add(src, G4_offset, src);       // src array offset
     __ add(dst, G4_offset, dst);       // dst array offset
-    __ and3(G5_lh, Klass::_lh_log2_element_size_mask, G3_elsize); // log2 element size
+    __ srl( G5_lh,     LayoutHelper::_element_size_shift, G3_elsize);
+    __ and3(G3_elsize, LayoutHelper::_element_size_mask,  G3_elsize); // log2 element size
 
     // next registers should be set before the jump to corresponding stub
     const Register from     = O0;  // source array address
@@ -2807,14 +2798,15 @@
     __ br(Assembler::always,false,Assembler::pt,StubRoutines::_jlong_arraycopy);
     __ delayed()->signx(length, count); // length
 
+    Label L_different_objArray, L_plain_copy, L_checkcast_copy;
+
     // objArrayKlass
   __ BIND(L_objArray);
     // live at this point:  G3_src_klass, G4_dst_klass, src[_pos], dst[_pos], length
 
-    Label L_plain_copy, L_checkcast_copy;
     //  test array classes for subtyping
     __ cmp(G3_src_klass, G4_dst_klass);         // usual case is exact equality
-    __ brx(Assembler::notEqual, true, Assembler::pn, L_checkcast_copy);
+    __ brx(Assembler::notEqual, true, Assembler::pn, L_different_objArray);
     __ delayed()->lduw(G4_dst_klass, lh_offset, O5_temp); // hoisted from below
 
     // Identically typed arrays can be copied without element-wise checks.
@@ -2831,7 +2823,7 @@
     __ br(Assembler::always, false, Assembler::pt,StubRoutines::_oop_arraycopy);
     __ delayed()->signx(length, count); // length
 
-  __ BIND(L_checkcast_copy);
+  __ BIND(L_different_objArray);
     // live at this point:  G3_src_klass, G4_dst_klass
     {
       // Before looking at dst.length, make sure dst is also an objArray.
