Thu, 15 May 2008 22:43:11 -0700
6701887: JDK7 server VM in endless loop in Node::dominates
Summary: The method Node::dominates loops in the dead code which does not have a Region node.
Reviewed-by: jrose, never
1.1 --- a/src/share/vm/opto/c2_globals.hpp Thu May 15 22:40:43 2008 -0700 1.2 +++ b/src/share/vm/opto/c2_globals.hpp Thu May 15 22:43:11 2008 -0700 1.3 @@ -390,5 +390,8 @@ 1.4 \ 1.5 product(intx, MaxLabelRootDepth, 1100, \ 1.6 "Maximum times call Label_Root to prevent stack overflow") \ 1.7 + \ 1.8 + diagnostic(intx, DominatorSearchLimit, 1000, \ 1.9 + "Iterations limit in Node::dominates") \ 1.10 1.11 C2_FLAGS(DECLARE_DEVELOPER_FLAG, DECLARE_PD_DEVELOPER_FLAG, DECLARE_PRODUCT_FLAG, DECLARE_PD_PRODUCT_FLAG, DECLARE_DIAGNOSTIC_FLAG, DECLARE_NOTPRODUCT_FLAG)
2.1 --- a/src/share/vm/opto/memnode.cpp Thu May 15 22:40:43 2008 -0700 2.2 +++ b/src/share/vm/opto/memnode.cpp Thu May 15 22:43:11 2008 -0700 2.3 @@ -256,7 +256,7 @@ 2.4 if (dom == NULL || dom->is_top()) 2.5 return false; // Conservative answer for dead code 2.6 2.7 - if (dom->is_Start() || dom->is_Root() || dom == sub) 2.8 + if (dom->is_Con() || dom->is_Start() || dom->is_Root() || dom == sub) 2.9 return true; 2.10 2.11 // 'dom' dominates 'sub' if its control edge and control edges 2.12 @@ -298,7 +298,7 @@ 2.13 return false; // Conservative answer for dead code 2.14 assert(n->is_CFG(), "expecting control"); 2.15 } 2.16 - if (n->is_Start() || n->is_Root()) { 2.17 + if (n->is_Con() || n->is_Start() || n->is_Root()) { 2.18 only_dominating_controls = true; 2.19 } else if (n->is_CFG()) { 2.20 if (n->dominates(sub, nlist)) 2.21 @@ -308,12 +308,11 @@ 2.22 } else { 2.23 // First, own control edge. 2.24 Node* m = n->find_exact_control(n->in(0)); 2.25 - if (m == NULL) 2.26 - continue; 2.27 - if (m->is_top()) 2.28 - return false; // Conservative answer for dead code 2.29 - dom_list.push(m); 2.30 - 2.31 + if (m != NULL) { 2.32 + if (m->is_top()) 2.33 + return false; // Conservative answer for dead code 2.34 + dom_list.push(m); 2.35 + } 2.36 // Now, the rest of edges. 2.37 uint cnt = n->req(); 2.38 for (uint i = 1; i < cnt; i++) {
3.1 --- a/src/share/vm/opto/node.cpp Thu May 15 22:40:43 2008 -0700 3.2 +++ b/src/share/vm/opto/node.cpp Thu May 15 22:43:11 2008 -0700 3.3 @@ -1043,6 +1043,9 @@ 3.4 assert(this->is_CFG(), "expecting control"); 3.5 assert(sub != NULL && sub->is_CFG(), "expecting control"); 3.6 3.7 + // detect dead cycle without regions 3.8 + int iterations_without_region_limit = DominatorSearchLimit; 3.9 + 3.10 Node* orig_sub = sub; 3.11 nlist.clear(); 3.12 bool this_dominates = false; 3.13 @@ -1057,6 +1060,7 @@ 3.14 // Region nodes were visited. Continue walk up to Start or Root 3.15 // to make sure that it did not walk in a cycle. 3.16 this_dominates = true; // first time meet 3.17 + iterations_without_region_limit = DominatorSearchLimit; // Reset 3.18 } else { 3.19 return false; // already met before: walk in a cycle 3.20 } 3.21 @@ -1069,19 +1073,20 @@ 3.22 return false; // Conservative answer for dead code 3.23 3.24 if (sub == up && sub->is_Loop()) { 3.25 - up = sub->in(0); // in(LoopNode::EntryControl); 3.26 - } else if (sub == up && sub->is_Region()) { 3.27 + up = sub->in(1); // in(LoopNode::EntryControl); 3.28 + } else if (sub == up && sub->is_Region() && sub->req() == 3) { 3.29 + iterations_without_region_limit = DominatorSearchLimit; // Reset 3.30 uint i = 1; 3.31 - if (nlist.size() == 0) { 3.32 + uint size = nlist.size(); 3.33 + if (size == 0) { 3.34 // No Region nodes (except Loops) were visited before. 3.35 // Take first valid path on the way up to 'this'. 3.36 - } else if (nlist.at(nlist.size() - 1) == sub) { 3.37 + } else if (nlist.at(size - 1) == sub) { 3.38 // This Region node was just visited. Take other path. 3.39 i = region_input + 1; 3.40 nlist.pop(); 3.41 } else { 3.42 // Was this Region node visited before? 3.43 - uint size = nlist.size(); 3.44 for (uint j = 0; j < size; j++) { 3.45 if (nlist.at(j) == sub) { 3.46 return false; // The Region node was visited before. Give up. 3.47 @@ -1104,8 +1109,9 @@ 3.48 } 3.49 if (sub == up) 3.50 return false; // some kind of tight cycle 3.51 - if (orig_sub == up) 3.52 - return false; // walk in a cycle 3.53 + 3.54 + if (--iterations_without_region_limit < 0) 3.55 + return false; // dead cycle 3.56 3.57 sub = up; 3.58 }