< prev index next >

src/share/vm/opto/matcher.cpp

Print this page

        

*** 166,175 **** --- 166,221 ---- } } } #endif + // Array of RegMask, one per returned values (value type instances can + // be returned as multiple return values, one per field) + RegMask* Matcher::return_values_mask(const TypeTuple *range) { + uint cnt = range->cnt() - TypeFunc::Parms; + if (cnt == 0) { + return NULL; + } + RegMask* mask = NEW_RESOURCE_ARRAY(RegMask, cnt); + + if (!ValueTypeReturnedAsFields) { + // Get ideal-register return type + uint ireg = range->field_at(TypeFunc::Parms)->ideal_reg(); + // Get machine return register + OptoRegPair regs = return_value(ireg, false); + + // And mask for same + mask[0].Clear(); + mask[0].Insert(regs.first()); + if (OptoReg::is_valid(regs.second())) { + mask[0].Insert(regs.second()); + } + } else { + BasicType *sig_bt = NEW_RESOURCE_ARRAY(BasicType, cnt); + VMRegPair *vm_parm_regs = NEW_RESOURCE_ARRAY(VMRegPair, cnt); + + for (uint i = 0; i < cnt; i++) { + sig_bt[i] = range->field_at(i+TypeFunc::Parms)->basic_type(); + } + + int regs = SharedRuntime::java_return_convention(sig_bt, vm_parm_regs, cnt); + assert(regs > 0, "should have been tested during graph construction"); + for (uint i = 0; i < cnt; i++) { + mask[i].Clear(); + + OptoReg::Name reg1 = OptoReg::as_OptoReg(vm_parm_regs[i].first()); + if (OptoReg::is_valid(reg1)) { + mask[i].Insert(reg1); + } + OptoReg::Name reg2 = OptoReg::as_OptoReg(vm_parm_regs[i].second()); + if (OptoReg::is_valid(reg2)) { + mask[i].Insert(reg2); + } + } + } + return mask; + } //---------------------------match--------------------------------------------- void Matcher::match( ) { if( MaxLabelRootDepth < 100 ) { // Too small? assert(false, "invalid MaxLabelRootDepth, increase it to 100 minimum");
*** 181,205 **** #ifdef _LP64 // Pointers take 2 slots in 64-bit land _return_addr_mask.Insert(OptoReg::add(return_addr(),1)); #endif ! // Map a Java-signature return type into return register-value ! // machine registers for 0, 1 and 2 returned values. ! const TypeTuple *range = C->tf()->range(); ! if( range->cnt() > TypeFunc::Parms ) { // If not a void function ! // Get ideal-register return type ! uint ireg = range->field_at(TypeFunc::Parms)->ideal_reg(); ! // Get machine return register ! uint sop = C->start()->Opcode(); ! OptoRegPair regs = return_value(ireg, false); ! ! // And mask for same ! _return_value_mask = RegMask(regs.first()); ! if( OptoReg::is_valid(regs.second()) ) ! _return_value_mask.Insert(regs.second()); ! } // --------------- // Frame Layout // Need the method signature to determine the incoming argument types, --- 227,240 ---- #ifdef _LP64 // Pointers take 2 slots in 64-bit land _return_addr_mask.Insert(OptoReg::add(return_addr(),1)); #endif ! // Map Java-signature return types into return register-value ! // machine registers. ! const TypeTuple *range = C->tf()->range_cc(); ! _return_values_mask = return_values_mask(range); // --------------- // Frame Layout // Need the method signature to determine the incoming argument types,
*** 649,664 **** soe_cnt++; // Input RegMask array shared by all Returns. // The type for doubles and longs has a count of 2, but // there is only 1 returned value ! uint ret_edge_cnt = TypeFunc::Parms + ((C->tf()->range()->cnt() == TypeFunc::Parms) ? 0 : 1); RegMask *ret_rms = init_input_masks( ret_edge_cnt + soe_cnt, _return_addr_mask, c_frame_ptr_mask ); ! // Returns have 0 or 1 returned values depending on call signature. ! // Return register is specified by return_value in the AD file. ! if (ret_edge_cnt > TypeFunc::Parms) ! ret_rms[TypeFunc::Parms+0] = _return_value_mask; // Input RegMask array shared by all Rethrows. uint reth_edge_cnt = TypeFunc::Parms+1; RegMask *reth_rms = init_input_masks( reth_edge_cnt + soe_cnt, _return_addr_mask, c_frame_ptr_mask ); // Rethrow takes exception oop only, but in the argument 0 slot. --- 684,698 ---- soe_cnt++; // Input RegMask array shared by all Returns. // The type for doubles and longs has a count of 2, but // there is only 1 returned value ! uint ret_edge_cnt = C->tf()->range_cc()->cnt(); RegMask *ret_rms = init_input_masks( ret_edge_cnt + soe_cnt, _return_addr_mask, c_frame_ptr_mask ); ! for (i = TypeFunc::Parms; i < ret_edge_cnt; i++) { ! ret_rms[i] = _return_values_mask[i-TypeFunc::Parms]; ! } // Input RegMask array shared by all Rethrows. uint reth_edge_cnt = TypeFunc::Parms+1; RegMask *reth_rms = init_input_masks( reth_edge_cnt + soe_cnt, _return_addr_mask, c_frame_ptr_mask ); // Rethrow takes exception oop only, but in the argument 0 slot.
*** 1000,1010 **** if (C->failing()) return NULL; if (m == NULL) { Matcher::soft_match_failure(); return NULL; } } else { // Nothing the matcher cares about if( n->is_Proj() && n->in(0)->is_Multi()) { // Projections? // Convert to machine-dependent projection ! m = n->in(0)->as_Multi()->match( n->as_Proj(), this ); #ifdef ASSERT _new2old_map.map(m->_idx, n); #endif if (m->in(0) != NULL) // m might be top collect_null_checks(m, n); --- 1034,1048 ---- if (C->failing()) return NULL; if (m == NULL) { Matcher::soft_match_failure(); return NULL; } } else { // Nothing the matcher cares about if( n->is_Proj() && n->in(0)->is_Multi()) { // Projections? // Convert to machine-dependent projection ! RegMask* mask = NULL; ! if (n->in(0)->is_Call()) { ! mask = return_values_mask(n->in(0)->as_Call()->tf()->range_cc()); ! } ! m = n->in(0)->as_Multi()->match(n->as_Proj(), this, mask); #ifdef ASSERT _new2old_map.map(m->_idx, n); #endif if (m->in(0) != NULL) // m might be top collect_null_checks(m, n);
*** 1300,1310 **** // Kill the outgoing argument area, including any non-argument holes and // any legacy C-killed slots. Use Fat-Projections to do the killing. // Since the max-per-method covers the max-per-call-site and debug info // is excluded on the max-per-method basis, debug info cannot land in // this killed area. ! uint r_cnt = mcall->tf()->range()->cnt(); MachProjNode *proj = new MachProjNode( mcall, r_cnt+10000, RegMask::Empty, MachProjNode::fat_proj ); if (!RegMask::can_represent_arg(OptoReg::Name(out_arg_limit_per_call-1))) { C->record_method_not_compilable("unsupported outgoing calling sequence"); } else { for (int i = begin_out_arg_area; i < out_arg_limit_per_call; i++) --- 1338,1348 ---- // Kill the outgoing argument area, including any non-argument holes and // any legacy C-killed slots. Use Fat-Projections to do the killing. // Since the max-per-method covers the max-per-call-site and debug info // is excluded on the max-per-method basis, debug info cannot land in // this killed area. ! uint r_cnt = mcall->tf()->range_sig()->cnt(); MachProjNode *proj = new MachProjNode( mcall, r_cnt+10000, RegMask::Empty, MachProjNode::fat_proj ); if (!RegMask::can_represent_arg(OptoReg::Name(out_arg_limit_per_call-1))) { C->record_method_not_compilable("unsupported outgoing calling sequence"); } else { for (int i = begin_out_arg_area; i < out_arg_limit_per_call; i++)
< prev index next >