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);
  }
}
Пример #3
0
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);
    }
  }
}
Пример #4
0
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);

}
Пример #5
0
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;
}