< prev index next >

src/share/vm/opto/callGenerator.cpp

Print this page




 426 
 427   // Make enough space in the expression stack to transfer
 428   // the incoming arguments and return value.
 429   map->ensure_stack(jvms, jvms->method()->max_stack());
 430   const TypeTuple *domain_sig = call->_tf->domain_sig();
 431   uint nargs = method()->arg_size();
 432   assert(domain_sig->cnt() - TypeFunc::Parms == nargs, "inconsistent signature");
 433 
 434   uint j = TypeFunc::Parms;
 435   for (uint i1 = 0; i1 < nargs; i1++) {
 436     const Type* t = domain_sig->field_at(TypeFunc::Parms + i1);
 437     if (!ValueTypePassFieldsAsArgs) {
 438       Node* arg = call->in(TypeFunc::Parms + i1);
 439       if (t->isa_valuetypeptr()) {
 440         arg = ValueTypeNode::make(gvn, map->memory(), arg);
 441       }
 442       map->set_argument(jvms, i1, arg);
 443     } else {
 444       if (t->isa_valuetypeptr() && t->is_valuetypeptr()->klass() != C->env()->___Value_klass()) {
 445         ciValueKlass* vk = t->is_valuetypeptr()->value_type()->value_klass();
 446         Node* vt = C->create_vt_node(call, vk, vk, 0, j, true);
 447         map->set_argument(jvms, i1, gvn.transform(vt));
 448         j += vk->value_arg_slots();
 449       } else {
 450         map->set_argument(jvms, i1, call->in(j));
 451         j++;
 452       }
 453     }
 454   }
 455 
 456   C->print_inlining_assert_ready();
 457 
 458   C->print_inlining_move_to(this);
 459 
 460   C->log_late_inline(this);
 461 
 462   // This check is done here because for_method_handle_inline() method
 463   // needs jvms for inlined state.
 464   if (!do_late_inline_check(jvms)) {
 465     map->disconnect_inputs(NULL, C);
 466     return;


 477   // Now perform the inlining using the synthesized JVMState
 478   JVMState* new_jvms = _inline_cg->generate(jvms);
 479   if (new_jvms == NULL)  return;  // no change
 480   if (C->failing())      return;
 481 
 482   // Capture any exceptional control flow
 483   GraphKit kit(new_jvms);
 484 
 485   // Find the result object
 486   Node* result = C->top();
 487   ciType* return_type = _inline_cg->method()->return_type();
 488   int result_size = return_type->size();
 489   if (result_size != 0 && !kit.stopped()) {
 490     result = (result_size == 1) ? kit.pop() : kit.pop_pair();
 491   }
 492 
 493   C->set_has_loops(C->has_loops() || _inline_cg->method()->has_loops());
 494   C->env()->notice_inlined_method(_inline_cg->method());
 495   C->set_inlining_progress(true);
 496 
 497   if (return_type->is_valuetype() && return_type != C->env()->___Value_klass()) {
 498     if (result->is_ValueType()) {
 499       ValueTypeNode* vt = result->as_ValueType();
 500       if (!call->tf()->returns_value_type_as_fields()) {
 501         result = vt->allocate(&kit);
 502         result = C->initial_gvn()->transform(new ValueTypePtrNode(vt, result, C));
 503       } else {
 504         // Return of multiple values (the fields of a value type)
 505         vt->replace_call_results(call, C);
 506       }
 507     } else {







 508       assert(result->is_top(), "what else?");
 509       for (DUIterator_Fast imax, i = call->fast_outs(imax); i < imax; i++) {
 510         ProjNode *pn = call->fast_out(i)->as_Proj();
 511         uint con = pn->_con;
 512         if (con >= TypeFunc::Parms) {
 513           // C->gvn_replace_by(pn, C->top());
 514           C->initial_gvn()->hash_delete(pn);
 515           pn->set_req(0, C->top());
 516           --i; --imax;


 517         }
 518       }
 519     }
 520   }
 521 
 522   kit.replace_call(call, result, true);
 523 }
 524 
 525 
 526 CallGenerator* CallGenerator::for_late_inline(ciMethod* method, CallGenerator* inline_cg) {
 527   return new LateInlineCallGenerator(method, inline_cg);
 528 }
 529 
 530 class LateInlineMHCallGenerator : public LateInlineCallGenerator {
 531   ciMethod* _caller;
 532   int _attempt;
 533   bool _input_not_const;
 534 
 535   virtual bool do_late_inline_check(JVMState* jvms);
 536   virtual bool already_attempted() const { return _attempt > 0; }




 426 
 427   // Make enough space in the expression stack to transfer
 428   // the incoming arguments and return value.
 429   map->ensure_stack(jvms, jvms->method()->max_stack());
 430   const TypeTuple *domain_sig = call->_tf->domain_sig();
 431   uint nargs = method()->arg_size();
 432   assert(domain_sig->cnt() - TypeFunc::Parms == nargs, "inconsistent signature");
 433 
 434   uint j = TypeFunc::Parms;
 435   for (uint i1 = 0; i1 < nargs; i1++) {
 436     const Type* t = domain_sig->field_at(TypeFunc::Parms + i1);
 437     if (!ValueTypePassFieldsAsArgs) {
 438       Node* arg = call->in(TypeFunc::Parms + i1);
 439       if (t->isa_valuetypeptr()) {
 440         arg = ValueTypeNode::make(gvn, map->memory(), arg);
 441       }
 442       map->set_argument(jvms, i1, arg);
 443     } else {
 444       if (t->isa_valuetypeptr() && t->is_valuetypeptr()->klass() != C->env()->___Value_klass()) {
 445         ciValueKlass* vk = t->is_valuetypeptr()->value_type()->value_klass();
 446         Node* vt = ValueTypeNode::make(gvn, call, vk, j, true);
 447         map->set_argument(jvms, i1, gvn.transform(vt));
 448         j += vk->value_arg_slots();
 449       } else {
 450         map->set_argument(jvms, i1, call->in(j));
 451         j++;
 452       }
 453     }
 454   }
 455 
 456   C->print_inlining_assert_ready();
 457 
 458   C->print_inlining_move_to(this);
 459 
 460   C->log_late_inline(this);
 461 
 462   // This check is done here because for_method_handle_inline() method
 463   // needs jvms for inlined state.
 464   if (!do_late_inline_check(jvms)) {
 465     map->disconnect_inputs(NULL, C);
 466     return;


 477   // Now perform the inlining using the synthesized JVMState
 478   JVMState* new_jvms = _inline_cg->generate(jvms);
 479   if (new_jvms == NULL)  return;  // no change
 480   if (C->failing())      return;
 481 
 482   // Capture any exceptional control flow
 483   GraphKit kit(new_jvms);
 484 
 485   // Find the result object
 486   Node* result = C->top();
 487   ciType* return_type = _inline_cg->method()->return_type();
 488   int result_size = return_type->size();
 489   if (result_size != 0 && !kit.stopped()) {
 490     result = (result_size == 1) ? kit.pop() : kit.pop_pair();
 491   }
 492 
 493   C->set_has_loops(C->has_loops() || _inline_cg->method()->has_loops());
 494   C->env()->notice_inlined_method(_inline_cg->method());
 495   C->set_inlining_progress(true);
 496 
 497   if (return_type->is_valuetype()) {
 498     if (result->is_ValueType()) {
 499       ValueTypeNode* vt = result->as_ValueType();
 500       if (!call->tf()->returns_value_type_as_fields()) {
 501         result = vt->allocate(&kit);
 502         result = C->initial_gvn()->transform(new ValueTypePtrNode(vt, result, C));
 503       } else {
 504         // Return of multiple values (the fields of a value type)
 505         vt->replace_call_results(call, C);
 506       }
 507     } else {
 508       const Type* vt_t = call->_tf->range_sig()->field_at(TypeFunc::Parms);
 509       if (vt_t->is_valuetypeptr()->value_type()->value_klass() != C->env()->___Value_klass()) {
 510         if (gvn.type(result)->isa_valuetypeptr() && call->tf()->returns_value_type_as_fields()) {
 511           Node* cast = gvn.transform(new CheckCastPPNode(NULL, result, vt_t));
 512           ValueTypePtrNode* vtptr = ValueTypePtrNode::make(gvn, kit.merged_memory(), cast);
 513           vtptr->replace_call_results(call, C);
 514         } else {
 515           assert(result->is_top(), "what else?");
 516           for (DUIterator_Fast imax, i = call->fast_outs(imax); i < imax; i++) {
 517             ProjNode *pn = call->fast_out(i)->as_Proj();
 518             uint con = pn->_con;
 519             if (con >= TypeFunc::Parms) {

 520               C->initial_gvn()->hash_delete(pn);
 521               pn->set_req(0, C->top());
 522               --i; --imax;
 523             }
 524           }
 525         }
 526       }
 527     }
 528   }
 529 
 530   kit.replace_call(call, result, true);
 531 }
 532 
 533 
 534 CallGenerator* CallGenerator::for_late_inline(ciMethod* method, CallGenerator* inline_cg) {
 535   return new LateInlineCallGenerator(method, inline_cg);
 536 }
 537 
 538 class LateInlineMHCallGenerator : public LateInlineCallGenerator {
 539   ciMethod* _caller;
 540   int _attempt;
 541   bool _input_not_const;
 542 
 543   virtual bool do_late_inline_check(JVMState* jvms);
 544   virtual bool already_attempted() const { return _attempt > 0; }


< prev index next >