mirror of
https://github.com/openjdk/jdk.git
synced 2025-09-22 12:04:39 +02:00
8141551: C2 can not handle returns with inccompatible interface arrays
Reviewed-by: kvn
This commit is contained in:
parent
f6cb49ba48
commit
350b04eab2
5 changed files with 438 additions and 19 deletions
|
@ -988,13 +988,18 @@ void Parse::do_exits() {
|
|||
// 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 @@ void Parse::return_current(Node* value) {
|
|||
// 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);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue