209 // We have to make sure all elements conform to the destination array 210 Klass* bound = ObjArrayKlass::cast(d->klass())->element_klass(); 211 Klass* stype = ObjArrayKlass::cast(s->klass())->element_klass(); 212 if (stype == bound || stype->is_subtype_of(bound)) { 213 // elements are guaranteed to be subtypes, so no check necessary 214 HeapAccess<ARRAYCOPY_DISJOINT>::oop_arraycopy(s, d, src, dst, length); 215 } else { 216 // slow case: need individual subtype checks 217 // note: don't use obj_at_put below because it includes a redundant store check 218 if (!HeapAccess<ARRAYCOPY_DISJOINT | ARRAYCOPY_CHECKCAST>::oop_arraycopy(s, d, src, dst, length)) { 219 THROW(vmSymbols::java_lang_ArrayStoreException()); 220 } 221 } 222 } 223 } 224 225 void ObjArrayKlass::copy_array(arrayOop s, int src_pos, arrayOop d, 226 int dst_pos, int length, TRAPS) { 227 assert(s->is_objArray(), "must be obj array"); 228 229 if (!d->is_objArray()) { 230 THROW(vmSymbols::java_lang_ArrayStoreException()); 231 } 232 233 // Check is all offsets and lengths are non negative 234 if (src_pos < 0 || dst_pos < 0 || length < 0) { 235 THROW(vmSymbols::java_lang_ArrayIndexOutOfBoundsException()); 236 } 237 // Check if the ranges are valid 238 if ( (((unsigned int) length + (unsigned int) src_pos) > (unsigned int) s->length()) 239 || (((unsigned int) length + (unsigned int) dst_pos) > (unsigned int) d->length()) ) { 240 THROW(vmSymbols::java_lang_ArrayIndexOutOfBoundsException()); 241 } 242 243 // Special case. Boundary cases must be checked first 244 // This allows the following call: copy_array(s, s.length(), d.length(), 0). 245 // This is correct, since the position is supposed to be an 'in between point', i.e., s.length(), 246 // points to the right of the last element. 247 if (length==0) { 248 return; 319 int num_secondaries = num_extra_slots + 2 + num_elem_supers; 320 if (num_secondaries == 2) { 321 // Must share this for correct bootstrapping! 322 set_secondary_supers(Universe::the_array_interfaces_array()); 323 return NULL; 324 } else { 325 GrowableArray<Klass*>* secondaries = new GrowableArray<Klass*>(num_elem_supers+2); 326 secondaries->push(SystemDictionary::Cloneable_klass()); 327 secondaries->push(SystemDictionary::Serializable_klass()); 328 for (int i = 0; i < num_elem_supers; i++) { 329 Klass* elem_super = (Klass*) elem_supers->at(i); 330 Klass* array_super = elem_super->array_klass_or_null(); 331 assert(array_super != NULL, "must already have been created"); 332 secondaries->push(array_super); 333 } 334 return secondaries; 335 } 336 } 337 338 bool ObjArrayKlass::compute_is_subtype_of(Klass* k) { 339 if (!k->is_objArray_klass()) 340 return ArrayKlass::compute_is_subtype_of(k); 341 342 ObjArrayKlass* oak = ObjArrayKlass::cast(k); 343 return element_klass()->is_subtype_of(oak->element_klass()); 344 } 345 346 void ObjArrayKlass::initialize(TRAPS) { 347 bottom_klass()->initialize(THREAD); // dispatches to either InstanceKlass or TypeArrayKlass 348 } 349 350 void ObjArrayKlass::metaspace_pointers_do(MetaspaceClosure* it) { 351 ArrayKlass::metaspace_pointers_do(it); 352 it->push(&_element_klass); 353 it->push(&_bottom_klass); 354 } 355 356 // JVM support 357 358 jint ObjArrayKlass::compute_modifier_flags(TRAPS) const { 359 // The modifier for an objectArray is the same as its element 360 if (element_klass() == NULL) { 361 assert(Universe::is_bootstrapping(), "partial objArray only at startup"); 362 return JVM_ACC_ABSTRACT | JVM_ACC_FINAL | JVM_ACC_PUBLIC; 363 } | 209 // We have to make sure all elements conform to the destination array 210 Klass* bound = ObjArrayKlass::cast(d->klass())->element_klass(); 211 Klass* stype = ObjArrayKlass::cast(s->klass())->element_klass(); 212 if (stype == bound || stype->is_subtype_of(bound)) { 213 // elements are guaranteed to be subtypes, so no check necessary 214 HeapAccess<ARRAYCOPY_DISJOINT>::oop_arraycopy(s, d, src, dst, length); 215 } else { 216 // slow case: need individual subtype checks 217 // note: don't use obj_at_put below because it includes a redundant store check 218 if (!HeapAccess<ARRAYCOPY_DISJOINT | ARRAYCOPY_CHECKCAST>::oop_arraycopy(s, d, src, dst, length)) { 219 THROW(vmSymbols::java_lang_ArrayStoreException()); 220 } 221 } 222 } 223 } 224 225 void ObjArrayKlass::copy_array(arrayOop s, int src_pos, arrayOop d, 226 int dst_pos, int length, TRAPS) { 227 assert(s->is_objArray(), "must be obj array"); 228 229 if (d->is_valueArray()) { 230 ValueArrayKlass::cast(d->klass())->copy_array(s, src_pos, d, dst_pos, length, THREAD); 231 return; 232 } 233 234 if (!d->is_objArray()) { 235 THROW(vmSymbols::java_lang_ArrayStoreException()); 236 } 237 238 // Check is all offsets and lengths are non negative 239 if (src_pos < 0 || dst_pos < 0 || length < 0) { 240 THROW(vmSymbols::java_lang_ArrayIndexOutOfBoundsException()); 241 } 242 // Check if the ranges are valid 243 if ( (((unsigned int) length + (unsigned int) src_pos) > (unsigned int) s->length()) 244 || (((unsigned int) length + (unsigned int) dst_pos) > (unsigned int) d->length()) ) { 245 THROW(vmSymbols::java_lang_ArrayIndexOutOfBoundsException()); 246 } 247 248 // Special case. Boundary cases must be checked first 249 // This allows the following call: copy_array(s, s.length(), d.length(), 0). 250 // This is correct, since the position is supposed to be an 'in between point', i.e., s.length(), 251 // points to the right of the last element. 252 if (length==0) { 253 return; 324 int num_secondaries = num_extra_slots + 2 + num_elem_supers; 325 if (num_secondaries == 2) { 326 // Must share this for correct bootstrapping! 327 set_secondary_supers(Universe::the_array_interfaces_array()); 328 return NULL; 329 } else { 330 GrowableArray<Klass*>* secondaries = new GrowableArray<Klass*>(num_elem_supers+2); 331 secondaries->push(SystemDictionary::Cloneable_klass()); 332 secondaries->push(SystemDictionary::Serializable_klass()); 333 for (int i = 0; i < num_elem_supers; i++) { 334 Klass* elem_super = (Klass*) elem_supers->at(i); 335 Klass* array_super = elem_super->array_klass_or_null(); 336 assert(array_super != NULL, "must already have been created"); 337 secondaries->push(array_super); 338 } 339 return secondaries; 340 } 341 } 342 343 bool ObjArrayKlass::compute_is_subtype_of(Klass* k) { 344 if (k->is_valueArray_klass() || k->is_objArray_klass()) { 345 return element_klass()->is_subtype_of(ArrayKlass::cast(k)->element_klass()); 346 } else { 347 return ArrayKlass::compute_is_subtype_of(k); 348 } 349 } 350 351 void ObjArrayKlass::initialize(TRAPS) { 352 bottom_klass()->initialize(THREAD); // dispatches to either InstanceKlass or TypeArrayKlass 353 } 354 355 void ObjArrayKlass::metaspace_pointers_do(MetaspaceClosure* it) { 356 ArrayKlass::metaspace_pointers_do(it); 357 it->push(&_element_klass); 358 it->push(&_bottom_klass); 359 } 360 361 // JVM support 362 363 jint ObjArrayKlass::compute_modifier_flags(TRAPS) const { 364 // The modifier for an objectArray is the same as its element 365 if (element_klass() == NULL) { 366 assert(Universe::is_bootstrapping(), "partial objArray only at startup"); 367 return JVM_ACC_ABSTRACT | JVM_ACC_FINAL | JVM_ACC_PUBLIC; 368 } |