< prev index next >
src/hotspot/share/opto/valuetypenode.cpp
Print this page
@@ -36,25 +36,24 @@
ValueTypeBaseNode* ValueTypeBaseNode::clone_with_phis(PhaseGVN* gvn, Node* region) {
assert(!has_phi_inputs(region), "already cloned with phis");
ValueTypeBaseNode* vt = clone()->as_ValueTypeBase();
// Create a PhiNode for merging the oop values
- const TypeValueTypePtr* vtptr = value_type_ptr();
- vtptr = vtptr->cast_to_ptr_type(TypePtr::BotPTR)->is_valuetypeptr();
- PhiNode* oop = PhiNode::make(region, vt->get_oop(), vtptr);
- gvn->set_type(oop, vtptr);
+ const Type* phi_type = Type::get_const_type(value_klass());
+ PhiNode* oop = PhiNode::make(region, vt->get_oop(), phi_type);
+ gvn->set_type(oop, phi_type);
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);
+ phi_type = Type::get_const_type(type);
value = PhiNode::make(region, value, phi_type);
gvn->set_type(value, phi_type);
}
vt->set_field_value(i, value);
}
@@ -156,11 +155,13 @@
return value_klass()->declared_nonstatic_field_at(index)->type();
}
bool ValueTypeBaseNode::field_is_flattened(uint index) const {
assert(index < field_count(), "index out of bounds");
- return value_klass()->declared_nonstatic_field_at(index)->is_flattened();
+ ciField* field = value_klass()->declared_nonstatic_field_at(index);
+ assert(!field->is_flattened() || field->type()->is_valuetype(), "must be a value type");
+ return field->is_flattened();
}
int ValueTypeBaseNode::make_scalar_in_safepoint(Unique_Node_List& worklist, SafePointNode* sfpt, Node* root, PhaseGVN* gvn) {
ciValueKlass* vk = value_klass();
uint nfields = vk->nof_nonstatic_fields();
@@ -219,52 +220,50 @@
Node* vt = worklist.at(i);
vt->as_ValueType()->make_scalar_in_safepoints(root, gvn);
}
}
-void ValueTypeBaseNode::make(PhaseGVN* gvn, Node*& ctl, Node* mem, Node* n, ValueTypeBaseNode* vt, ciValueKlass* base_vk, int base_offset, int base_input, bool in) {
- assert(base_offset >= 0, "offset in value type always positive");
- for (uint i = 0; i < vt->field_count(); i++) {
- ciType* field_type = vt->field_type(i);
- int offset = base_offset + vt->field_offset(i);
- if (field_type->is_valuetype() && vt->field_is_flattened(i)) {
- ciValueKlass* embedded_vk = field_type->as_value_klass();
- ValueTypeNode* embedded_vt = ValueTypeNode::make(*gvn, embedded_vk);
- ValueTypeBaseNode::make(gvn, ctl, mem, n, embedded_vt, base_vk, offset - vt->value_klass()->first_field_offset(), base_input, in);
- vt->set_field_value(i, gvn->transform(embedded_vt));
+void ValueTypeBaseNode::initialize(PhaseGVN* gvn, Node*& ctl, Node* mem, MultiNode* multi, ciValueKlass* vk, int base_offset, int base_input, bool in) {
+ assert(base_offset >= 0, "offset in value type must be positive");
+ for (uint i = 0; i < field_count(); i++) {
+ ciType* ft = field_type(i);
+ int offset = base_offset + field_offset(i);
+ if (field_is_flattened(i)) {
+ // Flattened value type field
+ ValueTypeNode* vt = ValueTypeNode::make_uninitialized(*gvn, ft->as_value_klass());
+ vt->initialize(gvn, ctl, mem, multi, vk, offset - value_klass()->first_field_offset(), base_input, in);
+ set_field_value(i, gvn->transform(vt));
} else {
int j = 0; int extra = 0;
- for (; j < base_vk->nof_nonstatic_fields(); j++) {
- ciField* f = base_vk->nonstatic_field_at(j);
+ for (; j < vk->nof_nonstatic_fields(); j++) {
+ ciField* f = vk->nonstatic_field_at(j);
if (offset == f->offset()) {
- assert(f->type() == field_type, "inconsistent field type");
+ assert(f->type() == ft, "inconsistent field type");
break;
}
BasicType bt = f->type()->basic_type();
if (bt == T_LONG || bt == T_DOUBLE) {
extra++;
}
}
- assert(j != base_vk->nof_nonstatic_fields(), "must find");
+ assert(j != vk->nof_nonstatic_fields(), "must find");
Node* parm = NULL;
- if (n->is_Start()) {
+ if (multi->is_Start()) {
assert(in, "return from start?");
- parm = gvn->transform(new ParmNode(n->as_Start(), base_input + j + extra));
+ parm = gvn->transform(new ParmNode(multi->as_Start(), base_input + j + extra));
} else {
if (in) {
- assert(n->is_Call(), "nothing else here");
- parm = n->in(base_input + j + extra);
+ parm = multi->as_Call()->in(base_input + j + extra);
} else {
- parm = gvn->transform(new ProjNode(n->as_Call(), base_input + j + extra));
+ parm = gvn->transform(new ProjNode(multi->as_Call(), base_input + j + extra));
}
}
- if (field_type->is_valuetype()) {
+ if (ft->is_valuetype()) {
// Non-flattened value type field, check for null
- parm = ValueTypeNode::make(*gvn, ctl, mem, parm, /* null_check */ true);
-
+ parm = ValueTypeNode::make_from_oop(*gvn, ctl, mem, parm, /* null_check */ true);
}
- vt->set_field_value(i, parm);
+ set_field_value(i, parm);
// Record all these guys for later GVN.
gvn->record_for_igvn(parm);
}
}
}
@@ -272,15 +271,15 @@
void ValueTypeBaseNode::load(PhaseGVN& gvn, Node*& ctl, Node* mem, Node* base, Node* ptr, ciInstanceKlass* holder, int holder_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 = holder_offset + field_offset(i);
- ciType* ftype = field_type(i);
Node* value = NULL;
- if (ftype->is_valuetype() && field_is_flattened(i)) {
+ ciType* ft = field_type(i);
+ if (field_is_flattened(i)) {
// Recursively load the flattened value type field
- value = ValueTypeNode::make(gvn, ftype->as_value_klass(), ctl, mem, base, ptr, holder, offset);
+ value = ValueTypeNode::make_from_flattened(gvn, ft->as_value_klass(), ctl, mem, base, ptr, holder, 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.
@@ -293,34 +292,32 @@
if (con_type != NULL) {
// Found a constant field value
value = gvn.transform(gvn.makecon(con_type));
if (con_type->isa_valuetypeptr()) {
// Constant, non-flattened value type field
- value = ValueTypeNode::make(gvn, ctl, mem, value);
+ value = ValueTypeNode::make_from_oop(gvn, ctl, mem, value);
}
} else {
// Load field value from memory
- const Type* base_type = gvn.type(base);
+ const TypeAryPtr* ary_type = gvn.type(base)->isa_aryptr();
const TypePtr* adr_type = NULL;
- if (base_type->isa_aryptr()) {
+ bool is_array = ary_type != NULL;
+ if (is_array) {
// In the case of a flattened value type array, each field has its own slice
- adr_type = base_type->is_aryptr()->with_field_offset(offset)->add_offset(Type::OffsetBot);
+ adr_type = ary_type->with_field_offset(offset)->add_offset(Type::OffsetBot);
} else {
ciField* field = holder->get_field_by_offset(offset, false);
adr_type = gvn.C->alias_type(field)->adr_type();
}
Node* adr = gvn.transform(new AddPNode(base, ptr, gvn.MakeConX(offset)));
- BasicType bt = type2field[ftype->basic_type()];
- const Type* ft = Type::get_const_type(ftype);
- if (bt == T_VALUETYPE) {
- ft = ft->is_valuetypeptr()->cast_to_ptr_type(TypePtr::BotPTR);
- }
+ BasicType bt = type2field[ft->basic_type()];
assert(is_java_primitive(bt) || adr->bottom_type()->is_ptr_to_narrowoop() == UseCompressedOops, "inconsistent");
- value = gvn.transform(LoadNode::make(gvn, NULL, mem, adr, adr_type, ft, bt, MemNode::unordered));
+ const Type* rt = Type::get_const_type(ft);
+ value = gvn.transform(LoadNode::make(gvn, is_array ? ctl : NULL, mem, adr, adr_type, rt, bt, MemNode::unordered));
if (bt == T_VALUETYPE) {
// Non-flattened value type field, check for null
- value = ValueTypeNode::make(gvn, ctl, mem, value, /* null_check */ true);
+ value = ValueTypeNode::make_from_oop(gvn, ctl, mem, value, /* null_check */ true);
}
}
}
set_field_value(i, value);
}
@@ -339,34 +336,33 @@
}
// Write field values to memory
for (uint i = 0; i < field_count(); ++i) {
int offset = holder_offset + field_offset(i);
Node* value = field_value(i);
- if (value->is_ValueType() && field_is_flattened(i)) {
+ ciType* ft = field_type(i);
+ if (field_is_flattened(i)) {
// Recursively store the flattened value type field
- value->isa_ValueType()->store_flattened(kit, base, ptr, holder, offset);
+ value->as_ValueType()->store_flattened(kit, base, ptr, holder, offset);
} else {
- const Type* base_type = kit->gvn().type(base);
+ const TypeAryPtr* ary_type = kit->gvn().type(base)->isa_aryptr();
const TypePtr* adr_type = NULL;
- if (base_type->isa_aryptr()) {
+ bool is_array = ary_type != NULL;
+ if (is_array) {
// In the case of a flattened value type array, each field has its own slice
- adr_type = base_type->is_aryptr()->with_field_offset(offset)->add_offset(Type::OffsetBot);
+ adr_type = ary_type->with_field_offset(offset)->add_offset(Type::OffsetBot);
} else {
ciField* field = holder->get_field_by_offset(offset, false);
adr_type = kit->C->alias_type(field)->adr_type();
}
Node* adr = kit->basic_plus_adr(base, ptr, offset);
- BasicType bt = type2field[field_type(i)->basic_type()];
+ BasicType bt = type2field[ft->basic_type()];
if (is_java_primitive(bt)) {
kit->store_to_memory(kit->control(), adr, value, bt, adr_type, MemNode::unordered);
} else {
- const TypeOopPtr* ft = TypeOopPtr::make_from_klass(field_type(i)->as_klass());
- // Field may be NULL
- ft = ft->cast_to_ptr_type(TypePtr::BotPTR)->is_oopptr();
+ const TypeOopPtr* val_type = Type::get_const_type(ft)->is_oopptr();
assert(adr->bottom_type()->is_ptr_to_narrowoop() == UseCompressedOops, "inconsistent");
- bool is_array = base_type->isa_aryptr() != NULL;
- kit->store_oop(kit->control(), base, adr, adr_type, value, ft, bt, is_array, MemNode::unordered);
+ kit->store_oop(kit->control(), base, adr, adr_type, value, val_type, bt, is_array, MemNode::unordered);
}
}
}
}
@@ -380,16 +376,12 @@
return this;
}
// Not able to prove that value type is allocated.
// Emit runtime check that may be folded later.
assert(!is_allocated(&kit->gvn()), "should not be allocated");
- const TypeValueTypePtr* vtptr_type = bottom_type()->isa_valuetypeptr();
- if (vtptr_type == NULL) {
- vtptr_type = TypeValueTypePtr::make(bottom_type()->isa_valuetype(), TypePtr::NotNull);
- }
RegionNode* region = new RegionNode(3);
- PhiNode* oop = new PhiNode(region, vtptr_type);
+ PhiNode* oop = new PhiNode(region, value_type_ptr());
PhiNode* io = new PhiNode(region, Type::ABIO);
PhiNode* mem = new PhiNode(region, Type::MEMORY, TypePtr::BOTTOM);
// Oop is non-NULL, use it
region->init_req(1, kit->control());
@@ -465,38 +457,37 @@
--i; --imax;
}
}
}
-ValueTypeNode* ValueTypeNode::make(PhaseGVN& gvn, ciValueKlass* klass) {
+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), gvn.C);
+ return new ValueTypeNode(type, gvn.zerocon(T_VALUETYPE));
}
-Node* ValueTypeNode::make_default(PhaseGVN& gvn, ciValueKlass* vk) {
- // TODO re-use constant oop of pre-allocated default value type here?
+ValueTypeNode* ValueTypeNode::make_default(PhaseGVN& gvn, ciValueKlass* vk) {
// Create a new ValueTypeNode with default values
- ValueTypeNode* vt = ValueTypeNode::make(gvn, vk);
+ ValueTypeNode* vt = ValueTypeNode::make_uninitialized(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()) {
value = ValueTypeNode::make_default(gvn, field_type->as_value_klass());
} else {
value = gvn.zerocon(field_type->basic_type());
}
vt->set_field_value(i, value);
}
- return gvn.transform(vt);
+ return gvn.transform(vt)->as_ValueType();
}
-Node* ValueTypeNode::make(PhaseGVN& gvn, Node*& ctl, Node* mem, Node* oop, bool null_check) {
+ValueTypeNode* ValueTypeNode::make_from_oop(PhaseGVN& gvn, Node*& ctl, Node* mem, Node* oop, bool null_check) {
// Create and initialize a ValueTypeNode by loading all field
// values from a heap-allocated version and also save the oop.
- const TypeValueType* type = gvn.type(oop)->is_valuetypeptr()->value_type();
- ValueTypeNode* vt = new ValueTypeNode(type, oop, gvn.C);
+ ciValueKlass* vk = gvn.type(oop)->is_valuetypeptr()->value_klass();
+ ValueTypeNode* vt = new ValueTypeNode(TypeValueType::make(vk), oop);
if (null_check && !vt->is_allocated(&gvn)) {
// Add oop null check
Node* chk = gvn.transform(new CmpPNode(oop, gvn.zerocon(T_VALUETYPE)));
Node* tst = gvn.transform(new BoolNode(chk, BoolTest::ne));
@@ -507,67 +498,72 @@
// Load value type from memory if oop is non-null
oop = new CastPPNode(oop, TypePtr::NOTNULL);
oop->set_req(0, not_null);
oop = gvn.transform(oop);
- vt->load(gvn, not_null, mem, oop, oop, type->value_klass());
+ vt->load(gvn, not_null, mem, oop, oop, vk);
region->init_req(1, not_null);
// Use default value type if oop is null
- Node* def = make_default(gvn, type->value_klass());
+ ValueTypeNode* def = make_default(gvn, vk);
region->init_req(2, null);
// Merge the two value types and update control
vt = vt->clone_with_phis(&gvn, region)->as_ValueType();
- vt->merge_with(&gvn, def->as_ValueType(), 2, true);
+ vt->merge_with(&gvn, def, 2, true);
ctl = gvn.transform(region);
} else {
Node* init_ctl = ctl;
- vt->load(gvn, ctl, mem, oop, oop, type->value_klass());
+ vt->load(gvn, ctl, mem, oop, oop, vk);
vt = gvn.transform(vt)->as_ValueType();
assert(vt->is_allocated(&gvn), "value type should be allocated");
assert(init_ctl != ctl || oop->is_Con() || oop->is_CheckCastPP() || oop->Opcode() == Op_ValueTypePtr ||
- vt->is_loaded(&gvn, type) == oop, "value type should be loaded");
+ vt->is_loaded(&gvn) == oop, "value type should be loaded");
}
return vt;
}
-Node* ValueTypeNode::make(GraphKit* kit, Node* oop, bool null_check) {
+// GraphKit wrapper for the 'make_from_oop' method
+ValueTypeNode* ValueTypeNode::make_from_oop(GraphKit* kit, Node* oop, bool null_check) {
Node* ctl = kit->control();
- Node* vt = make(kit->gvn(), ctl, kit->merged_memory(), oop, null_check);
+ ValueTypeNode* vt = make_from_oop(kit->gvn(), ctl, kit->merged_memory(), oop, null_check);
kit->set_control(ctl);
return vt;
}
-Node* ValueTypeNode::make(PhaseGVN& gvn, ciValueKlass* vk, Node*& ctl, Node* mem, Node* obj, Node* ptr, ciInstanceKlass* holder, int holder_offset) {
+ValueTypeNode* ValueTypeNode::make_from_flattened(PhaseGVN& gvn, ciValueKlass* vk, Node*& ctl, Node* mem, Node* obj, Node* ptr, ciInstanceKlass* holder, int holder_offset) {
// Create and initialize a ValueTypeNode by loading all field values from
// a flattened value type field at 'holder_offset' or from a value type array.
- ValueTypeNode* vt = make(gvn, vk);
+ ValueTypeNode* vt = make_uninitialized(gvn, vk);
// The value type is flattened into the object without an oop header. Subtract the
// offset of the first field to account for the missing header when loading the values.
holder_offset -= vk->first_field_offset();
vt->load(gvn, ctl, mem, obj, ptr, holder, holder_offset);
- assert(vt->is_loaded(&gvn, vt->type()->isa_valuetype()) != obj, "holder oop should not be used as flattened value type oop");
+ assert(vt->is_loaded(&gvn) != obj, "holder oop should not be used as flattened value type oop");
return gvn.transform(vt)->as_ValueType();
}
-Node* ValueTypeNode::make(GraphKit* kit, ciValueKlass* vk, Node* obj, Node* ptr, ciInstanceKlass* holder, int holder_offset) {
+// GraphKit wrapper for the 'make_from_flattened' method
+ValueTypeNode* ValueTypeNode::make_from_flattened(GraphKit* kit, ciValueKlass* vk, Node* obj, Node* ptr, ciInstanceKlass* holder, int holder_offset) {
Node* ctl = kit->control();
- Node* vt = make(kit->gvn(), vk, ctl, kit->merged_memory(), obj, ptr, holder, holder_offset);
+ ValueTypeNode* vt = make_from_flattened(kit->gvn(), vk, ctl, kit->merged_memory(), obj, ptr, holder, holder_offset);
kit->set_control(ctl);
return vt;
}
-Node* ValueTypeNode::make(PhaseGVN& gvn, Node*& ctl, Node* mem, Node* n, ciValueKlass* vk, int base_input, bool in) {
- ValueTypeNode* vt = ValueTypeNode::make(gvn, vk);
- ValueTypeBaseNode::make(&gvn, ctl, mem, n, vt, vk, 0, base_input, in);
- return gvn.transform(vt);
+ValueTypeNode* ValueTypeNode::make_from_multi(PhaseGVN& gvn, Node*& ctl, Node* mem, MultiNode* multi, ciValueKlass* vk, int base_input, bool in) {
+ ValueTypeNode* vt = ValueTypeNode::make_uninitialized(gvn, vk);
+ vt->initialize(&gvn, ctl, mem, multi, vk, 0, base_input, in);
+ return gvn.transform(vt)->as_ValueType();
}
-Node* ValueTypeNode::is_loaded(PhaseGVN* phase, const TypeValueType* t, Node* base, int holder_offset) {
+Node* ValueTypeNode::is_loaded(PhaseGVN* phase, ciValueKlass* vk, Node* base, int holder_offset) {
+ if (vk == NULL) {
+ vk = value_klass();
+ }
if (field_count() == 0) {
- assert(t->value_klass()->is__Value(), "unexpected value type klass");
+ assert(vk->is__Value(), "unexpected value type klass");
assert(is_allocated(phase), "must be allocated");
return get_oop();
}
for (uint i = 0; i < field_count(); ++i) {
int offset = holder_offset + field_offset(i);
@@ -584,18 +580,18 @@
return NULL;
} else if (base == NULL) {
// Set base and check if pointer type matches
base = lbase;
const TypeValueTypePtr* vtptr = phase->type(base)->isa_valuetypeptr();
- if (vtptr == NULL || !vtptr->value_type()->eq(t)) {
+ if (vtptr == NULL || !vtptr->value_klass()->equals(vk)) {
return NULL;
}
}
} else if (value->isa_ValueType()) {
// Check value type field load recursively
ValueTypeNode* vt = value->as_ValueType();
- base = vt->is_loaded(phase, t, base, offset - vt->value_klass()->first_field_offset());
+ base = vt->is_loaded(phase, vk, base, offset - vt->value_klass()->first_field_offset());
if (base == NULL) {
return NULL;
}
} else {
return NULL;
@@ -605,19 +601,17 @@
}
Node* ValueTypeNode::allocate_fields(GraphKit* kit) {
ValueTypeNode* vt = clone()->as_ValueType();
for (uint i = 0; i < field_count(); i++) {
- Node* value = field_value(i);
- if (value->is_ValueType()) {
+ ValueTypeNode* value = field_value(i)->isa_ValueType();
if (field_is_flattened(i)) {
- value = value->as_ValueType()->allocate_fields(kit);
- } else {
+ // Flattened value type field
+ vt->set_field_value(i, value->allocate_fields(kit));
+ } else if (value != NULL){
// Non-flattened value type field
- value = value->as_ValueType()->allocate(kit);
- }
- vt->set_field_value(i, value);
+ vt->set_field_value(i, value->allocate(kit));
}
}
vt = kit->gvn().transform(vt)->as_ValueType();
kit->replace_in_map(this, vt);
return vt;
@@ -640,25 +634,24 @@
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() && field_is_flattened(i)) {
- ciValueKlass* embedded_vk = f_type->as_value_klass();
+ if (field_is_flattened(i)) {
+ // Flattened value type field
edges += arg->as_ValueType()->pass_fields(n, base_input, kit, assert_allocated, 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");
+ ciField* field = base_vk->nonstatic_field_at(j);
+ if (offset == field->offset()) {
+ assert(field->type() == field_type(i), "inconsistent field type");
break;
}
- BasicType bt = f->type()->basic_type();
+ BasicType bt = field->type()->basic_type();
if (bt == T_LONG || bt == T_DOUBLE) {
extra++;
}
}
if (arg->is_ValueType()) {
@@ -667,11 +660,11 @@
assert(!assert_allocated || vt->is_allocated(&kit.gvn()), "value type field should be allocated");
arg = vt->allocate(&kit)->get_oop();
}
n->init_req(base_input + j + extra, arg);
edges++;
- BasicType bt = f_type->basic_type();
+ BasicType bt = field_type(i)->basic_type();
if (bt == T_LONG || bt == T_DOUBLE) {
n->init_req(base_input + j + extra + 1, kit.top());
edges++;
}
}
@@ -680,11 +673,11 @@
}
Node* ValueTypeNode::Ideal(PhaseGVN* phase, bool can_reshape) {
if (!is_allocated(phase)) {
// Check if this value type is loaded from memory
- Node* base = is_loaded(phase, type()->is_valuetype());
+ Node* base = is_loaded(phase);
if (base != NULL) {
// Save the oop
set_oop(base);
assert(is_allocated(phase), "should now be allocated");
return this;
@@ -794,29 +787,29 @@
// Should be dead now
igvn->remove_dead_node(this);
}
-#ifndef PRODUCT
-
-void ValueTypeNode::dump_spec(outputStream* st) const {
- TypeNode::dump_spec(st);
+ValueTypePtrNode* ValueTypePtrNode::make_from_value_type(PhaseGVN& gvn, ValueTypeNode* vt) {
+ ValueTypePtrNode* vtptr = new ValueTypePtrNode(vt->value_klass(), vt->get_oop());
+ for (uint i = Oop+1; i < vt->req(); i++) {
+ vtptr->init_req(i, vt->in(i));
+ }
+ return gvn.transform(vtptr)->as_ValueTypePtr();
}
-#endif
-
-ValueTypePtrNode* ValueTypePtrNode::make(GraphKit* kit, ciValueKlass* vk, CallNode* call) {
- ValueTypePtrNode* vt = new ValueTypePtrNode(vk, kit->zerocon(T_VALUETYPE), kit->C);
+ValueTypePtrNode* ValueTypePtrNode::make_from_call(GraphKit* kit, ciValueKlass* vk, CallNode* call) {
+ ValueTypePtrNode* vtptr = new ValueTypePtrNode(vk, kit->zerocon(T_VALUETYPE));
Node* ctl = kit->control();
- ValueTypeBaseNode::make(&kit->gvn(), ctl, kit->merged_memory(), call, vt, vk, 0, TypeFunc::Parms+1, false);
+ vtptr->initialize(&kit->gvn(), ctl, kit->merged_memory(), call, vk);
kit->set_control(ctl);
- return vt;
+ return vtptr;
}
-ValueTypePtrNode* ValueTypePtrNode::make(PhaseGVN& gvn, Node*& ctl, Node* mem, Node* oop) {
+ValueTypePtrNode* ValueTypePtrNode::make_from_oop(PhaseGVN& gvn, Node*& ctl, Node* mem, Node* oop) {
// Create and initialize a ValueTypePtrNode by loading all field
// values from a heap-allocated version and also save the oop.
- ciValueKlass* vk = gvn.type(oop)->is_valuetypeptr()->value_type()->value_klass();
- ValueTypePtrNode* vtptr = new ValueTypePtrNode(vk, oop, gvn.C);
+ ciValueKlass* vk = gvn.type(oop)->is_valuetypeptr()->value_klass();
+ ValueTypePtrNode* vtptr = new ValueTypePtrNode(vk, oop);
vtptr->load(gvn, ctl, mem, oop, oop, vk);
return vtptr;
}
< prev index next >