< prev index next >
src/share/vm/opto/callGenerator.cpp
Print this page
*** 124,134 ****
DirectCallGenerator(ciMethod* method, bool separate_io_proj)
: CallGenerator(method),
_separate_io_proj(separate_io_proj)
{
if (method->is_method_handle_intrinsic() &&
! method->signature()->return_type() == ciEnv::current()->___Value_klass()) {
// If that call has not been optimized by the time optimizations
// are over, we'll need to add a call to create a value type
// instance from the klass returned by the call. Separating
// memory and I/O projections for exceptions is required to
// perform that graph transformation.
--- 124,134 ----
DirectCallGenerator(ciMethod* method, bool separate_io_proj)
: CallGenerator(method),
_separate_io_proj(separate_io_proj)
{
if (method->is_method_handle_intrinsic() &&
! method->signature()->return_type()->is__Value()) {
// If that call has not been optimized by the time optimizations
// are over, we'll need to add a call to create a value type
// instance from the klass returned by the call. Separating
// memory and I/O projections for exceptions is required to
// perform that graph transformation.
*** 182,194 ****
kit.set_edges_for_java_call(call, false, _separate_io_proj);
Node* ret = kit.set_results_for_java_call(call, _separate_io_proj);
// Check if return value is a value type pointer
const TypeValueTypePtr* vtptr = gvn.type(ret)->isa_valuetypeptr();
if (vtptr != NULL) {
! if (vtptr->klass() != kit.C->env()->___Value_klass()) {
// Create ValueTypeNode from the oop and replace the return value
! Node* vt = ValueTypeNode::make(gvn, kit.merged_memory(), ret);
kit.push_node(T_VALUETYPE, vt);
} else {
kit.push_node(T_VALUETYPE, ret);
}
} else {
--- 182,194 ----
kit.set_edges_for_java_call(call, false, _separate_io_proj);
Node* ret = kit.set_results_for_java_call(call, _separate_io_proj);
// Check if return value is a value type pointer
const TypeValueTypePtr* vtptr = gvn.type(ret)->isa_valuetypeptr();
if (vtptr != NULL) {
! if (!vtptr->is__Value()) {
// Create ValueTypeNode from the oop and replace the return value
! Node* vt = ValueTypeNode::make(&kit, ret);
kit.push_node(T_VALUETYPE, vt);
} else {
kit.push_node(T_VALUETYPE, ret);
}
} else {
*** 277,287 ****
kit.set_edges_for_java_call(call);
Node* ret = kit.set_results_for_java_call(call);
// Check if return value is a value type pointer
if (gvn.type(ret)->isa_valuetypeptr()) {
// Create ValueTypeNode from the oop and replace the return value
! Node* vt = ValueTypeNode::make(gvn, kit.merged_memory(), ret);
kit.push_node(T_VALUETYPE, vt);
} else {
kit.push_node(method()->return_type()->basic_type(), ret);
}
--- 277,289 ----
kit.set_edges_for_java_call(call);
Node* ret = kit.set_results_for_java_call(call);
// Check if return value is a value type pointer
if (gvn.type(ret)->isa_valuetypeptr()) {
// Create ValueTypeNode from the oop and replace the return value
! Node* ctl = kit.control();
! Node* vt = ValueTypeNode::make(&kit, ret);
! kit.set_control(ctl);
kit.push_node(T_VALUETYPE, vt);
} else {
kit.push_node(method()->return_type()->basic_type(), ret);
}
*** 435,451 ****
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() && t->is_valuetypeptr()->klass() != C->env()->___Value_klass()) {
ciValueKlass* vk = t->is_valuetypeptr()->value_type()->value_klass();
! Node* vt = ValueTypeNode::make(gvn, call, vk, j, true);
map->set_argument(jvms, i1, gvn.transform(vt));
j += vk->value_arg_slots();
} else {
map->set_argument(jvms, i1, call->in(j));
j++;
--- 437,457 ----
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()) {
! Node* ctl = map->control();
! arg = ValueTypeNode::make(gvn, ctl, map->memory(), arg);
! map->set_control(ctl);
}
map->set_argument(jvms, i1, arg);
} else {
! if (t->isa_valuetypeptr() && !t->is_valuetypeptr()->is__Value()) {
ciValueKlass* vk = t->is_valuetypeptr()->value_type()->value_klass();
! Node* ctl = map->control();
! Node* vt = ValueTypeNode::make(gvn, ctl, map->memory(), call, vk, j, true);
! map->set_control(ctl);
map->set_argument(jvms, i1, gvn.transform(vt));
j += vk->value_arg_slots();
} else {
map->set_argument(jvms, i1, call->in(j));
j++;
*** 494,540 ****
C->env()->notice_inlined_method(_inline_cg->method());
C->set_inlining_progress(true);
if (return_type->is_valuetype()) {
const Type* vt_t = call->_tf->range_sig()->field_at(TypeFunc::Parms);
if (result->is_ValueType()) {
ValueTypeNode* vt = result->as_ValueType();
! if (!call->tf()->returns_value_type_as_fields()) {
! result = vt->allocate(&kit);
! result = C->initial_gvn()->transform(new ValueTypePtrNode(vt, result, C));
} else {
// Return of multiple values (the fields of a value type)
! vt->replace_call_results(call, C);
if (gvn.type(vt->get_oop()) == TypePtr::NULL_PTR) {
result = vt->tagged_klass(gvn);
} else {
result = vt->get_oop();
}
}
! } else {
! if (vt_t->is_valuetypeptr()->value_type()->value_klass() != C->env()->___Value_klass()) {
! if (gvn.type(result)->isa_valuetypeptr() && call->tf()->returns_value_type_as_fields()) {
Node* cast = new CheckCastPPNode(NULL, result, vt_t);
gvn.record_for_igvn(cast);
! ValueTypePtrNode* vtptr = ValueTypePtrNode::make(gvn, kit.merged_memory(), gvn.transform(cast));
! vtptr->replace_call_results(call, C);
result = cast;
! } else {
assert(result->is_top(), "what else?");
for (DUIterator_Fast imax, i = call->fast_outs(imax); i < imax; i++) {
ProjNode *pn = call->fast_out(i)->as_Proj();
uint con = pn->_con;
if (con >= TypeFunc::Parms) {
! C->initial_gvn()->hash_delete(pn);
pn->set_req(0, C->top());
--i; --imax;
}
}
}
}
- }
- }
kit.replace_call(call, result, true);
}
--- 500,546 ----
C->env()->notice_inlined_method(_inline_cg->method());
C->set_inlining_progress(true);
if (return_type->is_valuetype()) {
const Type* vt_t = call->_tf->range_sig()->field_at(TypeFunc::Parms);
+ bool returned_as_fields = call->tf()->returns_value_type_as_fields();
if (result->is_ValueType()) {
ValueTypeNode* vt = result->as_ValueType();
! if (!returned_as_fields) {
! result = vt->allocate(&kit)->get_oop();
! result = gvn.transform(new ValueTypePtrNode(vt, result, C));
} else {
// Return of multiple values (the fields of a value type)
! vt->replace_call_results(&kit, call, C);
if (gvn.type(vt->get_oop()) == TypePtr::NULL_PTR) {
result = vt->tagged_klass(gvn);
} else {
result = vt->get_oop();
}
}
! } else if (gvn.type(result)->isa_valuetypeptr() && returned_as_fields) {
! assert(!vt_t->is_valuetypeptr()->is__Value(), "__Value not supported");
Node* cast = new CheckCastPPNode(NULL, result, vt_t);
gvn.record_for_igvn(cast);
! Node* ctl = kit.control();
! ValueTypePtrNode* vtptr = ValueTypePtrNode::make(gvn, ctl, kit.merged_memory(), gvn.transform(cast));
! kit.set_control(ctl);
! vtptr->replace_call_results(&kit, call, C);
result = cast;
! } else if (!return_type->is__Value()) {
assert(result->is_top(), "what else?");
for (DUIterator_Fast imax, i = call->fast_outs(imax); i < imax; i++) {
ProjNode *pn = call->fast_out(i)->as_Proj();
uint con = pn->_con;
if (con >= TypeFunc::Parms) {
! gvn.hash_delete(pn);
pn->set_req(0, C->top());
--i; --imax;
}
}
}
}
kit.replace_call(call, result, true);
}
*** 908,924 ****
PhaseGVN& gvn = kit.gvn();
Node* arg = kit.argument(arg_nb);
const Type* arg_type = arg->bottom_type();
const Type* sig_type = TypeOopPtr::make_from_klass(t->as_klass());
if (t->is_valuetype()) {
! assert(!(arg_type->isa_valuetype() && t == kit.C->env()->___Value_klass()), "need a pointer to the value type");
! if (arg_type->isa_valuetypeptr() && t != kit.C->env()->___Value_klass()) {
Node* cast = gvn.transform(new CheckCastPPNode(kit.control(), arg, sig_type));
! Node* vt = ValueTypeNode::make(gvn, kit.merged_memory(), cast);
kit.set_argument(arg_nb, vt);
} else {
! assert(t == kit.C->env()->___Value_klass() || arg->is_ValueType(), "inconsistent argument");
}
} else {
if (arg_type->isa_oopptr() && !arg_type->higher_equal(sig_type)) {
Node* cast_obj = gvn.transform(new CheckCastPPNode(kit.control(), arg, sig_type));
kit.set_argument(arg_nb, cast_obj);
--- 914,930 ----
PhaseGVN& gvn = kit.gvn();
Node* arg = kit.argument(arg_nb);
const Type* arg_type = arg->bottom_type();
const Type* sig_type = TypeOopPtr::make_from_klass(t->as_klass());
if (t->is_valuetype()) {
! assert(!(arg_type->isa_valuetype() && t->is__Value()), "need a pointer to the value type");
! if (arg_type->isa_valuetypeptr() && !t->is__Value()) {
Node* cast = gvn.transform(new CheckCastPPNode(kit.control(), arg, sig_type));
! Node* vt = ValueTypeNode::make(&kit, cast);
kit.set_argument(arg_nb, vt);
} else {
! assert(t->is__Value() || arg->is_ValueType(), "inconsistent argument");
}
} else {
if (arg_type->isa_oopptr() && !arg_type->higher_equal(sig_type)) {
Node* cast_obj = gvn.transform(new CheckCastPPNode(kit.control(), arg, sig_type));
kit.set_argument(arg_nb, cast_obj);
< prev index next >