8194992: Null pointer dereference in MultiNode::proj_out related to loopexit()
authordlong
Thu, 18 Jan 2018 10:05:32 -0800
changeset 48603 e5da6c246176
parent 48602 6481320bb72c
child 48604 37a5a1109b93
8194992: Null pointer dereference in MultiNode::proj_out related to loopexit() Reviewed-by: kvn, thartmann
src/hotspot/share/opto/loopTransform.cpp
src/hotspot/share/opto/loopnode.cpp
src/hotspot/share/opto/loopnode.hpp
src/hotspot/share/opto/loopopts.cpp
src/hotspot/share/opto/superword.cpp
--- a/src/hotspot/share/opto/loopTransform.cpp	Thu Jan 18 16:20:16 2018 +0000
+++ b/src/hotspot/share/opto/loopTransform.cpp	Thu Jan 18 10:05:32 2018 -0800
@@ -1017,7 +1017,6 @@
   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 @@
   // 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 @@
   // 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 @@
   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 @@
       }
       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 @@
   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);
--- a/src/hotspot/share/opto/loopnode.cpp	Thu Jan 18 16:20:16 2018 +0000
+++ b/src/hotspot/share/opto/loopnode.cpp	Thu Jan 18 10:05:32 2018 -0800
@@ -68,7 +68,7 @@
 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 @@
 
 #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 @@
       }
     }
     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");
--- a/src/hotspot/share/opto/loopnode.hpp	Thu Jan 18 16:20:16 2018 +0000
+++ b/src/hotspot/share/opto/loopnode.hpp	Thu Jan 18 10:05:32 2018 -0800
@@ -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 @@
 
   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 @@
       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 @@
 };
 
 
-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 @@
     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:
--- a/src/hotspot/share/opto/loopopts.cpp	Thu Jan 18 16:20:16 2018 +0000
+++ b/src/hotspot/share/opto/loopopts.cpp	Thu Jan 18 10:05:32 2018 -0800
@@ -1731,7 +1731,7 @@
     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;
--- a/src/hotspot/share/opto/superword.cpp	Thu Jan 18 16:20:16 2018 +0000
+++ b/src/hotspot/share/opto/superword.cpp	Thu Jan 18 10:05:32 2018 -0800
@@ -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 @@
   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");