hotspot/src/share/vm/opto/escape.cpp
changeset 13391 30245956af37
parent 12164 5fa74ba174b7
child 13393 f0344cc50a90
--- a/hotspot/src/share/vm/opto/escape.cpp	Mon Jul 23 13:04:59 2012 -0700
+++ b/hotspot/src/share/vm/opto/escape.cpp	Tue Jul 24 10:51:00 2012 -0700
@@ -1768,8 +1768,12 @@
     assert(ptadr->is_Field() && ptadr->ideal_node() == n, "sanity");
     return;
   }
+  bool unsafe = false;
+  bool is_oop = is_oop_field(n, offset, &unsafe);
+  if (unsafe) {
+    es = PointsToNode::GlobalEscape;
+  }
   Compile* C = _compile;
-  bool is_oop = is_oop_field(n, offset);
   FieldNode* field = new (C->comp_arena()) FieldNode(C, n, es, offset, is_oop);
   _nodes.at_put(n->_idx, field);
 }
@@ -1794,7 +1798,7 @@
   dst->set_arraycopy_dst();
 }
 
-bool ConnectionGraph::is_oop_field(Node* n, int offset) {
+bool ConnectionGraph::is_oop_field(Node* n, int offset, bool* unsafe) {
   const Type* adr_type = n->as_AddP()->bottom_type();
   BasicType bt = T_INT;
   if (offset == Type::OffsetBot) {
@@ -1813,7 +1817,16 @@
       if (field != NULL) {
         bt = field->layout_type();
       } else {
-        // Ignore non field load (for example, klass load)
+        // Check for unsafe oop field access
+        for (DUIterator_Fast imax, i = n->fast_outs(imax); i < imax; i++) {
+          int opcode = n->fast_out(i)->Opcode();
+          if (opcode == Op_StoreP || opcode == Op_LoadP ||
+              opcode == Op_StoreN || opcode == Op_LoadN) {
+            bt = T_OBJECT;
+            (*unsafe) = true;
+            break;
+          }
+        }
       }
     } else if (adr_type->isa_aryptr()) {
       if (offset == arrayOopDesc::length_offset_in_bytes()) {
@@ -1831,6 +1844,7 @@
         if (opcode == Op_StoreP || opcode == Op_LoadP ||
             opcode == Op_StoreN || opcode == Op_LoadN) {
           bt = T_OBJECT;
+          break;
         }
       }
     }