< prev index next >

src/share/vm/oops/generateOopMap.cpp

Print this page
rev 4134 : 7178145: Change constMethodOop::_exception_table to optionally inlined u2 table.
Summary: Change constMethodOop::_exception_table to optionally inlined u2 table.
Reviewed-by: bdelsart, coleenp, kamg


 383 
 384 void GenerateOopMap::bb_mark_fct(GenerateOopMap *c, int bci, int *data) {
 385   assert(bci>= 0 && bci < c->method()->code_size(), "index out of bounds");
 386   if (c->is_bb_header(bci))
 387      return;
 388 
 389   if (TraceNewOopMapGeneration) {
 390      tty->print_cr("Basicblock#%d begins at: %d", c->_bb_count, bci);
 391   }
 392   c->set_bbmark_bit(bci);
 393   c->_bb_count++;
 394 }
 395 
 396 
 397 void GenerateOopMap::mark_bbheaders_and_count_gc_points() {
 398   initialize_bb();
 399 
 400   bool fellThrough = false;  // False to get first BB marked.
 401 
 402   // First mark all exception handlers as start of a basic-block
 403   typeArrayOop excps = method()->exception_table();
 404   for(int i = 0; i < excps->length(); i += 4) {
 405     int handler_pc_idx = i+2;
 406     bb_mark_fct(this, excps->int_at(handler_pc_idx), NULL);
 407   }
 408 
 409   // Then iterate through the code
 410   BytecodeStream bcs(_method);
 411   Bytecodes::Code bytecode;
 412 
 413   while( (bytecode = bcs.next()) >= 0) {
 414     int bci = bcs.bci();
 415 
 416     if (!fellThrough)
 417         bb_mark_fct(this, bci, NULL);
 418 
 419     fellThrough = jump_targets_do(&bcs, &GenerateOopMap::bb_mark_fct, NULL);
 420 
 421      /* We will also mark successors of jsr's as basic block headers. */
 422     switch (bytecode) {
 423       case Bytecodes::_jsr:
 424         assert(!fellThrough, "should not happen");
 425         bb_mark_fct(this, bci + Bytecodes::length_for(bytecode), NULL);
 426         break;


 433     if (possible_gc_point(&bcs))
 434       _gc_points++;
 435   }
 436 }
 437 
 438 void GenerateOopMap::reachable_basicblock(GenerateOopMap *c, int bci, int *data) {
 439   assert(bci>= 0 && bci < c->method()->code_size(), "index out of bounds");
 440   BasicBlock* bb = c->get_basic_block_at(bci);
 441   if (bb->is_dead()) {
 442     bb->mark_as_alive();
 443     *data = 1; // Mark basicblock as changed
 444   }
 445 }
 446 
 447 
 448 void GenerateOopMap::mark_reachable_code() {
 449   int change = 1; // int to get function pointers to work
 450 
 451   // Mark entry basic block as alive and all exception handlers
 452   _basic_blocks[0].mark_as_alive();
 453   typeArrayOop excps = method()->exception_table();
 454   for(int i = 0; i < excps->length(); i += 4) {
 455     int handler_pc_idx = i+2;
 456     BasicBlock *bb = get_basic_block_at(excps->int_at(handler_pc_idx));
 457     // If block is not already alive (due to multiple exception handlers to same bb), then
 458     // make it alive
 459     if (bb->is_dead()) bb->mark_as_alive();
 460   }
 461 
 462   BytecodeStream bcs(_method);
 463 
 464   // Iterate through all basic blocks until we reach a fixpoint
 465   while (change) {
 466     change = 0;
 467 
 468     for (int i = 0; i < _bb_count; i++) {
 469       BasicBlock *bb = &_basic_blocks[i];
 470       if (bb->is_alive()) {
 471         // Position bytecodestream at last bytecode in basicblock
 472         bcs.set_start(bb->_end_bci);
 473         bcs.next();
 474         Bytecodes::Code bytecode = bcs.code();
 475         int bci = bcs.bci();
 476         assert(bci == bb->_end_bci, "wrong bci");


1173       // assume an exception could be taken here.
1174       if (_monitor_top == 0) {
1175         return;
1176       }
1177       break;
1178 
1179     case Bytecodes::_monitorexit:
1180       // If the monitor stack height is bad_monitors, then we have detected a
1181       // monitor matching problem earlier in the analysis.  If the
1182       // monitor stack height is 0, we are about to pop a monitor
1183       // off of an empty stack.  In either case, the bytecode
1184       // could throw an exception.
1185       if (_monitor_top != bad_monitors && _monitor_top != 0) {
1186         return;
1187       }
1188       break;
1189   }
1190 
1191   if (_has_exceptions) {
1192     int bci = itr->bci();
1193     typeArrayOop exct  = method()->exception_table();
1194     for(int i = 0; i< exct->length(); i+=4) {
1195       int start_pc   = exct->int_at(i);
1196       int end_pc     = exct->int_at(i+1);
1197       int handler_pc = exct->int_at(i+2);
1198       int catch_type = exct->int_at(i+3);
1199 
1200       if (start_pc <= bci && bci < end_pc) {
1201         BasicBlock *excBB = get_basic_block_at(handler_pc);
1202         CellTypeState *excStk = excBB->stack();
1203         CellTypeState *cOpStck = stack();
1204         CellTypeState cOpStck_0 = cOpStck[0];
1205         int cOpStackTop = _stack_top;
1206 
1207         // Exception stacks are always the same.
1208         assert(method()->max_stack() > 0, "sanity check");
1209 
1210         // We remembered the size and first element of "cOpStck"
1211         // above; now we temporarily set them to the appropriate
1212         // values for an exception handler. */
1213         cOpStck[0] = CellTypeState::make_slot_ref(_max_locals);
1214         _stack_top = 1;
1215 
1216         merge_state_into_bb(excBB);
1217 
1218         // Now undo the temporary change.


2047 }
2048 
2049 void GenerateOopMap::compute_map(TRAPS) {
2050 #ifndef PRODUCT
2051   if (TimeOopMap2) {
2052     method()->print_short_name(tty);
2053     tty->print("  ");
2054   }
2055   if (TimeOopMap) {
2056     _total_byte_count += method()->code_size();
2057   }
2058 #endif
2059   TraceTime t_single("oopmap time", TimeOopMap2);
2060   TraceTime t_all(NULL, &_total_oopmap_time, TimeOopMap);
2061 
2062   // Initialize values
2063   _got_error      = false;
2064   _conflict       = false;
2065   _max_locals     = method()->max_locals();
2066   _max_stack      = method()->max_stack();
2067   _has_exceptions = (method()->exception_table()->length() > 0);
2068   _nof_refval_conflicts = 0;
2069   _init_vars      = new GrowableArray<intptr_t>(5);  // There are seldom more than 5 init_vars
2070   _report_result  = false;
2071   _report_result_for_send = false;
2072   _new_var_map    = NULL;
2073   _ret_adr_tos    = new GrowableArray<intptr_t>(5);  // 5 seems like a good number;
2074   _did_rewriting  = false;
2075   _did_relocation = false;
2076 
2077   if (TraceNewOopMapGeneration) {
2078     tty->print("Method name: %s\n", method()->name()->as_C_string());
2079     if (Verbose) {
2080       _method->print_codes();
2081       tty->print_cr("Exception table:");
2082       typeArrayOop excps = method()->exception_table();
2083       for(int i = 0; i < excps->length(); i += 4) {
2084         tty->print_cr("[%d - %d] -> %d", excps->int_at(i + 0), excps->int_at(i + 1), excps->int_at(i + 2));

2085       }
2086     }
2087   }
2088 
2089   // if no code - do nothing
2090   // compiler needs info
2091   if (method()->code_size() == 0 || _max_locals + method()->max_stack() == 0) {
2092     fill_stackmap_prolog(0);
2093     fill_stackmap_epilog();
2094     return;
2095   }
2096   // Step 1: Compute all jump targets and their return value
2097   if (!_got_error)
2098     _rt.compute_ret_table(_method);
2099 
2100   // Step 2: Find all basic blocks and count GC points
2101   if (!_got_error)
2102     mark_bbheaders_and_count_gc_points();
2103 
2104   // Step 3: Calculate stack maps




 383 
 384 void GenerateOopMap::bb_mark_fct(GenerateOopMap *c, int bci, int *data) {
 385   assert(bci>= 0 && bci < c->method()->code_size(), "index out of bounds");
 386   if (c->is_bb_header(bci))
 387      return;
 388 
 389   if (TraceNewOopMapGeneration) {
 390      tty->print_cr("Basicblock#%d begins at: %d", c->_bb_count, bci);
 391   }
 392   c->set_bbmark_bit(bci);
 393   c->_bb_count++;
 394 }
 395 
 396 
 397 void GenerateOopMap::mark_bbheaders_and_count_gc_points() {
 398   initialize_bb();
 399 
 400   bool fellThrough = false;  // False to get first BB marked.
 401 
 402   // First mark all exception handlers as start of a basic-block
 403   ExceptionTable excps(method());
 404   for(int i = 0; i < excps.length(); i ++) {
 405     bb_mark_fct(this, excps.handler_pc(i), NULL);

 406   }
 407 
 408   // Then iterate through the code
 409   BytecodeStream bcs(_method);
 410   Bytecodes::Code bytecode;
 411 
 412   while( (bytecode = bcs.next()) >= 0) {
 413     int bci = bcs.bci();
 414 
 415     if (!fellThrough)
 416         bb_mark_fct(this, bci, NULL);
 417 
 418     fellThrough = jump_targets_do(&bcs, &GenerateOopMap::bb_mark_fct, NULL);
 419 
 420      /* We will also mark successors of jsr's as basic block headers. */
 421     switch (bytecode) {
 422       case Bytecodes::_jsr:
 423         assert(!fellThrough, "should not happen");
 424         bb_mark_fct(this, bci + Bytecodes::length_for(bytecode), NULL);
 425         break;


 432     if (possible_gc_point(&bcs))
 433       _gc_points++;
 434   }
 435 }
 436 
 437 void GenerateOopMap::reachable_basicblock(GenerateOopMap *c, int bci, int *data) {
 438   assert(bci>= 0 && bci < c->method()->code_size(), "index out of bounds");
 439   BasicBlock* bb = c->get_basic_block_at(bci);
 440   if (bb->is_dead()) {
 441     bb->mark_as_alive();
 442     *data = 1; // Mark basicblock as changed
 443   }
 444 }
 445 
 446 
 447 void GenerateOopMap::mark_reachable_code() {
 448   int change = 1; // int to get function pointers to work
 449 
 450   // Mark entry basic block as alive and all exception handlers
 451   _basic_blocks[0].mark_as_alive();
 452   ExceptionTable excps(method());
 453   for(int i = 0; i < excps.length(); i++) {
 454     BasicBlock *bb = get_basic_block_at(excps.handler_pc(i));

 455     // If block is not already alive (due to multiple exception handlers to same bb), then
 456     // make it alive
 457     if (bb->is_dead()) bb->mark_as_alive();
 458   }
 459 
 460   BytecodeStream bcs(_method);
 461 
 462   // Iterate through all basic blocks until we reach a fixpoint
 463   while (change) {
 464     change = 0;
 465 
 466     for (int i = 0; i < _bb_count; i++) {
 467       BasicBlock *bb = &_basic_blocks[i];
 468       if (bb->is_alive()) {
 469         // Position bytecodestream at last bytecode in basicblock
 470         bcs.set_start(bb->_end_bci);
 471         bcs.next();
 472         Bytecodes::Code bytecode = bcs.code();
 473         int bci = bcs.bci();
 474         assert(bci == bb->_end_bci, "wrong bci");


1171       // assume an exception could be taken here.
1172       if (_monitor_top == 0) {
1173         return;
1174       }
1175       break;
1176 
1177     case Bytecodes::_monitorexit:
1178       // If the monitor stack height is bad_monitors, then we have detected a
1179       // monitor matching problem earlier in the analysis.  If the
1180       // monitor stack height is 0, we are about to pop a monitor
1181       // off of an empty stack.  In either case, the bytecode
1182       // could throw an exception.
1183       if (_monitor_top != bad_monitors && _monitor_top != 0) {
1184         return;
1185       }
1186       break;
1187   }
1188 
1189   if (_has_exceptions) {
1190     int bci = itr->bci();
1191     ExceptionTable exct(method());
1192     for(int i = 0; i< exct.length(); i++) {
1193       int start_pc   = exct.start_pc(i);
1194       int end_pc     = exct.end_pc(i);
1195       int handler_pc = exct.handler_pc(i);
1196       int catch_type = exct.catch_type_index(i);
1197 
1198       if (start_pc <= bci && bci < end_pc) {
1199         BasicBlock *excBB = get_basic_block_at(handler_pc);
1200         CellTypeState *excStk = excBB->stack();
1201         CellTypeState *cOpStck = stack();
1202         CellTypeState cOpStck_0 = cOpStck[0];
1203         int cOpStackTop = _stack_top;
1204 
1205         // Exception stacks are always the same.
1206         assert(method()->max_stack() > 0, "sanity check");
1207 
1208         // We remembered the size and first element of "cOpStck"
1209         // above; now we temporarily set them to the appropriate
1210         // values for an exception handler. */
1211         cOpStck[0] = CellTypeState::make_slot_ref(_max_locals);
1212         _stack_top = 1;
1213 
1214         merge_state_into_bb(excBB);
1215 
1216         // Now undo the temporary change.


2045 }
2046 
2047 void GenerateOopMap::compute_map(TRAPS) {
2048 #ifndef PRODUCT
2049   if (TimeOopMap2) {
2050     method()->print_short_name(tty);
2051     tty->print("  ");
2052   }
2053   if (TimeOopMap) {
2054     _total_byte_count += method()->code_size();
2055   }
2056 #endif
2057   TraceTime t_single("oopmap time", TimeOopMap2);
2058   TraceTime t_all(NULL, &_total_oopmap_time, TimeOopMap);
2059 
2060   // Initialize values
2061   _got_error      = false;
2062   _conflict       = false;
2063   _max_locals     = method()->max_locals();
2064   _max_stack      = method()->max_stack();
2065   _has_exceptions = (method()->has_exception_handler());
2066   _nof_refval_conflicts = 0;
2067   _init_vars      = new GrowableArray<intptr_t>(5);  // There are seldom more than 5 init_vars
2068   _report_result  = false;
2069   _report_result_for_send = false;
2070   _new_var_map    = NULL;
2071   _ret_adr_tos    = new GrowableArray<intptr_t>(5);  // 5 seems like a good number;
2072   _did_rewriting  = false;
2073   _did_relocation = false;
2074 
2075   if (TraceNewOopMapGeneration) {
2076     tty->print("Method name: %s\n", method()->name()->as_C_string());
2077     if (Verbose) {
2078       _method->print_codes();
2079       tty->print_cr("Exception table:");
2080       ExceptionTable excps(method());
2081       for(int i = 0; i < excps.length(); i ++) {
2082         tty->print_cr("[%d - %d] -> %d",
2083                       excps.start_pc(i), excps.end_pc(i), excps.handler_pc(i));
2084       }
2085     }
2086   }
2087 
2088   // if no code - do nothing
2089   // compiler needs info
2090   if (method()->code_size() == 0 || _max_locals + method()->max_stack() == 0) {
2091     fill_stackmap_prolog(0);
2092     fill_stackmap_epilog();
2093     return;
2094   }
2095   // Step 1: Compute all jump targets and their return value
2096   if (!_got_error)
2097     _rt.compute_ret_table(_method);
2098 
2099   // Step 2: Find all basic blocks and count GC points
2100   if (!_got_error)
2101     mark_bbheaders_and_count_gc_points();
2102 
2103   // Step 3: Calculate stack maps


< prev index next >