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