< prev index next >
src/hotspot/share/opto/valuetypenode.cpp
Print this page
*** 313,347 ****
}
}
base_input += vk->value_arg_slots();
}
! const TypePtr* ValueTypeBaseNode::field_adr_type(Node* base, int offset, ciInstanceKlass* holder, PhaseGVN& gvn) const {
const TypeAryPtr* ary_type = gvn.type(base)->isa_aryptr();
const TypePtr* adr_type = NULL;
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 = ary_type->with_field_offset(offset)->add_offset(Type::OffsetBot);
} else {
ciField* field = holder->get_field_by_offset(offset, false);
assert(field != NULL, "field not found");
adr_type = gvn.C->alias_type(field)->adr_type();
}
return adr_type;
}
! void ValueTypeBaseNode::load(GraphKit* kit, 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);
Node* value = NULL;
ciType* ft = field_type(i);
if (field_is_flattened(i)) {
// Recursively load the flattened value type field
! value = ValueTypeNode::make_from_flattened(kit, ft->as_value_klass(), base, ptr, holder, offset);
} else {
const TypeOopPtr* oop_ptr = kit->gvn().type(base)->isa_oopptr();
bool is_array = (oop_ptr->isa_aryptr() != NULL);
if (base->is_Con() && !is_array) {
// If the oop to the value type is constant (static final field), we can
--- 313,349 ----
}
}
base_input += vk->value_arg_slots();
}
! const TypePtr* ValueTypeBaseNode::field_adr_type(Node* base, int offset, ciInstanceKlass* holder, DecoratorSet decorators, PhaseGVN& gvn) const {
const TypeAryPtr* ary_type = gvn.type(base)->isa_aryptr();
const TypePtr* adr_type = NULL;
bool is_array = ary_type != NULL;
! if ((decorators & C2_MISMATCHED) != 0) {
! adr_type = TypeRawPtr::BOTTOM;
! } else if (is_array) {
// In the case of a flattened value type array, each field has its own slice
adr_type = ary_type->with_field_offset(offset)->add_offset(Type::OffsetBot);
} else {
ciField* field = holder->get_field_by_offset(offset, false);
assert(field != NULL, "field not found");
adr_type = gvn.C->alias_type(field)->adr_type();
}
return adr_type;
}
! void ValueTypeBaseNode::load(GraphKit* kit, Node* base, Node* ptr, ciInstanceKlass* holder, int holder_offset, DecoratorSet decorators) {
// 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);
Node* value = NULL;
ciType* ft = field_type(i);
if (field_is_flattened(i)) {
// Recursively load the flattened value type field
! value = ValueTypeNode::make_from_flattened(kit, ft->as_value_klass(), base, ptr, holder, offset, decorators);
} else {
const TypeOopPtr* oop_ptr = kit->gvn().type(base)->isa_oopptr();
bool is_array = (oop_ptr->isa_aryptr() != NULL);
if (base->is_Con() && !is_array) {
// If the oop to the value type is constant (static final field), we can
*** 353,368 ****
const Type* con_type = Type::make_from_constant(constant, /*require_const=*/ true);
assert(con_type != NULL, "type not found");
value = kit->gvn().transform(kit->makecon(con_type));
} else {
// Load field value from memory
! const TypePtr* adr_type = field_adr_type(base, offset, holder, kit->gvn());
Node* adr = kit->basic_plus_adr(base, ptr, offset);
BasicType bt = type2field[ft->basic_type()];
assert(is_java_primitive(bt) || adr->bottom_type()->is_ptr_to_narrowoop() == UseCompressedOops, "inconsistent");
const Type* val_type = Type::get_const_type(ft);
- DecoratorSet decorators = IN_HEAP | MO_UNORDERED;
if (is_array) {
decorators |= IS_ARRAY;
}
value = kit->access_load_at(base, adr, adr_type, val_type, bt, decorators);
}
--- 355,369 ----
const Type* con_type = Type::make_from_constant(constant, /*require_const=*/ true);
assert(con_type != NULL, "type not found");
value = kit->gvn().transform(kit->makecon(con_type));
} else {
// Load field value from memory
! const TypePtr* adr_type = field_adr_type(base, offset, holder, decorators, kit->gvn());
Node* adr = kit->basic_plus_adr(base, ptr, offset);
BasicType bt = type2field[ft->basic_type()];
assert(is_java_primitive(bt) || adr->bottom_type()->is_ptr_to_narrowoop() == UseCompressedOops, "inconsistent");
const Type* val_type = Type::get_const_type(ft);
if (is_array) {
decorators |= IS_ARRAY;
}
value = kit->access_load_at(base, adr, adr_type, val_type, bt, decorators);
}
*** 377,397 ****
}
set_field_value(i, value);
}
}
! void ValueTypeBaseNode::store_flattened(GraphKit* kit, Node* base, Node* ptr, ciInstanceKlass* holder, int holder_offset) const {
// The value type is embedded into the object without an oop header. Subtract the
// offset of the first field to account for the missing header when storing the values.
if (holder == NULL) {
holder = value_klass();
}
holder_offset -= value_klass()->first_field_offset();
! store(kit, base, ptr, holder, holder_offset);
}
! void ValueTypeBaseNode::store(GraphKit* kit, Node* base, Node* ptr, ciInstanceKlass* holder, int holder_offset, bool deoptimize_on_exception) const {
// 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);
ciType* ft = field_type(i);
--- 378,398 ----
}
set_field_value(i, value);
}
}
! void ValueTypeBaseNode::store_flattened(GraphKit* kit, Node* base, Node* ptr, ciInstanceKlass* holder, int holder_offset, DecoratorSet decorators) const {
// The value type is embedded into the object without an oop header. Subtract the
// offset of the first field to account for the missing header when storing the values.
if (holder == NULL) {
holder = value_klass();
}
holder_offset -= value_klass()->first_field_offset();
! store(kit, base, ptr, holder, holder_offset, false, decorators);
}
! void ValueTypeBaseNode::store(GraphKit* kit, Node* base, Node* ptr, ciInstanceKlass* holder, int holder_offset, bool deoptimize_on_exception, DecoratorSet decorators) const {
// 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);
ciType* ft = field_type(i);
*** 399,418 ****
// 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);
BasicType bt = type2field[ft->basic_type()];
assert(is_java_primitive(bt) || adr->bottom_type()->is_ptr_to_narrowoop() == UseCompressedOops, "inconsistent");
const Type* val_type = Type::get_const_type(ft);
const TypeAryPtr* ary_type = kit->gvn().type(base)->isa_aryptr();
- DecoratorSet decorators = IN_HEAP | MO_UNORDERED;
if (ary_type != NULL) {
decorators |= IS_ARRAY;
}
kit->access_store_at(base, adr, adr_type, value, val_type, bt, decorators, deoptimize_on_exception);
}
--- 400,418 ----
// 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, decorators);
} else {
// Store field value to memory
! const TypePtr* adr_type = field_adr_type(base, offset, holder, decorators, kit->gvn());
Node* adr = kit->basic_plus_adr(base, ptr, offset);
BasicType bt = type2field[ft->basic_type()];
assert(is_java_primitive(bt) || adr->bottom_type()->is_ptr_to_narrowoop() == UseCompressedOops, "inconsistent");
const Type* val_type = Type::get_const_type(ft);
const TypeAryPtr* ary_type = kit->gvn().type(base)->isa_aryptr();
if (ary_type != NULL) {
decorators |= IS_ARRAY;
}
kit->access_store_at(base, adr, adr_type, value, val_type, bt, decorators, deoptimize_on_exception);
}
*** 601,628 ****
assert(vt->is_allocated(&gvn), "value type should be allocated");
return gvn.transform(vt)->as_ValueType();
}
// 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) {
// 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_uninitialized(kit->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(kit, obj, ptr, holder, holder_offset);
assert(vt->is_loaded(&kit->gvn()) != obj, "holder oop should not be used as flattened value type oop");
return kit->gvn().transform(vt)->as_ValueType();
}
ValueTypeNode* ValueTypeNode::make_from_multi(GraphKit* kit, MultiNode* multi, ciValueKlass* vk, uint& base_input, bool in) {
ValueTypeNode* vt = ValueTypeNode::make_uninitialized(kit->gvn(), vk);
vt->initialize(kit, multi, vk, 0, base_input, in);
return kit->gvn().transform(vt)->as_ValueType();
}
Node* ValueTypeNode::is_loaded(PhaseGVN* phase, ciValueKlass* vk, Node* base, int holder_offset) {
if (vk == NULL) {
vk = value_klass();
}
if (field_count() == 0) {
--- 601,659 ----
assert(vt->is_allocated(&gvn), "value type should be allocated");
return gvn.transform(vt)->as_ValueType();
}
// 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, DecoratorSet decorators) {
// 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_uninitialized(kit->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(kit, obj, ptr, holder, holder_offset, decorators);
assert(vt->is_loaded(&kit->gvn()) != obj, "holder oop should not be used as flattened value type oop");
return kit->gvn().transform(vt)->as_ValueType();
}
ValueTypeNode* ValueTypeNode::make_from_multi(GraphKit* kit, MultiNode* multi, ciValueKlass* vk, uint& base_input, bool in) {
ValueTypeNode* vt = ValueTypeNode::make_uninitialized(kit->gvn(), vk);
vt->initialize(kit, multi, vk, 0, base_input, in);
return kit->gvn().transform(vt)->as_ValueType();
}
+ ValueTypeNode* ValueTypeNode::make_larval(GraphKit* kit, bool allocate) const {
+ ciValueKlass* vk = value_klass();
+ ValueTypeNode* res = clone()->as_ValueType();
+ if (allocate) {
+ Node* klass_node = kit->makecon(TypeKlassPtr::make(vk));
+ Node* alloc_oop = kit->new_instance(klass_node, NULL, NULL, false);
+ AllocateNode* alloc = AllocateNode::Ideal_allocation(alloc_oop, &kit->gvn());
+ alloc->_larval = true;
+
+ store(kit, alloc_oop, alloc_oop, vk, 0, false);
+ res->set_oop(alloc_oop);
+ }
+ res->set_type(TypeValueType::make(vk, true));
+ res = kit->gvn().transform(res)->as_ValueType();
+ return res;
+ }
+
+ ValueTypeNode* ValueTypeNode::finish_larval(GraphKit* kit) const {
+ Node* obj = get_oop();
+ Node* mark_addr = kit->basic_plus_adr(obj, oopDesc::mark_offset_in_bytes());
+ Node* mark = kit->make_load(NULL, mark_addr, TypeX_X, TypeX_X->basic_type(), MemNode::unordered);
+ mark = kit->gvn().transform(new AndXNode(mark, kit->MakeConX(~markOopDesc::larval_mask_in_place)));
+ kit->store_to_memory(kit->control(), mark_addr, mark, TypeX_X->basic_type(), kit->gvn().type(mark_addr)->is_ptr(), MemNode::unordered);
+
+ ciValueKlass* vk = value_klass();
+ ValueTypeNode* res = clone()->as_ValueType();
+ res->set_type(TypeValueType::make(vk, false));
+ res = kit->gvn().transform(res)->as_ValueType();
+ return res;
+ }
+
Node* ValueTypeNode::is_loaded(PhaseGVN* phase, ciValueKlass* vk, Node* base, int holder_offset) {
if (vk == NULL) {
vk = value_klass();
}
if (field_count() == 0) {
< prev index next >