< prev index next >

src/hotspot/share/opto/graphKit.cpp

Print this page

        

@@ -3409,10 +3409,46 @@
 
   // Return final merged results
   set_control( _gvn.transform(region) );
   record_for_igvn(region);
 
+  bool not_null_free = !toop->can_be_value_type();
+  bool not_flattenable = !ValueArrayFlatten || not_null_free || (toop->is_valuetypeptr() && !toop->value_klass()->flatten_array());
+  if (EnableValhalla && not_flattenable) {
+    // Check if obj has been loaded from an array
+    obj = obj->isa_DecodeN() ? obj->in(1) : obj;
+    Node* array = NULL;
+    if (obj->isa_Load()) {
+      Node* address = obj->in(MemNode::Address);
+      if (address->isa_AddP()) {
+        array = address->as_AddP()->in(AddPNode::Base);
+      }
+    } else if (obj->is_Phi()) {
+      Node* region = obj->in(0);
+      if (region->req() == 3 && region->in(2) != NULL) {
+        IfNode* iff = region->in(2)->in(0)->isa_If();
+        if (iff != NULL) {
+          iff->is_flattened_array_check(&_gvn, array);
+        }
+      }
+    }
+    if (array != NULL) {
+      const TypeAryPtr* ary_t = _gvn.type(array)->isa_aryptr();
+      if (ary_t != NULL) {
+        if (!ary_t->is_not_null_free() && not_null_free) {
+          // Casting array element to a non-inline-type, mark array as not null-free.
+          Node* cast = _gvn.transform(new CheckCastPPNode(control(), array, ary_t->cast_to_not_null_free()));
+          replace_in_map(array, cast);
+        } else if (!ary_t->is_not_flat()) {
+          // Casting array element to a non-flattenable type, mark array as not flat.
+          Node* cast = _gvn.transform(new CheckCastPPNode(control(), array, ary_t->cast_to_not_flat()));
+          replace_in_map(array, cast);
+        }
+      }
+    }
+  }
+
   if (!is_value) {
     res = record_profiled_receiver_for_speculation(res);
     if (toop->is_valuetypeptr() && toop->value_klass()->is_scalarizable() && !gvn().type(res)->maybe_null()) {
       res = ValueTypeNode::make_from_oop(this, res, toop->value_klass());
     }

@@ -3474,14 +3510,14 @@
   }
   return _gvn.transform(new BoolNode(cmp, BoolTest::eq));
 }
 
 // Deoptimize if 'ary' is a null-free value type array and 'val' is null
-void GraphKit::gen_value_array_null_guard(Node* ary, Node* val, int nargs) {
+Node* GraphKit::gen_value_array_null_guard(Node* ary, Node* val, int nargs, bool safe_for_replace) {
   const Type* val_t = _gvn.type(val);
   if (val->is_ValueType() || !TypePtr::NULL_PTR->higher_equal(val_t)) {
-    return; // Never null
+    return ary; // Never null
   }
   RegionNode* region = new RegionNode(3);
   Node* null_ctl = top();
   null_check_oop(val, &null_ctl);
   if (null_ctl != top()) {

@@ -3497,10 +3533,21 @@
     region->init_req(1, control());
   }
   region->init_req(2, control());
   set_control(_gvn.transform(region));
   record_for_igvn(region);
+  const TypeAryPtr* ary_t = _gvn.type(ary)->is_aryptr();
+  if (val_t == TypePtr::NULL_PTR && !ary_t->is_not_null_free()) {
+    // Since we were just successfully storing null, the array can't be null free.
+    ary_t = ary_t->cast_to_not_null_free();
+    Node* cast = _gvn.transform(new CheckCastPPNode(control(), ary, ary_t));
+    if (safe_for_replace) {
+      replace_in_map(ary, cast);
+    }
+    ary = cast;
+  }
+  return ary;
 }
 
 Node* GraphKit::load_lh_array_tag(Node* kls) {
   Node* lhp = basic_plus_adr(kls, in_bytes(Klass::layout_helper_offset()));
   Node* layout_val = _gvn.transform(LoadNode::make(_gvn, NULL, immutable_memory(), lhp, lhp->bottom_type()->is_ptr(), TypeInt::INT, T_INT, MemNode::unordered));
< prev index next >