src/share/vm/compiler/methodLiveness.cpp

changeset 435
a61af66fc99e
child 777
37f87013dfd8
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/src/share/vm/compiler/methodLiveness.cpp	Sat Dec 01 00:00:00 2007 +0000
     1.3 @@ -0,0 +1,1063 @@
     1.4 +/*
     1.5 + * Copyright 1998-2006 Sun Microsystems, Inc.  All Rights Reserved.
     1.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     1.7 + *
     1.8 + * This code is free software; you can redistribute it and/or modify it
     1.9 + * under the terms of the GNU General Public License version 2 only, as
    1.10 + * published by the Free Software Foundation.
    1.11 + *
    1.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
    1.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    1.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    1.15 + * version 2 for more details (a copy is included in the LICENSE file that
    1.16 + * accompanied this code).
    1.17 + *
    1.18 + * You should have received a copy of the GNU General Public License version
    1.19 + * 2 along with this work; if not, write to the Free Software Foundation,
    1.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    1.21 + *
    1.22 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
    1.23 + * CA 95054 USA or visit www.sun.com if you need additional information or
    1.24 + * have any questions.
    1.25 + *
    1.26 + */
    1.27 +
    1.28 +// The MethodLiveness class performs a simple liveness analysis on a method
    1.29 +// in order to decide which locals are live (that is, will be used again) at
    1.30 +// a particular bytecode index (bci).
    1.31 +//
    1.32 +// The algorithm goes:
    1.33 +//
    1.34 +// 1. Break the method into a set of basic blocks.  For each basic block we
    1.35 +//    also keep track of its set of predecessors through normal control flow
    1.36 +//    and predecessors through exceptional control flow.
    1.37 +//
    1.38 +// 2. For each basic block, compute two sets, gen (the set of values used before
    1.39 +//    they are defined) and kill (the set of values defined before they are used)
    1.40 +//    in the basic block.  A basic block "needs" the locals in its gen set to
    1.41 +//    perform its computation.  A basic block "provides" values for the locals in
    1.42 +//    its kill set, allowing a need from a successor to be ignored.
    1.43 +//
    1.44 +// 3. Liveness information (the set of locals which are needed) is pushed backwards through
    1.45 +//    the program, from blocks to their predecessors.  We compute and store liveness
    1.46 +//    information for the normal/exceptional exit paths for each basic block.  When
    1.47 +//    this process reaches a fixed point, we are done.
    1.48 +//
    1.49 +// 4. When we are asked about the liveness at a particular bci with a basic block, we
    1.50 +//    compute gen/kill sets which represent execution from that bci to the exit of
    1.51 +//    its blocks.  We then compose this range gen/kill information with the normal
    1.52 +//    and exceptional exit information for the block to produce liveness information
    1.53 +//    at that bci.
    1.54 +//
    1.55 +// The algorithm is approximate in many respects.  Notably:
    1.56 +//
    1.57 +// 1. We do not do the analysis necessary to match jsr's with the appropriate ret.
    1.58 +//    Instead we make the conservative assumption that any ret can return to any
    1.59 +//    jsr return site.
    1.60 +// 2. Instead of computing the effects of exceptions at every instruction, we
    1.61 +//    summarize the effects of all exceptional continuations from the block as
    1.62 +//    a single set (_exception_exit), losing some information but simplifying the
    1.63 +//    analysis.
    1.64 +
    1.65 +
    1.66 +# include "incls/_precompiled.incl"
    1.67 +# include "incls/_methodLiveness.cpp.incl"
    1.68 +
    1.69 +//--------------------------------------------------------------------------
    1.70 +// The BitCounter class is used for counting the number of bits set in
    1.71 +// some BitMap.  It is only used when collecting liveness statistics.
    1.72 +
    1.73 +#ifndef PRODUCT
    1.74 +
    1.75 +class BitCounter: public BitMapClosure {
    1.76 + private:
    1.77 +  int _count;
    1.78 + public:
    1.79 +  BitCounter() : _count(0) {}
    1.80 +
    1.81 +  // Callback when bit in map is set
    1.82 +  virtual void do_bit(size_t offset) {
    1.83 +    _count++;
    1.84 +  }
    1.85 +
    1.86 +  int count() {
    1.87 +    return _count;
    1.88 +  }
    1.89 +};
    1.90 +
    1.91 +
    1.92 +//--------------------------------------------------------------------------
    1.93 +
    1.94 +
    1.95 +// Counts
    1.96 +long MethodLiveness::_total_bytes = 0;
    1.97 +int  MethodLiveness::_total_methods = 0;
    1.98 +
    1.99 +long MethodLiveness::_total_blocks = 0;
   1.100 +int  MethodLiveness::_max_method_blocks = 0;
   1.101 +
   1.102 +long MethodLiveness::_total_edges = 0;
   1.103 +int  MethodLiveness::_max_block_edges = 0;
   1.104 +
   1.105 +long MethodLiveness::_total_exc_edges = 0;
   1.106 +int  MethodLiveness::_max_block_exc_edges = 0;
   1.107 +
   1.108 +long MethodLiveness::_total_method_locals = 0;
   1.109 +int  MethodLiveness::_max_method_locals = 0;
   1.110 +
   1.111 +long MethodLiveness::_total_locals_queried = 0;
   1.112 +long MethodLiveness::_total_live_locals_queried = 0;
   1.113 +
   1.114 +long MethodLiveness::_total_visits = 0;
   1.115 +
   1.116 +#endif
   1.117 +
   1.118 +// Timers
   1.119 +elapsedTimer MethodLiveness::_time_build_graph;
   1.120 +elapsedTimer MethodLiveness::_time_gen_kill;
   1.121 +elapsedTimer MethodLiveness::_time_flow;
   1.122 +elapsedTimer MethodLiveness::_time_query;
   1.123 +elapsedTimer MethodLiveness::_time_total;
   1.124 +
   1.125 +MethodLiveness::MethodLiveness(Arena* arena, ciMethod* method)
   1.126 +#ifdef COMPILER1
   1.127 +  : _bci_block_start((uintptr_t*)arena->Amalloc((method->code_size() >> LogBitsPerByte) + 1), method->code_size())
   1.128 +#endif
   1.129 +{
   1.130 +  _arena = arena;
   1.131 +  _method = method;
   1.132 +  _bit_map_size_bits = method->max_locals();
   1.133 +  _bit_map_size_words = (_bit_map_size_bits / sizeof(unsigned int)) + 1;
   1.134 +
   1.135 +#ifdef COMPILER1
   1.136 +  _bci_block_start.clear();
   1.137 +#endif
   1.138 +}
   1.139 +
   1.140 +void MethodLiveness::compute_liveness() {
   1.141 +#ifndef PRODUCT
   1.142 +  if (TraceLivenessGen) {
   1.143 +    tty->print_cr("################################################################");
   1.144 +    tty->print("# Computing liveness information for ");
   1.145 +    method()->print_short_name();
   1.146 +  }
   1.147 +
   1.148 +  if (TimeLivenessAnalysis) _time_total.start();
   1.149 +#endif
   1.150 +
   1.151 +  {
   1.152 +    TraceTime buildGraph(NULL, &_time_build_graph, TimeLivenessAnalysis);
   1.153 +    init_basic_blocks();
   1.154 +  }
   1.155 +  {
   1.156 +    TraceTime genKill(NULL, &_time_gen_kill, TimeLivenessAnalysis);
   1.157 +    init_gen_kill();
   1.158 +  }
   1.159 +  {
   1.160 +    TraceTime flow(NULL, &_time_flow, TimeLivenessAnalysis);
   1.161 +    propagate_liveness();
   1.162 +  }
   1.163 +
   1.164 +#ifndef PRODUCT
   1.165 +  if (TimeLivenessAnalysis) _time_total.stop();
   1.166 +
   1.167 +  if (TimeLivenessAnalysis) {
   1.168 +    // Collect statistics
   1.169 +    _total_bytes += method()->code_size();
   1.170 +    _total_methods++;
   1.171 +
   1.172 +    int num_blocks = _block_count;
   1.173 +    _total_blocks += num_blocks;
   1.174 +    _max_method_blocks = MAX2(num_blocks,_max_method_blocks);
   1.175 +
   1.176 +    for (int i=0; i<num_blocks; i++) {
   1.177 +      BasicBlock *block = _block_list[i];
   1.178 +
   1.179 +      int numEdges = block->_normal_predecessors->length();
   1.180 +      int numExcEdges = block->_exception_predecessors->length();
   1.181 +
   1.182 +      _total_edges += numEdges;
   1.183 +      _total_exc_edges += numExcEdges;
   1.184 +      _max_block_edges = MAX2(numEdges,_max_block_edges);
   1.185 +      _max_block_exc_edges = MAX2(numExcEdges,_max_block_exc_edges);
   1.186 +    }
   1.187 +
   1.188 +    int numLocals = _bit_map_size_bits;
   1.189 +    _total_method_locals += numLocals;
   1.190 +    _max_method_locals = MAX2(numLocals,_max_method_locals);
   1.191 +  }
   1.192 +#endif
   1.193 +}
   1.194 +
   1.195 +
   1.196 +void MethodLiveness::init_basic_blocks() {
   1.197 +  bool bailout = false;
   1.198 +
   1.199 +  int method_len = method()->code_size();
   1.200 +  ciMethodBlocks *mblocks = method()->get_method_blocks();
   1.201 +
   1.202 +  // Create an array to store the bci->BasicBlock mapping.
   1.203 +  _block_map = new (arena()) GrowableArray<BasicBlock*>(arena(), method_len, method_len, NULL);
   1.204 +
   1.205 +  _block_count = mblocks->num_blocks();
   1.206 +  _block_list = (BasicBlock **) arena()->Amalloc(sizeof(BasicBlock *) * _block_count);
   1.207 +
   1.208 +  // Used for patching up jsr/ret control flow.
   1.209 +  GrowableArray<BasicBlock*>* jsr_exit_list = new GrowableArray<BasicBlock*>(5);
   1.210 +  GrowableArray<BasicBlock*>* ret_list = new GrowableArray<BasicBlock*>(5);
   1.211 +
   1.212 +  // generate our block list from ciMethodBlocks
   1.213 +  for (int blk = 0; blk < _block_count; blk++) {
   1.214 +    ciBlock *cib = mblocks->block(blk);
   1.215 +     int start_bci = cib->start_bci();
   1.216 +    _block_list[blk] = new (arena()) BasicBlock(this, start_bci, cib->limit_bci());
   1.217 +    _block_map->at_put(start_bci, _block_list[blk]);
   1.218 +#ifdef COMPILER1
   1.219 +    // mark all bcis where a new basic block starts
   1.220 +    _bci_block_start.set_bit(start_bci);
   1.221 +#endif // COMPILER1
   1.222 +  }
   1.223 +  // fill in the predecessors of blocks
   1.224 +  ciBytecodeStream bytes(method());
   1.225 +
   1.226 +  for (int blk = 0; blk < _block_count; blk++) {
   1.227 +    BasicBlock *current_block = _block_list[blk];
   1.228 +    int bci =  mblocks->block(blk)->control_bci();
   1.229 +
   1.230 +    if (bci == ciBlock::fall_through_bci) {
   1.231 +      int limit = current_block->limit_bci();
   1.232 +      if (limit < method_len) {
   1.233 +        BasicBlock *next = _block_map->at(limit);
   1.234 +        assert( next != NULL, "must be a block immediately following this one.");
   1.235 +        next->add_normal_predecessor(current_block);
   1.236 +      }
   1.237 +      continue;
   1.238 +    }
   1.239 +    bytes.reset_to_bci(bci);
   1.240 +    Bytecodes::Code code = bytes.next();
   1.241 +    BasicBlock *dest;
   1.242 +
   1.243 +    // Now we need to interpret the instruction's effect
   1.244 +    // on control flow.
   1.245 +    assert (current_block != NULL, "we must have a current block");
   1.246 +    switch (code) {
   1.247 +      case Bytecodes::_ifeq:
   1.248 +      case Bytecodes::_ifne:
   1.249 +      case Bytecodes::_iflt:
   1.250 +      case Bytecodes::_ifge:
   1.251 +      case Bytecodes::_ifgt:
   1.252 +      case Bytecodes::_ifle:
   1.253 +      case Bytecodes::_if_icmpeq:
   1.254 +      case Bytecodes::_if_icmpne:
   1.255 +      case Bytecodes::_if_icmplt:
   1.256 +      case Bytecodes::_if_icmpge:
   1.257 +      case Bytecodes::_if_icmpgt:
   1.258 +      case Bytecodes::_if_icmple:
   1.259 +      case Bytecodes::_if_acmpeq:
   1.260 +      case Bytecodes::_if_acmpne:
   1.261 +      case Bytecodes::_ifnull:
   1.262 +      case Bytecodes::_ifnonnull:
   1.263 +        // Two way branch.  Set predecessors at each destination.
   1.264 +        dest = _block_map->at(bytes.next_bci());
   1.265 +        assert(dest != NULL, "must be a block immediately following this one.");
   1.266 +        dest->add_normal_predecessor(current_block);
   1.267 +
   1.268 +        dest = _block_map->at(bytes.get_dest());
   1.269 +        assert(dest != NULL, "branch desination must start a block.");
   1.270 +        dest->add_normal_predecessor(current_block);
   1.271 +        break;
   1.272 +      case Bytecodes::_goto:
   1.273 +        dest = _block_map->at(bytes.get_dest());
   1.274 +        assert(dest != NULL, "branch desination must start a block.");
   1.275 +        dest->add_normal_predecessor(current_block);
   1.276 +        break;
   1.277 +      case Bytecodes::_goto_w:
   1.278 +        dest = _block_map->at(bytes.get_far_dest());
   1.279 +        assert(dest != NULL, "branch desination must start a block.");
   1.280 +        dest->add_normal_predecessor(current_block);
   1.281 +        break;
   1.282 +      case Bytecodes::_tableswitch:
   1.283 +        {
   1.284 +          Bytecode_tableswitch *tableswitch =
   1.285 +            Bytecode_tableswitch_at(bytes.cur_bcp());
   1.286 +
   1.287 +          int len = tableswitch->length();
   1.288 +
   1.289 +          dest = _block_map->at(bci + tableswitch->default_offset());
   1.290 +          assert(dest != NULL, "branch desination must start a block.");
   1.291 +          dest->add_normal_predecessor(current_block);
   1.292 +          while (--len >= 0) {
   1.293 +            dest = _block_map->at(bci + tableswitch->dest_offset_at(len));
   1.294 +            assert(dest != NULL, "branch desination must start a block.");
   1.295 +            dest->add_normal_predecessor(current_block);
   1.296 +          }
   1.297 +          break;
   1.298 +        }
   1.299 +
   1.300 +      case Bytecodes::_lookupswitch:
   1.301 +        {
   1.302 +          Bytecode_lookupswitch *lookupswitch =
   1.303 +            Bytecode_lookupswitch_at(bytes.cur_bcp());
   1.304 +
   1.305 +          int npairs = lookupswitch->number_of_pairs();
   1.306 +
   1.307 +          dest = _block_map->at(bci + lookupswitch->default_offset());
   1.308 +          assert(dest != NULL, "branch desination must start a block.");
   1.309 +          dest->add_normal_predecessor(current_block);
   1.310 +          while(--npairs >= 0) {
   1.311 +            LookupswitchPair *pair = lookupswitch->pair_at(npairs);
   1.312 +            dest = _block_map->at( bci + pair->offset());
   1.313 +            assert(dest != NULL, "branch desination must start a block.");
   1.314 +            dest->add_normal_predecessor(current_block);
   1.315 +          }
   1.316 +          break;
   1.317 +        }
   1.318 +
   1.319 +      case Bytecodes::_jsr:
   1.320 +        {
   1.321 +          assert(bytes.is_wide()==false, "sanity check");
   1.322 +          dest = _block_map->at(bytes.get_dest());
   1.323 +          assert(dest != NULL, "branch desination must start a block.");
   1.324 +          dest->add_normal_predecessor(current_block);
   1.325 +          BasicBlock *jsrExit = _block_map->at(current_block->limit_bci());
   1.326 +          assert(jsrExit != NULL, "jsr return bci must start a block.");
   1.327 +          jsr_exit_list->append(jsrExit);
   1.328 +          break;
   1.329 +        }
   1.330 +      case Bytecodes::_jsr_w:
   1.331 +        {
   1.332 +          dest = _block_map->at(bytes.get_far_dest());
   1.333 +          assert(dest != NULL, "branch desination must start a block.");
   1.334 +          dest->add_normal_predecessor(current_block);
   1.335 +          BasicBlock *jsrExit = _block_map->at(current_block->limit_bci());
   1.336 +          assert(jsrExit != NULL, "jsr return bci must start a block.");
   1.337 +          jsr_exit_list->append(jsrExit);
   1.338 +          break;
   1.339 +        }
   1.340 +
   1.341 +      case Bytecodes::_wide:
   1.342 +        assert(false, "wide opcodes should not be seen here");
   1.343 +        break;
   1.344 +      case Bytecodes::_athrow:
   1.345 +      case Bytecodes::_ireturn:
   1.346 +      case Bytecodes::_lreturn:
   1.347 +      case Bytecodes::_freturn:
   1.348 +      case Bytecodes::_dreturn:
   1.349 +      case Bytecodes::_areturn:
   1.350 +      case Bytecodes::_return:
   1.351 +        // These opcodes are  not the normal predecessors of any other opcodes.
   1.352 +        break;
   1.353 +      case Bytecodes::_ret:
   1.354 +        // We will patch up jsr/rets in a subsequent pass.
   1.355 +        ret_list->append(current_block);
   1.356 +        break;
   1.357 +      case Bytecodes::_breakpoint:
   1.358 +        // Bail out of there are breakpoints in here.
   1.359 +        bailout = true;
   1.360 +        break;
   1.361 +      default:
   1.362 +        // Do nothing.
   1.363 +        break;
   1.364 +    }
   1.365 +  }
   1.366 +  // Patch up the jsr/ret's.  We conservatively assume that any ret
   1.367 +  // can return to any jsr site.
   1.368 +  int ret_list_len = ret_list->length();
   1.369 +  int jsr_exit_list_len = jsr_exit_list->length();
   1.370 +  if (ret_list_len > 0 && jsr_exit_list_len > 0) {
   1.371 +    for (int i = jsr_exit_list_len - 1; i >= 0; i--) {
   1.372 +      BasicBlock *jsrExit = jsr_exit_list->at(i);
   1.373 +      for (int i = ret_list_len - 1; i >= 0; i--) {
   1.374 +        jsrExit->add_normal_predecessor(ret_list->at(i));
   1.375 +      }
   1.376 +    }
   1.377 +  }
   1.378 +
   1.379 +  // Compute exception edges.
   1.380 +  for (int b=_block_count-1; b >= 0; b--) {
   1.381 +    BasicBlock *block = _block_list[b];
   1.382 +    int block_start = block->start_bci();
   1.383 +    int block_limit = block->limit_bci();
   1.384 +    ciExceptionHandlerStream handlers(method());
   1.385 +    for (; !handlers.is_done(); handlers.next()) {
   1.386 +      ciExceptionHandler* handler = handlers.handler();
   1.387 +      int start       = handler->start();
   1.388 +      int limit       = handler->limit();
   1.389 +      int handler_bci = handler->handler_bci();
   1.390 +
   1.391 +      int intersect_start = MAX2(block_start, start);
   1.392 +      int intersect_limit = MIN2(block_limit, limit);
   1.393 +      if (intersect_start < intersect_limit) {
   1.394 +        // The catch range has a nonempty intersection with this
   1.395 +        // basic block.  That means this basic block can be an
   1.396 +        // exceptional predecessor.
   1.397 +        _block_map->at(handler_bci)->add_exception_predecessor(block);
   1.398 +
   1.399 +        if (handler->is_catch_all()) {
   1.400 +          // This is a catch-all block.
   1.401 +          if (intersect_start == block_start && intersect_limit == block_limit) {
   1.402 +            // The basic block is entirely contained in this catch-all block.
   1.403 +            // Skip the rest of the exception handlers -- they can never be
   1.404 +            // reached in execution.
   1.405 +            break;
   1.406 +          }
   1.407 +        }
   1.408 +      }
   1.409 +    }
   1.410 +  }
   1.411 +}
   1.412 +
   1.413 +void MethodLiveness::init_gen_kill() {
   1.414 +  for (int i=_block_count-1; i >= 0; i--) {
   1.415 +    _block_list[i]->compute_gen_kill(method());
   1.416 +  }
   1.417 +}
   1.418 +
   1.419 +void MethodLiveness::propagate_liveness() {
   1.420 +  int num_blocks = _block_count;
   1.421 +  BasicBlock *block;
   1.422 +
   1.423 +  // We start our work list off with all blocks in it.
   1.424 +  // Alternately, we could start off the work list with the list of all
   1.425 +  // blocks which could exit the method directly, along with one block
   1.426 +  // from any infinite loop.  If this matters, it can be changed.  It
   1.427 +  // may not be clear from looking at the code, but the order of the
   1.428 +  // workList will be the opposite of the creation order of the basic
   1.429 +  // blocks, which should be decent for quick convergence (with the
   1.430 +  // possible exception of exception handlers, which are all created
   1.431 +  // early).
   1.432 +  _work_list = NULL;
   1.433 +  for (int i = 0; i < num_blocks; i++) {
   1.434 +    block = _block_list[i];
   1.435 +    block->set_next(_work_list);
   1.436 +    block->set_on_work_list(true);
   1.437 +    _work_list = block;
   1.438 +  }
   1.439 +
   1.440 +
   1.441 +  while ((block = work_list_get()) != NULL) {
   1.442 +    block->propagate(this);
   1.443 +    NOT_PRODUCT(_total_visits++;)
   1.444 +  }
   1.445 +}
   1.446 +
   1.447 +void MethodLiveness::work_list_add(BasicBlock *block) {
   1.448 +  if (!block->on_work_list()) {
   1.449 +    block->set_next(_work_list);
   1.450 +    block->set_on_work_list(true);
   1.451 +    _work_list = block;
   1.452 +  }
   1.453 +}
   1.454 +
   1.455 +MethodLiveness::BasicBlock *MethodLiveness::work_list_get() {
   1.456 +  BasicBlock *block = _work_list;
   1.457 +  if (block != NULL) {
   1.458 +    block->set_on_work_list(false);
   1.459 +    _work_list = block->next();
   1.460 +  }
   1.461 +  return block;
   1.462 +}
   1.463 +
   1.464 +
   1.465 +MethodLivenessResult MethodLiveness::get_liveness_at(int entry_bci) {
   1.466 +  int bci = entry_bci;
   1.467 +  bool is_entry = false;
   1.468 +  if (entry_bci == InvocationEntryBci) {
   1.469 +    is_entry = true;
   1.470 +    bci = 0;
   1.471 +  }
   1.472 +
   1.473 +  MethodLivenessResult answer(NULL,0);
   1.474 +
   1.475 +  if (_block_count > 0) {
   1.476 +    if (TimeLivenessAnalysis) _time_total.start();
   1.477 +    if (TimeLivenessAnalysis) _time_query.start();
   1.478 +
   1.479 +    assert( 0 <= bci && bci < method()->code_size(), "bci out of range" );
   1.480 +    BasicBlock *block = _block_map->at(bci);
   1.481 +    // We may not be at the block start, so search backwards to find the block
   1.482 +    // containing bci.
   1.483 +    int t = bci;
   1.484 +    while (block == NULL && t > 0) {
   1.485 +     block = _block_map->at(--t);
   1.486 +    }
   1.487 +    assert( block != NULL, "invalid bytecode index; must be instruction index" );
   1.488 +    assert(bci >= block->start_bci() && bci < block->limit_bci(), "block must contain bci.");
   1.489 +
   1.490 +    answer = block->get_liveness_at(method(), bci);
   1.491 +
   1.492 +    if (is_entry && method()->is_synchronized() && !method()->is_static()) {
   1.493 +      // Synchronized methods use the receiver once on entry.
   1.494 +      answer.at_put(0, true);
   1.495 +    }
   1.496 +
   1.497 +#ifndef PRODUCT
   1.498 +    if (TraceLivenessQuery) {
   1.499 +      tty->print("Liveness query of ");
   1.500 +      method()->print_short_name();
   1.501 +      tty->print(" @ %d : result is ", bci);
   1.502 +      answer.print_on(tty);
   1.503 +    }
   1.504 +
   1.505 +    if (TimeLivenessAnalysis) _time_query.stop();
   1.506 +    if (TimeLivenessAnalysis) _time_total.stop();
   1.507 +#endif
   1.508 +  }
   1.509 +
   1.510 +#ifndef PRODUCT
   1.511 +  if (TimeLivenessAnalysis) {
   1.512 +    // Collect statistics.
   1.513 +    _total_locals_queried += _bit_map_size_bits;
   1.514 +    BitCounter counter;
   1.515 +    answer.iterate(&counter);
   1.516 +    _total_live_locals_queried += counter.count();
   1.517 +  }
   1.518 +#endif
   1.519 +
   1.520 +  return answer;
   1.521 +}
   1.522 +
   1.523 +
   1.524 +#ifndef PRODUCT
   1.525 +
   1.526 +void MethodLiveness::print_times() {
   1.527 +  tty->print_cr ("Accumulated liveness analysis times/statistics:");
   1.528 +  tty->print_cr ("-----------------------------------------------");
   1.529 +  tty->print_cr ("  Total         : %3.3f sec.", _time_total.seconds());
   1.530 +  tty->print_cr ("    Build graph : %3.3f sec. (%2.2f%%)", _time_build_graph.seconds(),
   1.531 +                 _time_build_graph.seconds() * 100 / _time_total.seconds());
   1.532 +  tty->print_cr ("    Gen / Kill  : %3.3f sec. (%2.2f%%)", _time_gen_kill.seconds(),
   1.533 +                 _time_gen_kill.seconds() * 100 / _time_total.seconds());
   1.534 +  tty->print_cr ("    Dataflow    : %3.3f sec. (%2.2f%%)", _time_flow.seconds(),
   1.535 +                 _time_flow.seconds() * 100 / _time_total.seconds());
   1.536 +  tty->print_cr ("    Query       : %3.3f sec. (%2.2f%%)", _time_query.seconds(),
   1.537 +                 _time_query.seconds() * 100 / _time_total.seconds());
   1.538 +  tty->print_cr ("  #bytes   : %8d (%3.0f bytes per sec)",
   1.539 +                 _total_bytes,
   1.540 +                 _total_bytes / _time_total.seconds());
   1.541 +  tty->print_cr ("  #methods : %8d (%3.0f methods per sec)",
   1.542 +                 _total_methods,
   1.543 +                 _total_methods / _time_total.seconds());
   1.544 +  tty->print_cr ("    avg locals : %3.3f    max locals : %3d",
   1.545 +                 (float)_total_method_locals / _total_methods,
   1.546 +                 _max_method_locals);
   1.547 +  tty->print_cr ("    avg blocks : %3.3f    max blocks : %3d",
   1.548 +                 (float)_total_blocks / _total_methods,
   1.549 +                 _max_method_blocks);
   1.550 +  tty->print_cr ("    avg bytes  : %3.3f",
   1.551 +                 (float)_total_bytes / _total_methods);
   1.552 +  tty->print_cr ("  #blocks  : %8d",
   1.553 +                 _total_blocks);
   1.554 +  tty->print_cr ("    avg normal predecessors    : %3.3f  max normal predecessors    : %3d",
   1.555 +                 (float)_total_edges / _total_blocks,
   1.556 +                 _max_block_edges);
   1.557 +  tty->print_cr ("    avg exception predecessors : %3.3f  max exception predecessors : %3d",
   1.558 +                 (float)_total_exc_edges / _total_blocks,
   1.559 +                 _max_block_exc_edges);
   1.560 +  tty->print_cr ("    avg visits                 : %3.3f",
   1.561 +                 (float)_total_visits / _total_blocks);
   1.562 +  tty->print_cr ("  #locals queried : %8d    #live : %8d   %%live : %2.2f%%",
   1.563 +                 _total_locals_queried,
   1.564 +                 _total_live_locals_queried,
   1.565 +                 100.0 * _total_live_locals_queried / _total_locals_queried);
   1.566 +}
   1.567 +
   1.568 +#endif
   1.569 +
   1.570 +
   1.571 +MethodLiveness::BasicBlock::BasicBlock(MethodLiveness *analyzer, int start, int limit) :
   1.572 +         _gen((uintptr_t*)analyzer->arena()->Amalloc(BytesPerWord * analyzer->bit_map_size_words()),
   1.573 +                         analyzer->bit_map_size_bits()),
   1.574 +         _kill((uintptr_t*)analyzer->arena()->Amalloc(BytesPerWord * analyzer->bit_map_size_words()),
   1.575 +                         analyzer->bit_map_size_bits()),
   1.576 +         _entry((uintptr_t*)analyzer->arena()->Amalloc(BytesPerWord * analyzer->bit_map_size_words()),
   1.577 +                         analyzer->bit_map_size_bits()),
   1.578 +         _normal_exit((uintptr_t*)analyzer->arena()->Amalloc(BytesPerWord * analyzer->bit_map_size_words()),
   1.579 +                         analyzer->bit_map_size_bits()),
   1.580 +         _exception_exit((uintptr_t*)analyzer->arena()->Amalloc(BytesPerWord * analyzer->bit_map_size_words()),
   1.581 +                         analyzer->bit_map_size_bits()),
   1.582 +         _last_bci(-1) {
   1.583 +  _analyzer = analyzer;
   1.584 +  _start_bci = start;
   1.585 +  _limit_bci = limit;
   1.586 +  _normal_predecessors =
   1.587 +    new (analyzer->arena()) GrowableArray<MethodLiveness::BasicBlock*>(analyzer->arena(), 5, 0, NULL);
   1.588 +  _exception_predecessors =
   1.589 +    new (analyzer->arena()) GrowableArray<MethodLiveness::BasicBlock*>(analyzer->arena(), 5, 0, NULL);
   1.590 +  _normal_exit.clear();
   1.591 +  _exception_exit.clear();
   1.592 +  _entry.clear();
   1.593 +
   1.594 +  // this initialization is not strictly necessary.
   1.595 +  // _gen and _kill are cleared at the beginning of compute_gen_kill_range()
   1.596 +  _gen.clear();
   1.597 +  _kill.clear();
   1.598 +}
   1.599 +
   1.600 +
   1.601 +
   1.602 +MethodLiveness::BasicBlock *MethodLiveness::BasicBlock::split(int split_bci) {
   1.603 +  int start = _start_bci;
   1.604 +  int limit = _limit_bci;
   1.605 +
   1.606 +  if (TraceLivenessGen) {
   1.607 +    tty->print_cr(" ** Splitting block (%d,%d) at %d", start, limit, split_bci);
   1.608 +  }
   1.609 +
   1.610 +  GrowableArray<BasicBlock*>* save_predecessors = _normal_predecessors;
   1.611 +
   1.612 +  assert (start < split_bci && split_bci < limit, "improper split");
   1.613 +
   1.614 +  // Make a new block to cover the first half of the range.
   1.615 +  BasicBlock *first_half = new (_analyzer->arena()) BasicBlock(_analyzer, start, split_bci);
   1.616 +
   1.617 +  // Assign correct values to the second half (this)
   1.618 +  _normal_predecessors = first_half->_normal_predecessors;
   1.619 +  _start_bci = split_bci;
   1.620 +  add_normal_predecessor(first_half);
   1.621 +
   1.622 +  // Assign correct predecessors to the new first half
   1.623 +  first_half->_normal_predecessors = save_predecessors;
   1.624 +
   1.625 +  return first_half;
   1.626 +}
   1.627 +
   1.628 +void MethodLiveness::BasicBlock::compute_gen_kill(ciMethod* method) {
   1.629 +  ciBytecodeStream bytes(method);
   1.630 +  bytes.reset_to_bci(start_bci());
   1.631 +  bytes.set_max_bci(limit_bci());
   1.632 +  compute_gen_kill_range(&bytes);
   1.633 +
   1.634 +}
   1.635 +
   1.636 +void MethodLiveness::BasicBlock::compute_gen_kill_range(ciBytecodeStream *bytes) {
   1.637 +  _gen.clear();
   1.638 +  _kill.clear();
   1.639 +
   1.640 +  while (bytes->next() != ciBytecodeStream::EOBC()) {
   1.641 +    compute_gen_kill_single(bytes);
   1.642 +  }
   1.643 +}
   1.644 +
   1.645 +void MethodLiveness::BasicBlock::compute_gen_kill_single(ciBytecodeStream *instruction) {
   1.646 +  int localNum;
   1.647 +
   1.648 +  // We prohibit _gen and _kill from having locals in common.  If we
   1.649 +  // know that one is definitely going to be applied before the other,
   1.650 +  // we could save some computation time by relaxing this prohibition.
   1.651 +
   1.652 +  switch (instruction->cur_bc()) {
   1.653 +    case Bytecodes::_nop:
   1.654 +    case Bytecodes::_goto:
   1.655 +    case Bytecodes::_goto_w:
   1.656 +    case Bytecodes::_aconst_null:
   1.657 +    case Bytecodes::_new:
   1.658 +    case Bytecodes::_iconst_m1:
   1.659 +    case Bytecodes::_iconst_0:
   1.660 +    case Bytecodes::_iconst_1:
   1.661 +    case Bytecodes::_iconst_2:
   1.662 +    case Bytecodes::_iconst_3:
   1.663 +    case Bytecodes::_iconst_4:
   1.664 +    case Bytecodes::_iconst_5:
   1.665 +    case Bytecodes::_fconst_0:
   1.666 +    case Bytecodes::_fconst_1:
   1.667 +    case Bytecodes::_fconst_2:
   1.668 +    case Bytecodes::_bipush:
   1.669 +    case Bytecodes::_sipush:
   1.670 +    case Bytecodes::_lconst_0:
   1.671 +    case Bytecodes::_lconst_1:
   1.672 +    case Bytecodes::_dconst_0:
   1.673 +    case Bytecodes::_dconst_1:
   1.674 +    case Bytecodes::_ldc2_w:
   1.675 +    case Bytecodes::_ldc:
   1.676 +    case Bytecodes::_ldc_w:
   1.677 +    case Bytecodes::_iaload:
   1.678 +    case Bytecodes::_faload:
   1.679 +    case Bytecodes::_baload:
   1.680 +    case Bytecodes::_caload:
   1.681 +    case Bytecodes::_saload:
   1.682 +    case Bytecodes::_laload:
   1.683 +    case Bytecodes::_daload:
   1.684 +    case Bytecodes::_aaload:
   1.685 +    case Bytecodes::_iastore:
   1.686 +    case Bytecodes::_fastore:
   1.687 +    case Bytecodes::_bastore:
   1.688 +    case Bytecodes::_castore:
   1.689 +    case Bytecodes::_sastore:
   1.690 +    case Bytecodes::_lastore:
   1.691 +    case Bytecodes::_dastore:
   1.692 +    case Bytecodes::_aastore:
   1.693 +    case Bytecodes::_pop:
   1.694 +    case Bytecodes::_pop2:
   1.695 +    case Bytecodes::_dup:
   1.696 +    case Bytecodes::_dup_x1:
   1.697 +    case Bytecodes::_dup_x2:
   1.698 +    case Bytecodes::_dup2:
   1.699 +    case Bytecodes::_dup2_x1:
   1.700 +    case Bytecodes::_dup2_x2:
   1.701 +    case Bytecodes::_swap:
   1.702 +    case Bytecodes::_iadd:
   1.703 +    case Bytecodes::_fadd:
   1.704 +    case Bytecodes::_isub:
   1.705 +    case Bytecodes::_fsub:
   1.706 +    case Bytecodes::_imul:
   1.707 +    case Bytecodes::_fmul:
   1.708 +    case Bytecodes::_idiv:
   1.709 +    case Bytecodes::_fdiv:
   1.710 +    case Bytecodes::_irem:
   1.711 +    case Bytecodes::_frem:
   1.712 +    case Bytecodes::_ishl:
   1.713 +    case Bytecodes::_ishr:
   1.714 +    case Bytecodes::_iushr:
   1.715 +    case Bytecodes::_iand:
   1.716 +    case Bytecodes::_ior:
   1.717 +    case Bytecodes::_ixor:
   1.718 +    case Bytecodes::_l2f:
   1.719 +    case Bytecodes::_l2i:
   1.720 +    case Bytecodes::_d2f:
   1.721 +    case Bytecodes::_d2i:
   1.722 +    case Bytecodes::_fcmpl:
   1.723 +    case Bytecodes::_fcmpg:
   1.724 +    case Bytecodes::_ladd:
   1.725 +    case Bytecodes::_dadd:
   1.726 +    case Bytecodes::_lsub:
   1.727 +    case Bytecodes::_dsub:
   1.728 +    case Bytecodes::_lmul:
   1.729 +    case Bytecodes::_dmul:
   1.730 +    case Bytecodes::_ldiv:
   1.731 +    case Bytecodes::_ddiv:
   1.732 +    case Bytecodes::_lrem:
   1.733 +    case Bytecodes::_drem:
   1.734 +    case Bytecodes::_land:
   1.735 +    case Bytecodes::_lor:
   1.736 +    case Bytecodes::_lxor:
   1.737 +    case Bytecodes::_ineg:
   1.738 +    case Bytecodes::_fneg:
   1.739 +    case Bytecodes::_i2f:
   1.740 +    case Bytecodes::_f2i:
   1.741 +    case Bytecodes::_i2c:
   1.742 +    case Bytecodes::_i2s:
   1.743 +    case Bytecodes::_i2b:
   1.744 +    case Bytecodes::_lneg:
   1.745 +    case Bytecodes::_dneg:
   1.746 +    case Bytecodes::_l2d:
   1.747 +    case Bytecodes::_d2l:
   1.748 +    case Bytecodes::_lshl:
   1.749 +    case Bytecodes::_lshr:
   1.750 +    case Bytecodes::_lushr:
   1.751 +    case Bytecodes::_i2l:
   1.752 +    case Bytecodes::_i2d:
   1.753 +    case Bytecodes::_f2l:
   1.754 +    case Bytecodes::_f2d:
   1.755 +    case Bytecodes::_lcmp:
   1.756 +    case Bytecodes::_dcmpl:
   1.757 +    case Bytecodes::_dcmpg:
   1.758 +    case Bytecodes::_ifeq:
   1.759 +    case Bytecodes::_ifne:
   1.760 +    case Bytecodes::_iflt:
   1.761 +    case Bytecodes::_ifge:
   1.762 +    case Bytecodes::_ifgt:
   1.763 +    case Bytecodes::_ifle:
   1.764 +    case Bytecodes::_tableswitch:
   1.765 +    case Bytecodes::_ireturn:
   1.766 +    case Bytecodes::_freturn:
   1.767 +    case Bytecodes::_if_icmpeq:
   1.768 +    case Bytecodes::_if_icmpne:
   1.769 +    case Bytecodes::_if_icmplt:
   1.770 +    case Bytecodes::_if_icmpge:
   1.771 +    case Bytecodes::_if_icmpgt:
   1.772 +    case Bytecodes::_if_icmple:
   1.773 +    case Bytecodes::_lreturn:
   1.774 +    case Bytecodes::_dreturn:
   1.775 +    case Bytecodes::_if_acmpeq:
   1.776 +    case Bytecodes::_if_acmpne:
   1.777 +    case Bytecodes::_jsr:
   1.778 +    case Bytecodes::_jsr_w:
   1.779 +    case Bytecodes::_getstatic:
   1.780 +    case Bytecodes::_putstatic:
   1.781 +    case Bytecodes::_getfield:
   1.782 +    case Bytecodes::_putfield:
   1.783 +    case Bytecodes::_invokevirtual:
   1.784 +    case Bytecodes::_invokespecial:
   1.785 +    case Bytecodes::_invokestatic:
   1.786 +    case Bytecodes::_invokeinterface:
   1.787 +    case Bytecodes::_newarray:
   1.788 +    case Bytecodes::_anewarray:
   1.789 +    case Bytecodes::_checkcast:
   1.790 +    case Bytecodes::_arraylength:
   1.791 +    case Bytecodes::_instanceof:
   1.792 +    case Bytecodes::_athrow:
   1.793 +    case Bytecodes::_areturn:
   1.794 +    case Bytecodes::_monitorenter:
   1.795 +    case Bytecodes::_monitorexit:
   1.796 +    case Bytecodes::_ifnull:
   1.797 +    case Bytecodes::_ifnonnull:
   1.798 +    case Bytecodes::_multianewarray:
   1.799 +    case Bytecodes::_lookupswitch:
   1.800 +      // These bytecodes have no effect on the method's locals.
   1.801 +      break;
   1.802 +
   1.803 +    case Bytecodes::_return:
   1.804 +      if (instruction->method()->intrinsic_id() == vmIntrinsics::_Object_init) {
   1.805 +        // return from Object.init implicitly registers a finalizer
   1.806 +        // for the receiver if needed, so keep it alive.
   1.807 +        load_one(0);
   1.808 +      }
   1.809 +      break;
   1.810 +
   1.811 +
   1.812 +    case Bytecodes::_lload:
   1.813 +    case Bytecodes::_dload:
   1.814 +      load_two(instruction->get_index());
   1.815 +      break;
   1.816 +
   1.817 +    case Bytecodes::_lload_0:
   1.818 +    case Bytecodes::_dload_0:
   1.819 +      load_two(0);
   1.820 +      break;
   1.821 +
   1.822 +    case Bytecodes::_lload_1:
   1.823 +    case Bytecodes::_dload_1:
   1.824 +      load_two(1);
   1.825 +      break;
   1.826 +
   1.827 +    case Bytecodes::_lload_2:
   1.828 +    case Bytecodes::_dload_2:
   1.829 +      load_two(2);
   1.830 +      break;
   1.831 +
   1.832 +    case Bytecodes::_lload_3:
   1.833 +    case Bytecodes::_dload_3:
   1.834 +      load_two(3);
   1.835 +      break;
   1.836 +
   1.837 +    case Bytecodes::_iload:
   1.838 +    case Bytecodes::_iinc:
   1.839 +    case Bytecodes::_fload:
   1.840 +    case Bytecodes::_aload:
   1.841 +    case Bytecodes::_ret:
   1.842 +      load_one(instruction->get_index());
   1.843 +      break;
   1.844 +
   1.845 +    case Bytecodes::_iload_0:
   1.846 +    case Bytecodes::_fload_0:
   1.847 +    case Bytecodes::_aload_0:
   1.848 +      load_one(0);
   1.849 +      break;
   1.850 +
   1.851 +    case Bytecodes::_iload_1:
   1.852 +    case Bytecodes::_fload_1:
   1.853 +    case Bytecodes::_aload_1:
   1.854 +      load_one(1);
   1.855 +      break;
   1.856 +
   1.857 +    case Bytecodes::_iload_2:
   1.858 +    case Bytecodes::_fload_2:
   1.859 +    case Bytecodes::_aload_2:
   1.860 +      load_one(2);
   1.861 +      break;
   1.862 +
   1.863 +    case Bytecodes::_iload_3:
   1.864 +    case Bytecodes::_fload_3:
   1.865 +    case Bytecodes::_aload_3:
   1.866 +      load_one(3);
   1.867 +      break;
   1.868 +
   1.869 +    case Bytecodes::_lstore:
   1.870 +    case Bytecodes::_dstore:
   1.871 +      store_two(localNum = instruction->get_index());
   1.872 +      break;
   1.873 +
   1.874 +    case Bytecodes::_lstore_0:
   1.875 +    case Bytecodes::_dstore_0:
   1.876 +      store_two(0);
   1.877 +      break;
   1.878 +
   1.879 +    case Bytecodes::_lstore_1:
   1.880 +    case Bytecodes::_dstore_1:
   1.881 +      store_two(1);
   1.882 +      break;
   1.883 +
   1.884 +    case Bytecodes::_lstore_2:
   1.885 +    case Bytecodes::_dstore_2:
   1.886 +      store_two(2);
   1.887 +      break;
   1.888 +
   1.889 +    case Bytecodes::_lstore_3:
   1.890 +    case Bytecodes::_dstore_3:
   1.891 +      store_two(3);
   1.892 +      break;
   1.893 +
   1.894 +    case Bytecodes::_istore:
   1.895 +    case Bytecodes::_fstore:
   1.896 +    case Bytecodes::_astore:
   1.897 +      store_one(instruction->get_index());
   1.898 +      break;
   1.899 +
   1.900 +    case Bytecodes::_istore_0:
   1.901 +    case Bytecodes::_fstore_0:
   1.902 +    case Bytecodes::_astore_0:
   1.903 +      store_one(0);
   1.904 +      break;
   1.905 +
   1.906 +    case Bytecodes::_istore_1:
   1.907 +    case Bytecodes::_fstore_1:
   1.908 +    case Bytecodes::_astore_1:
   1.909 +      store_one(1);
   1.910 +      break;
   1.911 +
   1.912 +    case Bytecodes::_istore_2:
   1.913 +    case Bytecodes::_fstore_2:
   1.914 +    case Bytecodes::_astore_2:
   1.915 +      store_one(2);
   1.916 +      break;
   1.917 +
   1.918 +    case Bytecodes::_istore_3:
   1.919 +    case Bytecodes::_fstore_3:
   1.920 +    case Bytecodes::_astore_3:
   1.921 +      store_one(3);
   1.922 +      break;
   1.923 +
   1.924 +    case Bytecodes::_wide:
   1.925 +      fatal("Iterator should skip this bytecode");
   1.926 +      break;
   1.927 +
   1.928 +    default:
   1.929 +      tty->print("unexpected opcode: %d\n", instruction->cur_bc());
   1.930 +      ShouldNotReachHere();
   1.931 +      break;
   1.932 +  }
   1.933 +}
   1.934 +
   1.935 +void MethodLiveness::BasicBlock::load_two(int local) {
   1.936 +  load_one(local);
   1.937 +  load_one(local+1);
   1.938 +}
   1.939 +
   1.940 +void MethodLiveness::BasicBlock::load_one(int local) {
   1.941 +  if (!_kill.at(local)) {
   1.942 +    _gen.at_put(local, true);
   1.943 +  }
   1.944 +}
   1.945 +
   1.946 +void MethodLiveness::BasicBlock::store_two(int local) {
   1.947 +  store_one(local);
   1.948 +  store_one(local+1);
   1.949 +}
   1.950 +
   1.951 +void MethodLiveness::BasicBlock::store_one(int local) {
   1.952 +  if (!_gen.at(local)) {
   1.953 +    _kill.at_put(local, true);
   1.954 +  }
   1.955 +}
   1.956 +
   1.957 +void MethodLiveness::BasicBlock::propagate(MethodLiveness *ml) {
   1.958 +  // These set operations could be combined for efficiency if the
   1.959 +  // performance of this analysis becomes an issue.
   1.960 +  _entry.set_union(_normal_exit);
   1.961 +  _entry.set_difference(_kill);
   1.962 +  _entry.set_union(_gen);
   1.963 +
   1.964 +  // Note that we merge information from our exceptional successors
   1.965 +  // just once, rather than at individual bytecodes.
   1.966 +  _entry.set_union(_exception_exit);
   1.967 +
   1.968 +  if (TraceLivenessGen) {
   1.969 +    tty->print_cr(" ** Visiting block at %d **", start_bci());
   1.970 +    print_on(tty);
   1.971 +  }
   1.972 +
   1.973 +  int i;
   1.974 +  for (i=_normal_predecessors->length()-1; i>=0; i--) {
   1.975 +    BasicBlock *block = _normal_predecessors->at(i);
   1.976 +    if (block->merge_normal(_entry)) {
   1.977 +      ml->work_list_add(block);
   1.978 +    }
   1.979 +  }
   1.980 +  for (i=_exception_predecessors->length()-1; i>=0; i--) {
   1.981 +    BasicBlock *block = _exception_predecessors->at(i);
   1.982 +    if (block->merge_exception(_entry)) {
   1.983 +      ml->work_list_add(block);
   1.984 +    }
   1.985 +  }
   1.986 +}
   1.987 +
   1.988 +bool MethodLiveness::BasicBlock::merge_normal(BitMap other) {
   1.989 +  return _normal_exit.set_union_with_result(other);
   1.990 +}
   1.991 +
   1.992 +bool MethodLiveness::BasicBlock::merge_exception(BitMap other) {
   1.993 +  return _exception_exit.set_union_with_result(other);
   1.994 +}
   1.995 +
   1.996 +MethodLivenessResult MethodLiveness::BasicBlock::get_liveness_at(ciMethod* method, int bci) {
   1.997 +  MethodLivenessResult answer(NEW_RESOURCE_ARRAY(uintptr_t, _analyzer->bit_map_size_words()),
   1.998 +                _analyzer->bit_map_size_bits());
   1.999 +  answer.set_is_valid();
  1.1000 +
  1.1001 +#ifndef ASSERT
  1.1002 +  if (bci == start_bci()) {
  1.1003 +    answer.set_from(_entry);
  1.1004 +    return answer;
  1.1005 +  }
  1.1006 +#endif
  1.1007 +
  1.1008 +#ifdef ASSERT
  1.1009 +  ResourceMark rm;
  1.1010 +  BitMap g(_gen.size()); g.set_from(_gen);
  1.1011 +  BitMap k(_kill.size()); k.set_from(_kill);
  1.1012 +#endif
  1.1013 +  if (_last_bci != bci || trueInDebug) {
  1.1014 +    ciBytecodeStream bytes(method);
  1.1015 +    bytes.reset_to_bci(bci);
  1.1016 +    bytes.set_max_bci(limit_bci());
  1.1017 +    compute_gen_kill_range(&bytes);
  1.1018 +    assert(_last_bci != bci ||
  1.1019 +           (g.is_same(_gen) && k.is_same(_kill)), "cached computation is incorrect");
  1.1020 +    _last_bci = bci;
  1.1021 +  }
  1.1022 +
  1.1023 +  answer.clear();
  1.1024 +  answer.set_union(_normal_exit);
  1.1025 +  answer.set_difference(_kill);
  1.1026 +  answer.set_union(_gen);
  1.1027 +  answer.set_union(_exception_exit);
  1.1028 +
  1.1029 +#ifdef ASSERT
  1.1030 +  if (bci == start_bci()) {
  1.1031 +    assert(answer.is_same(_entry), "optimized answer must be accurate");
  1.1032 +  }
  1.1033 +#endif
  1.1034 +
  1.1035 +  return answer;
  1.1036 +}
  1.1037 +
  1.1038 +#ifndef PRODUCT
  1.1039 +
  1.1040 +void MethodLiveness::BasicBlock::print_on(outputStream *os) const {
  1.1041 +  os->print_cr("===================================================================");
  1.1042 +  os->print_cr("    Block start: %4d, limit: %4d", _start_bci, _limit_bci);
  1.1043 +  os->print   ("    Normal predecessors (%2d)      @", _normal_predecessors->length());
  1.1044 +  int i;
  1.1045 +  for (i=0; i < _normal_predecessors->length(); i++) {
  1.1046 +    os->print(" %4d", _normal_predecessors->at(i)->start_bci());
  1.1047 +  }
  1.1048 +  os->cr();
  1.1049 +  os->print   ("    Exceptional predecessors (%2d) @", _exception_predecessors->length());
  1.1050 +  for (i=0; i < _exception_predecessors->length(); i++) {
  1.1051 +    os->print(" %4d", _exception_predecessors->at(i)->start_bci());
  1.1052 +  }
  1.1053 +  os->cr();
  1.1054 +  os->print ("    Normal Exit   : ");
  1.1055 +  _normal_exit.print_on(os);
  1.1056 +  os->print ("    Gen           : ");
  1.1057 +  _gen.print_on(os);
  1.1058 +  os->print ("    Kill          : ");
  1.1059 +  _kill.print_on(os);
  1.1060 +  os->print ("    Exception Exit: ");
  1.1061 +  _exception_exit.print_on(os);
  1.1062 +  os->print ("    Entry         : ");
  1.1063 +  _entry.print_on(os);
  1.1064 +}
  1.1065 +
  1.1066 +#endif // PRODUCT

mercurial