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; }
|