8055530: assert(_exits.control()->is_top() || !_gvn.type(ret_phi)->empty()) failed: return value must be well defined
authorroland
Mon, 22 Dec 2014 11:21:20 +0100
changeset 28395 fbe08d791778
parent 28394 6d382dc493e5
child 28396 7fe4347e6792
8055530: assert(_exits.control()->is_top() || !_gvn.type(ret_phi)->empty()) failed: return value must be well defined Summary: concurrent class loading causes return phi to become top Reviewed-by: kvn
hotspot/src/share/vm/opto/c2compiler.cpp
hotspot/src/share/vm/opto/c2compiler.hpp
hotspot/src/share/vm/opto/compile.cpp
hotspot/src/share/vm/opto/parse1.cpp
--- a/hotspot/src/share/vm/opto/c2compiler.cpp	Tue Dec 30 11:09:42 2014 +0300
+++ b/hotspot/src/share/vm/opto/c2compiler.cpp	Mon Dec 22 11:21:20 2014 +0100
@@ -39,6 +39,9 @@
 const char* C2Compiler::retry_no_escape_analysis() {
   return "retry without escape analysis";
 }
+const char* C2Compiler::retry_class_loading_during_parsing() {
+  return "retry class loading during parsing";
+}
 bool C2Compiler::init_c2_runtime() {
 
   // Check assumptions used while running ADLC
@@ -104,6 +107,10 @@
 
     // Check result and retry if appropriate.
     if (C.failure_reason() != NULL) {
+      if (C.failure_reason_is(retry_class_loading_during_parsing())) {
+        env->report_failure(C.failure_reason());
+        continue;  // retry
+      }
       if (C.failure_reason_is(retry_no_subsuming_loads())) {
         assert(subsume_loads, "must make progress");
         subsume_loads = false;
--- a/hotspot/src/share/vm/opto/c2compiler.hpp	Tue Dec 30 11:09:42 2014 +0300
+++ b/hotspot/src/share/vm/opto/c2compiler.hpp	Mon Dec 22 11:21:20 2014 +0100
@@ -47,6 +47,7 @@
   // sentinel value used to trigger backtracking in compile_method().
   static const char* retry_no_subsuming_loads();
   static const char* retry_no_escape_analysis();
+  static const char* retry_class_loading_during_parsing();
 
   // Print compilation timers and statistics
   void print_timers();
--- a/hotspot/src/share/vm/opto/compile.cpp	Tue Dec 30 11:09:42 2014 +0300
+++ b/hotspot/src/share/vm/opto/compile.cpp	Mon Dec 22 11:21:20 2014 +0100
@@ -774,7 +774,9 @@
     }
     JVMState* jvms = build_start_state(start(), tf());
     if ((jvms = cg->generate(jvms)) == NULL) {
-      record_method_not_compilable("method parse failed");
+      if (!failure_reason_is(C2Compiler::retry_class_loading_during_parsing())) {
+        record_method_not_compilable("method parse failed");
+      }
       return;
     }
     GraphKit kit(jvms);
--- a/hotspot/src/share/vm/opto/parse1.cpp	Tue Dec 30 11:09:42 2014 +0300
+++ b/hotspot/src/share/vm/opto/parse1.cpp	Mon Dec 22 11:21:20 2014 +0100
@@ -27,6 +27,7 @@
 #include "interpreter/linkResolver.hpp"
 #include "oops/method.hpp"
 #include "opto/addnode.hpp"
+#include "opto/c2compiler.hpp"
 #include "opto/castnode.hpp"
 #include "opto/idealGraphPrinter.hpp"
 #include "opto/locknode.hpp"
@@ -986,7 +987,18 @@
   if (tf()->range()->cnt() > TypeFunc::Parms) {
     const Type* ret_type = tf()->range()->field_at(TypeFunc::Parms);
     Node*       ret_phi  = _gvn.transform( _exits.argument(0) );
-    assert(_exits.control()->is_top() || !_gvn.type(ret_phi)->empty(), "return value must be well defined");
+    if (!_exits.control()->is_top() && _gvn.type(ret_phi)->empty()) {
+      // In case of concurrent class loading, the type we set for the
+      // ret_phi in build_exits() may have been too optimistic and the
+      // ret_phi may be top now.
+#ifdef ASSERT
+      {
+        MutexLockerEx ml(Compile_lock, Mutex::_no_safepoint_check_flag);
+        assert(ret_type->isa_ptr() && C->env()->system_dictionary_modification_counter_changed(), "return value must be well defined");
+      }
+#endif
+      C->record_failure(C2Compiler::retry_class_loading_during_parsing());
+    }
     _exits.push_node(ret_type->basic_type(), ret_phi);
   }