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 (!HeapAccess<ARRAYCOPY_DISJOINT | ARRAYCOPY_CHECKCAST>::oop_arraycopy(s, d, src, dst, 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 THROW(vmSymbols::java_lang_ArrayIndexOutOfBoundsException());
255 }
256 // Check if the ranges are valid
257 if ( (((unsigned int) length + (unsigned int) src_pos) > (unsigned int) s->length())
258 || (((unsigned int) length + (unsigned int) dst_pos) > (unsigned int) d->length()) ) {
259 THROW(vmSymbols::java_lang_ArrayIndexOutOfBoundsException());
260 }
261
262 // Special case. Boundary cases must be checked first
263 // This allows the following call: copy_array(s, s.length(), d.length(), 0).
264 // This is correct, since the position is supposed to be an 'in between point', i.e., s.length(),
265 // points to the right of the last element.
266 if (length==0) {
267 return;
268 }
269 if (UseCompressedOops) {
270 narrowOop* const src = objArrayOop(s)->obj_at_addr<narrowOop>(src_pos);
271 narrowOop* const dst = objArrayOop(d)->obj_at_addr<narrowOop>(dst_pos);
272 do_copy<narrowOop>(s, src, d, dst, length, CHECK);
273 } else {
274 oop* const src = objArrayOop(s)->obj_at_addr<oop>(src_pos);
275 oop* const dst = objArrayOop(d)->obj_at_addr<oop>(dst_pos);
276 do_copy<oop> (s, src, d, dst, length, CHECK);
277 }
278 }
279
|
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 (!HeapAccess<ARRAYCOPY_DISJOINT | ARRAYCOPY_CHECKCAST>::oop_arraycopy(s, d, src, dst, 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("while trying to copy from index %i of an object array with length %i", src_pos, s->length());
259 } else if (dst_pos < 0) {
260 ss.print("while trying to copy to index %i of an object array with length %i", dst_pos, d->length());
261 } else {
262 ss.print("while trying to copy a negative range %i from an object array with length %i to an object array with length %i",
263 length, s->length(), d->length());
264 }
265 THROW_MSG(vmSymbols::java_lang_ArrayIndexOutOfBoundsException(), ss.as_string());
266 }
267 // Check if the ranges are valid
268 if ( (((unsigned int) length + (unsigned int) src_pos) > (unsigned int) s->length())
269 || (((unsigned int) length + (unsigned int) dst_pos) > (unsigned int) d->length()) ) {
270 // Pass specific exception reason.
271 ResourceMark rm;
272 stringStream ss;
273 if (((unsigned int) length + (unsigned int) src_pos) > (unsigned int) s->length()) {
274 ss.print("while trying to copy from index %u of an object array with length %i", (unsigned int) length + (unsigned int) src_pos, s->length());
275 } else {
276 ss.print("while trying to copy to index %u of an object array with length %i", (unsigned int) length + (unsigned int) dst_pos, d->length());
277 }
278 THROW_MSG(vmSymbols::java_lang_ArrayIndexOutOfBoundsException(), ss.as_string());
279 }
280
281 // Special case. Boundary cases must be checked first
282 // This allows the following call: copy_array(s, s.length(), d.length(), 0).
283 // This is correct, since the position is supposed to be an 'in between point', i.e., s.length(),
284 // points to the right of the last element.
285 if (length==0) {
286 return;
287 }
288 if (UseCompressedOops) {
289 narrowOop* const src = objArrayOop(s)->obj_at_addr<narrowOop>(src_pos);
290 narrowOop* const dst = objArrayOop(d)->obj_at_addr<narrowOop>(dst_pos);
291 do_copy<narrowOop>(s, src, d, dst, length, CHECK);
292 } else {
293 oop* const src = objArrayOop(s)->obj_at_addr<oop>(src_pos);
294 oop* const dst = objArrayOop(d)->obj_at_addr<oop>(dst_pos);
295 do_copy<oop> (s, src, d, dst, length, CHECK);
296 }
297 }
298
|