--- old/src/share/vm/opto/escape.cpp 2017-06-01 17:27:44.539204295 +0200 +++ new/src/share/vm/opto/escape.cpp 2017-06-01 17:27:44.462204395 +0200 @@ -370,6 +370,17 @@ (n->is_CallStaticJava() && n->as_CallStaticJava()->is_boxing_method())) { add_call_node(n->as_Call()); + } else if (n->as_Call()->tf()->returns_value_type_as_fields()) { + bool returns_oop = false; + for (DUIterator_Fast imax, i = n->fast_outs(imax); i < imax && !returns_oop; i++) { + ProjNode* pn = n->fast_out(i)->as_Proj(); + if (pn->_con >= TypeFunc::Parms && pn->bottom_type()->isa_oopptr()) { + returns_oop = true; + } + } + if (returns_oop) { + add_call_node(n->as_Call()); + } } } return; @@ -474,8 +485,10 @@ } case Op_Proj: { // we are only interested in the oop result projection from a call - if (n->as_Proj()->_con == TypeFunc::Parms && n->in(0)->is_Call() && - n->in(0)->as_Call()->returns_pointer()) { + if (n->as_Proj()->_con >= TypeFunc::Parms && n->in(0)->is_Call() && + (n->in(0)->as_Call()->returns_pointer() || n->bottom_type()->isa_oopptr())) { + assert((n->as_Proj()->_con == TypeFunc::Parms && n->in(0)->as_Call()->returns_pointer()) || + n->in(0)->as_Call()->tf()->returns_value_type_as_fields(), "what kind of oop return is it?"); add_local_var_and_edge(n, PointsToNode::NoEscape, n->in(0), delayed_worklist); } @@ -681,8 +694,10 @@ } case Op_Proj: { // we are only interested in the oop result projection from a call - if (n->as_Proj()->_con == TypeFunc::Parms && n->in(0)->is_Call() && - n->in(0)->as_Call()->returns_pointer()) { + if (n->as_Proj()->_con >= TypeFunc::Parms && n->in(0)->is_Call() && + (n->in(0)->as_Call()->returns_pointer()|| n->bottom_type()->isa_oopptr())) { + assert((n->as_Proj()->_con == TypeFunc::Parms && n->in(0)->as_Call()->returns_pointer()) || + n->in(0)->as_Call()->tf()->returns_value_type_as_fields(), "what kind of oop return is it?"); add_local_var_and_edge(n, PointsToNode::NoEscape, n->in(0), NULL); break; } @@ -797,7 +812,7 @@ } void ConnectionGraph::add_call_node(CallNode* call) { - assert(call->returns_pointer(), "only for call which returns pointer"); + assert(call->returns_pointer() || call->tf()->returns_value_type_as_fields(), "only for call which returns pointer"); uint call_idx = call->_idx; if (call->is_Allocate()) { Node* k = call->in(AllocateNode::KlassNode);