Mercurial > hg > truffle
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: |