mirror of
https://github.com/openjdk/jdk.git
synced 2025-09-21 03:24:38 +02:00
8014189: JVM crash with SEGV in ConnectionGraph::record_for_escape_analysis()
Add NULL checks and asserts for Type::make_ptr() returned value. Reviewed-by: twisti
This commit is contained in:
parent
b4977e887a
commit
d7176bf7f8
9 changed files with 44 additions and 19 deletions
|
@ -484,6 +484,9 @@ void ConnectionGraph::add_node_to_connection_graph(Node *n, Unique_Node_List *de
|
||||||
Node* adr = n->in(MemNode::Address);
|
Node* adr = n->in(MemNode::Address);
|
||||||
const Type *adr_type = igvn->type(adr);
|
const Type *adr_type = igvn->type(adr);
|
||||||
adr_type = adr_type->make_ptr();
|
adr_type = adr_type->make_ptr();
|
||||||
|
if (adr_type == NULL) {
|
||||||
|
break; // skip dead nodes
|
||||||
|
}
|
||||||
if (adr_type->isa_oopptr() ||
|
if (adr_type->isa_oopptr() ||
|
||||||
(opcode == Op_StoreP || opcode == Op_StoreN || opcode == Op_StoreNKlass) &&
|
(opcode == Op_StoreP || opcode == Op_StoreN || opcode == Op_StoreNKlass) &&
|
||||||
(adr_type == TypeRawPtr::NOTNULL &&
|
(adr_type == TypeRawPtr::NOTNULL &&
|
||||||
|
@ -676,14 +679,18 @@ void ConnectionGraph::add_final_edges(Node *n) {
|
||||||
case Op_GetAndSetP:
|
case Op_GetAndSetP:
|
||||||
case Op_GetAndSetN: {
|
case Op_GetAndSetN: {
|
||||||
Node* adr = n->in(MemNode::Address);
|
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);
|
const Type *adr_type = _igvn->type(adr);
|
||||||
adr_type = adr_type->make_ptr();
|
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() ||
|
if (adr_type->isa_oopptr() ||
|
||||||
(opcode == Op_StoreP || opcode == Op_StoreN || opcode == Op_StoreNKlass) &&
|
(opcode == Op_StoreP || opcode == Op_StoreN || opcode == Op_StoreNKlass) &&
|
||||||
(adr_type == TypeRawPtr::NOTNULL &&
|
(adr_type == TypeRawPtr::NOTNULL &&
|
||||||
|
@ -1813,9 +1820,8 @@ Node* ConnectionGraph::optimize_ptr_compare(Node* n) {
|
||||||
jobj2->ideal_node()->is_Con()) {
|
jobj2->ideal_node()->is_Con()) {
|
||||||
// Klass or String constants compare. Need to be careful with
|
// Klass or String constants compare. Need to be careful with
|
||||||
// compressed pointers - compare types of ConN and ConP instead of nodes.
|
// compressed pointers - compare types of ConN and ConP instead of nodes.
|
||||||
const Type* t1 = jobj1->ideal_node()->bottom_type()->make_ptr();
|
const Type* t1 = jobj1->ideal_node()->get_ptr_type();
|
||||||
const Type* t2 = jobj2->ideal_node()->bottom_type()->make_ptr();
|
const Type* t2 = jobj2->ideal_node()->get_ptr_type();
|
||||||
assert(t1 != NULL && t2 != NULL, "sanity");
|
|
||||||
if (t1->make_ptr() == t2->make_ptr()) {
|
if (t1->make_ptr() == t2->make_ptr()) {
|
||||||
return _pcmp_eq;
|
return _pcmp_eq;
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -219,9 +219,10 @@ void Block::implicit_null_check(PhaseCFG *cfg, Node *proj, Node *val, int allowe
|
||||||
// cannot reason about it; is probably not implicit null exception
|
// cannot reason about it; is probably not implicit null exception
|
||||||
} else {
|
} else {
|
||||||
const TypePtr* tptr;
|
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
|
// 32-bits narrow oop can be the base of address expressions
|
||||||
tptr = base->bottom_type()->make_ptr();
|
tptr = base->get_ptr_type();
|
||||||
} else {
|
} else {
|
||||||
// only regular oops are expected here
|
// only regular oops are expected here
|
||||||
tptr = base->bottom_type()->is_ptr();
|
tptr = base->bottom_type()->is_ptr();
|
||||||
|
|
|
@ -2783,7 +2783,7 @@ bool LibraryCallKit::inline_unsafe_load_store(BasicType type, LoadStoreKind kind
|
||||||
|
|
||||||
#ifdef _LP64
|
#ifdef _LP64
|
||||||
if (type == T_OBJECT && adr->bottom_type()->is_ptr_to_narrowoop() && kind == LS_xchg) {
|
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
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -349,11 +349,11 @@ const class TypePtr *MachNode::adr_type() const {
|
||||||
if (base == NodeSentinel) return TypePtr::BOTTOM;
|
if (base == NodeSentinel) return TypePtr::BOTTOM;
|
||||||
|
|
||||||
const Type* t = base->bottom_type();
|
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
|
// 32-bit unscaled narrow oop can be the base of any address expression
|
||||||
t = t->make_ptr();
|
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
|
// 32-bit unscaled narrow oop can be the base of any address expression
|
||||||
t = t->make_ptr();
|
t = t->make_ptr();
|
||||||
}
|
}
|
||||||
|
|
|
@ -834,7 +834,7 @@ bool PhaseMacroExpand::scalar_replacement(AllocateNode *alloc, GrowableArray <Sa
|
||||||
if (field_val->is_EncodeP()) {
|
if (field_val->is_EncodeP()) {
|
||||||
field_val = field_val->in(1);
|
field_val = field_val->in(1);
|
||||||
} else {
|
} 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);
|
sfpt->add_req(field_val);
|
||||||
|
|
|
@ -1398,6 +1398,21 @@ const TypeLong* Node::find_long_type() const {
|
||||||
return NULL;
|
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.
|
// Get a double constant from a ConstNode.
|
||||||
// Returns the constant if it is a double ConstNode
|
// Returns the constant if it is a double ConstNode
|
||||||
jdouble Node::getd() const {
|
jdouble Node::getd() const {
|
||||||
|
|
|
@ -965,6 +965,8 @@ public:
|
||||||
}
|
}
|
||||||
const TypeLong* find_long_type() const;
|
const TypeLong* find_long_type() const;
|
||||||
|
|
||||||
|
const TypePtr* get_ptr_type() const;
|
||||||
|
|
||||||
// These guys are called by code generated by ADLC:
|
// These guys are called by code generated by ADLC:
|
||||||
intptr_t get_ptr() const;
|
intptr_t get_ptr() const;
|
||||||
intptr_t get_narrowcon() const;
|
intptr_t get_narrowcon() const;
|
||||||
|
|
|
@ -929,7 +929,7 @@ void Compile::Process_OopMap_Node(MachNode *mach, int current_offset) {
|
||||||
scval = new_loc_value( _regalloc, obj_reg, Location::oop );
|
scval = new_loc_value( _regalloc, obj_reg, Location::oop );
|
||||||
}
|
}
|
||||||
} else {
|
} 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());
|
scval = new ConstantOopWriteValue(tp->is_oopptr()->const_oop()->constant_encoding());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -863,10 +863,11 @@ const Type *CmpNNode::sub( const Type *t1, const Type *t2 ) const {
|
||||||
const TypePtr *r1 = t2->make_ptr();
|
const TypePtr *r1 = t2->make_ptr();
|
||||||
|
|
||||||
// Undefined inputs makes for an undefined result
|
// Undefined inputs makes for an undefined result
|
||||||
if( TypePtr::above_centerline(r0->_ptr) ||
|
if ((r0 == NULL) || (r1 == NULL) ||
|
||||||
TypePtr::above_centerline(r1->_ptr) )
|
TypePtr::above_centerline(r0->_ptr) ||
|
||||||
|
TypePtr::above_centerline(r1->_ptr)) {
|
||||||
return Type::TOP;
|
return Type::TOP;
|
||||||
|
}
|
||||||
if (r0 == r1 && r0->singleton()) {
|
if (r0 == r1 && r0->singleton()) {
|
||||||
// Equal pointer constants (klasses, nulls, etc.)
|
// Equal pointer constants (klasses, nulls, etc.)
|
||||||
return TypeInt::CC_EQ;
|
return TypeInt::CC_EQ;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue