8194992: Null pointer dereference in MultiNode::proj_out related to loopexit()

Reviewed-by: kvn, thartmann
This commit is contained in:
Dean Long 2018-01-18 10:05:32 -08:00
parent 80ac199ab3
commit 4f496a5786
5 changed files with 23 additions and 22 deletions

View File

@ -1017,7 +1017,6 @@ void PhaseIdealLoop::insert_pre_post_loops( IdealLoopTree *loop, Node_List &old_
CountedLoopNode *main_head = loop->_head->as_CountedLoop();
assert( main_head->is_normal_loop(), "" );
CountedLoopEndNode *main_end = main_head->loopexit();
guarantee(main_end != NULL, "no loop exit node");
assert( main_end->outcnt() == 2, "1 true, 1 false path only" );
Node *pre_header= main_head->in(LoopNode::EntryControl);
@ -1243,7 +1242,6 @@ void PhaseIdealLoop::insert_vector_post_loop(IdealLoopTree *loop, Node_List &old
// Find common pieces of the loop being guarded with pre & post loops
CountedLoopNode *main_head = loop->_head->as_CountedLoop();
CountedLoopEndNode *main_end = main_head->loopexit();
guarantee(main_end != NULL, "no loop exit node");
// diagnostic to show loop end is not properly formed
assert(main_end->outcnt() == 2, "1 true, 1 false path only");
@ -1293,7 +1291,6 @@ void PhaseIdealLoop::insert_scalar_rced_post_loop(IdealLoopTree *loop, Node_List
// Find common pieces of the loop being guarded with pre & post loops
CountedLoopNode *main_head = loop->_head->as_CountedLoop();
CountedLoopEndNode *main_end = main_head->loopexit();
guarantee(main_end != NULL, "no loop exit node");
// diagnostic to show loop end is not properly formed
assert(main_end->outcnt() == 2, "1 true, 1 false path only");
@ -1427,7 +1424,6 @@ void PhaseIdealLoop::do_unroll( IdealLoopTree *loop, Node_List &old_new, bool ad
assert(LoopUnrollLimit, "");
CountedLoopNode *loop_head = loop->_head->as_CountedLoop();
CountedLoopEndNode *loop_end = loop_head->loopexit();
assert(loop_end, "");
#ifndef PRODUCT
if (PrintOpto && VerifyLoopOptimizations) {
tty->print("Unrolling ");
@ -2972,7 +2968,7 @@ bool PhaseIdealLoop::match_fill_loop(IdealLoopTree* lpt, Node*& store, Node*& st
}
store = n;
store_value = value;
} else if (n->is_If() && n != head->loopexit()) {
} else if (n->is_If() && n != head->loopexit_or_null()) {
msg = "extra control flow";
msg_node = n;
}
@ -3114,7 +3110,6 @@ bool PhaseIdealLoop::match_fill_loop(IdealLoopTree* lpt, Node*& store, Node*& st
ok.set(store->in(MemNode::Memory)->_idx);
CountedLoopEndNode* loop_exit = head->loopexit();
guarantee(loop_exit != NULL, "no loop exit node");
// Loop structure is ok
ok.set(head->_idx);

View File

@ -68,7 +68,7 @@ void LoopNode::dump_spec(outputStream *st) const {
bool LoopNode::is_valid_counted_loop() const {
if (is_CountedLoop()) {
CountedLoopNode* l = as_CountedLoop();
CountedLoopEndNode* le = l->loopexit();
CountedLoopEndNode* le = l->loopexit_or_null();
if (le != NULL &&
le->proj_out_or_null(1 /* true */) == l->in(LoopNode::LoopBackControl)) {
Node* phi = l->phi();
@ -793,7 +793,7 @@ bool PhaseIdealLoop::is_counted_loop(Node* x, IdealLoopTree*& loop) {
#ifdef ASSERT
assert(l->is_valid_counted_loop(), "counted loop shape is messed up");
assert(l == loop->_head && l->phi() == phi && l->loopexit() == lex, "" );
assert(l == loop->_head && l->phi() == phi && l->loopexit_or_null() == lex, "" );
#endif
#ifndef PRODUCT
if (TraceLoopOpts) {
@ -917,7 +917,7 @@ void LoopNode::verify_strip_mined(int expect_skeleton) const {
}
}
CountedLoopEndNode* cle = inner_out->in(0)->as_CountedLoopEnd();
assert(cle == inner->loopexit(), "mismatch");
assert(cle == inner->loopexit_or_null(), "mismatch");
bool has_skeleton = outer_le->in(1)->bottom_type()->singleton() && outer_le->in(1)->bottom_type()->is_int()->get_con() == 0;
if (has_skeleton) {
assert(expect_skeleton == 1 || expect_skeleton == -1, "unexpected skeleton node");

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1998, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1998, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -215,6 +215,7 @@ public:
Node *init_control() const { return in(EntryControl); }
Node *back_control() const { return in(LoopBackControl); }
CountedLoopEndNode *loopexit_or_null() const;
CountedLoopEndNode *loopexit() const;
Node *init_trip() const;
Node *stride() const;
@ -342,7 +343,7 @@ public:
return NULL;
}
Node *ln = iv_phi->in(0);
if (ln->is_CountedLoop() && ln->as_CountedLoop()->loopexit() == this) {
if (ln->is_CountedLoop() && ln->as_CountedLoop()->loopexit_or_null() == this) {
return (CountedLoopNode*)ln;
}
return NULL;
@ -354,7 +355,7 @@ public:
};
inline CountedLoopEndNode *CountedLoopNode::loopexit() const {
inline CountedLoopEndNode *CountedLoopNode::loopexit_or_null() const {
Node *bc = back_control();
if( bc == NULL ) return NULL;
Node *le = bc->in(0);
@ -362,13 +363,18 @@ inline CountedLoopEndNode *CountedLoopNode::loopexit() const {
return NULL;
return (CountedLoopEndNode*)le;
}
inline Node *CountedLoopNode::init_trip() const { return loopexit() ? loopexit()->init_trip() : NULL; }
inline Node *CountedLoopNode::stride() const { return loopexit() ? loopexit()->stride() : NULL; }
inline int CountedLoopNode::stride_con() const { return loopexit() ? loopexit()->stride_con() : 0; }
inline bool CountedLoopNode::stride_is_con() const { return loopexit() && loopexit()->stride_is_con(); }
inline Node *CountedLoopNode::limit() const { return loopexit() ? loopexit()->limit() : NULL; }
inline Node *CountedLoopNode::incr() const { return loopexit() ? loopexit()->incr() : NULL; }
inline Node *CountedLoopNode::phi() const { return loopexit() ? loopexit()->phi() : NULL; }
inline CountedLoopEndNode *CountedLoopNode::loopexit() const {
CountedLoopEndNode* cle = loopexit_or_null();
assert(cle != NULL, "loopexit is NULL");
return cle;
}
inline Node *CountedLoopNode::init_trip() const { return loopexit_or_null() ? loopexit()->init_trip() : NULL; }
inline Node *CountedLoopNode::stride() const { return loopexit_or_null() ? loopexit()->stride() : NULL; }
inline int CountedLoopNode::stride_con() const { return loopexit_or_null() ? loopexit()->stride_con() : 0; }
inline bool CountedLoopNode::stride_is_con() const { return loopexit_or_null() && loopexit()->stride_is_con(); }
inline Node *CountedLoopNode::limit() const { return loopexit_or_null() ? loopexit()->limit() : NULL; }
inline Node *CountedLoopNode::incr() const { return loopexit_or_null() ? loopexit()->incr() : NULL; }
inline Node *CountedLoopNode::phi() const { return loopexit_or_null() ? loopexit()->phi() : NULL; }
//------------------------------LoopLimitNode-----------------------------
// Counted Loop limit node which represents exact final iterator value:

View File

@ -1731,7 +1731,7 @@ void PhaseIdealLoop::clone_outer_loop(LoopNode* head, CloneLoopMode mode, IdealL
Node* sfpt = cl->outer_safepoint();
CountedLoopEndNode* cle = cl->loopexit();
CountedLoopNode* new_cl = old_new[cl->_idx]->as_CountedLoop();
CountedLoopEndNode* new_cle = new_cl->as_CountedLoop()->loopexit();
CountedLoopEndNode* new_cle = new_cl->as_CountedLoop()->loopexit_or_null();
Node* cle_out = cle->proj_out(false);
Node* new_sfpt = NULL;

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2007, 2017, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -190,7 +190,7 @@ void SuperWord::unrolling_analysis(int &local_loop_unroll_factor) {
int *ignored_loop_nodes = NEW_RESOURCE_ARRAY(int, ignored_size);
Node_Stack nstack((int)ignored_size);
CountedLoopNode *cl = lpt()->_head->as_CountedLoop();
Node *cl_exit = cl->loopexit();
Node *cl_exit = cl->loopexit_or_null();
int rpo_idx = _post_block.length();
assert(rpo_idx == 0, "post loop block is empty");