diff -r 52b70541d4d3 -r 519e22b6900d hotspot/src/share/vm/opto/escape.cpp --- a/hotspot/src/share/vm/opto/escape.cpp Mon May 11 17:59:54 2009 -0700 +++ b/hotspot/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)