< prev index next >

src/share/vm/oops/generateOopMap.cpp

Print this page




 220   if (_target_bci > bci) _target_bci += delta;
 221 
 222   for (int k = 0; k < _jsrs->length(); k++) {
 223     int jsr = _jsrs->at(k);
 224     if (jsr > bci) _jsrs->at_put(k, jsr+delta);
 225   }
 226 }
 227 
 228 void RetTable::compute_ret_table(const methodHandle& method) {
 229   BytecodeStream i(method);
 230   Bytecodes::Code bytecode;
 231 
 232   while( (bytecode = i.next()) >= 0) {
 233     switch (bytecode) {
 234       case Bytecodes::_jsr:
 235         add_jsr(i.next_bci(), i.dest());
 236         break;
 237       case Bytecodes::_jsr_w:
 238         add_jsr(i.next_bci(), i.dest_w());
 239         break;


 240     }
 241   }
 242 }
 243 
 244 void RetTable::add_jsr(int return_bci, int target_bci) {
 245   RetTableEntry* entry = _first;
 246 
 247   // Scan table for entry
 248   for (;entry && entry->target_bci() != target_bci; entry = entry->next());
 249 
 250   if (!entry) {
 251     // Allocate new entry and put in list
 252     entry = new RetTableEntry(target_bci, _first);
 253     _first = entry;
 254   }
 255 
 256   // Now "entry" is set.  Make sure that the entry is initialized
 257   // and has room for the new jsr.
 258   entry->add_jsr(return_bci);
 259 }


 413   Bytecodes::Code bytecode;
 414 
 415   while( (bytecode = bcs.next()) >= 0) {
 416     int bci = bcs.bci();
 417 
 418     if (!fellThrough)
 419         bb_mark_fct(this, bci, NULL);
 420 
 421     fellThrough = jump_targets_do(&bcs, &GenerateOopMap::bb_mark_fct, NULL);
 422 
 423      /* We will also mark successors of jsr's as basic block headers. */
 424     switch (bytecode) {
 425       case Bytecodes::_jsr:
 426         assert(!fellThrough, "should not happen");
 427         bb_mark_fct(this, bci + Bytecodes::length_for(bytecode), NULL);
 428         break;
 429       case Bytecodes::_jsr_w:
 430         assert(!fellThrough, "should not happen");
 431         bb_mark_fct(this, bci + Bytecodes::length_for(bytecode), NULL);
 432         break;


 433     }
 434 
 435     if (possible_gc_point(&bcs))
 436       _gc_points++;
 437   }
 438 }
 439 
 440 void GenerateOopMap::set_bbmark_bit(int bci) {
 441   _bb_hdr_bits.at_put(bci, true);
 442 }
 443 
 444 void GenerateOopMap::reachable_basicblock(GenerateOopMap *c, int bci, int *data) {
 445   assert(bci>= 0 && bci < c->method()->code_size(), "index out of bounds");
 446   BasicBlock* bb = c->get_basic_block_at(bci);
 447   if (bb->is_dead()) {
 448     bb->mark_as_alive();
 449     *data = 1; // Mark basicblock as changed
 450   }
 451 }
 452 


 472 
 473     for (int i = 0; i < _bb_count; i++) {
 474       BasicBlock *bb = &_basic_blocks[i];
 475       if (bb->is_alive()) {
 476         // Position bytecodestream at last bytecode in basicblock
 477         bcs.set_start(bb->_end_bci);
 478         bcs.next();
 479         Bytecodes::Code bytecode = bcs.code();
 480         int bci = bcs.bci();
 481         assert(bci == bb->_end_bci, "wrong bci");
 482 
 483         bool fell_through = jump_targets_do(&bcs, &GenerateOopMap::reachable_basicblock, &change);
 484 
 485         // We will also mark successors of jsr's as alive.
 486         switch (bytecode) {
 487           case Bytecodes::_jsr:
 488           case Bytecodes::_jsr_w:
 489             assert(!fell_through, "should not happen");
 490             reachable_basicblock(this, bci + Bytecodes::length_for(bytecode), &change);
 491             break;


 492         }
 493         if (fell_through) {
 494           // Mark successor as alive
 495           if (bb[1].is_dead()) {
 496             bb[1].mark_as_alive();
 497             change = 1;
 498           }
 499         }
 500       }
 501     }
 502   }
 503 }
 504 
 505 /* If the current instruction in "c" has no effect on control flow,
 506    returns "true".  Otherwise, calls "jmpFct" one or more times, with
 507    "c", an appropriate "pcDelta", and "data" as arguments, then
 508    returns "false".  There is one exception: if the current
 509    instruction is a "ret", returns "false" without calling "jmpFct".
 510    Arrangements for tracking the control flow of a "ret" must be made
 511    externally. */


1170     case Bytecodes::_return:
1171       // If the monitor stack height is not zero when we leave the method,
1172       // then we are either exiting with a non-empty stack or we have
1173       // found monitor trouble earlier in our analysis.  In either case,
1174       // assume an exception could be taken here.
1175       if (_monitor_top == 0) {
1176         return;
1177       }
1178       break;
1179 
1180     case Bytecodes::_monitorexit:
1181       // If the monitor stack height is bad_monitors, then we have detected a
1182       // monitor matching problem earlier in the analysis.  If the
1183       // monitor stack height is 0, we are about to pop a monitor
1184       // off of an empty stack.  In either case, the bytecode
1185       // could throw an exception.
1186       if (_monitor_top != bad_monitors && _monitor_top != 0) {
1187         return;
1188       }
1189       break;



1190   }
1191 
1192   if (_has_exceptions) {
1193     int bci = itr->bci();
1194     ExceptionTable exct(method());
1195     for(int i = 0; i< exct.length(); i++) {
1196       int start_pc   = exct.start_pc(i);
1197       int end_pc     = exct.end_pc(i);
1198       int handler_pc = exct.handler_pc(i);
1199       int catch_type = exct.catch_type_index(i);
1200 
1201       if (start_pc <= bci && bci < end_pc) {
1202         BasicBlock *excBB = get_basic_block_at(handler_pc);
1203         guarantee(excBB != NULL, "no basic block for exception");
1204         CellTypeState *excStk = excBB->stack();
1205         CellTypeState *cOpStck = stack();
1206         CellTypeState cOpStck_0 = cOpStck[0];
1207         int cOpStackTop = _stack_top;
1208 
1209         // Exception stacks are always the same.


1255 
1256 void GenerateOopMap::report_monitor_mismatch(const char *msg) {
1257   ResourceMark rm;
1258   outputStream* out = Log(monitormismatch)::info_stream();
1259   out->print("Monitor mismatch in method ");
1260   method()->print_short_name(out);
1261   out->print_cr(": %s", msg);
1262 }
1263 
1264 void GenerateOopMap::print_states(outputStream *os,
1265                                   CellTypeState* vec, int num) {
1266   for (int i = 0; i < num; i++) {
1267     vec[i].print(tty);
1268   }
1269 }
1270 
1271 // Print the state values at the current bytecode.
1272 void GenerateOopMap::print_current_state(outputStream   *os,
1273                                          BytecodeStream *currentBC,
1274                                          bool            detailed) {
1275 
1276   if (detailed) {
1277     os->print("     %4d vars     = ", currentBC->bci());
1278     print_states(os, vars(), _max_locals);
1279     os->print("    %s", Bytecodes::name(currentBC->code()));










1280     switch(currentBC->code()) {
1281       case Bytecodes::_invokevirtual:
1282       case Bytecodes::_invokespecial:
1283       case Bytecodes::_invokestatic:
1284       case Bytecodes::_invokedynamic:
1285       case Bytecodes::_invokeinterface:
1286         int idx = currentBC->has_index_u4() ? currentBC->get_index_u4() : currentBC->get_index_u2_cpcache();
1287         ConstantPool* cp      = method()->constants();
1288         int nameAndTypeIdx    = cp->name_and_type_ref_index_at(idx);
1289         int signatureIdx      = cp->signature_ref_index_at(nameAndTypeIdx);
1290         Symbol* signature     = cp->symbol_at(signatureIdx);
1291         os->print("%s", signature->as_C_string());
1292     }





1293     os->cr();
1294     os->print("          stack    = ");
1295     print_states(os, stack(), _stack_top);
1296     os->cr();
1297     if (_monitor_top != bad_monitors) {
1298       os->print("          monitors = ");
1299       print_states(os, monitors(), _monitor_top);
1300     } else {
1301       os->print("          [bad monitor stack]");
1302     }
1303     os->cr();
1304   } else {
1305     os->print("    %4d  vars = '%s' ", currentBC->bci(),  state_vec_to_string(vars(), _max_locals));
1306     os->print("     stack = '%s' ", state_vec_to_string(stack(), _stack_top));
1307     if (_monitor_top != bad_monitors) {
1308       os->print("  monitors = '%s'  \t%s", state_vec_to_string(monitors(), _monitor_top), Bytecodes::name(currentBC->code()));
1309     } else {
1310       os->print("  [bad monitor stack]");
1311     }
1312     switch(currentBC->code()) {
1313       case Bytecodes::_invokevirtual:
1314       case Bytecodes::_invokespecial:
1315       case Bytecodes::_invokestatic:
1316       case Bytecodes::_invokedynamic:
1317       case Bytecodes::_invokeinterface:
1318         int idx = currentBC->has_index_u4() ? currentBC->get_index_u4() : currentBC->get_index_u2_cpcache();
1319         ConstantPool* cp      = method()->constants();
1320         int nameAndTypeIdx    = cp->name_and_type_ref_index_at(idx);
1321         int signatureIdx      = cp->signature_ref_index_at(nameAndTypeIdx);
1322         Symbol* signature     = cp->symbol_at(signatureIdx);
1323         os->print("%s", signature->as_C_string());
1324     }

1325     os->cr();
1326   }
1327 }
1328 
1329 // Sets the current state to be the state after executing the
1330 // current instruction, starting in the current state.
1331 void GenerateOopMap::interp1(BytecodeStream *itr) {
1332   if (TraceNewOopMapGeneration) {
1333     print_current_state(tty, itr, TraceNewOopMapGenerationDetailed);
1334   }
1335 
1336   // Should we report the results? Result is reported *before* the instruction at the current bci is executed.
1337   // However, not for calls. For calls we do not want to include the arguments, so we postpone the reporting until
1338   // they have been popped (in method ppl).
1339   if (_report_result == true) {
1340     switch(itr->code()) {
1341       case Bytecodes::_invokevirtual:
1342       case Bytecodes::_invokespecial:
1343       case Bytecodes::_invokestatic:
1344       case Bytecodes::_invokedynamic:
1345       case Bytecodes::_invokeinterface:
1346         _itr_send = itr;


2459   }
2460 
2461   // Relocator returns a new method oop.
2462   _did_relocation = true;
2463   _method = m;
2464 }
2465 
2466 
2467 bool GenerateOopMap::is_astore(BytecodeStream *itr, int *index) {
2468   Bytecodes::Code bc = itr->code();
2469   switch(bc) {
2470     case Bytecodes::_astore_0:
2471     case Bytecodes::_astore_1:
2472     case Bytecodes::_astore_2:
2473     case Bytecodes::_astore_3:
2474       *index = bc - Bytecodes::_astore_0;
2475       return true;
2476     case Bytecodes::_astore:
2477       *index = itr->get_index();
2478       return true;
2479   }
2480   return false;

2481 }
2482 
2483 bool GenerateOopMap::is_aload(BytecodeStream *itr, int *index) {
2484   Bytecodes::Code bc = itr->code();
2485   switch(bc) {
2486     case Bytecodes::_aload_0:
2487     case Bytecodes::_aload_1:
2488     case Bytecodes::_aload_2:
2489     case Bytecodes::_aload_3:
2490       *index = bc - Bytecodes::_aload_0;
2491       return true;
2492 
2493     case Bytecodes::_aload:
2494       *index = itr->get_index();
2495       return true;
2496   }

2497   return false;

2498 }
2499 
2500 
2501 // Return true iff the top of the operand stack holds a return address at
2502 // the current instruction
2503 bool GenerateOopMap::stack_top_holds_ret_addr(int bci) {
2504   for(int i = 0; i < _ret_adr_tos->length(); i++) {
2505     if (_ret_adr_tos->at(i) == bci)
2506       return true;
2507   }
2508 
2509   return false;
2510 }
2511 
2512 void GenerateOopMap::compute_ret_adr_at_TOS() {
2513   assert(_ret_adr_tos != NULL, "must be initialized");
2514   _ret_adr_tos->clear();
2515 
2516   for (int i = 0; i < bb_count(); i++) {
2517     BasicBlock* bb = &_basic_blocks[i];




 220   if (_target_bci > bci) _target_bci += delta;
 221 
 222   for (int k = 0; k < _jsrs->length(); k++) {
 223     int jsr = _jsrs->at(k);
 224     if (jsr > bci) _jsrs->at_put(k, jsr+delta);
 225   }
 226 }
 227 
 228 void RetTable::compute_ret_table(const methodHandle& method) {
 229   BytecodeStream i(method);
 230   Bytecodes::Code bytecode;
 231 
 232   while( (bytecode = i.next()) >= 0) {
 233     switch (bytecode) {
 234       case Bytecodes::_jsr:
 235         add_jsr(i.next_bci(), i.dest());
 236         break;
 237       case Bytecodes::_jsr_w:
 238         add_jsr(i.next_bci(), i.dest_w());
 239         break;
 240       default:
 241         break;
 242     }
 243   }
 244 }
 245 
 246 void RetTable::add_jsr(int return_bci, int target_bci) {
 247   RetTableEntry* entry = _first;
 248 
 249   // Scan table for entry
 250   for (;entry && entry->target_bci() != target_bci; entry = entry->next());
 251 
 252   if (!entry) {
 253     // Allocate new entry and put in list
 254     entry = new RetTableEntry(target_bci, _first);
 255     _first = entry;
 256   }
 257 
 258   // Now "entry" is set.  Make sure that the entry is initialized
 259   // and has room for the new jsr.
 260   entry->add_jsr(return_bci);
 261 }


 415   Bytecodes::Code bytecode;
 416 
 417   while( (bytecode = bcs.next()) >= 0) {
 418     int bci = bcs.bci();
 419 
 420     if (!fellThrough)
 421         bb_mark_fct(this, bci, NULL);
 422 
 423     fellThrough = jump_targets_do(&bcs, &GenerateOopMap::bb_mark_fct, NULL);
 424 
 425      /* We will also mark successors of jsr's as basic block headers. */
 426     switch (bytecode) {
 427       case Bytecodes::_jsr:
 428         assert(!fellThrough, "should not happen");
 429         bb_mark_fct(this, bci + Bytecodes::length_for(bytecode), NULL);
 430         break;
 431       case Bytecodes::_jsr_w:
 432         assert(!fellThrough, "should not happen");
 433         bb_mark_fct(this, bci + Bytecodes::length_for(bytecode), NULL);
 434         break;
 435       default:
 436         break;
 437     }
 438 
 439     if (possible_gc_point(&bcs))
 440       _gc_points++;
 441   }
 442 }
 443 
 444 void GenerateOopMap::set_bbmark_bit(int bci) {
 445   _bb_hdr_bits.at_put(bci, true);
 446 }
 447 
 448 void GenerateOopMap::reachable_basicblock(GenerateOopMap *c, int bci, int *data) {
 449   assert(bci>= 0 && bci < c->method()->code_size(), "index out of bounds");
 450   BasicBlock* bb = c->get_basic_block_at(bci);
 451   if (bb->is_dead()) {
 452     bb->mark_as_alive();
 453     *data = 1; // Mark basicblock as changed
 454   }
 455 }
 456 


 476 
 477     for (int i = 0; i < _bb_count; i++) {
 478       BasicBlock *bb = &_basic_blocks[i];
 479       if (bb->is_alive()) {
 480         // Position bytecodestream at last bytecode in basicblock
 481         bcs.set_start(bb->_end_bci);
 482         bcs.next();
 483         Bytecodes::Code bytecode = bcs.code();
 484         int bci = bcs.bci();
 485         assert(bci == bb->_end_bci, "wrong bci");
 486 
 487         bool fell_through = jump_targets_do(&bcs, &GenerateOopMap::reachable_basicblock, &change);
 488 
 489         // We will also mark successors of jsr's as alive.
 490         switch (bytecode) {
 491           case Bytecodes::_jsr:
 492           case Bytecodes::_jsr_w:
 493             assert(!fell_through, "should not happen");
 494             reachable_basicblock(this, bci + Bytecodes::length_for(bytecode), &change);
 495             break;
 496           default:
 497             break;
 498         }
 499         if (fell_through) {
 500           // Mark successor as alive
 501           if (bb[1].is_dead()) {
 502             bb[1].mark_as_alive();
 503             change = 1;
 504           }
 505         }
 506       }
 507     }
 508   }
 509 }
 510 
 511 /* If the current instruction in "c" has no effect on control flow,
 512    returns "true".  Otherwise, calls "jmpFct" one or more times, with
 513    "c", an appropriate "pcDelta", and "data" as arguments, then
 514    returns "false".  There is one exception: if the current
 515    instruction is a "ret", returns "false" without calling "jmpFct".
 516    Arrangements for tracking the control flow of a "ret" must be made
 517    externally. */


1176     case Bytecodes::_return:
1177       // If the monitor stack height is not zero when we leave the method,
1178       // then we are either exiting with a non-empty stack or we have
1179       // found monitor trouble earlier in our analysis.  In either case,
1180       // assume an exception could be taken here.
1181       if (_monitor_top == 0) {
1182         return;
1183       }
1184       break;
1185 
1186     case Bytecodes::_monitorexit:
1187       // If the monitor stack height is bad_monitors, then we have detected a
1188       // monitor matching problem earlier in the analysis.  If the
1189       // monitor stack height is 0, we are about to pop a monitor
1190       // off of an empty stack.  In either case, the bytecode
1191       // could throw an exception.
1192       if (_monitor_top != bad_monitors && _monitor_top != 0) {
1193         return;
1194       }
1195       break;
1196 
1197     default:
1198       break;
1199   }
1200 
1201   if (_has_exceptions) {
1202     int bci = itr->bci();
1203     ExceptionTable exct(method());
1204     for(int i = 0; i< exct.length(); i++) {
1205       int start_pc   = exct.start_pc(i);
1206       int end_pc     = exct.end_pc(i);
1207       int handler_pc = exct.handler_pc(i);
1208       int catch_type = exct.catch_type_index(i);
1209 
1210       if (start_pc <= bci && bci < end_pc) {
1211         BasicBlock *excBB = get_basic_block_at(handler_pc);
1212         guarantee(excBB != NULL, "no basic block for exception");
1213         CellTypeState *excStk = excBB->stack();
1214         CellTypeState *cOpStck = stack();
1215         CellTypeState cOpStck_0 = cOpStck[0];
1216         int cOpStackTop = _stack_top;
1217 
1218         // Exception stacks are always the same.


1264 
1265 void GenerateOopMap::report_monitor_mismatch(const char *msg) {
1266   ResourceMark rm;
1267   outputStream* out = Log(monitormismatch)::info_stream();
1268   out->print("Monitor mismatch in method ");
1269   method()->print_short_name(out);
1270   out->print_cr(": %s", msg);
1271 }
1272 
1273 void GenerateOopMap::print_states(outputStream *os,
1274                                   CellTypeState* vec, int num) {
1275   for (int i = 0; i < num; i++) {
1276     vec[i].print(tty);
1277   }
1278 }
1279 
1280 // Print the state values at the current bytecode.
1281 void GenerateOopMap::print_current_state(outputStream   *os,
1282                                          BytecodeStream *currentBC,
1283                                          bool            detailed) {

1284   if (detailed) {
1285     os->print("     %4d vars     = ", currentBC->bci());
1286     print_states(os, vars(), _max_locals);
1287     os->print("    %s", Bytecodes::name(currentBC->code()));
1288   } else {
1289     os->print("    %4d  vars = '%s' ", currentBC->bci(),  state_vec_to_string(vars(), _max_locals));
1290     os->print("     stack = '%s' ", state_vec_to_string(stack(), _stack_top));
1291     if (_monitor_top != bad_monitors) {
1292       os->print("  monitors = '%s'  \t%s", state_vec_to_string(monitors(), _monitor_top), Bytecodes::name(currentBC->code()));
1293     } else {
1294       os->print("  [bad monitor stack]");
1295     }
1296   }
1297 
1298   switch(currentBC->code()) {
1299     case Bytecodes::_invokevirtual:
1300     case Bytecodes::_invokespecial:
1301     case Bytecodes::_invokestatic:
1302     case Bytecodes::_invokedynamic:
1303     case Bytecodes::_invokeinterface: {
1304       int idx = currentBC->has_index_u4() ? currentBC->get_index_u4() : currentBC->get_index_u2_cpcache();
1305       ConstantPool* cp      = method()->constants();
1306       int nameAndTypeIdx    = cp->name_and_type_ref_index_at(idx);
1307       int signatureIdx      = cp->signature_ref_index_at(nameAndTypeIdx);
1308       Symbol* signature     = cp->symbol_at(signatureIdx);
1309       os->print("%s", signature->as_C_string());
1310     }
1311     default:
1312       break;
1313   }
1314 
1315   if (detailed) {
1316     os->cr();
1317     os->print("          stack    = ");
1318     print_states(os, stack(), _stack_top);
1319     os->cr();
1320     if (_monitor_top != bad_monitors) {
1321       os->print("          monitors = ");
1322       print_states(os, monitors(), _monitor_top);
1323     } else {
1324       os->print("          [bad monitor stack]");
1325     }





















1326   }
1327   
1328   os->cr();

1329 }
1330 
1331 // Sets the current state to be the state after executing the
1332 // current instruction, starting in the current state.
1333 void GenerateOopMap::interp1(BytecodeStream *itr) {
1334   if (TraceNewOopMapGeneration) {
1335     print_current_state(tty, itr, TraceNewOopMapGenerationDetailed);
1336   }
1337 
1338   // Should we report the results? Result is reported *before* the instruction at the current bci is executed.
1339   // However, not for calls. For calls we do not want to include the arguments, so we postpone the reporting until
1340   // they have been popped (in method ppl).
1341   if (_report_result == true) {
1342     switch(itr->code()) {
1343       case Bytecodes::_invokevirtual:
1344       case Bytecodes::_invokespecial:
1345       case Bytecodes::_invokestatic:
1346       case Bytecodes::_invokedynamic:
1347       case Bytecodes::_invokeinterface:
1348         _itr_send = itr;


2461   }
2462 
2463   // Relocator returns a new method oop.
2464   _did_relocation = true;
2465   _method = m;
2466 }
2467 
2468 
2469 bool GenerateOopMap::is_astore(BytecodeStream *itr, int *index) {
2470   Bytecodes::Code bc = itr->code();
2471   switch(bc) {
2472     case Bytecodes::_astore_0:
2473     case Bytecodes::_astore_1:
2474     case Bytecodes::_astore_2:
2475     case Bytecodes::_astore_3:
2476       *index = bc - Bytecodes::_astore_0;
2477       return true;
2478     case Bytecodes::_astore:
2479       *index = itr->get_index();
2480       return true;
2481     default:
2482       return false;
2483   }
2484 }
2485 
2486 bool GenerateOopMap::is_aload(BytecodeStream *itr, int *index) {
2487   Bytecodes::Code bc = itr->code();
2488   switch(bc) {
2489     case Bytecodes::_aload_0:
2490     case Bytecodes::_aload_1:
2491     case Bytecodes::_aload_2:
2492     case Bytecodes::_aload_3:
2493       *index = bc - Bytecodes::_aload_0;
2494       return true;
2495 
2496     case Bytecodes::_aload:
2497       *index = itr->get_index();
2498       return true;
2499 
2500     default:
2501       return false;
2502   }
2503 }
2504 
2505 
2506 // Return true iff the top of the operand stack holds a return address at
2507 // the current instruction
2508 bool GenerateOopMap::stack_top_holds_ret_addr(int bci) {
2509   for(int i = 0; i < _ret_adr_tos->length(); i++) {
2510     if (_ret_adr_tos->at(i) == bci)
2511       return true;
2512   }
2513 
2514   return false;
2515 }
2516 
2517 void GenerateOopMap::compute_ret_adr_at_TOS() {
2518   assert(_ret_adr_tos != NULL, "must be initialized");
2519   _ret_adr_tos->clear();
2520 
2521   for (int i = 0; i < bb_count(); i++) {
2522     BasicBlock* bb = &_basic_blocks[i];


< prev index next >