< prev index next >

src/hotspot/share/opto/graphKit.cpp

Print this page

        

*** 1530,1540 **** } ld = _gvn.transform(ld); if (bt == T_VALUETYPE) { // Loading a non-flattened (but flattenable) value type from memory // We need to return the default value type if the field is null ! ld = ValueTypeNode::make_from_oop(this, ld, t->make_valuetypeptr()->value_klass(), true /* null check */); } else if (bt == T_VALUETYPEPTR) { // Loading non-flattenable value type from memory inc_sp(1); Node* null_ctl = top(); Node* not_null_obj = null_check_common(ld, T_VALUETYPE, false, &null_ctl, false); --- 1530,1540 ---- } ld = _gvn.transform(ld); if (bt == T_VALUETYPE) { // Loading a non-flattened (but flattenable) value type from memory // We need to return the default value type if the field is null ! ld = ValueTypeNode::make_from_oop(this, ld, t->make_oopptr()->value_klass(), true /* null check */); } else if (bt == T_VALUETYPEPTR) { // Loading non-flattenable value type from memory inc_sp(1); Node* null_ctl = top(); Node* not_null_obj = null_check_common(ld, T_VALUETYPE, false, &null_ctl, false);
*** 1544,1554 **** set_control(null_ctl); replace_in_map(ld, null()); uncommon_trap(Deoptimization::Reason_null_check, Deoptimization::Action_none); } dec_sp(1); ! ld = ValueTypeNode::make_from_oop(this, not_null_obj, t->make_valuetypeptr()->value_klass()); } else if (((bt == T_OBJECT) && C->do_escape_analysis()) || C->eliminate_boxing()) { // Improve graph before escape analysis and boxing elimination. record_for_igvn(ld); } return ld; --- 1544,1554 ---- set_control(null_ctl); replace_in_map(ld, null()); uncommon_trap(Deoptimization::Reason_null_check, Deoptimization::Action_none); } dec_sp(1); ! ld = ValueTypeNode::make_from_oop(this, not_null_obj, t->make_oopptr()->value_klass()); } else if (((bt == T_OBJECT) && C->do_escape_analysis()) || C->eliminate_boxing()) { // Improve graph before escape analysis and boxing elimination. record_for_igvn(ld); } return ld;
*** 1781,1791 **** for (uint i = TypeFunc::Parms, idx = TypeFunc::Parms; i < nargs; i++) { Node* arg = argument(i-TypeFunc::Parms); if (ValueTypePassFieldsAsArgs) { if (arg->is_ValueType()) { ValueTypeNode* vt = arg->as_ValueType(); ! if (!domain->field_at(i)->is_valuetypeptr()->is__Value()) { // 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(). --- 1781,1792 ---- for (uint i = TypeFunc::Parms, idx = TypeFunc::Parms; i < nargs; i++) { Node* arg = argument(i-TypeFunc::Parms); if (ValueTypePassFieldsAsArgs) { if (arg->is_ValueType()) { ValueTypeNode* vt = arg->as_ValueType(); ! // TODO fix this with the calling convention changes ! if (true /*!domain->field_at(i)->is_valuetypeptr()->is__Value()*/) { // 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().
*** 1868,1879 **** } else { // 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->isa_valuetypeptr(), "only value types for multiple return values"); ! ciValueKlass* vk = t->is_valuetypeptr()->value_klass(); Node* ctl = control(); ret = ValueTypeNode::make_from_multi(_gvn, ctl, merged_memory(), call, vk, TypeFunc::Parms+1, false); set_control(ctl); } } --- 1869,1880 ---- } else { // 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(); Node* ctl = control(); ret = ValueTypeNode::make_from_multi(_gvn, ctl, merged_memory(), call, vk, TypeFunc::Parms+1, false); set_control(ctl); } }
*** 2337,2347 **** const TypeFunc* tf = TypeFunc::make(dest_method); int nargs = tf->domain_sig()->cnt() - TypeFunc::Parms; int skip = Bytecodes::has_receiver(bc) ? 1 : 0; for (int j = skip, i = 0; j < nargs && i < TypeProfileArgsLimit; j++) { const Type *targ = tf->domain_sig()->field_at(j + TypeFunc::Parms); ! if (targ->isa_oopptr() && !targ->isa_valuetypeptr()) { ProfilePtrKind ptr_kind = ProfileMaybeNull; ciKlass* better_type = NULL; if (method()->argument_profiled_type(bci(), i, better_type, ptr_kind)) { record_profile_for_speculation(argument(j), better_type, ptr_kind); } --- 2338,2348 ---- const TypeFunc* tf = TypeFunc::make(dest_method); int nargs = tf->domain_sig()->cnt() - TypeFunc::Parms; int skip = Bytecodes::has_receiver(bc) ? 1 : 0; for (int j = skip, i = 0; j < nargs && i < TypeProfileArgsLimit; j++) { const Type *targ = tf->domain_sig()->field_at(j + TypeFunc::Parms); ! if (targ->isa_oopptr() && !targ->is_valuetypeptr()) { ProfilePtrKind ptr_kind = ProfileMaybeNull; ciKlass* better_type = NULL; if (method()->argument_profiled_type(bci(), i, better_type, ptr_kind)) { record_profile_for_speculation(argument(j), better_type, ptr_kind); }
*** 3129,3144 **** // the control edge for the cast failure. Otherwise, an appropriate // uncommon trap or exception is thrown. Node* GraphKit::gen_checkcast(Node *obj, Node* superklass, Node* *failure_control) { kill_dead_locals(); // Benefit all the uncommon traps ! const TypeKlassPtr *tk = _gvn.type(superklass)->is_klassptr(); ! const Type *toop = TypeOopPtr::make_from_klass(tk->klass()); ! if (toop->isa_valuetypeptr()) { if (obj->is_ValueType()) { const TypeValueType* tvt = _gvn.type(obj)->is_valuetype(); ! if (toop->is_valuetypeptr()->value_klass() == tvt->value_klass()) { return obj; } else { builtin_throw(Deoptimization::Reason_class_check, makecon(TypeKlassPtr::make(tvt->value_klass()))); return top(); } --- 3130,3145 ---- // the control edge for the cast failure. Otherwise, an appropriate // uncommon trap or exception is thrown. Node* GraphKit::gen_checkcast(Node *obj, Node* superklass, Node* *failure_control) { kill_dead_locals(); // Benefit all the uncommon traps ! const TypeKlassPtr* tk = _gvn.type(superklass)->is_klassptr(); ! const TypeOopPtr* toop = TypeOopPtr::make_from_klass(tk->klass()); ! if (toop->is_valuetypeptr()) { if (obj->is_ValueType()) { const TypeValueType* tvt = _gvn.type(obj)->is_valuetype(); ! if (toop->klass() == tvt->value_klass()) { return obj; } else { builtin_throw(Deoptimization::Reason_class_check, makecon(TypeKlassPtr::make(tvt->value_klass()))); return top(); }
*** 3173,3184 **** case Compile::SSC_always_true: // If we know the type check always succeed then we don't use // the profiling data at this bytecode. Don't lose it, feed it // to the type system as a speculative type. obj = record_profiled_receiver_for_speculation(obj); ! if (toop->isa_valuetypeptr()) { ! obj = ValueTypeNode::make_from_oop(this, obj, toop->isa_valuetypeptr()->value_klass()); } 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. --- 3174,3185 ---- case Compile::SSC_always_true: // If we know the type check always succeed then we don't use // the profiling data at this bytecode. Don't lose it, feed it // to the type system as a speculative type. obj = record_profiled_receiver_for_speculation(obj); ! if (toop->is_valuetypeptr()) { ! obj = ValueTypeNode::make_from_oop(this, obj, toop->value_klass()); } 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.
*** 3288,3299 **** // Return final merged results set_control( _gvn.transform(region) ); record_for_igvn(region); res = record_profiled_receiver_for_speculation(res); ! if (toop->isa_valuetypeptr()) { ! res = ValueTypeNode::make_from_oop(this, res, toop->isa_valuetypeptr()->value_klass()); } return res; } // Deoptimize if 'ary' is flattened or if 'obj' is null and 'ary' is a value type array --- 3289,3300 ---- // Return final merged results set_control( _gvn.transform(region) ); record_for_igvn(region); res = record_profiled_receiver_for_speculation(res); ! if (toop->is_valuetypeptr()) { ! res = ValueTypeNode::make_from_oop(this, res, toop->value_klass()); } return res; } // Deoptimize if 'ary' is flattened or if 'obj' is null and 'ary' is a value type array
*** 3623,3633 **** } else { const TypePtr* telemref = oop_type->add_offset(Type::OffsetBot); int elemidx = C->get_alias_index(telemref); hook_memory_on_init(*this, elemidx, minit_in, minit_out); } ! } else if (oop_type->isa_instptr() || oop_type->isa_valuetypeptr()) { ciInstanceKlass* ik = oop_type->klass()->as_instance_klass(); for (int i = 0, len = ik->nof_nonstatic_fields(); i < len; i++) { ciField* field = ik->nonstatic_field_at(i); if (field->offset() >= TrackedInitializationLimit * HeapWordSize) continue; // do not bother to track really large numbers of fields --- 3624,3634 ---- } else { const TypePtr* telemref = oop_type->add_offset(Type::OffsetBot); int elemidx = C->get_alias_index(telemref); hook_memory_on_init(*this, elemidx, minit_in, minit_out); } ! } else if (oop_type->isa_instptr()) { ciInstanceKlass* ik = oop_type->klass()->as_instance_klass(); for (int i = 0, len = ik->nof_nonstatic_fields(); i < len; i++) { ciField* field = ik->nonstatic_field_at(i); if (field->offset() >= TrackedInitializationLimit * HeapWordSize) continue; // do not bother to track really large numbers of fields
*** 3990,4000 **** // Loop body: initialize array element at 'index' set_control(loop); set_all_memory(mem); Node* adr = array_element_address(array, index, T_OBJECT); ! const TypeOopPtr* elemtype = TypeValueTypePtr::make(TypePtr::NotNull, vk); store_oop_to_array(control(), array, adr, TypeAryPtr::OOPS, oop, elemtype, T_VALUETYPE, MemNode::release); // Check if we need to execute another loop iteration length = SubI(length, intcon(1)); IfNode* iff = create_and_map_if(control(), Bool(CmpI(index, length), BoolTest::lt), PROB_FAIR, COUNT_UNKNOWN); --- 3991,4001 ---- // Loop body: initialize array element at 'index' set_control(loop); set_all_memory(mem); Node* adr = array_element_address(array, index, T_OBJECT); ! const TypeOopPtr* elemtype = TypeInstPtr::make(TypePtr::NotNull, vk); store_oop_to_array(control(), array, adr, TypeAryPtr::OOPS, oop, elemtype, T_VALUETYPE, MemNode::release); // Check if we need to execute another loop iteration length = SubI(length, intcon(1)); IfNode* iff = create_and_map_if(control(), Bool(CmpI(index, length), BoolTest::lt), PROB_FAIR, COUNT_UNKNOWN);
< prev index next >