# HG changeset patch # User kvn # Date 1242091813 25200 # Node ID b2934faac289474f3147a67e9dc0ff7d8252b3a3 # Parent a9e1164550227cd3dcce3b48e424fd4b33cd61b2 6836054: java/util/Arrays/CopyMethods.java fails on solaris-sparc with IllegalArgumentException Summary: Do not mark an allocation as scalar replaceable if its actual type in unknown statically. Reviewed-by: never diff -r a9e116455022 -r b2934faac289 src/share/vm/opto/escape.cpp --- a/src/share/vm/opto/escape.cpp Mon May 11 17:59:54 2009 -0700 +++ b/src/share/vm/opto/escape.cpp Mon May 11 18:30:13 2009 -0700 @@ -905,15 +905,22 @@ // see if it is unescaped. if (es != PointsToNode::NoEscape || !ptn->_scalar_replaceable) continue; - if (alloc->is_Allocate()) { - // Set the scalar_replaceable flag before the next check. - alloc->as_Allocate()->_is_scalar_replaceable = true; + + // Find CheckCastPP for the allocate or for the return value of a call + n = alloc->result_cast(); + if (n == NULL) { // No uses except Initialize node + if (alloc->is_Allocate()) { + // Set the scalar_replaceable flag for allocation + // so it could be eliminated if it has no uses. + alloc->as_Allocate()->_is_scalar_replaceable = true; + } + continue; } - // find CheckCastPP of call return value - n = alloc->result_cast(); - if (n == NULL || // No uses accept Initialize or - !n->is_CheckCastPP()) // not unique CheckCastPP. + if (!n->is_CheckCastPP()) { // not unique CheckCastPP. + assert(!alloc->is_Allocate(), "allocation should have unique type"); continue; + } + // The inline code for Object.clone() casts the allocation result to // java.lang.Object and then to the actual type of the allocated // object. Detect this case and use the second cast. @@ -934,9 +941,17 @@ if (cast2 != NULL) { n = cast2; } else { + // Non-scalar replaceable if the allocation type is unknown statically + // (reflection allocation), the object can't be restored during + // deoptimization without precise type. continue; } } + if (alloc->is_Allocate()) { + // Set the scalar_replaceable flag for allocation + // so it could be eliminated. + alloc->as_Allocate()->_is_scalar_replaceable = true; + } set_escape_state(n->_idx, es); // in order for an object to be scalar-replaceable, it must be: // - a direct allocation (not a call returning an object)