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