< prev index next >

src/hotspot/share/opto/doCall.cpp

Print this page

        

*** 645,664 **** round_double_result(cg->method()); ciType* rtype = cg->method()->return_type(); ciType* ctype = declared_signature->return_type(); - Node* retnode = peek(); - if (rtype->basic_type() == T_VALUETYPE && !retnode->is_ValueType()) { - pop(); - assert(!cg->is_inline(), "should have ValueTypeNode result when inlining"); - ciValueKlass* vk = _gvn.type(retnode)->value_klass(); - // We will deoptimize if the return value is null and then need to continue execution after the call - ValueTypeNode* vt = ValueTypeNode::make_from_oop(this, retnode, vk, /* buffer_check */ false, /* null2default */ false, iter().next_bci()); - push_node(T_VALUETYPE, vt); - } - if (Bytecodes::has_optional_appendix(iter().cur_bc_raw()) || is_signature_polymorphic) { // Be careful here with return types. if (ctype != rtype) { BasicType rt = rtype->basic_type(); BasicType ct = ctype->basic_type(); --- 645,654 ----
*** 679,695 **** // A NULL ValueType cannot be returned to compiled code. The 'areturn' bytecode // handler will deoptimize its caller if it is about to return a NULL ValueType. // (See comments inside TypeTuple::make_range). sig_type = sig_type->join_speculative(TypePtr::NOTNULL); } ! if (arg_type != NULL && !arg_type->higher_equal(sig_type) && !retnode->is_ValueType()) { ! pop(); Node* cast_obj = _gvn.transform(new CheckCastPPNode(control(), retnode, sig_type)); - if (ct == T_VALUETYPE) { - // We will deoptimize if the return value is null and then need to continue execution after the call - cast_obj = ValueTypeNode::make_from_oop(this, cast_obj, ctype->as_value_klass(), /* buffer_check */ false, /* null2default */ false, iter().next_bci()); - } push(cast_obj); } } } else { assert(rt == ct, "unexpected mismatch: rt=%s, ct=%s", type2name(rt), type2name(ct)); --- 669,681 ---- // A NULL ValueType cannot be returned to compiled code. The 'areturn' bytecode // handler will deoptimize its caller if it is about to return a NULL ValueType. // (See comments inside TypeTuple::make_range). sig_type = sig_type->join_speculative(TypePtr::NOTNULL); } ! if (arg_type != NULL && !arg_type->higher_equal(sig_type) && !peek()->is_ValueType()) { ! Node* retnode = pop(); Node* cast_obj = _gvn.transform(new CheckCastPPNode(control(), retnode, sig_type)); push(cast_obj); } } } else { assert(rt == ct, "unexpected mismatch: rt=%s, ct=%s", type2name(rt), type2name(ct));
*** 709,718 **** --- 695,716 ---- // the accessing class). assert(!rtype->is_loaded() || !ctype->is_loaded() || rtype == ctype, "mismatched return types: rtype=%s, ctype=%s", rtype->name(), ctype->name()); } + if (rtype->basic_type() == T_VALUETYPE && !peek()->is_ValueType()) { + // Deoptimize if the return value is null and then continue execution after the call + Node* retnode = pop(); + assert(!gvn().type(retnode)->maybe_null() || !cg->method()->get_Method()->is_returning_vt(), "should never be null"); + if (rtype->as_value_klass()->is_scalarizable()) { + retnode = ValueTypeNode::make_from_oop(this, retnode, rtype->as_value_klass(), /* buffer_check */ false, /* null2default */ false, iter().next_bci()); + } else if (gvn().type(retnode)->maybe_null()) { + retnode = filter_null(retnode, false, NULL, iter().next_bci()); + } + push_node(T_VALUETYPE, retnode); + } + // If the return type of the method is not loaded, assert that the // value we got is a null. Otherwise, we need to recompile. if (!rtype->is_loaded()) { if (PrintOpto && (Verbose || WizardMode)) { method()->print_name(); tty->print_cr(" asserting nullness of result at bci: %d", bci());
< prev index next >