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()) ||
|
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;
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;
262 stringStream ss;
263 ss.print("arraycopy: type mismatch: can not copy object[] into %s[]",
264 type2name_tab[ArrayKlass::cast(d->klass())->element_type()]);
265 THROW_MSG(vmSymbols::java_lang_ArrayStoreException(), ss.as_string());
266 }
267
268 // Check is all offsets and lengths are non negative
269 if (src_pos < 0 || dst_pos < 0 || length < 0) {
270 // Pass specific exception reason.
271 ResourceMark rm;
272 stringStream ss;
273 if (src_pos < 0) {
274 ss.print("arraycopy: source index %d out of bounds for object array[%d]",
275 src_pos, s->length());
276 } else if (dst_pos < 0) {
277 ss.print("arraycopy: destination index %d out of bounds for object array[%d]",
278 dst_pos, d->length());
279 } else {
280 ss.print("arraycopy: length %d is negative", length);
281 }
282 THROW_MSG(vmSymbols::java_lang_ArrayIndexOutOfBoundsException(), ss.as_string());
283 }
284 // Check if the ranges are valid
285 if ((((unsigned int) length + (unsigned int) src_pos) > (unsigned int) s->length()) ||
|