src/share/vm/opto/valuetypenode.cpp
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File valhalla-experimental Cdiff src/share/vm/opto/valuetypenode.cpp

src/share/vm/opto/valuetypenode.cpp

Print this page

        

*** 57,75 **** void ValueTypeNode::load_values(PhaseGVN& gvn, Node* mem, ciInstanceKlass* holder, Node* base, int base_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 = base_offset + get_field_offset(i); Node* adr = gvn.transform(new AddPNode(base, base, gvn.longcon(offset))); ciField* field = holder->get_field_by_offset(offset, false); const TypePtr* adr_type = gvn.C->alias_type(field)->adr_type(); Node* value = NULL; ! ciType* field_type = get_field_type(i); ! if (field_type->is_valuetype()) { // Recursively load the flattened value type field ! value = ValueTypeNode::make(gvn, field_type->as_value_klass(), mem, holder, base, 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. --- 57,75 ---- void ValueTypeNode::load_values(PhaseGVN& gvn, Node* mem, ciInstanceKlass* holder, Node* base, int base_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 = base_offset + field_offset(i); Node* adr = gvn.transform(new AddPNode(base, base, gvn.longcon(offset))); ciField* field = holder->get_field_by_offset(offset, false); const TypePtr* adr_type = gvn.C->alias_type(field)->adr_type(); Node* value = NULL; ! ciType* f_type = field_type(i); ! if (f_type->is_valuetype()) { // Recursively load the flattened value type field ! value = ValueTypeNode::make(gvn, f_type->as_value_klass(), mem, holder, base, 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.
*** 81,91 **** if (con_type != NULL) { // Found a constant field value value = gvn.makecon(con_type); } else { // Load field value from memory ! value = LoadNode::make(gvn, NULL, mem, adr, adr_type, Type::get_const_type(field_type), field_type->basic_type(), MemNode::unordered); } } set_field_value(i, gvn.transform(value)); } } --- 81,91 ---- if (con_type != NULL) { // Found a constant field value value = gvn.makecon(con_type); } else { // Load field value from memory ! 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)); } }
*** 98,117 **** } void ValueTypeNode::store_values(GraphKit* kit, ciInstanceKlass* holder, Node* base, int base_offset) const { // Write field values to memory for (uint i = 0; i < field_count(); ++i) { ! int offset = base_offset + get_field_offset(i); Node* adr = kit->basic_plus_adr(base, base, offset); ciField* field = holder->get_field_by_offset(offset, false); const TypePtr* adr_type = kit->C->alias_type(field)->adr_type(); ! Node* value = get_field_value(i); if (value->is_ValueType()) { // Recursively store the flattened value type field value->isa_ValueType()->store_to_field(kit, holder, base, offset); } else { ! kit->store_to_memory(kit->control(), adr, value, get_field_type(i)->basic_type(), adr_type, MemNode::unordered); } } } Node* ValueTypeNode::store_to_memory(GraphKit* kit) { --- 98,117 ---- } void ValueTypeNode::store_values(GraphKit* kit, ciInstanceKlass* holder, Node* base, int base_offset) const { // Write field values to memory for (uint i = 0; i < field_count(); ++i) { ! int offset = base_offset + field_offset(i); Node* adr = kit->basic_plus_adr(base, base, offset); ciField* field = holder->get_field_by_offset(offset, false); const TypePtr* adr_type = kit->C->alias_type(field)->adr_type(); ! Node* value = field_value(i); if (value->is_ValueType()) { // Recursively store the flattened value type field value->isa_ValueType()->store_to_field(kit, holder, base, offset); } else { ! kit->store_to_memory(kit->control(), adr, value, field_type(i)->basic_type(), adr_type, MemNode::unordered); } } } Node* ValueTypeNode::store_to_memory(GraphKit* kit) {
*** 183,194 **** gvn.set_type(oop, vtptr); 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->get_field_type(i); ! Node* value = vt->get_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); --- 183,194 ---- gvn.set_type(oop, vtptr); 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);
*** 208,218 **** bool result = get_oop()->is_Phi() && get_oop()->as_Phi()->region() == region; #ifdef ASSERT if (result) { // Check all field value inputs for consistency for (uint i = 0; i < field_count(); ++i) { ! Node* value = get_field_value(i); if (value->is_ValueType()) { assert(value->as_ValueType()->has_phi_inputs(region), "inconsistent phi inputs"); } else { assert(value->is_Phi() && value->as_Phi()->region() == region, "inconsistent phi inputs"); } --- 208,218 ---- bool result = get_oop()->is_Phi() && get_oop()->as_Phi()->region() == region; #ifdef ASSERT if (result) { // Check all field value inputs for consistency for (uint i = 0; i < field_count(); ++i) { ! Node* value = field_value(i); if (value->is_ValueType()) { assert(value->as_ValueType()->has_phi_inputs(region), "inconsistent phi inputs"); } else { assert(value->is_Phi() && value->as_Phi()->region() == region, "inconsistent phi inputs"); }
*** 232,243 **** set_oop(kit->gvn().transform_no_reclaim(phi)); kit->record_for_igvn(phi); } // Merge field values for (uint i = 0; i < field_count(); ++i) { ! Node* val1 = get_field_value(i); ! Node* val2 = other->get_field_value(i); if (val1->isa_ValueType()) { val1->as_ValueType()->merge_with(kit, val2->as_ValueType(), pnum); } else { assert(!val2->is_ValueType(), "inconsistent merge values"); val1->set_req(pnum, val2); --- 232,243 ---- set_oop(kit->gvn().transform_no_reclaim(phi)); kit->record_for_igvn(phi); } // 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(kit, val2->as_ValueType(), pnum); } else { assert(!val2->is_ValueType(), "inconsistent merge values"); val1->set_req(pnum, val2);
*** 254,281 **** return kit->gvn().transform_no_reclaim(this); } return this; } ! Node* ValueTypeNode::get_field_value(uint index) const { assert(index < field_count(), "index out of bounds"); return in(Values + index); } // Get the value of the field at the given offset. // If 'recursive' is true, flattened value type fields will be resolved recursively. ! Node* ValueTypeNode::get_field_value_by_offset(int offset, bool recursive) const { // If the field at 'offset' belongs to a flattened value type field, 'index' refers to the // corresponding ValueTypeNode input and 'sub_offset' is the offset in flattened value type. int index = value_klass()->field_index_by_offset(offset); ! int sub_offset = offset - get_field_offset(index); ! Node* value = get_field_value(index); if (recursive && value->is_ValueType()) { // Flattened value type field ValueTypeNode* vt = value->as_ValueType(); sub_offset += vt->value_klass()->first_field_offset(); // Add header size ! return vt->get_field_value_by_offset(sub_offset); } assert(!(recursive && value->is_ValueType()), "should not be a value type"); assert(sub_offset == 0, "offset mismatch"); return value; } --- 254,281 ---- return kit->gvn().transform_no_reclaim(this); } return this; } ! Node* ValueTypeNode::field_value(uint index) const { assert(index < field_count(), "index out of bounds"); return in(Values + index); } // Get the value of the field at the given offset. // If 'recursive' is true, flattened value type fields will be resolved recursively. ! Node* ValueTypeNode::field_value_by_offset(int offset, bool recursive) const { // If the field at 'offset' belongs to a flattened value type field, 'index' refers to the // corresponding ValueTypeNode input and 'sub_offset' is the offset in flattened value type. int index = value_klass()->field_index_by_offset(offset); ! int sub_offset = offset - field_offset(index); ! Node* value = field_value(index); if (recursive && value->is_ValueType()) { // Flattened value type field ValueTypeNode* vt = value->as_ValueType(); sub_offset += vt->value_klass()->first_field_offset(); // Add header size ! return vt->field_value_by_offset(sub_offset); } assert(!(recursive && value->is_ValueType()), "should not be a value type"); assert(sub_offset == 0, "offset mismatch"); return value; }
*** 283,298 **** void ValueTypeNode::set_field_value(uint index, Node* value) { assert(index < field_count(), "index out of bounds"); set_req(Values + index, value); } ! int ValueTypeNode::get_field_offset(uint index) const { assert(index < field_count(), "index out of bounds"); return value_klass()->field_offset_by_index(index); } ! ciType* ValueTypeNode::get_field_type(uint index) const { assert(index < field_count(), "index out of bounds"); return value_klass()->field_type_by_index(index); } void ValueTypeNode::make_scalar_in_safepoints(Compile* C) { --- 283,298 ---- void ValueTypeNode::set_field_value(uint index, Node* value) { assert(index < field_count(), "index out of bounds"); set_req(Values + index, value); } ! int ValueTypeNode::field_offset(uint index) const { assert(index < field_count(), "index out of bounds"); return value_klass()->field_offset_by_index(index); } ! ciType* ValueTypeNode::field_type(uint index) const { assert(index < field_count(), "index out of bounds"); return value_klass()->field_type_by_index(index); } void ValueTypeNode::make_scalar_in_safepoints(Compile* C) {
*** 324,334 **** sobj->init_req(0, C->root()); // Iterate over the value type fields in order of increasing // offset and add the field values to the safepoint. for (uint j = 0; j < nfields; ++j) { int offset = vk->nonstatic_field_at(j)->offset(); ! Node* value = get_field_value_by_offset(offset, true /* include flattened value type fields */); sfpt->add_req(value); } jvms->set_endoff(sfpt->req()); int nb = sfpt->replace_edges_in_range(this, sobj, start, end); --i; imax -= nb; --- 324,334 ---- sobj->init_req(0, C->root()); // Iterate over the value type fields in order of increasing // offset and add the field values to the safepoint. for (uint j = 0; j < nfields; ++j) { int offset = vk->nonstatic_field_at(j)->offset(); ! Node* value = field_value_by_offset(offset, true /* include flattened value type fields */); sfpt->add_req(value); } jvms->set_endoff(sfpt->req()); int nb = sfpt->replace_edges_in_range(this, sobj, start, end); --i; imax -= nb;
*** 342,373 **** if (base_vk == NULL) { base_vk = vk; } uint edges = 0; for (uint i = 0; i < field_count(); i++) { ! ciType* field_type = get_field_type(i); ! int offset = base_offset + get_field_offset(i) - (base_offset > 0 ? vk->first_field_offset() : 0); ! Node* arg = get_field_value(i); ! if (field_type->is_valuetype()) { ! ciValueKlass* embedded_vk = field_type->as_value_klass(); edges += arg->as_ValueType()->set_arguments_for_java_call(call, base_input, kit, 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() == field_type, "inconsistent field type"); break; } BasicType bt = f->type()->basic_type(); if (bt == T_LONG || bt == T_DOUBLE) { extra++; } } call->init_req(base_input + j + extra, arg); edges++; ! BasicType bt = field_type->basic_type(); if (bt == T_LONG || bt == T_DOUBLE) { call->init_req(base_input + j + extra + 1, kit.top()); edges++; } } --- 342,373 ---- 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()) { ! ciValueKlass* embedded_vk = f_type->as_value_klass(); edges += arg->as_ValueType()->set_arguments_for_java_call(call, base_input, kit, 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"); break; } BasicType bt = f->type()->basic_type(); if (bt == T_LONG || bt == T_DOUBLE) { extra++; } } call->init_req(base_input + j + extra, arg); edges++; ! BasicType bt = f_type->basic_type(); if (bt == T_LONG || bt == T_DOUBLE) { call->init_req(base_input + j + extra + 1, kit.top()); edges++; } }
src/share/vm/opto/valuetypenode.cpp
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File