/*
* Optimized packing that does a 'local packing' of the code rather than building a brand new method and packing into it. Only
* usable when the packing is going to be done just once.
*/
public void optimizedPackBody(MethodGen gen) {
InstructionList theBody = getBody();
InstructionHandle iHandle = theBody.getStart();
int currLine = -1;
int lineNumberOffset = (fromFilename == null) ? 0 : getEnclosingClass().getSourceDebugExtensionOffset(fromFilename);
Map<LocalVariableTag, LVPosition> localVariables = new HashMap<LocalVariableTag, LVPosition>();
LinkedList<ExceptionRange> exceptionList = new LinkedList<ExceptionRange>();
Set<InstructionHandle> forDeletion = new HashSet<InstructionHandle>();
Set<BranchHandle> branchInstructions = new HashSet<BranchHandle>();
// OPTIMIZE sort out in here: getRange()/insertHandler() and type of
// exceptionList
while (iHandle != null) {
Instruction inst = iHandle.getInstruction();
// InstructionHandle nextInst = iHandle.getNext();
// OPTIMIZE remove this instructionhandle as it now points to
// nowhere?
if (inst == Range.RANGEINSTRUCTION) {
Range r = Range.getRange(iHandle);
if (r instanceof ExceptionRange) {
ExceptionRange er = (ExceptionRange) r;
if (er.getStart() == iHandle) {
if (!er.isEmpty()) {
// order is important, insert handlers in order of start
insertHandler(er, exceptionList);
}
}
}
forDeletion.add(iHandle);
} else {
if (inst instanceof InstructionBranch) {
branchInstructions.add((BranchHandle) iHandle);
}
for (InstructionTargeter targeter : iHandle.getTargetersCopy()) {
if (targeter instanceof LineNumberTag) {
int line = ((LineNumberTag) targeter).getLineNumber();
if (line != currLine) {
gen.addLineNumber(iHandle, line + lineNumberOffset);
currLine = line;
}
} else if (targeter instanceof LocalVariableTag) {
LocalVariableTag lvt = (LocalVariableTag) targeter;
LVPosition p = localVariables.get(lvt);
// If we don't know about it, create a new position
// and store
// If we do know about it - update its end position
if (p == null) {
LVPosition newp = new LVPosition();
newp.start = newp.end = iHandle;
localVariables.put(lvt, newp);
} else {
p.end = iHandle;
}
}
}
}
iHandle = iHandle.getNext();
}
for (BranchHandle branchHandle : branchInstructions) {
handleBranchInstruction(branchHandle, forDeletion);
}
// now add exception handlers
for (ExceptionRange r : exceptionList) {
if (r.isEmpty()) {
continue;
}
gen.addExceptionHandler(jumpForward(r.getRealStart(), forDeletion), jumpForward(r.getRealEnd(), forDeletion),
jumpForward(r.getHandler(), forDeletion),
(r.getCatchType() == null) ? null : (ObjectType) BcelWorld.makeBcelType(r.getCatchType()));
}
for (InstructionHandle handle : forDeletion) {
try {
theBody.delete(handle);
} catch (TargetLostException e) {
e.printStackTrace();
}
}
gen.setInstructionList(theBody);