KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > Analysis


1 /***
2  * ASM examples: examples showing how ASM can be used
3  * Copyright (c) 2000-2005 INRIA, France Telecom
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  * notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  * notice, this list of conditions and the following disclaimer in the
13  * documentation and/or other materials provided with the distribution.
14  * 3. Neither the name of the copyright holders nor the names of its
15  * contributors may be used to endorse or promote products derived from
16  * this software without specific prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
22  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
28  * THE POSSIBILITY OF SUCH DAMAGE.
29  */

30 import java.util.HashSet JavaDoc;
31 import java.util.Iterator JavaDoc;
32 import java.util.List JavaDoc;
33 import java.util.Set JavaDoc;
34
35 import org.objectweb.asm.ClassReader;
36 import org.objectweb.asm.Opcodes;
37 import org.objectweb.asm.tree.AbstractInsnNode;
38 import org.objectweb.asm.tree.ClassNode;
39 import org.objectweb.asm.tree.IincInsnNode;
40 import org.objectweb.asm.tree.MethodNode;
41 import org.objectweb.asm.tree.VarInsnNode;
42 import org.objectweb.asm.tree.analysis.Analyzer;
43 import org.objectweb.asm.tree.analysis.BasicVerifier;
44 import org.objectweb.asm.tree.analysis.SourceInterpreter;
45 import org.objectweb.asm.tree.analysis.SourceValue;
46 import org.objectweb.asm.tree.analysis.Frame;
47 import org.objectweb.asm.util.TraceMethodVisitor;
48
49 /**
50  * @author Eric Bruneton
51  */

52 public class Analysis implements Opcodes {
53
54     public static void main(final String JavaDoc[] args) throws Exception JavaDoc {
55         ClassReader cr = new ClassReader("Analysis");
56         ClassNode cn = new ClassNode();
57         cr.accept(cn, ClassReader.SKIP_DEBUG);
58
59         List JavaDoc methods = cn.methods;
60         for (int i = 0; i < methods.size(); ++i) {
61             MethodNode method = (MethodNode) methods.get(i);
62             if (method.instructions.size() > 0) {
63                 if (!analyze(cn, method)) {
64                     Analyzer a = new Analyzer(new BasicVerifier());
65                     try {
66                         a.analyze(cn.name, method);
67                     } catch (Exception JavaDoc ignored) {
68                     }
69                     final Frame[] frames = a.getFrames();
70
71                     TraceMethodVisitor mv = new TraceMethodVisitor() {
72                         public void visitMaxs(
73                             final int maxStack,
74                             final int maxLocals)
75                         {
76                             for (int i = 0; i < text.size(); ++i) {
77                                 String JavaDoc s = frames[i] == null
78                                         ? "null"
79                                         : frames[i].toString();
80                                 while (s.length() < Math.max(20, maxStack
81                                         + maxLocals + 1))
82                                 {
83                                     s += " ";
84                                 }
85                                 System.err.print(Integer.toString(i + 1000)
86                                         .substring(1)
87                                         + " " + s + " : " + text.get(i));
88                             }
89                             System.err.println();
90                         }
91                     };
92                     for (int j = 0; j < method.instructions.size(); ++j) {
93                         Object JavaDoc insn = method.instructions.get(j);
94                         ((AbstractInsnNode) insn).accept(mv);
95                     }
96                     mv.visitMaxs(0, 0);
97                 }
98             }
99         }
100     }
101
102     /*
103      * Detects unused xSTORE instructions, i.e. xSTORE instructions without at
104      * least one xLOAD corresponding instruction in their successor instructions
105      * (in the control flow graph).
106      */

107     public static boolean analyze(final ClassNode c, final MethodNode m)
108             throws Exception JavaDoc
109     {
110         Analyzer a = new Analyzer(new SourceInterpreter());
111         Frame[] frames = a.analyze(c.name, m);
112
113         // for each xLOAD instruction, we find the xSTORE instructions that can
114
// produce the value loaded by this instruction, and we put them in
115
// 'stores'
116
Set JavaDoc stores = new HashSet JavaDoc();
117         for (int i = 0; i < m.instructions.size(); ++i) {
118             Object JavaDoc insn = m.instructions.get(i);
119             int opcode = ((AbstractInsnNode) insn).getOpcode();
120             if ((opcode >= ILOAD && opcode <= ALOAD) || opcode == IINC) {
121                 int var = opcode == IINC
122                         ? ((IincInsnNode) insn).var
123                         : ((VarInsnNode) insn).var;
124                 Frame f = frames[i];
125                 if (f != null) {
126                     Set JavaDoc s = ((SourceValue) f.getLocal(var)).insns;
127                     Iterator JavaDoc j = s.iterator();
128                     while (j.hasNext()) {
129                         insn = j.next();
130                         if (insn instanceof VarInsnNode) {
131                             stores.add(insn);
132                         }
133                     }
134                 }
135             }
136         }
137
138         // we then find all the xSTORE instructions that are not in 'stores'
139
boolean ok = true;
140         for (int i = 0; i < m.instructions.size(); ++i) {
141             Object JavaDoc insn = m.instructions.get(i);
142             if (insn instanceof AbstractInsnNode) {
143                 int opcode = ((AbstractInsnNode) insn).getOpcode();
144                 if (opcode >= ISTORE && opcode <= ASTORE) {
145                     if (!stores.contains(insn)) {
146                         ok = false;
147                         System.err.println("method " + m.name
148                                 + ", instruction " + i
149                                 + ": useless store instruction");
150                     }
151                 }
152             }
153         }
154         return ok;
155     }
156
157     /*
158      * Test for the above method, with three useless xSTORE instructions.
159      */

160     public int test(int i, int j) {
161         i = i + 1; // ok, because i can be read after this point
162

163         if (j == 0) {
164             j = 1; // useless
165
} else {
166             try {
167                 j = j - 1; // ok, because j can be accessed in the catch
168
int k = 0;
169                 if (i > 0) {
170                     k = i - 1;
171                 }
172                 return k;
173             } catch (Exception JavaDoc e) { // useless ASTORE (e is never used)
174
j = j + 1; // useless
175
}
176         }
177
178         return 0;
179     }
180 }
181
Popular Tags