< prev index next >

src/share/vm/opto/cfgnode.cpp

Print this page
rev 9165 : 8141551: C2 can not handle returns with inccompatible interface arrays
Reviewed-by: kvn

@@ -982,29 +982,42 @@
   const Type* ft = t->filter_speculative(_type);  // Worst case type
 
 #ifdef ASSERT
   // The following logic has been moved into TypeOopPtr::filter.
   const Type* jt = t->join_speculative(_type);
-  if( jt->empty() ) {           // Emptied out???
+  if (jt->empty()) {           // Emptied out???
 
     // Check for evil case of 't' being a class and '_type' expecting an
     // interface.  This can happen because the bytecodes do not contain
     // enough type info to distinguish a Java-level interface variable
     // from a Java-level object variable.  If we meet 2 classes which
     // both implement interface I, but their meet is at 'j/l/O' which
     // doesn't implement I, we have no way to tell if the result should
     // be 'I' or 'j/l/O'.  Thus we'll pick 'j/l/O'.  If this then flows
     // into a Phi which "knows" it's an Interface type we'll have to
     // uplift the type.
-    if( !t->empty() && ttip && ttip->is_loaded() && ttip->klass()->is_interface() )
-      { assert(ft == _type, ""); } // Uplift to interface
-    else if( !t->empty() && ttkp && ttkp->is_loaded() && ttkp->klass()->is_interface() )
-      { assert(ft == _type, ""); } // Uplift to interface
+    if (!t->empty() && ttip && ttip->is_loaded() && ttip->klass()->is_interface()) {
+      assert(ft == _type, ""); // Uplift to interface
+    } else if (!t->empty() && ttkp && ttkp->is_loaded() && ttkp->klass()->is_interface()) {
+      assert(ft == _type, ""); // Uplift to interface
+    } else {
+      // We also have to handle 'evil cases' of interface- vs. class-arrays
+      const TypePtr* ttp;
+      Type::get_arrays_base_elements(jt, _type, NULL, &ttp);
+      if (!t->empty() && ttp != NULL) {
+        const TypeInstPtr* ktip = ttp->isa_instptr();
+        if (ktip != NULL && ktip->is_loaded() && ktip->klass()->is_interface()) {
+          assert(ft == _type, ""); // Uplift to array of interface
+        } else {
     // Otherwise it's something stupid like non-overlapping int ranges
     // found on dying counted loops.
-    else
-      { assert(ft == Type::TOP, ""); } // Canonical empty value
+          assert(ft == Type::TOP, ""); // Canonical empty value
+        }
+      } else {
+        assert(ft == Type::TOP, ""); // Canonical empty value
+      }
+    }
   }
 
   else {
 
     // If we have an interface-typed Phi and we narrow to a class type, the join
< prev index next >