--- a/hotspot/src/share/vm/opto/parse1.cpp Mon Oct 05 23:50:43 2015 +0200
+++ b/hotspot/src/share/vm/opto/parse1.cpp Mon Nov 16 14:19:10 2015 +0100
@@ -988,13 +988,18 @@
// 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
+ // Otherwise, we've encountered an error and have to mark the method as
+ // not compilable. Just using an assertion instead would be dangerous
+ // as this could lead to an infinite compile loop in non-debug builds.
{
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");
+ if (C->env()->system_dictionary_modification_counter_changed()) {
+ C->record_failure(C2Compiler::retry_class_loading_during_parsing());
+ } else {
+ C->record_method_not_compilable("Can't determine return type.");
+ }
}
-#endif
- C->record_failure(C2Compiler::retry_class_loading_during_parsing());
+ return;
}
_exits.push_node(ret_type->basic_type(), ret_phi);
}
@@ -2144,15 +2149,24 @@
// here.
Node* phi = _exits.argument(0);
const TypeInstPtr *tr = phi->bottom_type()->isa_instptr();
- if( tr && tr->klass()->is_loaded() &&
- tr->klass()->is_interface() ) {
+ if (tr && tr->klass()->is_loaded() &&
+ tr->klass()->is_interface()) {
const TypeInstPtr *tp = value->bottom_type()->isa_instptr();
if (tp && tp->klass()->is_loaded() &&
!tp->klass()->is_interface()) {
// sharpen the type eagerly; this eases certain assert checking
if (tp->higher_equal(TypeInstPtr::NOTNULL))
tr = tr->join_speculative(TypeInstPtr::NOTNULL)->is_instptr();
- value = _gvn.transform(new CheckCastPPNode(0,value,tr));
+ value = _gvn.transform(new CheckCastPPNode(0, value, tr));
+ }
+ } else {
+ // Also handle returns of oop-arrays to an arrays-of-interface return
+ const TypeInstPtr* phi_tip;
+ const TypeInstPtr* val_tip;
+ Type::get_arrays_base_elements(phi->bottom_type(), value->bottom_type(), &phi_tip, &val_tip);
+ if (phi_tip != NULL && phi_tip->is_loaded() && phi_tip->klass()->is_interface() &&
+ val_tip != NULL && val_tip->is_loaded() && !val_tip->klass()->is_interface()) {
+ value = _gvn.transform(new CheckCastPPNode(0, value, phi->bottom_type()));
}
}
phi->add_req(value);