6836054: java/util/Arrays/CopyMethods.java fails on solaris-sparc with IllegalArgumentException
authorkvn
Mon, 11 May 2009 18:30:13 -0700
changeset 2871 519e22b6900d
parent 2870 52b70541d4d3
child 2872 93eb5ac6cfb0
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
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)