View Javadoc

1   // ModRefAnalysis.java, created Thu Feb 14 18:09:11 2002 by joewhaley
2   // Copyright (C) 2001-3 John Whaley <jwhaley@alum.mit.edu>
3   // Licensed under the terms of the GNU LGPL; see COPYING for details.
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 }