< prev index next >

src/hotspot/share/oops/objArrayKlass.cpp

Print this page

        

@@ -231,30 +231,24 @@
     ArrayAccess<>::oop_arraycopy(s, src_offset, d, dst_offset, length);
   } else {
     // We have to make sure all elements conform to the destination array
     Klass* bound = ObjArrayKlass::cast(d->klass())->element_klass();
     Klass* stype = ObjArrayKlass::cast(s->klass())->element_klass();
+    // Perform null check if dst is null-free but src has no such guarantee
+    bool null_check = ((!ArrayKlass::cast(s->klass())->storage_properties().is_null_free()) &&
+        ArrayKlass::cast(d->klass())->storage_properties().is_null_free());
     if (stype == bound || stype->is_subtype_of(bound)) {
-      // elements are guaranteed to be subtypes, so no check necessary
-      ArrayAccess<ARRAYCOPY_DISJOINT>::oop_arraycopy(s, src_offset, d, dst_offset, length);
+      if (null_check) {
+        ArrayAccess<ARRAYCOPY_DISJOINT | ARRAYCOPY_NOTNULL>::oop_arraycopy(s, src_offset, d, dst_offset, length);
     } else {
-      // slow case: need individual subtype checks
-      // note: don't use obj_at_put below because it includes a redundant store check
-      if (!ArrayAccess<ARRAYCOPY_DISJOINT | ARRAYCOPY_CHECKCAST>::oop_arraycopy(s, src_offset, d, dst_offset, length)) {
-        ResourceMark rm(THREAD);
-        stringStream ss;
-        if (!bound->is_subtype_of(stype)) {
-          ss.print("arraycopy: type mismatch: can not copy %s[] into %s[]",
-                   stype->external_name(), bound->external_name());
-        } else {
-          // oop_arraycopy should return the index in the source array that
-          // contains the problematic oop.
-          ss.print("arraycopy: element type mismatch: can not cast one of the elements"
-                   " of %s[] to the type of the destination array, %s",
-                   stype->external_name(), bound->external_name());
+        ArrayAccess<ARRAYCOPY_DISJOINT>::oop_arraycopy(s, src_offset, d, dst_offset, length);
         }
-        THROW_MSG(vmSymbols::java_lang_ArrayStoreException(), ss.as_string());
+    } else {
+      if (null_check) {
+        ArrayAccess<ARRAYCOPY_DISJOINT | ARRAYCOPY_CHECKCAST | ARRAYCOPY_NOTNULL>::oop_arraycopy(s, src_offset, d, dst_offset, length);
+      } else {
+        ArrayAccess<ARRAYCOPY_DISJOINT | ARRAYCOPY_CHECKCAST>::oop_arraycopy(s, src_offset, d, dst_offset, length);
       }
     }
   }
 }
 

@@ -318,32 +312,11 @@
   // This is correct, since the position is supposed to be an 'in between point', i.e., s.length(),
   // points to the right of the last element.
   if (length==0) {
     return;
   }
-  if (EnableValhalla && ArrayKlass::cast(d->klass())->element_klass()->is_value()) {
-    assert(d->is_objArray(), "Expected objArray");
-    ValueKlass* d_elem_vklass = ValueKlass::cast(ArrayKlass::cast(d->klass())->element_klass());
-    objArrayOop da = objArrayOop(d);
-    objArrayOop sa = objArrayOop(s);
-    int src_end = src_pos + length;
-    bool null_free = ArrayKlass::cast(s->klass())->storage_properties().is_null_free() ||
-                     ArrayKlass::cast(d->klass())->storage_properties().is_null_free();
-    while (src_pos < src_end) {
-      oop se = sa->obj_at(src_pos);
-      if (null_free && se == NULL) {
-        THROW(vmSymbols::java_lang_NullPointerException());
-      }
-      // Check exact type per element
-      if (se != NULL && se->klass() != d_elem_vklass) {
-        THROW(vmSymbols::java_lang_ArrayStoreException());
-      }
-      da->obj_at_put(dst_pos, se);  // TODO: review with ValueArrayKlass::copy_array and Access API
-      dst_pos++;
-      src_pos++;
-    }
-  } else if (UseCompressedOops) {
+  if (UseCompressedOops) {
     size_t src_offset = (size_t) objArrayOopDesc::obj_at_offset<narrowOop>(src_pos);
     size_t dst_offset = (size_t) objArrayOopDesc::obj_at_offset<narrowOop>(dst_pos);
     assert(arrayOopDesc::obj_offset_to_raw<narrowOop>(s, src_offset, NULL) ==
            objArrayOop(s)->obj_at_addr_raw<narrowOop>(src_pos), "sanity");
     assert(arrayOopDesc::obj_offset_to_raw<narrowOop>(d, dst_offset, NULL) ==
< prev index next >