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);
|