BitMap MethodLiveness::BasicBlock::get_liveness_at(ciMethod* method, int bci) { BitMap answer(NEW_RESOURCE_ARRAY(uintptr_t, _analyzer->bit_map_size_words()), _analyzer->bit_map_size_bits()); #ifndef ASSERT if (bci == start_bci()) { answer.set_from(_entry); return answer; } #endif answer.clear(); ciByteCodeStream bytes(method); bytes.reset_to_bci(bci); bytes.set_max_bci(limit_bci()); compute_gen_kill_range(&bytes); answer.set_union(_normal_exit); answer.set_difference(_kill); answer.set_union(_gen); answer.set_union(_exception_exit); #ifdef ASSERT if (bci == start_bci()) { assert(answer.is_same(_entry), "optimized answer must be accurate"); } #endif return answer; }
// ------------------------------------------------------------------ // ciBlock::print_on void ciBlock::print_on(outputStream* st) const { st->print_cr("--------------------------------------------------------"); st->print ("ciBlock [%d - %d) control : ", start_bci(), limit_bci()); if (control_bci() == fall_through_bci) { st->print_cr("%d:fall through", limit_bci()); } else { st->print_cr("%d:%s", control_bci(), Bytecodes::name(method()->java_code_at_bci(control_bci()))); } if (Verbose || WizardMode) { method()->print_codes_on(start_bci(), limit_bci(), st); } }
void MethodLiveness::BasicBlock::propagate(MethodLiveness *ml) { // These set operations could be combined for efficiency if the // performance of this analysis becomes an issue. _entry.set_union(_normal_exit); _entry.set_difference(_kill); _entry.set_union(_gen); // Note that we merge information from our exceptional successors // just once, rather than at individual bytecodes. _entry.set_union(_exception_exit); if (TraceLivenessGen) { tty->print_cr(" ** Visiting block at %d **", start_bci()); print_on(tty); } int i; for (i=_normal_predecessors->length()-1; i>=0; i--) { BasicBlock *block = _normal_predecessors->at(i); if (block->merge_normal(_entry)) { ml->work_list_add(block); } } for (i=_exception_predecessors->length()-1; i>=0; i--) { BasicBlock *block = _exception_predecessors->at(i); if (block->merge_exception(_entry)) { ml->work_list_add(block); } } }
void MethodLiveness::BasicBlock::compute_gen_kill(ciMethod* method) { ciBytecodeStream bytes(method); bytes.reset_to_bci(start_bci()); bytes.set_max_bci(limit_bci()); compute_gen_kill_range(&bytes); }
MethodLivenessResult MethodLiveness::BasicBlock::get_liveness_at(ciMethod* method, int bci) { MethodLivenessResult answer(NEW_RESOURCE_ARRAY(uintptr_t, _analyzer->bit_map_size_words()), _analyzer->bit_map_size_bits()); answer.set_is_valid(); #ifndef ASSERT if (bci == start_bci()) { answer.set_from(_entry); return answer; } #endif #ifdef ASSERT ResourceMark rm; BitMap g(_gen.size()); g.set_from(_gen); BitMap k(_kill.size()); k.set_from(_kill); #endif if (_last_bci != bci || trueInDebug) { ciBytecodeStream bytes(method); bytes.reset_to_bci(bci); bytes.set_max_bci(limit_bci()); compute_gen_kill_range(&bytes); assert(_last_bci != bci || (g.is_same(_gen) && k.is_same(_kill)), "cached computation is incorrect"); _last_bci = bci; } answer.clear(); answer.set_union(_normal_exit); answer.set_difference(_kill); answer.set_union(_gen); answer.set_union(_exception_exit); #ifdef ASSERT if (bci == start_bci()) { assert(answer.is_same(_entry), "optimized answer must be accurate"); } #endif return answer; }