diff src/share/vm/opto/escape.cpp @ 293:c3e045194476

6731641: assert(m->adr_type() == mach->adr_type(),"matcher should not change adr type") Summary: fixed few addP node type and narrow oop type problems. Reviewed-by: rasbold, never
author kvn
date Fri, 01 Aug 2008 10:06:45 -0700
parents b0fe4deeb9fb
children af945ba2e739
line wrap: on
line diff
--- a/src/share/vm/opto/escape.cpp	Thu Jul 31 15:47:42 2008 -0700
+++ b/src/share/vm/opto/escape.cpp	Fri Aug 01 10:06:45 2008 -0700
@@ -492,13 +492,13 @@
 // Adjust the type and inputs of an AddP which computes the
 // address of a field of an instance
 //
-void ConnectionGraph::split_AddP(Node *addp, Node *base,  PhaseGVN  *igvn) {
+bool ConnectionGraph::split_AddP(Node *addp, Node *base,  PhaseGVN  *igvn) {
   const TypeOopPtr *base_t = igvn->type(base)->isa_oopptr();
   assert(base_t != NULL && base_t->is_known_instance(), "expecting instance oopptr");
   const TypeOopPtr *t = igvn->type(addp)->isa_oopptr();
   if (t == NULL) {
     // We are computing a raw address for a store captured by an Initialize
-    // compute an appropriate address type.
+    // compute an appropriate address type (cases #3 and #5).
     assert(igvn->type(addp) == TypeRawPtr::NOTNULL, "must be raw pointer");
     assert(addp->in(AddPNode::Address)->is_Proj(), "base of raw address must be result projection from allocation");
     int offs = (int)igvn->find_intptr_t_con(addp->in(AddPNode::Offset), Type::OffsetBot);
@@ -508,6 +508,25 @@
   int inst_id =  base_t->instance_id();
   assert(!t->is_known_instance() || t->instance_id() == inst_id,
                              "old type must be non-instance or match new type");
+
+  // The type 't' could be subclass of 'base_t'.
+  // As result t->offset() could be large then base_t's size and it will
+  // cause the failure in add_offset() with narrow oops since TypeOopPtr()
+  // constructor verifies correctness of the offset.
+  //
+  // It could happend on subclass's branch (from the type profiling
+  // inlining) which was not eliminated during parsing since the exactness
+  // of the allocation type was not propagated to the subclass type check.
+  //
+  // Do nothing for such AddP node and don't process its users since
+  // this code branch will go away.
+  //
+  if (!t->is_known_instance() &&
+      !t->klass()->equals(base_t->klass()) &&
+      t->klass()->is_subtype_of(base_t->klass())) {
+     return false; // bail out
+  }
+
   const TypeOopPtr *tinst = base_t->add_offset(t->offset())->is_oopptr();
   // Do NOT remove the next call: ensure an new alias index is allocated
   // for the instance type
@@ -542,6 +561,7 @@
   }
   // Put on IGVN worklist since at least addp's type was changed above.
   record_for_optimizer(addp);
+  return true;
 }
 
 //
@@ -969,7 +989,7 @@
       if (elem == _phantom_object)
         continue; // Assume the value was set outside this method.
       Node *base = get_map(elem);  // CheckCastPP node
-      split_AddP(n, base, igvn);
+      if (!split_AddP(n, base, igvn)) continue; // wrong type
       tinst = igvn->type(base)->isa_oopptr();
     } else if (n->is_Phi() ||
                n->is_CheckCastPP() ||
@@ -1012,6 +1032,8 @@
           tn->set_type(tn_type);
           igvn->hash_insert(tn);
           record_for_optimizer(n);
+        } else {
+          continue; // wrong type
         }
       }
     } else {