216 } |
216 } |
217 return h_array(); |
217 return h_array(); |
218 } |
218 } |
219 |
219 |
220 // Either oop or narrowOop depending on UseCompressedOops. |
220 // Either oop or narrowOop depending on UseCompressedOops. |
221 template <class T> void ObjArrayKlass::do_copy(arrayOop s, T* src, |
221 void ObjArrayKlass::do_copy(arrayOop s, size_t src_offset, |
222 arrayOop d, T* dst, int length, TRAPS) { |
222 arrayOop d, size_t dst_offset, int length, TRAPS) { |
223 if (oopDesc::equals(s, d)) { |
223 if (oopDesc::equals(s, d)) { |
224 // since source and destination are equal we do not need conversion checks. |
224 // since source and destination are equal we do not need conversion checks. |
225 assert(length > 0, "sanity check"); |
225 assert(length > 0, "sanity check"); |
226 HeapAccess<>::oop_arraycopy(s, d, src, dst, length); |
226 ArrayAccess<>::oop_arraycopy(s, src_offset, d, dst_offset, length); |
227 } else { |
227 } else { |
228 // We have to make sure all elements conform to the destination array |
228 // We have to make sure all elements conform to the destination array |
229 Klass* bound = ObjArrayKlass::cast(d->klass())->element_klass(); |
229 Klass* bound = ObjArrayKlass::cast(d->klass())->element_klass(); |
230 Klass* stype = ObjArrayKlass::cast(s->klass())->element_klass(); |
230 Klass* stype = ObjArrayKlass::cast(s->klass())->element_klass(); |
231 if (stype == bound || stype->is_subtype_of(bound)) { |
231 if (stype == bound || stype->is_subtype_of(bound)) { |
232 // elements are guaranteed to be subtypes, so no check necessary |
232 // elements are guaranteed to be subtypes, so no check necessary |
233 HeapAccess<ARRAYCOPY_DISJOINT>::oop_arraycopy(s, d, src, dst, length); |
233 ArrayAccess<ARRAYCOPY_DISJOINT>::oop_arraycopy(s, src_offset, d, dst_offset, length); |
234 } else { |
234 } else { |
235 // slow case: need individual subtype checks |
235 // slow case: need individual subtype checks |
236 // note: don't use obj_at_put below because it includes a redundant store check |
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)) { |
237 if (!ArrayAccess<ARRAYCOPY_DISJOINT | ARRAYCOPY_CHECKCAST>::oop_arraycopy(s, src_offset, d, dst_offset, length)) { |
238 THROW(vmSymbols::java_lang_ArrayStoreException()); |
238 THROW(vmSymbols::java_lang_ArrayStoreException()); |
239 } |
239 } |
240 } |
240 } |
241 } |
241 } |
242 } |
242 } |
287 // points to the right of the last element. |
287 // points to the right of the last element. |
288 if (length==0) { |
288 if (length==0) { |
289 return; |
289 return; |
290 } |
290 } |
291 if (UseCompressedOops) { |
291 if (UseCompressedOops) { |
292 narrowOop* const src = objArrayOop(s)->obj_at_addr<narrowOop>(src_pos); |
292 size_t src_offset = (size_t) objArrayOopDesc::obj_at_offset<narrowOop>(src_pos); |
293 narrowOop* const dst = objArrayOop(d)->obj_at_addr<narrowOop>(dst_pos); |
293 size_t dst_offset = (size_t) objArrayOopDesc::obj_at_offset<narrowOop>(dst_pos); |
294 do_copy<narrowOop>(s, src, d, dst, length, CHECK); |
294 assert(arrayOopDesc::obj_offset_to_raw<narrowOop>(s, src_offset, NULL) == |
|
295 objArrayOop(s)->obj_at_addr<narrowOop>(src_pos), "sanity"); |
|
296 assert(arrayOopDesc::obj_offset_to_raw<narrowOop>(d, dst_offset, NULL) == |
|
297 objArrayOop(d)->obj_at_addr<narrowOop>(dst_pos), "sanity"); |
|
298 do_copy(s, src_offset, d, dst_offset, length, CHECK); |
295 } else { |
299 } else { |
296 oop* const src = objArrayOop(s)->obj_at_addr<oop>(src_pos); |
300 size_t src_offset = (size_t) objArrayOopDesc::obj_at_offset<oop>(src_pos); |
297 oop* const dst = objArrayOop(d)->obj_at_addr<oop>(dst_pos); |
301 size_t dst_offset = (size_t) objArrayOopDesc::obj_at_offset<oop>(dst_pos); |
298 do_copy<oop> (s, src, d, dst, length, CHECK); |
302 assert(arrayOopDesc::obj_offset_to_raw<oop>(s, src_offset, NULL) == |
|
303 objArrayOop(s)->obj_at_addr<oop>(src_pos), "sanity"); |
|
304 assert(arrayOopDesc::obj_offset_to_raw<oop>(d, dst_offset, NULL) == |
|
305 objArrayOop(d)->obj_at_addr<oop>(dst_pos), "sanity"); |
|
306 do_copy(s, src_offset, d, dst_offset, length, CHECK); |
299 } |
307 } |
300 } |
308 } |
301 |
309 |
302 |
310 |
303 Klass* ObjArrayKlass::array_klass_impl(bool or_null, int n, TRAPS) { |
311 Klass* ObjArrayKlass::array_klass_impl(bool or_null, int n, TRAPS) { |