if (!exceptionEdge.isExceptionEdge()) { throw new IllegalArgumentException(); InstructionHandle handle = exceptionEdge.getSource().getExceptionThrower(); if (handle == null) { throw new IllegalStateException(); BasicBlock basicBlock = (handle.getInstruction() instanceof ATHROW) ? exceptionEdge.getSource() : getSuccessorWithEdgeType(exceptionEdge.getSource(), EdgeTypes.FALL_THROUGH_EDGE); if (removedEdge.getType() == EdgeTypes.FALL_THROUGH_EDGE && removedEdge.getSource() == exceptionEdge.getSource()) { basicBlock = removedEdge.getTarget(); break;
@Override protected Edge allocateEdge(BasicBlock source, BasicBlock target) { return new Edge(source, target); }
@Override public void visitEdge(Edge edge) { if (REPORT_PATH_DEBUG) { System.out.println("Edge of type " + Edge.edgeTypeToString(edge.getType()) + " to " + edge.getTarget().getLabel()); if (edge.getTarget().getFirstInstruction() != null) { System.out.println(" First instruction in target: " + edge.getTarget().getFirstInstruction()); } if (edge.getTarget().isExceptionThrower()) { System.out.println(" exception thrower for " + edge.getTarget().getExceptionThrower()); } if (edge.isExceptionEdge()) { System.out.println(" exceptions thrown: " + typeDataflow.getEdgeExceptionSet(edge)); } } } };
public NonImplicitExceptionPostDominatorsAnalysis(CFG cfg, ReverseDepthFirstSearch rdfs, DepthFirstSearch dfs) { super(cfg, rdfs, dfs, edge -> !edge.isExceptionEdge() || edge.isFlagSet(EdgeTypes.EXPLICIT_EXCEPTIONS_FLAG)); } }
/** * Like bb.getFirstInstruction() except that if null is returned it will * follow the FALL_THROUGH_EDGE (if any) */ private static InstructionHandle getDeepFirstInstruction(CFG cfg, BasicBlock bb) { InstructionHandle ih = bb.getFirstInstruction(); if (ih != null) { return ih; } Iterator<Edge> iei = cfg.outgoingEdgeIterator(bb); while (iei.hasNext()) { Edge e = iei.next(); if (EdgeTypes.FALL_THROUGH_EDGE == e.getType()) { return getDeepFirstInstruction(cfg, e.getTarget()); } } return null; }
BasicBlock source = getSource(); BasicBlock target = getTarget(); buf.append(getLabel()); buf.append(") type "); buf.append(edgeTypeToString(type)); buf.append(" from block "); buf.append(reverse ? target.getLabel() : source.getLabel());
/** * Determine whether dataflow should be propagated on given edge. * * @param edge * the edge * @return true if dataflow should be propagated on the edge, false * otherwise */ private boolean isExceptionEdge(Edge edge) { boolean isExceptionEdge = edge.isExceptionEdge(); if (isExceptionEdge) { if (DEBUG) { System.out.println("NOT Ignoring " + edge); } return true; // false } if (edge.getType() != EdgeTypes.FALL_THROUGH_EDGE) { return false; } InstructionHandle h = edge.getSource().getLastInstruction(); if (h != null && h.getInstruction() instanceof IFNONNULL && isNullCheck(h, methodGen.getConstantPool())) { return true; } return false; }
public List<Edge> getDuplicates(CFG cfg, Edge edge) { InstructionHandle ih = edge.getSource().getLastInstruction(); if(ih == null) { return Collections.emptyList(); } BitSet duplicates = getDuplicates(ih.getPosition()); if(duplicates.isEmpty()) { return Collections.emptyList(); } List<Edge> result = new ArrayList<>(); for(Iterator<Edge> edgeIterator = cfg.edgeIterator(); edgeIterator.hasNext(); ) { Edge next = edgeIterator.next(); if(next.getType() != edge.getType()) { continue; } InstructionHandle lastInst = next.getSource().getLastInstruction(); if(lastInst != null && lastInst.getPosition() >= 0 && duplicates.get(lastInst.getPosition())) { result.add(next); } } return result; }
boolean isBackEdge = edge.isBackwardInBytecode(); Set<Integer> loopExitBranches = ClassContext.getLoopExitBranches(method, methodGen); assert loopExitBranches != null; boolean sourceIsTopOfLoop = edge.sourceIsTopOfLoop(loopExitBranches); if (sourceIsTopOfLoop && edge.getType() == EdgeTypes.FALL_THROUGH_EDGE) { isBackEdge = true; if (DEBUG && isBackEdge && edge.getType() == EdgeTypes.IFCMP_EDGE) { System.out.println(" result: " + result);
/** * Constructor. * * @param cfg * the CFG to compute dominator relationships for * @param ignoreExceptionEdges * true if exception edges should be ignored */ public AbstractDominatorsAnalysis(CFG cfg, final boolean ignoreExceptionEdges) { this(cfg, edge -> { if (ignoreExceptionEdges && edge.isExceptionEdge()) { return false; } else { return true; } }); }
@Override public void edgeTransfer(Edge edge, ReturnPathType fact) { // The edges leading into the exit block create the "seed" values // for the analysis. The exception edges create values indicating // that a normal (non-exception) return is not possible, // while the non-exception edges create values indicating that // a normal return is possible. if (edge.getTarget() == cfg.getExit()) { fact.setCanReturnNormally(!edge.isExceptionEdge()); } }
if (edge.isExceptionEdge()) { if (DEBUG_DEREFS) { System.out.println("On exception edge " + edge.formatAsString(false)); System.out.println("On edge " + edge.formatAsString(false)); BasicBlock source = edge.getSource(); ValueNumberFrame vnaFact = vnaDataflow.getResultFact(source); IsNullValueFrame invFact = invDataflow.getFactAtMidEdge(edge); if (edge.isExceptionEdge()) { BasicBlock b = cfg.getSuccessorWithEdgeType(source, EdgeTypes.FALL_THROUGH_EDGE); if (b != null) {
/** * Get the first successor reachable from given edge type. * * @param source * the source block * @param edgeType * the edge type leading to the successor * @return the successor, or null if there is no outgoing edge with the * specified edge type */ public BasicBlock getSuccessorWithEdgeType(BasicBlock source, @Type int edgeType) { Edge edge = getOutgoingEdgeWithType(source, edgeType); return edge != null ? edge.getTarget() : null; }
private static void debug(BasicBlock bb, BasicBlock pred, Edge edge, String msg) { System.out.print("Dataflow (block " + blockId(bb) + ", predecessor " + blockId(pred) + " [" + Edge.edgeTypeToString(edge.getType()) + "]): " + msg); }
/** * Get the set of exceptions that can be thrown on given edge. This should * only be called after the analysis completes. * * @param edge * the Edge * @return the ExceptionSet */ public ExceptionSet getEdgeExceptionSet(Edge edge) { CachedExceptionSet cachedExceptionSet = thrownExceptionSetMap.get(edge.getSource()); return cachedExceptionSet.getEdgeExceptionSet(edge); }
@Override public String toString() { return formatAsString(false); }