KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > hansel > HanselCodeAdapter


1 package org.hansel;
2
3 import static org.objectweb.asm.Opcodes.ALOAD;
4 import static org.objectweb.asm.Opcodes.ASTORE;
5 import static org.objectweb.asm.Opcodes.ATHROW;
6 import static org.objectweb.asm.Opcodes.MONITOREXIT;
7
8 import java.util.Iterator JavaDoc;
9 import java.util.List JavaDoc;
10 import java.util.Vector JavaDoc;
11
12 import org.objectweb.asm.Label;
13 import org.objectweb.asm.MethodAdapter;
14 import org.objectweb.asm.MethodVisitor;
15 import org.objectweb.asm.Opcodes;
16 import org.objectweb.asm.tree.AbstractInsnNode;
17 import org.objectweb.asm.tree.InsnList;
18 import org.objectweb.asm.tree.LabelNode;
19 import org.objectweb.asm.tree.LineNumberNode;
20 import org.objectweb.asm.tree.TryCatchBlockNode;
21
22 public class HanselCodeAdapter extends MethodAdapter {
23     private boolean first;
24     private int pos;
25     private InsnList instructions;
26     private String JavaDoc className;
27     private String JavaDoc methodName;
28     private HanselFrame[] frames;
29     private List JavaDoc<Probe> probes;
30     private List JavaDoc tryCatchBlocks;
31     private Probe methodProbe;
32     private int access;
33     private ClassLoader JavaDoc loader;
34     
35     public HanselCodeAdapter(int access, String JavaDoc className,
36             String JavaDoc methodName, InsnList instructions, List JavaDoc tryCatchBlocks, MethodVisitor mv,
37             HanselFrame[] frames, ClassLoader JavaDoc loader) {
38         super(mv);
39         
40         this.access = access;
41         this.first = true;
42         this.pos = 0;
43         this.instructions = instructions;
44         this.className = className;
45         this.methodName = methodName;
46         this.frames = frames;
47         this.probes = new Vector JavaDoc<Probe>();
48         this.tryCatchBlocks = tryCatchBlocks;
49         this.loader = loader;
50     }
51     
52     private void addProbe(Probe probe) {
53         probe.insertProbeCode(mv);
54         probes.add(probe);
55     }
56     
57     private void checkFirst() {
58         //System.out.println(pos + " -> " + instructions.get(pos) + " : " +
59
// Thread.currentThread().getStackTrace()[3].getMethodName());
60
pos++;
61                
62         
63         if (!first) {
64             return;
65         }
66         first = false;
67         
68         if (!isEmptyPrivateConstructor() && !isStaticConstructor()) {
69             methodProbe = ProbeFactory.createMethodProbe(getProbeData());
70             addProbe(methodProbe);
71         }
72     }
73     
74     private boolean isEmptyPrivateConstructor() {
75         return "<init>".equals(methodName) &&
76         ((access & Opcodes.ACC_PRIVATE) > 0) &&
77         countRelevantInstructions(instructions) == 3;
78     }
79     
80     private int countRelevantInstructions(InsnList instructions) {
81         int count = 0;
82         for (AbstractInsnNode node : instructions.toArray()) {
83             if (!(node instanceof LineNumberNode) &&
84                     !(node instanceof LabelNode)) {
85                 count++;
86             }
87         }
88         return count;
89     }
90
91     private boolean isStaticConstructor() {
92         return "<clinit>".equals(methodName);
93     }
94     
95     private ProbeData getProbeData() {
96         return new ProbeData(
97                 className,
98                 methodName,
99                 frames[pos - 1],
100                 pos,
101                 instructions.size(),
102                 loader);
103     }
104     
105     public void visitLineNumber(int line, Label start) {
106         super.visitLineNumber(line, start);
107         checkFirst();
108         
109         
110         int startIndex = Util.findIndex(instructions, start);
111         
112         
113         for (int i=0; i<probes.size(); i++) {
114             ProbeData pd = probes.get(i).getProbeData();
115             if (startIndex < pd.getPosition()) {
116                 pd.setLineNumber(line);
117             }
118         }
119     }
120     
121     public void visitInsn(final int opcode) {
122         checkFirst();
123         
124         mv.visitInsn(opcode);
125     }
126     
127     public void visitIntInsn(final int opcode, final int operand) {
128         checkFirst();
129         
130         mv.visitIntInsn(opcode, operand);
131     }
132     
133     public void visitVarInsn(final int opcode, final int var) {
134         checkFirst();
135         
136         mv.visitVarInsn(opcode, var);
137     }
138     
139     public void visitFieldInsn(final int opcode,
140             final String JavaDoc owner,
141             final String JavaDoc name,
142             final String JavaDoc desc) {
143         checkFirst();
144         
145         mv.visitFieldInsn(opcode, owner, name, desc);
146     }
147     
148     public void visitMethodInsn(final int opcode,
149             final String JavaDoc owner,
150             final String JavaDoc name,
151             final String JavaDoc desc) {
152         checkFirst();
153         
154         mv.visitMethodInsn(opcode, owner, name, desc);
155     }
156     
157     public void visitJumpInsn(final int opcode, final Label label) {
158         checkFirst();
159         
160         if (opcode != Opcodes.GOTO) {
161             addProbe(ProbeFactory.createBranchProbe(getProbeData(),
162                     opcode));
163         }
164         
165         mv.visitJumpInsn(opcode, label);
166     }
167     
168     public void visitLabel(final Label label) {
169         //System.out.println(pos + " -> " + instructions.get(pos) + " : visitLabel");
170

171         pos++;
172         
173         mv.visitLabel(label);
174         
175         if (isExceptionHandler(label) && !isMonitorExitHandler()) {
176             addProbe(ProbeFactory.createExceptionProbe(getProbeData(),
177                     methodProbe));
178         }
179     }
180     
181     private boolean isMonitorExitHandler() {
182         if (instructions.size() < pos + 6) {
183             return false;
184         }
185         
186         if (!isOpcode(pos, ASTORE)) {
187             return false;
188         }
189         
190         if (!isOpcode(pos + 1, ALOAD)) {
191             return false;
192         }
193         
194         if (!isOpcode(pos + 2, MONITOREXIT)) {
195             return false;
196         }
197         
198         if (!isLabel(pos + 3)) {
199             return false;
200         }
201         
202         if (!isOpcode(pos + 4, ALOAD)) {
203             return false;
204         }
205         
206         if (!isOpcode(pos + 5, ATHROW)) {
207             return false;
208         }
209         return true;
210     }
211     
212     private boolean isLabel(int pos) {
213         return (instructions.get(pos) instanceof LabelNode);
214     }
215     
216     private boolean isOpcode(int pos, int opcode) {
217         return (instructions.get(pos) instanceof AbstractInsnNode)
218         && (((AbstractInsnNode) instructions.get(pos)).getOpcode() == opcode);
219     }
220     
221     private boolean isExceptionHandler(Label l) {
222         Iterator JavaDoc it = tryCatchBlocks.iterator();
223         while (it.hasNext()) {
224             TryCatchBlockNode tryCatchBlockNode = ((TryCatchBlockNode) it.next());
225             if (tryCatchBlockNode.handler.getLabel() == l &&
226                     (tryCatchBlockNode.type != null)) {
227                 return true;
228             }
229         }
230         
231         return false;
232     }
233     
234     public void visitLdcInsn(final Object JavaDoc cst) {
235         checkFirst();
236         
237         mv.visitLdcInsn(cst);
238     }
239     
240     public void visitIincInsn(final int var, final int increment) {
241         checkFirst();
242         
243         mv.visitIincInsn(var, increment);
244     }
245     
246     public void visitTableSwitchInsn(final int min,
247             final int max,
248             final Label dflt,
249             final Label labels[]) {
250         checkFirst();
251         
252         addProbe(ProbeFactory.createSelectProbe(getProbeData(),
253                 min, max, dflt, labels));
254         
255         mv.visitTableSwitchInsn(min, max, dflt, labels);
256     }
257     
258     public void visitLookupSwitchInsn(final Label dflt,
259             final int keys[],
260             final Label labels[]) {
261         checkFirst();
262         
263         addProbe(ProbeFactory.createSelectProbe(getProbeData(),
264                 dflt, keys, labels));
265         
266         mv.visitLookupSwitchInsn(dflt, keys, labels);
267     }
268     
269     public void visitMultiANewArrayInsn(final String JavaDoc desc, final int dims) {
270         checkFirst();
271         
272         mv.visitMultiANewArrayInsn(desc, dims);
273     }
274     
275     public void visitTryCatchBlock(final Label start, final Label end,
276             final Label handler, final String JavaDoc type) {
277         //checkFirst();
278

279         mv.visitTryCatchBlock(start, end, handler, type);
280     }
281     
282     public void visitTypeInsn(int param, String JavaDoc str) {
283         checkFirst();
284         
285         super.visitTypeInsn(param, str);
286     }
287     
288     public void visitAttribute(org.objectweb.asm.Attribute attribute) {
289         checkFirst();
290         
291         super.visitAttribute(attribute);
292     }
293     
294     public void visitMaxs(int param, int param1) {
295         //checkFirst();
296

297         super.visitMaxs(param, param1);
298     }
299
300     @Override JavaDoc
301     public void visitFrame(int type, int nLocal, Object JavaDoc[] local, int nStack, Object JavaDoc[] stack) {
302         checkFirst();
303         
304         super.visitFrame(type, nLocal, local, nStack, stack);
305     }
306
307     @Override JavaDoc
308     public void visitEnd() {
309         super.visitEnd();
310         
311         if (pos != frames.length) {
312             throw new IllegalStateException JavaDoc("Inconsistent instrumentation: "
313                     + pos + " != " + frames.length);
314         }
315     }
316     
317     
318 }
319
Popular Tags