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
|