< prev index next >

src/hotspot/share/oops/objArrayKlass.cpp

Print this page
rev 50570 : 8204943: Improve message of ArrayStoreException.


 218 }
 219 
 220 // Either oop or narrowOop depending on UseCompressedOops.
 221 void ObjArrayKlass::do_copy(arrayOop s, size_t src_offset,
 222                             arrayOop d, size_t dst_offset, int length, TRAPS) {
 223   if (oopDesc::equals(s, d)) {
 224     // since source and destination are equal we do not need conversion checks.
 225     assert(length > 0, "sanity check");
 226     ArrayAccess<>::oop_arraycopy(s, src_offset, d, dst_offset, length);
 227   } else {
 228     // We have to make sure all elements conform to the destination array
 229     Klass* bound = ObjArrayKlass::cast(d->klass())->element_klass();
 230     Klass* stype = ObjArrayKlass::cast(s->klass())->element_klass();
 231     if (stype == bound || stype->is_subtype_of(bound)) {
 232       // elements are guaranteed to be subtypes, so no check necessary
 233       ArrayAccess<ARRAYCOPY_DISJOINT>::oop_arraycopy(s, src_offset, d, dst_offset, length);
 234     } else {
 235       // slow case: need individual subtype checks
 236       // note: don't use obj_at_put below because it includes a redundant store check
 237       if (!ArrayAccess<ARRAYCOPY_DISJOINT | ARRAYCOPY_CHECKCAST>::oop_arraycopy(s, src_offset, d, dst_offset, length)) {
 238         THROW(vmSymbols::java_lang_ArrayStoreException());












 239       }
 240     }
 241   }
 242 }
 243 
 244 void ObjArrayKlass::copy_array(arrayOop s, int src_pos, arrayOop d,
 245                                int dst_pos, int length, TRAPS) {
 246   assert(s->is_objArray(), "must be obj array");
 247 
 248   if (!d->is_objArray()) {
 249     THROW(vmSymbols::java_lang_ArrayStoreException());








 250   }
 251 
 252   // Check is all offsets and lengths are non negative
 253   if (src_pos < 0 || dst_pos < 0 || length < 0) {
 254     // Pass specific exception reason.
 255     ResourceMark rm;
 256     stringStream ss;
 257     if (src_pos < 0) {
 258       ss.print("arraycopy: source index %d out of bounds for object array[%d]",
 259                src_pos, s->length());
 260     } else if (dst_pos < 0) {
 261       ss.print("arraycopy: destination index %d out of bounds for object array[%d]",
 262                dst_pos, d->length());
 263     } else {
 264       ss.print("arraycopy: length %d is negative", length);
 265     }
 266     THROW_MSG(vmSymbols::java_lang_ArrayIndexOutOfBoundsException(), ss.as_string());
 267   }
 268   // Check if the ranges are valid
 269   if ((((unsigned int) length + (unsigned int) src_pos) > (unsigned int) s->length()) ||
 270       (((unsigned int) length + (unsigned int) dst_pos) > (unsigned int) d->length())) {
 271     // Pass specific exception reason.
 272     ResourceMark rm;
 273     stringStream ss;
 274     if (((unsigned int) length + (unsigned int) src_pos) > (unsigned int) s->length()) {
 275       ss.print("arraycopy: last source index %u out of bounds for object array[%d]",
 276                (unsigned int) length + (unsigned int) src_pos, s->length());
 277     } else {
 278       ss.print("arraycopy: last destination index %u out of bounds for object array[%d]",
 279                (unsigned int) length + (unsigned int) dst_pos, d->length());
 280     }
 281     THROW_MSG(vmSymbols::java_lang_ArrayIndexOutOfBoundsException(), ss.as_string());
 282   }
 283 
 284   // Special case. Boundary cases must be checked first
 285   // This allows the following call: copy_array(s, s.length(), d.length(), 0).
 286   // This is correct, since the position is supposed to be an 'in between point', i.e., s.length(),
 287   // points to the right of the last element.
 288   if (length==0) {
 289     return;
 290   }
 291   if (UseCompressedOops) {
 292     size_t src_offset = (size_t) objArrayOopDesc::obj_at_offset<narrowOop>(src_pos);




 218 }
 219 
 220 // Either oop or narrowOop depending on UseCompressedOops.
 221 void ObjArrayKlass::do_copy(arrayOop s, size_t src_offset,
 222                             arrayOop d, size_t dst_offset, int length, TRAPS) {
 223   if (oopDesc::equals(s, d)) {
 224     // since source and destination are equal we do not need conversion checks.
 225     assert(length > 0, "sanity check");
 226     ArrayAccess<>::oop_arraycopy(s, src_offset, d, dst_offset, length);
 227   } else {
 228     // We have to make sure all elements conform to the destination array
 229     Klass* bound = ObjArrayKlass::cast(d->klass())->element_klass();
 230     Klass* stype = ObjArrayKlass::cast(s->klass())->element_klass();
 231     if (stype == bound || stype->is_subtype_of(bound)) {
 232       // elements are guaranteed to be subtypes, so no check necessary
 233       ArrayAccess<ARRAYCOPY_DISJOINT>::oop_arraycopy(s, src_offset, d, dst_offset, length);
 234     } else {
 235       // slow case: need individual subtype checks
 236       // note: don't use obj_at_put below because it includes a redundant store check
 237       if (!ArrayAccess<ARRAYCOPY_DISJOINT | ARRAYCOPY_CHECKCAST>::oop_arraycopy(s, src_offset, d, dst_offset, length)) {
 238         ResourceMark rm(THREAD);
 239         stringStream ss;
 240         if (!bound->is_subtype_of(stype)) {
 241           ss.print("arraycopy: type mismatch: can not copy %s[] into %s[]",
 242                    stype->external_name(), bound->external_name());
 243         } else {
 244           // oop_arraycopy should return the index in the source array that
 245           // contains the problematic oop.
 246           ss.print("arraycopy: element type mismatch: can not cast one of the elements"
 247                    " of %s[] to the type of the destination array, %s",
 248                    stype->external_name(), bound->external_name());
 249         }
 250         THROW_MSG(vmSymbols::java_lang_ArrayStoreException(), ss.as_string());
 251       }
 252     }
 253   }
 254 }
 255 
 256 void ObjArrayKlass::copy_array(arrayOop s, int src_pos, arrayOop d,
 257                                int dst_pos, int length, TRAPS) {
 258   assert(s->is_objArray(), "must be obj array");
 259 
 260   if (!d->is_objArray()) {
 261     ResourceMark rm(THREAD);
 262     stringStream ss;
 263     if (d->is_typeArray()) {
 264       ss.print("arraycopy: type mismatch: can not copy object array[] into %s[]",
 265                type2name_tab[ArrayKlass::cast(d->klass())->element_type()]);
 266     } else {
 267       ss.print("arraycopy: destination type %s is not an array", d->klass()->external_name());
 268     }
 269     THROW_MSG(vmSymbols::java_lang_ArrayStoreException(), ss.as_string());
 270   }
 271 
 272   // Check is all offsets and lengths are non negative
 273   if (src_pos < 0 || dst_pos < 0 || length < 0) {
 274     // Pass specific exception reason.
 275     ResourceMark rm(THREAD);
 276     stringStream ss;
 277     if (src_pos < 0) {
 278       ss.print("arraycopy: source index %d out of bounds for object array[%d]",
 279                src_pos, s->length());
 280     } else if (dst_pos < 0) {
 281       ss.print("arraycopy: destination index %d out of bounds for object array[%d]",
 282                dst_pos, d->length());
 283     } else {
 284       ss.print("arraycopy: length %d is negative", length);
 285     }
 286     THROW_MSG(vmSymbols::java_lang_ArrayIndexOutOfBoundsException(), ss.as_string());
 287   }
 288   // Check if the ranges are valid
 289   if ((((unsigned int) length + (unsigned int) src_pos) > (unsigned int) s->length()) ||
 290       (((unsigned int) length + (unsigned int) dst_pos) > (unsigned int) d->length())) {
 291     // Pass specific exception reason.
 292     ResourceMark rm(THREAD);
 293     stringStream ss;
 294     if (((unsigned int) length + (unsigned int) src_pos) > (unsigned int) s->length()) {
 295       ss.print("arraycopy: last source index %u out of bounds for object array[%d]",
 296                (unsigned int) length + (unsigned int) src_pos, s->length());
 297     } else {
 298       ss.print("arraycopy: last destination index %u out of bounds for object array[%d]",
 299                (unsigned int) length + (unsigned int) dst_pos, d->length());
 300     }
 301     THROW_MSG(vmSymbols::java_lang_ArrayIndexOutOfBoundsException(), ss.as_string());
 302   }
 303 
 304   // Special case. Boundary cases must be checked first
 305   // This allows the following call: copy_array(s, s.length(), d.length(), 0).
 306   // This is correct, since the position is supposed to be an 'in between point', i.e., s.length(),
 307   // points to the right of the last element.
 308   if (length==0) {
 309     return;
 310   }
 311   if (UseCompressedOops) {
 312     size_t src_offset = (size_t) objArrayOopDesc::obj_at_offset<narrowOop>(src_pos);


< prev index next >