src/share/vm/ci/ciTypeFlow.cpp

changeset 802
194b8e3a2fc4
parent 435
a61af66fc99e
child 905
ad8c8ca4ab0f
     1.1 --- a/src/share/vm/ci/ciTypeFlow.cpp	Wed Sep 17 08:29:17 2008 -0700
     1.2 +++ b/src/share/vm/ci/ciTypeFlow.cpp	Wed Sep 17 12:59:52 2008 -0700
     1.3 @@ -338,8 +338,10 @@
     1.4    }
     1.5    _trap_bci = -1;
     1.6    _trap_index = 0;
     1.7 +  _def_locals.clear();
     1.8  }
     1.9  
    1.10 +
    1.11  // ------------------------------------------------------------------
    1.12  // ciTypeFlow::get_start_state
    1.13  //
    1.14 @@ -735,7 +737,7 @@
    1.15  void ciTypeFlow::StateVector::do_new(ciBytecodeStream* str) {
    1.16    bool will_link;
    1.17    ciKlass* klass = str->get_klass(will_link);
    1.18 -  if (!will_link) {
    1.19 +  if (!will_link || str->is_unresolved_klass()) {
    1.20      trap(str, klass, str->get_klass_index());
    1.21    } else {
    1.22      push_object(klass);
    1.23 @@ -1268,7 +1270,9 @@
    1.24      }
    1.25    case Bytecodes::_iinc:
    1.26      {
    1.27 -      check_int(local(str->get_index()));
    1.28 +      int lnum = str->get_index();
    1.29 +      check_int(local(lnum));
    1.30 +      store_to_local(lnum);
    1.31        break;
    1.32      }
    1.33    case Bytecodes::_iload:   load_local_int(str->get_index()); break;
    1.34 @@ -1506,6 +1510,46 @@
    1.35  }
    1.36  #endif
    1.37  
    1.38 +
    1.39 +// ------------------------------------------------------------------
    1.40 +// ciTypeFlow::SuccIter::next
    1.41 +//
    1.42 +void ciTypeFlow::SuccIter::next() {
    1.43 +  int succ_ct = _pred->successors()->length();
    1.44 +  int next = _index + 1;
    1.45 +  if (next < succ_ct) {
    1.46 +    _index = next;
    1.47 +    _succ = _pred->successors()->at(next);
    1.48 +    return;
    1.49 +  }
    1.50 +  for (int i = next - succ_ct; i < _pred->exceptions()->length(); i++) {
    1.51 +    // Do not compile any code for unloaded exception types.
    1.52 +    // Following compiler passes are responsible for doing this also.
    1.53 +    ciInstanceKlass* exception_klass = _pred->exc_klasses()->at(i);
    1.54 +    if (exception_klass->is_loaded()) {
    1.55 +      _index = next;
    1.56 +      _succ = _pred->exceptions()->at(i);
    1.57 +      return;
    1.58 +    }
    1.59 +    next++;
    1.60 +  }
    1.61 +  _index = -1;
    1.62 +  _succ = NULL;
    1.63 +}
    1.64 +
    1.65 +// ------------------------------------------------------------------
    1.66 +// ciTypeFlow::SuccIter::set_succ
    1.67 +//
    1.68 +void ciTypeFlow::SuccIter::set_succ(Block* succ) {
    1.69 +  int succ_ct = _pred->successors()->length();
    1.70 +  if (_index < succ_ct) {
    1.71 +    _pred->successors()->at_put(_index, succ);
    1.72 +  } else {
    1.73 +    int idx = _index - succ_ct;
    1.74 +    _pred->exceptions()->at_put(idx, succ);
    1.75 +  }
    1.76 +}
    1.77 +
    1.78  // ciTypeFlow::Block
    1.79  //
    1.80  // A basic block.
    1.81 @@ -1526,10 +1570,11 @@
    1.82    _jsrs = new_jsrs;
    1.83    _next = NULL;
    1.84    _on_work_list = false;
    1.85 -  _pre_order = -1; assert(!has_pre_order(), "");
    1.86 -  _private_copy = false;
    1.87 +  _backedge_copy = false;
    1.88 +  _exception_entry = false;
    1.89    _trap_bci = -1;
    1.90    _trap_index = 0;
    1.91 +  df_init();
    1.92  
    1.93    if (CITraceTypeFlow) {
    1.94      tty->print_cr(">> Created new block");
    1.95 @@ -1541,55 +1586,13 @@
    1.96  }
    1.97  
    1.98  // ------------------------------------------------------------------
    1.99 -// ciTypeFlow::Block::clone_loop_head
   1.100 -//
   1.101 -ciTypeFlow::Block*
   1.102 -ciTypeFlow::Block::clone_loop_head(ciTypeFlow* analyzer,
   1.103 -                                   int branch_bci,
   1.104 -                                   ciTypeFlow::Block* target,
   1.105 -                                   ciTypeFlow::JsrSet* jsrs) {
   1.106 -  // Loop optimizations are not performed on Tier1 compiles. Do nothing.
   1.107 -  if (analyzer->env()->comp_level() < CompLevel_full_optimization) {
   1.108 -    return target;
   1.109 -  }
   1.110 -
   1.111 -  // The current block ends with a branch.
   1.112 -  //
   1.113 -  // If the target block appears to be the test-clause of a for loop, and
   1.114 -  // it is not too large, and it has not yet been cloned, clone it.
   1.115 -  // The pre-existing copy becomes the private clone used only by
   1.116 -  // the initial iteration of the loop.  (We know we are simulating
   1.117 -  // the initial iteration right now, since we have never calculated
   1.118 -  // successors before for this block.)
   1.119 -
   1.120 -  if (branch_bci <= start()
   1.121 -      && (target->limit() - target->start()) <= CICloneLoopTestLimit
   1.122 -      && target->private_copy_count() == 0) {
   1.123 -    // Setting the private_copy bit ensures that the target block cannot be
   1.124 -    // reached by any other paths, such as fall-in from the loop body.
   1.125 -    // The private copy will be accessible only on successor lists
   1.126 -    // created up to this point.
   1.127 -    target->set_private_copy(true);
   1.128 -    if (CITraceTypeFlow) {
   1.129 -      tty->print(">> Cloning a test-clause block ");
   1.130 -      print_value_on(tty);
   1.131 -      tty->cr();
   1.132 -    }
   1.133 -    // If the target is the current block, then later on a new copy of the
   1.134 -    // target block will be created when its bytecodes are reached by
   1.135 -    // an alternate path. (This is the case for loops with the loop
   1.136 -    // head at the bci-wise bottom of the loop, as with pre-1.4.2 javac.)
   1.137 -    //
   1.138 -    // Otherwise, duplicate the target block now and use it immediately.
   1.139 -    // (The case for loops with the loop head at the bci-wise top of the
   1.140 -    // loop, as with 1.4.2 javac.)
   1.141 -    //
   1.142 -    // In either case, the new copy of the block will remain public.
   1.143 -    if (target != this) {
   1.144 -      target = analyzer->block_at(branch_bci, jsrs);
   1.145 -    }
   1.146 -  }
   1.147 -  return target;
   1.148 +// ciTypeFlow::Block::df_init
   1.149 +void ciTypeFlow::Block::df_init() {
   1.150 +  _pre_order = -1; assert(!has_pre_order(), "");
   1.151 +  _post_order = -1; assert(!has_post_order(), "");
   1.152 +  _loop = NULL;
   1.153 +  _irreducible_entry = false;
   1.154 +  _rpo_next = NULL;
   1.155  }
   1.156  
   1.157  // ------------------------------------------------------------------
   1.158 @@ -1644,7 +1647,6 @@
   1.159        case Bytecodes::_ifnull:       case Bytecodes::_ifnonnull:
   1.160          // Our successors are the branch target and the next bci.
   1.161          branch_bci = str->get_dest();
   1.162 -        clone_loop_head(analyzer, branch_bci, this, jsrs);
   1.163          _successors =
   1.164            new (arena) GrowableArray<Block*>(arena, 2, 0, NULL);
   1.165          assert(_successors->length() == IF_NOT_TAKEN, "");
   1.166 @@ -1658,14 +1660,7 @@
   1.167          _successors =
   1.168            new (arena) GrowableArray<Block*>(arena, 1, 0, NULL);
   1.169          assert(_successors->length() == GOTO_TARGET, "");
   1.170 -        target = analyzer->block_at(branch_bci, jsrs);
   1.171 -        // If the target block has not been visited yet, and looks like
   1.172 -        // a two-way branch, attempt to clone it if it is a loop head.
   1.173 -        if (target->_successors != NULL
   1.174 -            && target->_successors->length() == (IF_TAKEN + 1)) {
   1.175 -          target = clone_loop_head(analyzer, branch_bci, target, jsrs);
   1.176 -        }
   1.177 -        _successors->append(target);
   1.178 +        _successors->append(analyzer->block_at(branch_bci, jsrs));
   1.179          break;
   1.180  
   1.181        case Bytecodes::_jsr:
   1.182 @@ -1801,65 +1796,60 @@
   1.183  }
   1.184  
   1.185  // ------------------------------------------------------------------
   1.186 -// ciTypeFlow::Block::is_simpler_than
   1.187 -//
   1.188 -// A relation used to order our work list.  We work on a block earlier
   1.189 -// if it has a smaller jsr stack or it occurs earlier in the program
   1.190 -// text.
   1.191 -//
   1.192 -// Note: maybe we should redo this functionality to make blocks
   1.193 -// which correspond to exceptions lower priority.
   1.194 -bool ciTypeFlow::Block::is_simpler_than(ciTypeFlow::Block* other) {
   1.195 -  if (other == NULL) {
   1.196 -    return true;
   1.197 -  } else {
   1.198 -    int size1 = _jsrs->size();
   1.199 -    int size2 = other->_jsrs->size();
   1.200 -    if (size1 < size2) {
   1.201 -      return true;
   1.202 -    } else if (size2 < size1) {
   1.203 -      return false;
   1.204 -    } else {
   1.205 -#if 0
   1.206 -      if (size1 > 0) {
   1.207 -        int r1 = _jsrs->record_at(0)->return_address();
   1.208 -        int r2 = _jsrs->record_at(0)->return_address();
   1.209 -        if (r1 < r2) {
   1.210 -          return true;
   1.211 -        } else if (r2 < r1) {
   1.212 -          return false;
   1.213 -        } else {
   1.214 -          int e1 = _jsrs->record_at(0)->return_address();
   1.215 -          int e2 = _jsrs->record_at(0)->return_address();
   1.216 -          if (e1 < e2) {
   1.217 -            return true;
   1.218 -          } else if (e2 < e1) {
   1.219 -            return false;
   1.220 -          }
   1.221 -        }
   1.222 -      }
   1.223 -#endif
   1.224 -      return (start() <= other->start());
   1.225 -    }
   1.226 -  }
   1.227 +// ciTypeFlow::Block::set_backedge_copy
   1.228 +// Use this only to make a pre-existing public block into a backedge copy.
   1.229 +void ciTypeFlow::Block::set_backedge_copy(bool z) {
   1.230 +  assert(z || (z == is_backedge_copy()), "cannot make a backedge copy public");
   1.231 +  _backedge_copy = z;
   1.232  }
   1.233  
   1.234  // ------------------------------------------------------------------
   1.235 -// ciTypeFlow::Block::set_private_copy
   1.236 -// Use this only to make a pre-existing public block into a private copy.
   1.237 -void ciTypeFlow::Block::set_private_copy(bool z) {
   1.238 -  assert(z || (z == is_private_copy()), "cannot make a private copy public");
   1.239 -  _private_copy = z;
   1.240 +// ciTypeFlow::Block::is_clonable_exit
   1.241 +//
   1.242 +// At most 2 normal successors, one of which continues looping,
   1.243 +// and all exceptional successors must exit.
   1.244 +bool ciTypeFlow::Block::is_clonable_exit(ciTypeFlow::Loop* lp) {
   1.245 +  int normal_cnt  = 0;
   1.246 +  int in_loop_cnt = 0;
   1.247 +  for (SuccIter iter(this); !iter.done(); iter.next()) {
   1.248 +    Block* succ = iter.succ();
   1.249 +    if (iter.is_normal_ctrl()) {
   1.250 +      if (++normal_cnt > 2) return false;
   1.251 +      if (lp->contains(succ->loop())) {
   1.252 +        if (++in_loop_cnt > 1) return false;
   1.253 +      }
   1.254 +    } else {
   1.255 +      if (lp->contains(succ->loop())) return false;
   1.256 +    }
   1.257 +  }
   1.258 +  return in_loop_cnt == 1;
   1.259 +}
   1.260 +
   1.261 +// ------------------------------------------------------------------
   1.262 +// ciTypeFlow::Block::looping_succ
   1.263 +//
   1.264 +ciTypeFlow::Block* ciTypeFlow::Block::looping_succ(ciTypeFlow::Loop* lp) {
   1.265 +  assert(successors()->length() <= 2, "at most 2 normal successors");
   1.266 +  for (SuccIter iter(this); !iter.done(); iter.next()) {
   1.267 +    Block* succ = iter.succ();
   1.268 +    if (lp->contains(succ->loop())) {
   1.269 +      return succ;
   1.270 +    }
   1.271 +  }
   1.272 +  return NULL;
   1.273  }
   1.274  
   1.275  #ifndef PRODUCT
   1.276  // ------------------------------------------------------------------
   1.277  // ciTypeFlow::Block::print_value_on
   1.278  void ciTypeFlow::Block::print_value_on(outputStream* st) const {
   1.279 -  if (has_pre_order())  st->print("#%-2d ", pre_order());
   1.280 +  if (has_pre_order()) st->print("#%-2d ", pre_order());
   1.281 +  if (has_rpo())       st->print("rpo#%-2d ", rpo());
   1.282    st->print("[%d - %d)", start(), limit());
   1.283 +  if (is_loop_head()) st->print(" lphd");
   1.284 +  if (is_irreducible_entry()) st->print(" irred");
   1.285    if (_jsrs->size() > 0) { st->print("/");  _jsrs->print_on(st); }
   1.286 -  if (is_private_copy())  st->print("/private_copy");
   1.287 +  if (is_backedge_copy())  st->print("/backedge_copy");
   1.288  }
   1.289  
   1.290  // ------------------------------------------------------------------
   1.291 @@ -1871,6 +1861,16 @@
   1.292    st->print_cr("  ====================================================  ");
   1.293    st->print ("  ");
   1.294    print_value_on(st);
   1.295 +  st->print(" Stored locals: "); def_locals()->print_on(st, outer()->method()->max_locals()); tty->cr();
   1.296 +  if (loop() && loop()->parent() != NULL) {
   1.297 +    st->print(" loops:");
   1.298 +    Loop* lp = loop();
   1.299 +    do {
   1.300 +      st->print(" %d<-%d", lp->head()->pre_order(),lp->tail()->pre_order());
   1.301 +      if (lp->is_irreducible()) st->print("(ir)");
   1.302 +      lp = lp->parent();
   1.303 +    } while (lp->parent() != NULL);
   1.304 +  }
   1.305    st->cr();
   1.306    _state->print_on(st);
   1.307    if (_successors == NULL) {
   1.308 @@ -1907,6 +1907,21 @@
   1.309  }
   1.310  #endif
   1.311  
   1.312 +#ifndef PRODUCT
   1.313 +// ------------------------------------------------------------------
   1.314 +// ciTypeFlow::LocalSet::print_on
   1.315 +void ciTypeFlow::LocalSet::print_on(outputStream* st, int limit) const {
   1.316 +  st->print("{");
   1.317 +  for (int i = 0; i < max; i++) {
   1.318 +    if (test(i)) st->print(" %d", i);
   1.319 +  }
   1.320 +  if (limit > max) {
   1.321 +    st->print(" %d..%d ", max, limit);
   1.322 +  }
   1.323 +  st->print(" }");
   1.324 +}
   1.325 +#endif
   1.326 +
   1.327  // ciTypeFlow
   1.328  //
   1.329  // This is a pass over the bytecodes which computes the following:
   1.330 @@ -1922,12 +1937,11 @@
   1.331    _max_locals = method->max_locals();
   1.332    _max_stack = method->max_stack();
   1.333    _code_size = method->code_size();
   1.334 +  _has_irreducible_entry = false;
   1.335    _osr_bci = osr_bci;
   1.336    _failure_reason = NULL;
   1.337    assert(start_bci() >= 0 && start_bci() < code_size() , "correct osr_bci argument");
   1.338 -
   1.339    _work_list = NULL;
   1.340 -  _next_pre_order = 0;
   1.341  
   1.342    _ciblock_count = _methodBlocks->num_blocks();
   1.343    _idx_to_blocklist = NEW_ARENA_ARRAY(arena(), GrowableArray<Block*>*, _ciblock_count);
   1.344 @@ -1949,12 +1963,6 @@
   1.345    _work_list = next_block->next();
   1.346    next_block->set_next(NULL);
   1.347    next_block->set_on_work_list(false);
   1.348 -  if (!next_block->has_pre_order()) {
   1.349 -    // Assign "pre_order" as each new block is taken from the work list.
   1.350 -    // This number may be used by following phases to order block visits.
   1.351 -    assert(!have_block_count(), "must not have mapped blocks yet")
   1.352 -    next_block->set_pre_order(_next_pre_order++);
   1.353 -  }
   1.354    return next_block;
   1.355  }
   1.356  
   1.357 @@ -1962,30 +1970,37 @@
   1.358  // ciTypeFlow::add_to_work_list
   1.359  //
   1.360  // Add a basic block to our work list.
   1.361 +// List is sorted by decreasing postorder sort (same as increasing RPO)
   1.362  void ciTypeFlow::add_to_work_list(ciTypeFlow::Block* block) {
   1.363    assert(!block->is_on_work_list(), "must not already be on work list");
   1.364  
   1.365    if (CITraceTypeFlow) {
   1.366 -    tty->print(">> Adding block%s ", block->has_pre_order() ? " (again)" : "");
   1.367 +    tty->print(">> Adding block ");
   1.368      block->print_value_on(tty);
   1.369      tty->print_cr(" to the work list : ");
   1.370    }
   1.371  
   1.372    block->set_on_work_list(true);
   1.373 -  if (block->is_simpler_than(_work_list)) {
   1.374 +
   1.375 +  // decreasing post order sort
   1.376 +
   1.377 +  Block* prev = NULL;
   1.378 +  Block* current = _work_list;
   1.379 +  int po = block->post_order();
   1.380 +  while (current != NULL) {
   1.381 +    if (!current->has_post_order() || po > current->post_order())
   1.382 +      break;
   1.383 +    prev = current;
   1.384 +    current = current->next();
   1.385 +  }
   1.386 +  if (prev == NULL) {
   1.387      block->set_next(_work_list);
   1.388      _work_list = block;
   1.389    } else {
   1.390 -    Block *temp = _work_list;
   1.391 -    while (!block->is_simpler_than(temp->next())) {
   1.392 -      if (CITraceTypeFlow) {
   1.393 -        tty->print(".");
   1.394 -      }
   1.395 -      temp = temp->next();
   1.396 -    }
   1.397 -    block->set_next(temp->next());
   1.398 -    temp->set_next(block);
   1.399 +    block->set_next(current);
   1.400 +    prev->set_next(block);
   1.401    }
   1.402 +
   1.403    if (CITraceTypeFlow) {
   1.404      tty->cr();
   1.405    }
   1.406 @@ -2008,7 +2023,7 @@
   1.407    assert(ciblk->start_bci() == bci, "bad ciBlock boundaries");
   1.408    Block* block = get_block_for(ciblk->index(), jsrs, option);
   1.409  
   1.410 -  assert(block == NULL? (option == no_create): block->is_private_copy() == (option == create_private_copy), "create option consistent with result");
   1.411 +  assert(block == NULL? (option == no_create): block->is_backedge_copy() == (option == create_backedge_copy), "create option consistent with result");
   1.412  
   1.413    if (CITraceTypeFlow) {
   1.414      if (block != NULL) {
   1.415 @@ -2072,8 +2087,9 @@
   1.416      }
   1.417  
   1.418      if (block->meet_exception(exception_klass, state)) {
   1.419 -      // Block was modified.  Add it to the work list.
   1.420 -      if (!block->is_on_work_list()) {
   1.421 +      // Block was modified and has PO.  Add it to the work list.
   1.422 +      if (block->has_post_order() &&
   1.423 +          !block->is_on_work_list()) {
   1.424          add_to_work_list(block);
   1.425        }
   1.426      }
   1.427 @@ -2091,8 +2107,9 @@
   1.428    for (int i = 0; i < len; i++) {
   1.429      Block* block = successors->at(i);
   1.430      if (block->meet(state)) {
   1.431 -      // Block was modified.  Add it to the work list.
   1.432 -      if (!block->is_on_work_list()) {
   1.433 +      // Block was modified and has PO.  Add it to the work list.
   1.434 +      if (block->has_post_order() &&
   1.435 +          !block->is_on_work_list()) {
   1.436          add_to_work_list(block);
   1.437        }
   1.438      }
   1.439 @@ -2133,6 +2150,111 @@
   1.440    return true;
   1.441  }
   1.442  
   1.443 +// ------------------------------------------------------------------
   1.444 +// ciTypeFlow::clone_loop_heads
   1.445 +//
   1.446 +// Clone the loop heads
   1.447 +bool ciTypeFlow::clone_loop_heads(Loop* lp, StateVector* temp_vector, JsrSet* temp_set) {
   1.448 +  bool rslt = false;
   1.449 +  for (PreorderLoops iter(loop_tree_root()); !iter.done(); iter.next()) {
   1.450 +    lp = iter.current();
   1.451 +    Block* head = lp->head();
   1.452 +    if (lp == loop_tree_root() ||
   1.453 +        lp->is_irreducible() ||
   1.454 +        !head->is_clonable_exit(lp))
   1.455 +      continue;
   1.456 +
   1.457 +    // check not already cloned
   1.458 +    if (head->backedge_copy_count() != 0)
   1.459 +      continue;
   1.460 +
   1.461 +    // check _no_ shared head below us
   1.462 +    Loop* ch;
   1.463 +    for (ch = lp->child(); ch != NULL && ch->head() != head; ch = ch->sibling());
   1.464 +    if (ch != NULL)
   1.465 +      continue;
   1.466 +
   1.467 +    // Clone head
   1.468 +    Block* new_head = head->looping_succ(lp);
   1.469 +    Block* clone = clone_loop_head(lp, temp_vector, temp_set);
   1.470 +    // Update lp's info
   1.471 +    clone->set_loop(lp);
   1.472 +    lp->set_head(new_head);
   1.473 +    lp->set_tail(clone);
   1.474 +    // And move original head into outer loop
   1.475 +    head->set_loop(lp->parent());
   1.476 +
   1.477 +    rslt = true;
   1.478 +  }
   1.479 +  return rslt;
   1.480 +}
   1.481 +
   1.482 +// ------------------------------------------------------------------
   1.483 +// ciTypeFlow::clone_loop_head
   1.484 +//
   1.485 +// Clone lp's head and replace tail's successors with clone.
   1.486 +//
   1.487 +//  |
   1.488 +//  v
   1.489 +// head <-> body
   1.490 +//  |
   1.491 +//  v
   1.492 +// exit
   1.493 +//
   1.494 +// new_head
   1.495 +//
   1.496 +//  |
   1.497 +//  v
   1.498 +// head ----------\
   1.499 +//  |             |
   1.500 +//  |             v
   1.501 +//  |  clone <-> body
   1.502 +//  |    |
   1.503 +//  | /--/
   1.504 +//  | |
   1.505 +//  v v
   1.506 +// exit
   1.507 +//
   1.508 +ciTypeFlow::Block* ciTypeFlow::clone_loop_head(Loop* lp, StateVector* temp_vector, JsrSet* temp_set) {
   1.509 +  Block* head = lp->head();
   1.510 +  Block* tail = lp->tail();
   1.511 +  if (CITraceTypeFlow) {
   1.512 +    tty->print(">> Requesting clone of loop head "); head->print_value_on(tty);
   1.513 +    tty->print("  for predecessor ");                tail->print_value_on(tty);
   1.514 +    tty->cr();
   1.515 +  }
   1.516 +  Block* clone = block_at(head->start(), head->jsrs(), create_backedge_copy);
   1.517 +  assert(clone->backedge_copy_count() == 1, "one backedge copy for all back edges");
   1.518 +
   1.519 +  assert(!clone->has_pre_order(), "just created");
   1.520 +  clone->set_next_pre_order();
   1.521 +
   1.522 +  // Insert clone after (orig) tail in reverse post order
   1.523 +  clone->set_rpo_next(tail->rpo_next());
   1.524 +  tail->set_rpo_next(clone);
   1.525 +
   1.526 +  // tail->head becomes tail->clone
   1.527 +  for (SuccIter iter(tail); !iter.done(); iter.next()) {
   1.528 +    if (iter.succ() == head) {
   1.529 +      iter.set_succ(clone);
   1.530 +      break;
   1.531 +    }
   1.532 +  }
   1.533 +  flow_block(tail, temp_vector, temp_set);
   1.534 +  if (head == tail) {
   1.535 +    // For self-loops, clone->head becomes clone->clone
   1.536 +    flow_block(clone, temp_vector, temp_set);
   1.537 +    for (SuccIter iter(clone); !iter.done(); iter.next()) {
   1.538 +      if (iter.succ() == head) {
   1.539 +        iter.set_succ(clone);
   1.540 +        break;
   1.541 +      }
   1.542 +    }
   1.543 +  }
   1.544 +  flow_block(clone, temp_vector, temp_set);
   1.545 +
   1.546 +  return clone;
   1.547 +}
   1.548  
   1.549  // ------------------------------------------------------------------
   1.550  // ciTypeFlow::flow_block
   1.551 @@ -2159,11 +2281,14 @@
   1.552  
   1.553    // Grab the state from the current block.
   1.554    block->copy_state_into(state);
   1.555 +  state->def_locals()->clear();
   1.556  
   1.557    GrowableArray<Block*>*           exceptions = block->exceptions();
   1.558    GrowableArray<ciInstanceKlass*>* exc_klasses = block->exc_klasses();
   1.559    bool has_exceptions = exceptions->length() > 0;
   1.560  
   1.561 +  bool exceptions_used = false;
   1.562 +
   1.563    ciBytecodeStream str(method());
   1.564    str.reset_to_bci(start);
   1.565    Bytecodes::Code code;
   1.566 @@ -2172,6 +2297,7 @@
   1.567      // Check for exceptional control flow from this point.
   1.568      if (has_exceptions && can_trap(str)) {
   1.569        flow_exceptions(exceptions, exc_klasses, state);
   1.570 +      exceptions_used = true;
   1.571      }
   1.572      // Apply the effects of the current bytecode to our state.
   1.573      bool res = state->apply_one_bytecode(&str);
   1.574 @@ -2189,9 +2315,14 @@
   1.575          block->print_on(tty);
   1.576        }
   1.577  
   1.578 +      // Save set of locals defined in this block
   1.579 +      block->def_locals()->add(state->def_locals());
   1.580 +
   1.581        // Record (no) successors.
   1.582        block->successors(&str, state, jsrs);
   1.583  
   1.584 +      assert(!has_exceptions || exceptions_used, "Not removing exceptions");
   1.585 +
   1.586        // Discontinue interpretation of this Block.
   1.587        return;
   1.588      }
   1.589 @@ -2202,6 +2333,7 @@
   1.590      // Check for exceptional control flow from this point.
   1.591      if (has_exceptions && can_trap(str)) {
   1.592        flow_exceptions(exceptions, exc_klasses, state);
   1.593 +      exceptions_used = true;
   1.594      }
   1.595  
   1.596      // Fix the JsrSet to reflect effect of the bytecode.
   1.597 @@ -2218,11 +2350,306 @@
   1.598      successors = block->successors(&str, NULL, NULL);
   1.599    }
   1.600  
   1.601 +  // Save set of locals defined in this block
   1.602 +  block->def_locals()->add(state->def_locals());
   1.603 +
   1.604 +  // Remove untaken exception paths
   1.605 +  if (!exceptions_used)
   1.606 +    exceptions->clear();
   1.607 +
   1.608    // Pass our state to successors.
   1.609    flow_successors(successors, state);
   1.610  }
   1.611  
   1.612  // ------------------------------------------------------------------
   1.613 +// ciTypeFlow::PostOrderLoops::next
   1.614 +//
   1.615 +// Advance to next loop tree using a postorder, left-to-right traversal.
   1.616 +void ciTypeFlow::PostorderLoops::next() {
   1.617 +  assert(!done(), "must not be done.");
   1.618 +  if (_current->sibling() != NULL) {
   1.619 +    _current = _current->sibling();
   1.620 +    while (_current->child() != NULL) {
   1.621 +      _current = _current->child();
   1.622 +    }
   1.623 +  } else {
   1.624 +    _current = _current->parent();
   1.625 +  }
   1.626 +}
   1.627 +
   1.628 +// ------------------------------------------------------------------
   1.629 +// ciTypeFlow::PreOrderLoops::next
   1.630 +//
   1.631 +// Advance to next loop tree using a preorder, left-to-right traversal.
   1.632 +void ciTypeFlow::PreorderLoops::next() {
   1.633 +  assert(!done(), "must not be done.");
   1.634 +  if (_current->child() != NULL) {
   1.635 +    _current = _current->child();
   1.636 +  } else if (_current->sibling() != NULL) {
   1.637 +    _current = _current->sibling();
   1.638 +  } else {
   1.639 +    while (_current != _root && _current->sibling() == NULL) {
   1.640 +      _current = _current->parent();
   1.641 +    }
   1.642 +    if (_current == _root) {
   1.643 +      _current = NULL;
   1.644 +      assert(done(), "must be done.");
   1.645 +    } else {
   1.646 +      assert(_current->sibling() != NULL, "must be more to do");
   1.647 +      _current = _current->sibling();
   1.648 +    }
   1.649 +  }
   1.650 +}
   1.651 +
   1.652 +// ------------------------------------------------------------------
   1.653 +// ciTypeFlow::Loop::sorted_merge
   1.654 +//
   1.655 +// Merge the branch lp into this branch, sorting on the loop head
   1.656 +// pre_orders. Returns the leaf of the merged branch.
   1.657 +// Child and sibling pointers will be setup later.
   1.658 +// Sort is (looking from leaf towards the root)
   1.659 +//  descending on primary key: loop head's pre_order, and
   1.660 +//  ascending  on secondary key: loop tail's pre_order.
   1.661 +ciTypeFlow::Loop* ciTypeFlow::Loop::sorted_merge(Loop* lp) {
   1.662 +  Loop* leaf = this;
   1.663 +  Loop* prev = NULL;
   1.664 +  Loop* current = leaf;
   1.665 +  while (lp != NULL) {
   1.666 +    int lp_pre_order = lp->head()->pre_order();
   1.667 +    // Find insertion point for "lp"
   1.668 +    while (current != NULL) {
   1.669 +      if (current == lp)
   1.670 +        return leaf; // Already in list
   1.671 +      if (current->head()->pre_order() < lp_pre_order)
   1.672 +        break;
   1.673 +      if (current->head()->pre_order() == lp_pre_order &&
   1.674 +          current->tail()->pre_order() > lp->tail()->pre_order()) {
   1.675 +        break;
   1.676 +      }
   1.677 +      prev = current;
   1.678 +      current = current->parent();
   1.679 +    }
   1.680 +    Loop* next_lp = lp->parent(); // Save future list of items to insert
   1.681 +    // Insert lp before current
   1.682 +    lp->set_parent(current);
   1.683 +    if (prev != NULL) {
   1.684 +      prev->set_parent(lp);
   1.685 +    } else {
   1.686 +      leaf = lp;
   1.687 +    }
   1.688 +    prev = lp;     // Inserted item is new prev[ious]
   1.689 +    lp = next_lp;  // Next item to insert
   1.690 +  }
   1.691 +  return leaf;
   1.692 +}
   1.693 +
   1.694 +// ------------------------------------------------------------------
   1.695 +// ciTypeFlow::build_loop_tree
   1.696 +//
   1.697 +// Incrementally build loop tree.
   1.698 +void ciTypeFlow::build_loop_tree(Block* blk) {
   1.699 +  assert(!blk->is_post_visited(), "precondition");
   1.700 +  Loop* innermost = NULL; // merge of loop tree branches over all successors
   1.701 +
   1.702 +  for (SuccIter iter(blk); !iter.done(); iter.next()) {
   1.703 +    Loop*  lp   = NULL;
   1.704 +    Block* succ = iter.succ();
   1.705 +    if (!succ->is_post_visited()) {
   1.706 +      // Found backedge since predecessor post visited, but successor is not
   1.707 +      assert(succ->pre_order() <= blk->pre_order(), "should be backedge");
   1.708 +
   1.709 +      // Create a LoopNode to mark this loop.
   1.710 +      lp = new (arena()) Loop(succ, blk);
   1.711 +      if (succ->loop() == NULL)
   1.712 +        succ->set_loop(lp);
   1.713 +      // succ->loop will be updated to innermost loop on a later call, when blk==succ
   1.714 +
   1.715 +    } else {  // Nested loop
   1.716 +      lp = succ->loop();
   1.717 +
   1.718 +      // If succ is loop head, find outer loop.
   1.719 +      while (lp != NULL && lp->head() == succ) {
   1.720 +        lp = lp->parent();
   1.721 +      }
   1.722 +      if (lp == NULL) {
   1.723 +        // Infinite loop, it's parent is the root
   1.724 +        lp = loop_tree_root();
   1.725 +      }
   1.726 +    }
   1.727 +
   1.728 +    // Check for irreducible loop.
   1.729 +    // Successor has already been visited. If the successor's loop head
   1.730 +    // has already been post-visited, then this is another entry into the loop.
   1.731 +    while (lp->head()->is_post_visited() && lp != loop_tree_root()) {
   1.732 +      _has_irreducible_entry = true;
   1.733 +      lp->set_irreducible(succ);
   1.734 +      if (!succ->is_on_work_list()) {
   1.735 +        // Assume irreducible entries need more data flow
   1.736 +        add_to_work_list(succ);
   1.737 +      }
   1.738 +      lp = lp->parent();
   1.739 +      assert(lp != NULL, "nested loop must have parent by now");
   1.740 +    }
   1.741 +
   1.742 +    // Merge loop tree branch for all successors.
   1.743 +    innermost = innermost == NULL ? lp : innermost->sorted_merge(lp);
   1.744 +
   1.745 +  } // end loop
   1.746 +
   1.747 +  if (innermost == NULL) {
   1.748 +    assert(blk->successors()->length() == 0, "CFG exit");
   1.749 +    blk->set_loop(loop_tree_root());
   1.750 +  } else if (innermost->head() == blk) {
   1.751 +    // If loop header, complete the tree pointers
   1.752 +    if (blk->loop() != innermost) {
   1.753 +#if ASSERT
   1.754 +      assert(blk->loop()->head() == innermost->head(), "same head");
   1.755 +      Loop* dl;
   1.756 +      for (dl = innermost; dl != NULL && dl != blk->loop(); dl = dl->parent());
   1.757 +      assert(dl == blk->loop(), "blk->loop() already in innermost list");
   1.758 +#endif
   1.759 +      blk->set_loop(innermost);
   1.760 +    }
   1.761 +    innermost->def_locals()->add(blk->def_locals());
   1.762 +    Loop* l = innermost;
   1.763 +    Loop* p = l->parent();
   1.764 +    while (p && l->head() == blk) {
   1.765 +      l->set_sibling(p->child());  // Put self on parents 'next child'
   1.766 +      p->set_child(l);             // Make self the first child of parent
   1.767 +      p->def_locals()->add(l->def_locals());
   1.768 +      l = p;                       // Walk up the parent chain
   1.769 +      p = l->parent();
   1.770 +    }
   1.771 +  } else {
   1.772 +    blk->set_loop(innermost);
   1.773 +    innermost->def_locals()->add(blk->def_locals());
   1.774 +  }
   1.775 +}
   1.776 +
   1.777 +// ------------------------------------------------------------------
   1.778 +// ciTypeFlow::Loop::contains
   1.779 +//
   1.780 +// Returns true if lp is nested loop.
   1.781 +bool ciTypeFlow::Loop::contains(ciTypeFlow::Loop* lp) const {
   1.782 +  assert(lp != NULL, "");
   1.783 +  if (this == lp || head() == lp->head()) return true;
   1.784 +  int depth1 = depth();
   1.785 +  int depth2 = lp->depth();
   1.786 +  if (depth1 > depth2)
   1.787 +    return false;
   1.788 +  while (depth1 < depth2) {
   1.789 +    depth2--;
   1.790 +    lp = lp->parent();
   1.791 +  }
   1.792 +  return this == lp;
   1.793 +}
   1.794 +
   1.795 +// ------------------------------------------------------------------
   1.796 +// ciTypeFlow::Loop::depth
   1.797 +//
   1.798 +// Loop depth
   1.799 +int ciTypeFlow::Loop::depth() const {
   1.800 +  int dp = 0;
   1.801 +  for (Loop* lp = this->parent(); lp != NULL; lp = lp->parent())
   1.802 +    dp++;
   1.803 +  return dp;
   1.804 +}
   1.805 +
   1.806 +#ifndef PRODUCT
   1.807 +// ------------------------------------------------------------------
   1.808 +// ciTypeFlow::Loop::print
   1.809 +void ciTypeFlow::Loop::print(outputStream* st, int indent) const {
   1.810 +  for (int i = 0; i < indent; i++) st->print(" ");
   1.811 +  st->print("%d<-%d %s",
   1.812 +            is_root() ? 0 : this->head()->pre_order(),
   1.813 +            is_root() ? 0 : this->tail()->pre_order(),
   1.814 +            is_irreducible()?" irr":"");
   1.815 +  st->print(" defs: ");
   1.816 +  def_locals()->print_on(st, _head->outer()->method()->max_locals());
   1.817 +  st->cr();
   1.818 +  for (Loop* ch = child(); ch != NULL; ch = ch->sibling())
   1.819 +    ch->print(st, indent+2);
   1.820 +}
   1.821 +#endif
   1.822 +
   1.823 +// ------------------------------------------------------------------
   1.824 +// ciTypeFlow::df_flow_types
   1.825 +//
   1.826 +// Perform the depth first type flow analysis. Helper for flow_types.
   1.827 +void ciTypeFlow::df_flow_types(Block* start,
   1.828 +                               bool do_flow,
   1.829 +                               StateVector* temp_vector,
   1.830 +                               JsrSet* temp_set) {
   1.831 +  int dft_len = 100;
   1.832 +  GrowableArray<Block*> stk(arena(), dft_len, 0, NULL);
   1.833 +
   1.834 +  ciBlock* dummy = _methodBlocks->make_dummy_block();
   1.835 +  JsrSet* root_set = new JsrSet(NULL, 0);
   1.836 +  Block* root_head = new (arena()) Block(this, dummy, root_set);
   1.837 +  Block* root_tail = new (arena()) Block(this, dummy, root_set);
   1.838 +  root_head->set_pre_order(0);
   1.839 +  root_head->set_post_order(0);
   1.840 +  root_tail->set_pre_order(max_jint);
   1.841 +  root_tail->set_post_order(max_jint);
   1.842 +  set_loop_tree_root(new (arena()) Loop(root_head, root_tail));
   1.843 +
   1.844 +  stk.push(start);
   1.845 +
   1.846 +  _next_pre_order = 0;  // initialize pre_order counter
   1.847 +  _rpo_list = NULL;
   1.848 +  int next_po = 0;      // initialize post_order counter
   1.849 +
   1.850 +  // Compute RPO and the control flow graph
   1.851 +  int size;
   1.852 +  while ((size = stk.length()) > 0) {
   1.853 +    Block* blk = stk.top(); // Leave node on stack
   1.854 +    if (!blk->is_visited()) {
   1.855 +      // forward arc in graph
   1.856 +      assert (!blk->has_pre_order(), "");
   1.857 +      blk->set_next_pre_order();
   1.858 +
   1.859 +      if (_next_pre_order >= MaxNodeLimit / 2) {
   1.860 +        // Too many basic blocks.  Bail out.
   1.861 +        // This can happen when try/finally constructs are nested to depth N,
   1.862 +        // and there is O(2**N) cloning of jsr bodies.  See bug 4697245!
   1.863 +        // "MaxNodeLimit / 2" is used because probably the parser will
   1.864 +        // generate at least twice that many nodes and bail out.
   1.865 +        record_failure("too many basic blocks");
   1.866 +        return;
   1.867 +      }
   1.868 +      if (do_flow) {
   1.869 +        flow_block(blk, temp_vector, temp_set);
   1.870 +        if (failing()) return; // Watch for bailouts.
   1.871 +      }
   1.872 +    } else if (!blk->is_post_visited()) {
   1.873 +      // cross or back arc
   1.874 +      for (SuccIter iter(blk); !iter.done(); iter.next()) {
   1.875 +        Block* succ = iter.succ();
   1.876 +        if (!succ->is_visited()) {
   1.877 +          stk.push(succ);
   1.878 +        }
   1.879 +      }
   1.880 +      if (stk.length() == size) {
   1.881 +        // There were no additional children, post visit node now
   1.882 +        stk.pop(); // Remove node from stack
   1.883 +
   1.884 +        build_loop_tree(blk);
   1.885 +        blk->set_post_order(next_po++);   // Assign post order
   1.886 +        prepend_to_rpo_list(blk);
   1.887 +        assert(blk->is_post_visited(), "");
   1.888 +
   1.889 +        if (blk->is_loop_head() && !blk->is_on_work_list()) {
   1.890 +          // Assume loop heads need more data flow
   1.891 +          add_to_work_list(blk);
   1.892 +        }
   1.893 +      }
   1.894 +    } else {
   1.895 +      stk.pop(); // Remove post-visited node from stack
   1.896 +    }
   1.897 +  }
   1.898 +}
   1.899 +
   1.900 +// ------------------------------------------------------------------
   1.901  // ciTypeFlow::flow_types
   1.902  //
   1.903  // Perform the type flow analysis, creating and cloning Blocks as
   1.904 @@ -2233,91 +2660,93 @@
   1.905    JsrSet* temp_set = new JsrSet(NULL, 16);
   1.906  
   1.907    // Create the method entry block.
   1.908 -  Block* block = block_at(start_bci(), temp_set);
   1.909 -  block->set_pre_order(_next_pre_order++);
   1.910 -  assert(block->is_start(), "start block must have order #0");
   1.911 +  Block* start = block_at(start_bci(), temp_set);
   1.912  
   1.913    // Load the initial state into it.
   1.914    const StateVector* start_state = get_start_state();
   1.915    if (failing())  return;
   1.916 -  block->meet(start_state);
   1.917 -  add_to_work_list(block);
   1.918 +  start->meet(start_state);
   1.919  
   1.920 -  // Trickle away.
   1.921 +  // Depth first visit
   1.922 +  df_flow_types(start, true /*do flow*/, temp_vector, temp_set);
   1.923 +
   1.924 +  if (failing())  return;
   1.925 +  assert(_rpo_list == start, "must be start");
   1.926 +
   1.927 +  // Any loops found?
   1.928 +  if (loop_tree_root()->child() != NULL &&
   1.929 +      env()->comp_level() >= CompLevel_full_optimization) {
   1.930 +      // Loop optimizations are not performed on Tier1 compiles.
   1.931 +
   1.932 +    bool changed = clone_loop_heads(loop_tree_root(), temp_vector, temp_set);
   1.933 +
   1.934 +    // If some loop heads were cloned, recompute postorder and loop tree
   1.935 +    if (changed) {
   1.936 +      loop_tree_root()->set_child(NULL);
   1.937 +      for (Block* blk = _rpo_list; blk != NULL;) {
   1.938 +        Block* next = blk->rpo_next();
   1.939 +        blk->df_init();
   1.940 +        blk = next;
   1.941 +      }
   1.942 +      df_flow_types(start, false /*no flow*/, temp_vector, temp_set);
   1.943 +    }
   1.944 +  }
   1.945 +
   1.946 +  if (CITraceTypeFlow) {
   1.947 +    tty->print_cr("\nLoop tree");
   1.948 +    loop_tree_root()->print();
   1.949 +  }
   1.950 +
   1.951 +  // Continue flow analysis until fixed point reached
   1.952 +
   1.953 +  debug_only(int max_block = _next_pre_order;)
   1.954 +
   1.955    while (!work_list_empty()) {
   1.956 -    Block* block = work_list_next();
   1.957 -    flow_block(block, temp_vector, temp_set);
   1.958 +    Block* blk = work_list_next();
   1.959 +    assert (blk->has_post_order(), "post order assigned above");
   1.960  
   1.961 +    flow_block(blk, temp_vector, temp_set);
   1.962  
   1.963 -    // NodeCountCutoff is the number of nodes at which the parser
   1.964 -    // will bail out.  Probably if we already have lots of BBs,
   1.965 -    // the parser will generate at least twice that many nodes and bail out.
   1.966 -    // Therefore, this is a conservatively large limit at which to
   1.967 -    // bail out in the pre-parse typeflow pass.
   1.968 -    int block_limit = MaxNodeLimit / 2;
   1.969 -
   1.970 -    if (_next_pre_order >= block_limit) {
   1.971 -      // Too many basic blocks.  Bail out.
   1.972 -      //
   1.973 -      // This can happen when try/finally constructs are nested to depth N,
   1.974 -      // and there is O(2**N) cloning of jsr bodies.  See bug 4697245!
   1.975 -      record_failure("too many basic blocks");
   1.976 -      return;
   1.977 -    }
   1.978 -
   1.979 -    // Watch for bailouts.
   1.980 -    if (failing())  return;
   1.981 +    assert (max_block == _next_pre_order, "no new blocks");
   1.982 +    assert (!failing(), "no more bailouts");
   1.983    }
   1.984  }
   1.985  
   1.986  // ------------------------------------------------------------------
   1.987  // ciTypeFlow::map_blocks
   1.988  //
   1.989 -// Create the block map, which indexes blocks in pre_order.
   1.990 +// Create the block map, which indexes blocks in reverse post-order.
   1.991  void ciTypeFlow::map_blocks() {
   1.992    assert(_block_map == NULL, "single initialization");
   1.993 -  int pre_order_limit = _next_pre_order;
   1.994 -  _block_map = NEW_ARENA_ARRAY(arena(), Block*, pre_order_limit);
   1.995 -  assert(pre_order_limit == block_count(), "");
   1.996 -  int po;
   1.997 -  for (po = 0; po < pre_order_limit; po++) {
   1.998 -    debug_only(_block_map[po] = NULL);
   1.999 +  int block_ct = _next_pre_order;
  1.1000 +  _block_map = NEW_ARENA_ARRAY(arena(), Block*, block_ct);
  1.1001 +  assert(block_ct == block_count(), "");
  1.1002 +
  1.1003 +  Block* blk = _rpo_list;
  1.1004 +  for (int m = 0; m < block_ct; m++) {
  1.1005 +    int rpo = blk->rpo();
  1.1006 +    assert(rpo == m, "should be sequential");
  1.1007 +    _block_map[rpo] = blk;
  1.1008 +    blk = blk->rpo_next();
  1.1009    }
  1.1010 -  ciMethodBlocks *mblks = _methodBlocks;
  1.1011 -  ciBlock* current = NULL;
  1.1012 -  int limit_bci = code_size();
  1.1013 -  for (int bci = 0; bci < limit_bci; bci++) {
  1.1014 -    ciBlock* ciblk = mblks->block_containing(bci);
  1.1015 -    if (ciblk != NULL && ciblk != current) {
  1.1016 -      current = ciblk;
  1.1017 -      int curidx = ciblk->index();
  1.1018 -      int block_count = (_idx_to_blocklist[curidx] == NULL) ? 0 : _idx_to_blocklist[curidx]->length();
  1.1019 -      for (int i = 0; i < block_count; i++) {
  1.1020 -        Block* block = _idx_to_blocklist[curidx]->at(i);
  1.1021 -        if (!block->has_pre_order())  continue;
  1.1022 -        int po = block->pre_order();
  1.1023 -        assert(_block_map[po] == NULL, "unique ref to block");
  1.1024 -        assert(0 <= po && po < pre_order_limit, "");
  1.1025 -        _block_map[po] = block;
  1.1026 -      }
  1.1027 -    }
  1.1028 -  }
  1.1029 -  for (po = 0; po < pre_order_limit; po++) {
  1.1030 -    assert(_block_map[po] != NULL, "must not drop any blocks");
  1.1031 -    Block* block = _block_map[po];
  1.1032 +  assert(blk == NULL, "should be done");
  1.1033 +
  1.1034 +  for (int j = 0; j < block_ct; j++) {
  1.1035 +    assert(_block_map[j] != NULL, "must not drop any blocks");
  1.1036 +    Block* block = _block_map[j];
  1.1037      // Remove dead blocks from successor lists:
  1.1038      for (int e = 0; e <= 1; e++) {
  1.1039        GrowableArray<Block*>* l = e? block->exceptions(): block->successors();
  1.1040 -      for (int i = 0; i < l->length(); i++) {
  1.1041 -        Block* s = l->at(i);
  1.1042 -        if (!s->has_pre_order()) {
  1.1043 +      for (int k = 0; k < l->length(); k++) {
  1.1044 +        Block* s = l->at(k);
  1.1045 +        if (!s->has_post_order()) {
  1.1046            if (CITraceTypeFlow) {
  1.1047              tty->print("Removing dead %s successor of #%d: ", (e? "exceptional":  "normal"), block->pre_order());
  1.1048              s->print_value_on(tty);
  1.1049              tty->cr();
  1.1050            }
  1.1051            l->remove(s);
  1.1052 -          --i;
  1.1053 +          --k;
  1.1054          }
  1.1055        }
  1.1056      }
  1.1057 @@ -2329,7 +2758,7 @@
  1.1058  //
  1.1059  // Find a block with this ciBlock which has a compatible JsrSet.
  1.1060  // If no such block exists, create it, unless the option is no_create.
  1.1061 -// If the option is create_private_copy, always create a fresh private copy.
  1.1062 +// If the option is create_backedge_copy, always create a fresh backedge copy.
  1.1063  ciTypeFlow::Block* ciTypeFlow::get_block_for(int ciBlockIndex, ciTypeFlow::JsrSet* jsrs, CreateOption option) {
  1.1064    Arena* a = arena();
  1.1065    GrowableArray<Block*>* blocks = _idx_to_blocklist[ciBlockIndex];
  1.1066 @@ -2342,11 +2771,11 @@
  1.1067      _idx_to_blocklist[ciBlockIndex] = blocks;
  1.1068    }
  1.1069  
  1.1070 -  if (option != create_private_copy) {
  1.1071 +  if (option != create_backedge_copy) {
  1.1072      int len = blocks->length();
  1.1073      for (int i = 0; i < len; i++) {
  1.1074        Block* block = blocks->at(i);
  1.1075 -      if (!block->is_private_copy() && block->is_compatible_with(jsrs)) {
  1.1076 +      if (!block->is_backedge_copy() && block->is_compatible_with(jsrs)) {
  1.1077          return block;
  1.1078        }
  1.1079      }
  1.1080 @@ -2357,15 +2786,15 @@
  1.1081  
  1.1082    // We did not find a compatible block.  Create one.
  1.1083    Block* new_block = new (a) Block(this, _methodBlocks->block(ciBlockIndex), jsrs);
  1.1084 -  if (option == create_private_copy)  new_block->set_private_copy(true);
  1.1085 +  if (option == create_backedge_copy)  new_block->set_backedge_copy(true);
  1.1086    blocks->append(new_block);
  1.1087    return new_block;
  1.1088  }
  1.1089  
  1.1090  // ------------------------------------------------------------------
  1.1091 -// ciTypeFlow::private_copy_count
  1.1092 +// ciTypeFlow::backedge_copy_count
  1.1093  //
  1.1094 -int ciTypeFlow::private_copy_count(int ciBlockIndex, ciTypeFlow::JsrSet* jsrs) const {
  1.1095 +int ciTypeFlow::backedge_copy_count(int ciBlockIndex, ciTypeFlow::JsrSet* jsrs) const {
  1.1096    GrowableArray<Block*>* blocks = _idx_to_blocklist[ciBlockIndex];
  1.1097  
  1.1098    if (blocks == NULL) {
  1.1099 @@ -2376,7 +2805,7 @@
  1.1100    int len = blocks->length();
  1.1101    for (int i = 0; i < len; i++) {
  1.1102      Block* block = blocks->at(i);
  1.1103 -    if (block->is_private_copy() && block->is_compatible_with(jsrs)) {
  1.1104 +    if (block->is_backedge_copy() && block->is_compatible_with(jsrs)) {
  1.1105        count++;
  1.1106      }
  1.1107    }
  1.1108 @@ -2405,10 +2834,12 @@
  1.1109    if (failing()) {
  1.1110      return;
  1.1111    }
  1.1112 +
  1.1113 +  map_blocks();
  1.1114 +
  1.1115    if (CIPrintTypeFlow || CITraceTypeFlow) {
  1.1116 -    print_on(tty);
  1.1117 +    rpo_print_on(tty);
  1.1118    }
  1.1119 -  map_blocks();
  1.1120  }
  1.1121  
  1.1122  // ------------------------------------------------------------------
  1.1123 @@ -2466,4 +2897,19 @@
  1.1124    st->print_cr("********************************************************");
  1.1125    st->cr();
  1.1126  }
  1.1127 +
  1.1128 +void ciTypeFlow::rpo_print_on(outputStream* st) const {
  1.1129 +  st->print_cr("********************************************************");
  1.1130 +  st->print   ("TypeFlow for ");
  1.1131 +  method()->name()->print_symbol_on(st);
  1.1132 +  int limit_bci = code_size();
  1.1133 +  st->print_cr("  %d bytes", limit_bci);
  1.1134 +  for (Block* blk = _rpo_list; blk != NULL; blk = blk->rpo_next()) {
  1.1135 +    blk->print_on(st);
  1.1136 +    st->print_cr("--------------------------------------------------------");
  1.1137 +    st->cr();
  1.1138 +  }
  1.1139 +  st->print_cr("********************************************************");
  1.1140 +  st->cr();
  1.1141 +}
  1.1142  #endif

mercurial