< prev index next >
src/hotspot/share/opto/parse1.cpp
Print this page
@@ -1116,17 +1116,12 @@
}
if (ret_type->isa_int()) {
BasicType ret_bt = method()->return_type()->basic_type();
ret_phi = mask_int_value(ret_phi, ret_bt, &_gvn);
}
- if (_caller->has_method() && ret_type->is_valuetypeptr()) {
- // Inlined methods return a ValueTypeNode
- _exits.push_node(T_VALUETYPE, ret_phi);
- } else {
_exits.push_node(ret_type->basic_type(), ret_phi);
}
- }
// Note: Logic for creating and optimizing the ReturnNode is in Compile.
// Unlock along the exceptional paths.
// This is done late so that we can common up equivalent exceptions
@@ -2327,24 +2322,27 @@
make_dtrace_method_exit(method());
}
// frame pointer is always same, already captured
if (value != NULL) {
Node* phi = _exits.argument(0);
- const TypeOopPtr* tr = phi->bottom_type()->isa_oopptr();
- if (tf()->returns_value_type_as_fields() && !_caller->has_method() && !value->is_ValueType()) {
- // TODO there should be a checkcast in between, right?
- value = ValueTypeNode::make_from_oop(this, value, phi->bottom_type()->is_valuetype()->value_klass());
- }
- if (value->is_ValueType() && !_caller->has_method()) {
- // Value type is returned as oop from root method
- if (tf()->returns_value_type_as_fields()) {
- // Make sure non-flattened value type fields are allocated
+ const Type* return_type = phi->bottom_type();
+ const TypeOopPtr* tr = return_type->isa_oopptr();
+ if (return_type->isa_valuetype()) {
+ // Value type is returned as fields, make sure it is scalarized
+ if (!value->is_ValueType()) {
+ value = ValueTypeNode::make_from_oop(this, value, return_type->is_valuetype()->value_klass());
+ }
+ if (!_caller->has_method()) {
+ // Value type is returned as fields from root method, make
+ // sure all non-flattened value type fields are allocated.
+ assert(tf()->returns_value_type_as_fields(), "must be returned as fields");
value = value->as_ValueType()->allocate_fields(this);
- } else {
- // Make sure value type is allocated
- value = value->as_ValueType()->allocate(this)->get_oop();
}
+ } else if (value->is_ValueType()) {
+ // Value type is returned as oop, make sure it is allocated
+ assert(tr && tr->can_be_value_type(), "must return a value type pointer");
+ value = ValueTypePtrNode::make_from_value_type(this, value->as_ValueType());
} else if (tr && tr->isa_instptr() && tr->klass()->is_loaded() && tr->klass()->is_interface()) {
// If returning oops to an interface-return, there is a silent free
// cast from oop to interface allowed by the Verifier. Make it explicit here.
const TypeInstPtr* tp = value->bottom_type()->isa_instptr();
if (tp && tp->klass()->is_loaded() && !tp->klass()->is_interface()) {
@@ -2356,14 +2354,14 @@
}
} else {
// Handle returns of oop-arrays to an arrays-of-interface return
const TypeInstPtr* phi_tip;
const TypeInstPtr* val_tip;
- Type::get_arrays_base_elements(phi->bottom_type(), value->bottom_type(), &phi_tip, &val_tip);
+ Type::get_arrays_base_elements(return_type, value->bottom_type(), &phi_tip, &val_tip);
if (phi_tip != NULL && phi_tip->is_loaded() && phi_tip->klass()->is_interface() &&
val_tip != NULL && val_tip->is_loaded() && !val_tip->klass()->is_interface()) {
- value = _gvn.transform(new CheckCastPPNode(0, value, phi->bottom_type()));
+ value = _gvn.transform(new CheckCastPPNode(0, value, return_type));
}
}
phi->add_req(value);
}
< prev index next >