< prev index next >

src/share/vm/opto/parse1.cpp

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

*** 989,1005 **** Node* ret_phi = _gvn.transform( _exits.argument(0) ); 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); } // Note: Logic for creating and optimizing the ReturnNode is in Compile. --- 989,1010 ---- Node* ret_phi = _gvn.transform( _exits.argument(0) ); 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. ! // 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); ! 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."); + } + } + return; } _exits.push_node(ret_type->basic_type(), ret_phi); } // Note: Logic for creating and optimizing the ReturnNode is in Compile.
*** 2145,2163 **** // If returning oops to an interface-return, there is a silent free // cast from oop to interface allowed by the Verifier. Make it explicit // here. Node* phi = _exits.argument(0); const TypeInstPtr *tr = phi->bottom_type()->isa_instptr(); ! 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)); } } phi->add_req(value); } --- 2150,2181 ---- // If returning oops to an interface-return, there is a silent free // cast from oop to interface allowed by the Verifier. Make it explicit // here. Node* phi = _exits.argument(0); const TypeInstPtr *tr = phi->bottom_type()->isa_instptr(); ! 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)); ! } ! } else { ! // Also handle returns of oop-arrays to an arrays-of-interface return ! const TypePtr* phi_tp; ! const TypePtr* val_tp; ! Type::get_arrays_base_elements(phi->bottom_type(), value->bottom_type(), &phi_tp, &val_tp); ! if (phi_tp != NULL && val_tp != NULL) { ! const TypeInstPtr *tr = phi_tp->isa_instptr(); ! const TypeInstPtr *tp = val_tp->isa_instptr(); ! if (tr != NULL && tr->is_loaded() && tr->klass()->is_interface() && ! tp != NULL && tp->is_loaded() && !tp->klass()->is_interface()) { ! value = _gvn.transform(new CheckCastPPNode(0, value, phi->bottom_type())); ! } } } phi->add_req(value); }
< prev index next >