1 19 20 package edu.umd.cs.findbugs.ba; 21 22 import org.apache.bcel.generic.IFNONNULL; 23 import org.apache.bcel.generic.IFNULL; 24 import org.apache.bcel.generic.Instruction; 25 import org.apache.bcel.generic.InstructionHandle; 26 import org.apache.bcel.generic.MethodGen; 27 28 import edu.umd.cs.findbugs.SystemProperties; 29 import edu.umd.cs.findbugs.annotations.DefaultAnnotationForParameters; 30 import edu.umd.cs.findbugs.annotations.NonNull; 31 32 @DefaultAnnotationForParameters(NonNull.class) 33 public class ResourceValueAnalysis <Resource> extends FrameDataflowAnalysis<ResourceValue, ResourceValueFrame> 34 implements EdgeTypes { 35 36 private static final boolean DEBUG = SystemProperties.getBoolean("dataflow.debug"); 37 38 private MethodGen methodGen; 39 private CFG cfg; 40 private ResourceTracker<Resource> resourceTracker; 41 private Resource resource; 42 private ResourceValueFrameModelingVisitor visitor; 43 private boolean ignoreImplicitExceptions; 44 45 public ResourceValueAnalysis(MethodGen methodGen, CFG cfg, DepthFirstSearch dfs, 46 ResourceTracker<Resource> resourceTracker, Resource resource) { 47 48 super(dfs); 49 this.methodGen = methodGen; 50 this.cfg = cfg; 51 this.resourceTracker = resourceTracker; 52 this.resource = resource; 53 this.visitor = resourceTracker.createVisitor(resource, methodGen.getConstantPool()); 54 55 this.ignoreImplicitExceptions = resourceTracker.ignoreImplicitExceptions(resource); 56 } 57 58 public ResourceValueFrame createFact() { 59 ResourceValueFrame fact = new ResourceValueFrame(methodGen.getMaxLocals()); 60 fact.setTop(); 61 return fact; 62 } 63 64 public void initEntryFact(ResourceValueFrame result) { 65 result.setValid(); 66 result.clearStack(); 67 final int numSlots = result.getNumSlots(); 68 for (int i = 0; i < numSlots; ++i) { 69 boolean slotContainsInstance = resourceTracker.isParamInstance(resource, i); 70 result.setValue(i, slotContainsInstance ? ResourceValue.instance() : ResourceValue.notInstance()); 71 } 72 } 73 74 public void meetInto(ResourceValueFrame fact, Edge edge, ResourceValueFrame result) throws DataflowAnalysisException { 75 BasicBlock source = edge.getSource(); 76 BasicBlock dest = edge.getTarget(); 77 78 ResourceValueFrame tmpFact = null; 79 80 if (edge.isExceptionEdge()) { 81 if (AnalysisContext.currentAnalysisContext().getBoolProperty(AnalysisFeatures.ACCURATE_EXCEPTIONS) && 86 ignoreImplicitExceptions && 87 !edge.isFlagSet(EXPLICIT_EXCEPTIONS_FLAG)) 88 return; 89 90 if (resourceTracker.ignoreExceptionEdge(edge, resource, methodGen.getConstantPool())) 92 return; 93 94 if (fact.getStatus() == ResourceValueFrame.OPEN) { 95 tmpFact = modifyFrame(fact, null); 97 tmpFact.setStatus(ResourceValueFrame.OPEN_ON_EXCEPTION_PATH); 98 } 99 100 if (fact.isValid()) { 101 InstructionHandle exceptionThrower = source.getExceptionThrower(); 105 BasicBlock fallThroughSuccessor = cfg.getSuccessorWithEdgeType(source, FALL_THROUGH_EDGE); 106 if (DEBUG && fallThroughSuccessor == null) System.out.println("Null fall through successor!"); 107 if (fallThroughSuccessor != null && 108 resourceTracker.isResourceClose(fallThroughSuccessor, exceptionThrower, methodGen.getConstantPool(), resource, fact)) { 109 tmpFact = modifyFrame(fact, tmpFact); 110 tmpFact.setStatus(ResourceValueFrame.CLOSED); 111 if (DEBUG) System.out.print("(failed attempt to close)"); 112 } 113 } 114 115 if (dest.isExceptionHandler()) { 116 if (fact.isValid()) { 118 tmpFact = modifyFrame(fact, tmpFact); 119 tmpFact.clearStack(); 120 tmpFact.pushValue(ResourceValue.notInstance()); 121 } 122 } 123 } 124 125 int edgeType = edge.getType(); 127 if (edgeType == IFCMP_EDGE || edgeType == FALL_THROUGH_EDGE) { 128 InstructionHandle lastInSourceHandle = source.getLastInstruction(); 129 if (lastInSourceHandle != null) { 130 Instruction lastInSource = lastInSourceHandle.getInstruction(); 131 if (lastInSource instanceof IFNULL || lastInSource instanceof IFNONNULL) { 132 ResourceValueFrame startFrame = getStartFact(source); 134 if (startFrame.isValid()) { 135 ResourceValueFrame frameAtIf = getFactAtLocation(new Location(lastInSourceHandle, source)); 138 ResourceValue topValue = frameAtIf.getValue(frameAtIf.getNumSlots() - 1); 139 140 if (topValue.isInstance()) { 141 if ((lastInSource instanceof IFNULL && edgeType == IFCMP_EDGE) || 142 (lastInSource instanceof IFNONNULL && edgeType == FALL_THROUGH_EDGE)) { 143 tmpFact = modifyFrame(fact, tmpFact); 145 tmpFact.setStatus(ResourceValueFrame.NONEXISTENT); 146 } 147 } 148 } 149 } 150 } 151 } 152 153 if (tmpFact != null) 154 fact = tmpFact; 155 156 mergeInto(fact, result); 157 } 158 159 @Override 160 protected void mergeInto(ResourceValueFrame frame, ResourceValueFrame result) 161 throws DataflowAnalysisException { 162 super.mergeInto(frame, result); 164 165 result.setStatus(Math.min(result.getStatus(), frame.getStatus())); 167 } 168 169 @Override 171 protected void mergeValues(ResourceValueFrame otherFrame, ResourceValueFrame resultFrame, int slot) throws DataflowAnalysisException { 172 ResourceValue value = ResourceValue.merge(resultFrame.getValue(slot), otherFrame.getValue(slot)); 173 resultFrame.setValue(slot, value); 174 } 175 176 @Override 177 public void transferInstruction(InstructionHandle handle, BasicBlock basicBlock, ResourceValueFrame fact) 178 throws DataflowAnalysisException { 179 180 visitor.setFrameAndLocation(fact, new Location(handle, basicBlock)); 181 visitor.transferInstruction(handle, basicBlock); 182 183 } 184 185 } 186 187 | Popular Tags |