< prev index next >

src/hotspot/share/opto/valuetypenode.cpp

Print this page

        

@@ -45,11 +45,11 @@
 
   // 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()) {
+    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,11 +93,11 @@
   }
   // 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()) {
+    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,11 +118,11 @@
   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()) {
+    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,10 +162,17 @@
 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,11 +290,11 @@
           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");
+        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,11 +353,15 @@
         }
         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,10 +382,14 @@
     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,11 +457,11 @@
 }
 
 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();
+  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,47 +493,49 @@
       --i; --imax;
     }
   }
 }
 
-ValueTypeNode* ValueTypeNode::make_uninitialized(PhaseGVN& gvn, ciValueKlass* klass) {
+ValueTypeNode* ValueTypeNode::make_uninitialized(PhaseGVN& gvn, ciValueKlass* vk) {
   // Create a new ValueTypeNode with uninitialized values and NULL oop
-  const TypeValueType* type = TypeValueType::make(klass);
-  return new ValueTypeNode(type, gvn.zerocon(T_VALUETYPE));
+  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
-  Node* oop = default_oop(gvn, vk);
-  const TypeValueType* type = TypeValueType::make(vk);
-  ValueTypeNode* vt = new ValueTypeNode(type, oop);
+  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()) {
-      value = ValueTypeNode::make_default(gvn, field_type->as_value_klass());
+    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))) {
+        !(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,11 +545,11 @@
   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);
+  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,11 +662,11 @@
     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()) {
+    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,10 +818,11 @@
                 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,11 +900,11 @@
   }
 
   // Process users
   for (DUIterator_Fast imax, i = fast_outs(imax); i < imax; i++) {
     Node* out = fast_out(i);
-    if (out->isa_ValueType() != NULL) {
+    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 >