view src/clojure/asm/commons/CodeSizeEvaluator.java @ 10:ef7dbbd6452c

added clojure source goodness
author Robert McIntyre <rlm@mit.edu>
date Sat, 21 Aug 2010 06:25:44 -0400
parents
children
line wrap: on
line source
1 /***
2 * ASM: a very small and fast Java bytecode manipulation framework
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 package clojure.asm.commons;
32 import clojure.asm.Label;
33 import clojure.asm.MethodAdapter;
34 import clojure.asm.MethodVisitor;
35 import clojure.asm.Opcodes;
37 /**
38 * A {@link MethodAdapter} that can be used to approximate method size.
39 *
40 * @author Eugene Kuleshov
41 */
42 public class CodeSizeEvaluator extends MethodAdapter implements Opcodes{
44 private int minSize;
46 private int maxSize;
48 public CodeSizeEvaluator(final MethodVisitor mv){
49 super(mv);
50 }
52 public int getMinSize(){
53 return this.minSize;
54 }
56 public int getMaxSize(){
57 return this.maxSize;
58 }
60 public void visitInsn(final int opcode){
61 minSize += 1;
62 maxSize += 1;
63 if(mv != null)
64 {
65 mv.visitInsn(opcode);
66 }
67 }
69 public void visitIntInsn(final int opcode, final int operand){
70 if(opcode == SIPUSH)
71 {
72 minSize += 3;
73 maxSize += 3;
74 }
75 else
76 {
77 minSize += 2;
78 maxSize += 2;
79 }
80 if(mv != null)
81 {
82 mv.visitIntInsn(opcode, operand);
83 }
84 }
86 public void visitVarInsn(final int opcode, final int var){
87 if(var < 4 && opcode != Opcodes.RET)
88 {
89 minSize += 1;
90 maxSize += 1;
91 }
92 else if(var >= 256)
93 {
94 minSize += 4;
95 maxSize += 4;
96 }
97 else
98 {
99 minSize += 2;
100 maxSize += 2;
101 }
102 if(mv != null)
103 {
104 mv.visitVarInsn(opcode, var);
105 }
106 }
108 public void visitTypeInsn(final int opcode, final String desc){
109 minSize += 3;
110 maxSize += 3;
111 if(mv != null)
112 {
113 mv.visitTypeInsn(opcode, desc);
114 }
115 }
117 public void visitFieldInsn(
118 final int opcode,
119 final String owner,
120 final String name,
121 final String desc){
122 minSize += 3;
123 maxSize += 3;
124 if(mv != null)
125 {
126 mv.visitFieldInsn(opcode, owner, name, desc);
127 }
128 }
130 public void visitMethodInsn(
131 final int opcode,
132 final String owner,
133 final String name,
134 final String desc){
135 if(opcode == INVOKEINTERFACE)
136 {
137 minSize += 5;
138 maxSize += 5;
139 }
140 else
141 {
142 minSize += 3;
143 maxSize += 3;
144 }
145 if(mv != null)
146 {
147 mv.visitMethodInsn(opcode, owner, name, desc);
148 }
149 }
151 public void visitJumpInsn(final int opcode, final Label label){
152 minSize += 3;
153 if(opcode == GOTO || opcode == JSR)
154 {
155 maxSize += 5;
156 }
157 else
158 {
159 maxSize += 8;
160 }
161 if(mv != null)
162 {
163 mv.visitJumpInsn(opcode, label);
164 }
165 }
167 public void visitLdcInsn(final Object cst){
168 if(cst instanceof Long || cst instanceof Double)
169 {
170 minSize += 3;
171 maxSize += 3;
172 }
173 else
174 {
175 minSize += 2;
176 maxSize += 3;
177 }
178 if(mv != null)
179 {
180 mv.visitLdcInsn(cst);
181 }
182 }
184 public void visitIincInsn(final int var, final int increment){
185 if(var > 255 || increment > 127 || increment < -128)
186 {
187 minSize += 6;
188 maxSize += 6;
189 }
190 else
191 {
192 minSize += 3;
193 maxSize += 3;
194 }
195 if(mv != null)
196 {
197 mv.visitIincInsn(var, increment);
198 }
199 }
201 public void visitTableSwitchInsn(
202 final int min,
203 final int max,
204 final Label dflt,
205 final Label[] labels){
206 minSize += 13 + labels.length * 4;
207 maxSize += 16 + labels.length * 4;
208 if(mv != null)
209 {
210 mv.visitTableSwitchInsn(min, max, dflt, labels);
211 }
212 }
214 public void visitLookupSwitchInsn(
215 final Label dflt,
216 final int[] keys,
217 final Label[] labels){
218 minSize += 9 + keys.length * 8;
219 maxSize += 12 + keys.length * 8;
220 if(mv != null)
221 {
222 mv.visitLookupSwitchInsn(dflt, keys, labels);
223 }
224 }
226 public void visitMultiANewArrayInsn(final String desc, final int dims){
227 minSize += 4;
228 maxSize += 4;
229 if(mv != null)
230 {
231 mv.visitMultiANewArrayInsn(desc, dims);
232 }
233 }
234 }