< prev index next >
src/share/vm/opto/callnode.cpp
Print this page
@@ -71,11 +71,11 @@
return RegMask::Empty;
}
//------------------------------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:
case TypeFunc::Memory:
return new MachProjNode(this,proj->_con,RegMask::Empty,MachProjNode::unmatched_proj);
@@ -685,49 +685,65 @@
if (_cnt != COUNT_UNKNOWN) st->print(" C=%f",_cnt);
if (jvms() != NULL) jvms()->dump_spec(st);
}
#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 );
}
//------------------------------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.
+ 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:
ShouldNotReachHere();
}
< prev index next >