< prev index next >
src/hotspot/share/opto/graphKit.cpp
Print this page
*** 1392,1401 ****
--- 1392,1432 ----
}
return value;
}
+ Node* GraphKit::filter_null(Node* value, bool null2default, ciValueKlass* vk, int trap_bci) {
+ Node* null_ctl = top();
+ value = null_check_oop(value, &null_ctl);
+ if (!null_ctl->is_top()) {
+ if (null2default) {
+ // Return default value if oop is null
+ Node* region = new RegionNode(3);
+ region->init_req(1, control());
+ region->init_req(2, null_ctl);
+ value = PhiNode::make(region, value, TypeInstPtr::make(TypePtr::BotPTR, vk));
+ value->set_req(2, ValueTypeNode::default_oop(gvn(), vk));
+ set_control(gvn().transform(region));
+ value = gvn().transform(value);
+ } else {
+ // Deoptimize if oop is null
+ PreserveJVMState pjvms(this);
+ set_control(null_ctl);
+ int cur_bci = bci();
+ if (trap_bci != -1) {
+ // Put trap at different bytecode
+ push(null());
+ set_bci(trap_bci);
+ }
+ uncommon_trap(Deoptimization::Reason_null_check, Deoptimization::Action_none);
+ if (trap_bci != -1) {
+ set_bci(cur_bci);
+ }
+ }
+ }
+ return value;
+ }
//------------------------------cast_not_null----------------------------------
// Cast obj to not-null on this path
Node* GraphKit::cast_not_null(Node* obj, bool do_replace_in_map) {
assert(!obj->is_ValueType(), "should not cast value type");
*** 1788,1814 ****
continue;
} else {
// Pass value type argument via oop to callee
arg = vt->allocate(this)->get_oop();
}
! } else if (t->is_valuetypeptr()) {
! ciMethod* declared_method = method()->get_method_at_bci(bci());
! if (arg->is_ValueTypePtr()) {
! // We are calling an Object method with a value type receiver
! ValueTypePtrNode* vt = arg->isa_ValueTypePtr();
! assert(i == TypeFunc::Parms && !declared_method->is_static(), "argument must be receiver");
! assert(vt->is_allocated(&gvn()), "argument must be allocated");
! arg = vt->get_oop();
! } else {
// Constant null passed for a value type argument
assert(arg->bottom_type()->remove_speculative() == TypePtr::NULL_PTR, "Anything other than null?");
int arg_size = declared_method->signature()->arg_size_for_bc(java_bc());
inc_sp(arg_size); // restore arguments
uncommon_trap(Deoptimization::Reason_null_check, Deoptimization::Action_none);
return;
}
- }
call->init_req(idx, arg);
idx++;
}
}
--- 1819,1837 ----
continue;
} else {
// Pass value type argument via oop to callee
arg = vt->allocate(this)->get_oop();
}
! } else if (t->is_valuetypeptr() && !arg->is_ValueTypePtr() && gvn().type(arg)->maybe_null()) {
// Constant null passed for a value type argument
assert(arg->bottom_type()->remove_speculative() == TypePtr::NULL_PTR, "Anything other than null?");
+ ciMethod* declared_method = method()->get_method_at_bci(bci());
int arg_size = declared_method->signature()->arg_size_for_bc(java_bc());
inc_sp(arg_size); // restore arguments
uncommon_trap(Deoptimization::Reason_null_check, Deoptimization::Action_none);
return;
}
call->init_req(idx, arg);
idx++;
}
}
*** 2861,2873 ****
// Subsume downstream occurrences of receiver with a cast to
// recv_xtype, since now we know what the type will be.
Node* cast = new CheckCastPPNode(control(), receiver, recv_xtype);
Node* res = _gvn.transform(cast);
if (recv_xtype->is_valuetypeptr()) {
! assert(!gvn().type(res)->is_ptr()->maybe_null(), "should never be null");
res = ValueTypeNode::make_from_oop(this, res, recv_xtype->value_klass());
}
(*casted_receiver) = res;
// (User must make the replace_in_map call.)
return fail;
--- 2884,2898 ----
// Subsume downstream occurrences of receiver with a cast to
// recv_xtype, since now we know what the type will be.
Node* cast = new CheckCastPPNode(control(), receiver, recv_xtype);
Node* res = _gvn.transform(cast);
if (recv_xtype->is_valuetypeptr()) {
! assert(!gvn().type(res)->maybe_null(), "should never be null");
! if (recv_xtype->value_klass()->is_scalarizable()) {
res = ValueTypeNode::make_from_oop(this, res, recv_xtype->value_klass());
}
+ }
(*casted_receiver) = res;
// (User must make the replace_in_map call.)
return fail;
*** 3166,3183 ****
// the profiling data at this bytecode. Don't lose it, feed it
// to the type system as a speculative type.
if (!is_value) {
obj = record_profiled_receiver_for_speculation(obj);
if (toop->is_valuetypeptr()) {
obj = ValueTypeNode::make_from_oop(this, obj, toop->value_klass(), /* buffer_check */ false, /* null2default */ false);
}
}
return obj;
case Compile::SSC_always_false:
// It needs a null check because a null will *pass* the cast check.
! // A non-null value will always produce an exception.
! if (is_value) {
builtin_throw(Deoptimization::Reason_class_check, makecon(TypeKlassPtr::make(klass)));
return top();
} else {
return null_assert(obj);
}
--- 3191,3212 ----
// the profiling data at this bytecode. Don't lose it, feed it
// to the type system as a speculative type.
if (!is_value) {
obj = record_profiled_receiver_for_speculation(obj);
if (toop->is_valuetypeptr()) {
+ if (toop->value_klass()->is_scalarizable()) {
obj = ValueTypeNode::make_from_oop(this, obj, toop->value_klass(), /* buffer_check */ false, /* null2default */ false);
+ } else {
+ obj = filter_null(obj);
+ }
}
}
return obj;
case Compile::SSC_always_false:
// It needs a null check because a null will *pass* the cast check.
! if (is_value || toop->is_valuetypeptr()) {
! // Value types are never null - always throw an exception
builtin_throw(Deoptimization::Reason_class_check, makecon(TypeKlassPtr::make(klass)));
return top();
} else {
return null_assert(obj);
}
*** 3206,3216 ****
bool never_see_null = ((failure_control == NULL) // regular case only
&& seems_never_null(obj, data, speculative_not_null));
// Null check; get casted pointer; set region slot 3
Node* null_ctl = top();
! Node* not_null_obj = is_value ? obj : null_check_oop(obj, &null_ctl, never_see_null, safe_for_replace, speculative_not_null);
// If not_null_obj is dead, only null-path is taken
if (stopped()) { // Doing instance-of on a NULL?
set_control(null_ctl);
return null();
--- 3235,3252 ----
bool never_see_null = ((failure_control == NULL) // regular case only
&& seems_never_null(obj, data, speculative_not_null));
// Null check; get casted pointer; set region slot 3
Node* null_ctl = top();
! Node* not_null_obj = NULL;
! if (is_value) {
! not_null_obj = obj;
! } else if (toop->is_valuetypeptr()) {
! not_null_obj = filter_null(obj);
! } else {
! not_null_obj = null_check_oop(obj, &null_ctl, never_see_null, safe_for_replace, speculative_not_null);
! }
// If not_null_obj is dead, only null-path is taken
if (stopped()) { // Doing instance-of on a NULL?
set_control(null_ctl);
return null();
*** 3263,3278 ****
}
// Generate the subtype check
Node* not_subtype_ctrl = gen_subtype_check( obj_klass, superklass );
- if (is_value) {
- not_null_obj = ValueTypePtrNode::make_from_value_type(this, not_null_obj->as_ValueType(), true);
- }
-
// Plug in success path into the merge
! cast_obj = _gvn.transform(new CheckCastPPNode(control(), not_null_obj, toop));
// Failure path ends in uncommon trap (or may be dead - failure impossible)
if (failure_control == NULL) {
if (not_subtype_ctrl != top()) { // If failure is possible
PreserveJVMState pjvms(this);
set_control(not_subtype_ctrl);
--- 3299,3310 ----
}
// Generate the subtype check
Node* not_subtype_ctrl = gen_subtype_check( obj_klass, superklass );
// Plug in success path into the merge
! cast_obj = is_value ? not_null_obj : _gvn.transform(new CheckCastPPNode(control(), not_null_obj, toop));
// Failure path ends in uncommon trap (or may be dead - failure impossible)
if (failure_control == NULL) {
if (not_subtype_ctrl != top()) { // If failure is possible
PreserveJVMState pjvms(this);
set_control(not_subtype_ctrl);
*** 3304,3314 ****
record_for_igvn(region);
if (!is_value) {
res = record_profiled_receiver_for_speculation(res);
if (toop->is_valuetypeptr()) {
! res = ValueTypeNode::make_from_oop(this, res, toop->value_klass(), /* buffer_check */ false, /* null2default */ false);
}
}
return res;
}
--- 3336,3349 ----
record_for_igvn(region);
if (!is_value) {
res = record_profiled_receiver_for_speculation(res);
if (toop->is_valuetypeptr()) {
! assert(!gvn().type(res)->maybe_null(), "should never be null");
! if (toop->value_klass()->is_scalarizable()) {
! res = ValueTypeNode::make_from_oop(this, res, toop->value_klass());
! }
}
}
return res;
}
*** 4351,4362 ****
--- 4386,4400 ----
/*is_unsigned_load=*/false);
if (con_type != NULL) {
Node* con = makecon(con_type);
if (field->layout_type() == T_VALUETYPE) {
// Load value type from constant oop
+ assert(!con_type->maybe_null(), "should never be null");
+ if (field->type()->as_value_klass()->is_scalarizable()) {
con = ValueTypeNode::make_from_oop(this, con, field->type()->as_value_klass());
}
+ }
return con;
}
return NULL;
}
< prev index next >