hotspot/src/share/vm/opto/memnode.cpp
changeset 38030 93f24e7b3c43
parent 38017 55047d16f141
child 38033 996ce936543f
--- a/hotspot/src/share/vm/opto/memnode.cpp	Mon Apr 11 21:42:31 2016 +0300
+++ b/hotspot/src/share/vm/opto/memnode.cpp	Mon Apr 11 21:42:55 2016 +0300
@@ -796,7 +796,7 @@
 #endif
     {
       assert(!adr->bottom_type()->is_ptr_to_narrowoop() && !adr->bottom_type()->is_ptr_to_narrowklass(), "should have got back a narrow oop");
-      load = new LoadPNode(ctl, mem, adr, adr_type, rt->is_oopptr(), mo, control_dependency);
+      load = new LoadPNode(ctl, mem, adr, adr_type, rt->is_ptr(), mo, control_dependency);
     }
     break;
   }
@@ -1620,72 +1620,6 @@
   return NULL;
 }
 
-static ciConstant check_mismatched_access(ciConstant con, BasicType loadbt, bool is_unsigned) {
-  BasicType conbt = con.basic_type();
-  switch (conbt) {
-    case T_BOOLEAN: conbt = T_BYTE;   break;
-    case T_ARRAY:   conbt = T_OBJECT; break;
-  }
-  switch (loadbt) {
-    case T_BOOLEAN:   loadbt = T_BYTE;   break;
-    case T_NARROWOOP: loadbt = T_OBJECT; break;
-    case T_ARRAY:     loadbt = T_OBJECT; break;
-    case T_ADDRESS:   loadbt = T_OBJECT; break;
-  }
-  if (conbt == loadbt) {
-    if (is_unsigned && conbt == T_BYTE) {
-      // LoadB (T_BYTE) with a small mask (<=8-bit) is converted to LoadUB (T_BYTE).
-      return ciConstant(T_INT, con.as_int() & 0xFF);
-    } else {
-      return con;
-    }
-  }
-  if (conbt == T_SHORT && loadbt == T_CHAR) {
-    // LoadS (T_SHORT) with a small mask (<=16-bit) is converted to LoadUS (T_CHAR).
-    return ciConstant(T_INT, con.as_int() & 0xFFFF);
-  }
-  return ciConstant(); // T_ILLEGAL
-}
-
-// Try to constant-fold a stable array element.
-static const Type* fold_stable_ary_elem(const TypeAryPtr* ary, int off, bool is_unsigned_load, BasicType loadbt) {
-  assert(ary->const_oop(), "array should be constant");
-  assert(ary->is_stable(), "array should be stable");
-
-  // Decode the results of GraphKit::array_element_address.
-  ciArray* aobj = ary->const_oop()->as_array();
-  ciConstant element_value = aobj->element_value_by_offset(off);
-  if (element_value.basic_type() == T_ILLEGAL) {
-    return NULL; // wrong offset
-  }
-  ciConstant con = check_mismatched_access(element_value, loadbt, is_unsigned_load);
-  assert(con.basic_type() != T_ILLEGAL, "elembt=%s; loadbt=%s; unsigned=%d",
-         type2name(element_value.basic_type()), type2name(loadbt), is_unsigned_load);
-
-  if (con.basic_type() != T_ILLEGAL && // not a mismatched access
-      !con.is_null_or_zero()) {        // not a default value
-    const Type* con_type = Type::make_from_constant(con);
-    if (con_type != NULL) {
-      if (con_type->isa_aryptr()) {
-        // Join with the array element type, in case it is also stable.
-        int dim = ary->stable_dimension();
-        con_type = con_type->is_aryptr()->cast_to_stable(true, dim-1);
-      }
-      if (loadbt == T_NARROWOOP && con_type->isa_oopptr()) {
-        con_type = con_type->make_narrowoop();
-      }
-#ifndef PRODUCT
-      if (TraceIterativeGVN) {
-        tty->print("FoldStableValues: array element [off=%d]: con_type=", off);
-        con_type->dump(); tty->cr();
-      }
-#endif //PRODUCT
-      return con_type;
-    }
-  }
-  return NULL;
-}
-
 //------------------------------Value-----------------------------------------
 const Type* LoadNode::Value(PhaseGVN* phase) const {
   // Either input is TOP ==> the result is TOP
@@ -1714,10 +1648,14 @@
     const bool off_beyond_header = ((uint)off >= (uint)min_base_off);
 
     // Try to constant-fold a stable array element.
-    if (FoldStableValues && !is_mismatched_access() && ary->is_stable() && ary->const_oop() != NULL) {
+    if (FoldStableValues && !is_mismatched_access() && ary->is_stable()) {
       // Make sure the reference is not into the header and the offset is constant
-      if (off_beyond_header && adr->is_AddP() && off != Type::OffsetBot) {
-        const Type* con_type = fold_stable_ary_elem(ary, off, is_unsigned(), memory_type());
+      ciObject* aobj = ary->const_oop();
+      if (aobj != NULL && off_beyond_header && adr->is_AddP() && off != Type::OffsetBot) {
+        int stable_dimension = (ary->stable_dimension() > 0 ? ary->stable_dimension() - 1 : 0);
+        const Type* con_type = Type::make_constant_from_array_element(aobj->as_array(), off,
+                                                                      stable_dimension,
+                                                                      memory_type(), is_unsigned());
         if (con_type != NULL) {
           return con_type;
         }
@@ -1784,28 +1722,10 @@
     // For oop loads, we expect the _type to be precise.
     // Optimizations for constant objects
     ciObject* const_oop = tinst->const_oop();
-    if (const_oop != NULL) {
-      // For constant CallSites treat the target field as a compile time constant.
-      if (const_oop->is_call_site()) {
-        ciCallSite* call_site = const_oop->as_call_site();
-        ciField* field = call_site->klass()->as_instance_klass()->get_field_by_offset(off, /*is_static=*/ false);
-        if (field != NULL && field->is_call_site_target()) {
-          ciMethodHandle* target = call_site->get_target();
-          if (target != NULL) {  // just in case
-            ciConstant constant(T_OBJECT, target);
-            const Type* t;
-            if (adr->bottom_type()->is_ptr_to_narrowoop()) {
-              t = TypeNarrowOop::make_from_constant(constant.as_object(), true);
-            } else {
-              t = TypeOopPtr::make_from_constant(constant.as_object(), true);
-            }
-            // Add a dependence for invalidation of the optimization.
-            if (!call_site->is_constant_call_site()) {
-              C->dependencies()->assert_call_site_target_value(call_site, target);
-            }
-            return t;
-          }
-        }
+    if (const_oop != NULL && const_oop->is_instance()) {
+      const Type* con_type = Type::make_constant_from_field(const_oop->as_instance(), off, is_unsigned(), memory_type());
+      if (con_type != NULL) {
+        return con_type;
       }
     }
   } else if (tp->base() == Type::KlassPtr) {