--- old/src/share/vm/opto/callnode.cpp 2017-06-01 17:27:43.614205500 +0200 +++ new/src/share/vm/opto/callnode.cpp 2017-06-01 17:27:43.537205600 +0200 @@ -40,6 +40,7 @@ #include "opto/rootnode.hpp" #include "opto/runtime.hpp" #include "opto/valuetypenode.hpp" +#include "runtime/sharedRuntime.hpp" // Portions of code courtesy of Clifford Click @@ -73,7 +74,7 @@ //------------------------------match------------------------------------------ // Construct projections for incoming parameters, and their RegMask info -Node *StartNode::match( const ProjNode *proj, const Matcher *match ) { +Node *StartNode::match(const ProjNode *proj, const Matcher *match, const RegMask* mask) { switch (proj->_con) { case TypeFunc::Control: case TypeFunc::I_O: @@ -687,14 +688,21 @@ } #endif -const Type *CallNode::bottom_type() const { return tf()->range(); } +const Type *CallNode::bottom_type() const { return tf()->range_cc(); } const Type* CallNode::Value(PhaseGVN* phase) const { if (phase->type(in(0)) == Type::TOP) return Type::TOP; - return tf()->range(); + return tf()->range_cc(); } //------------------------------calling_convention----------------------------- -void CallNode::calling_convention( BasicType* sig_bt, VMRegPair *parm_regs, uint argcnt ) const { +void CallNode::calling_convention(BasicType* sig_bt, VMRegPair *parm_regs, uint argcnt) const { + if (_entry_point == StubRoutines::store_value_type_fields_to_buf()) { + // The call to that stub is a special case: its inputs are + // multiple values returned from a call and so it should follow + // the return convention. + SharedRuntime::java_return_convention(sig_bt, parm_regs, argcnt); + return; + } // Use the standard compiler calling convention Matcher::calling_convention( sig_bt, parm_regs, argcnt, true ); } @@ -703,29 +711,39 @@ //------------------------------match------------------------------------------ // Construct projections for control, I/O, memory-fields, ..., and // return result(s) along with their RegMask info -Node *CallNode::match( const ProjNode *proj, const Matcher *match ) { - switch (proj->_con) { +Node *CallNode::match(const ProjNode *proj, const Matcher *match, const RegMask* mask) { + uint con = proj->_con; + const TypeTuple *range_cc = tf()->range_cc(); + if (con >= TypeFunc::Parms) { + if (is_CallRuntime()) { + if (con == TypeFunc::Parms) { + uint ideal_reg = range_cc->field_at(TypeFunc::Parms)->ideal_reg(); + OptoRegPair regs = match->c_return_value(ideal_reg,true); + RegMask rm = RegMask(regs.first()); + if (OptoReg::is_valid(regs.second())) { + rm.Insert(regs.second()); + } + return new MachProjNode(this,con,rm,ideal_reg); + } else { + assert(con == TypeFunc::Parms+1, "only one return value"); + assert(range_cc->field_at(TypeFunc::Parms+1) == Type::HALF, ""); + return new MachProjNode(this,con, RegMask::Empty, (uint)OptoReg::Bad); + } + } else { + // The Call may return multiple values (value type fields): we + // create one projection per returned values. + assert(con <= TypeFunc::Parms+1 || ValueTypeReturnedAsFields, "only for multi value return"); + uint ideal_reg = range_cc->field_at(con)->ideal_reg(); + return new MachProjNode(this, con, mask[con-TypeFunc::Parms], ideal_reg); + } + } + + switch (con) { case TypeFunc::Control: case TypeFunc::I_O: case TypeFunc::Memory: return new MachProjNode(this,proj->_con,RegMask::Empty,MachProjNode::unmatched_proj); - case TypeFunc::Parms+1: // For LONG & DOUBLE returns - assert(tf()->range()->field_at(TypeFunc::Parms+1) == Type::HALF, ""); - // 2nd half of doubles and longs - return new MachProjNode(this,proj->_con, RegMask::Empty, (uint)OptoReg::Bad); - - case TypeFunc::Parms: { // Normal returns - uint ideal_reg = tf()->range()->field_at(TypeFunc::Parms)->ideal_reg(); - OptoRegPair regs = is_CallRuntime() - ? match->c_return_value(ideal_reg,true) // Calls into C runtime - : match-> return_value(ideal_reg,true); // Calls into compiled Java code - RegMask rm = RegMask(regs.first()); - if( OptoReg::is_valid(regs.second()) ) - rm.Insert( regs.second() ); - return new MachProjNode(this,proj->_con,rm,ideal_reg); - } - case TypeFunc::ReturnAdr: case TypeFunc::FramePtr: default: