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