< prev index next >
src/hotspot/share/opto/callGenerator.cpp
Print this page
@@ -121,18 +121,18 @@
bool _separate_io_proj;
public:
DirectCallGenerator(ciMethod* method, bool separate_io_proj)
: CallGenerator(method),
+ _call_node(NULL),
_separate_io_proj(separate_io_proj)
{
- // TODO fix this with the calling convention changes
- if (false /*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
+ if (ValueTypeReturnedAsFields && method->is_method_handle_intrinsic()) {
+ // 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 (see PhaseMacroExpand::expand_mh_intrinsic_return).
+ // Separating memory and I/O projections for exceptions is required to
// perform that graph transformation.
_separate_io_proj = true;
}
}
virtual JVMState* generate(JVMState* jvms);
@@ -434,28 +434,31 @@
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);
- map->set_argument(jvms, i1, arg);
- } else {
- assert(false, "FIXME");
- // TODO move this into Parse::Parse because we might need to deopt
- /*
+ if (method()->get_Method()->has_scalarized_args()) {
GraphKit arg_kit(jvms, &gvn);
- if (t->is_valuetypeptr()) {
- ciValueKlass* vk = t->value_klass();
- ValueTypeNode* vt = ValueTypeNode::make_from_multi(&arg_kit, call, vk, j, true);
- arg_kit.set_argument(i1, vt);
- j += vk->value_arg_slots();
+ // TODO for now, don't scalarize value type receivers because of interface calls
+ if (t->is_valuetypeptr() && (method()->is_static() || i1 != 0)) {
+ arg_kit.set_control(map->control());
+ ValueTypeNode* vt = ValueTypeNode::make_from_multi(&arg_kit, call, t->value_klass(), j, true);
+ map->set_control(arg_kit.control());
+ map->set_argument(jvms, i1, vt);
} else {
- arg_kit.set_argument(i1, call->in(j));
+ int index = j;
+ SigEntry res_entry = method()->get_Method()->get_res_entry();
+ if (res_entry._offset != -1 && (index - TypeFunc::Parms) >= res_entry._offset) {
+ // Skip reserved entry
+ index += type2size[res_entry._bt];
+ }
+ map->set_argument(jvms, i1, call->in(index));
j++;
}
- */
+ } else {
+ Node* arg = call->in(TypeFunc::Parms + i1);
+ map->set_argument(jvms, i1, arg);
}
}
C->print_inlining_assert_ready();
@@ -500,24 +503,22 @@
// Handle value type returns
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 = ValueTypePtrNode::make_from_value_type(&kit, vt);
- } else {
- assert(false, "FIXME");
+ if (returned_as_fields) {
// 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 {
+ if (vt->is_allocated(&gvn) && !StressValueTypeReturnedAsFields) {
result = vt->get_oop();
+ } else {
+ result = vt->tagged_klass(gvn);
}
+ } else {
+ result = ValueTypePtrNode::make_from_value_type(&kit, vt);
}
} else if (gvn.type(result)->is_valuetypeptr() && returned_as_fields) {
- assert(false, "FIXME");
const Type* vt_t = call->_tf->range_sig()->field_at(TypeFunc::Parms);
Node* cast = new CheckCastPPNode(NULL, result, vt_t);
gvn.record_for_igvn(cast);
ValueTypePtrNode* vtptr = ValueTypePtrNode::make_from_oop(&kit, gvn.transform(cast));
vtptr->replace_call_results(&kit, call, C);
< prev index next >