< prev index next >
src/hotspot/share/opto/valuetypenode.cpp
Print this page
*** 45,55 ****
// Create a PhiNode each for merging the field values
for (uint i = 0; i < vt->field_count(); ++i) {
ciType* type = vt->field_type(i);
Node* value = vt->field_value(i);
! if (type->is_valuetype()) {
// Handle flattened value type fields recursively
value = value->as_ValueType()->clone_with_phis(gvn, region);
} else {
phi_type = Type::get_const_type(type);
value = PhiNode::make(region, value, phi_type);
--- 45,55 ----
// Create a PhiNode each for merging the field values
for (uint i = 0; i < vt->field_count(); ++i) {
ciType* type = vt->field_type(i);
Node* value = vt->field_value(i);
! if (type->is_valuetype() && value->isa_ValueType()) {
// Handle flattened value type fields recursively
value = value->as_ValueType()->clone_with_phis(gvn, region);
} else {
phi_type = Type::get_const_type(type);
value = PhiNode::make(region, value, phi_type);
*** 93,103 ****
}
// Merge field values
for (uint i = 0; i < field_count(); ++i) {
Node* val1 = field_value(i);
Node* val2 = other->field_value(i);
! if (val1->isa_ValueType()) {
val1->as_ValueType()->merge_with(gvn, val2->as_ValueType(), pnum, transform);
} else {
assert(val1->is_Phi(), "must be a phi node");
assert(!val2->is_ValueType(), "inconsistent merge values");
val1->set_req(pnum, val2);
--- 93,103 ----
}
// Merge field values
for (uint i = 0; i < field_count(); ++i) {
Node* val1 = field_value(i);
Node* val2 = other->field_value(i);
! if (val1->is_ValueType()) {
val1->as_ValueType()->merge_with(gvn, val2->as_ValueType(), pnum, transform);
} else {
assert(val1->is_Phi(), "must be a phi node");
assert(!val2->is_ValueType(), "inconsistent merge values");
val1->set_req(pnum, val2);
*** 118,128 ****
phi->add_req(NULL);
assert(phi->req() == region->req(), "must be same size as region");
for (uint i = 0; i < field_count(); ++i) {
Node* val = field_value(i);
! if (val->isa_ValueType()) {
val->as_ValueType()->add_new_path(region);
} else {
val->as_Phi()->add_req(NULL);
assert(val->req() == region->req(), "must be same size as region");
}
--- 118,128 ----
phi->add_req(NULL);
assert(phi->req() == region->req(), "must be same size as region");
for (uint i = 0; i < field_count(); ++i) {
Node* val = field_value(i);
! if (val->is_ValueType()) {
val->as_ValueType()->add_new_path(region);
} else {
val->as_Phi()->add_req(NULL);
assert(val->req() == region->req(), "must be same size as region");
}
*** 162,171 ****
--- 162,178 ----
void ValueTypeBaseNode::set_field_value(uint index, Node* value) {
assert(index < field_count(), "index out of bounds");
set_req(Values + index, value);
}
+ void ValueTypeBaseNode::set_field_value_by_offset(int offset, Node* value) {
+ uint i = 0;
+ for (; i < field_count() && field_offset(i) != offset; i++) { }
+ assert(i < field_count(), "field not found");
+ set_field_value(i, value);
+ }
+
int ValueTypeBaseNode::field_offset(uint index) const {
assert(index < field_count(), "index out of bounds");
return value_klass()->declared_nonstatic_field_at(index)->offset();
}
*** 283,293 ****
parm = gvn.transform(new ProjNode(multi->as_Call(), base_input + j + extra));
}
}
if (ft->is_valuetype()) {
// Non-flattened value type field
! assert(!gvn.type(parm)->is_ptr()->maybe_null(), "should never be null");
parm = ValueTypeNode::make_from_oop(kit, parm, ft->as_value_klass());
}
set_field_value(i, parm);
// Record all these guys for later GVN.
gvn.record_for_igvn(parm);
--- 290,300 ----
parm = gvn.transform(new ProjNode(multi->as_Call(), base_input + j + extra));
}
}
if (ft->is_valuetype()) {
// Non-flattened value type field
! assert(!gvn.type(parm)->maybe_null(), "should never be null");
parm = ValueTypeNode::make_from_oop(kit, parm, ft->as_value_klass());
}
set_field_value(i, parm);
// Record all these guys for later GVN.
gvn.record_for_igvn(parm);
*** 346,356 ****
--- 353,367 ----
}
value = kit->access_load_at(base, adr, adr_type, val_type, bt, decorators);
}
if (ft->is_valuetype()) {
// Loading a non-flattened value type from memory
+ if (ft->as_value_klass()->is_scalarizable()) {
value = ValueTypeNode::make_from_oop(kit, value, ft->as_value_klass(), /* buffer_check */ false, /* null2default */ field_is_flattenable(i), trap_bci);
+ } else {
+ value = kit->filter_null(value, field_is_flattenable(i), ft->as_value_klass(), trap_bci);
+ }
}
}
set_field_value(i, value);
}
}
*** 371,380 ****
--- 382,395 ----
int offset = holder_offset + field_offset(i);
Node* value = field_value(i);
ciType* ft = field_type(i);
if (field_is_flattened(i)) {
// Recursively store the flattened value type field
+ if (!value->is_ValueType()) {
+ assert(!kit->gvn().type(value)->maybe_null(), "should never be null");
+ value = ValueTypeNode::make_from_oop(kit, value, ft->as_value_klass());
+ }
value->as_ValueType()->store_flattened(kit, base, ptr, holder, offset);
} else {
// Store field value to memory
const TypePtr* adr_type = field_adr_type(base, offset, holder, kit->gvn());
Node* adr = kit->basic_plus_adr(base, ptr, offset);
*** 442,452 ****
}
bool ValueTypeBaseNode::is_allocated(PhaseGVN* phase) const {
Node* oop = get_oop();
const Type* oop_type = (phase != NULL) ? phase->type(oop) : oop->bottom_type();
! return !oop_type->is_ptr()->maybe_null();
}
// When a call returns multiple values, it has several result
// projections, one per field. Replacing the result of the call by a
// value type node (after late inlining) requires that for each result
--- 457,467 ----
}
bool ValueTypeBaseNode::is_allocated(PhaseGVN* phase) const {
Node* oop = get_oop();
const Type* oop_type = (phase != NULL) ? phase->type(oop) : oop->bottom_type();
! return !oop_type->maybe_null();
}
// When a call returns multiple values, it has several result
// projections, one per field. Replacing the result of the call by a
// value type node (after late inlining) requires that for each result
*** 478,524 ****
--i; --imax;
}
}
}
! ValueTypeNode* ValueTypeNode::make_uninitialized(PhaseGVN& gvn, ciValueKlass* klass) {
// Create a new ValueTypeNode with uninitialized values and NULL oop
! const TypeValueType* type = TypeValueType::make(klass);
! return new ValueTypeNode(type, gvn.zerocon(T_VALUETYPE));
}
Node* ValueTypeNode::default_oop(PhaseGVN& gvn, ciValueKlass* vk) {
// Returns the constant oop of the default value type allocation
return gvn.makecon(TypeInstPtr::make(vk->default_value_instance()));
}
ValueTypeNode* ValueTypeNode::make_default(PhaseGVN& gvn, ciValueKlass* vk) {
// Create a new ValueTypeNode with default values
! Node* oop = default_oop(gvn, vk);
! const TypeValueType* type = TypeValueType::make(vk);
! ValueTypeNode* vt = new ValueTypeNode(type, oop);
for (uint i = 0; i < vt->field_count(); ++i) {
ciType* field_type = vt->field_type(i);
Node* value = NULL;
! if (field_type->is_valuetype()) {
! value = ValueTypeNode::make_default(gvn, field_type->as_value_klass());
} else {
value = gvn.zerocon(field_type->basic_type());
}
vt->set_field_value(i, value);
}
vt = gvn.transform(vt)->as_ValueType();
assert(vt->is_default(gvn), "must be the default value type");
return vt;
}
-
bool ValueTypeNode::is_default(PhaseGVN& gvn) const {
for (uint i = 0; i < field_count(); ++i) {
Node* value = field_value(i);
if (!gvn.type(value)->is_zero_type() &&
! !(value->is_ValueType() && value->as_ValueType()->is_default(gvn))) {
return false;
}
}
return true;
}
--- 493,541 ----
--i; --imax;
}
}
}
! ValueTypeNode* ValueTypeNode::make_uninitialized(PhaseGVN& gvn, ciValueKlass* vk) {
// Create a new ValueTypeNode with uninitialized values and NULL oop
! return new ValueTypeNode(vk, gvn.zerocon(T_VALUETYPE));
}
Node* ValueTypeNode::default_oop(PhaseGVN& gvn, ciValueKlass* vk) {
// Returns the constant oop of the default value type allocation
return gvn.makecon(TypeInstPtr::make(vk->default_value_instance()));
}
ValueTypeNode* ValueTypeNode::make_default(PhaseGVN& gvn, ciValueKlass* vk) {
// Create a new ValueTypeNode with default values
! ValueTypeNode* vt = new ValueTypeNode(vk, default_oop(gvn, vk));
for (uint i = 0; i < vt->field_count(); ++i) {
ciType* field_type = vt->field_type(i);
Node* value = NULL;
! if (field_type->is_valuetype() && vt->field_is_flattenable(i)) {
! ciValueKlass* field_klass = field_type->as_value_klass();
! if (field_klass->is_scalarizable() || vt->field_is_flattened(i)) {
! value = ValueTypeNode::make_default(gvn, field_klass);
! } else {
! value = default_oop(gvn, field_klass);
! }
} else {
value = gvn.zerocon(field_type->basic_type());
}
vt->set_field_value(i, value);
}
vt = gvn.transform(vt)->as_ValueType();
assert(vt->is_default(gvn), "must be the default value type");
return vt;
}
bool ValueTypeNode::is_default(PhaseGVN& gvn) const {
for (uint i = 0; i < field_count(); ++i) {
Node* value = field_value(i);
if (!gvn.type(value)->is_zero_type() &&
! !(value->is_ValueType() && value->as_ValueType()->is_default(gvn)) &&
! !(field_type(i)->is_valuetype() && value == default_oop(gvn, field_type(i)->as_value_klass()))) {
return false;
}
}
return true;
}
*** 528,538 ****
const TypePtr* oop_type = gvn.type(oop)->is_ptr();
bool null_check = oop_type->maybe_null();
// Create and initialize a ValueTypeNode by loading all field
// values from a heap-allocated version and also save the oop.
! ValueTypeNode* vt = new ValueTypeNode(TypeValueType::make(vk), oop);
if (null_check) {
// Add a null check because the oop may be null
Node* null_ctl = kit->top();
Node* not_null_oop = kit->null_check_oop(oop, &null_ctl);
--- 545,555 ----
const TypePtr* oop_type = gvn.type(oop)->is_ptr();
bool null_check = oop_type->maybe_null();
// Create and initialize a ValueTypeNode by loading all field
// values from a heap-allocated version and also save the oop.
! ValueTypeNode* vt = new ValueTypeNode(vk, oop);
if (null_check) {
// Add a null check because the oop may be null
Node* null_ctl = kit->top();
Node* not_null_oop = kit->null_check_oop(oop, &null_ctl);
*** 645,655 ****
return get_oop();
}
for (uint i = 0; i < field_count(); ++i) {
int offset = holder_offset + field_offset(i);
Node* value = field_value(i);
! if (value->isa_ValueType()) {
ValueTypeNode* vt = value->as_ValueType();
if (field_is_flattened(i)) {
// Check value type field load recursively
base = vt->is_loaded(phase, vk, base, offset - vt->value_klass()->first_field_offset());
if (base == NULL) {
--- 662,672 ----
return get_oop();
}
for (uint i = 0; i < field_count(); ++i) {
int offset = holder_offset + field_offset(i);
Node* value = field_value(i);
! if (value->is_ValueType()) {
ValueTypeNode* vt = value->as_ValueType();
if (field_is_flattened(i)) {
// Check value type field load recursively
base = vt->is_loaded(phase, vk, base, offset - vt->value_klass()->first_field_offset());
if (base == NULL) {
*** 801,810 ****
--- 818,828 ----
StoreNode* store = addp->fast_out(k)->isa_Store();
if (store != NULL && store->outcnt() != 0) {
// Remove the useless store
Node* mem = store->in(MemNode::Memory);
Node* val = store->in(MemNode::ValueIn);
+ val = val->is_EncodeP() ? val->in(1) : val;
const Type* val_type = igvn->type(val);
assert(val_type->is_zero_type() || (val->is_Con() && val_type->make_ptr()->is_valuetypeptr()),
"must be zero-type or default value store");
igvn->replace_in_uses(store, mem);
}
*** 882,892 ****
}
// Process users
for (DUIterator_Fast imax, i = fast_outs(imax); i < imax; i++) {
Node* out = fast_out(i);
! if (out->isa_ValueType() != NULL) {
// Recursively process value type users
out->as_ValueType()->remove_redundant_allocations(igvn, phase);
} else if (out->isa_Allocate() != NULL) {
// Allocate users should be linked
assert(out->in(AllocateNode::ValueNode) == this, "should be linked");
--- 900,910 ----
}
// Process users
for (DUIterator_Fast imax, i = fast_outs(imax); i < imax; i++) {
Node* out = fast_out(i);
! if (out->is_ValueType()) {
// Recursively process value type users
out->as_ValueType()->remove_redundant_allocations(igvn, phase);
} else if (out->isa_Allocate() != NULL) {
// Allocate users should be linked
assert(out->in(AllocateNode::ValueNode) == this, "should be linked");
< prev index next >