comparison src/share/vm/opto/parse3.cpp @ 3805:263247c478c5

7058510: multinewarray with 6 dimensions uncommon traps in server compiler Summary: Pass arguments to runtime via java array for arrays with > 5 dimensions Reviewed-by: never, kvn, jrose, pbk
author iveresov
date Fri, 08 Jul 2011 15:33:03 -0700
parents c7f3d0b4570f
children fdb992d83a87
comparison
equal deleted inserted replaced
3804:faa472957b38 3805:263247c478c5
415 ciArrayKlass* array_klass = iter().get_klass(will_link)->as_array_klass(); 415 ciArrayKlass* array_klass = iter().get_klass(will_link)->as_array_klass();
416 assert(will_link, "multianewarray: typeflow responsibility"); 416 assert(will_link, "multianewarray: typeflow responsibility");
417 417
418 // Note: Array classes are always initialized; no is_initialized check. 418 // Note: Array classes are always initialized; no is_initialized check.
419 419
420 enum { MAX_DIMENSION = 5 };
421 if (ndimensions > MAX_DIMENSION || ndimensions <= 0) {
422 uncommon_trap(Deoptimization::Reason_unhandled,
423 Deoptimization::Action_none);
424 return;
425 }
426
427 kill_dead_locals(); 420 kill_dead_locals();
428 421
429 // get the lengths from the stack (first dimension is on top) 422 // get the lengths from the stack (first dimension is on top)
430 Node* length[MAX_DIMENSION+1]; 423 Node** length = NEW_RESOURCE_ARRAY(Node*, ndimensions + 1);
431 length[ndimensions] = NULL; // terminating null for make_runtime_call 424 length[ndimensions] = NULL; // terminating null for make_runtime_call
432 int j; 425 int j;
433 for (j = ndimensions-1; j >= 0 ; j--) length[j] = pop(); 426 for (j = ndimensions-1; j >= 0 ; j--) length[j] = pop();
434 427
435 // The original expression was of this form: new T[length0][length1]... 428 // The original expression was of this form: new T[length0][length1]...
468 return; 461 return;
469 } 462 }
470 463
471 address fun = NULL; 464 address fun = NULL;
472 switch (ndimensions) { 465 switch (ndimensions) {
473 //case 1: Actually, there is no case 1. It's handled by new_array. 466 case 1: ShouldNotReachHere(); break;
474 case 2: fun = OptoRuntime::multianewarray2_Java(); break; 467 case 2: fun = OptoRuntime::multianewarray2_Java(); break;
475 case 3: fun = OptoRuntime::multianewarray3_Java(); break; 468 case 3: fun = OptoRuntime::multianewarray3_Java(); break;
476 case 4: fun = OptoRuntime::multianewarray4_Java(); break; 469 case 4: fun = OptoRuntime::multianewarray4_Java(); break;
477 case 5: fun = OptoRuntime::multianewarray5_Java(); break; 470 case 5: fun = OptoRuntime::multianewarray5_Java(); break;
478 default: ShouldNotReachHere();
479 }; 471 };
480 472 Node* c = NULL;
481 Node* c = make_runtime_call(RC_NO_LEAF | RC_NO_IO, 473
482 OptoRuntime::multianewarray_Type(ndimensions), 474 if (fun != NULL) {
483 fun, NULL, TypeRawPtr::BOTTOM, 475 c = make_runtime_call(RC_NO_LEAF | RC_NO_IO,
484 makecon(TypeKlassPtr::make(array_klass)), 476 OptoRuntime::multianewarray_Type(ndimensions),
485 length[0], length[1], length[2], 477 fun, NULL, TypeRawPtr::BOTTOM,
486 length[3], length[4]); 478 makecon(TypeKlassPtr::make(array_klass)),
479 length[0], length[1], length[2],
480 length[3], length[4]);
481 } else {
482 // Create a java array for dimension sizes
483 Node* dims = NULL;
484 { PreserveReexecuteState preexecs(this);
485 _sp += ndimensions;
486 Node* dims_array_klass = makecon(TypeKlassPtr::make(ciArrayKlass::make(ciType::make(T_INT))));
487 dims = new_array(dims_array_klass, intcon(ndimensions), 0);
488
489 // Fill-in it with values
490 for (j = 0; j < ndimensions; j++) {
491 Node *dims_elem = array_element_address(dims, intcon(j), T_INT);
492 store_to_memory(control(), dims_elem, length[j], T_INT, TypeAryPtr::INTS);
493 }
494 }
495
496 c = make_runtime_call(RC_NO_LEAF | RC_NO_IO,
497 OptoRuntime::multianewarrayN_Type(),
498 OptoRuntime::multianewarrayN_Java(), NULL, TypeRawPtr::BOTTOM,
499 makecon(TypeKlassPtr::make(array_klass)),
500 dims);
501 }
502
487 Node* res = _gvn.transform(new (C, 1) ProjNode(c, TypeFunc::Parms)); 503 Node* res = _gvn.transform(new (C, 1) ProjNode(c, TypeFunc::Parms));
488 504
489 const Type* type = TypeOopPtr::make_from_klass_raw(array_klass); 505 const Type* type = TypeOopPtr::make_from_klass_raw(array_klass);
490 506
491 // Improve the type: We know it's not null, exact, and of a given length. 507 // Improve the type: We know it's not null, exact, and of a given length.
494 510
495 const TypeInt* ltype = _gvn.find_int_type(length[0]); 511 const TypeInt* ltype = _gvn.find_int_type(length[0]);
496 if (ltype != NULL) 512 if (ltype != NULL)
497 type = type->is_aryptr()->cast_to_size(ltype); 513 type = type->is_aryptr()->cast_to_size(ltype);
498 514
499 // We cannot sharpen the nested sub-arrays, since the top level is mutable. 515 // We cannot sharpen the nested sub-arrays, since the top level is mutable.
500 516
501 Node* cast = _gvn.transform( new (C, 2) CheckCastPPNode(control(), res, type) ); 517 Node* cast = _gvn.transform( new (C, 2) CheckCastPPNode(control(), res, type) );
502 push(cast); 518 push(cast);
503 519
504 // Possible improvements: 520 // Possible improvements: