Fri, 15 Apr 2016 12:02:37 +0530
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
1.1 --- a/src/share/vm/opto/c2compiler.cpp Thu Apr 21 13:17:25 2016 +0200 1.2 +++ b/src/share/vm/opto/c2compiler.cpp Fri Apr 15 12:02:37 2016 +0530 1.3 @@ -49,6 +49,9 @@ 1.4 const char* C2Compiler::retry_no_escape_analysis() { 1.5 return "retry without escape analysis"; 1.6 } 1.7 +const char* C2Compiler::retry_class_loading_during_parsing() { 1.8 + return "retry class loading during parsing"; 1.9 +} 1.10 bool C2Compiler::init_c2_runtime() { 1.11 1.12 // Check assumptions used while running ADLC 1.13 @@ -115,6 +118,10 @@ 1.14 1.15 // Check result and retry if appropriate. 1.16 if (C.failure_reason() != NULL) { 1.17 + if (C.failure_reason_is(retry_class_loading_during_parsing())) { 1.18 + env->record_failure(C.failure_reason()); 1.19 + continue; // retry 1.20 + } 1.21 if (C.failure_reason_is(retry_no_subsuming_loads())) { 1.22 assert(subsume_loads, "must make progress"); 1.23 subsume_loads = false;
2.1 --- a/src/share/vm/opto/c2compiler.hpp Thu Apr 21 13:17:25 2016 +0200 2.2 +++ b/src/share/vm/opto/c2compiler.hpp Fri Apr 15 12:02:37 2016 +0530 2.3 @@ -49,6 +49,7 @@ 2.4 // sentinel value used to trigger backtracking in compile_method(). 2.5 static const char* retry_no_subsuming_loads(); 2.6 static const char* retry_no_escape_analysis(); 2.7 + static const char* retry_class_loading_during_parsing(); 2.8 2.9 // Print compilation timers and statistics 2.10 void print_timers();
3.1 --- a/src/share/vm/opto/compile.cpp Thu Apr 21 13:17:25 2016 +0200 3.2 +++ b/src/share/vm/opto/compile.cpp Fri Apr 15 12:02:37 2016 +0530 3.3 @@ -791,7 +791,9 @@ 3.4 } 3.5 JVMState* jvms = build_start_state(start(), tf()); 3.6 if ((jvms = cg->generate(jvms)) == NULL) { 3.7 - record_method_not_compilable("method parse failed"); 3.8 + if (!failure_reason_is(C2Compiler::retry_class_loading_during_parsing())) { 3.9 + record_method_not_compilable("method parse failed"); 3.10 + } 3.11 return; 3.12 } 3.13 GraphKit kit(jvms);
4.1 --- a/src/share/vm/opto/parse1.cpp Thu Apr 21 13:17:25 2016 +0200 4.2 +++ b/src/share/vm/opto/parse1.cpp Fri Apr 15 12:02:37 2016 +0530 4.3 @@ -27,6 +27,7 @@ 4.4 #include "interpreter/linkResolver.hpp" 4.5 #include "oops/method.hpp" 4.6 #include "opto/addnode.hpp" 4.7 +#include "opto/c2compiler.hpp" 4.8 #include "opto/idealGraphPrinter.hpp" 4.9 #include "opto/locknode.hpp" 4.10 #include "opto/memnode.hpp" 4.11 @@ -957,7 +958,18 @@ 4.12 if (tf()->range()->cnt() > TypeFunc::Parms) { 4.13 const Type* ret_type = tf()->range()->field_at(TypeFunc::Parms); 4.14 Node* ret_phi = _gvn.transform( _exits.argument(0) ); 4.15 - assert(_exits.control()->is_top() || !_gvn.type(ret_phi)->empty(), "return value must be well defined"); 4.16 + if (!_exits.control()->is_top() && _gvn.type(ret_phi)->empty()) { 4.17 + // In case of concurrent class loading, the type we set for the 4.18 + // ret_phi in build_exits() may have been too optimistic and the 4.19 + // ret_phi may be top now. 4.20 +#ifdef ASSERT 4.21 + { 4.22 + MutexLockerEx ml(Compile_lock, Mutex::_no_safepoint_check_flag); 4.23 + assert(ret_type->isa_ptr() && C->env()->system_dictionary_modification_counter_changed(), "return value must be well defined"); 4.24 + } 4.25 +#endif 4.26 + C->record_failure(C2Compiler::retry_class_loading_during_parsing()); 4.27 + } 4.28 _exits.push_node(ret_type->basic_type(), ret_phi); 4.29 } 4.30