private Edge getEdgeWithType(Iterator<Edge> iter, @Type int edgeType) { while (iter.hasNext()) { Edge edge = iter.next(); if (edge.getType() == edgeType) { return edge; } } return null; }
@Override public boolean acceptBranch(Edge edge, InstructionHandle source) { boolean isIfNull = (source.getInstruction() instanceof IFNULL); return edge.getType() == (isIfNull ? IFCMP_EDGE : FALL_THROUGH_EDGE); } }
private Type nullCheck(short opcode, Edge edge, InstructionHandle last, BasicBlock sourceBlock) throws DataflowAnalysisException { if (DEBUG_NULL_CHECK) { System.out.println("checking for nullcheck on edge " + edge); } Type type = null; if ((opcode == Const.IFNULL && edge.getType() == EdgeTypes.IFCMP_EDGE) || (opcode == Const.IFNONNULL && edge.getType() == EdgeTypes.FALL_THROUGH_EDGE)) { Location location = new Location(last, sourceBlock); TypeFrame typeFrame = typeDataflow.getFactAtLocation(location); if (typeFrame.isValid()) { type = typeFrame.getTopValue(); if (DEBUG_NULL_CHECK) { System.out.println("ifnull comparison of " + type + " to null at " + last); } } } return type; }
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); }
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; }
/** * 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; }
@Override public void meetInto(ReturnPath fact, Edge edge, ReturnPath result) throws DataflowAnalysisException { switch (edge.getType()) { case UNHANDLED_EXCEPTION_EDGE: fact = new ReturnPath(ReturnPath.UE); break; case EXIT_EDGE: fact = new ReturnPath(ReturnPath.EXIT); break; default: break; } result.mergeWith(fact); }
if (dfs.getDFSEdgeType(outEdge) == BACK_EDGE || outEdge.getType() == UNHANDLED_EXCEPTION_EDGE) { continue;
private InstructionHandle findThenFinish(CFG cfg, BasicBlock thenBB, int elsePos) { InstructionHandle inst = thenBB.getFirstInstruction(); while (inst == null) { Iterator<Edge> ie = cfg.outgoingEdgeIterator(thenBB); while (ie.hasNext()) { Edge e = ie.next(); if (e.getType() == EdgeTypes.FALL_THROUGH_EDGE) { thenBB = e.getTarget(); break; } } inst = thenBB.getFirstInstruction(); } InstructionHandle lastIns = inst; while (inst.getPosition() < elsePos) { lastIns = inst; inst = inst.getNext(); } return lastIns; }
@Override public InstructionHandle next() { if (!hasNext()) { throw new NoSuchElementException(); } InstructionHandle result = next; if(result == block.getFirstInstruction()) { do { Iterator<Edge> edgeIterator = cfg.incomingEdgeIterator(block); if(!edgeIterator.hasNext()) { break; } Edge edge = edgeIterator.next(); if(!edgeIterator.hasNext() && edge.getType() == EdgeTypes.FALL_THROUGH_EDGE) { block = edge.getSource(); } else { break; } } while(block.isExceptionThrower()); } next = (block.isExceptionThrower() || result == block.getFirstInstruction()) ? null : next.getPrev(); return result; }
@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)); } } } };
/** * Clear deref sets of values if this edge is the non-null branch of an if * comparison. * * @param fact * a datflow fact * @param edge * edge to check * @return possibly-modified dataflow fact */ private @CheckForNull ValueNumber findValueKnownNonnullOnBranch(UnconditionalValueDerefSet fact, Edge edge) { IsNullValueFrame invFrame = invDataflow.getResultFact(edge.getSource()); if (!invFrame.isValid()) { return null; } IsNullConditionDecision decision = invFrame.getDecision(); if (decision == null) { return null; } IsNullValue inv = decision.getDecision(edge.getType()); if (inv == null || !inv.isDefinitelyNotNull()) { return null; } ValueNumber value = decision.getValue(); if (DEBUG) { System.out.println("Value number " + value + " is known nonnull on " + edge); } return value; }
/** * 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; }
while (iei.hasNext()) { Edge e = iei.next(); int eType = e.getType(); if (eType == EdgeTypes.GOTO_EDGE) { BasicBlock target = e.getTarget();
private Location getEdgeTargetLocation(CFG cfg, Edge edge) { BasicBlock targetBlock = edge.getTarget(); // Target block is nonempty? if (targetBlock.getFirstInstruction() != null) { return new Location(targetBlock.getFirstInstruction(), targetBlock); } // Target block is an ETB? if (targetBlock.isExceptionThrower()) { BasicBlock fallThroughSuccessor = cfg.getSuccessorWithEdgeType(targetBlock, EdgeTypes.FALL_THROUGH_EDGE); if (fallThroughSuccessor == null) { // Fall through edge might have been pruned for (Iterator<Edge> i = cfg.removedEdgeIterator(); i.hasNext();) { Edge removedEdge = i.next(); if (removedEdge.getSource() == targetBlock && removedEdge.getType() == EdgeTypes.FALL_THROUGH_EDGE) { fallThroughSuccessor = removedEdge.getTarget(); break; } } } if (fallThroughSuccessor != null && fallThroughSuccessor.getFirstInstruction() != null) { return new Location(fallThroughSuccessor.getFirstInstruction(), fallThroughSuccessor); } } return null; }
if (removedEdge.getType() == EdgeTypes.FALL_THROUGH_EDGE && removedEdge.getSource() == exceptionEdge.getSource()) { basicBlock = removedEdge.getTarget();