Ejemplo n.º 1
0
// Changes all jumps crossing "break_bci" by "delta".  May enqueue things
// on "rc->changes"
void Relocator::change_jumps(int break_bci, int delta) {
  int bci = 0;
  Bytecodes::Code bc;
  // Now, adjust any affected instructions. 
  while (bci < code_length()) {
    switch (bc= code_at(bci)) {
      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:
      case Bytecodes::_goto:
      case Bytecodes::_jsr:
	change_jump(bci, bci+1, true, break_bci, delta);
	break;
      case Bytecodes::_goto_w:
      case Bytecodes::_jsr_w:
	change_jump(bci, bci+1, false, break_bci, delta);
	break;
      case Bytecodes::_tableswitch: 
      case Bytecodes::_lookupswitch: 
      case Bytecodes::_fast_linearswitch:
      case Bytecodes::_fast_binaryswitch: {	
	int recPad = get_orig_switch_pad(bci, (bc != Bytecodes::_tableswitch));
        int oldPad = (recPad != -1) ? recPad : align(bci+1) - (bci+1);
	if (bci > break_bci) {
	  int new_bci = bci + delta;
	  int newPad = align(new_bci+1) - (new_bci+1);
	  // Do we need to check the padding? 
	  if (newPad != oldPad) {
	    if (recPad == -1) {
              _changes->push(new ChangeSwitchPad(bci, oldPad, (bc != Bytecodes::_tableswitch)));
	    }
	  }
	}	
	
	// Then the rest, which depend on the kind of switch.
	switch (bc) {
	  case Bytecodes::_tableswitch: {
            change_jump(bci, bci +1 + oldPad, false, break_bci, delta);
            // We cannot use the Bytecode_tableswitch abstraction, since the padding might not be correct.            
            int lo = int_at(bci + 1 + oldPad + 4 * 1);
            int hi = int_at(bci + 1 + oldPad + 4 * 2);
            int n = hi - lo + 1;
	    for (int k = 0; k < n; k++) {
	      change_jump(bci, bci +1 + oldPad + 4*(k+3), false, break_bci, delta);
	    }
	    // Special next-bci calculation here...
	    bci += 1 + oldPad + (n+3)*4;
	    continue;
	  }
	  case Bytecodes::_lookupswitch:
	  case Bytecodes::_fast_linearswitch:
          case Bytecodes::_fast_binaryswitch: {
            change_jump(bci, bci +1 + oldPad, false, break_bci, delta);
            // We cannot use the Bytecode_lookupswitch abstraction, since the padding might not be correct.            
	    int npairs = int_at(bci + 1 + oldPad + 4 * 1);
	    for (int k = 0; k < npairs; k++) {
              change_jump(bci, bci + 1 + oldPad + 4*(2 + 2*k + 1), false, break_bci, delta);
	    }
	    /* Special next-bci calculation here... */
	    bci += 1 + oldPad + (2 + (npairs*2))*4;
	    continue;
	  }
	  default:
	    ShouldNotReachHere();
	}
      }
      default:
	break;
    }
    bci += rc_instr_len(bci);
  }
}