|
|
|
@ -46,8 +46,8 @@ import java.util.*; |
|
|
|
|
import java.util.Map.Entry; |
|
|
|
|
|
|
|
|
|
public class FinallyProcessor { |
|
|
|
|
private final Map<Integer, Integer> finallyBlockIDs = new HashMap<Integer, Integer>(); |
|
|
|
|
private final Map<Integer, Integer> catchallBlockIDs = new HashMap<Integer, Integer>(); |
|
|
|
|
private final Map<Integer, Integer> finallyBlockIDs = new HashMap<>(); |
|
|
|
|
private final Map<Integer, Integer> catchallBlockIDs = new HashMap<>(); |
|
|
|
|
|
|
|
|
|
private final MethodDescriptor methodDescriptor; |
|
|
|
|
private final VarProcessor varProcessor; |
|
|
|
@ -64,7 +64,7 @@ public class FinallyProcessor { |
|
|
|
|
private boolean processStatementEx(StructMethod mt, RootStatement root, ControlFlowGraph graph) { |
|
|
|
|
int bytecode_version = mt.getClassStruct().getBytecodeVersion(); |
|
|
|
|
|
|
|
|
|
LinkedList<Statement> stack = new LinkedList<Statement>(); |
|
|
|
|
LinkedList<Statement> stack = new LinkedList<>(); |
|
|
|
|
stack.add(root); |
|
|
|
|
|
|
|
|
|
while (!stack.isEmpty()) { |
|
|
|
@ -191,7 +191,7 @@ public class FinallyProcessor { |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private Record getFinallyInformation(StructMethod mt, RootStatement root, CatchAllStatement fstat) { |
|
|
|
|
Map<BasicBlock, Boolean> mapLast = new HashMap<BasicBlock, Boolean>(); |
|
|
|
|
Map<BasicBlock, Boolean> mapLast = new HashMap<>(); |
|
|
|
|
|
|
|
|
|
BasicBlockStatement firstBlockStatement = fstat.getHandler().getBasichead(); |
|
|
|
|
BasicBlock firstBasicBlock = firstBlockStatement.getBlock(); |
|
|
|
@ -220,10 +220,10 @@ public class FinallyProcessor { |
|
|
|
|
FlattenStatementsHelper flatthelper = new FlattenStatementsHelper(); |
|
|
|
|
DirectGraph dgraph = flatthelper.buildDirectGraph(root); |
|
|
|
|
|
|
|
|
|
LinkedList<DirectNode> stack = new LinkedList<DirectNode>(); |
|
|
|
|
LinkedList<DirectNode> stack = new LinkedList<>(); |
|
|
|
|
stack.add(dgraph.first); |
|
|
|
|
|
|
|
|
|
Set<DirectNode> setVisited = new HashSet<DirectNode>(); |
|
|
|
|
Set<DirectNode> setVisited = new HashSet<>(); |
|
|
|
|
|
|
|
|
|
while (!stack.isEmpty()) { |
|
|
|
|
|
|
|
|
@ -374,7 +374,7 @@ public class FinallyProcessor { |
|
|
|
|
Record information, |
|
|
|
|
int bytecode_version) { |
|
|
|
|
|
|
|
|
|
Set<BasicBlock> setCopy = new HashSet<BasicBlock>(setTry); |
|
|
|
|
Set<BasicBlock> setCopy = new HashSet<>(setTry); |
|
|
|
|
|
|
|
|
|
int finallytype = information.firstCode; |
|
|
|
|
Map<BasicBlock, Boolean> mapLast = information.mapLast; |
|
|
|
@ -464,7 +464,7 @@ public class FinallyProcessor { |
|
|
|
|
setCopy.add(newhead); |
|
|
|
|
setCopy.add(newheadinit); |
|
|
|
|
|
|
|
|
|
for (BasicBlock hd : new HashSet<BasicBlock>(newheadinit.getSuccExceptions())) { |
|
|
|
|
for (BasicBlock hd : new HashSet<>(newheadinit.getSuccExceptions())) { |
|
|
|
|
ExceptionRangeCFG range = graph.getExceptionRange(hd, newheadinit); |
|
|
|
|
|
|
|
|
|
if (setCopy.containsAll(range.getProtectedRange())) { |
|
|
|
@ -477,7 +477,7 @@ public class FinallyProcessor { |
|
|
|
|
|
|
|
|
|
private static void insertBlockBefore(ControlFlowGraph graph, BasicBlock oldblock, BasicBlock newblock) { |
|
|
|
|
|
|
|
|
|
List<BasicBlock> lstTemp = new ArrayList<BasicBlock>(); |
|
|
|
|
List<BasicBlock> lstTemp = new ArrayList<>(); |
|
|
|
|
lstTemp.addAll(oldblock.getPreds()); |
|
|
|
|
lstTemp.addAll(oldblock.getPredExceptions()); |
|
|
|
|
|
|
|
|
@ -510,7 +510,7 @@ public class FinallyProcessor { |
|
|
|
|
|
|
|
|
|
private static HashSet<BasicBlock> getAllBasicBlocks(Statement stat) { |
|
|
|
|
|
|
|
|
|
List<Statement> lst = new LinkedList<Statement>(); |
|
|
|
|
List<Statement> lst = new LinkedList<>(); |
|
|
|
|
lst.add(stat); |
|
|
|
|
|
|
|
|
|
int index = 0; |
|
|
|
@ -527,7 +527,7 @@ public class FinallyProcessor { |
|
|
|
|
} |
|
|
|
|
while (index < lst.size()); |
|
|
|
|
|
|
|
|
|
HashSet<BasicBlock> res = new HashSet<BasicBlock>(); |
|
|
|
|
HashSet<BasicBlock> res = new HashSet<>(); |
|
|
|
|
|
|
|
|
|
for (Statement st : lst) { |
|
|
|
|
res.add(((BasicBlockStatement)st).getBlock()); |
|
|
|
@ -569,7 +569,7 @@ public class FinallyProcessor { |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// identify start blocks
|
|
|
|
|
HashSet<BasicBlock> startBlocks = new HashSet<BasicBlock>(); |
|
|
|
|
HashSet<BasicBlock> startBlocks = new HashSet<>(); |
|
|
|
|
for (BasicBlock block : tryBlocks) { |
|
|
|
|
startBlocks.addAll(block.getSuccs()); |
|
|
|
|
} |
|
|
|
@ -578,7 +578,7 @@ public class FinallyProcessor { |
|
|
|
|
startBlocks.remove(graph.getLast()); |
|
|
|
|
startBlocks.removeAll(tryBlocks); |
|
|
|
|
|
|
|
|
|
List<Area> lstAreas = new ArrayList<Area>(); |
|
|
|
|
List<Area> lstAreas = new ArrayList<>(); |
|
|
|
|
|
|
|
|
|
for (BasicBlock start : startBlocks) { |
|
|
|
|
|
|
|
|
@ -648,17 +648,17 @@ public class FinallyProcessor { |
|
|
|
|
public BlockStackEntry(BasicBlock blockCatch, BasicBlock blockSample, List<int[]> lstStoreVars) { |
|
|
|
|
this.blockCatch = blockCatch; |
|
|
|
|
this.blockSample = blockSample; |
|
|
|
|
this.lstStoreVars = new ArrayList<int[]>(lstStoreVars); |
|
|
|
|
this.lstStoreVars = new ArrayList<>(lstStoreVars); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
List<BlockStackEntry> stack = new LinkedList<BlockStackEntry>(); |
|
|
|
|
List<BlockStackEntry> stack = new LinkedList<>(); |
|
|
|
|
|
|
|
|
|
Set<BasicBlock> setSample = new HashSet<BasicBlock>(); |
|
|
|
|
Set<BasicBlock> setSample = new HashSet<>(); |
|
|
|
|
|
|
|
|
|
Map<String, BasicBlock[]> mapNext = new HashMap<String, BasicBlock[]>(); |
|
|
|
|
Map<String, BasicBlock[]> mapNext = new HashMap<>(); |
|
|
|
|
|
|
|
|
|
stack.add(new BlockStackEntry(startCatch, startSample, new ArrayList<int[]>())); |
|
|
|
|
stack.add(new BlockStackEntry(startCatch, startSample, new ArrayList<>())); |
|
|
|
|
|
|
|
|
|
while (!stack.isEmpty()) { |
|
|
|
|
|
|
|
|
@ -719,7 +719,7 @@ public class FinallyProcessor { |
|
|
|
|
|
|
|
|
|
if (instrCatch.opcode == CodeConstants.opc_astore && |
|
|
|
|
instrSample.opcode == CodeConstants.opc_astore) { |
|
|
|
|
lst = new ArrayList<int[]>(lst); |
|
|
|
|
lst = new ArrayList<>(lst); |
|
|
|
|
lst.add(new int[]{instrCatch.getOperand(0), instrSample.getOperand(0)}); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
@ -738,7 +738,7 @@ public class FinallyProcessor { |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (isLastBlock) { |
|
|
|
|
Set<BasicBlock> setSuccs = new HashSet<BasicBlock>(blockSample.getSuccs()); |
|
|
|
|
Set<BasicBlock> setSuccs = new HashSet<>(blockSample.getSuccs()); |
|
|
|
|
setSuccs.removeAll(setSample); |
|
|
|
|
|
|
|
|
|
for (BlockStackEntry stackent : stack) { |
|
|
|
@ -753,7 +753,7 @@ public class FinallyProcessor { |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return new Area(startSample, setSample, getUniqueNext(graph, new HashSet<BasicBlock[]>(mapNext.values()))); |
|
|
|
|
return new Area(startSample, setSample, getUniqueNext(graph, new HashSet<>(mapNext.values()))); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private static BasicBlock getUniqueNext(ControlFlowGraph graph, Set<BasicBlock[]> setNext) { |
|
|
|
@ -887,7 +887,7 @@ public class FinallyProcessor { |
|
|
|
|
if (seqPattern.length() < seqSample.length()) { // split in two blocks
|
|
|
|
|
|
|
|
|
|
SimpleInstructionSequence seq = new SimpleInstructionSequence(); |
|
|
|
|
LinkedList<Integer> oldOffsets = new LinkedList<Integer>(); |
|
|
|
|
LinkedList<Integer> oldOffsets = new LinkedList<>(); |
|
|
|
|
for (int i = seqSample.length() - 1; i >= seqPattern.length(); i--) { |
|
|
|
|
seq.addInstruction(0, seqSample.getInstr(i), -1); |
|
|
|
|
oldOffsets.addFirst(sample.getOldOffset(i)); |
|
|
|
@ -898,7 +898,7 @@ public class FinallyProcessor { |
|
|
|
|
newblock.setSeq(seq); |
|
|
|
|
newblock.getInstrOldOffsets().addAll(oldOffsets); |
|
|
|
|
|
|
|
|
|
List<BasicBlock> lstTemp = new ArrayList<BasicBlock>(); |
|
|
|
|
List<BasicBlock> lstTemp = new ArrayList<>(); |
|
|
|
|
lstTemp.addAll(sample.getSuccs()); |
|
|
|
|
|
|
|
|
|
// move successors
|
|
|
|
@ -976,14 +976,14 @@ public class FinallyProcessor { |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// collect common exception ranges of predecessors and successors
|
|
|
|
|
Set<BasicBlock> setCommonExceptionHandlers = new HashSet<BasicBlock>(next.getSuccExceptions()); |
|
|
|
|
Set<BasicBlock> setCommonExceptionHandlers = new HashSet<>(next.getSuccExceptions()); |
|
|
|
|
for (BasicBlock pred : start.getPreds()) { |
|
|
|
|
setCommonExceptionHandlers.retainAll(pred.getSuccExceptions()); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
boolean is_outside_range = false; |
|
|
|
|
|
|
|
|
|
Set<BasicBlock> setPredecessors = new HashSet<BasicBlock>(start.getPreds()); |
|
|
|
|
Set<BasicBlock> setPredecessors = new HashSet<>(start.getPreds()); |
|
|
|
|
|
|
|
|
|
// replace start with next
|
|
|
|
|
for (BasicBlock pred : setPredecessors) { |
|
|
|
@ -1005,7 +1005,7 @@ public class FinallyProcessor { |
|
|
|
|
is_outside_range = true; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
Set<ExceptionRangeCFG> setRemovedExceptionRanges = new HashSet<ExceptionRangeCFG>(); |
|
|
|
|
Set<ExceptionRangeCFG> setRemovedExceptionRanges = new HashSet<>(); |
|
|
|
|
for (BasicBlock handler : block.getSuccExceptions()) { |
|
|
|
|
setRemovedExceptionRanges.add(graph.getExceptionRange(handler, block)); |
|
|
|
|
} |
|
|
|
@ -1020,7 +1020,7 @@ public class FinallyProcessor { |
|
|
|
|
// shift extern edges on splitted blocks
|
|
|
|
|
if (block.getSeq().isEmpty() && block.getSuccs().size() == 1) { |
|
|
|
|
BasicBlock succs = block.getSuccs().get(0); |
|
|
|
|
for (BasicBlock pred : new ArrayList<BasicBlock>(block.getPreds())) { |
|
|
|
|
for (BasicBlock pred : new ArrayList<>(block.getPreds())) { |
|
|
|
|
if (!setBlocks.contains(pred)) { |
|
|
|
|
pred.replaceSuccessor(block, succs); |
|
|
|
|
} |
|
|
|
|