private void createNewBookmarks(List<TryCatchBlock> tryCatchBlocks) { // Add new bookmarks for (int i = tryCatchBookmarks.size(); i < tryCatchBlocks.size(); ++i) { TryCatchBlock tryCatch = tryCatchBlocks.get(tryCatchBlocks.size() - 1 - i); TryCatchBookmark bookmark = new TryCatchBookmark(); bookmark.block = stack.peek(); bookmark.offset = bookmark.block.body.size(); bookmark.exceptionHandler = tryCatch.getHandler().getIndex(); bookmark.exceptionType = tryCatch.getExceptionType(); bookmark.exceptionVariable = tryCatch.getHandler().getExceptionVariable() != null ? tryCatch.getHandler().getExceptionVariable().getIndex() : null; bookmark.block.tryCatches.add(bookmark); tryCatchBookmarks.add(bookmark); } }
private void markAssignment(Variable var) { Deque<BasicBlock> worklist = new ArrayDeque<>(); worklist.push(currentBlock); if (variableDefined[var.getIndex()]) { for (TryCatchBlock tryCatch : currentBlock.getTryCatchBlocks()) { placePhi(tryCatch.getHandler().getIndex(), var, currentBlock, worklist); } } else { variableDefined[var.getIndex()] = true; } while (!worklist.isEmpty()) { BasicBlock block = worklist.pop(); int[] frontiers = domFrontiers[block.getIndex()]; if (frontiers != null) { for (int frontier : frontiers) { placePhi(frontier, var, block, worklist); } } } }
TryCatchBlock tryCatch = tryCatchBlocks.get(start); TryCatchBookmark bookmark = tryCatchBookmarks.get(start); if (tryCatch.getHandler().getIndex() != bookmark.exceptionHandler) { break;
private void fillExceptionHandlers(Program program) { exceptionHandlers = new boolean[program.basicBlockCount()]; for (int i = 0; i < exceptionHandlers.length; ++i) { BasicBlock block = program.basicBlockAt(i); for (TryCatchBlock tryCatch : block.getTryCatchBlocks()) { exceptionHandlers[tryCatch.getHandler().getIndex()] = true; } } }
private BitSet getUsedVarsInBlock(LivenessAnalyzer liveness, BasicBlock block) { BitSet usedVars = new BitSet(); TransitionExtractor transitionExtractor = new TransitionExtractor(); block.getLastInstruction().acceptVisitor(transitionExtractor); for (BasicBlock successor : transitionExtractor.getTargets()) { usedVars.or(liveness.liveIn(successor.getIndex())); } for (TryCatchBlock tryCatch : block.getTryCatchBlocks()) { usedVars.or(liveness.liveIn(tryCatch.getHandler().getIndex())); } return usedVars; }
public void fixProgram() { if (mappings == null) { return; } for (BasicBlock block : program.getBasicBlocks()) { Map<BasicBlock, List<Incoming>> incomingsBySource = new LinkedHashMap<>(); for (Phi phi : block.getPhis()) { for (Incoming incoming : phi.getIncomings()) { if (mappings[incoming.getSource().getIndex()] == incoming.getSource().getIndex()) { continue; } incomingsBySource.computeIfAbsent(incoming.getSource(), b -> new ArrayList<>()).add(incoming); } } for (BasicBlock source : incomingsBySource.keySet()) { boolean isExceptionHandler = source.getTryCatchBlocks().stream() .anyMatch(tryCatch -> tryCatch.getHandler() == block); if (isExceptionHandler) { fixIncomingsInExceptionHandler(source, incomingsBySource.get(source)); } else { BasicBlock newSource = program.basicBlockAt(mappings[source.getIndex()]); for (Incoming incoming : incomingsBySource.get(source)) { incoming.setSource(newSource); } } } } RedundantJumpElimination.optimize(program); }
private void propagateException(String thrownTypeName, BasicBlock block) { for (TryCatchBlock tryCatch : block.getTryCatchBlocks()) { String expectedType = tryCatch.getExceptionType(); if (expectedType == null || hierarchy.isSuperType(expectedType, thrownTypeName, false)) { if (tryCatch.getHandler().getExceptionVariable() == null) { break; } int exceptionNode = packNodeAndDegree(tryCatch.getHandler().getExceptionVariable().getIndex(), 0); exceptionNode = nodeMapping[exceptionNode]; int thrownType = getTypeByName(thrownTypeName); if (getNodeTypes(exceptionNode).add(thrownType)) { nodeChanged[exceptionNode] = true; changed = true; } break; } } }
data.writeInt(tryCatch.getExceptionType() != null ? symbolTable.lookup( tryCatch.getExceptionType()) : -1); data.writeShort(tryCatch.getHandler().getIndex());
tryCatch.getHandler().setExceptionVariable(program.variableAt(minLocal + method.maxLocals)); block.getTryCatchBlocks().add(tryCatch);
private void fixOutgoingPhis(BasicBlock block, BasicBlock newBlock, int[] currentJointSources, IntSet outgoingVariablesToRemove, IntSet variablesDefinedHere) { for (TryCatchBlock tryCatch : block.getTryCatchBlocks()) { for (Phi phi : tryCatch.getHandler().getPhis()) { int value = currentJointSources[phi.getReceiver().getIndex()]; if (value < 0) {
liveOut.or(liveness.liveIn(tryCatch.getHandler().getIndex()));
public void transform(BasicBlock block) { Instruction lastInsn = block.getLastInstruction(); if (lastInsn != null) { lastInsn.acceptVisitor(this); } for (Phi phi : block.getPhis()) { for (Incoming incoming : phi.getIncomings()) { incoming.setSource(map(incoming.getSource())); } } for (TryCatchBlock tryCatch : block.getTryCatchBlocks()) { tryCatch.setHandler(map(tryCatch.getHandler())); } }
BasicBlock block = program.basicBlockAt(i); for (TryCatchBlock tryCatch : block.getTryCatchBlocks()) { exceptionHandlers.add(tryCatch.getHandler());
switchInsn.setDefaultTarget(tryCatch.getHandler()); } else { SwitchTableEntry catchEntry = new SwitchTableEntry(); catchEntry.setTarget(tryCatch.getHandler()); catchEntry.setCondition(handler.getId()); switchInsn.getEntries().add(catchEntry);
for (int j = 0; j < block.getTryCatchBlocks().size(); ++j) { TryCatchBlock tryCatch = block.getTryCatchBlocks().get(j); if (tryCatch.getHandler() == block) { block.getTryCatchBlocks().remove(j--);
for (Phi phi : tryCatch.getHandler().getPhis()) { phi.getIncomings().removeIf(incoming -> incoming.getSource() == target);
stack.push(tryCatch.getHandler().getIndex()); tryCatch.getHandler().removeIncomingsFrom(block);
public static Graph buildControlFlowGraph(Program program) { GraphBuilder graphBuilder = new GraphBuilder(program.basicBlockCount()); TransitionExtractor transitionExtractor = new TransitionExtractor(); for (int i = 0; i < program.basicBlockCount(); ++i) { BasicBlock block = program.basicBlockAt(i); Instruction insn = block.getLastInstruction(); if (insn != null) { insn.acceptVisitor(transitionExtractor); if (transitionExtractor.getTargets() != null) { for (BasicBlock successor : transitionExtractor.getTargets()) { graphBuilder.addEdge(i, successor.getIndex()); } } } for (TryCatchBlock tryCatch : block.getTryCatchBlocks()) { graphBuilder.addEdge(i, tryCatch.getHandler().getIndex()); } } return graphBuilder.build(); }
exceptionHandlingSuccessors.add(tryCatch.getHandler().getIndex());
int handler = tryCatch.getHandler().getIndex(); tryCatchCopy.setExceptionType(tryCatch.getExceptionType()); tryCatchCopy.setHandler(program.basicBlockAt(copiedNodes.getOrDefault(handler, handler)));