327 else { 328 return Universe::typeArrayKlassObj(type); 329 } 330 } 331 332 arrayOop Reflection::reflect_new_array(oop element_mirror, jint length, TRAPS) { 333 if (element_mirror == NULL) { 334 THROW_0(vmSymbols::java_lang_NullPointerException()); 335 } 336 if (length < 0) { 337 THROW_MSG_0(vmSymbols::java_lang_NegativeArraySizeException(), err_msg("%d", length)); 338 } 339 if (java_lang_Class::is_primitive(element_mirror)) { 340 Klass* tak = basic_type_mirror_to_arrayklass(element_mirror, CHECK_NULL); 341 return TypeArrayKlass::cast(tak)->allocate(length, THREAD); 342 } else { 343 Klass* k = java_lang_Class::as_Klass(element_mirror); 344 if (k->is_array_klass() && ArrayKlass::cast(k)->dimension() >= MAX_DIM) { 345 THROW_0(vmSymbols::java_lang_IllegalArgumentException()); 346 } 347 return oopFactory::new_array(k, length, THREAD); 348 } 349 } 350 351 352 arrayOop Reflection::reflect_new_multi_array(oop element_mirror, typeArrayOop dim_array, TRAPS) { 353 assert(dim_array->is_typeArray(), "just checking"); 354 assert(TypeArrayKlass::cast(dim_array->klass())->element_type() == T_INT, "just checking"); 355 356 if (element_mirror == NULL) { 357 THROW_0(vmSymbols::java_lang_NullPointerException()); 358 } 359 360 int len = dim_array->length(); 361 if (len <= 0 || len > MAX_DIM) { 362 THROW_0(vmSymbols::java_lang_IllegalArgumentException()); 363 } 364 365 jint dimensions[MAX_DIM]; // C array copy of intArrayOop 366 for (int i = 0; i < len; i++) { 367 int d = dim_array->int_at(i); 368 if (d < 0) { 369 THROW_MSG_0(vmSymbols::java_lang_NegativeArraySizeException(), err_msg("%d", d)); 370 } 371 dimensions[i] = d; 372 } 373 374 Klass* klass; 375 int dim = len; 376 if (java_lang_Class::is_primitive(element_mirror)) { 377 klass = basic_type_mirror_to_arrayklass(element_mirror, CHECK_NULL); 378 } else { 379 klass = java_lang_Class::as_Klass(element_mirror); 380 if (klass->is_array_klass()) { 381 int k_dim = ArrayKlass::cast(klass)->dimension(); 382 if (k_dim + len > MAX_DIM) { 383 THROW_0(vmSymbols::java_lang_IllegalArgumentException()); 384 } 385 dim += k_dim; 386 } 387 } 388 klass = klass->array_klass(dim, CHECK_NULL); 389 oop obj = ArrayKlass::cast(klass)->multi_allocate(len, dimensions, CHECK_NULL); 390 assert(obj->is_array(), "just checking"); 391 return arrayOop(obj); 392 } 393 394 395 static bool under_unsafe_anonymous_host(const InstanceKlass* ik, const InstanceKlass* unsafe_anonymous_host) { 396 DEBUG_ONLY(int inf_loop_check = 1000 * 1000 * 1000); 397 for (;;) { 398 const InstanceKlass* hc = ik->unsafe_anonymous_host(); 399 if (hc == NULL) return false; 400 if (hc == unsafe_anonymous_host) return true; 401 ik = hc; 402 403 // There's no way to make a host class loop short of patching memory. 404 // Therefore there cannot be a loop here unless there's another bug. 405 // Still, let's check for it. 406 assert(--inf_loop_check > 0, "no unsafe_anonymous_host loop"); 407 } 408 } | 327 else { 328 return Universe::typeArrayKlassObj(type); 329 } 330 } 331 332 arrayOop Reflection::reflect_new_array(oop element_mirror, jint length, TRAPS) { 333 if (element_mirror == NULL) { 334 THROW_0(vmSymbols::java_lang_NullPointerException()); 335 } 336 if (length < 0) { 337 THROW_MSG_0(vmSymbols::java_lang_NegativeArraySizeException(), err_msg("%d", length)); 338 } 339 if (java_lang_Class::is_primitive(element_mirror)) { 340 Klass* tak = basic_type_mirror_to_arrayklass(element_mirror, CHECK_NULL); 341 return TypeArrayKlass::cast(tak)->allocate(length, THREAD); 342 } else { 343 Klass* k = java_lang_Class::as_Klass(element_mirror); 344 if (k->is_array_klass() && ArrayKlass::cast(k)->dimension() >= MAX_DIM) { 345 THROW_0(vmSymbols::java_lang_IllegalArgumentException()); 346 } 347 if (java_lang_Class::is_box_type(element_mirror)) { 348 return oopFactory::new_objArray(k, length, THREAD); 349 } else { 350 return oopFactory::new_valueArray(k, length, THREAD); 351 } 352 } 353 } 354 355 356 arrayOop Reflection::reflect_new_multi_array(oop element_mirror, typeArrayOop dim_array, TRAPS) { 357 assert(dim_array->is_typeArray(), "just checking"); 358 assert(TypeArrayKlass::cast(dim_array->klass())->element_type() == T_INT, "just checking"); 359 360 if (element_mirror == NULL) { 361 THROW_0(vmSymbols::java_lang_NullPointerException()); 362 } 363 364 int len = dim_array->length(); 365 if (len <= 0 || len > MAX_DIM) { 366 THROW_0(vmSymbols::java_lang_IllegalArgumentException()); 367 } 368 369 jint dimensions[MAX_DIM]; // C array copy of intArrayOop 370 for (int i = 0; i < len; i++) { 371 int d = dim_array->int_at(i); 372 if (d < 0) { 373 THROW_MSG_0(vmSymbols::java_lang_NegativeArraySizeException(), err_msg("%d", d)); 374 } 375 dimensions[i] = d; 376 } 377 378 Klass* klass; 379 int dim = len; 380 if (java_lang_Class::is_primitive(element_mirror)) { 381 klass = basic_type_mirror_to_arrayklass(element_mirror, CHECK_NULL); 382 } else { 383 klass = java_lang_Class::as_Klass(element_mirror); 384 if (klass->is_array_klass()) { 385 int k_dim = ArrayKlass::cast(klass)->dimension(); 386 if (k_dim + len > MAX_DIM) { 387 THROW_0(vmSymbols::java_lang_IllegalArgumentException()); 388 } 389 dim += k_dim; 390 } 391 } 392 ArrayStorageProperties storage_props = FieldType::get_array_storage_properties(klass->name()); 393 klass = klass->array_klass(storage_props, dim, CHECK_NULL); 394 oop obj = ArrayKlass::cast(klass)->multi_allocate(len, dimensions, CHECK_NULL); 395 assert(obj->is_array(), "just checking"); 396 return arrayOop(obj); 397 } 398 399 400 static bool under_unsafe_anonymous_host(const InstanceKlass* ik, const InstanceKlass* unsafe_anonymous_host) { 401 DEBUG_ONLY(int inf_loop_check = 1000 * 1000 * 1000); 402 for (;;) { 403 const InstanceKlass* hc = ik->unsafe_anonymous_host(); 404 if (hc == NULL) return false; 405 if (hc == unsafe_anonymous_host) return true; 406 ik = hc; 407 408 // There's no way to make a host class loop short of patching memory. 409 // Therefore there cannot be a loop here unless there's another bug. 410 // Still, let's check for it. 411 assert(--inf_loop_check > 0, "no unsafe_anonymous_host loop"); 412 } 413 } |