< prev index next >

src/share/vm/opto/cfgnode.cpp

Print this page

        

@@ -1641,10 +1641,46 @@
       }
       return vt;
     }
   }
 
+  if (type()->isa_valuetypeptr() && can_reshape) {
+    const TypeValueTypePtr* vtptr = NULL;
+    for (uint i = 1; i < req(); i++) {
+      if (in(i) != NULL && in(i)->is_ValueTypePtr()) {
+        const TypeValueTypePtr* t = phase->type(in(i))->is_valuetypeptr();
+        if (vtptr == NULL) {
+          vtptr = t;
+        } else {
+          assert(vtptr == t, "Phi should merge identical value types");
+        }
+      } else {
+        assert(in(i) == NULL || vtptr == NULL || phase->type(in(i))->higher_equal(vtptr) || phase->type(in(i)) == Type::TOP ||
+               phase->type(in(i))->is_valuetypeptr()->value_type()->value_klass() == phase->C->env()->___Value_klass(), "bad type");
+      }
+    }
+    if (vtptr != NULL) {
+      // One input is a value type. All inputs must have the same
+      // type.
+      bool progress = false;
+      PhaseIterGVN* igvn = phase->is_IterGVN();
+      for (uint i = 1; i < req(); i++) {
+        if (in(i) != NULL && !phase->type(in(i))->higher_equal(vtptr)) {
+          // Can't transform because CheckCastPPNode::Identity can
+          // push the cast up through another Phi and cause this same
+          // transformation to run again, indefinitely
+          Node* cast = igvn->register_new_node_with_optimizer(new CheckCastPPNode(NULL, in(i), vtptr));
+          set_req(i, cast);
+          progress = true;
+        }
+      }
+      if (progress) {
+        return this;
+      }
+    }
+  }
+
   Node *top = phase->C->top();
   bool new_phi = (outcnt() == 0); // transforming new Phi
   // No change for igvn if new phi is not hooked
   if (new_phi && can_reshape)
     return NULL;

@@ -2343,10 +2379,11 @@
   if( phase->type(in(1)) == Type::TOP ) return in(1);
   if( phase->type(in(0)) == Type::TOP ) return in(0);
   // We only come from CatchProj, unless the CatchProj goes away.
   // If the CatchProj is optimized away, then we just carry the
   // exception oop through.
+  if (in(1)->is_Phi()) return this;
   CallNode *call = in(1)->in(0)->as_Call();
 
   return ( in(0)->is_CatchProj() && in(0)->in(0)->in(1) == in(1) )
     ? this
     : call->in(TypeFunc::Parms);
< prev index next >