hotspot/src/share/vm/opto/compile.cpp
changeset 955 723d7b577fba
parent 953 202a1f972a92
child 961 7fb3b13d4205
--- a/hotspot/src/share/vm/opto/compile.cpp	Wed Jul 16 10:08:57 2008 -0700
+++ b/hotspot/src/share/vm/opto/compile.cpp	Wed Jul 16 16:04:39 2008 -0700
@@ -999,9 +999,14 @@
   int offset = tj->offset();
   TypePtr::PTR ptr = tj->ptr();
 
+  // Known instance (scalarizable allocation) alias only with itself.
+  bool is_known_inst = tj->isa_oopptr() != NULL &&
+                       tj->is_oopptr()->is_known_instance();
+
   // Process weird unsafe references.
   if (offset == Type::OffsetBot && (tj->isa_instptr() /*|| tj->isa_klassptr()*/)) {
     assert(InlineUnsafeOps, "indeterminate pointers come only from unsafe ops");
+    assert(!is_known_inst, "scalarizable allocation should not have unsafe references");
     tj = TypeOopPtr::BOTTOM;
     ptr = tj->ptr();
     offset = tj->offset();
@@ -1009,14 +1014,20 @@
 
   // Array pointers need some flattening
   const TypeAryPtr *ta = tj->isa_aryptr();
-  if( ta && _AliasLevel >= 2 ) {
+  if( ta && is_known_inst ) {
+    if ( offset != Type::OffsetBot &&
+         offset > arrayOopDesc::length_offset_in_bytes() ) {
+      offset = Type::OffsetBot; // Flatten constant access into array body only
+      tj = ta = TypeAryPtr::make(ptr, ta->ary(), ta->klass(), true, offset, ta->instance_id());
+    }
+  } else if( ta && _AliasLevel >= 2 ) {
     // For arrays indexed by constant indices, we flatten the alias
     // space to include all of the array body.  Only the header, klass
     // and array length can be accessed un-aliased.
     if( offset != Type::OffsetBot ) {
       if( ta->const_oop() ) { // methodDataOop or methodOop
         offset = Type::OffsetBot;   // Flatten constant access into array body
-        tj = ta = TypeAryPtr::make(ptr,ta->const_oop(),ta->ary(),ta->klass(),false,Type::OffsetBot, ta->instance_id());
+        tj = ta = TypeAryPtr::make(ptr,ta->const_oop(),ta->ary(),ta->klass(),false,offset);
       } else if( offset == arrayOopDesc::length_offset_in_bytes() ) {
         // range is OK as-is.
         tj = ta = TypeAryPtr::RANGE;
@@ -1030,29 +1041,29 @@
         ptr = TypePtr::BotPTR;
       } else {                  // Random constant offset into array body
         offset = Type::OffsetBot;   // Flatten constant access into array body
-        tj = ta = TypeAryPtr::make(ptr,ta->ary(),ta->klass(),false,Type::OffsetBot, ta->instance_id());
+        tj = ta = TypeAryPtr::make(ptr,ta->ary(),ta->klass(),false,offset);
       }
     }
     // Arrays of fixed size alias with arrays of unknown size.
     if (ta->size() != TypeInt::POS) {
       const TypeAry *tary = TypeAry::make(ta->elem(), TypeInt::POS);
-      tj = ta = TypeAryPtr::make(ptr,ta->const_oop(),tary,ta->klass(),false,offset, ta->instance_id());
+      tj = ta = TypeAryPtr::make(ptr,ta->const_oop(),tary,ta->klass(),false,offset);
     }
     // Arrays of known objects become arrays of unknown objects.
     if (ta->elem()->isa_narrowoop() && ta->elem() != TypeNarrowOop::BOTTOM) {
       const TypeAry *tary = TypeAry::make(TypeNarrowOop::BOTTOM, ta->size());
-      tj = ta = TypeAryPtr::make(ptr,ta->const_oop(),tary,NULL,false,offset, ta->instance_id());
+      tj = ta = TypeAryPtr::make(ptr,ta->const_oop(),tary,NULL,false,offset);
     }
     if (ta->elem()->isa_oopptr() && ta->elem() != TypeInstPtr::BOTTOM) {
       const TypeAry *tary = TypeAry::make(TypeInstPtr::BOTTOM, ta->size());
-      tj = ta = TypeAryPtr::make(ptr,ta->const_oop(),tary,NULL,false,offset, ta->instance_id());
+      tj = ta = TypeAryPtr::make(ptr,ta->const_oop(),tary,NULL,false,offset);
     }
     // Arrays of bytes and of booleans both use 'bastore' and 'baload' so
     // cannot be distinguished by bytecode alone.
     if (ta->elem() == TypeInt::BOOL) {
       const TypeAry *tary = TypeAry::make(TypeInt::BYTE, ta->size());
       ciKlass* aklass = ciTypeArrayKlass::make(T_BYTE);
-      tj = ta = TypeAryPtr::make(ptr,ta->const_oop(),tary,aklass,false,offset, ta->instance_id());
+      tj = ta = TypeAryPtr::make(ptr,ta->const_oop(),tary,aklass,false,offset);
     }
     // During the 2nd round of IterGVN, NotNull castings are removed.
     // Make sure the Bottom and NotNull variants alias the same.
@@ -1072,21 +1083,24 @@
     if( ptr == TypePtr::Constant ) {
       // No constant oop pointers (such as Strings); they alias with
       // unknown strings.
+      assert(!is_known_inst, "not scalarizable allocation");
       tj = to = TypeInstPtr::make(TypePtr::BotPTR,to->klass(),false,0,offset);
-    } else if( to->is_known_instance_field() ) {
+    } else if( is_known_inst ) {
       tj = to; // Keep NotNull and klass_is_exact for instance type
     } else if( ptr == TypePtr::NotNull || to->klass_is_exact() ) {
       // During the 2nd round of IterGVN, NotNull castings are removed.
       // Make sure the Bottom and NotNull variants alias the same.
       // Also, make sure exact and non-exact variants alias the same.
-      tj = to = TypeInstPtr::make(TypePtr::BotPTR,to->klass(),false,0,offset, to->instance_id());
+      tj = to = TypeInstPtr::make(TypePtr::BotPTR,to->klass(),false,0,offset);
     }
     // Canonicalize the holder of this field
     ciInstanceKlass *k = to->klass()->as_instance_klass();
     if (offset >= 0 && offset < instanceOopDesc::base_offset_in_bytes()) {
       // First handle header references such as a LoadKlassNode, even if the
       // object's klass is unloaded at compile time (4965979).
-      tj = to = TypeInstPtr::make(TypePtr::BotPTR, env()->Object_klass(), false, NULL, offset, to->instance_id());
+      if (!is_known_inst) { // Do it only for non-instance types
+        tj = to = TypeInstPtr::make(TypePtr::BotPTR, env()->Object_klass(), false, NULL, offset);
+      }
     } else if (offset < 0 || offset >= k->size_helper() * wordSize) {
       to = NULL;
       tj = TypeOopPtr::BOTTOM;
@@ -1094,7 +1108,11 @@
     } else {
       ciInstanceKlass *canonical_holder = k->get_canonical_holder(offset);
       if (!k->equals(canonical_holder) || tj->offset() != offset) {
-        tj = to = TypeInstPtr::make(to->ptr(), canonical_holder, false, NULL, offset, to->instance_id());
+        if( is_known_inst ) {
+          tj = to = TypeInstPtr::make(to->ptr(), canonical_holder, true, NULL, offset, to->instance_id());
+        } else {
+          tj = to = TypeInstPtr::make(to->ptr(), canonical_holder, false, NULL, offset);
+        }
       }
     }
   }
@@ -1280,7 +1298,9 @@
   assert(flat != TypePtr::BOTTOM,     "cannot alias-analyze an untyped ptr");
   if (flat->isa_oopptr() && !flat->isa_klassptr()) {
     const TypeOopPtr* foop = flat->is_oopptr();
-    const TypePtr* xoop = foop->cast_to_exactness(!foop->klass_is_exact())->is_ptr();
+    // Scalarizable allocations have exact klass always.
+    bool exact = !foop->klass_is_exact() || foop->is_known_instance();
+    const TypePtr* xoop = foop->cast_to_exactness(exact)->is_ptr();
     assert(foop == flatten_alias_type(xoop), "exactness must not affect alias type");
   }
   assert(flat == flatten_alias_type(flat), "exact bit doesn't matter");