// first pass: copy the instructions directly, populate the srcToDest
// map,
// fix frame instructions
for (InstructionHandle src = sourceList.getStart(); src != null; src = src.getNext()) {
Instruction fresh = Utility.copyInstruction(src.getInstruction());
InstructionHandle dest;
// OPTIMIZE optimize this stuff?
if (fresh.isConstantPoolInstruction()) {
// need to reset index to go to new constant pool. This is
// totally
// a computation leak... we're testing this LOTS of times. Sigh.
if (isAcrossClass) {
InstructionCP cpi = (InstructionCP) fresh;
cpi.setIndex(recipientCpg.addConstant(donorCpg.getConstant(cpi.getIndex()), donorCpg));
}
}
if (src.getInstruction() == Range.RANGEINSTRUCTION) {
dest = ret.append(Range.RANGEINSTRUCTION);
} else if (fresh.isReturnInstruction()) {
if (keepReturns) {
dest = ret.append(fresh);
} else {
dest = ret.append(InstructionFactory.createBranchInstruction(Constants.GOTO, end));
}
} else if (fresh instanceof InstructionBranch) {
dest = ret.append((InstructionBranch) fresh);
} else if (fresh.isLocalVariableInstruction() || fresh instanceof RET) {
// IndexedInstruction indexed = (IndexedInstruction) fresh;
int oldIndex = fresh.getIndex();
int freshIndex;
if (!frameEnv.hasKey(oldIndex)) {
freshIndex = recipient.allocateLocal(2);
frameEnv.put(oldIndex, freshIndex);
} else {
freshIndex = frameEnv.get(oldIndex);
}
if (fresh instanceof RET) {
fresh.setIndex(freshIndex);
} else {
fresh = ((InstructionLV) fresh).setIndexAndCopyIfNecessary(freshIndex);
}
dest = ret.append(fresh);
} else {
dest = ret.append(fresh);
}
srcToDest.put(src, dest);
}
// second pass: retarget branch instructions, copy ranges and tags
Map<Tag, Tag> tagMap = new HashMap<Tag, Tag>();
Map<BcelShadow, BcelShadow> shadowMap = new HashMap<BcelShadow, BcelShadow>();
for (InstructionHandle dest = ret.getStart(), src = sourceList.getStart(); dest != null; dest = dest.getNext(), src = src
.getNext()) {
Instruction inst = dest.getInstruction();
// retarget branches
if (inst instanceof InstructionBranch) {
InstructionBranch branch = (InstructionBranch) inst;
InstructionHandle oldTarget = branch.getTarget();