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: twisti
--- a/hotspot/src/share/vm/opto/escape.cpp Wed May 08 15:08:01 2013 -0700
+++ b/hotspot/src/share/vm/opto/escape.cpp Thu May 09 17:28:04 2013 -0700
@@ -484,6 +484,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 || opcode == Op_StoreNKlass) &&
(adr_type == TypeRawPtr::NOTNULL &&
@@ -676,14 +679,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 || opcode == Op_StoreNKlass) &&
(adr_type == TypeRawPtr::NOTNULL &&
@@ -1813,9 +1820,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/hotspot/src/share/vm/opto/lcm.cpp Wed May 08 15:08:01 2013 -0700
+++ b/hotspot/src/share/vm/opto/lcm.cpp Thu May 09 17:28:04 2013 -0700
@@ -219,9 +219,10 @@
// 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 ||
+ Universe::narrow_klass_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/hotspot/src/share/vm/opto/library_call.cpp Wed May 08 15:08:01 2013 -0700
+++ b/hotspot/src/share/vm/opto/library_call.cpp Thu May 09 17:28:04 2013 -0700
@@ -2783,7 +2783,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/hotspot/src/share/vm/opto/machnode.cpp Wed May 08 15:08:01 2013 -0700
+++ b/hotspot/src/share/vm/opto/machnode.cpp Thu May 09 17:28:04 2013 -0700
@@ -349,11 +349,11 @@
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();
}
- if (UseCompressedKlassPointers && Universe::narrow_klass_shift() == 0) {
+ if (t->isa_narrowklass() && Universe::narrow_klass_shift() == 0) {
// 32-bit unscaled narrow oop can be the base of any address expression
t = t->make_ptr();
}
--- a/hotspot/src/share/vm/opto/macro.cpp Wed May 08 15:08:01 2013 -0700
+++ b/hotspot/src/share/vm/opto/macro.cpp Thu May 09 17:28:04 2013 -0700
@@ -834,7 +834,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/hotspot/src/share/vm/opto/node.cpp Wed May 08 15:08:01 2013 -0700
+++ b/hotspot/src/share/vm/opto/node.cpp Thu May 09 17:28:04 2013 -0700
@@ -1398,6 +1398,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/hotspot/src/share/vm/opto/node.hpp Wed May 08 15:08:01 2013 -0700
+++ b/hotspot/src/share/vm/opto/node.hpp Thu May 09 17:28:04 2013 -0700
@@ -965,6 +965,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/hotspot/src/share/vm/opto/output.cpp Wed May 08 15:08:01 2013 -0700
+++ b/hotspot/src/share/vm/opto/output.cpp Thu May 09 17:28:04 2013 -0700
@@ -929,7 +929,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/hotspot/src/share/vm/opto/subnode.cpp Wed May 08 15:08:01 2013 -0700
+++ b/hotspot/src/share/vm/opto/subnode.cpp Thu May 09 17:28:04 2013 -0700
@@ -863,10 +863,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;