// 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); } }