changeset 3222:ed4c92f54c2d

7154997: assert(false) failed: not G1 barrier raw StoreP Summary: Skip only G1 cases and explicitly set global escape state in unsafe cases. Reviewed-by: never
author kvn
date Tue, 20 Mar 2012 13:10:13 -0700
parents 1a11548571e8
children ad412114302a
files src/share/vm/opto/escape.cpp
diffstat 1 files changed, 44 insertions(+), 10 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/vm/opto/escape.cpp	Fri Mar 16 23:52:03 2012 -0700
+++ b/src/share/vm/opto/escape.cpp	Tue Mar 20 13:10:13 2012 -0700
@@ -467,21 +467,41 @@
           int offs = (int)igvn->find_intptr_t_con(adr->in(AddPNode::Offset), Type::OffsetBot);
           assert(offs != Type::OffsetBot, "offset must be a constant");
         }
+#endif
       } else {
         // Ignore copy the displaced header to the BoxNode (OSR compilation).
         if (adr->is_BoxLock())
           break;
-
-        if (!adr->is_AddP()) {
-          n->dump(1);
-          assert(adr->is_AddP(), "expecting an AddP");
+        // Stored value escapes in unsafe access.
+        if ((opcode == Op_StoreP) && (adr_type == TypeRawPtr::BOTTOM)) {
+          // Pointer stores in G1 barriers looks like unsafe access.
+          // Ignore such stores to be able scalar replace non-escaping
+          // allocations.
+          if (UseG1GC && adr->is_AddP()) {
+            Node* base = get_addp_base(adr);
+            if (base->Opcode() == Op_LoadP &&
+                base->in(MemNode::Address)->is_AddP()) {
+              adr = base->in(MemNode::Address);
+              Node* tls = get_addp_base(adr);
+              if (tls->Opcode() == Op_ThreadLocal) {
+                int offs = (int)igvn->find_intptr_t_con(adr->in(AddPNode::Offset), Type::OffsetBot);
+                if (offs == in_bytes(JavaThread::satb_mark_queue_offset() +
+                                     PtrQueue::byte_offset_of_buf())) {
+                  break; // G1 pre barier previous oop value store.
+                }
+                if (offs == in_bytes(JavaThread::dirty_card_queue_offset() +
+                                     PtrQueue::byte_offset_of_buf())) {
+                  break; // G1 post barier card address store.
+                }
+              }
+            }
+          }
+          delayed_worklist->push(n); // Process unsafe access later.
+          break;
         }
-        // Ignore G1 barrier's stores.
-        if (!UseG1GC || (opcode != Op_StoreP) ||
-            (adr_type != TypeRawPtr::BOTTOM)) {
-          n->dump(1);
-          assert(false, "not G1 barrier raw StoreP");
-        }
+#ifdef ASSERT
+        n->dump(1);
+        assert(false, "not unsafe or G1 barrier raw StoreP");
 #endif
       }
       break;
@@ -636,6 +656,20 @@
         assert(ptn != NULL, "node should be registered");
         add_edge(adr_ptn, ptn);
         break;
+      } else if ((opcode == Op_StoreP) && (adr_type == TypeRawPtr::BOTTOM)) {
+        // Stored value escapes in unsafe access.
+        Node *val = n->in(MemNode::ValueIn);
+        PointsToNode* ptn = ptnode_adr(val->_idx);
+        assert(ptn != NULL, "node should be registered");
+        ptn->set_escape_state(PointsToNode::GlobalEscape);
+        // Add edge to object for unsafe access with offset.
+        PointsToNode* adr_ptn = ptnode_adr(adr->_idx);
+        assert(adr_ptn != NULL, "node should be registered");
+        if (adr_ptn->is_Field()) {
+          assert(adr_ptn->as_Field()->is_oop(), "should be oop field");
+          add_edge(adr_ptn, ptn);
+        }
+        break;
       }
       ELSE_FAIL("Op_StoreP");
     }