1
2
3
4 package joeq.Compiler.BytecodeAnalysis;
5
6 import java.util.HashMap;
7 import java.util.HashSet;
8 import java.util.Iterator;
9 import java.util.Map;
10 import java.util.Set;
11 import joeq.Class.jq_InstanceField;
12 import joeq.Class.jq_Method;
13 import joeq.Class.jq_MethodVisitor;
14 import joeq.Class.jq_StaticField;
15 import jwutil.strings.Strings;
16
17 /***
18 * Simple mod/ref analysis.
19 *
20 * @author John Whaley <jwhaley@alum.mit.edu>
21 * @version $Id: ModRefAnalysis.java 2282 2005-05-28 11:14:27Z joewhaley $
22 */
23 public class ModRefAnalysis extends BytecodeVisitor {
24
25 public static final boolean INTRA_CLASS = true;
26 public static final boolean ALWAYS_TRACE = false;
27
28 public static class ModRefVisitor extends jq_MethodVisitor.EmptyVisitor {
29 public void visitMethod(jq_Method m) {
30 m.getDeclaringClass().load();
31 if (m.getBytecode() == null) return;
32 ModRefAnalysis s = new ModRefAnalysis(m);
33 results.put(m, s);
34 s.forwardTraversal();
35 }
36 }
37
38 public static Map results = new HashMap();
39
40 protected Set mod = new HashSet();
41 protected Set ref = new HashSet();
42
43 /*** Creates new ModRefAnalysis */
44 public ModRefAnalysis(jq_Method m) {
45 super(m);
46 this.TRACE = ALWAYS_TRACE;
47 }
48
49 public Set getMod() { return mod; }
50 public Set getRef() { return ref; }
51
52 public void visitIGETSTATIC(jq_StaticField f) {
53 super.visitIGETSTATIC(f);
54 f = tryResolve(f);
55 ref.add(f);
56 }
57 public void visitLGETSTATIC(jq_StaticField f) {
58 super.visitLGETSTATIC(f);
59 f = tryResolve(f);
60 ref.add(f);
61 }
62 public void visitFGETSTATIC(jq_StaticField f) {
63 super.visitFGETSTATIC(f);
64 f = tryResolve(f);
65 ref.add(f);
66 }
67 public void visitDGETSTATIC(jq_StaticField f) {
68 super.visitDGETSTATIC(f);
69 f = tryResolve(f);
70 ref.add(f);
71 }
72 public void visitAGETSTATIC(jq_StaticField f) {
73 super.visitAGETSTATIC(f);
74 f = tryResolve(f);
75 ref.add(f);
76 }
77 public void visitZGETSTATIC(jq_StaticField f) {
78 super.visitZGETSTATIC(f);
79 f = tryResolve(f);
80 ref.add(f);
81 }
82 public void visitBGETSTATIC(jq_StaticField f) {
83 super.visitBGETSTATIC(f);
84 f = tryResolve(f);
85 ref.add(f);
86 }
87 public void visitCGETSTATIC(jq_StaticField f) {
88 super.visitCGETSTATIC(f);
89 f = tryResolve(f);
90 ref.add(f);
91 }
92 public void visitSGETSTATIC(jq_StaticField f) {
93 super.visitSGETSTATIC(f);
94 f = tryResolve(f);
95 ref.add(f);
96 }
97 public void visitIPUTSTATIC(jq_StaticField f) {
98 super.visitIPUTSTATIC(f);
99 f = tryResolve(f);
100 mod.add(f);
101 }
102 public void visitLPUTSTATIC(jq_StaticField f) {
103 super.visitLPUTSTATIC(f);
104 f = tryResolve(f);
105 mod.add(f);
106 }
107 public void visitFPUTSTATIC(jq_StaticField f) {
108 super.visitFPUTSTATIC(f);
109 f = tryResolve(f);
110 mod.add(f);
111 }
112 public void visitDPUTSTATIC(jq_StaticField f) {
113 super.visitDPUTSTATIC(f);
114 f = tryResolve(f);
115 mod.add(f);
116 }
117 public void visitAPUTSTATIC(jq_StaticField f) {
118 super.visitAPUTSTATIC(f);
119 f = tryResolve(f);
120 mod.add(f);
121 }
122 public void visitZPUTSTATIC(jq_StaticField f) {
123 super.visitZPUTSTATIC(f);
124 f = tryResolve(f);
125 mod.add(f);
126 }
127 public void visitBPUTSTATIC(jq_StaticField f) {
128 super.visitBPUTSTATIC(f);
129 f = tryResolve(f);
130 mod.add(f);
131 }
132 public void visitCPUTSTATIC(jq_StaticField f) {
133 super.visitCPUTSTATIC(f);
134 f = tryResolve(f);
135 mod.add(f);
136 }
137 public void visitSPUTSTATIC(jq_StaticField f) {
138 super.visitSPUTSTATIC(f);
139 f = tryResolve(f);
140 mod.add(f);
141 }
142 public void visitIGETFIELD(jq_InstanceField f) {
143 super.visitIGETFIELD(f);
144 f = tryResolve(f);
145 ref.add(f);
146 }
147 public void visitLGETFIELD(jq_InstanceField f) {
148 super.visitLGETFIELD(f);
149 f = tryResolve(f);
150 ref.add(f);
151 }
152 public void visitFGETFIELD(jq_InstanceField f) {
153 super.visitFGETFIELD(f);
154 f = tryResolve(f);
155 ref.add(f);
156 }
157 public void visitDGETFIELD(jq_InstanceField f) {
158 super.visitDGETFIELD(f);
159 f = tryResolve(f);
160 ref.add(f);
161 }
162 public void visitAGETFIELD(jq_InstanceField f) {
163 super.visitAGETFIELD(f);
164 f = tryResolve(f);
165 ref.add(f);
166 }
167 public void visitBGETFIELD(jq_InstanceField f) {
168 super.visitBGETFIELD(f);
169 f = tryResolve(f);
170 ref.add(f);
171 }
172 public void visitCGETFIELD(jq_InstanceField f) {
173 super.visitCGETFIELD(f);
174 f = tryResolve(f);
175 ref.add(f);
176 }
177 public void visitSGETFIELD(jq_InstanceField f) {
178 super.visitSGETFIELD(f);
179 f = tryResolve(f);
180 ref.add(f);
181 }
182 public void visitZGETFIELD(jq_InstanceField f) {
183 super.visitZGETFIELD(f);
184 f = tryResolve(f);
185 ref.add(f);
186 }
187 public void visitIPUTFIELD(jq_InstanceField f) {
188 super.visitIPUTFIELD(f);
189 f = tryResolve(f);
190 mod.add(f);
191 }
192 public void visitLPUTFIELD(jq_InstanceField f) {
193 super.visitLPUTFIELD(f);
194 f = tryResolve(f);
195 mod.add(f);
196 }
197 public void visitFPUTFIELD(jq_InstanceField f) {
198 super.visitFPUTFIELD(f);
199 f = tryResolve(f);
200 mod.add(f);
201 }
202 public void visitDPUTFIELD(jq_InstanceField f) {
203 super.visitDPUTFIELD(f);
204 f = tryResolve(f);
205 mod.add(f);
206 }
207 public void visitAPUTFIELD(jq_InstanceField f) {
208 super.visitAPUTFIELD(f);
209 f = tryResolve(f);
210 mod.add(f);
211 }
212 public void visitBPUTFIELD(jq_InstanceField f) {
213 super.visitBPUTFIELD(f);
214 f = tryResolve(f);
215 mod.add(f);
216 }
217 public void visitCPUTFIELD(jq_InstanceField f) {
218 super.visitCPUTFIELD(f);
219 f = tryResolve(f);
220 mod.add(f);
221 }
222 public void visitSPUTFIELD(jq_InstanceField f) {
223 super.visitSPUTFIELD(f);
224 f = tryResolve(f);
225 mod.add(f);
226 }
227 public void visitZPUTFIELD(jq_InstanceField f) {
228 super.visitZPUTFIELD(f);
229 f = tryResolve(f);
230 mod.add(f);
231 }
232 protected void handleInvoke(jq_Method target) {
233 ModRefAnalysis s = (ModRefAnalysis)results.get(target);
234 if (s == null) {
235 if (INTRA_CLASS) {
236 if (target.getDeclaringClass() != this.method.getDeclaringClass())
237 return;
238 }
239 target.getDeclaringClass().load();
240 if (target.getBytecode() == null) return;
241 s = new ModRefAnalysis(target);
242 results.put(target, s);
243 s.forwardTraversal();
244 }
245 mod.addAll(s.mod);
246 ref.addAll(s.ref);
247 }
248 protected void invokeHelper(byte op, jq_Method f) {
249 f = (jq_Method) tryResolve(f);
250 Iterator i = CallTargets.getTargets(this.method.getDeclaringClass(), f, op, true).iterator();
251 while (i.hasNext()) {
252 jq_Method m = (jq_Method)i.next();
253 handleInvoke(m);
254 }
255 }
256 public void visitIINVOKE(byte op, jq_Method f) {
257 super.visitIINVOKE(op, f);
258 invokeHelper(op, f);
259 }
260 public void visitLINVOKE(byte op, jq_Method f) {
261 super.visitLINVOKE(op, f);
262 invokeHelper(op, f);
263 }
264 public void visitFINVOKE(byte op, jq_Method f) {
265 super.visitFINVOKE(op, f);
266 invokeHelper(op, f);
267 }
268 public void visitDINVOKE(byte op, jq_Method f) {
269 super.visitDINVOKE(op, f);
270 invokeHelper(op, f);
271 }
272 public void visitAINVOKE(byte op, jq_Method f) {
273 super.visitAINVOKE(op, f);
274 invokeHelper(op, f);
275 }
276 public void visitVINVOKE(byte op, jq_Method f) {
277 super.visitVINVOKE(op, f);
278 invokeHelper(op, f);
279 }
280
281 public String toString() {
282 return "Mod: "+mod+Strings.lineSep+"Ref: "+ref;
283 }
284 }