< prev index next >

src/hotspot/share/opto/valuetypenode.cpp

Print this page

        

*** 45,55 **** // 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 { phi_type = Type::get_const_type(type); value = PhiNode::make(region, value, phi_type); --- 45,55 ---- // 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() && value->isa_ValueType()) { // Handle flattened value type fields recursively value = value->as_ValueType()->clone_with_phis(gvn, region); } else { phi_type = Type::get_const_type(type); value = PhiNode::make(region, value, phi_type);
*** 93,103 **** } // 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(gvn, val2->as_ValueType(), pnum, transform); } else { assert(val1->is_Phi(), "must be a phi node"); assert(!val2->is_ValueType(), "inconsistent merge values"); val1->set_req(pnum, val2); --- 93,103 ---- } // Merge field values for (uint i = 0; i < field_count(); ++i) { Node* val1 = field_value(i); Node* val2 = other->field_value(i); ! if (val1->is_ValueType()) { val1->as_ValueType()->merge_with(gvn, val2->as_ValueType(), pnum, transform); } else { assert(val1->is_Phi(), "must be a phi node"); assert(!val2->is_ValueType(), "inconsistent merge values"); val1->set_req(pnum, val2);
*** 118,128 **** phi->add_req(NULL); assert(phi->req() == region->req(), "must be same size as region"); for (uint i = 0; i < field_count(); ++i) { Node* val = field_value(i); ! if (val->isa_ValueType()) { val->as_ValueType()->add_new_path(region); } else { val->as_Phi()->add_req(NULL); assert(val->req() == region->req(), "must be same size as region"); } --- 118,128 ---- phi->add_req(NULL); assert(phi->req() == region->req(), "must be same size as region"); for (uint i = 0; i < field_count(); ++i) { Node* val = field_value(i); ! if (val->is_ValueType()) { val->as_ValueType()->add_new_path(region); } else { val->as_Phi()->add_req(NULL); assert(val->req() == region->req(), "must be same size as region"); }
*** 162,171 **** --- 162,178 ---- void ValueTypeBaseNode::set_field_value(uint index, Node* value) { assert(index < field_count(), "index out of bounds"); set_req(Values + index, value); } + void ValueTypeBaseNode::set_field_value_by_offset(int offset, Node* value) { + uint i = 0; + for (; i < field_count() && field_offset(i) != offset; i++) { } + assert(i < field_count(), "field not found"); + set_field_value(i, value); + } + int ValueTypeBaseNode::field_offset(uint index) const { assert(index < field_count(), "index out of bounds"); return value_klass()->declared_nonstatic_field_at(index)->offset(); }
*** 283,293 **** parm = gvn.transform(new ProjNode(multi->as_Call(), base_input + j + extra)); } } if (ft->is_valuetype()) { // Non-flattened value type field ! assert(!gvn.type(parm)->is_ptr()->maybe_null(), "should never be null"); parm = ValueTypeNode::make_from_oop(kit, parm, ft->as_value_klass()); } set_field_value(i, parm); // Record all these guys for later GVN. gvn.record_for_igvn(parm); --- 290,300 ---- parm = gvn.transform(new ProjNode(multi->as_Call(), base_input + j + extra)); } } if (ft->is_valuetype()) { // Non-flattened value type field ! assert(!gvn.type(parm)->maybe_null(), "should never be null"); parm = ValueTypeNode::make_from_oop(kit, parm, ft->as_value_klass()); } set_field_value(i, parm); // Record all these guys for later GVN. gvn.record_for_igvn(parm);
*** 346,356 **** --- 353,367 ---- } value = kit->access_load_at(base, adr, adr_type, val_type, bt, decorators); } if (ft->is_valuetype()) { // Loading a non-flattened value type from memory + if (ft->as_value_klass()->is_scalarizable()) { value = ValueTypeNode::make_from_oop(kit, value, ft->as_value_klass(), /* buffer_check */ false, /* null2default */ field_is_flattenable(i), trap_bci); + } else { + value = kit->filter_null(value, field_is_flattenable(i), ft->as_value_klass(), trap_bci); + } } } set_field_value(i, value); } }
*** 371,380 **** --- 382,395 ---- int offset = holder_offset + field_offset(i); Node* value = field_value(i); ciType* ft = field_type(i); if (field_is_flattened(i)) { // 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);
*** 442,452 **** } bool ValueTypeBaseNode::is_allocated(PhaseGVN* phase) const { Node* oop = get_oop(); const Type* oop_type = (phase != NULL) ? phase->type(oop) : oop->bottom_type(); ! return !oop_type->is_ptr()->maybe_null(); } // When a call returns multiple values, it has several result // projections, one per field. Replacing the result of the call by a // value type node (after late inlining) requires that for each result --- 457,467 ---- } bool ValueTypeBaseNode::is_allocated(PhaseGVN* phase) const { Node* oop = get_oop(); const Type* oop_type = (phase != NULL) ? phase->type(oop) : oop->bottom_type(); ! return !oop_type->maybe_null(); } // When a call returns multiple values, it has several result // projections, one per field. Replacing the result of the call by a // value type node (after late inlining) requires that for each result
*** 478,524 **** --i; --imax; } } } ! 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)); } Node* ValueTypeNode::default_oop(PhaseGVN& gvn, ciValueKlass* vk) { // Returns the constant oop of the default value type allocation return gvn.makecon(TypeInstPtr::make(vk->default_value_instance())); } ValueTypeNode* ValueTypeNode::make_default(PhaseGVN& gvn, ciValueKlass* vk) { // Create a new ValueTypeNode with default values ! Node* oop = default_oop(gvn, vk); ! const TypeValueType* type = TypeValueType::make(vk); ! ValueTypeNode* vt = new ValueTypeNode(type, oop); 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); } vt = gvn.transform(vt)->as_ValueType(); assert(vt->is_default(gvn), "must be the default value type"); return vt; } - bool ValueTypeNode::is_default(PhaseGVN& gvn) const { for (uint i = 0; i < field_count(); ++i) { Node* value = field_value(i); if (!gvn.type(value)->is_zero_type() && ! !(value->is_ValueType() && value->as_ValueType()->is_default(gvn))) { return false; } } return true; } --- 493,541 ---- --i; --imax; } } } ! ValueTypeNode* ValueTypeNode::make_uninitialized(PhaseGVN& gvn, ciValueKlass* vk) { // Create a new ValueTypeNode with uninitialized values and NULL oop ! return new ValueTypeNode(vk, gvn.zerocon(T_VALUETYPE)); } Node* ValueTypeNode::default_oop(PhaseGVN& gvn, ciValueKlass* vk) { // Returns the constant oop of the default value type allocation return gvn.makecon(TypeInstPtr::make(vk->default_value_instance())); } ValueTypeNode* ValueTypeNode::make_default(PhaseGVN& gvn, ciValueKlass* vk) { // Create a new ValueTypeNode with default values ! ValueTypeNode* vt = new ValueTypeNode(vk, default_oop(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() && vt->field_is_flattenable(i)) { ! ciValueKlass* field_klass = field_type->as_value_klass(); ! if (field_klass->is_scalarizable() || vt->field_is_flattened(i)) { ! value = ValueTypeNode::make_default(gvn, field_klass); ! } else { ! value = default_oop(gvn, field_klass); ! } } else { value = gvn.zerocon(field_type->basic_type()); } vt->set_field_value(i, value); } vt = gvn.transform(vt)->as_ValueType(); assert(vt->is_default(gvn), "must be the default value type"); return vt; } bool ValueTypeNode::is_default(PhaseGVN& gvn) const { for (uint i = 0; i < field_count(); ++i) { Node* value = field_value(i); if (!gvn.type(value)->is_zero_type() && ! !(value->is_ValueType() && value->as_ValueType()->is_default(gvn)) && ! !(field_type(i)->is_valuetype() && value == default_oop(gvn, field_type(i)->as_value_klass()))) { return false; } } return true; }
*** 528,538 **** const TypePtr* oop_type = gvn.type(oop)->is_ptr(); bool null_check = oop_type->maybe_null(); // Create and initialize a ValueTypeNode by loading all field // values from a heap-allocated version and also save the oop. ! ValueTypeNode* vt = new ValueTypeNode(TypeValueType::make(vk), oop); if (null_check) { // Add a null check because the oop may be null Node* null_ctl = kit->top(); Node* not_null_oop = kit->null_check_oop(oop, &null_ctl); --- 545,555 ---- const TypePtr* oop_type = gvn.type(oop)->is_ptr(); bool null_check = oop_type->maybe_null(); // Create and initialize a ValueTypeNode by loading all field // values from a heap-allocated version and also save the oop. ! ValueTypeNode* vt = new ValueTypeNode(vk, oop); if (null_check) { // Add a null check because the oop may be null Node* null_ctl = kit->top(); Node* not_null_oop = kit->null_check_oop(oop, &null_ctl);
*** 645,655 **** return get_oop(); } for (uint i = 0; i < field_count(); ++i) { int offset = holder_offset + field_offset(i); Node* value = field_value(i); ! if (value->isa_ValueType()) { ValueTypeNode* vt = value->as_ValueType(); if (field_is_flattened(i)) { // Check value type field load recursively base = vt->is_loaded(phase, vk, base, offset - vt->value_klass()->first_field_offset()); if (base == NULL) { --- 662,672 ---- return get_oop(); } for (uint i = 0; i < field_count(); ++i) { int offset = holder_offset + field_offset(i); Node* value = field_value(i); ! if (value->is_ValueType()) { ValueTypeNode* vt = value->as_ValueType(); if (field_is_flattened(i)) { // Check value type field load recursively base = vt->is_loaded(phase, vk, base, offset - vt->value_klass()->first_field_offset()); if (base == NULL) {
*** 801,810 **** --- 818,828 ---- StoreNode* store = addp->fast_out(k)->isa_Store(); if (store != NULL && store->outcnt() != 0) { // Remove the useless store Node* mem = store->in(MemNode::Memory); Node* val = store->in(MemNode::ValueIn); + val = val->is_EncodeP() ? val->in(1) : val; const Type* val_type = igvn->type(val); assert(val_type->is_zero_type() || (val->is_Con() && val_type->make_ptr()->is_valuetypeptr()), "must be zero-type or default value store"); igvn->replace_in_uses(store, mem); }
*** 882,892 **** } // Process users for (DUIterator_Fast imax, i = fast_outs(imax); i < imax; i++) { Node* out = fast_out(i); ! if (out->isa_ValueType() != NULL) { // Recursively process value type users out->as_ValueType()->remove_redundant_allocations(igvn, phase); } else if (out->isa_Allocate() != NULL) { // Allocate users should be linked assert(out->in(AllocateNode::ValueNode) == this, "should be linked"); --- 900,910 ---- } // Process users for (DUIterator_Fast imax, i = fast_outs(imax); i < imax; i++) { Node* out = fast_out(i); ! if (out->is_ValueType()) { // Recursively process value type users out->as_ValueType()->remove_redundant_allocations(igvn, phase); } else if (out->isa_Allocate() != NULL) { // Allocate users should be linked assert(out->in(AllocateNode::ValueNode) == this, "should be linked");
< prev index next >