KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > edu > umd > cs > findbugs > ba > ResourceValueAnalysis


1 /*
2  * Bytecode Analysis Framework
3  * Copyright (C) 2003-2005 University of Maryland
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2.1 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18  */

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 this edge throws only implicit exceptions
82
// (as determined by TypeAnalysis and PruneInfeasibleExceptionEdges),
83
// and the resource tracker says to ignore implicit exceptions
84
// for this resource, ignore it.
85
if (AnalysisContext.currentAnalysisContext().getBoolProperty(AnalysisFeatures.ACCURATE_EXCEPTIONS) &&
86                     ignoreImplicitExceptions &&
87                     !edge.isFlagSet(EXPLICIT_EXCEPTIONS_FLAG))
88                 return;
89
90             // The ResourceTracker may veto the exception edge
91
if (resourceTracker.ignoreExceptionEdge(edge, resource, methodGen.getConstantPool()))
92                 return;
93             
94             if (fact.getStatus() == ResourceValueFrame.OPEN) {
95                 // If status is OPEN, downgrade to OPEN_ON_EXCEPTION_PATH
96
tmpFact = modifyFrame(fact, null);
97                 tmpFact.setStatus(ResourceValueFrame.OPEN_ON_EXCEPTION_PATH);
98             }
99
100             if (fact.isValid()) {
101                 // Special case: if the instruction that closes the resource
102
// throws an exception, we consider the resource to be successfully
103
// closed anyway.
104
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                 // Clear stack, push value for exception
117
if (fact.isValid()) {
118                     tmpFact = modifyFrame(fact, tmpFact);
119                     tmpFact.clearStack();
120                     tmpFact.pushValue(ResourceValue.notInstance());
121                 }
122             }
123         }
124
125         // Make the resource nonexistent if it is compared against null
126
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                     // Get the frame at the if statement
133
ResourceValueFrame startFrame = getStartFact(source);
134                     if (startFrame.isValid()) {
135                         // The source block has a valid start fact.
136
// That means it is safe to inspect the frame at the If instruction.
137
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                                 //System.out.println("**** making resource nonexistent on edge "+edge.getId());
144
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 JavaDoc
160          protected void mergeInto(ResourceValueFrame frame, ResourceValueFrame result)
161             throws DataflowAnalysisException {
162         // Merge slots
163
super.mergeInto(frame, result);
164
165         // Merge status
166
result.setStatus(Math.min(result.getStatus(), frame.getStatus()));
167     }
168     
169     //@Override
170
@Override JavaDoc
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 JavaDoc
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 // vim:ts=4
188
Popular Tags