< prev index next >

src/share/vm/opto/valuetypenode.cpp

Print this page




  43   for (uint i = 0; i < vt->field_count(); ++i) {
  44     ciType* field_type = vt->field_type(i);
  45     Node* value = NULL;
  46     if (field_type->is_valuetype()) {
  47       value = ValueTypeNode::make_default(gvn, field_type->as_value_klass());
  48     } else {
  49       value = gvn.zerocon(field_type->basic_type());
  50     }
  51     vt->set_field_value(i, value);
  52   }
  53   return gvn.transform(vt);
  54 }
  55 
  56 Node* ValueTypeNode::make(PhaseGVN& gvn, Node* mem, Node* oop) {
  57   // Create and initialize a ValueTypeNode by loading all field
  58   // values from a heap-allocated version and also save the oop.
  59   const TypeValueType* type = gvn.type(oop)->is_valuetypeptr()->value_type();
  60   ValueTypeNode* vt = new ValueTypeNode(type, oop);
  61   vt->load(gvn, mem, oop, oop, type->value_klass());
  62   assert(vt->is_allocated(&gvn), "value type should be allocated");
  63   assert(oop->is_Con() || oop->is_CheckCastPP() || vt->is_loaded(&gvn, type) != NULL, "value type should be loaded");
  64   return gvn.transform(vt);
  65 }
  66 
  67 Node* ValueTypeNode::make(PhaseGVN& gvn, ciValueKlass* vk, Node* mem, Node* obj, Node* ptr, ciInstanceKlass* holder, int holder_offset) {
  68   // Create and initialize a ValueTypeNode by loading all field values from
  69   // a flattened value type field at 'holder_offset' or from a value type array.
  70   ValueTypeNode* vt = make(gvn, vk);
  71   // The value type is flattened into the object without an oop header. Subtract the
  72   // offset of the first field to account for the missing header when loading the values.
  73   holder_offset -= vk->first_field_offset();
  74   vt->load(gvn, mem, obj, ptr, holder, holder_offset);
  75   vt = gvn.transform(vt)->as_ValueType();
  76   assert(!vt->is_allocated(&gvn), "value type should not be allocated");
  77   return vt;
  78 }
  79 
  80 void ValueTypeNode::load(PhaseGVN& gvn, Node* mem, Node* base, Node* ptr, ciInstanceKlass* holder, int holder_offset) {
  81   // Initialize the value type by loading its field values from
  82   // memory and adding the values as input edges to the node.
  83   for (uint i = 0; i < field_count(); ++i) {
  84     int offset = holder_offset + field_offset(i);
  85     ciType* ftype = field_type(i);
  86     Node* value = NULL;
  87     if (ftype->is_valuetype()) {
  88       // Recursively load the flattened value type field
  89       value = ValueTypeNode::make(gvn, ftype->as_value_klass(), mem, base, ptr, holder, offset);
  90     } else {
  91       const Type* con_type = NULL;
  92       if (base->is_Con()) {
  93         // If the oop to the value type is constant (static final field), we can
  94         // also treat the fields as constants because the value type is immutable.
  95         const TypeOopPtr* oop_ptr = base->bottom_type()->isa_oopptr();
  96         ciObject* constant_oop = oop_ptr->const_oop();
  97         ciField* field = holder->get_field_by_offset(offset, false);


 106         const Type* base_type = gvn.type(base);
 107         const TypePtr* adr_type = NULL;
 108         if (base_type->isa_aryptr()) {
 109           // In the case of a flattened value type array, each field
 110           // has its own slice
 111           adr_type = base_type->is_aryptr()->with_field_offset(offset)->add_offset(Type::OffsetBot);
 112         } else {
 113           ciField* field = holder->get_field_by_offset(offset, false);
 114           adr_type = gvn.C->alias_type(field)->adr_type();
 115         }
 116         Node* adr = gvn.transform(new AddPNode(base, ptr, gvn.MakeConX(offset)));
 117         BasicType bt = type2field[ftype->basic_type()];
 118         value = LoadNode::make(gvn, NULL, mem, adr, adr_type, Type::get_const_type(ftype), bt, MemNode::unordered);
 119       }
 120     }
 121     set_field_value(i, gvn.transform(value));
 122   }
 123 }
 124 
 125 Node* ValueTypeNode::is_loaded(PhaseGVN* phase, const TypeValueType* t, Node* base, int holder_offset) {





 126   for (uint i = 0; i < field_count(); ++i) {
 127     int offset = holder_offset + field_offset(i);
 128     Node* value = field_value(i);
 129     if (value->isa_DecodeN()) {
 130       // Skip DecodeN
 131       value = value->in(1);
 132     }
 133     if (value->isa_Load()) {
 134       AddPNode* load_addr = value->in(MemNode::Address)->as_AddP();
 135       if (base == NULL) {
 136         // Set base and check if pointer type matches
 137         base = load_addr->base_node();
 138         const TypeValueTypePtr* vtptr = phase->type(base)->isa_valuetypeptr();
 139         if (vtptr == NULL || !vtptr->value_type()->eq(t)) {
 140           return NULL;
 141         }
 142       }
 143       // Check if base and offset of field load matches
 144       Node* off = load_addr->in(AddPNode::Offset);
 145       int load_offset = LP64_ONLY(off->get_long()) NOT_LP64(off->get_int());


 449       n->init_req(base_input + j + extra, arg);
 450       edges++;
 451       BasicType bt = f_type->basic_type();
 452       if (bt == T_LONG || bt == T_DOUBLE) {
 453         n->init_req(base_input + j + extra + 1, kit.top());
 454         edges++;
 455       }
 456     }
 457   }
 458   return edges;
 459 }
 460 
 461 Node* ValueTypeNode::Ideal(PhaseGVN* phase, bool can_reshape) {
 462   if (!is_allocated(phase)) {
 463     // Check if this value type is loaded from memory
 464     Node* base = is_loaded(phase, type()->is_valuetype());
 465     if (base != NULL) {
 466       // Save the oop
 467       set_oop(base);
 468       assert(is_allocated(phase), "should now be allocated");

 469     }
 470   }
 471 
 472   if (can_reshape) {
 473     PhaseIterGVN* igvn = phase->is_IterGVN();
 474     if (is_allocated(igvn)) {
 475       // Value type is heap allocated, search for safepoint uses
 476       for (DUIterator_Fast imax, i = fast_outs(imax); i < imax; i++) {
 477         Node* out = fast_out(i);
 478         if (out->is_SafePoint()) {
 479           // Let SafePointNode::Ideal() take care of re-wiring the
 480           // safepoint to the oop input instead of the value type node.
 481           igvn->rehash_node_delayed(out);
 482         }
 483       }
 484     }
 485   }
 486   return NULL;
 487 }
 488 




  43   for (uint i = 0; i < vt->field_count(); ++i) {
  44     ciType* field_type = vt->field_type(i);
  45     Node* value = NULL;
  46     if (field_type->is_valuetype()) {
  47       value = ValueTypeNode::make_default(gvn, field_type->as_value_klass());
  48     } else {
  49       value = gvn.zerocon(field_type->basic_type());
  50     }
  51     vt->set_field_value(i, value);
  52   }
  53   return gvn.transform(vt);
  54 }
  55 
  56 Node* ValueTypeNode::make(PhaseGVN& gvn, Node* mem, Node* oop) {
  57   // Create and initialize a ValueTypeNode by loading all field
  58   // values from a heap-allocated version and also save the oop.
  59   const TypeValueType* type = gvn.type(oop)->is_valuetypeptr()->value_type();
  60   ValueTypeNode* vt = new ValueTypeNode(type, oop);
  61   vt->load(gvn, mem, oop, oop, type->value_klass());
  62   assert(vt->is_allocated(&gvn), "value type should be allocated");
  63   assert(oop->is_Con() || oop->is_CheckCastPP() || vt->is_loaded(&gvn, type) == oop, "value type should be loaded");
  64   return gvn.transform(vt);
  65 }
  66 
  67 Node* ValueTypeNode::make(PhaseGVN& gvn, ciValueKlass* vk, Node* mem, Node* obj, Node* ptr, ciInstanceKlass* holder, int holder_offset) {
  68   // Create and initialize a ValueTypeNode by loading all field values from
  69   // a flattened value type field at 'holder_offset' or from a value type array.
  70   ValueTypeNode* vt = make(gvn, vk);
  71   // The value type is flattened into the object without an oop header. Subtract the
  72   // offset of the first field to account for the missing header when loading the values.
  73   holder_offset -= vk->first_field_offset();
  74   vt->load(gvn, mem, obj, ptr, holder, holder_offset);
  75   assert(vt->is_loaded(&gvn, vt->type()->isa_valuetype()) != obj, "holder oop should not be used as flattened value type oop");
  76   return gvn.transform(vt)->as_ValueType();

  77 }
  78 
  79 void ValueTypeNode::load(PhaseGVN& gvn, Node* mem, Node* base, Node* ptr, ciInstanceKlass* holder, int holder_offset) {
  80   // Initialize the value type by loading its field values from
  81   // memory and adding the values as input edges to the node.
  82   for (uint i = 0; i < field_count(); ++i) {
  83     int offset = holder_offset + field_offset(i);
  84     ciType* ftype = field_type(i);
  85     Node* value = NULL;
  86     if (ftype->is_valuetype()) {
  87       // Recursively load the flattened value type field
  88       value = ValueTypeNode::make(gvn, ftype->as_value_klass(), mem, base, ptr, holder, offset);
  89     } else {
  90       const Type* con_type = NULL;
  91       if (base->is_Con()) {
  92         // If the oop to the value type is constant (static final field), we can
  93         // also treat the fields as constants because the value type is immutable.
  94         const TypeOopPtr* oop_ptr = base->bottom_type()->isa_oopptr();
  95         ciObject* constant_oop = oop_ptr->const_oop();
  96         ciField* field = holder->get_field_by_offset(offset, false);


 105         const Type* base_type = gvn.type(base);
 106         const TypePtr* adr_type = NULL;
 107         if (base_type->isa_aryptr()) {
 108           // In the case of a flattened value type array, each field
 109           // has its own slice
 110           adr_type = base_type->is_aryptr()->with_field_offset(offset)->add_offset(Type::OffsetBot);
 111         } else {
 112           ciField* field = holder->get_field_by_offset(offset, false);
 113           adr_type = gvn.C->alias_type(field)->adr_type();
 114         }
 115         Node* adr = gvn.transform(new AddPNode(base, ptr, gvn.MakeConX(offset)));
 116         BasicType bt = type2field[ftype->basic_type()];
 117         value = LoadNode::make(gvn, NULL, mem, adr, adr_type, Type::get_const_type(ftype), bt, MemNode::unordered);
 118       }
 119     }
 120     set_field_value(i, gvn.transform(value));
 121   }
 122 }
 123 
 124 Node* ValueTypeNode::is_loaded(PhaseGVN* phase, const TypeValueType* t, Node* base, int holder_offset) {
 125   if (field_count() == 0) {
 126     assert(t->value_klass() == phase->C->env()->___Value_klass(), "unexpected value type klass");
 127     assert(is_allocated(phase), "must be allocated");
 128     return get_oop();
 129   }
 130   for (uint i = 0; i < field_count(); ++i) {
 131     int offset = holder_offset + field_offset(i);
 132     Node* value = field_value(i);
 133     if (value->isa_DecodeN()) {
 134       // Skip DecodeN
 135       value = value->in(1);
 136     }
 137     if (value->isa_Load()) {
 138       AddPNode* load_addr = value->in(MemNode::Address)->as_AddP();
 139       if (base == NULL) {
 140         // Set base and check if pointer type matches
 141         base = load_addr->base_node();
 142         const TypeValueTypePtr* vtptr = phase->type(base)->isa_valuetypeptr();
 143         if (vtptr == NULL || !vtptr->value_type()->eq(t)) {
 144           return NULL;
 145         }
 146       }
 147       // Check if base and offset of field load matches
 148       Node* off = load_addr->in(AddPNode::Offset);
 149       int load_offset = LP64_ONLY(off->get_long()) NOT_LP64(off->get_int());


 453       n->init_req(base_input + j + extra, arg);
 454       edges++;
 455       BasicType bt = f_type->basic_type();
 456       if (bt == T_LONG || bt == T_DOUBLE) {
 457         n->init_req(base_input + j + extra + 1, kit.top());
 458         edges++;
 459       }
 460     }
 461   }
 462   return edges;
 463 }
 464 
 465 Node* ValueTypeNode::Ideal(PhaseGVN* phase, bool can_reshape) {
 466   if (!is_allocated(phase)) {
 467     // Check if this value type is loaded from memory
 468     Node* base = is_loaded(phase, type()->is_valuetype());
 469     if (base != NULL) {
 470       // Save the oop
 471       set_oop(base);
 472       assert(is_allocated(phase), "should now be allocated");
 473       return this;
 474     }
 475   }
 476 
 477   if (can_reshape) {
 478     PhaseIterGVN* igvn = phase->is_IterGVN();
 479     if (is_allocated(igvn)) {
 480       // Value type is heap allocated, search for safepoint uses
 481       for (DUIterator_Fast imax, i = fast_outs(imax); i < imax; i++) {
 482         Node* out = fast_out(i);
 483         if (out->is_SafePoint()) {
 484           // Let SafePointNode::Ideal() take care of re-wiring the
 485           // safepoint to the oop input instead of the value type node.
 486           igvn->rehash_node_delayed(out);
 487         }
 488       }
 489     }
 490   }
 491   return NULL;
 492 }
 493 


< prev index next >