< prev index next >

src/share/vm/opto/callGenerator.cpp

Print this page
rev 10513 : fix incremental inlining with value types

*** 370,384 **** if (call == NULL || call->outcnt() == 0 || call->in(0) == NULL || call->in(0)->is_top()) { return; } ! // FIXME: late inlining of methods that take value type arguments is ! // broken: arguments at the call are set up so fields of value type ! // arguments are passed but code here expects a single argument per ! // value type (a ValueTypeNode) instead. ! const TypeTuple *r = call->tf()->domain_sig(); for (int i1 = 0; i1 < method()->arg_size(); i1++) { if (call->in(TypeFunc::Parms + i1)->is_top() && r->field_at(TypeFunc::Parms + i1) != Type::HALF) { assert(Compile::current()->inlining_incrementally(), "shouldn't happen during parsing"); return; } --- 370,380 ---- if (call == NULL || call->outcnt() == 0 || call->in(0) == NULL || call->in(0)->is_top()) { return; } ! const TypeTuple *r = call->tf()->domain_cc(); for (int i1 = 0; i1 < method()->arg_size(); i1++) { if (call->in(TypeFunc::Parms + i1)->is_top() && r->field_at(TypeFunc::Parms + i1) != Type::HALF) { assert(Compile::current()->inlining_incrementally(), "shouldn't happen during parsing"); return; }
*** 402,431 **** SafePointNode* map = new SafePointNode(size, jvms); for (uint i1 = 0; i1 < size; i1++) { map->init_req(i1, call->in(i1)); } // Make sure the state is a MergeMem for parsing. if (!map->in(TypeFunc::Memory)->is_MergeMem()) { Node* mem = MergeMemNode::make(map->in(TypeFunc::Memory)); ! C->initial_gvn()->set_type_bottom(mem); map->set_req(TypeFunc::Memory, mem); } - uint nargs = method()->arg_size(); // blow away old call arguments Node* top = C->top(); ! for (uint i1 = 0; i1 < nargs; i1++) { ! map->set_req(TypeFunc::Parms + i1, top); } jvms->set_map(map); // Make enough space in the expression stack to transfer // the incoming arguments and return value. map->ensure_stack(jvms, jvms->method()->max_stack()); for (uint i1 = 0; i1 < nargs; i1++) { ! map->set_argument(jvms, i1, call->in(TypeFunc::Parms + i1)); } C->print_inlining_assert_ready(); C->print_inlining_move_to(this); --- 398,449 ---- SafePointNode* map = new SafePointNode(size, jvms); for (uint i1 = 0; i1 < size; i1++) { map->init_req(i1, call->in(i1)); } + PhaseGVN& gvn = *C->initial_gvn(); // Make sure the state is a MergeMem for parsing. if (!map->in(TypeFunc::Memory)->is_MergeMem()) { Node* mem = MergeMemNode::make(map->in(TypeFunc::Memory)); ! gvn.set_type_bottom(mem); map->set_req(TypeFunc::Memory, mem); } // blow away old call arguments Node* top = C->top(); ! for (uint i1 = TypeFunc::Parms; i1 < call->_tf->domain_cc()->cnt(); i1++) { ! map->set_req(i1, top); } jvms->set_map(map); // Make enough space in the expression stack to transfer // the incoming arguments and return value. map->ensure_stack(jvms, jvms->method()->max_stack()); + const TypeTuple *domain_sig = call->_tf->domain_sig(); + uint nargs = method()->arg_size(); + assert(domain_sig->cnt() - TypeFunc::Parms == nargs, "inconsistent signature"); + + uint j = TypeFunc::Parms; for (uint i1 = 0; i1 < nargs; i1++) { ! const Type* t = domain_sig->field_at(TypeFunc::Parms + i1); ! if (!ValueTypePassFieldsAsArgs) { ! Node* arg = call->in(TypeFunc::Parms + i1); ! if (t->isa_valuetypeptr()) { ! arg = ValueTypeNode::make(gvn, map->memory(), arg); ! } ! map->set_argument(jvms, i1, arg); ! } else { ! if (t->isa_valuetypeptr()) { ! ciValueKlass* vk = t->is_valuetypeptr()->value_type()->value_klass(); ! Node* vt = C->create_vt_node(call, vk, vk, 0, j); ! map->set_argument(jvms, i1, gvn.transform(vt)); ! j += vk->value_arg_slots(); ! } else { ! map->set_argument(jvms, i1, call->in(j)); ! j++; ! } ! } } C->print_inlining_assert_ready(); C->print_inlining_move_to(this);
*** 464,473 **** --- 482,495 ---- C->set_has_loops(C->has_loops() || _inline_cg->method()->has_loops()); C->env()->notice_inlined_method(_inline_cg->method()); C->set_inlining_progress(true); + if (result->is_ValueType()) { + result = result->as_ValueType()->store_to_memory(&kit); + } + kit.replace_call(call, result, true); } CallGenerator* CallGenerator::for_late_inline(ciMethod* method, CallGenerator* inline_cg) {
< prev index next >