hotspot/src/share/vm/opto/escape.cpp
author kvn
Fri, 29 Feb 2008 19:57:41 -0800
changeset 209 2a924148a40a
parent 1 489c9b5090e2
child 211 e2b60448c234
permissions -rw-r--r--
6667618: disable LoadL->ConvL2I ==> LoadI optimization Summary: this optimization causes problems (sizes of Load and Store nodes do not match) for objects initialization code and Escape Analysis Reviewed-by: jrose, never
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
     1
/*
489c9b5090e2 Initial load
duke
parents:
diff changeset
     2
 * Copyright 2005-2006 Sun Microsystems, Inc.  All Rights Reserved.
489c9b5090e2 Initial load
duke
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
489c9b5090e2 Initial load
duke
parents:
diff changeset
     4
 *
489c9b5090e2 Initial load
duke
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
489c9b5090e2 Initial load
duke
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
489c9b5090e2 Initial load
duke
parents:
diff changeset
     7
 * published by the Free Software Foundation.
489c9b5090e2 Initial load
duke
parents:
diff changeset
     8
 *
489c9b5090e2 Initial load
duke
parents:
diff changeset
     9
 * This code is distributed in the hope that it will be useful, but WITHOUT
489c9b5090e2 Initial load
duke
parents:
diff changeset
    10
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
489c9b5090e2 Initial load
duke
parents:
diff changeset
    11
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
489c9b5090e2 Initial load
duke
parents:
diff changeset
    12
 * version 2 for more details (a copy is included in the LICENSE file that
489c9b5090e2 Initial load
duke
parents:
diff changeset
    13
 * accompanied this code).
489c9b5090e2 Initial load
duke
parents:
diff changeset
    14
 *
489c9b5090e2 Initial load
duke
parents:
diff changeset
    15
 * You should have received a copy of the GNU General Public License version
489c9b5090e2 Initial load
duke
parents:
diff changeset
    16
 * 2 along with this work; if not, write to the Free Software Foundation,
489c9b5090e2 Initial load
duke
parents:
diff changeset
    17
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    18
 *
489c9b5090e2 Initial load
duke
parents:
diff changeset
    19
 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
489c9b5090e2 Initial load
duke
parents:
diff changeset
    20
 * CA 95054 USA or visit www.sun.com if you need additional information or
489c9b5090e2 Initial load
duke
parents:
diff changeset
    21
 * have any questions.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    22
 *
489c9b5090e2 Initial load
duke
parents:
diff changeset
    23
 */
489c9b5090e2 Initial load
duke
parents:
diff changeset
    24
489c9b5090e2 Initial load
duke
parents:
diff changeset
    25
#include "incls/_precompiled.incl"
489c9b5090e2 Initial load
duke
parents:
diff changeset
    26
#include "incls/_escape.cpp.incl"
489c9b5090e2 Initial load
duke
parents:
diff changeset
    27
489c9b5090e2 Initial load
duke
parents:
diff changeset
    28
uint PointsToNode::edge_target(uint e) const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    29
  assert(_edges != NULL && e < (uint)_edges->length(), "valid edge index");
489c9b5090e2 Initial load
duke
parents:
diff changeset
    30
  return (_edges->at(e) >> EdgeShift);
489c9b5090e2 Initial load
duke
parents:
diff changeset
    31
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
    32
489c9b5090e2 Initial load
duke
parents:
diff changeset
    33
PointsToNode::EdgeType PointsToNode::edge_type(uint e) const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    34
  assert(_edges != NULL && e < (uint)_edges->length(), "valid edge index");
489c9b5090e2 Initial load
duke
parents:
diff changeset
    35
  return (EdgeType) (_edges->at(e) & EdgeMask);
489c9b5090e2 Initial load
duke
parents:
diff changeset
    36
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
    37
489c9b5090e2 Initial load
duke
parents:
diff changeset
    38
void PointsToNode::add_edge(uint targIdx, PointsToNode::EdgeType et) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    39
  uint v = (targIdx << EdgeShift) + ((uint) et);
489c9b5090e2 Initial load
duke
parents:
diff changeset
    40
  if (_edges == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    41
     Arena *a = Compile::current()->comp_arena();
489c9b5090e2 Initial load
duke
parents:
diff changeset
    42
    _edges = new(a) GrowableArray<uint>(a, INITIAL_EDGE_COUNT, 0, 0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
    43
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    44
  _edges->append_if_missing(v);
489c9b5090e2 Initial load
duke
parents:
diff changeset
    45
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
    46
489c9b5090e2 Initial load
duke
parents:
diff changeset
    47
void PointsToNode::remove_edge(uint targIdx, PointsToNode::EdgeType et) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    48
  uint v = (targIdx << EdgeShift) + ((uint) et);
489c9b5090e2 Initial load
duke
parents:
diff changeset
    49
489c9b5090e2 Initial load
duke
parents:
diff changeset
    50
  _edges->remove(v);
489c9b5090e2 Initial load
duke
parents:
diff changeset
    51
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
    52
489c9b5090e2 Initial load
duke
parents:
diff changeset
    53
#ifndef PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
    54
static char *node_type_names[] = {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    55
  "UnknownType",
489c9b5090e2 Initial load
duke
parents:
diff changeset
    56
  "JavaObject",
489c9b5090e2 Initial load
duke
parents:
diff changeset
    57
  "LocalVar",
489c9b5090e2 Initial load
duke
parents:
diff changeset
    58
  "Field"
489c9b5090e2 Initial load
duke
parents:
diff changeset
    59
};
489c9b5090e2 Initial load
duke
parents:
diff changeset
    60
489c9b5090e2 Initial load
duke
parents:
diff changeset
    61
static char *esc_names[] = {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    62
  "UnknownEscape",
489c9b5090e2 Initial load
duke
parents:
diff changeset
    63
  "NoEscape     ",
489c9b5090e2 Initial load
duke
parents:
diff changeset
    64
  "ArgEscape    ",
489c9b5090e2 Initial load
duke
parents:
diff changeset
    65
  "GlobalEscape "
489c9b5090e2 Initial load
duke
parents:
diff changeset
    66
};
489c9b5090e2 Initial load
duke
parents:
diff changeset
    67
489c9b5090e2 Initial load
duke
parents:
diff changeset
    68
static char *edge_type_suffix[] = {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    69
 "?", // UnknownEdge
489c9b5090e2 Initial load
duke
parents:
diff changeset
    70
 "P", // PointsToEdge
489c9b5090e2 Initial load
duke
parents:
diff changeset
    71
 "D", // DeferredEdge
489c9b5090e2 Initial load
duke
parents:
diff changeset
    72
 "F"  // FieldEdge
489c9b5090e2 Initial load
duke
parents:
diff changeset
    73
};
489c9b5090e2 Initial load
duke
parents:
diff changeset
    74
489c9b5090e2 Initial load
duke
parents:
diff changeset
    75
void PointsToNode::dump() const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    76
  NodeType nt = node_type();
489c9b5090e2 Initial load
duke
parents:
diff changeset
    77
  EscapeState es = escape_state();
489c9b5090e2 Initial load
duke
parents:
diff changeset
    78
  tty->print("%s  %s  [[", node_type_names[(int) nt], esc_names[(int) es]);
489c9b5090e2 Initial load
duke
parents:
diff changeset
    79
  for (uint i = 0; i < edge_count(); i++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    80
    tty->print(" %d%s", edge_target(i), edge_type_suffix[(int) edge_type(i)]);
489c9b5090e2 Initial load
duke
parents:
diff changeset
    81
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    82
  tty->print("]]  ");
489c9b5090e2 Initial load
duke
parents:
diff changeset
    83
  if (_node == NULL)
489c9b5090e2 Initial load
duke
parents:
diff changeset
    84
    tty->print_cr("<null>");
489c9b5090e2 Initial load
duke
parents:
diff changeset
    85
  else
489c9b5090e2 Initial load
duke
parents:
diff changeset
    86
    _node->dump();
489c9b5090e2 Initial load
duke
parents:
diff changeset
    87
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
    88
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
    89
489c9b5090e2 Initial load
duke
parents:
diff changeset
    90
ConnectionGraph::ConnectionGraph(Compile * C) : _processed(C->comp_arena()), _node_map(C->comp_arena()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    91
  _collecting = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    92
  this->_compile = C;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    93
  const PointsToNode &dummy = PointsToNode();
489c9b5090e2 Initial load
duke
parents:
diff changeset
    94
  _nodes = new(C->comp_arena()) GrowableArray<PointsToNode>(C->comp_arena(), (int) INITIAL_NODE_COUNT, 0, dummy);
489c9b5090e2 Initial load
duke
parents:
diff changeset
    95
  _phantom_object = C->top()->_idx;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    96
  PointsToNode *phn = ptnode_adr(_phantom_object);
489c9b5090e2 Initial load
duke
parents:
diff changeset
    97
  phn->set_node_type(PointsToNode::JavaObject);
489c9b5090e2 Initial load
duke
parents:
diff changeset
    98
  phn->set_escape_state(PointsToNode::GlobalEscape);
489c9b5090e2 Initial load
duke
parents:
diff changeset
    99
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   100
489c9b5090e2 Initial load
duke
parents:
diff changeset
   101
void ConnectionGraph::add_pointsto_edge(uint from_i, uint to_i) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   102
  PointsToNode *f = ptnode_adr(from_i);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   103
  PointsToNode *t = ptnode_adr(to_i);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   104
489c9b5090e2 Initial load
duke
parents:
diff changeset
   105
  assert(f->node_type() != PointsToNode::UnknownType && t->node_type() != PointsToNode::UnknownType, "node types must be set");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   106
  assert(f->node_type() == PointsToNode::LocalVar || f->node_type() == PointsToNode::Field, "invalid source of PointsTo edge");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   107
  assert(t->node_type() == PointsToNode::JavaObject, "invalid destination of PointsTo edge");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   108
  f->add_edge(to_i, PointsToNode::PointsToEdge);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   109
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   110
489c9b5090e2 Initial load
duke
parents:
diff changeset
   111
void ConnectionGraph::add_deferred_edge(uint from_i, uint to_i) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   112
  PointsToNode *f = ptnode_adr(from_i);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   113
  PointsToNode *t = ptnode_adr(to_i);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   114
489c9b5090e2 Initial load
duke
parents:
diff changeset
   115
  assert(f->node_type() != PointsToNode::UnknownType && t->node_type() != PointsToNode::UnknownType, "node types must be set");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   116
  assert(f->node_type() == PointsToNode::LocalVar || f->node_type() == PointsToNode::Field, "invalid source of Deferred edge");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   117
  assert(t->node_type() == PointsToNode::LocalVar || t->node_type() == PointsToNode::Field, "invalid destination of Deferred edge");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   118
  // don't add a self-referential edge, this can occur during removal of
489c9b5090e2 Initial load
duke
parents:
diff changeset
   119
  // deferred edges
489c9b5090e2 Initial load
duke
parents:
diff changeset
   120
  if (from_i != to_i)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   121
    f->add_edge(to_i, PointsToNode::DeferredEdge);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   122
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   123
489c9b5090e2 Initial load
duke
parents:
diff changeset
   124
int ConnectionGraph::type_to_offset(const Type *t) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   125
  const TypePtr *t_ptr = t->isa_ptr();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   126
  assert(t_ptr != NULL, "must be a pointer type");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   127
  return t_ptr->offset();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   128
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   129
489c9b5090e2 Initial load
duke
parents:
diff changeset
   130
void ConnectionGraph::add_field_edge(uint from_i, uint to_i, int offset) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   131
  PointsToNode *f = ptnode_adr(from_i);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   132
  PointsToNode *t = ptnode_adr(to_i);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   133
489c9b5090e2 Initial load
duke
parents:
diff changeset
   134
  assert(f->node_type() != PointsToNode::UnknownType && t->node_type() != PointsToNode::UnknownType, "node types must be set");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   135
  assert(f->node_type() == PointsToNode::JavaObject, "invalid destination of Field edge");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   136
  assert(t->node_type() == PointsToNode::Field, "invalid destination of Field edge");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   137
  assert (t->offset() == -1 || t->offset() == offset, "conflicting field offsets");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   138
  t->set_offset(offset);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   139
489c9b5090e2 Initial load
duke
parents:
diff changeset
   140
  f->add_edge(to_i, PointsToNode::FieldEdge);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   141
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   142
489c9b5090e2 Initial load
duke
parents:
diff changeset
   143
void ConnectionGraph::set_escape_state(uint ni, PointsToNode::EscapeState es) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   144
  PointsToNode *npt = ptnode_adr(ni);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   145
  PointsToNode::EscapeState old_es = npt->escape_state();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   146
  if (es > old_es)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   147
    npt->set_escape_state(es);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   148
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   149
489c9b5090e2 Initial load
duke
parents:
diff changeset
   150
PointsToNode::EscapeState ConnectionGraph::escape_state(Node *n, PhaseTransform *phase) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   151
  uint idx = n->_idx;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   152
  PointsToNode::EscapeState es;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   153
489c9b5090e2 Initial load
duke
parents:
diff changeset
   154
  // If we are still collecting we don't know the answer yet
489c9b5090e2 Initial load
duke
parents:
diff changeset
   155
  if (_collecting)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   156
    return PointsToNode::UnknownEscape;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   157
489c9b5090e2 Initial load
duke
parents:
diff changeset
   158
  // if the node was created after the escape computation, return
489c9b5090e2 Initial load
duke
parents:
diff changeset
   159
  // UnknownEscape
489c9b5090e2 Initial load
duke
parents:
diff changeset
   160
  if (idx >= (uint)_nodes->length())
489c9b5090e2 Initial load
duke
parents:
diff changeset
   161
    return PointsToNode::UnknownEscape;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   162
489c9b5090e2 Initial load
duke
parents:
diff changeset
   163
  es = _nodes->at_grow(idx).escape_state();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   164
489c9b5090e2 Initial load
duke
parents:
diff changeset
   165
  // if we have already computed a value, return it
489c9b5090e2 Initial load
duke
parents:
diff changeset
   166
  if (es != PointsToNode::UnknownEscape)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   167
    return es;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   168
489c9b5090e2 Initial load
duke
parents:
diff changeset
   169
  // compute max escape state of anything this node could point to
489c9b5090e2 Initial load
duke
parents:
diff changeset
   170
  VectorSet ptset(Thread::current()->resource_area());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   171
  PointsTo(ptset, n, phase);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   172
  for( VectorSetI i(&ptset); i.test() && es != PointsToNode::GlobalEscape; ++i ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   173
    uint pt = i.elem;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   174
    PointsToNode::EscapeState pes = _nodes->at(pt).escape_state();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   175
    if (pes > es)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   176
      es = pes;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   177
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   178
  // cache the computed escape state
489c9b5090e2 Initial load
duke
parents:
diff changeset
   179
  assert(es != PointsToNode::UnknownEscape, "should have computed an escape state");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   180
  _nodes->adr_at(idx)->set_escape_state(es);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   181
  return es;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   182
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   183
489c9b5090e2 Initial load
duke
parents:
diff changeset
   184
void ConnectionGraph::PointsTo(VectorSet &ptset, Node * n, PhaseTransform *phase) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   185
  VectorSet visited(Thread::current()->resource_area());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   186
  GrowableArray<uint>  worklist;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   187
489c9b5090e2 Initial load
duke
parents:
diff changeset
   188
  n = skip_casts(n);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   189
  PointsToNode  npt = _nodes->at_grow(n->_idx);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   190
489c9b5090e2 Initial load
duke
parents:
diff changeset
   191
  // If we have a JavaObject, return just that object
489c9b5090e2 Initial load
duke
parents:
diff changeset
   192
  if (npt.node_type() == PointsToNode::JavaObject) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   193
    ptset.set(n->_idx);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   194
    return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   195
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   196
  // we may have a Phi which has not been processed
489c9b5090e2 Initial load
duke
parents:
diff changeset
   197
  if (npt._node == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   198
    assert(n->is_Phi(), "unprocessed node must be a Phi");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   199
    record_for_escape_analysis(n);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   200
    npt = _nodes->at(n->_idx);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   201
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   202
  worklist.push(n->_idx);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   203
  while(worklist.length() > 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   204
    int ni = worklist.pop();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   205
    PointsToNode pn = _nodes->at_grow(ni);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   206
    if (!visited.test(ni)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   207
      visited.set(ni);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   208
489c9b5090e2 Initial load
duke
parents:
diff changeset
   209
      // ensure that all inputs of a Phi have been processed
489c9b5090e2 Initial load
duke
parents:
diff changeset
   210
      if (_collecting && pn._node->is_Phi()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   211
        PhiNode *phi = pn._node->as_Phi();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   212
        process_phi_escape(phi, phase);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   213
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   214
489c9b5090e2 Initial load
duke
parents:
diff changeset
   215
      int edges_processed = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   216
      for (uint e = 0; e < pn.edge_count(); e++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   217
        PointsToNode::EdgeType et = pn.edge_type(e);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   218
        if (et == PointsToNode::PointsToEdge) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   219
          ptset.set(pn.edge_target(e));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   220
          edges_processed++;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   221
        } else if (et == PointsToNode::DeferredEdge) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   222
          worklist.push(pn.edge_target(e));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   223
          edges_processed++;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   224
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   225
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   226
      if (edges_processed == 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   227
        // no deferred or pointsto edges found.  Assume the value was set outside
489c9b5090e2 Initial load
duke
parents:
diff changeset
   228
        // this method.  Add the phantom object to the pointsto set.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   229
        ptset.set(_phantom_object);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   230
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   231
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   232
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   233
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   234
489c9b5090e2 Initial load
duke
parents:
diff changeset
   235
void ConnectionGraph::remove_deferred(uint ni) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   236
  VectorSet visited(Thread::current()->resource_area());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   237
489c9b5090e2 Initial load
duke
parents:
diff changeset
   238
  uint i = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   239
  PointsToNode *ptn = ptnode_adr(ni);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   240
489c9b5090e2 Initial load
duke
parents:
diff changeset
   241
  while(i < ptn->edge_count()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   242
    if (ptn->edge_type(i) != PointsToNode::DeferredEdge) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   243
      i++;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   244
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   245
      uint t = ptn->edge_target(i);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   246
      PointsToNode *ptt = ptnode_adr(t);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   247
      ptn->remove_edge(t, PointsToNode::DeferredEdge);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   248
      if(!visited.test(t)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   249
        visited.set(t);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   250
        for (uint j = 0; j < ptt->edge_count(); j++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   251
          uint n1 = ptt->edge_target(j);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   252
          PointsToNode *pt1 = ptnode_adr(n1);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   253
          switch(ptt->edge_type(j)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   254
            case PointsToNode::PointsToEdge:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   255
               add_pointsto_edge(ni, n1);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   256
              break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   257
            case PointsToNode::DeferredEdge:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   258
              add_deferred_edge(ni, n1);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   259
              break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   260
            case PointsToNode::FieldEdge:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   261
              assert(false, "invalid connection graph");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   262
              break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   263
          }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   264
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   265
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   266
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   267
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   268
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   269
489c9b5090e2 Initial load
duke
parents:
diff changeset
   270
489c9b5090e2 Initial load
duke
parents:
diff changeset
   271
//  Add an edge to node given by "to_i" from any field of adr_i whose offset
489c9b5090e2 Initial load
duke
parents:
diff changeset
   272
//  matches "offset"  A deferred edge is added if to_i is a LocalVar, and
489c9b5090e2 Initial load
duke
parents:
diff changeset
   273
//  a pointsto edge is added if it is a JavaObject
489c9b5090e2 Initial load
duke
parents:
diff changeset
   274
489c9b5090e2 Initial load
duke
parents:
diff changeset
   275
void ConnectionGraph::add_edge_from_fields(uint adr_i, uint to_i, int offs) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   276
  PointsToNode an = _nodes->at_grow(adr_i);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   277
  PointsToNode to = _nodes->at_grow(to_i);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   278
  bool deferred = (to.node_type() == PointsToNode::LocalVar);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   279
489c9b5090e2 Initial load
duke
parents:
diff changeset
   280
  for (uint fe = 0; fe < an.edge_count(); fe++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   281
    assert(an.edge_type(fe) == PointsToNode::FieldEdge, "expecting a field edge");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   282
    int fi = an.edge_target(fe);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   283
    PointsToNode pf = _nodes->at_grow(fi);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   284
    int po = pf.offset();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   285
    if (po == offs || po == Type::OffsetBot || offs == Type::OffsetBot) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   286
      if (deferred)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   287
        add_deferred_edge(fi, to_i);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   288
      else
489c9b5090e2 Initial load
duke
parents:
diff changeset
   289
        add_pointsto_edge(fi, to_i);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   290
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   291
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   292
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   293
489c9b5090e2 Initial load
duke
parents:
diff changeset
   294
//  Add a deferred  edge from node given by "from_i" to any field of adr_i whose offset
489c9b5090e2 Initial load
duke
parents:
diff changeset
   295
//  matches "offset"
489c9b5090e2 Initial load
duke
parents:
diff changeset
   296
void ConnectionGraph::add_deferred_edge_to_fields(uint from_i, uint adr_i, int offs) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   297
  PointsToNode an = _nodes->at_grow(adr_i);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   298
  for (uint fe = 0; fe < an.edge_count(); fe++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   299
    assert(an.edge_type(fe) == PointsToNode::FieldEdge, "expecting a field edge");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   300
    int fi = an.edge_target(fe);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   301
    PointsToNode pf = _nodes->at_grow(fi);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   302
    int po = pf.offset();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   303
    if (pf.edge_count() == 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   304
      // we have not seen any stores to this field, assume it was set outside this method
489c9b5090e2 Initial load
duke
parents:
diff changeset
   305
      add_pointsto_edge(fi, _phantom_object);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   306
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   307
    if (po == offs || po == Type::OffsetBot || offs == Type::OffsetBot) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   308
      add_deferred_edge(from_i, fi);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   309
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   310
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   311
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   312
489c9b5090e2 Initial load
duke
parents:
diff changeset
   313
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   314
// Search memory chain of "mem" to find a MemNode whose address
489c9b5090e2 Initial load
duke
parents:
diff changeset
   315
// is the specified alias index.  Returns the MemNode found or the
489c9b5090e2 Initial load
duke
parents:
diff changeset
   316
// first non-MemNode encountered.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   317
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   318
Node *ConnectionGraph::find_mem(Node *mem, int alias_idx, PhaseGVN  *igvn) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   319
  if (mem == NULL)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   320
    return mem;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   321
  while (mem->is_Mem()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   322
    const Type *at = igvn->type(mem->in(MemNode::Address));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   323
    if (at != Type::TOP) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   324
      assert (at->isa_ptr() != NULL, "pointer type required.");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   325
      int idx = _compile->get_alias_index(at->is_ptr());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   326
      if (idx == alias_idx)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   327
        break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   328
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   329
    mem = mem->in(MemNode::Memory);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   330
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   331
  return mem;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   332
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   333
489c9b5090e2 Initial load
duke
parents:
diff changeset
   334
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   335
// Adjust the type and inputs of an AddP which computes the
489c9b5090e2 Initial load
duke
parents:
diff changeset
   336
// address of a field of an instance
489c9b5090e2 Initial load
duke
parents:
diff changeset
   337
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   338
void ConnectionGraph::split_AddP(Node *addp, Node *base,  PhaseGVN  *igvn) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   339
  const TypeOopPtr *t = igvn->type(addp)->isa_oopptr();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   340
  const TypeOopPtr *base_t = igvn->type(base)->isa_oopptr();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   341
  assert(t != NULL,  "expecting oopptr");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   342
  assert(base_t != NULL && base_t->is_instance(), "expecting instance oopptr");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   343
  uint inst_id =  base_t->instance_id();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   344
  assert(!t->is_instance() || t->instance_id() == inst_id,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   345
                             "old type must be non-instance or match new type");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   346
  const TypeOopPtr *tinst = base_t->add_offset(t->offset())->is_oopptr();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   347
  // ensure an alias index is allocated for the instance type
489c9b5090e2 Initial load
duke
parents:
diff changeset
   348
  int alias_idx = _compile->get_alias_index(tinst);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   349
  igvn->set_type(addp, tinst);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   350
  // record the allocation in the node map
489c9b5090e2 Initial load
duke
parents:
diff changeset
   351
  set_map(addp->_idx, get_map(base->_idx));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   352
  // if the Address input is not the appropriate instance type (due to intervening
489c9b5090e2 Initial load
duke
parents:
diff changeset
   353
  // casts,) insert a cast
489c9b5090e2 Initial load
duke
parents:
diff changeset
   354
  Node *adr = addp->in(AddPNode::Address);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   355
  const TypeOopPtr  *atype = igvn->type(adr)->isa_oopptr();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   356
  if (atype->instance_id() != inst_id) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   357
    assert(!atype->is_instance(), "no conflicting instances");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   358
    const TypeOopPtr *new_atype = base_t->add_offset(atype->offset())->isa_oopptr();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   359
    Node *acast = new (_compile, 2) CastPPNode(adr, new_atype);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   360
    acast->set_req(0, adr->in(0));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   361
    igvn->set_type(acast, new_atype);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   362
    record_for_optimizer(acast);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   363
    Node *bcast = acast;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   364
    Node *abase = addp->in(AddPNode::Base);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   365
    if (abase != adr) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   366
      bcast = new (_compile, 2) CastPPNode(abase, base_t);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   367
      bcast->set_req(0, abase->in(0));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   368
      igvn->set_type(bcast, base_t);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   369
      record_for_optimizer(bcast);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   370
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   371
    igvn->hash_delete(addp);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   372
    addp->set_req(AddPNode::Base, bcast);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   373
    addp->set_req(AddPNode::Address, acast);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   374
    igvn->hash_insert(addp);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   375
    record_for_optimizer(addp);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   376
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   377
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   378
489c9b5090e2 Initial load
duke
parents:
diff changeset
   379
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   380
// Create a new version of orig_phi if necessary. Returns either the newly
489c9b5090e2 Initial load
duke
parents:
diff changeset
   381
// created phi or an existing phi.  Sets create_new to indicate wheter  a new
489c9b5090e2 Initial load
duke
parents:
diff changeset
   382
// phi was created.  Cache the last newly created phi in the node map.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   383
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   384
PhiNode *ConnectionGraph::create_split_phi(PhiNode *orig_phi, int alias_idx, GrowableArray<PhiNode *>  &orig_phi_worklist, PhaseGVN  *igvn, bool &new_created) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   385
  Compile *C = _compile;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   386
  new_created = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   387
  int phi_alias_idx = C->get_alias_index(orig_phi->adr_type());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   388
  // nothing to do if orig_phi is bottom memory or matches alias_idx
489c9b5090e2 Initial load
duke
parents:
diff changeset
   389
  if (phi_alias_idx == Compile::AliasIdxBot || phi_alias_idx == alias_idx) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   390
    return orig_phi;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   391
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   392
  // have we already created a Phi for this alias index?
489c9b5090e2 Initial load
duke
parents:
diff changeset
   393
  PhiNode *result = get_map_phi(orig_phi->_idx);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   394
  const TypePtr *atype = C->get_adr_type(alias_idx);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   395
  if (result != NULL && C->get_alias_index(result->adr_type()) == alias_idx) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   396
    return result;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   397
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   398
489c9b5090e2 Initial load
duke
parents:
diff changeset
   399
  orig_phi_worklist.append_if_missing(orig_phi);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   400
  result = PhiNode::make(orig_phi->in(0), NULL, Type::MEMORY, atype);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   401
  set_map_phi(orig_phi->_idx, result);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   402
  igvn->set_type(result, result->bottom_type());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   403
  record_for_optimizer(result);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   404
  new_created = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   405
  return result;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   406
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   407
489c9b5090e2 Initial load
duke
parents:
diff changeset
   408
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   409
// Return a new version  of Memory Phi "orig_phi" with the inputs having the
489c9b5090e2 Initial load
duke
parents:
diff changeset
   410
// specified alias index.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   411
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   412
PhiNode *ConnectionGraph::split_memory_phi(PhiNode *orig_phi, int alias_idx, GrowableArray<PhiNode *>  &orig_phi_worklist, PhaseGVN  *igvn) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   413
489c9b5090e2 Initial load
duke
parents:
diff changeset
   414
  assert(alias_idx != Compile::AliasIdxBot, "can't split out bottom memory");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   415
  Compile *C = _compile;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   416
  bool new_phi_created;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   417
  PhiNode *result =  create_split_phi(orig_phi, alias_idx, orig_phi_worklist, igvn, new_phi_created);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   418
  if (!new_phi_created) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   419
    return result;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   420
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   421
489c9b5090e2 Initial load
duke
parents:
diff changeset
   422
  GrowableArray<PhiNode *>  phi_list;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   423
  GrowableArray<uint>  cur_input;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   424
489c9b5090e2 Initial load
duke
parents:
diff changeset
   425
  PhiNode *phi = orig_phi;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   426
  uint idx = 1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   427
  bool finished = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   428
  while(!finished) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   429
    while (idx < phi->req()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   430
      Node *mem = find_mem(phi->in(idx), alias_idx, igvn);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   431
      if (mem != NULL && mem->is_Phi()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   432
        PhiNode *nphi = create_split_phi(mem->as_Phi(), alias_idx, orig_phi_worklist, igvn, new_phi_created);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   433
        if (new_phi_created) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   434
          // found an phi for which we created a new split, push current one on worklist and begin
489c9b5090e2 Initial load
duke
parents:
diff changeset
   435
          // processing new one
489c9b5090e2 Initial load
duke
parents:
diff changeset
   436
          phi_list.push(phi);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   437
          cur_input.push(idx);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   438
          phi = mem->as_Phi();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   439
          result = nphi;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   440
          idx = 1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   441
          continue;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   442
        } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   443
          mem = nphi;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   444
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   445
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   446
      result->set_req(idx++, mem);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   447
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   448
#ifdef ASSERT
489c9b5090e2 Initial load
duke
parents:
diff changeset
   449
    // verify that the new Phi has an input for each input of the original
489c9b5090e2 Initial load
duke
parents:
diff changeset
   450
    assert( phi->req() == result->req(), "must have same number of inputs.");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   451
    assert( result->in(0) != NULL && result->in(0) == phi->in(0), "regions must match");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   452
    for (uint i = 1; i < phi->req(); i++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   453
      assert((phi->in(i) == NULL) == (result->in(i) == NULL), "inputs must correspond.");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   454
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   455
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
   456
    // we have finished processing a Phi, see if there are any more to do
489c9b5090e2 Initial load
duke
parents:
diff changeset
   457
    finished = (phi_list.length() == 0 );
489c9b5090e2 Initial load
duke
parents:
diff changeset
   458
    if (!finished) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   459
      phi = phi_list.pop();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   460
      idx = cur_input.pop();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   461
      PhiNode *prev_phi = get_map_phi(phi->_idx);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   462
      prev_phi->set_req(idx++, result);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   463
      result = prev_phi;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   464
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   465
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   466
  return result;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   467
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   468
489c9b5090e2 Initial load
duke
parents:
diff changeset
   469
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   470
//  Convert the types of unescaped object to instance types where possible,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   471
//  propagate the new type information through the graph, and update memory
489c9b5090e2 Initial load
duke
parents:
diff changeset
   472
//  edges and MergeMem inputs to reflect the new type.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   473
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   474
//  We start with allocations (and calls which may be allocations)  on alloc_worklist.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   475
//  The processing is done in 4 phases:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   476
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   477
//  Phase 1:  Process possible allocations from alloc_worklist.  Create instance
489c9b5090e2 Initial load
duke
parents:
diff changeset
   478
//            types for the CheckCastPP for allocations where possible.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   479
//            Propagate the the new types through users as follows:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   480
//               casts and Phi:  push users on alloc_worklist
489c9b5090e2 Initial load
duke
parents:
diff changeset
   481
//               AddP:  cast Base and Address inputs to the instance type
489c9b5090e2 Initial load
duke
parents:
diff changeset
   482
//                      push any AddP users on alloc_worklist and push any memnode
489c9b5090e2 Initial load
duke
parents:
diff changeset
   483
//                      users onto memnode_worklist.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   484
//  Phase 2:  Process MemNode's from memnode_worklist. compute new address type and
489c9b5090e2 Initial load
duke
parents:
diff changeset
   485
//            search the Memory chain for a store with the appropriate type
489c9b5090e2 Initial load
duke
parents:
diff changeset
   486
//            address type.  If a Phi is found, create a new version with
489c9b5090e2 Initial load
duke
parents:
diff changeset
   487
//            the approriate memory slices from each of the Phi inputs.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   488
//            For stores, process the users as follows:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   489
//               MemNode:  push on memnode_worklist
489c9b5090e2 Initial load
duke
parents:
diff changeset
   490
//               MergeMem: push on mergemem_worklist
489c9b5090e2 Initial load
duke
parents:
diff changeset
   491
//  Phase 3:  Process MergeMem nodes from mergemem_worklist.  Walk each memory slice
489c9b5090e2 Initial load
duke
parents:
diff changeset
   492
//            moving the first node encountered of each  instance type to the
489c9b5090e2 Initial load
duke
parents:
diff changeset
   493
//            the input corresponding to its alias index.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   494
//            appropriate memory slice.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   495
//  Phase 4:  Update the inputs of non-instance memory Phis and the Memory input of memnodes.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   496
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   497
// In the following example, the CheckCastPP nodes are the cast of allocation
489c9b5090e2 Initial load
duke
parents:
diff changeset
   498
// results and the allocation of node 29 is unescaped and eligible to be an
489c9b5090e2 Initial load
duke
parents:
diff changeset
   499
// instance type.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   500
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   501
// We start with:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   502
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   503
//     7 Parm #memory
489c9b5090e2 Initial load
duke
parents:
diff changeset
   504
//    10  ConI  "12"
489c9b5090e2 Initial load
duke
parents:
diff changeset
   505
//    19  CheckCastPP   "Foo"
489c9b5090e2 Initial load
duke
parents:
diff changeset
   506
//    20  AddP  _ 19 19 10  Foo+12  alias_index=4
489c9b5090e2 Initial load
duke
parents:
diff changeset
   507
//    29  CheckCastPP   "Foo"
489c9b5090e2 Initial load
duke
parents:
diff changeset
   508
//    30  AddP  _ 29 29 10  Foo+12  alias_index=4
489c9b5090e2 Initial load
duke
parents:
diff changeset
   509
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   510
//    40  StoreP  25   7  20   ... alias_index=4
489c9b5090e2 Initial load
duke
parents:
diff changeset
   511
//    50  StoreP  35  40  30   ... alias_index=4
489c9b5090e2 Initial load
duke
parents:
diff changeset
   512
//    60  StoreP  45  50  20   ... alias_index=4
489c9b5090e2 Initial load
duke
parents:
diff changeset
   513
//    70  LoadP    _  60  30   ... alias_index=4
489c9b5090e2 Initial load
duke
parents:
diff changeset
   514
//    80  Phi     75  50  60   Memory alias_index=4
489c9b5090e2 Initial load
duke
parents:
diff changeset
   515
//    90  LoadP    _  80  30   ... alias_index=4
489c9b5090e2 Initial load
duke
parents:
diff changeset
   516
//   100  LoadP    _  80  20   ... alias_index=4
489c9b5090e2 Initial load
duke
parents:
diff changeset
   517
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   518
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   519
// Phase 1 creates an instance type for node 29 assigning it an instance id of 24
489c9b5090e2 Initial load
duke
parents:
diff changeset
   520
// and creating a new alias index for node 30.  This gives:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   521
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   522
//     7 Parm #memory
489c9b5090e2 Initial load
duke
parents:
diff changeset
   523
//    10  ConI  "12"
489c9b5090e2 Initial load
duke
parents:
diff changeset
   524
//    19  CheckCastPP   "Foo"
489c9b5090e2 Initial load
duke
parents:
diff changeset
   525
//    20  AddP  _ 19 19 10  Foo+12  alias_index=4
489c9b5090e2 Initial load
duke
parents:
diff changeset
   526
//    29  CheckCastPP   "Foo"  iid=24
489c9b5090e2 Initial load
duke
parents:
diff changeset
   527
//    30  AddP  _ 29 29 10  Foo+12  alias_index=6  iid=24
489c9b5090e2 Initial load
duke
parents:
diff changeset
   528
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   529
//    40  StoreP  25   7  20   ... alias_index=4
489c9b5090e2 Initial load
duke
parents:
diff changeset
   530
//    50  StoreP  35  40  30   ... alias_index=6
489c9b5090e2 Initial load
duke
parents:
diff changeset
   531
//    60  StoreP  45  50  20   ... alias_index=4
489c9b5090e2 Initial load
duke
parents:
diff changeset
   532
//    70  LoadP    _  60  30   ... alias_index=6
489c9b5090e2 Initial load
duke
parents:
diff changeset
   533
//    80  Phi     75  50  60   Memory alias_index=4
489c9b5090e2 Initial load
duke
parents:
diff changeset
   534
//    90  LoadP    _  80  30   ... alias_index=6
489c9b5090e2 Initial load
duke
parents:
diff changeset
   535
//   100  LoadP    _  80  20   ... alias_index=4
489c9b5090e2 Initial load
duke
parents:
diff changeset
   536
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   537
// In phase 2, new memory inputs are computed for the loads and stores,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   538
// And a new version of the phi is created.  In phase 4, the inputs to
489c9b5090e2 Initial load
duke
parents:
diff changeset
   539
// node 80 are updated and then the memory nodes are updated with the
489c9b5090e2 Initial load
duke
parents:
diff changeset
   540
// values computed in phase 2.  This results in:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   541
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   542
//     7 Parm #memory
489c9b5090e2 Initial load
duke
parents:
diff changeset
   543
//    10  ConI  "12"
489c9b5090e2 Initial load
duke
parents:
diff changeset
   544
//    19  CheckCastPP   "Foo"
489c9b5090e2 Initial load
duke
parents:
diff changeset
   545
//    20  AddP  _ 19 19 10  Foo+12  alias_index=4
489c9b5090e2 Initial load
duke
parents:
diff changeset
   546
//    29  CheckCastPP   "Foo"  iid=24
489c9b5090e2 Initial load
duke
parents:
diff changeset
   547
//    30  AddP  _ 29 29 10  Foo+12  alias_index=6  iid=24
489c9b5090e2 Initial load
duke
parents:
diff changeset
   548
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   549
//    40  StoreP  25  7   20   ... alias_index=4
489c9b5090e2 Initial load
duke
parents:
diff changeset
   550
//    50  StoreP  35  7   30   ... alias_index=6
489c9b5090e2 Initial load
duke
parents:
diff changeset
   551
//    60  StoreP  45  40  20   ... alias_index=4
489c9b5090e2 Initial load
duke
parents:
diff changeset
   552
//    70  LoadP    _  50  30   ... alias_index=6
489c9b5090e2 Initial load
duke
parents:
diff changeset
   553
//    80  Phi     75  40  60   Memory alias_index=4
489c9b5090e2 Initial load
duke
parents:
diff changeset
   554
//   120  Phi     75  50  50   Memory alias_index=6
489c9b5090e2 Initial load
duke
parents:
diff changeset
   555
//    90  LoadP    _ 120  30   ... alias_index=6
489c9b5090e2 Initial load
duke
parents:
diff changeset
   556
//   100  LoadP    _  80  20   ... alias_index=4
489c9b5090e2 Initial load
duke
parents:
diff changeset
   557
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   558
void ConnectionGraph::split_unique_types(GrowableArray<Node *>  &alloc_worklist) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   559
  GrowableArray<Node *>  memnode_worklist;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   560
  GrowableArray<Node *>  mergemem_worklist;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   561
  GrowableArray<PhiNode *>  orig_phis;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   562
  PhaseGVN  *igvn = _compile->initial_gvn();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   563
  uint new_index_start = (uint) _compile->num_alias_types();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   564
  VectorSet visited(Thread::current()->resource_area());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   565
  VectorSet ptset(Thread::current()->resource_area());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   566
489c9b5090e2 Initial load
duke
parents:
diff changeset
   567
  //  Phase 1:  Process possible allocations from alloc_worklist.  Create instance
489c9b5090e2 Initial load
duke
parents:
diff changeset
   568
  //            types for the CheckCastPP for allocations where possible.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   569
  while (alloc_worklist.length() != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   570
    Node *n = alloc_worklist.pop();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   571
    uint ni = n->_idx;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   572
    if (n->is_Call()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   573
      CallNode *alloc = n->as_Call();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   574
      // copy escape information to call node
489c9b5090e2 Initial load
duke
parents:
diff changeset
   575
      PointsToNode ptn = _nodes->at(alloc->_idx);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   576
      PointsToNode::EscapeState es = escape_state(alloc, igvn);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   577
      alloc->_escape_state = es;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   578
      // find CheckCastPP of call return value
489c9b5090e2 Initial load
duke
parents:
diff changeset
   579
      n = alloc->proj_out(TypeFunc::Parms);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   580
      if (n != NULL && n->outcnt() == 1) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   581
        n = n->unique_out();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   582
        if (n->Opcode() != Op_CheckCastPP) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   583
          continue;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   584
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   585
      } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   586
        continue;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   587
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   588
      // we have an allocation or call which returns a Java object, see if it is unescaped
489c9b5090e2 Initial load
duke
parents:
diff changeset
   589
      if (es != PointsToNode::NoEscape || !ptn._unique_type) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   590
        continue; //  can't make a unique type
489c9b5090e2 Initial load
duke
parents:
diff changeset
   591
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   592
      set_map(alloc->_idx, n);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   593
      set_map(n->_idx, alloc);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   594
      const TypeInstPtr *t = igvn->type(n)->isa_instptr();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   595
      // Unique types which are arrays are not currently supported.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   596
      // The check for AllocateArray is needed in case an array
489c9b5090e2 Initial load
duke
parents:
diff changeset
   597
      // allocation is immediately cast to Object
489c9b5090e2 Initial load
duke
parents:
diff changeset
   598
      if (t == NULL || alloc->is_AllocateArray())
489c9b5090e2 Initial load
duke
parents:
diff changeset
   599
        continue;  // not a TypeInstPtr
489c9b5090e2 Initial load
duke
parents:
diff changeset
   600
      const TypeOopPtr *tinst = t->cast_to_instance(ni);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   601
      igvn->hash_delete(n);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   602
      igvn->set_type(n,  tinst);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   603
      n->raise_bottom_type(tinst);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   604
      igvn->hash_insert(n);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   605
    } else if (n->is_AddP()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   606
      ptset.Clear();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   607
      PointsTo(ptset, n->in(AddPNode::Address), igvn);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   608
      assert(ptset.Size() == 1, "AddP address is unique");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   609
      Node *base = get_map(ptset.getelem());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   610
      split_AddP(n, base, igvn);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   611
    } else if (n->is_Phi() || n->Opcode() == Op_CastPP || n->Opcode() == Op_CheckCastPP) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   612
      if (visited.test_set(n->_idx)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   613
        assert(n->is_Phi(), "loops only through Phi's");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   614
        continue;  // already processed
489c9b5090e2 Initial load
duke
parents:
diff changeset
   615
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   616
      ptset.Clear();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   617
      PointsTo(ptset, n, igvn);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   618
      if (ptset.Size() == 1) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   619
        TypeNode *tn = n->as_Type();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   620
        Node *val = get_map(ptset.getelem());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   621
        const TypeInstPtr *val_t = igvn->type(val)->isa_instptr();;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   622
        assert(val_t != NULL && val_t->is_instance(), "instance type expected.");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   623
        const TypeInstPtr *tn_t = igvn->type(tn)->isa_instptr();;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   624
489c9b5090e2 Initial load
duke
parents:
diff changeset
   625
        if (tn_t != NULL && val_t->cast_to_instance(TypeOopPtr::UNKNOWN_INSTANCE)->higher_equal(tn_t)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   626
          igvn->hash_delete(tn);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   627
          igvn->set_type(tn, val_t);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   628
          tn->set_type(val_t);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   629
          igvn->hash_insert(tn);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   630
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   631
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   632
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   633
      continue;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   634
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   635
    // push users on appropriate worklist
489c9b5090e2 Initial load
duke
parents:
diff changeset
   636
    for (DUIterator_Fast imax, i = n->fast_outs(imax); i < imax; i++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   637
      Node *use = n->fast_out(i);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   638
      if(use->is_Mem() && use->in(MemNode::Address) == n) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   639
        memnode_worklist.push(use);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   640
      } else if (use->is_AddP() || use->is_Phi() || use->Opcode() == Op_CastPP || use->Opcode() == Op_CheckCastPP) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   641
        alloc_worklist.push(use);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   642
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   643
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   644
489c9b5090e2 Initial load
duke
parents:
diff changeset
   645
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   646
  uint new_index_end = (uint) _compile->num_alias_types();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   647
489c9b5090e2 Initial load
duke
parents:
diff changeset
   648
  //  Phase 2:  Process MemNode's from memnode_worklist. compute new address type and
489c9b5090e2 Initial load
duke
parents:
diff changeset
   649
  //            compute new values for Memory inputs  (the Memory inputs are not
489c9b5090e2 Initial load
duke
parents:
diff changeset
   650
  //            actually updated until phase 4.)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   651
  if (memnode_worklist.length() == 0)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   652
    return;  // nothing to do
489c9b5090e2 Initial load
duke
parents:
diff changeset
   653
489c9b5090e2 Initial load
duke
parents:
diff changeset
   654
489c9b5090e2 Initial load
duke
parents:
diff changeset
   655
  while (memnode_worklist.length() != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   656
    Node *n = memnode_worklist.pop();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   657
    if (n->is_Phi()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   658
      assert(n->as_Phi()->adr_type() != TypePtr::BOTTOM, "narrow memory slice required");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   659
      // we don't need to do anything, but the users must be pushed if we haven't processed
489c9b5090e2 Initial load
duke
parents:
diff changeset
   660
      // this Phi before
489c9b5090e2 Initial load
duke
parents:
diff changeset
   661
      if (visited.test_set(n->_idx))
489c9b5090e2 Initial load
duke
parents:
diff changeset
   662
        continue;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   663
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   664
      assert(n->is_Mem(), "memory node required.");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   665
      Node *addr = n->in(MemNode::Address);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   666
      const Type *addr_t = igvn->type(addr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   667
      if (addr_t == Type::TOP)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   668
        continue;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   669
      assert (addr_t->isa_ptr() != NULL, "pointer type required.");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   670
      int alias_idx = _compile->get_alias_index(addr_t->is_ptr());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   671
      Node *mem = find_mem(n->in(MemNode::Memory), alias_idx, igvn);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   672
      if (mem->is_Phi()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   673
        mem = split_memory_phi(mem->as_Phi(), alias_idx, orig_phis, igvn);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   674
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   675
      if (mem != n->in(MemNode::Memory))
489c9b5090e2 Initial load
duke
parents:
diff changeset
   676
        set_map(n->_idx, mem);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   677
      if (n->is_Load()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   678
        continue;  // don't push users
489c9b5090e2 Initial load
duke
parents:
diff changeset
   679
      } else if (n->is_LoadStore()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   680
        // get the memory projection
489c9b5090e2 Initial load
duke
parents:
diff changeset
   681
        for (DUIterator_Fast imax, i = n->fast_outs(imax); i < imax; i++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   682
          Node *use = n->fast_out(i);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   683
          if (use->Opcode() == Op_SCMemProj) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   684
            n = use;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   685
            break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   686
          }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   687
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   688
        assert(n->Opcode() == Op_SCMemProj, "memory projection required");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   689
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   690
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   691
    // push user on appropriate worklist
489c9b5090e2 Initial load
duke
parents:
diff changeset
   692
    for (DUIterator_Fast imax, i = n->fast_outs(imax); i < imax; i++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   693
      Node *use = n->fast_out(i);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   694
      if (use->is_Phi()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   695
        memnode_worklist.push(use);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   696
      } else if(use->is_Mem() && use->in(MemNode::Memory) == n) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   697
        memnode_worklist.push(use);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   698
      } else if (use->is_MergeMem()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   699
        mergemem_worklist.push(use);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   700
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   701
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   702
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   703
489c9b5090e2 Initial load
duke
parents:
diff changeset
   704
  //  Phase 3:  Process MergeMem nodes from mergemem_worklist.  Walk each memory slice
489c9b5090e2 Initial load
duke
parents:
diff changeset
   705
  //            moving the first node encountered of each  instance type to the
489c9b5090e2 Initial load
duke
parents:
diff changeset
   706
  //            the input corresponding to its alias index.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   707
  while (mergemem_worklist.length() != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   708
    Node *n = mergemem_worklist.pop();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   709
    assert(n->is_MergeMem(), "MergeMem node required.");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   710
    MergeMemNode *nmm = n->as_MergeMem();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   711
    // Note: we don't want to use MergeMemStream here because we only want to
489c9b5090e2 Initial load
duke
parents:
diff changeset
   712
    //       scan inputs which exist at the start, not ones we add during processing
489c9b5090e2 Initial load
duke
parents:
diff changeset
   713
    uint nslices = nmm->req();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   714
    igvn->hash_delete(nmm);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   715
    for (uint i = Compile::AliasIdxRaw+1; i < nslices; i++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   716
      Node * mem = nmm->in(i);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   717
      Node * cur = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   718
      if (mem == NULL || mem->is_top())
489c9b5090e2 Initial load
duke
parents:
diff changeset
   719
        continue;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   720
      while (mem->is_Mem()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   721
        const Type *at = igvn->type(mem->in(MemNode::Address));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   722
        if (at != Type::TOP) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   723
          assert (at->isa_ptr() != NULL, "pointer type required.");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   724
          uint idx = (uint)_compile->get_alias_index(at->is_ptr());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   725
          if (idx == i) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   726
            if (cur == NULL)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   727
              cur = mem;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   728
          } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   729
            if (idx >= nmm->req() || nmm->is_empty_memory(nmm->in(idx))) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   730
              nmm->set_memory_at(idx, mem);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   731
            }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   732
          }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   733
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   734
        mem = mem->in(MemNode::Memory);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   735
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   736
      nmm->set_memory_at(i, (cur != NULL) ? cur : mem);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   737
      if (mem->is_Phi()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   738
        // We have encountered a Phi, we need to split the Phi for
489c9b5090e2 Initial load
duke
parents:
diff changeset
   739
        // any  instance of the current type if we haven't encountered
489c9b5090e2 Initial load
duke
parents:
diff changeset
   740
        //  a value of the instance along the chain.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   741
        for (uint ni = new_index_start; ni < new_index_end; ni++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   742
          if((uint)_compile->get_general_index(ni) == i) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   743
            Node *m = (ni >= nmm->req()) ? nmm->empty_memory() : nmm->in(ni);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   744
            if (nmm->is_empty_memory(m)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   745
              nmm->set_memory_at(ni, split_memory_phi(mem->as_Phi(), ni, orig_phis, igvn));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   746
            }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   747
          }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   748
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   749
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   750
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   751
    igvn->hash_insert(nmm);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   752
    record_for_optimizer(nmm);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   753
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   754
489c9b5090e2 Initial load
duke
parents:
diff changeset
   755
  //  Phase 4:  Update the inputs of non-instance memory Phis and the Memory input of memnodes
489c9b5090e2 Initial load
duke
parents:
diff changeset
   756
  //
489c9b5090e2 Initial load
duke
parents:
diff changeset
   757
  // First update the inputs of any non-instance Phi's from
489c9b5090e2 Initial load
duke
parents:
diff changeset
   758
  // which we split out an instance Phi.  Note we don't have
489c9b5090e2 Initial load
duke
parents:
diff changeset
   759
  // to recursively process Phi's encounted on the input memory
489c9b5090e2 Initial load
duke
parents:
diff changeset
   760
  // chains as is done in split_memory_phi() since they  will
489c9b5090e2 Initial load
duke
parents:
diff changeset
   761
  // also be processed here.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   762
  while (orig_phis.length() != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   763
    PhiNode *phi = orig_phis.pop();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   764
    int alias_idx = _compile->get_alias_index(phi->adr_type());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   765
    igvn->hash_delete(phi);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   766
    for (uint i = 1; i < phi->req(); i++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   767
      Node *mem = phi->in(i);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   768
      Node *new_mem = find_mem(mem, alias_idx, igvn);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   769
      if (mem != new_mem) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   770
        phi->set_req(i, new_mem);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   771
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   772
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   773
    igvn->hash_insert(phi);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   774
    record_for_optimizer(phi);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   775
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   776
489c9b5090e2 Initial load
duke
parents:
diff changeset
   777
  // Update the memory inputs of MemNodes with the value we computed
489c9b5090e2 Initial load
duke
parents:
diff changeset
   778
  // in Phase 2.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   779
  for (int i = 0; i < _nodes->length(); i++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   780
    Node *nmem = get_map(i);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   781
    if (nmem != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   782
      Node *n = _nodes->at(i)._node;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   783
      if (n != NULL && n->is_Mem()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   784
        igvn->hash_delete(n);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   785
        n->set_req(MemNode::Memory, nmem);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   786
        igvn->hash_insert(n);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   787
        record_for_optimizer(n);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   788
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   789
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   790
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   791
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   792
489c9b5090e2 Initial load
duke
parents:
diff changeset
   793
void ConnectionGraph::compute_escape() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   794
  GrowableArray<int>  worklist;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   795
  GrowableArray<Node *>  alloc_worklist;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   796
  VectorSet visited(Thread::current()->resource_area());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   797
  PhaseGVN  *igvn = _compile->initial_gvn();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   798
489c9b5090e2 Initial load
duke
parents:
diff changeset
   799
  // process Phi nodes from the deferred list, they may not have
489c9b5090e2 Initial load
duke
parents:
diff changeset
   800
  while(_deferred.size() > 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   801
    Node * n = _deferred.pop();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   802
    PhiNode * phi = n->as_Phi();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   803
489c9b5090e2 Initial load
duke
parents:
diff changeset
   804
    process_phi_escape(phi, igvn);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   805
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   806
489c9b5090e2 Initial load
duke
parents:
diff changeset
   807
  VectorSet ptset(Thread::current()->resource_area());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   808
489c9b5090e2 Initial load
duke
parents:
diff changeset
   809
  // remove deferred edges from the graph and collect
489c9b5090e2 Initial load
duke
parents:
diff changeset
   810
  // information we will need for type splitting
489c9b5090e2 Initial load
duke
parents:
diff changeset
   811
  for (uint ni = 0; ni < (uint)_nodes->length(); ni++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   812
    PointsToNode * ptn = _nodes->adr_at(ni);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   813
    PointsToNode::NodeType nt = ptn->node_type();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   814
489c9b5090e2 Initial load
duke
parents:
diff changeset
   815
    if (nt == PointsToNode::UnknownType) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   816
      continue;  // not a node we are interested in
489c9b5090e2 Initial load
duke
parents:
diff changeset
   817
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   818
    Node *n = ptn->_node;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   819
    if (nt == PointsToNode::LocalVar || nt == PointsToNode::Field) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   820
      remove_deferred(ni);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   821
      if (n->is_AddP()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   822
        // if this AddP computes an address which may point to more that one
489c9b5090e2 Initial load
duke
parents:
diff changeset
   823
        // object, nothing the address points to can be a unique type.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   824
        Node *base = n->in(AddPNode::Base);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   825
        ptset.Clear();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   826
        PointsTo(ptset, base, igvn);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   827
        if (ptset.Size() > 1) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   828
          for( VectorSetI j(&ptset); j.test(); ++j ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   829
            PointsToNode *ptaddr = _nodes->adr_at(j.elem);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   830
            ptaddr->_unique_type = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   831
          }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   832
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   833
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   834
    } else if (n->is_Call()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   835
        // initialize _escape_state of calls to GlobalEscape
489c9b5090e2 Initial load
duke
parents:
diff changeset
   836
        n->as_Call()->_escape_state = PointsToNode::GlobalEscape;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   837
        // push call on alloc_worlist (alocations are calls)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   838
        // for processing by split_unique_types()
489c9b5090e2 Initial load
duke
parents:
diff changeset
   839
        alloc_worklist.push(n);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   840
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   841
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   842
  // push all GlobalEscape nodes on the worklist
489c9b5090e2 Initial load
duke
parents:
diff changeset
   843
  for (uint nj = 0; nj < (uint)_nodes->length(); nj++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   844
    if (_nodes->at(nj).escape_state() == PointsToNode::GlobalEscape) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   845
      worklist.append(nj);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   846
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   847
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   848
  // mark all node reachable from GlobalEscape nodes
489c9b5090e2 Initial load
duke
parents:
diff changeset
   849
  while(worklist.length() > 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   850
    PointsToNode n = _nodes->at(worklist.pop());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   851
    for (uint ei = 0; ei < n.edge_count(); ei++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   852
      uint npi = n.edge_target(ei);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   853
      PointsToNode *np = ptnode_adr(npi);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   854
      if (np->escape_state() != PointsToNode::GlobalEscape) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   855
        np->set_escape_state(PointsToNode::GlobalEscape);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   856
        worklist.append_if_missing(npi);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   857
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   858
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   859
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   860
489c9b5090e2 Initial load
duke
parents:
diff changeset
   861
  // push all ArgEscape nodes on the worklist
489c9b5090e2 Initial load
duke
parents:
diff changeset
   862
  for (uint nk = 0; nk < (uint)_nodes->length(); nk++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   863
    if (_nodes->at(nk).escape_state() == PointsToNode::ArgEscape)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   864
      worklist.push(nk);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   865
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   866
  // mark all node reachable from ArgEscape nodes
489c9b5090e2 Initial load
duke
parents:
diff changeset
   867
  while(worklist.length() > 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   868
    PointsToNode n = _nodes->at(worklist.pop());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   869
489c9b5090e2 Initial load
duke
parents:
diff changeset
   870
    for (uint ei = 0; ei < n.edge_count(); ei++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   871
      uint npi = n.edge_target(ei);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   872
      PointsToNode *np = ptnode_adr(npi);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   873
      if (np->escape_state() != PointsToNode::ArgEscape) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   874
        np->set_escape_state(PointsToNode::ArgEscape);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   875
        worklist.append_if_missing(npi);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   876
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   877
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   878
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   879
  _collecting = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   880
489c9b5090e2 Initial load
duke
parents:
diff changeset
   881
  // Now use the escape information to create unique types for
489c9b5090e2 Initial load
duke
parents:
diff changeset
   882
  // unescaped objects
489c9b5090e2 Initial load
duke
parents:
diff changeset
   883
  split_unique_types(alloc_worklist);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   884
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   885
489c9b5090e2 Initial load
duke
parents:
diff changeset
   886
Node * ConnectionGraph::skip_casts(Node *n) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   887
  while(n->Opcode() == Op_CastPP || n->Opcode() == Op_CheckCastPP) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   888
    n = n->in(1);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   889
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   890
  return n;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   891
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   892
489c9b5090e2 Initial load
duke
parents:
diff changeset
   893
void ConnectionGraph::process_phi_escape(PhiNode *phi, PhaseTransform *phase) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   894
489c9b5090e2 Initial load
duke
parents:
diff changeset
   895
  if (phi->type()->isa_oopptr() == NULL)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   896
    return;  // nothing to do if not an oop
489c9b5090e2 Initial load
duke
parents:
diff changeset
   897
489c9b5090e2 Initial load
duke
parents:
diff changeset
   898
  PointsToNode *ptadr = ptnode_adr(phi->_idx);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   899
  int incount = phi->req();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   900
  int non_null_inputs = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   901
489c9b5090e2 Initial load
duke
parents:
diff changeset
   902
  for (int i = 1; i < incount ; i++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   903
    if (phi->in(i) != NULL)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   904
      non_null_inputs++;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   905
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   906
  if (non_null_inputs == ptadr->_inputs_processed)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   907
    return;  // no new inputs since the last time this node was processed,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   908
             // the current information is valid
489c9b5090e2 Initial load
duke
parents:
diff changeset
   909
489c9b5090e2 Initial load
duke
parents:
diff changeset
   910
  ptadr->_inputs_processed = non_null_inputs;  // prevent recursive processing of this node
489c9b5090e2 Initial load
duke
parents:
diff changeset
   911
  for (int j = 1; j < incount ; j++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   912
    Node * n = phi->in(j);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   913
    if (n == NULL)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   914
      continue;  // ignore NULL
489c9b5090e2 Initial load
duke
parents:
diff changeset
   915
    n =  skip_casts(n);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   916
    if (n->is_top() || n == phi)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   917
      continue;  // ignore top or inputs which go back this node
489c9b5090e2 Initial load
duke
parents:
diff changeset
   918
    int nopc = n->Opcode();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   919
    PointsToNode  npt = _nodes->at(n->_idx);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   920
    if (_nodes->at(n->_idx).node_type() == PointsToNode::JavaObject) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   921
      add_pointsto_edge(phi->_idx, n->_idx);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   922
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   923
      add_deferred_edge(phi->_idx, n->_idx);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   924
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   925
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   926
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   927
489c9b5090e2 Initial load
duke
parents:
diff changeset
   928
void ConnectionGraph::process_call_arguments(CallNode *call, PhaseTransform *phase) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   929
489c9b5090e2 Initial load
duke
parents:
diff changeset
   930
    _processed.set(call->_idx);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   931
    switch (call->Opcode()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   932
489c9b5090e2 Initial load
duke
parents:
diff changeset
   933
    // arguments to allocation and locking don't escape
489c9b5090e2 Initial load
duke
parents:
diff changeset
   934
    case Op_Allocate:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   935
    case Op_AllocateArray:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   936
    case Op_Lock:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   937
    case Op_Unlock:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   938
      break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   939
489c9b5090e2 Initial load
duke
parents:
diff changeset
   940
    case Op_CallStaticJava:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   941
    // For a static call, we know exactly what method is being called.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   942
    // Use bytecode estimator to record the call's escape affects
489c9b5090e2 Initial load
duke
parents:
diff changeset
   943
    {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   944
      ciMethod *meth = call->as_CallJava()->method();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   945
      if (meth != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   946
        const TypeTuple * d = call->tf()->domain();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   947
        BCEscapeAnalyzer call_analyzer(meth);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   948
        VectorSet ptset(Thread::current()->resource_area());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   949
        for (uint i = TypeFunc::Parms; i < d->cnt(); i++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   950
          const Type* at = d->field_at(i);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   951
          int k = i - TypeFunc::Parms;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   952
489c9b5090e2 Initial load
duke
parents:
diff changeset
   953
          if (at->isa_oopptr() != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   954
            Node *arg = skip_casts(call->in(i));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   955
489c9b5090e2 Initial load
duke
parents:
diff changeset
   956
            if (!call_analyzer.is_arg_stack(k)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   957
              // The argument global escapes, mark everything it could point to
489c9b5090e2 Initial load
duke
parents:
diff changeset
   958
              ptset.Clear();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   959
              PointsTo(ptset, arg, phase);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   960
              for( VectorSetI j(&ptset); j.test(); ++j ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   961
                uint pt = j.elem;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   962
489c9b5090e2 Initial load
duke
parents:
diff changeset
   963
                set_escape_state(pt, PointsToNode::GlobalEscape);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   964
              }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   965
            } else if (!call_analyzer.is_arg_local(k)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   966
              // The argument itself doesn't escape, but any fields might
489c9b5090e2 Initial load
duke
parents:
diff changeset
   967
              ptset.Clear();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   968
              PointsTo(ptset, arg, phase);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   969
              for( VectorSetI j(&ptset); j.test(); ++j ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   970
                uint pt = j.elem;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   971
                add_edge_from_fields(pt, _phantom_object, Type::OffsetBot);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   972
              }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   973
            }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   974
          }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   975
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   976
        call_analyzer.copy_dependencies(C()->dependencies());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   977
        break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   978
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   979
      // fall-through if not a Java method
489c9b5090e2 Initial load
duke
parents:
diff changeset
   980
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   981
489c9b5090e2 Initial load
duke
parents:
diff changeset
   982
    default:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   983
    // Some other type of call, assume the worst case: all arguments
489c9b5090e2 Initial load
duke
parents:
diff changeset
   984
    // globally escape.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   985
    {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   986
      // adjust escape state for  outgoing arguments
489c9b5090e2 Initial load
duke
parents:
diff changeset
   987
      const TypeTuple * d = call->tf()->domain();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   988
      VectorSet ptset(Thread::current()->resource_area());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   989
      for (uint i = TypeFunc::Parms; i < d->cnt(); i++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   990
        const Type* at = d->field_at(i);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   991
489c9b5090e2 Initial load
duke
parents:
diff changeset
   992
        if (at->isa_oopptr() != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   993
          Node *arg = skip_casts(call->in(i));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   994
          ptset.Clear();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   995
          PointsTo(ptset, arg, phase);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   996
          for( VectorSetI j(&ptset); j.test(); ++j ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   997
            uint pt = j.elem;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   998
489c9b5090e2 Initial load
duke
parents:
diff changeset
   999
            set_escape_state(pt, PointsToNode::GlobalEscape);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1000
          }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1001
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1002
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1003
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1004
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1005
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1006
void ConnectionGraph::process_call_result(ProjNode *resproj, PhaseTransform *phase) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1007
  CallNode *call = resproj->in(0)->as_Call();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1008
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1009
  PointsToNode *ptadr = ptnode_adr(resproj->_idx);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1010
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1011
  ptadr->_node = resproj;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1012
  ptadr->set_node_type(PointsToNode::LocalVar);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1013
  set_escape_state(resproj->_idx, PointsToNode::UnknownEscape);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1014
  _processed.set(resproj->_idx);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1015
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1016
  switch (call->Opcode()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1017
    case Op_Allocate:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1018
    {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1019
      Node *k = call->in(AllocateNode::KlassNode);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1020
      const TypeKlassPtr *kt;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1021
      if (k->Opcode() == Op_LoadKlass) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1022
        kt = k->as_Load()->type()->isa_klassptr();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1023
      } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1024
        kt = k->as_Type()->type()->isa_klassptr();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1025
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1026
      assert(kt != NULL, "TypeKlassPtr  required.");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1027
      ciKlass* cik = kt->klass();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1028
      ciInstanceKlass* ciik = cik->as_instance_klass();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1029
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1030
      PointsToNode *ptadr = ptnode_adr(call->_idx);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1031
      ptadr->set_node_type(PointsToNode::JavaObject);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1032
      if (cik->is_subclass_of(_compile->env()->Thread_klass()) || ciik->has_finalizer()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1033
        set_escape_state(call->_idx, PointsToNode::GlobalEscape);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1034
        add_pointsto_edge(resproj->_idx, _phantom_object);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1035
      } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1036
        set_escape_state(call->_idx, PointsToNode::NoEscape);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1037
        add_pointsto_edge(resproj->_idx, call->_idx);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1038
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1039
      _processed.set(call->_idx);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1040
      break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1041
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1042
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1043
    case Op_AllocateArray:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1044
    {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1045
      PointsToNode *ptadr = ptnode_adr(call->_idx);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1046
      ptadr->set_node_type(PointsToNode::JavaObject);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1047
      set_escape_state(call->_idx, PointsToNode::NoEscape);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1048
      _processed.set(call->_idx);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1049
      add_pointsto_edge(resproj->_idx, call->_idx);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1050
      break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1051
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1052
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1053
    case Op_Lock:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1054
    case Op_Unlock:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1055
      break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1056
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1057
    case Op_CallStaticJava:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1058
    // For a static call, we know exactly what method is being called.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1059
    // Use bytecode estimator to record whether the call's return value escapes
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1060
    {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1061
      const TypeTuple *r = call->tf()->range();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1062
      const Type* ret_type = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1063
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1064
      if (r->cnt() > TypeFunc::Parms)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1065
        ret_type = r->field_at(TypeFunc::Parms);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1066
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1067
      // Note:  we use isa_ptr() instead of isa_oopptr()  here because the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1068
      //        _multianewarray functions return a TypeRawPtr.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1069
      if (ret_type == NULL || ret_type->isa_ptr() == NULL)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1070
        break;  // doesn't return a pointer type
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1071
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1072
      ciMethod *meth = call->as_CallJava()->method();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1073
      if (meth == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1074
        // not a Java method, assume global escape
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1075
        set_escape_state(call->_idx, PointsToNode::GlobalEscape);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1076
        if (resproj != NULL)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1077
          add_pointsto_edge(resproj->_idx, _phantom_object);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1078
      } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1079
        BCEscapeAnalyzer call_analyzer(meth);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1080
        VectorSet ptset(Thread::current()->resource_area());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1081
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1082
        if (call_analyzer.is_return_local() && resproj != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1083
          // determine whether any arguments are returned
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1084
          const TypeTuple * d = call->tf()->domain();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1085
          set_escape_state(call->_idx, PointsToNode::NoEscape);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1086
          for (uint i = TypeFunc::Parms; i < d->cnt(); i++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1087
            const Type* at = d->field_at(i);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1088
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1089
            if (at->isa_oopptr() != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1090
              Node *arg = skip_casts(call->in(i));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1091
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1092
              if (call_analyzer.is_arg_returned(i - TypeFunc::Parms)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1093
                PointsToNode *arg_esp = _nodes->adr_at(arg->_idx);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1094
                if (arg_esp->node_type() == PointsToNode::JavaObject)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1095
                  add_pointsto_edge(resproj->_idx, arg->_idx);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1096
                else
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1097
                  add_deferred_edge(resproj->_idx, arg->_idx);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1098
                arg_esp->_hidden_alias = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1099
              }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1100
            }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1101
          }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1102
        } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1103
          set_escape_state(call->_idx, PointsToNode::GlobalEscape);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1104
          if (resproj != NULL)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1105
            add_pointsto_edge(resproj->_idx, _phantom_object);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1106
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1107
        call_analyzer.copy_dependencies(C()->dependencies());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1108
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1109
      break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1110
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1111
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1112
    default:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1113
    // Some other type of call, assume the worst case that the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1114
    // returned value, if any, globally escapes.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1115
    {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1116
      const TypeTuple *r = call->tf()->range();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1117
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1118
      if (r->cnt() > TypeFunc::Parms) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1119
        const Type* ret_type = r->field_at(TypeFunc::Parms);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1120
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1121
        // Note:  we use isa_ptr() instead of isa_oopptr()  here because the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1122
        //        _multianewarray functions return a TypeRawPtr.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1123
        if (ret_type->isa_ptr() != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1124
          PointsToNode *ptadr = ptnode_adr(call->_idx);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1125
          ptadr->set_node_type(PointsToNode::JavaObject);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1126
          set_escape_state(call->_idx, PointsToNode::GlobalEscape);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1127
          if (resproj != NULL)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1128
            add_pointsto_edge(resproj->_idx, _phantom_object);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1129
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1130
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1131
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1132
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1133
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1134
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1135
void ConnectionGraph::record_for_escape_analysis(Node *n) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1136
  if (_collecting) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1137
    if (n->is_Phi()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1138
      PhiNode *phi = n->as_Phi();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1139
      const Type *pt = phi->type();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1140
      if ((pt->isa_oopptr() != NULL) || pt == TypePtr::NULL_PTR) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1141
        PointsToNode *ptn = ptnode_adr(phi->_idx);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1142
        ptn->set_node_type(PointsToNode::LocalVar);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1143
        ptn->_node = n;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1144
        _deferred.push(n);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1145
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1146
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1147
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1148
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1149
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1150
void ConnectionGraph::record_escape_work(Node *n, PhaseTransform *phase) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1151
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1152
  int opc = n->Opcode();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1153
  PointsToNode *ptadr = ptnode_adr(n->_idx);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1154
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1155
  if (_processed.test(n->_idx))
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1156
    return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1157
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1158
  ptadr->_node = n;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1159
  if (n->is_Call()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1160
    CallNode *call = n->as_Call();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1161
    process_call_arguments(call, phase);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1162
    return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1163
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1164
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1165
  switch (opc) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1166
    case Op_AddP:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1167
    {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1168
      Node *base = skip_casts(n->in(AddPNode::Base));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1169
      ptadr->set_node_type(PointsToNode::Field);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1170
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1171
      // create a field edge to this node from everything adr could point to
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1172
      VectorSet ptset(Thread::current()->resource_area());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1173
      PointsTo(ptset, base, phase);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1174
      for( VectorSetI i(&ptset); i.test(); ++i ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1175
        uint pt = i.elem;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1176
        add_field_edge(pt, n->_idx, type_to_offset(phase->type(n)));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1177
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1178
      break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1179
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1180
    case Op_Parm:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1181
    {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1182
      ProjNode *nproj = n->as_Proj();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1183
      uint con = nproj->_con;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1184
      if (con < TypeFunc::Parms)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1185
        return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1186
      const Type *t = nproj->in(0)->as_Start()->_domain->field_at(con);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1187
      if (t->isa_ptr() == NULL)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1188
        return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1189
      ptadr->set_node_type(PointsToNode::JavaObject);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1190
      if (t->isa_oopptr() != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1191
        set_escape_state(n->_idx, PointsToNode::ArgEscape);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1192
      } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1193
        // this must be the incoming state of an OSR compile, we have to assume anything
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1194
        // passed in globally escapes
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1195
        assert(_compile->is_osr_compilation(), "bad argument type for non-osr compilation");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1196
        set_escape_state(n->_idx, PointsToNode::GlobalEscape);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1197
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1198
      _processed.set(n->_idx);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1199
      break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1200
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1201
    case Op_Phi:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1202
    {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1203
      PhiNode *phi = n->as_Phi();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1204
      if (phi->type()->isa_oopptr() == NULL)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1205
        return;  // nothing to do if not an oop
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1206
      ptadr->set_node_type(PointsToNode::LocalVar);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1207
      process_phi_escape(phi, phase);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1208
      break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1209
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1210
    case Op_CreateEx:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1211
    {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1212
      // assume that all exception objects globally escape
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1213
      ptadr->set_node_type(PointsToNode::JavaObject);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1214
      set_escape_state(n->_idx, PointsToNode::GlobalEscape);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1215
      _processed.set(n->_idx);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1216
      break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1217
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1218
    case Op_ConP:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1219
    {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1220
      const Type *t = phase->type(n);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1221
      ptadr->set_node_type(PointsToNode::JavaObject);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1222
      // assume all pointer constants globally escape except for null
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1223
      if (t == TypePtr::NULL_PTR)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1224
        set_escape_state(n->_idx, PointsToNode::NoEscape);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1225
      else
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1226
        set_escape_state(n->_idx, PointsToNode::GlobalEscape);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1227
      _processed.set(n->_idx);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1228
      break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1229
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1230
    case Op_LoadKlass:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1231
    {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1232
      ptadr->set_node_type(PointsToNode::JavaObject);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1233
      set_escape_state(n->_idx, PointsToNode::GlobalEscape);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1234
      _processed.set(n->_idx);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1235
      break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1236
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1237
    case Op_LoadP:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1238
    {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1239
      const Type *t = phase->type(n);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1240
      if (!t->isa_oopptr())
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1241
        return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1242
      ptadr->set_node_type(PointsToNode::LocalVar);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1243
      set_escape_state(n->_idx, PointsToNode::UnknownEscape);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1244
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1245
      Node *adr = skip_casts(n->in(MemNode::Address));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1246
      const Type *adr_type = phase->type(adr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1247
      Node *adr_base = skip_casts((adr->Opcode() == Op_AddP) ? adr->in(AddPNode::Base) : adr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1248
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1249
      // For everything "adr" could point to, create a deferred edge from
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1250
      // this node to each field with the same offset as "adr_type"
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1251
      VectorSet ptset(Thread::current()->resource_area());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1252
      PointsTo(ptset, adr_base, phase);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1253
      // If ptset is empty, then this value must have been set outside
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1254
      // this method, so we add the phantom node
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1255
      if (ptset.Size() == 0)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1256
        ptset.set(_phantom_object);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1257
      for( VectorSetI i(&ptset); i.test(); ++i ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1258
        uint pt = i.elem;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1259
        add_deferred_edge_to_fields(n->_idx, pt, type_to_offset(adr_type));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1260
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1261
      break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1262
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1263
    case Op_StoreP:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1264
    case Op_StorePConditional:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1265
    case Op_CompareAndSwapP:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1266
    {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1267
      Node *adr = n->in(MemNode::Address);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1268
      Node *val = skip_casts(n->in(MemNode::ValueIn));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1269
      const Type *adr_type = phase->type(adr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1270
      if (!adr_type->isa_oopptr())
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1271
        return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1272
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1273
      assert(adr->Opcode() == Op_AddP, "expecting an AddP");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1274
      Node *adr_base = adr->in(AddPNode::Base);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1275
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1276
      // For everything "adr_base" could point to, create a deferred edge to "val" from each field
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1277
      // with the same offset as "adr_type"
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1278
      VectorSet ptset(Thread::current()->resource_area());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1279
      PointsTo(ptset, adr_base, phase);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1280
      for( VectorSetI i(&ptset); i.test(); ++i ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1281
        uint pt = i.elem;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1282
        add_edge_from_fields(pt, val->_idx, type_to_offset(adr_type));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1283
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1284
      break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1285
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1286
    case Op_Proj:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1287
    {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1288
      ProjNode *nproj = n->as_Proj();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1289
      Node *n0 = nproj->in(0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1290
      // we are only interested in the result projection from a call
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1291
      if (nproj->_con == TypeFunc::Parms && n0->is_Call() ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1292
        process_call_result(nproj, phase);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1293
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1294
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1295
      break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1296
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1297
    case Op_CastPP:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1298
    case Op_CheckCastPP:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1299
    {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1300
      ptadr->set_node_type(PointsToNode::LocalVar);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1301
      int ti = n->in(1)->_idx;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1302
      if (_nodes->at(ti).node_type() == PointsToNode::JavaObject) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1303
        add_pointsto_edge(n->_idx, ti);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1304
      } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1305
        add_deferred_edge(n->_idx, ti);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1306
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1307
      break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1308
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1309
    default:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1310
      ;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1311
      // nothing to do
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1312
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1313
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1314
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1315
void ConnectionGraph::record_escape(Node *n, PhaseTransform *phase) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1316
  if (_collecting)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1317
    record_escape_work(n, phase);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1318
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1319
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1320
#ifndef PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1321
void ConnectionGraph::dump() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1322
  PhaseGVN  *igvn = _compile->initial_gvn();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1323
  bool first = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1324
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1325
  for (uint ni = 0; ni < (uint)_nodes->length(); ni++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1326
    PointsToNode *esp = _nodes->adr_at(ni);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1327
    if (esp->node_type() == PointsToNode::UnknownType || esp->_node == NULL)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1328
      continue;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1329
    PointsToNode::EscapeState es = escape_state(esp->_node, igvn);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1330
    if (es == PointsToNode::NoEscape || (Verbose &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1331
            (es != PointsToNode::UnknownEscape || esp->edge_count() != 0))) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1332
      // don't print null pointer node which almost every method has
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1333
      if (esp->_node->Opcode() != Op_ConP || igvn->type(esp->_node) != TypePtr::NULL_PTR) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1334
        if (first) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1335
          tty->print("======== Connection graph for ");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1336
          C()->method()->print_short_name();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1337
          tty->cr();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1338
          first = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1339
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1340
        tty->print("%4d  ", ni);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1341
        esp->dump();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1342
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1343
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1344
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1345
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1346
#endif