示例#1
0
// The current instruction of "c" is a jump; one of its offset starts
// at "offset" and is a short if "isShort" is "TRUE",
// and an integer otherwise.  If the jump crosses "breakPC", change
// the span of the jump by "delta".
void Relocator::change_jump(int bci, int offset, bool is_short, int break_bci, int delta) {
  int bci_delta = (is_short) ? short_at(offset) : int_at(offset);
  int targ = bci + bci_delta;

  if ((bci <= break_bci && targ >  break_bci) ||
      (bci >  break_bci && targ <= break_bci)) {
    int new_delta;
    if (bci_delta > 0)
      new_delta = bci_delta + delta;
    else
      new_delta = bci_delta - delta;

    if (is_short && ((new_delta > MAX_SHORT) || new_delta < MIN_SHORT)) {
      push_jump_widen(bci, delta, new_delta);
    } else if (is_short) {
      short_at_put(offset, new_delta);
    } else {
      int_at_put(offset, new_delta);
    }
  }
}
示例#2
0
// handle jump_widen instruction. Called be ChangeJumpWiden class
bool Relocator::handle_jump_widen(int bci, int delta) {
  int ilen = rc_instr_len(bci);

  Bytecodes::Code bc = code_at(bci);
  switch (bc) {
    case Bytecodes::_ifeq:
    case Bytecodes::_ifne:
    case Bytecodes::_iflt:
    case Bytecodes::_ifge:
    case Bytecodes::_ifgt:
    case Bytecodes::_ifle:
    case Bytecodes::_if_icmpeq:
    case Bytecodes::_if_icmpne:
    case Bytecodes::_if_icmplt:
    case Bytecodes::_if_icmpge:
    case Bytecodes::_if_icmpgt:
    case Bytecodes::_if_icmple:
    case Bytecodes::_if_acmpeq:
    case Bytecodes::_if_acmpne:
    case Bytecodes::_ifnull:
    case Bytecodes::_ifnonnull: {
      const int goto_length   = Bytecodes::length_for(Bytecodes::_goto);

      // If 'if' points to the next bytecode after goto, it's already handled.
      // it shouldn't be.
      assert (short_at(bci+1) != ilen+goto_length, "if relocation already handled");
      assert(ilen == 3, "check length");

      // Convert to 0 if <cond> goto 6
      //            3 _goto 11
      //            6 _goto_w <wide delta offset>
      //            11 <else code>
      const int goto_w_length = Bytecodes::length_for(Bytecodes::_goto_w);
      const int add_bci = goto_length + goto_w_length;

      if (!relocate_code(bci, 3, /*delta*/add_bci)) return false;

      // if bytecode points to goto_w instruction
      short_at_put(bci + 1, ilen + goto_length);

      int cbci = bci + ilen;
      // goto around
      code_at_put(cbci, Bytecodes::_goto);
      short_at_put(cbci + 1, add_bci);
      // goto_w <wide delta>
      cbci = cbci + goto_length;
      code_at_put(cbci, Bytecodes::_goto_w);
      if (delta > 0) {
        delta += 2;                 // goto_w is 2 bytes more than "if" code
      } else {
        delta -= ilen+goto_length;  // branch starts at goto_w offset
      }
      int_at_put(cbci + 1, delta);
      break;

      }
    case Bytecodes::_goto:
    case Bytecodes::_jsr:
      assert(ilen == 3, "check length");

      if (!relocate_code(bci, 3, 2)) return false;
      if (bc == Bytecodes::_goto)
        code_at_put(bci, Bytecodes::_goto_w);
      else
        code_at_put(bci, Bytecodes::_jsr_w);

      // If it's a forward jump, add 2 for the widening.
      if (delta > 0) delta += 2;
      int_at_put(bci + 1, delta);
      break;

    default: ShouldNotReachHere();
  }

  return true;
}
 void set_pc(int index, jushort start_pc) {
   GUARANTEE((index * 2) < length(),
             "line number table pc index out of bounds");
   GUARANTEE(is_short_array(), "Line number table wrong type");
   short_at_put(index * 2, start_pc);
 }