8194992: Null pointer dereference in MultiNode::proj_out related to loopexit()
Reviewed-by: kvn, thartmann
This commit is contained in:
parent
80ac199ab3
commit
4f496a5786
@ -1017,7 +1017,6 @@ void PhaseIdealLoop::insert_pre_post_loops( IdealLoopTree *loop, Node_List &old_
|
|||||||
CountedLoopNode *main_head = loop->_head->as_CountedLoop();
|
CountedLoopNode *main_head = loop->_head->as_CountedLoop();
|
||||||
assert( main_head->is_normal_loop(), "" );
|
assert( main_head->is_normal_loop(), "" );
|
||||||
CountedLoopEndNode *main_end = main_head->loopexit();
|
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" );
|
assert( main_end->outcnt() == 2, "1 true, 1 false path only" );
|
||||||
|
|
||||||
Node *pre_header= main_head->in(LoopNode::EntryControl);
|
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
|
// Find common pieces of the loop being guarded with pre & post loops
|
||||||
CountedLoopNode *main_head = loop->_head->as_CountedLoop();
|
CountedLoopNode *main_head = loop->_head->as_CountedLoop();
|
||||||
CountedLoopEndNode *main_end = main_head->loopexit();
|
CountedLoopEndNode *main_end = main_head->loopexit();
|
||||||
guarantee(main_end != NULL, "no loop exit node");
|
|
||||||
// diagnostic to show loop end is not properly formed
|
// diagnostic to show loop end is not properly formed
|
||||||
assert(main_end->outcnt() == 2, "1 true, 1 false path only");
|
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
|
// Find common pieces of the loop being guarded with pre & post loops
|
||||||
CountedLoopNode *main_head = loop->_head->as_CountedLoop();
|
CountedLoopNode *main_head = loop->_head->as_CountedLoop();
|
||||||
CountedLoopEndNode *main_end = main_head->loopexit();
|
CountedLoopEndNode *main_end = main_head->loopexit();
|
||||||
guarantee(main_end != NULL, "no loop exit node");
|
|
||||||
// diagnostic to show loop end is not properly formed
|
// diagnostic to show loop end is not properly formed
|
||||||
assert(main_end->outcnt() == 2, "1 true, 1 false path only");
|
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, "");
|
assert(LoopUnrollLimit, "");
|
||||||
CountedLoopNode *loop_head = loop->_head->as_CountedLoop();
|
CountedLoopNode *loop_head = loop->_head->as_CountedLoop();
|
||||||
CountedLoopEndNode *loop_end = loop_head->loopexit();
|
CountedLoopEndNode *loop_end = loop_head->loopexit();
|
||||||
assert(loop_end, "");
|
|
||||||
#ifndef PRODUCT
|
#ifndef PRODUCT
|
||||||
if (PrintOpto && VerifyLoopOptimizations) {
|
if (PrintOpto && VerifyLoopOptimizations) {
|
||||||
tty->print("Unrolling ");
|
tty->print("Unrolling ");
|
||||||
@ -2972,7 +2968,7 @@ bool PhaseIdealLoop::match_fill_loop(IdealLoopTree* lpt, Node*& store, Node*& st
|
|||||||
}
|
}
|
||||||
store = n;
|
store = n;
|
||||||
store_value = value;
|
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 = "extra control flow";
|
||||||
msg_node = n;
|
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);
|
ok.set(store->in(MemNode::Memory)->_idx);
|
||||||
|
|
||||||
CountedLoopEndNode* loop_exit = head->loopexit();
|
CountedLoopEndNode* loop_exit = head->loopexit();
|
||||||
guarantee(loop_exit != NULL, "no loop exit node");
|
|
||||||
|
|
||||||
// Loop structure is ok
|
// Loop structure is ok
|
||||||
ok.set(head->_idx);
|
ok.set(head->_idx);
|
||||||
|
@ -68,7 +68,7 @@ void LoopNode::dump_spec(outputStream *st) const {
|
|||||||
bool LoopNode::is_valid_counted_loop() const {
|
bool LoopNode::is_valid_counted_loop() const {
|
||||||
if (is_CountedLoop()) {
|
if (is_CountedLoop()) {
|
||||||
CountedLoopNode* l = as_CountedLoop();
|
CountedLoopNode* l = as_CountedLoop();
|
||||||
CountedLoopEndNode* le = l->loopexit();
|
CountedLoopEndNode* le = l->loopexit_or_null();
|
||||||
if (le != NULL &&
|
if (le != NULL &&
|
||||||
le->proj_out_or_null(1 /* true */) == l->in(LoopNode::LoopBackControl)) {
|
le->proj_out_or_null(1 /* true */) == l->in(LoopNode::LoopBackControl)) {
|
||||||
Node* phi = l->phi();
|
Node* phi = l->phi();
|
||||||
@ -793,7 +793,7 @@ bool PhaseIdealLoop::is_counted_loop(Node* x, IdealLoopTree*& loop) {
|
|||||||
|
|
||||||
#ifdef ASSERT
|
#ifdef ASSERT
|
||||||
assert(l->is_valid_counted_loop(), "counted loop shape is messed up");
|
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
|
#endif
|
||||||
#ifndef PRODUCT
|
#ifndef PRODUCT
|
||||||
if (TraceLoopOpts) {
|
if (TraceLoopOpts) {
|
||||||
@ -917,7 +917,7 @@ void LoopNode::verify_strip_mined(int expect_skeleton) const {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
CountedLoopEndNode* cle = inner_out->in(0)->as_CountedLoopEnd();
|
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;
|
bool has_skeleton = outer_le->in(1)->bottom_type()->singleton() && outer_le->in(1)->bottom_type()->is_int()->get_con() == 0;
|
||||||
if (has_skeleton) {
|
if (has_skeleton) {
|
||||||
assert(expect_skeleton == 1 || expect_skeleton == -1, "unexpected skeleton node");
|
assert(expect_skeleton == 1 || expect_skeleton == -1, "unexpected skeleton node");
|
||||||
|
@ -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.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* 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 *init_control() const { return in(EntryControl); }
|
||||||
Node *back_control() const { return in(LoopBackControl); }
|
Node *back_control() const { return in(LoopBackControl); }
|
||||||
|
CountedLoopEndNode *loopexit_or_null() const;
|
||||||
CountedLoopEndNode *loopexit() const;
|
CountedLoopEndNode *loopexit() const;
|
||||||
Node *init_trip() const;
|
Node *init_trip() const;
|
||||||
Node *stride() const;
|
Node *stride() const;
|
||||||
@ -342,7 +343,7 @@ public:
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
Node *ln = iv_phi->in(0);
|
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 (CountedLoopNode*)ln;
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -354,7 +355,7 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
inline CountedLoopEndNode *CountedLoopNode::loopexit() const {
|
inline CountedLoopEndNode *CountedLoopNode::loopexit_or_null() const {
|
||||||
Node *bc = back_control();
|
Node *bc = back_control();
|
||||||
if( bc == NULL ) return NULL;
|
if( bc == NULL ) return NULL;
|
||||||
Node *le = bc->in(0);
|
Node *le = bc->in(0);
|
||||||
@ -362,13 +363,18 @@ inline CountedLoopEndNode *CountedLoopNode::loopexit() const {
|
|||||||
return NULL;
|
return NULL;
|
||||||
return (CountedLoopEndNode*)le;
|
return (CountedLoopEndNode*)le;
|
||||||
}
|
}
|
||||||
inline Node *CountedLoopNode::init_trip() const { return loopexit() ? loopexit()->init_trip() : NULL; }
|
inline CountedLoopEndNode *CountedLoopNode::loopexit() const {
|
||||||
inline Node *CountedLoopNode::stride() const { return loopexit() ? loopexit()->stride() : NULL; }
|
CountedLoopEndNode* cle = loopexit_or_null();
|
||||||
inline int CountedLoopNode::stride_con() const { return loopexit() ? loopexit()->stride_con() : 0; }
|
assert(cle != NULL, "loopexit is NULL");
|
||||||
inline bool CountedLoopNode::stride_is_con() const { return loopexit() && loopexit()->stride_is_con(); }
|
return cle;
|
||||||
inline Node *CountedLoopNode::limit() const { return loopexit() ? loopexit()->limit() : NULL; }
|
}
|
||||||
inline Node *CountedLoopNode::incr() const { return loopexit() ? loopexit()->incr() : NULL; }
|
inline Node *CountedLoopNode::init_trip() const { return loopexit_or_null() ? loopexit()->init_trip() : NULL; }
|
||||||
inline Node *CountedLoopNode::phi() const { return loopexit() ? loopexit()->phi() : 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-----------------------------
|
//------------------------------LoopLimitNode-----------------------------
|
||||||
// Counted Loop limit node which represents exact final iterator value:
|
// Counted Loop limit node which represents exact final iterator value:
|
||||||
|
@ -1731,7 +1731,7 @@ void PhaseIdealLoop::clone_outer_loop(LoopNode* head, CloneLoopMode mode, IdealL
|
|||||||
Node* sfpt = cl->outer_safepoint();
|
Node* sfpt = cl->outer_safepoint();
|
||||||
CountedLoopEndNode* cle = cl->loopexit();
|
CountedLoopEndNode* cle = cl->loopexit();
|
||||||
CountedLoopNode* new_cl = old_new[cl->_idx]->as_CountedLoop();
|
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* cle_out = cle->proj_out(false);
|
||||||
|
|
||||||
Node* new_sfpt = NULL;
|
Node* new_sfpt = NULL;
|
||||||
|
@ -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.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* 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);
|
int *ignored_loop_nodes = NEW_RESOURCE_ARRAY(int, ignored_size);
|
||||||
Node_Stack nstack((int)ignored_size);
|
Node_Stack nstack((int)ignored_size);
|
||||||
CountedLoopNode *cl = lpt()->_head->as_CountedLoop();
|
CountedLoopNode *cl = lpt()->_head->as_CountedLoop();
|
||||||
Node *cl_exit = cl->loopexit();
|
Node *cl_exit = cl->loopexit_or_null();
|
||||||
int rpo_idx = _post_block.length();
|
int rpo_idx = _post_block.length();
|
||||||
|
|
||||||
assert(rpo_idx == 0, "post loop block is empty");
|
assert(rpo_idx == 0, "post loop block is empty");
|
||||||
|
Loading…
Reference in New Issue
Block a user