diff src/share/vm/opto/macro.cpp @ 253:b0fe4deeb9fb

6726999: nsk/stress/jck12a/jck12a010 assert(n != null,"Bad immediate dominator info.") Summary: Escape Analysis fixes. Reviewed-by: never, rasbold
author kvn
date Mon, 28 Jul 2008 17:12:52 -0700
parents 02a35ad4adf8
children af945ba2e739 1ee8caae33af
line wrap: on
line diff
--- a/src/share/vm/opto/macro.cpp	Fri Jul 25 16:03:40 2008 -0700
+++ b/src/share/vm/opto/macro.cpp	Mon Jul 28 17:12:52 2008 -0700
@@ -194,9 +194,10 @@
 }
 
 // Search for a memory operation for the specified memory slice.
-static Node *scan_mem_chain(Node *mem, int alias_idx, int offset, Node *start_mem, Node *alloc) {
+static Node *scan_mem_chain(Node *mem, int alias_idx, int offset, Node *start_mem, Node *alloc, PhaseGVN *phase) {
   Node *orig_mem = mem;
   Node *alloc_mem = alloc->in(TypeFunc::Memory);
+  const TypeOopPtr *tinst = phase->C->get_adr_type(alias_idx)->isa_oopptr();
   while (true) {
     if (mem == alloc_mem || mem == start_mem ) {
       return mem;  // hit one of our sentinals
@@ -208,7 +209,13 @@
       // already know that the object is safe to eliminate.
       if (in->is_Initialize() && in->as_Initialize()->allocation() == alloc) {
         return in;
-      } else if (in->is_Call() || in->is_MemBar()) {
+      } else if (in->is_Call()) {
+        CallNode *call = in->as_Call();
+        if (!call->may_modify(tinst, phase)) {
+          mem = call->in(TypeFunc::Memory);
+        }
+        mem = in->in(TypeFunc::Memory);
+      } else if (in->is_MemBar()) {
         mem = in->in(TypeFunc::Memory);
       } else {
         assert(false, "unexpected projection");
@@ -265,7 +272,7 @@
   }
 
   if (level <= 0) {
-    return NULL;
+    return NULL; // Give up: phi tree too deep
   }
   Node *start_mem = C->start()->proj_out(TypeFunc::Memory);
   Node *alloc_mem = alloc->in(TypeFunc::Memory);
@@ -283,7 +290,7 @@
     if (in == NULL || in->is_top()) {
       values.at_put(j, in);
     } else  {
-      Node *val = scan_mem_chain(in, alias_idx, offset, start_mem, alloc);
+      Node *val = scan_mem_chain(in, alias_idx, offset, start_mem, alloc, &_igvn);
       if (val == start_mem || val == alloc_mem) {
         // hit a sentinel, return appropriate 0 value
         values.at_put(j, _igvn.zerocon(ft));
@@ -308,7 +315,8 @@
         }
         values.at_put(j, val);
       } else {
-        return NULL;  // unknown node  on this path
+        assert(false, "unknown node on this path");
+        return NULL;  // unknown node on this path
       }
     }
   }
@@ -344,7 +352,7 @@
     if (visited.test_set(mem->_idx)) {
       return NULL;  // found a loop, give up
     }
-    mem = scan_mem_chain(mem, alias_idx, offset, start_mem, alloc);
+    mem = scan_mem_chain(mem, alias_idx, offset, start_mem, alloc, &_igvn);
     if (mem == start_mem || mem == alloc_mem) {
       done = true;  // hit a sentinel, return appropriate 0 value
     } else if (mem->is_Initialize()) {
@@ -368,7 +376,7 @@
       Node *unique_input = NULL;
       Node *top = C->top();
       for (uint i = 1; i < mem->req(); i++) {
-        Node *n = scan_mem_chain(mem->in(i), alias_idx, offset, start_mem, alloc);
+        Node *n = scan_mem_chain(mem->in(i), alias_idx, offset, start_mem, alloc, &_igvn);
         if (n == NULL || n == top || n == mem) {
           continue;
         } else if (unique_input == NULL) {
@@ -396,7 +404,7 @@
     } else if (mem->is_Phi()) {
       // attempt to produce a Phi reflecting the values on the input paths of the Phi
       Node_Stack value_phis(a, 8);
-      Node * phi = value_from_mem_phi(mem, ft, ftype, adr_t, alloc, &value_phis, 8);
+      Node * phi = value_from_mem_phi(mem, ft, ftype, adr_t, alloc, &value_phis, ValueSearchLimit);
       if (phi != NULL) {
         return phi;
       } else {
@@ -463,7 +471,7 @@
           Node* n = use->fast_out(k);
           if (!n->is_Store() && n->Opcode() != Op_CastP2X) {
             DEBUG_ONLY(disq_node = n;)
-            if (n->is_Load()) {
+            if (n->is_Load() || n->is_LoadStore()) {
               NOT_PRODUCT(fail_eliminate = "Field load";)
             } else {
               NOT_PRODUCT(fail_eliminate = "Not store field referrence";)