src/share/vm/oops/generateOopMap.cpp

Print this page


   1 /*
   2  * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *


 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");


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


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

2076       }
2077     }
2078   }
2079 
2080   // if no code - do nothing
2081   // compiler needs info
2082   if (method()->code_size() == 0 || _max_locals + method()->max_stack() == 0) {
2083     fill_stackmap_prolog(0);
2084     fill_stackmap_epilog();
2085     return;
2086   }
2087   // Step 1: Compute all jump targets and their return value
2088   if (!_got_error)
2089     _rt.compute_ret_table(_method);
2090 
2091   // Step 2: Find all basic blocks and count GC points
2092   if (!_got_error)
2093     mark_bbheaders_and_count_gc_points();
2094 
2095   // Step 3: Calculate stack maps


   1 /*
   2  * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *


 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");


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


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