changeset 4697:f2ce8a7ee5a0

8014189: JVM crash with SEGV in ConnectionGraph::record_for_escape_analysis() Summary: Add NULL checks and asserts for Type::make_ptr() returned value. Reviewed-by: kvn
author poonam
date Wed, 15 May 2013 10:12:25 -0700
parents feb41fc13635
children ec4e3a5cc748
files src/share/vm/opto/escape.cpp src/share/vm/opto/lcm.cpp src/share/vm/opto/library_call.cpp src/share/vm/opto/machnode.cpp src/share/vm/opto/macro.cpp src/share/vm/opto/node.cpp src/share/vm/opto/node.hpp src/share/vm/opto/output.cpp src/share/vm/opto/subnode.cpp
diffstat 9 files changed, 42 insertions(+), 18 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/vm/opto/escape.cpp	Tue May 14 09:11:21 2013 +0200
+++ b/src/share/vm/opto/escape.cpp	Wed May 15 10:12:25 2013 -0700
@@ -464,6 +464,9 @@
       Node* adr = n->in(MemNode::Address);
       const Type *adr_type = igvn->type(adr);
       adr_type = adr_type->make_ptr();
+      if (adr_type == NULL) {
+        break; // skip dead nodes
+      }
       if (adr_type->isa_oopptr() ||
           (opcode == Op_StoreP || opcode == Op_StoreN) &&
                         (adr_type == TypeRawPtr::NOTNULL &&
@@ -652,14 +655,18 @@
     case Op_GetAndSetP:
     case Op_GetAndSetN: {
       Node* adr = n->in(MemNode::Address);
-      if (opcode == Op_GetAndSetP || opcode == Op_GetAndSetN) {
-        const Type* t = _igvn->type(n);
-        if (t->make_ptr() != NULL) {
-          add_local_var_and_edge(n, PointsToNode::NoEscape, adr, NULL);
-        }
-      }
       const Type *adr_type = _igvn->type(adr);
       adr_type = adr_type->make_ptr();
+#ifdef ASSERT
+      if (adr_type == NULL) {
+        n->dump(1);
+        assert(adr_type != NULL, "dead node should not be on list");
+        break;
+      }
+#endif
+      if (opcode == Op_GetAndSetP || opcode == Op_GetAndSetN) {
+        add_local_var_and_edge(n, PointsToNode::NoEscape, adr, NULL);
+      }
       if (adr_type->isa_oopptr() ||
           (opcode == Op_StoreP || opcode == Op_StoreN) &&
                         (adr_type == TypeRawPtr::NOTNULL &&
@@ -1782,9 +1789,8 @@
       jobj2->ideal_node()->is_Con()) {
     // Klass or String constants compare. Need to be careful with
     // compressed pointers - compare types of ConN and ConP instead of nodes.
-    const Type* t1 = jobj1->ideal_node()->bottom_type()->make_ptr();
-    const Type* t2 = jobj2->ideal_node()->bottom_type()->make_ptr();
-    assert(t1 != NULL && t2 != NULL, "sanity");
+    const Type* t1 = jobj1->ideal_node()->get_ptr_type();
+    const Type* t2 = jobj2->ideal_node()->get_ptr_type();
     if (t1->make_ptr() == t2->make_ptr()) {
       return _pcmp_eq;
     } else {
--- a/src/share/vm/opto/lcm.cpp	Tue May 14 09:11:21 2013 +0200
+++ b/src/share/vm/opto/lcm.cpp	Wed May 15 10:12:25 2013 -0700
@@ -217,9 +217,9 @@
         // cannot reason about it; is probably not implicit null exception
       } else {
         const TypePtr* tptr;
-        if (UseCompressedOops && Universe::narrow_oop_shift() == 0) {
+        if (UseCompressedOops && (Universe::narrow_oop_shift() == 0)) {
           // 32-bits narrow oop can be the base of address expressions
-          tptr = base->bottom_type()->make_ptr();
+          tptr = base->get_ptr_type();
         } else {
           // only regular oops are expected here
           tptr = base->bottom_type()->is_ptr();
--- a/src/share/vm/opto/library_call.cpp	Tue May 14 09:11:21 2013 +0200
+++ b/src/share/vm/opto/library_call.cpp	Wed May 15 10:12:25 2013 -0700
@@ -2769,7 +2769,7 @@
 
 #ifdef _LP64
   if (type == T_OBJECT && adr->bottom_type()->is_ptr_to_narrowoop() && kind == LS_xchg) {
-    load_store = _gvn.transform(new (C) DecodeNNode(load_store, load_store->bottom_type()->make_ptr()));
+    load_store = _gvn.transform(new (C) DecodeNNode(load_store, load_store->get_ptr_type()));
   }
 #endif
 
--- a/src/share/vm/opto/machnode.cpp	Tue May 14 09:11:21 2013 +0200
+++ b/src/share/vm/opto/machnode.cpp	Wed May 15 10:12:25 2013 -0700
@@ -348,7 +348,7 @@
   if (base == NodeSentinel)  return TypePtr::BOTTOM;
 
   const Type* t = base->bottom_type();
-  if (UseCompressedOops && Universe::narrow_oop_shift() == 0) {
+  if (t->isa_narrowoop() && Universe::narrow_oop_shift() == 0) {
     // 32-bit unscaled narrow oop can be the base of any address expression
     t = t->make_ptr();
   }
--- a/src/share/vm/opto/macro.cpp	Tue May 14 09:11:21 2013 +0200
+++ b/src/share/vm/opto/macro.cpp	Wed May 15 10:12:25 2013 -0700
@@ -827,7 +827,7 @@
         if (field_val->is_EncodeP()) {
           field_val = field_val->in(1);
         } else {
-          field_val = transform_later(new (C) DecodeNNode(field_val, field_val->bottom_type()->make_ptr()));
+          field_val = transform_later(new (C) DecodeNNode(field_val, field_val->get_ptr_type()));
         }
       }
       sfpt->add_req(field_val);
--- a/src/share/vm/opto/node.cpp	Tue May 14 09:11:21 2013 +0200
+++ b/src/share/vm/opto/node.cpp	Wed May 15 10:12:25 2013 -0700
@@ -1383,6 +1383,21 @@
   return NULL;
 }
 
+
+/**
+ * Return a ptr type for nodes which should have it.
+ */
+const TypePtr* Node::get_ptr_type() const {
+  const TypePtr* tp = this->bottom_type()->make_ptr();
+#ifdef ASSERT
+  if (tp == NULL) {
+    this->dump(1);
+    assert((tp != NULL), "unexpected node type");
+  }
+#endif
+  return tp;
+}
+
 // Get a double constant from a ConstNode.
 // Returns the constant if it is a double ConstNode
 jdouble Node::getd() const {
--- a/src/share/vm/opto/node.hpp	Tue May 14 09:11:21 2013 +0200
+++ b/src/share/vm/opto/node.hpp	Wed May 15 10:12:25 2013 -0700
@@ -952,6 +952,8 @@
   }
   const TypeLong* find_long_type() const;
 
+  const TypePtr* get_ptr_type() const;
+
   // These guys are called by code generated by ADLC:
   intptr_t get_ptr() const;
   intptr_t get_narrowcon() const;
--- a/src/share/vm/opto/output.cpp	Tue May 14 09:11:21 2013 +0200
+++ b/src/share/vm/opto/output.cpp	Wed May 15 10:12:25 2013 -0700
@@ -931,7 +931,7 @@
           scval = new_loc_value( _regalloc, obj_reg, Location::oop );
         }
       } else {
-        const TypePtr *tp = obj_node->bottom_type()->make_ptr();
+        const TypePtr *tp = obj_node->get_ptr_type();
         scval = new ConstantOopWriteValue(tp->is_oopptr()->const_oop()->constant_encoding());
       }
 
--- a/src/share/vm/opto/subnode.cpp	Tue May 14 09:11:21 2013 +0200
+++ b/src/share/vm/opto/subnode.cpp	Wed May 15 10:12:25 2013 -0700
@@ -865,10 +865,11 @@
   const TypePtr *r1 = t2->make_ptr();
 
   // Undefined inputs makes for an undefined result
-  if( TypePtr::above_centerline(r0->_ptr) ||
-      TypePtr::above_centerline(r1->_ptr) )
+  if ((r0 == NULL) || (r1 == NULL) ||
+      TypePtr::above_centerline(r0->_ptr) ||
+      TypePtr::above_centerline(r1->_ptr)) {
     return Type::TOP;
-
+  }
   if (r0 == r1 && r0->singleton()) {
     // Equal pointer constants (klasses, nulls, etc.)
     return TypeInt::CC_EQ;