284 oop result; |
284 oop result; |
285 |
285 |
286 if (Klass::cast(array_type)->oop_is_typeArray()) { |
286 if (Klass::cast(array_type)->oop_is_typeArray()) { |
287 // The oopFactory likes to work with the element type. |
287 // The oopFactory likes to work with the element type. |
288 // (We could bypass the oopFactory, since it doesn't add much value.) |
288 // (We could bypass the oopFactory, since it doesn't add much value.) |
289 BasicType elem_type = typeArrayKlass::cast(array_type)->element_type(); |
289 BasicType elem_type = TypeArrayKlass::cast(array_type)->element_type(); |
290 result = oopFactory::new_typeArray(elem_type, len, THREAD); |
290 result = oopFactory::new_typeArray(elem_type, len, THREAD); |
291 } else { |
291 } else { |
292 // Although the oopFactory likes to work with the elem_type, |
292 // Although the oopFactory likes to work with the elem_type, |
293 // the compiler prefers the array_type, since it must already have |
293 // the compiler prefers the array_type, since it must already have |
294 // that latter value in hand for the fast path. |
294 // that latter value in hand for the fast path. |
295 Klass* elem_type = objArrayKlass::cast(array_type)->element_klass(); |
295 Klass* elem_type = ObjArrayKlass::cast(array_type)->element_klass(); |
296 result = oopFactory::new_objArray(elem_type, len, THREAD); |
296 result = oopFactory::new_objArray(elem_type, len, THREAD); |
297 } |
297 } |
298 |
298 |
299 // Pass oops back through thread local storage. Our apparent type to Java |
299 // Pass oops back through thread local storage. Our apparent type to Java |
300 // is that we return an oop, but we can block on exit from this routine and |
300 // is that we return an oop, but we can block on exit from this routine and |
321 // Scavenge and allocate an instance. |
321 // Scavenge and allocate an instance. |
322 oop result; |
322 oop result; |
323 |
323 |
324 assert(Klass::cast(array_type)->oop_is_typeArray(), "should be called only for type array"); |
324 assert(Klass::cast(array_type)->oop_is_typeArray(), "should be called only for type array"); |
325 // The oopFactory likes to work with the element type. |
325 // The oopFactory likes to work with the element type. |
326 BasicType elem_type = typeArrayKlass::cast(array_type)->element_type(); |
326 BasicType elem_type = TypeArrayKlass::cast(array_type)->element_type(); |
327 result = oopFactory::new_typeArray_nozero(elem_type, len, THREAD); |
327 result = oopFactory::new_typeArray_nozero(elem_type, len, THREAD); |
328 |
328 |
329 // Pass oops back through thread local storage. Our apparent type to Java |
329 // Pass oops back through thread local storage. Our apparent type to Java |
330 // is that we return an oop, but we can block on exit from this routine and |
330 // is that we return an oop, but we can block on exit from this routine and |
331 // a GC can trash the oop in C's return register. The generated stub will |
331 // a GC can trash the oop in C's return register. The generated stub will |
342 oop result = thread->vm_result(); |
342 oop result = thread->vm_result(); |
343 if ((len > 0) && (result != NULL) && |
343 if ((len > 0) && (result != NULL) && |
344 is_deoptimized_caller_frame(thread)) { |
344 is_deoptimized_caller_frame(thread)) { |
345 // Zero array here if the caller is deoptimized. |
345 // Zero array here if the caller is deoptimized. |
346 int size = ((typeArrayOop)result)->object_size(); |
346 int size = ((typeArrayOop)result)->object_size(); |
347 BasicType elem_type = typeArrayKlass::cast(array_type)->element_type(); |
347 BasicType elem_type = TypeArrayKlass::cast(array_type)->element_type(); |
348 const size_t hs = arrayOopDesc::header_size(elem_type); |
348 const size_t hs = arrayOopDesc::header_size(elem_type); |
349 // Align to next 8 bytes to avoid trashing arrays's length. |
349 // Align to next 8 bytes to avoid trashing arrays's length. |
350 const size_t aligned_hs = align_object_offset(hs); |
350 const size_t aligned_hs = align_object_offset(hs); |
351 HeapWord* obj = (HeapWord*)result; |
351 HeapWord* obj = (HeapWord*)result; |
352 if (aligned_hs > hs) { |
352 if (aligned_hs > hs) { |
368 assert(check_compiled_frame(thread), "incorrect caller"); |
368 assert(check_compiled_frame(thread), "incorrect caller"); |
369 assert(elem_type->is_klass(), "not a class"); |
369 assert(elem_type->is_klass(), "not a class"); |
370 jint dims[2]; |
370 jint dims[2]; |
371 dims[0] = len1; |
371 dims[0] = len1; |
372 dims[1] = len2; |
372 dims[1] = len2; |
373 oop obj = arrayKlass::cast(elem_type)->multi_allocate(2, dims, THREAD); |
373 oop obj = ArrayKlass::cast(elem_type)->multi_allocate(2, dims, THREAD); |
374 deoptimize_caller_frame(thread, HAS_PENDING_EXCEPTION); |
374 deoptimize_caller_frame(thread, HAS_PENDING_EXCEPTION); |
375 thread->set_vm_result(obj); |
375 thread->set_vm_result(obj); |
376 JRT_END |
376 JRT_END |
377 |
377 |
378 // multianewarray for 3 dimensions |
378 // multianewarray for 3 dimensions |
384 assert(elem_type->is_klass(), "not a class"); |
384 assert(elem_type->is_klass(), "not a class"); |
385 jint dims[3]; |
385 jint dims[3]; |
386 dims[0] = len1; |
386 dims[0] = len1; |
387 dims[1] = len2; |
387 dims[1] = len2; |
388 dims[2] = len3; |
388 dims[2] = len3; |
389 oop obj = arrayKlass::cast(elem_type)->multi_allocate(3, dims, THREAD); |
389 oop obj = ArrayKlass::cast(elem_type)->multi_allocate(3, dims, THREAD); |
390 deoptimize_caller_frame(thread, HAS_PENDING_EXCEPTION); |
390 deoptimize_caller_frame(thread, HAS_PENDING_EXCEPTION); |
391 thread->set_vm_result(obj); |
391 thread->set_vm_result(obj); |
392 JRT_END |
392 JRT_END |
393 |
393 |
394 // multianewarray for 4 dimensions |
394 // multianewarray for 4 dimensions |
401 jint dims[4]; |
401 jint dims[4]; |
402 dims[0] = len1; |
402 dims[0] = len1; |
403 dims[1] = len2; |
403 dims[1] = len2; |
404 dims[2] = len3; |
404 dims[2] = len3; |
405 dims[3] = len4; |
405 dims[3] = len4; |
406 oop obj = arrayKlass::cast(elem_type)->multi_allocate(4, dims, THREAD); |
406 oop obj = ArrayKlass::cast(elem_type)->multi_allocate(4, dims, THREAD); |
407 deoptimize_caller_frame(thread, HAS_PENDING_EXCEPTION); |
407 deoptimize_caller_frame(thread, HAS_PENDING_EXCEPTION); |
408 thread->set_vm_result(obj); |
408 thread->set_vm_result(obj); |
409 JRT_END |
409 JRT_END |
410 |
410 |
411 // multianewarray for 5 dimensions |
411 // multianewarray for 5 dimensions |
419 dims[0] = len1; |
419 dims[0] = len1; |
420 dims[1] = len2; |
420 dims[1] = len2; |
421 dims[2] = len3; |
421 dims[2] = len3; |
422 dims[3] = len4; |
422 dims[3] = len4; |
423 dims[4] = len5; |
423 dims[4] = len5; |
424 oop obj = arrayKlass::cast(elem_type)->multi_allocate(5, dims, THREAD); |
424 oop obj = ArrayKlass::cast(elem_type)->multi_allocate(5, dims, THREAD); |
425 deoptimize_caller_frame(thread, HAS_PENDING_EXCEPTION); |
425 deoptimize_caller_frame(thread, HAS_PENDING_EXCEPTION); |
426 thread->set_vm_result(obj); |
426 thread->set_vm_result(obj); |
427 JRT_END |
427 JRT_END |
428 |
428 |
429 JRT_ENTRY(void, OptoRuntime::multianewarrayN_C(Klass* elem_type, arrayOopDesc* dims, JavaThread *thread)) |
429 JRT_ENTRY(void, OptoRuntime::multianewarrayN_C(Klass* elem_type, arrayOopDesc* dims, JavaThread *thread)) |
436 assert(len > 0, "Dimensions array should contain data"); |
436 assert(len > 0, "Dimensions array should contain data"); |
437 jint *j_dims = typeArrayOop(dims)->int_at_addr(0); |
437 jint *j_dims = typeArrayOop(dims)->int_at_addr(0); |
438 jint *c_dims = NEW_RESOURCE_ARRAY(jint, len); |
438 jint *c_dims = NEW_RESOURCE_ARRAY(jint, len); |
439 Copy::conjoint_jints_atomic(j_dims, c_dims, len); |
439 Copy::conjoint_jints_atomic(j_dims, c_dims, len); |
440 |
440 |
441 oop obj = arrayKlass::cast(elem_type)->multi_allocate(len, c_dims, THREAD); |
441 oop obj = ArrayKlass::cast(elem_type)->multi_allocate(len, c_dims, THREAD); |
442 deoptimize_caller_frame(thread, HAS_PENDING_EXCEPTION); |
442 deoptimize_caller_frame(thread, HAS_PENDING_EXCEPTION); |
443 thread->set_vm_result(obj); |
443 thread->set_vm_result(obj); |
444 JRT_END |
444 JRT_END |
445 |
445 |
446 |
446 |