< prev index next >

src/hotspot/share/oops/objArrayKlass.cpp

erik arraycopy

200         ArrayKlass* ak = ArrayKlass::cast(ld_klass);                                                                                 
201         oop sub_array = ak->multi_allocate(rank-1, &sizes[1], CHECK_NULL);                                                           
202         h_array->obj_at_put(index, sub_array);                                                                                       
203       }                                                                                                                              
204     } else {                                                                                                                         
205       // Since this array dimension has zero length, nothing will be                                                                 
206       // allocated, however the lower dimension values must be checked                                                               
207       // for illegal values.                                                                                                         
208       for (int i = 0; i < rank - 1; ++i) {                                                                                           
209         sizes += 1;                                                                                                                  
210         if (*sizes < 0) {                                                                                                            
211           THROW_MSG_0(vmSymbols::java_lang_NegativeArraySizeException(), err_msg("%d", *sizes));                                     
212         }                                                                                                                            
213       }                                                                                                                              
214     }                                                                                                                                
215   }                                                                                                                                  
216   return h_array();                                                                                                                  
217 }                                                                                                                                    
218 
219 // Either oop or narrowOop depending on UseCompressedOops.                                                                           
220 template <class T> void ObjArrayKlass::do_copy(arrayOop s, size_t src_offset,                                                        
221                                arrayOop d, size_t dst_offset, int length, TRAPS) {                                                   
222   if (oopDesc::equals(s, d)) {                                                                                                       
223     // since source and destination are equal we do not need conversion checks.                                                      
224     assert(length > 0, "sanity check");                                                                                              
225     ArrayAccess<>::template oop_arraycopy<T>(s, src_offset, d, dst_offset, length);                                                  
226   } else {                                                                                                                           
227     // We have to make sure all elements conform to the destination array                                                            
228     Klass* bound = ObjArrayKlass::cast(d->klass())->element_klass();                                                                 
229     Klass* stype = ObjArrayKlass::cast(s->klass())->element_klass();                                                                 
230     if (stype == bound || stype->is_subtype_of(bound)) {                                                                             
231       // elements are guaranteed to be subtypes, so no check necessary                                                               
232       ArrayAccess<ARRAYCOPY_DISJOINT>::template oop_arraycopy<T>(s, src_offset, d, dst_offset, length);                              
233     } else {                                                                                                                         
234       // slow case: need individual subtype checks                                                                                   
235       // note: don't use obj_at_put below because it includes a redundant store check                                                
236       if (!ArrayAccess<ARRAYCOPY_DISJOINT | ARRAYCOPY_CHECKCAST>::template oop_arraycopy<T>(s, src_offset, d, dst_offset, length)) { 
237         THROW(vmSymbols::java_lang_ArrayStoreException());                                                                           
238       }                                                                                                                              
239     }                                                                                                                                
240   }                                                                                                                                  
241 }                                                                                                                                    
242 
243 void ObjArrayKlass::copy_array(arrayOop s, int src_pos, arrayOop d,                                                                  
244                                int dst_pos, int length, TRAPS) {                                                                     
245   assert(s->is_objArray(), "must be obj array");                                                                                     
246 
247   if (!d->is_objArray()) {                                                                                                           
248     THROW(vmSymbols::java_lang_ArrayStoreException());                                                                               
249   }                                                                                                                                  
250 
251   // Check is all offsets and lengths are non negative                                                                               
252   if (src_pos < 0 || dst_pos < 0 || length < 0) {                                                                                    
253     // Pass specific exception reason.                                                                                               
254     ResourceMark rm;                                                                                                                 
255     stringStream ss;                                                                                                                 

200         ArrayKlass* ak = ArrayKlass::cast(ld_klass);
201         oop sub_array = ak->multi_allocate(rank-1, &sizes[1], CHECK_NULL);
202         h_array->obj_at_put(index, sub_array);
203       }
204     } else {
205       // Since this array dimension has zero length, nothing will be
206       // allocated, however the lower dimension values must be checked
207       // for illegal values.
208       for (int i = 0; i < rank - 1; ++i) {
209         sizes += 1;
210         if (*sizes < 0) {
211           THROW_MSG_0(vmSymbols::java_lang_NegativeArraySizeException(), err_msg("%d", *sizes));
212         }
213       }
214     }
215   }
216   return h_array();
217 }
218 
219 // Either oop or narrowOop depending on UseCompressedOops.
220 void ObjArrayKlass::do_copy(arrayOop s, size_t src_offset,
221                             arrayOop d, size_t dst_offset, int length, TRAPS) {
222   if (oopDesc::equals(s, d)) {
223     // since source and destination are equal we do not need conversion checks.
224     assert(length > 0, "sanity check");
225     ArrayAccess<>::oop_arraycopy(s, src_offset, d, dst_offset, length);
226   } else {
227     // We have to make sure all elements conform to the destination array
228     Klass* bound = ObjArrayKlass::cast(d->klass())->element_klass();
229     Klass* stype = ObjArrayKlass::cast(s->klass())->element_klass();
230     if (stype == bound || stype->is_subtype_of(bound)) {
231       // elements are guaranteed to be subtypes, so no check necessary
232       ArrayAccess<ARRAYCOPY_DISJOINT>::oop_arraycopy(s, src_offset, d, dst_offset, length);
233     } else {
234       // slow case: need individual subtype checks
235       // note: don't use obj_at_put below because it includes a redundant store check
236       if (!ArrayAccess<ARRAYCOPY_DISJOINT | ARRAYCOPY_CHECKCAST>::oop_arraycopy(s, src_offset, d, dst_offset, length)) {
237         THROW(vmSymbols::java_lang_ArrayStoreException());
238       }
239     }
240   }
241 }
242 
243 void ObjArrayKlass::copy_array(arrayOop s, int src_pos, arrayOop d,
244                                int dst_pos, int length, TRAPS) {
245   assert(s->is_objArray(), "must be obj array");
246 
247   if (!d->is_objArray()) {
248     THROW(vmSymbols::java_lang_ArrayStoreException());
249   }
250 
251   // Check is all offsets and lengths are non negative
252   if (src_pos < 0 || dst_pos < 0 || length < 0) {
253     // Pass specific exception reason.
254     ResourceMark rm;
255     stringStream ss;

273     if (((unsigned int) length + (unsigned int) src_pos) > (unsigned int) s->length()) {                                             
274       ss.print("arraycopy: last source index %u out of bounds for object array[%d]",                                                 
275                (unsigned int) length + (unsigned int) src_pos, s->length());                                                         
276     } else {                                                                                                                         
277       ss.print("arraycopy: last destination index %u out of bounds for object array[%d]",                                            
278                (unsigned int) length + (unsigned int) dst_pos, d->length());                                                         
279     }                                                                                                                                
280     THROW_MSG(vmSymbols::java_lang_ArrayIndexOutOfBoundsException(), ss.as_string());                                                
281   }                                                                                                                                  
282 
283   // Special case. Boundary cases must be checked first                                                                              
284   // This allows the following call: copy_array(s, s.length(), d.length(), 0).                                                       
285   // This is correct, since the position is supposed to be an 'in between point', i.e., s.length(),                                  
286   // points to the right of the last element.                                                                                        
287   if (length==0) {                                                                                                                   
288     return;                                                                                                                          
289   }                                                                                                                                  
290   if (UseCompressedOops) {                                                                                                           
291     size_t src_offset = (size_t) objArrayOopDesc::obj_at_offset<narrowOop>(src_pos);                                                 
292     size_t dst_offset = (size_t) objArrayOopDesc::obj_at_offset<narrowOop>(dst_pos);                                                 
293     assert(arrayOopDesc::obj_offset_to_raw<narrowOop>(s, src_offset, NULL) == objArrayOop(s)->obj_at_addr<narrowOop>(src_pos), "sanit
294     assert(arrayOopDesc::obj_offset_to_raw<narrowOop>(d, dst_offset, NULL) == objArrayOop(d)->obj_at_addr<narrowOop>(dst_pos), "sanit
295     do_copy<narrowOop>(s, src_offset, d, dst_offset, length, CHECK);                                                                 
                                                                                                                                     
                                                                                                                                     
296   } else {                                                                                                                           
297     size_t src_offset = (size_t) objArrayOopDesc::obj_at_offset<oop>(src_pos);                                                       
298     size_t dst_offset = (size_t) objArrayOopDesc::obj_at_offset<oop>(dst_pos);                                                       
299     assert(arrayOopDesc::obj_offset_to_raw<oop>(s, src_offset, NULL) == objArrayOop(s)->obj_at_addr<oop>(src_pos), "sanity");        
300     assert(arrayOopDesc::obj_offset_to_raw<oop>(d, dst_offset, NULL) == objArrayOop(d)->obj_at_addr<oop>(dst_pos), "sanity");        
301     do_copy<oop> (s, src_offset, d, dst_offset, length, CHECK);                                                                      
                                                                                                                                     
                                                                                                                                     
302   }                                                                                                                                  
303 }                                                                                                                                    
304 
305 
306 Klass* ObjArrayKlass::array_klass_impl(bool or_null, int n, TRAPS) {                                                                 
307 
308   assert(dimension() <= n, "check order of chain");                                                                                  
309   int dim = dimension();                                                                                                             
310   if (dim == n) return this;                                                                                                         
311 
312   // lock-free read needs acquire semantics                                                                                          
313   if (higher_dimension_acquire() == NULL) {                                                                                          
314     if (or_null)  return NULL;                                                                                                       
315 
316     ResourceMark rm;                                                                                                                 
317     JavaThread *jt = (JavaThread *)THREAD;                                                                                           
318     {                                                                                                                                
319       MutexLocker mc(Compile_lock, THREAD);   // for vtables                                                                         
320       // Ensure atomic creation of higher dimensions                                                                                 

273     if (((unsigned int) length + (unsigned int) src_pos) > (unsigned int) s->length()) {
274       ss.print("arraycopy: last source index %u out of bounds for object array[%d]",
275                (unsigned int) length + (unsigned int) src_pos, s->length());
276     } else {
277       ss.print("arraycopy: last destination index %u out of bounds for object array[%d]",
278                (unsigned int) length + (unsigned int) dst_pos, d->length());
279     }
280     THROW_MSG(vmSymbols::java_lang_ArrayIndexOutOfBoundsException(), ss.as_string());
281   }
282 
283   // Special case. Boundary cases must be checked first
284   // This allows the following call: copy_array(s, s.length(), d.length(), 0).
285   // This is correct, since the position is supposed to be an 'in between point', i.e., s.length(),
286   // points to the right of the last element.
287   if (length==0) {
288     return;
289   }
290   if (UseCompressedOops) {
291     size_t src_offset = (size_t) objArrayOopDesc::obj_at_offset<narrowOop>(src_pos);
292     size_t dst_offset = (size_t) objArrayOopDesc::obj_at_offset<narrowOop>(dst_pos);
293     assert(arrayOopDesc::obj_offset_to_raw<narrowOop>(s, src_offset, NULL) ==
294            objArrayOop(s)->obj_at_addr<narrowOop>(src_pos), "sanity");
295     assert(arrayOopDesc::obj_offset_to_raw<narrowOop>(d, dst_offset, NULL) ==
296            objArrayOop(d)->obj_at_addr<narrowOop>(dst_pos), "sanity");
297     do_copy(s, src_offset, d, dst_offset, length, CHECK);
298   } else {
299     size_t src_offset = (size_t) objArrayOopDesc::obj_at_offset<oop>(src_pos);
300     size_t dst_offset = (size_t) objArrayOopDesc::obj_at_offset<oop>(dst_pos);
301     assert(arrayOopDesc::obj_offset_to_raw<oop>(s, src_offset, NULL) ==
302            objArrayOop(s)->obj_at_addr<oop>(src_pos), "sanity");
303     assert(arrayOopDesc::obj_offset_to_raw<oop>(d, dst_offset, NULL) ==
304            objArrayOop(d)->obj_at_addr<oop>(dst_pos), "sanity");
305     do_copy(s, src_offset, d, dst_offset, length, CHECK);
306   }
307 }
308 
309 
310 Klass* ObjArrayKlass::array_klass_impl(bool or_null, int n, TRAPS) {
311 
312   assert(dimension() <= n, "check order of chain");
313   int dim = dimension();
314   if (dim == n) return this;
315 
316   // lock-free read needs acquire semantics
317   if (higher_dimension_acquire() == NULL) {
318     if (or_null)  return NULL;
319 
320     ResourceMark rm;
321     JavaThread *jt = (JavaThread *)THREAD;
322     {
323       MutexLocker mc(Compile_lock, THREAD);   // for vtables
324       // Ensure atomic creation of higher dimensions
< prev index next >