void (ControlFlowGraph graph) { for (BasicBlock block : graph.getBlocks()) { InstructionSequence seq = block.getSeq(); int len = seq.length(); if (len > 0 && len < 3) { boolean ok = false; if (seq.getLastInstr().opcode >= CodeConstants.opc_ireturn && seq.getLastInstr().opcode <= CodeConstants.opc_return) { if (len == 1) { ok = true; } else if (seq.getLastInstr().opcode != CodeConstants.opc_return) { ok = switch (seq.getInstr(0).opcode) { case CodeConstants.opc_iload, CodeConstants.opc_lload, CodeConstants.opc_fload, CodeConstants.opc_dload, CodeConstants.opc_aload, CodeConstants.opc_aconst_null, CodeConstants.opc_bipush, CodeConstants.opc_sipush, CodeConstants.opc_lconst_0, CodeConstants.opc_lconst_1, CodeConstants.opc_fconst_0, CodeConstants.opc_fconst_1, CodeConstants.opc_fconst_2, CodeConstants.opc_dconst_0, CodeConstants.opc_dconst_1, CodeConstants.opc_ldc, CodeConstants.opc_ldc_w, CodeConstants.opc_ldc2_w -> true; default -> false; }; } } if (ok) { if (!block.getPredecessors().isEmpty()) { Set<BasicBlock> predecessorHandlersUnion = new HashSet<>(); Set<BasicBlock> predecessorHandlersIntersection = new HashSet<>(); boolean firstPredecessor = true; for (BasicBlock predecessor : block.getPredecessors()) { if (firstPredecessor) { predecessorHandlersIntersection.addAll(predecessor.getSuccessorExceptions()); firstPredecessor = false; } else { predecessorHandlersIntersection.retainAll(predecessor.getSuccessorExceptions()); } predecessorHandlersUnion.addAll(predecessor.getSuccessorExceptions()); } // add exception ranges from predecessors for (BasicBlock basicBlock : block.getSuccessorExceptions()) { predecessorHandlersIntersection.remove(basicBlock); } BasicBlock predecessor = block.getPredecessors().get(0); for (BasicBlock handler : predecessorHandlersIntersection) { ExceptionRangeCFG range = graph.getExceptionRange(handler, predecessor); range.getProtectedRange().add(block); block.addSuccessorException(handler); } // remove redundant ranges Set<BasicBlock> setRangesToBeRemoved = new HashSet<>(block.getSuccessorExceptions()); setRangesToBeRemoved.removeAll(predecessorHandlersUnion); for (BasicBlock handler : setRangesToBeRemoved) { ExceptionRangeCFG range = graph.getExceptionRange(handler, block); if (range.getProtectedRange().size() > 1) { range.getProtectedRange().remove(block); block.removeSuccessorException(handler); } } } if (block.getPredecessors().size() == 1 && block.getPredecessorExceptions().isEmpty()) { BasicBlock predecessor = block.getPredecessors().get(0); if (predecessor.getSuccessors().size() == 1) { // add exception ranges of the predecessor for (BasicBlock successor : predecessor.getSuccessorExceptions()) { if (!block.getSuccessorExceptions().contains(successor)) { ExceptionRangeCFG range = graph.getExceptionRange(successor, predecessor); range.getProtectedRange().add(block); block.addSuccessorException(successor); } } // remove superfluous ranges from successors for (BasicBlock successor : new HashSet<>(block.getSuccessorExceptions())) { if (!predecessor.getSuccessorExceptions().contains(successor)) { ExceptionRangeCFG range = graph.getExceptionRange(successor, block); if (range.getProtectedRange().size() > 1) { range.getProtectedRange().remove(block); block.removeSuccessorException(successor); } } } } } } } } }