< prev index next >

src/share/vm/opto/valuetypenode.cpp

Print this page

        

*** 53,190 **** } Node* ValueTypeNode::make(PhaseGVN& gvn, Node* mem, Node* oop) { // Create and initialize a ValueTypeNode by loading all field // values from a heap-allocated version and also save the oop. ! const TypeValueTypePtr* vtptr = gvn.type(oop)->is_valuetypeptr(); ! ValueTypeNode* vt = new ValueTypeNode(vtptr->value_type(), oop); ! vt->load_values(gvn, mem, oop, oop); return gvn.transform(vt); } ! Node* ValueTypeNode::make(PhaseGVN& gvn, ciValueKlass* vk, Node* mem, Node* obj, Node* ptr, ciKlass* holder, int field_offset) { // Create and initialize a ValueTypeNode by loading all field values from ! // a flattened value type field at 'field_offset' or from a value type array. ValueTypeNode* vt = make(gvn, vk); - int base_offset = 0; - if (holder->is_value_array_klass()) { - assert(field_offset == 0, "field offset not supported for arrays"); - } else { // 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. ! base_offset = field_offset - vk->first_field_offset(); ! } ! vt->load_values(gvn, mem, obj, ptr, holder, base_offset); return gvn.transform(vt); } ! void ValueTypeNode::load_values(PhaseGVN& gvn, Node* mem, Node* base, Node* ptr, ciKlass* holder, int f_offset) { ! ciInstanceKlass* lookup; ! if (holder) { ! // Flattened ! if (holder->is_value_array_klass()) { ! lookup = value_klass(); ! } else { ! lookup = holder->as_instance_klass(); ! } ! } else { ! // Not flattened ! assert(f_offset == 0, "must be"); ! lookup = value_klass(); ! } // 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 = f_offset + field_offset(i); ! ciField* field = lookup->get_field_by_offset(offset, false); ! ciType* f_type = field_type(i); Node* value = NULL; ! if (f_type->is_valuetype()) { ! if (holder && holder->is_value_array_klass()) { ! offset -= value_klass()->first_field_offset(); ! } // Recursively load the flattened value type field ! value = ValueTypeNode::make(gvn, f_type->as_value_klass(), mem, base, ptr, lookup, 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. const TypeOopPtr* oop_ptr = base->bottom_type()->isa_oopptr(); ciObject* constant_oop = oop_ptr->const_oop(); ciConstant constant = constant_oop->as_instance()->field_value(field); con_type = Type::make_from_constant(constant, /*require_const=*/ true); } if (con_type != NULL) { // Found a constant field value value = gvn.makecon(con_type); } else { // Load field value from memory - if (holder && holder->is_value_array_klass()) { - offset -= value_klass()->first_field_offset(); - } const Type* base_type = gvn.type(base); const TypePtr* adr_type = NULL; if (base_type->isa_aryptr()) { // 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); } else { adr_type = gvn.C->alias_type(field)->adr_type(); } Node* adr = gvn.transform(new AddPNode(base, ptr, gvn.MakeConX(offset))); ! 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)); } } ! void ValueTypeNode::store_to_field(GraphKit* kit, Node* obj, Node* ptr, ciInstanceKlass* instance_type, int field_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. ! int base_offset = field_offset - value_klass()->first_field_offset(); ! store_values(kit, obj, ptr, instance_type, base_offset); } ! void ValueTypeNode::store_values(GraphKit* kit, Node* base, Node* ptr, ciKlass* holder, int holder_offset) const { ! ciInstanceKlass* lookup; ! if (holder) { ! // flattened ! if (holder->is_value_array_klass()) { ! assert(holder_offset == 0, "must be"); ! lookup = value_klass(); ! } else { ! lookup = holder->as_instance_klass(); ! } ! } else { ! // not flattened ! assert(holder_offset == 0, "must be"); ! lookup = value_klass(); ! } // 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()) { // Recursively store the flattened value type field ! if (holder && holder->is_value_array_klass()) { ! offset -= value_klass()->first_field_offset(); ! } ! value->isa_ValueType()->store_to_field(kit, base, ptr, lookup, offset); } else { - if (holder && holder->is_value_array_klass()) { - offset -= value_klass()->first_field_offset(); - } const Type* base_type = kit->gvn().type(base); const TypePtr* adr_type = NULL; if (base_type->isa_aryptr()) { ! // 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); } else { ! ciField* field = lookup->get_field_by_offset(offset, false); adr_type = kit->C->alias_type(field)->adr_type(); } Node* adr = kit->basic_plus_adr(base, ptr, offset); kit->store_to_memory(kit->control(), adr, value, field_type(i)->basic_type(), adr_type, MemNode::unordered); } --- 53,146 ---- } Node* ValueTypeNode::make(PhaseGVN& gvn, Node* mem, Node* oop) { // 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); ! vt->load_values(gvn, mem, oop, oop, type->value_klass()); return gvn.transform(vt); } ! Node* ValueTypeNode::make(PhaseGVN& gvn, ciValueKlass* vk, 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); // 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_values(gvn, mem, obj, ptr, holder, holder_offset); return gvn.transform(vt); } ! void ValueTypeNode::load_values(PhaseGVN& gvn, 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()) { // Recursively load the flattened value type field ! value = ValueTypeNode::make(gvn, ftype->as_value_klass(), 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. const TypeOopPtr* oop_ptr = base->bottom_type()->isa_oopptr(); ciObject* constant_oop = oop_ptr->const_oop(); + ciField* field = holder->get_field_by_offset(offset, false); ciConstant constant = constant_oop->as_instance()->field_value(field); con_type = Type::make_from_constant(constant, /*require_const=*/ true); } if (con_type != NULL) { // Found a constant field value value = gvn.makecon(con_type); } else { // Load field value from memory const Type* base_type = gvn.type(base); const TypePtr* adr_type = NULL; if (base_type->isa_aryptr()) { // 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); } 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))); ! value = LoadNode::make(gvn, NULL, mem, adr, adr_type, Type::get_const_type(ftype), ftype->basic_type(), MemNode::unordered); } } set_field_value(i, gvn.transform(value)); } } ! void ValueTypeNode::store(GraphKit* kit, Node* obj, 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. ! holder_offset -= value_klass()->first_field_offset(); ! store_values(kit, obj, ptr, holder, holder_offset); } ! void ValueTypeNode::store_values(GraphKit* kit, Node* base, Node* ptr, ciInstanceKlass* holder, int holder_offset) 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); if (value->is_ValueType()) { // Recursively store the flattened value type field ! value->isa_ValueType()->store(kit, base, ptr, value_klass(), offset); } else { const Type* base_type = kit->gvn().type(base); const TypePtr* adr_type = NULL; if (base_type->isa_aryptr()) { ! // 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); } 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); kit->store_to_memory(kit->control(), adr, value, field_type(i)->basic_type(), adr_type, MemNode::unordered); }
*** 221,237 **** mem ->init_req(1, kit->merged_memory()); // Oop is NULL, allocate value type kit->set_control(null_ctl); kit->kill_dead_locals(); ! Node* klass_node = kit->makecon(TypeKlassPtr::make(value_klass())); Node* alloc_oop = kit->new_instance(klass_node); AllocateNode* alloc = AllocateNode::Ideal_allocation(alloc_oop, &kit->gvn()); // TODO enable/fix this // alloc->initialization()->set_complete_with_arraycopy(); // Write field values to memory ! store_values(kit, alloc_oop, alloc_oop); region->init_req(2, kit->control()); oop ->init_req(2, alloc_oop); io ->init_req(2, kit->i_o()); mem ->init_req(2, kit->merged_memory()); --- 177,194 ---- mem ->init_req(1, kit->merged_memory()); // Oop is NULL, allocate value type kit->set_control(null_ctl); kit->kill_dead_locals(); ! ciValueKlass* vk = value_klass(); ! Node* klass_node = kit->makecon(TypeKlassPtr::make(vk)); Node* alloc_oop = kit->new_instance(klass_node); AllocateNode* alloc = AllocateNode::Ideal_allocation(alloc_oop, &kit->gvn()); // TODO enable/fix this // alloc->initialization()->set_complete_with_arraycopy(); // Write field values to memory ! store_values(kit, alloc_oop, alloc_oop, vk); region->init_req(2, kit->control()); oop ->init_req(2, alloc_oop); io ->init_req(2, kit->i_o()); mem ->init_req(2, kit->merged_memory());
< prev index next >