001: /***
002: * ASM: a very small and fast Java bytecode manipulation framework
003: * Copyright (c) 2000-2005 INRIA, France Telecom
004: * All rights reserved.
005: *
006: * Redistribution and use in source and binary forms, with or without
007: * modification, are permitted provided that the following conditions
008: * are met:
009: * 1. Redistributions of source code must retain the above copyright
010: * notice, this list of conditions and the following disclaimer.
011: * 2. Redistributions in binary form must reproduce the above copyright
012: * notice, this list of conditions and the following disclaimer in the
013: * documentation and/or other materials provided with the distribution.
014: * 3. Neither the name of the copyright holders nor the names of its
015: * contributors may be used to endorse or promote products derived from
016: * this software without specific prior written permission.
017: *
018: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
019: * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
020: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
021: * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
022: * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
023: * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
024: * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
025: * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
026: * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
027: * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
028: * THE POSSIBILITY OF SUCH DAMAGE.
029: */package org.objectweb.asm.commons;
030:
031: import org.objectweb.asm.Label;
032: import org.objectweb.asm.MethodAdapter;
033: import org.objectweb.asm.MethodVisitor;
034: import org.objectweb.asm.Opcodes;
035:
036: /**
037: * A {@link MethodAdapter} that can be used to approximate method size.
038: *
039: * @author Eugene Kuleshov
040: */
041: public class CodeSizeEvaluator extends MethodAdapter implements Opcodes {
042:
043: private int minSize;
044:
045: private int maxSize;
046:
047: public CodeSizeEvaluator(final MethodVisitor mv) {
048: super (mv);
049: }
050:
051: public int getMinSize() {
052: return this .minSize;
053: }
054:
055: public int getMaxSize() {
056: return this .maxSize;
057: }
058:
059: @Override
060: public void visitInsn(final int opcode) {
061: minSize += 1;
062: maxSize += 1;
063: if (mv != null) {
064: mv.visitInsn(opcode);
065: }
066: }
067:
068: @Override
069: public void visitIntInsn(final int opcode, final int operand) {
070: if (opcode == SIPUSH) {
071: minSize += 3;
072: maxSize += 3;
073: } else {
074: minSize += 2;
075: maxSize += 2;
076: }
077: if (mv != null) {
078: mv.visitIntInsn(opcode, operand);
079: }
080: }
081:
082: @Override
083: public void visitVarInsn(final int opcode, final int var) {
084: if (var < 4 && opcode != Opcodes.RET) {
085: minSize += 1;
086: maxSize += 1;
087: } else if (var >= 256) {
088: minSize += 4;
089: maxSize += 4;
090: } else {
091: minSize += 2;
092: maxSize += 2;
093: }
094: if (mv != null) {
095: mv.visitVarInsn(opcode, var);
096: }
097: }
098:
099: @Override
100: public void visitTypeInsn(final int opcode, final String desc) {
101: minSize += 3;
102: maxSize += 3;
103: if (mv != null) {
104: mv.visitTypeInsn(opcode, desc);
105: }
106: }
107:
108: @Override
109: public void visitFieldInsn(final int opcode, final String owner,
110: final String name, final String desc) {
111: minSize += 3;
112: maxSize += 3;
113: if (mv != null) {
114: mv.visitFieldInsn(opcode, owner, name, desc);
115: }
116: }
117:
118: @Override
119: public void visitMethodInsn(final int opcode, final String owner,
120: final String name, final String desc) {
121: if (opcode == INVOKEINTERFACE) {
122: minSize += 5;
123: maxSize += 5;
124: } else {
125: minSize += 3;
126: maxSize += 3;
127: }
128: if (mv != null) {
129: mv.visitMethodInsn(opcode, owner, name, desc);
130: }
131: }
132:
133: @Override
134: public void visitJumpInsn(final int opcode, final Label label) {
135: minSize += 3;
136: if (opcode == GOTO || opcode == JSR) {
137: maxSize += 5;
138: } else {
139: maxSize += 8;
140: }
141: if (mv != null) {
142: mv.visitJumpInsn(opcode, label);
143: }
144: }
145:
146: @Override
147: public void visitLdcInsn(final Object cst) {
148: if (cst instanceof Long || cst instanceof Double) {
149: minSize += 3;
150: maxSize += 3;
151: } else {
152: minSize += 2;
153: maxSize += 3;
154: }
155: if (mv != null) {
156: mv.visitLdcInsn(cst);
157: }
158: }
159:
160: @Override
161: public void visitIincInsn(final int var, final int increment) {
162: if (var > 255 || increment > 127 || increment < -128) {
163: minSize += 6;
164: maxSize += 6;
165: } else {
166: minSize += 3;
167: maxSize += 3;
168: }
169: if (mv != null) {
170: mv.visitIincInsn(var, increment);
171: }
172: }
173:
174: @Override
175: public void visitTableSwitchInsn(final int min, final int max,
176: final Label dflt, final Label[] labels) {
177: minSize += 13 + labels.length * 4;
178: maxSize += 16 + labels.length * 4;
179: if (mv != null) {
180: mv.visitTableSwitchInsn(min, max, dflt, labels);
181: }
182: }
183:
184: @Override
185: public void visitLookupSwitchInsn(final Label dflt,
186: final int[] keys, final Label[] labels) {
187: minSize += 9 + keys.length * 8;
188: maxSize += 12 + keys.length * 8;
189: if (mv != null) {
190: mv.visitLookupSwitchInsn(dflt, keys, labels);
191: }
192: }
193:
194: @Override
195: public void visitMultiANewArrayInsn(final String desc,
196: final int dims) {
197: minSize += 4;
198: maxSize += 4;
199: if (mv != null) {
200: mv.visitMultiANewArrayInsn(desc, dims);
201: }
202: }
203: }
|