}
private static void splitBasicBlocks(MethodNode mth) {
InsnNode prevInsn = null;
Map<Integer, BlockNode> blocksMap = new HashMap<Integer, BlockNode>();
BlockNode curBlock = startNewBlock(mth, 0);
mth.setEnterBlock(curBlock);
// split into blocks
for (InsnNode insn : mth.getInstructions()) {
if (insn == null) {
continue;
}
boolean startNew = false;
if (prevInsn != null) {
InsnType type = prevInsn.getType();
if (type == InsnType.GOTO
|| type == InsnType.THROW
|| SEPARATE_INSNS.contains(type)) {
if (type == InsnType.RETURN || type == InsnType.THROW) {
mth.addExitBlock(curBlock);
}
BlockNode block = startNewBlock(mth, insn.getOffset());
if (type == InsnType.MONITOR_ENTER || type == InsnType.MONITOR_EXIT) {
connect(curBlock, block);
}
curBlock = block;
startNew = true;
} else {
startNew = isSplitByJump(prevInsn, insn)
|| SEPARATE_INSNS.contains(insn.getType())
|| isDoWhile(blocksMap, curBlock, insn);
if (startNew) {
BlockNode block = startNewBlock(mth, insn.getOffset());
connect(curBlock, block);
curBlock = block;
}
}
}
// for try/catch make empty block for connect handlers
if (insn.contains(AFlag.TRY_ENTER)) {
BlockNode block;
if (insn.getOffset() != 0 && !startNew) {
block = startNewBlock(mth, insn.getOffset());
connect(curBlock, block);
curBlock = block;
}
blocksMap.put(insn.getOffset(), curBlock);
// add this insn in new block
block = startNewBlock(mth, -1);
curBlock.add(AFlag.SYNTHETIC);
SplitterBlockAttr splitter = new SplitterBlockAttr(curBlock);
block.addAttr(splitter);
curBlock.addAttr(splitter);
connect(curBlock, block);
curBlock = block;
} else {
blocksMap.put(insn.getOffset(), curBlock);