< prev index next >
src/hotspot/share/opto/graphKit.cpp
Print this page
@@ -1542,11 +1542,11 @@
} else {
ld = LoadNode::make(_gvn, ctl, mem, adr, adr_type, t, bt, mo, control_dependency, unaligned, mismatched);
}
ld = _gvn.transform(ld);
- if (((bt == T_OBJECT || bt == T_VALUETYPE || bt == T_VALUETYPEPTR) && C->do_escape_analysis()) || C->eliminate_boxing()) {
+ if (((bt == T_OBJECT || bt == T_VALUETYPE) && C->do_escape_analysis()) || C->eliminate_boxing()) {
// Improve graph before escape analysis and boxing elimination.
record_for_igvn(ld);
}
return ld;
}
@@ -1792,11 +1792,12 @@
Node* arg = argument(i-TypeFunc::Parms);
const Type* t = domain->field_at(i);
if (arg->is_ValueType()) {
assert(t->is_oopptr()->can_be_value_type(), "wrong argument type");
ValueTypeNode* vt = arg->as_ValueType();
- if (ValueTypePassFieldsAsArgs) {
+ // TODO for now, don't scalarize value type receivers because of interface calls
+ if (call->method()->get_Method()->has_scalarized_args() && t->is_valuetypeptr() && (call->method()->is_static() || i != TypeFunc::Parms)) {
// We don't pass value type arguments by reference but instead
// pass each field of the value type
idx += vt->pass_fields(call, idx, *this);
// If a value type argument is passed as fields, attach the Method* to the call site
// to be able to access the extended signature later via attached_method_before_pc().
@@ -1806,12 +1807,20 @@
} else {
// Pass value type argument via oop to callee
arg = vt->allocate(this)->get_oop();
}
}
- call->init_req(idx, arg);
- idx++;
+ call->init_req(idx++, arg);
+
+ SigEntry res_entry = call->method()->get_Method()->get_res_entry();
+ if ((int)(idx - TypeFunc::Parms) == res_entry._offset) {
+ // Skip reserved entry
+ call->init_req(idx++, top());
+ if (res_entry._bt == T_DOUBLE || res_entry._bt == T_LONG) {
+ call->init_req(idx++, top());
+ }
+ }
}
}
//---------------------------set_edges_for_java_call---------------------------
// Connect a newly created call into the current JVMS.
@@ -1863,22 +1872,19 @@
// Capture the return value, if any.
Node* ret;
if (call->method() == NULL ||
call->method()->return_type()->basic_type() == T_VOID) {
ret = top();
- } else {
- if (!call->tf()->returns_value_type_as_fields()) {
- ret = _gvn.transform(new ProjNode(call, TypeFunc::Parms));
- } else {
+ } else if (call->tf()->returns_value_type_as_fields()) {
// Return of multiple values (value type fields): we create a
// ValueType node, each field is a projection from the call.
const TypeTuple* range_sig = call->tf()->range_sig();
const Type* t = range_sig->field_at(TypeFunc::Parms);
- assert(t->is_valuetypeptr(), "only value types for multiple return values");
- ciValueKlass* vk = t->value_klass();
- ret = ValueTypeNode::make_from_multi(this, call, vk, TypeFunc::Parms+1, false);
- }
+ uint base_input = TypeFunc::Parms + 1;
+ ret = ValueTypeNode::make_from_multi(this, call, t->value_klass(), base_input, false);
+ } else {
+ ret = _gvn.transform(new ProjNode(call, TypeFunc::Parms));
}
return ret;
}
< prev index next >