1 #ifdef USE_PRAGMA_IDENT_SRC 2 #pragma ident "@(#)ciMethodBlocks.cpp 1.6 07/09/28 10:23:22 JVM" 3 #endif 4 /* 5 * Copyright 2006 Sun Microsystems, Inc. All Rights Reserved. 6 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 7 * 8 * This code is free software; you can redistribute it and/or modify it 9 * under the terms of the GNU General Public License version 2 only, as 10 * published by the Free Software Foundation. 11 * 12 * This code is distributed in the hope that it will be useful, but WITHOUT 13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 14 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 15 * version 2 for more details (a copy is included in the LICENSE file that 16 * accompanied this code). 17 * 18 * You should have received a copy of the GNU General Public License version 19 * 2 along with this work; if not, write to the Free Software Foundation, 20 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 21 * 22 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, 23 * CA 95054 USA or visit www.sun.com if you need additional information or 24 * have any questions. 25 * 26 */ 27 28 #include "incls/_precompiled.incl" 29 #include "incls/_ciMethodBlocks.cpp.incl" 30 31 // ciMethodBlocks 32 33 34 35 ciBlock *ciMethodBlocks::block_containing(int bci) { 36 ciBlock *blk = _bci_to_block[bci]; 37 return blk; 38 } 39 40 bool ciMethodBlocks::is_block_start(int bci) { 41 assert(bci >=0 && bci < _code_size, "valid bytecode range"); 42 ciBlock *b = _bci_to_block[bci]; 43 assert(b != NULL, "must have block for bytecode"); 44 return b->start_bci() == bci; 45 } 46 47 // ------------------------------------------------------------------ 48 // ciMethodBlocks::split_block_at 49 // 50 // Split the block spanning bci into two separate ranges. The former 51 // block becomes the second half and a new range is created for the 52 // first half. Returns the range beginning at bci. 53 ciBlock *ciMethodBlocks::split_block_at(int bci) { 54 ciBlock *former_block = block_containing(bci); 55 ciBlock *new_block = new(_arena) ciBlock(_method, _num_blocks++, this, former_block->start_bci()); 56 _blocks->append(new_block); 57 assert(former_block != NULL, "must not be NULL"); 58 new_block->set_limit_bci(bci); 59 former_block->set_start_bci(bci); 60 for (int pos=bci-1; pos >= 0; pos--) { 61 ciBlock *current_block = block_containing(pos); 62 if (current_block == former_block) { 63 // Replace it. 64 _bci_to_block[pos] = new_block; 65 } else if (current_block == NULL) { 66 // Non-bytecode start. Skip. 67 continue; 68 } else { 69 // We are done with our backwards walk 70 break; 71 } 72 } 73 return former_block; 74 } 75 76 ciBlock *ciMethodBlocks::make_block_at(int bci) { 77 ciBlock *cb = block_containing(bci); 78 if (cb == NULL ) { 79 // This is our first time visiting this bytecode. Create 80 // a fresh block and assign it this starting point. 81 ciBlock *nb = new(_arena) ciBlock(_method, _num_blocks++, this, bci); 82 _blocks->append(nb); 83 _bci_to_block[bci] = nb; 84 return nb; 85 } else if (cb->start_bci() == bci) { 86 // The block begins at bci. Simply return it. 87 return cb; 88 } else { 89 // We have already created a block containing bci but 90 // not starting at bci. This existing block needs to 91 // be split into two. 92 return split_block_at(bci); 93 } 94 } 95 96 void ciMethodBlocks::do_analysis() { 97 ciBytecodeStream s(_method); 98 ciBlock *cur_block = block_containing(0); 99 int limit_bci = _method->code_size(); 100 101 while (s.next() != ciBytecodeStream::EOBC()) { 102 int bci = s.cur_bci(); 103 // Determine if a new block has been made at the current bci. If 104 // this block differs from our current range, switch to the new 105 // one and end the old one. 106 assert(cur_block != NULL, "must always have a current block"); 107 ciBlock *new_block = block_containing(bci); 108 if (new_block == NULL) { 109 // We have not marked this bci as the start of a new block. 110 // Keep interpreting the current_range. 111 _bci_to_block[bci] = cur_block; 112 } else { 113 cur_block->set_limit_bci(bci); 114 cur_block = new_block; 115 } 116 117 switch (s.cur_bc()) { 118 case Bytecodes::_ifeq : 119 case Bytecodes::_ifne : 120 case Bytecodes::_iflt : 121 case Bytecodes::_ifge : 122 case Bytecodes::_ifgt : 123 case Bytecodes::_ifle : 124 case Bytecodes::_if_icmpeq : 125 case Bytecodes::_if_icmpne : 126 case Bytecodes::_if_icmplt : 127 case Bytecodes::_if_icmpge : 128 case Bytecodes::_if_icmpgt : 129 case Bytecodes::_if_icmple : 130 case Bytecodes::_if_acmpeq : 131 case Bytecodes::_if_acmpne : 132 case Bytecodes::_ifnull : 133 case Bytecodes::_ifnonnull : 134 { 135 cur_block->set_control_bci(bci); 136 ciBlock *fall_through = make_block_at(s.next_bci()); 137 int dest_bci = s.get_dest(); 138 ciBlock *dest = make_block_at(dest_bci); 139 break; 140 } 141 142 case Bytecodes::_goto : 143 { 144 cur_block->set_control_bci(bci); 145 if (s.next_bci() < limit_bci) { 146 (void) make_block_at(s.next_bci()); 147 } 148 int dest_bci = s.get_dest(); 149 ciBlock *dest = make_block_at(dest_bci); 150 break; 151 } 152 153 case Bytecodes::_jsr : 154 { 155 cur_block->set_control_bci(bci); 156 ciBlock *ret = make_block_at(s.next_bci()); 157 int dest_bci = s.get_dest(); 158 ciBlock *dest = make_block_at(dest_bci); 159 break; 160 } 161 162 case Bytecodes::_tableswitch : 163 { 164 cur_block->set_control_bci(bci); 165 Bytecode_tableswitch* switch_ = Bytecode_tableswitch_at(s.cur_bcp()); 166 int len = switch_->length(); 167 ciBlock *dest; 168 int dest_bci; 169 for (int i = 0; i < len; i++) { 170 dest_bci = s.cur_bci() + switch_->dest_offset_at(i); 171 dest = make_block_at(dest_bci); 172 } 173 dest_bci = s.cur_bci() + switch_->default_offset(); 174 make_block_at(dest_bci); 175 if (s.next_bci() < limit_bci) { 176 dest = make_block_at(s.next_bci()); 177 } 178 } 179 break; 180 181 case Bytecodes::_lookupswitch: 182 { 183 cur_block->set_control_bci(bci); 184 Bytecode_lookupswitch* switch_ = Bytecode_lookupswitch_at(s.cur_bcp()); 185 int len = switch_->number_of_pairs(); 186 ciBlock *dest; 187 int dest_bci; 188 for (int i = 0; i < len; i++) { 189 dest_bci = s.cur_bci() + switch_->pair_at(i)->offset(); 190 dest = make_block_at(dest_bci); 191 } 192 dest_bci = s.cur_bci() + switch_->default_offset(); 193 dest = make_block_at(dest_bci); 194 if (s.next_bci() < limit_bci) { 195 dest = make_block_at(s.next_bci()); 196 } 197 } 198 break; 199 200 case Bytecodes::_goto_w : 201 { 202 cur_block->set_control_bci(bci); 203 if (s.next_bci() < limit_bci) { 204 (void) make_block_at(s.next_bci()); 205 } 206 int dest_bci = s.get_far_dest(); 207 ciBlock *dest = make_block_at(dest_bci); 208 break; 209 } 210 211 case Bytecodes::_jsr_w : 212 { 213 cur_block->set_control_bci(bci); 214 ciBlock *ret = make_block_at(s.next_bci()); 215 int dest_bci = s.get_far_dest(); 216 ciBlock *dest = make_block_at(dest_bci); 217 break; 218 } 219 220 case Bytecodes::_athrow : 221 cur_block->set_may_throw(); 222 // fall-through 223 case Bytecodes::_ret : 224 case Bytecodes::_ireturn : 225 case Bytecodes::_lreturn : 226 case Bytecodes::_freturn : 227 case Bytecodes::_dreturn : 228 case Bytecodes::_areturn : 229 case Bytecodes::_return : 230 cur_block->set_control_bci(bci); 231 if (s.next_bci() < limit_bci) { 232 (void) make_block_at(s.next_bci()); 233 } 234 break; 235 } 236 } 237 // End the last block 238 cur_block->set_limit_bci(limit_bci); 239 } 240 241 ciMethodBlocks::ciMethodBlocks(Arena *arena, ciMethod *meth): _method(meth), 242 _arena(arena), _num_blocks(0), _code_size(meth->code_size()) { 243 int block_estimate = _code_size / 8; 244 245 _blocks = new(_arena) GrowableArray<ciBlock *>(block_estimate); 246 int b2bsize = _code_size * sizeof(ciBlock **); 247 _bci_to_block = (ciBlock **) arena->Amalloc(b2bsize); 248 Copy::zero_to_words((HeapWord*) _bci_to_block, b2bsize / sizeof(HeapWord)); 249 250 // create initial block covering the entire method 251 ciBlock *b = new(arena) ciBlock(_method, _num_blocks++, this, 0); 252 _blocks->append(b); 253 _bci_to_block[0] = b; 254 255 // create blocks for exception handlers 256 if (meth->has_exception_handlers()) { 257 for(ciExceptionHandlerStream str(meth); !str.is_done(); str.next()) { 258 ciExceptionHandler* handler = str.handler(); 259 ciBlock *eb = make_block_at(handler->handler_bci()); 260 eb->set_handler(); 261 int ex_start = handler->start(); 262 int ex_end = handler->limit(); 263 eb->set_exception_range(ex_start, ex_end); 264 // ensure a block at the start of exception range and start of following code 265 (void) make_block_at(ex_start); 266 if (ex_end < _code_size) 267 (void) make_block_at(ex_end); 268 } 269 } 270 271 // scan the bytecodes and identify blocks 272 do_analysis(); 273 274 // mark blocks that have exception handlers 275 if (meth->has_exception_handlers()) { 276 for(ciExceptionHandlerStream str(meth); !str.is_done(); str.next()) { 277 ciExceptionHandler* handler = str.handler(); 278 int ex_start = handler->start(); 279 int ex_end = handler->limit(); 280 281 int bci = ex_start; 282 while (bci < ex_end) { 283 ciBlock *b = block_containing(bci); 284 b->set_has_handler(); 285 bci = b->limit_bci(); 286 } 287 } 288 } 289 } 290 291 void ciMethodBlocks::clear_processed() { 292 for (int i = 0; i < _blocks->length(); i++) 293 _blocks->at(i)->clear_processed(); 294 } 295 296 #ifndef PRODUCT 297 void ciMethodBlocks::dump() { 298 tty->print("---- blocks for method: "); 299 _method->print(); 300 tty->cr(); 301 for (int i = 0; i < _blocks->length(); i++) { 302 tty->print(" B%d: ", i); _blocks->at(i)->dump(); 303 } 304 } 305 #endif 306 307 308 ciBlock::ciBlock(ciMethod *method, int index, ciMethodBlocks *mb, int start_bci) : 309 #ifndef PRODUCT 310 _method(method), 311 #endif 312 _idx(index), _flags(0), _start_bci(start_bci), _limit_bci(-1), _control_bci(fall_through_bci), 313 _ex_start_bci(-1), _ex_limit_bci(-1) { 314 } 315 316 void ciBlock::set_exception_range(int start_bci, int limit_bci) { 317 assert(limit_bci >= start_bci, "valid range"); 318 assert(is_handler(), "must be handler"); 319 _ex_start_bci = start_bci; 320 _ex_limit_bci = limit_bci; 321 } 322 323 #ifndef PRODUCT 324 static const char *flagnames[] = { 325 "Processed", 326 "Handler", 327 "MayThrow", 328 "Jsr", 329 "Ret", 330 "RetTarget", 331 "HasHandler", 332 }; 333 334 void ciBlock::dump() { 335 tty->print(" [%d .. %d), {", _start_bci, _limit_bci); 336 for (int i = 0; i < 8; i++) { 337 if ((_flags & (1 << i)) != 0) { 338 tty->print(" %s", flagnames[i]); 339 } 340 } 341 tty->print(" ]"); 342 if (is_handler()) 343 tty->print(" handles(%d..%d)", _ex_start_bci, _ex_limit_bci); 344 tty->cr(); 345 } 346 347 // ------------------------------------------------------------------ 348 // ciBlock::print_on 349 void ciBlock::print_on(outputStream* st) const { 350 st->print_cr("--------------------------------------------------------"); 351 st->print ("ciBlock [%d - %d) control : ", start_bci(), limit_bci()); 352 if (control_bci() == fall_through_bci) { 353 st->print_cr("%d:fall through", limit_bci()); 354 } else { 355 st->print_cr("%d:%s", control_bci(), 356 Bytecodes::name(method()->java_code_at_bci(control_bci()))); 357 } 358 359 if (Verbose || WizardMode) { 360 method()->print_codes_on(start_bci(), limit_bci(), st); 361 } 362 } 363 #endif