< 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 >