6701887: JDK7 server VM in endless loop in Node::dominates

Thu, 15 May 2008 22:43:11 -0700

author
kvn
date
Thu, 15 May 2008 22:43:11 -0700
changeset 590
723be81c1212
parent 589
09c2ba680204
child 591
5bba3366a9a2
child 597
8aa010f60e0f

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

src/share/vm/opto/c2_globals.hpp file | annotate | diff | comparison | revisions
src/share/vm/opto/memnode.cpp file | annotate | diff | comparison | revisions
src/share/vm/opto/node.cpp file | annotate | diff | comparison | revisions
     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    }

mercurial