src/share/vm/opto/valuetypenode.cpp
Index
Unified diffs
Context diffs
Sdiffs
Patch
New
Old
Previous File
Next File
valhalla-experimental Cdiff src/share/vm/opto/valuetypenode.cpp
src/share/vm/opto/valuetypenode.cpp
Print this page
*** 57,75 ****
void ValueTypeNode::load_values(PhaseGVN& gvn, Node* mem, ciInstanceKlass* holder, Node* base, int base_offset) {
// Initialize the value type by loading its field values from
// memory and adding the values as input edges to the node.
for (uint i = 0; i < field_count(); ++i) {
! int offset = base_offset + get_field_offset(i);
Node* adr = gvn.transform(new AddPNode(base, base, gvn.longcon(offset)));
ciField* field = holder->get_field_by_offset(offset, false);
const TypePtr* adr_type = gvn.C->alias_type(field)->adr_type();
Node* value = NULL;
! ciType* field_type = get_field_type(i);
! if (field_type->is_valuetype()) {
// Recursively load the flattened value type field
! value = ValueTypeNode::make(gvn, field_type->as_value_klass(), mem, holder, base, offset);
} else {
const Type* con_type = NULL;
if (base->is_Con()) {
// If the oop to the value type is constant (static final field), we can
// also treat the fields as constants because the value type is immutable.
--- 57,75 ----
void ValueTypeNode::load_values(PhaseGVN& gvn, Node* mem, ciInstanceKlass* holder, Node* base, int base_offset) {
// Initialize the value type by loading its field values from
// memory and adding the values as input edges to the node.
for (uint i = 0; i < field_count(); ++i) {
! int offset = base_offset + field_offset(i);
Node* adr = gvn.transform(new AddPNode(base, base, gvn.longcon(offset)));
ciField* field = holder->get_field_by_offset(offset, false);
const TypePtr* adr_type = gvn.C->alias_type(field)->adr_type();
Node* value = NULL;
! ciType* f_type = field_type(i);
! if (f_type->is_valuetype()) {
// Recursively load the flattened value type field
! value = ValueTypeNode::make(gvn, f_type->as_value_klass(), mem, holder, base, offset);
} else {
const Type* con_type = NULL;
if (base->is_Con()) {
// If the oop to the value type is constant (static final field), we can
// also treat the fields as constants because the value type is immutable.
*** 81,91 ****
if (con_type != NULL) {
// Found a constant field value
value = gvn.makecon(con_type);
} else {
// Load field value from memory
! value = LoadNode::make(gvn, NULL, mem, adr, adr_type, Type::get_const_type(field_type), field_type->basic_type(), MemNode::unordered);
}
}
set_field_value(i, gvn.transform(value));
}
}
--- 81,91 ----
if (con_type != NULL) {
// Found a constant field value
value = gvn.makecon(con_type);
} else {
// Load field value from memory
! value = LoadNode::make(gvn, NULL, mem, adr, adr_type, Type::get_const_type(f_type), f_type->basic_type(), MemNode::unordered);
}
}
set_field_value(i, gvn.transform(value));
}
}
*** 98,117 ****
}
void ValueTypeNode::store_values(GraphKit* kit, ciInstanceKlass* holder, Node* base, int base_offset) const {
// Write field values to memory
for (uint i = 0; i < field_count(); ++i) {
! int offset = base_offset + get_field_offset(i);
Node* adr = kit->basic_plus_adr(base, base, offset);
ciField* field = holder->get_field_by_offset(offset, false);
const TypePtr* adr_type = kit->C->alias_type(field)->adr_type();
! Node* value = get_field_value(i);
if (value->is_ValueType()) {
// Recursively store the flattened value type field
value->isa_ValueType()->store_to_field(kit, holder, base, offset);
} else {
! kit->store_to_memory(kit->control(), adr, value, get_field_type(i)->basic_type(), adr_type, MemNode::unordered);
}
}
}
Node* ValueTypeNode::store_to_memory(GraphKit* kit) {
--- 98,117 ----
}
void ValueTypeNode::store_values(GraphKit* kit, ciInstanceKlass* holder, Node* base, int base_offset) const {
// Write field values to memory
for (uint i = 0; i < field_count(); ++i) {
! int offset = base_offset + field_offset(i);
Node* adr = kit->basic_plus_adr(base, base, offset);
ciField* field = holder->get_field_by_offset(offset, false);
const TypePtr* adr_type = kit->C->alias_type(field)->adr_type();
! Node* value = field_value(i);
if (value->is_ValueType()) {
// Recursively store the flattened value type field
value->isa_ValueType()->store_to_field(kit, holder, base, offset);
} else {
! kit->store_to_memory(kit->control(), adr, value, field_type(i)->basic_type(), adr_type, MemNode::unordered);
}
}
}
Node* ValueTypeNode::store_to_memory(GraphKit* kit) {
*** 183,194 ****
gvn.set_type(oop, vtptr);
vt->set_oop(oop);
// Create a PhiNode each for merging the field values
for (uint i = 0; i < vt->field_count(); ++i) {
! ciType* type = vt->get_field_type(i);
! Node* value = vt->get_field_value(i);
if (type->is_valuetype()) {
// Handle flattened value type fields recursively
value = value->as_ValueType()->clone_with_phis(gvn, region);
} else {
const Type* phi_type = Type::get_const_type(type);
--- 183,194 ----
gvn.set_type(oop, vtptr);
vt->set_oop(oop);
// 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 {
const Type* phi_type = Type::get_const_type(type);
*** 208,218 ****
bool result = get_oop()->is_Phi() && get_oop()->as_Phi()->region() == region;
#ifdef ASSERT
if (result) {
// Check all field value inputs for consistency
for (uint i = 0; i < field_count(); ++i) {
! Node* value = get_field_value(i);
if (value->is_ValueType()) {
assert(value->as_ValueType()->has_phi_inputs(region), "inconsistent phi inputs");
} else {
assert(value->is_Phi() && value->as_Phi()->region() == region, "inconsistent phi inputs");
}
--- 208,218 ----
bool result = get_oop()->is_Phi() && get_oop()->as_Phi()->region() == region;
#ifdef ASSERT
if (result) {
// Check all field value inputs for consistency
for (uint i = 0; i < field_count(); ++i) {
! Node* value = field_value(i);
if (value->is_ValueType()) {
assert(value->as_ValueType()->has_phi_inputs(region), "inconsistent phi inputs");
} else {
assert(value->is_Phi() && value->as_Phi()->region() == region, "inconsistent phi inputs");
}
*** 232,243 ****
set_oop(kit->gvn().transform_no_reclaim(phi));
kit->record_for_igvn(phi);
}
// Merge field values
for (uint i = 0; i < field_count(); ++i) {
! Node* val1 = get_field_value(i);
! Node* val2 = other->get_field_value(i);
if (val1->isa_ValueType()) {
val1->as_ValueType()->merge_with(kit, val2->as_ValueType(), pnum);
} else {
assert(!val2->is_ValueType(), "inconsistent merge values");
val1->set_req(pnum, val2);
--- 232,243 ----
set_oop(kit->gvn().transform_no_reclaim(phi));
kit->record_for_igvn(phi);
}
// 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(kit, val2->as_ValueType(), pnum);
} else {
assert(!val2->is_ValueType(), "inconsistent merge values");
val1->set_req(pnum, val2);
*** 254,281 ****
return kit->gvn().transform_no_reclaim(this);
}
return this;
}
! Node* ValueTypeNode::get_field_value(uint index) const {
assert(index < field_count(), "index out of bounds");
return in(Values + index);
}
// Get the value of the field at the given offset.
// If 'recursive' is true, flattened value type fields will be resolved recursively.
! Node* ValueTypeNode::get_field_value_by_offset(int offset, bool recursive) const {
// If the field at 'offset' belongs to a flattened value type field, 'index' refers to the
// corresponding ValueTypeNode input and 'sub_offset' is the offset in flattened value type.
int index = value_klass()->field_index_by_offset(offset);
! int sub_offset = offset - get_field_offset(index);
! Node* value = get_field_value(index);
if (recursive && value->is_ValueType()) {
// Flattened value type field
ValueTypeNode* vt = value->as_ValueType();
sub_offset += vt->value_klass()->first_field_offset(); // Add header size
! return vt->get_field_value_by_offset(sub_offset);
}
assert(!(recursive && value->is_ValueType()), "should not be a value type");
assert(sub_offset == 0, "offset mismatch");
return value;
}
--- 254,281 ----
return kit->gvn().transform_no_reclaim(this);
}
return this;
}
! Node* ValueTypeNode::field_value(uint index) const {
assert(index < field_count(), "index out of bounds");
return in(Values + index);
}
// Get the value of the field at the given offset.
// If 'recursive' is true, flattened value type fields will be resolved recursively.
! Node* ValueTypeNode::field_value_by_offset(int offset, bool recursive) const {
// If the field at 'offset' belongs to a flattened value type field, 'index' refers to the
// corresponding ValueTypeNode input and 'sub_offset' is the offset in flattened value type.
int index = value_klass()->field_index_by_offset(offset);
! int sub_offset = offset - field_offset(index);
! Node* value = field_value(index);
if (recursive && value->is_ValueType()) {
// Flattened value type field
ValueTypeNode* vt = value->as_ValueType();
sub_offset += vt->value_klass()->first_field_offset(); // Add header size
! return vt->field_value_by_offset(sub_offset);
}
assert(!(recursive && value->is_ValueType()), "should not be a value type");
assert(sub_offset == 0, "offset mismatch");
return value;
}
*** 283,298 ****
void ValueTypeNode::set_field_value(uint index, Node* value) {
assert(index < field_count(), "index out of bounds");
set_req(Values + index, value);
}
! int ValueTypeNode::get_field_offset(uint index) const {
assert(index < field_count(), "index out of bounds");
return value_klass()->field_offset_by_index(index);
}
! ciType* ValueTypeNode::get_field_type(uint index) const {
assert(index < field_count(), "index out of bounds");
return value_klass()->field_type_by_index(index);
}
void ValueTypeNode::make_scalar_in_safepoints(Compile* C) {
--- 283,298 ----
void ValueTypeNode::set_field_value(uint index, Node* value) {
assert(index < field_count(), "index out of bounds");
set_req(Values + index, value);
}
! int ValueTypeNode::field_offset(uint index) const {
assert(index < field_count(), "index out of bounds");
return value_klass()->field_offset_by_index(index);
}
! ciType* ValueTypeNode::field_type(uint index) const {
assert(index < field_count(), "index out of bounds");
return value_klass()->field_type_by_index(index);
}
void ValueTypeNode::make_scalar_in_safepoints(Compile* C) {
*** 324,334 ****
sobj->init_req(0, C->root());
// Iterate over the value type fields in order of increasing
// offset and add the field values to the safepoint.
for (uint j = 0; j < nfields; ++j) {
int offset = vk->nonstatic_field_at(j)->offset();
! Node* value = get_field_value_by_offset(offset, true /* include flattened value type fields */);
sfpt->add_req(value);
}
jvms->set_endoff(sfpt->req());
int nb = sfpt->replace_edges_in_range(this, sobj, start, end);
--i; imax -= nb;
--- 324,334 ----
sobj->init_req(0, C->root());
// Iterate over the value type fields in order of increasing
// offset and add the field values to the safepoint.
for (uint j = 0; j < nfields; ++j) {
int offset = vk->nonstatic_field_at(j)->offset();
! Node* value = field_value_by_offset(offset, true /* include flattened value type fields */);
sfpt->add_req(value);
}
jvms->set_endoff(sfpt->req());
int nb = sfpt->replace_edges_in_range(this, sobj, start, end);
--i; imax -= nb;
*** 342,373 ****
if (base_vk == NULL) {
base_vk = vk;
}
uint edges = 0;
for (uint i = 0; i < field_count(); i++) {
! ciType* field_type = get_field_type(i);
! int offset = base_offset + get_field_offset(i) - (base_offset > 0 ? vk->first_field_offset() : 0);
! Node* arg = get_field_value(i);
! if (field_type->is_valuetype()) {
! ciValueKlass* embedded_vk = field_type->as_value_klass();
edges += arg->as_ValueType()->set_arguments_for_java_call(call, base_input, kit, base_vk, offset);
} else {
int j = 0; int extra = 0;
for (; j < base_vk->nof_nonstatic_fields(); j++) {
ciField* f = base_vk->nonstatic_field_at(j);
if (offset == f->offset()) {
! assert(f->type() == field_type, "inconsistent field type");
break;
}
BasicType bt = f->type()->basic_type();
if (bt == T_LONG || bt == T_DOUBLE) {
extra++;
}
}
call->init_req(base_input + j + extra, arg);
edges++;
! BasicType bt = field_type->basic_type();
if (bt == T_LONG || bt == T_DOUBLE) {
call->init_req(base_input + j + extra + 1, kit.top());
edges++;
}
}
--- 342,373 ----
if (base_vk == NULL) {
base_vk = vk;
}
uint edges = 0;
for (uint i = 0; i < field_count(); i++) {
! ciType* f_type = field_type(i);
! int offset = base_offset + field_offset(i) - (base_offset > 0 ? vk->first_field_offset() : 0);
! Node* arg = field_value(i);
! if (f_type->is_valuetype()) {
! ciValueKlass* embedded_vk = f_type->as_value_klass();
edges += arg->as_ValueType()->set_arguments_for_java_call(call, base_input, kit, base_vk, offset);
} else {
int j = 0; int extra = 0;
for (; j < base_vk->nof_nonstatic_fields(); j++) {
ciField* f = base_vk->nonstatic_field_at(j);
if (offset == f->offset()) {
! assert(f->type() == f_type, "inconsistent field type");
break;
}
BasicType bt = f->type()->basic_type();
if (bt == T_LONG || bt == T_DOUBLE) {
extra++;
}
}
call->init_req(base_input + j + extra, arg);
edges++;
! BasicType bt = f_type->basic_type();
if (bt == T_LONG || bt == T_DOUBLE) {
call->init_req(base_input + j + extra + 1, kit.top());
edges++;
}
}
src/share/vm/opto/valuetypenode.cpp
Index
Unified diffs
Context diffs
Sdiffs
Patch
New
Old
Previous File
Next File