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