KickJava   Java API By Example, From Geeks To Geeks.

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


1 /*
2  * Bytecode Analysis Framework
3  * Copyright (C) 2003,2004 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.Constants;
23 import org.apache.bcel.classfile.Method;
24 import org.apache.bcel.generic.Instruction;
25 import org.apache.bcel.generic.InstructionHandle;
26 import org.apache.bcel.generic.MethodGen;
27 import org.apache.bcel.generic.ReturnInstruction;
28
29 import edu.umd.cs.findbugs.SystemProperties;
30 import edu.umd.cs.findbugs.ba.vna.ValueNumber;
31 import edu.umd.cs.findbugs.ba.vna.ValueNumberAnalysis;
32 import edu.umd.cs.findbugs.ba.vna.ValueNumberDataflow;
33 import edu.umd.cs.findbugs.ba.vna.ValueNumberFrame;
34
35 /**
36  * Analysis to determine where particular values are locked in a method.
37  * The dataflow values are maps of value numbers to the number of times
38  * those values are locked.
39  *
40  * @author David Hovemeyer
41  * @see ValueNumberAnalysis
42  */

43 public class LockAnalysis extends ForwardDataflowAnalysis<LockSet> {
44     private static final boolean DEBUG = SystemProperties.getBoolean("la.debug");
45
46     private MethodGen methodGen;
47     private ValueNumberDataflow vnaDataflow;
48     private ValueNumberAnalysis vna;
49     private boolean isSynchronized;
50     private boolean isStatic;
51
52     public LockAnalysis(MethodGen methodGen, ValueNumberDataflow vnaDataflow, DepthFirstSearch dfs) {
53         super(dfs);
54         this.methodGen = methodGen;
55         this.vnaDataflow = vnaDataflow;
56         this.vna = vnaDataflow.getAnalysis();
57         this.isSynchronized = methodGen.isSynchronized();
58         this.isStatic = methodGen.isStatic();
59         if (DEBUG) System.out.println("Analyzing Locks in " + methodGen.getClassName() + "." + methodGen.getName());
60     }
61
62     public LockSet createFact() {
63         return new LockSet();
64     }
65
66     public void copy(LockSet source, LockSet dest) {
67         dest.copyFrom(source);
68     }
69
70     public void initEntryFact(LockSet result) {
71         result.clear();
72         result.setDefaultLockCount(0);
73
74         if (isSynchronized && !isStatic) {
75             ValueNumber thisValue = vna.getThisValue();
76             result.setLockCount(thisValue.getNumber(), 1);
77         } else if (isSynchronized && isStatic) {
78             ValueNumber thisValue = vna.getClassObjectValue(methodGen.getClassName());
79             result.setLockCount(thisValue.getNumber(), 1);
80         }
81     }
82
83     public void initResultFact(LockSet result) {
84         result.clear();
85         result.setDefaultLockCount(LockSet.TOP);
86     }
87
88     public void makeFactTop(LockSet fact) {
89         fact.clear();
90         fact.setDefaultLockCount(LockSet.TOP);
91     }
92     public boolean isTop(LockSet fact) {
93         return fact.isTop();
94     }
95     public boolean same(LockSet fact1, LockSet fact2) {
96         return fact1.sameAs(fact2);
97     }
98
99     public void meetInto(LockSet fact, Edge edge, LockSet result) throws DataflowAnalysisException {
100         result.meetWith(fact);
101     }
102
103     @Override JavaDoc
104          public void transferInstruction(InstructionHandle handle, BasicBlock basicBlock, LockSet fact)
105             throws DataflowAnalysisException {
106
107         Instruction ins = handle.getInstruction();
108         short opcode = ins.getOpcode();
109         if (opcode == Constants.MONITORENTER || opcode == Constants.MONITOREXIT) {
110             ValueNumberFrame frame = vnaDataflow.getFactAtLocation(new Location(handle, basicBlock));
111
112             // NOTE: if the CFG is pruned, there may be unreachable instructions,
113
// so make sure frame is valid.
114
if (frame.isValid()) {
115                 int lockNumber = frame.getTopValue().getNumber();
116                 lockOp(fact, lockNumber, opcode == Constants.MONITORENTER ? 1 : -1);
117             }
118         } else if ((ins instanceof ReturnInstruction) && isSynchronized && !isStatic) {
119             lockOp(fact, vna.getThisValue().getNumber(), -1);
120         }
121     }
122
123     private void lockOp(LockSet fact, int lockNumber, int delta) {
124         int value = fact.getLockCount(lockNumber);
125         if (value < 0) // can't modify TOP or BOTTOM value
126
return;
127         value += delta;
128         if (value < 0)
129             value = LockSet.BOTTOM;
130         if (DEBUG) System.out.println("Setting " + lockNumber + " to " + value + " in " + methodGen.getClassName() + "." + methodGen.getName());
131         fact.setLockCount(lockNumber, value);
132     }
133
134     @Override JavaDoc
135          public boolean isFactValid(LockSet fact) {
136         return true;
137     }
138
139     public static void main(String JavaDoc[] argv) throws Exception JavaDoc {
140         if (argv.length != 1) {
141             System.err.println("Usage: " + LockAnalysis.class.getName() + " <classfile>");
142             System.exit(1);
143         }
144
145         DataflowTestDriver<LockSet, LockAnalysis> driver = new DataflowTestDriver<LockSet, LockAnalysis>() {
146             @Override JavaDoc
147                          public Dataflow<LockSet, LockAnalysis> createDataflow(ClassContext classContext, Method method)
148                     throws CFGBuilderException, DataflowAnalysisException {
149                 return classContext.getLockDataflow(method);
150             }
151         };
152
153         driver.execute(argv[0]);
154     }
155 }
156
157 // vim:ts=4
158
Popular Tags