src/share/vm/opto/escape.cpp

changeset 7299
90297adbda9d
parent 7286
87f199a9c1b1
child 7385
9e69e8d1c900
     1.1 --- a/src/share/vm/opto/escape.cpp	Thu Oct 30 10:51:06 2014 +0100
     1.2 +++ b/src/share/vm/opto/escape.cpp	Fri Oct 24 10:28:19 2014 -0700
     1.3 @@ -37,6 +37,8 @@
     1.4  
     1.5  ConnectionGraph::ConnectionGraph(Compile * C, PhaseIterGVN *igvn) :
     1.6    _nodes(C->comp_arena(), C->unique(), C->unique(), NULL),
     1.7 +  _in_worklist(C->comp_arena()),
     1.8 +  _next_pidx(0),
     1.9    _collecting(true),
    1.10    _verify(false),
    1.11    _compile(C),
    1.12 @@ -124,13 +126,19 @@
    1.13    if (C->root() != NULL) {
    1.14      ideal_nodes.push(C->root());
    1.15    }
    1.16 +  // Processed ideal nodes are unique on ideal_nodes list
    1.17 +  // but several ideal nodes are mapped to the phantom_obj.
    1.18 +  // To avoid duplicated entries on the following worklists
    1.19 +  // add the phantom_obj only once to them.
    1.20 +  ptnodes_worklist.append(phantom_obj);
    1.21 +  java_objects_worklist.append(phantom_obj);
    1.22    for( uint next = 0; next < ideal_nodes.size(); ++next ) {
    1.23      Node* n = ideal_nodes.at(next);
    1.24      // Create PointsTo nodes and add them to Connection Graph. Called
    1.25      // only once per ideal node since ideal_nodes is Unique_Node list.
    1.26      add_node_to_connection_graph(n, &delayed_worklist);
    1.27      PointsToNode* ptn = ptnode_adr(n->_idx);
    1.28 -    if (ptn != NULL) {
    1.29 +    if (ptn != NULL && ptn != phantom_obj) {
    1.30        ptnodes_worklist.append(ptn);
    1.31        if (ptn->is_JavaObject()) {
    1.32          java_objects_worklist.append(ptn->as_JavaObject());
    1.33 @@ -414,7 +422,7 @@
    1.34      }
    1.35      case Op_CreateEx: {
    1.36        // assume that all exception objects globally escape
    1.37 -      add_java_object(n, PointsToNode::GlobalEscape);
    1.38 +      map_ideal_node(n, phantom_obj);
    1.39        break;
    1.40      }
    1.41      case Op_LoadKlass:
    1.42 @@ -1065,13 +1073,8 @@
    1.43    // on graph complexity. Observed 8 passes in jvm2008 compiler.compiler.
    1.44    // Set limit to 20 to catch situation when something did go wrong and
    1.45    // bailout Escape Analysis.
    1.46 -  // Also limit build time to 30 sec (60 in debug VM).
    1.47 +  // Also limit build time to 20 sec (60 in debug VM), EscapeAnalysisTimeout flag.
    1.48  #define CG_BUILD_ITER_LIMIT 20
    1.49 -#ifdef ASSERT
    1.50 -#define CG_BUILD_TIME_LIMIT 60.0
    1.51 -#else
    1.52 -#define CG_BUILD_TIME_LIMIT 30.0
    1.53 -#endif
    1.54  
    1.55    // Propagate GlobalEscape and ArgEscape escape states and check that
    1.56    // we still have non-escaping objects. The method pushs on _worklist
    1.57 @@ -1082,12 +1085,13 @@
    1.58    // Now propagate references to all JavaObject nodes.
    1.59    int java_objects_length = java_objects_worklist.length();
    1.60    elapsedTimer time;
    1.61 +  bool timeout = false;
    1.62    int new_edges = 1;
    1.63    int iterations = 0;
    1.64    do {
    1.65      while ((new_edges > 0) &&
    1.66 -          (iterations++   < CG_BUILD_ITER_LIMIT) &&
    1.67 -          (time.seconds() < CG_BUILD_TIME_LIMIT)) {
    1.68 +           (iterations++ < CG_BUILD_ITER_LIMIT)) {
    1.69 +      double start_time = time.seconds();
    1.70        time.start();
    1.71        new_edges = 0;
    1.72        // Propagate references to phantom_object for nodes pushed on _worklist
    1.73 @@ -1096,7 +1100,26 @@
    1.74        for (int next = 0; next < java_objects_length; ++next) {
    1.75          JavaObjectNode* ptn = java_objects_worklist.at(next);
    1.76          new_edges += add_java_object_edges(ptn, true);
    1.77 +
    1.78 +#define SAMPLE_SIZE 4
    1.79 +        if ((next % SAMPLE_SIZE) == 0) {
    1.80 +          // Each 4 iterations calculate how much time it will take
    1.81 +          // to complete graph construction.
    1.82 +          time.stop();
    1.83 +          double stop_time = time.seconds();
    1.84 +          double time_per_iter = (stop_time - start_time) / (double)SAMPLE_SIZE;
    1.85 +          double time_until_end = time_per_iter * (double)(java_objects_length - next);
    1.86 +          if ((start_time + time_until_end) >= EscapeAnalysisTimeout) {
    1.87 +            timeout = true;
    1.88 +            break; // Timeout
    1.89 +          }
    1.90 +          start_time = stop_time;
    1.91 +          time.start();
    1.92 +        }
    1.93 +#undef SAMPLE_SIZE
    1.94 +
    1.95        }
    1.96 +      if (timeout) break;
    1.97        if (new_edges > 0) {
    1.98          // Update escape states on each iteration if graph was updated.
    1.99          if (!find_non_escaped_objects(ptnodes_worklist, non_escaped_worklist)) {
   1.100 @@ -1104,9 +1127,12 @@
   1.101          }
   1.102        }
   1.103        time.stop();
   1.104 +      if (time.seconds() >= EscapeAnalysisTimeout) {
   1.105 +        timeout = true;
   1.106 +        break;
   1.107 +      }
   1.108      }
   1.109 -    if ((iterations     < CG_BUILD_ITER_LIMIT) &&
   1.110 -        (time.seconds() < CG_BUILD_TIME_LIMIT)) {
   1.111 +    if ((iterations < CG_BUILD_ITER_LIMIT) && !timeout) {
   1.112        time.start();
   1.113        // Find fields which have unknown value.
   1.114        int fields_length = oop_fields_worklist.length();
   1.115 @@ -1119,18 +1145,21 @@
   1.116          }
   1.117        }
   1.118        time.stop();
   1.119 +      if (time.seconds() >= EscapeAnalysisTimeout) {
   1.120 +        timeout = true;
   1.121 +        break;
   1.122 +      }
   1.123      } else {
   1.124        new_edges = 0; // Bailout
   1.125      }
   1.126    } while (new_edges > 0);
   1.127  
   1.128    // Bailout if passed limits.
   1.129 -  if ((iterations     >= CG_BUILD_ITER_LIMIT) ||
   1.130 -      (time.seconds() >= CG_BUILD_TIME_LIMIT)) {
   1.131 +  if ((iterations >= CG_BUILD_ITER_LIMIT) || timeout) {
   1.132      Compile* C = _compile;
   1.133      if (C->log() != NULL) {
   1.134        C->log()->begin_elem("connectionGraph_bailout reason='reached ");
   1.135 -      C->log()->text("%s", (iterations >= CG_BUILD_ITER_LIMIT) ? "iterations" : "time");
   1.136 +      C->log()->text("%s", timeout ? "time" : "iterations");
   1.137        C->log()->end_elem(" limit'");
   1.138      }
   1.139      assert(ExitEscapeAnalysisOnTimeout, err_msg_res("infinite EA connection graph build (%f sec, %d iterations) with %d nodes and worklist size %d",
   1.140 @@ -1147,7 +1176,6 @@
   1.141  #endif
   1.142  
   1.143  #undef CG_BUILD_ITER_LIMIT
   1.144 -#undef CG_BUILD_TIME_LIMIT
   1.145  
   1.146    // Find fields initialized by NULL for non-escaping Allocations.
   1.147    int non_escaped_length = non_escaped_worklist.length();
   1.148 @@ -1271,8 +1299,8 @@
   1.149        }
   1.150      }
   1.151    }
   1.152 -  while(_worklist.length() > 0) {
   1.153 -    PointsToNode* use = _worklist.pop();
   1.154 +  for (int l = 0; l < _worklist.length(); l++) {
   1.155 +    PointsToNode* use = _worklist.at(l);
   1.156      if (PointsToNode::is_base_use(use)) {
   1.157        // Add reference from jobj to field and from field to jobj (field's base).
   1.158        use = PointsToNode::get_use_node(use)->as_Field();
   1.159 @@ -1319,6 +1347,8 @@
   1.160        add_field_uses_to_worklist(use->as_Field());
   1.161      }
   1.162    }
   1.163 +  _worklist.clear();
   1.164 +  _in_worklist.Reset();
   1.165    return new_edges;
   1.166  }
   1.167  
   1.168 @@ -1898,7 +1928,7 @@
   1.169      return;
   1.170    }
   1.171    Compile* C = _compile;
   1.172 -  ptadr = new (C->comp_arena()) LocalVarNode(C, n, es);
   1.173 +  ptadr = new (C->comp_arena()) LocalVarNode(this, n, es);
   1.174    _nodes.at_put(n->_idx, ptadr);
   1.175  }
   1.176  
   1.177 @@ -1909,7 +1939,7 @@
   1.178      return;
   1.179    }
   1.180    Compile* C = _compile;
   1.181 -  ptadr = new (C->comp_arena()) JavaObjectNode(C, n, es);
   1.182 +  ptadr = new (C->comp_arena()) JavaObjectNode(this, n, es);
   1.183    _nodes.at_put(n->_idx, ptadr);
   1.184  }
   1.185  
   1.186 @@ -1925,7 +1955,7 @@
   1.187      es = PointsToNode::GlobalEscape;
   1.188    }
   1.189    Compile* C = _compile;
   1.190 -  FieldNode* field = new (C->comp_arena()) FieldNode(C, n, es, offset, is_oop);
   1.191 +  FieldNode* field = new (C->comp_arena()) FieldNode(this, n, es, offset, is_oop);
   1.192    _nodes.at_put(n->_idx, field);
   1.193  }
   1.194  
   1.195 @@ -1939,7 +1969,7 @@
   1.196      return;
   1.197    }
   1.198    Compile* C = _compile;
   1.199 -  ptadr = new (C->comp_arena()) ArraycopyNode(C, n, es);
   1.200 +  ptadr = new (C->comp_arena()) ArraycopyNode(this, n, es);
   1.201    _nodes.at_put(n->_idx, ptadr);
   1.202    // Add edge from arraycopy node to source object.
   1.203    (void)add_edge(ptadr, src);

mercurial