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 com.tc.asm.commons;
030:
031: import com.tc.asm.Label;
032: import com.tc.asm.MethodAdapter;
033: import com.tc.asm.MethodVisitor;
034: import com.tc.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: public void visitInsn(final int opcode) {
060: minSize += 1;
061: maxSize += 1;
062: if (mv != null) {
063: mv.visitInsn(opcode);
064: }
065: }
066:
067: public void visitIntInsn(final int opcode, final int operand) {
068: if (opcode == SIPUSH) {
069: minSize += 3;
070: maxSize += 3;
071: } else {
072: minSize += 2;
073: maxSize += 2;
074: }
075: if (mv != null) {
076: mv.visitIntInsn(opcode, operand);
077: }
078: }
079:
080: public void visitVarInsn(final int opcode, final int var) {
081: if (var < 4 && opcode != Opcodes.RET) {
082: minSize += 1;
083: maxSize += 1;
084: } else if (var >= 256) {
085: minSize += 4;
086: maxSize += 4;
087: } else {
088: minSize += 2;
089: maxSize += 2;
090: }
091: if (mv != null) {
092: mv.visitVarInsn(opcode, var);
093: }
094: }
095:
096: public void visitTypeInsn(final int opcode, final String desc) {
097: minSize += 3;
098: maxSize += 3;
099: if (mv != null) {
100: mv.visitTypeInsn(opcode, desc);
101: }
102: }
103:
104: public void visitFieldInsn(final int opcode, final String owner,
105: final String name, final String desc) {
106: minSize += 3;
107: maxSize += 3;
108: if (mv != null) {
109: mv.visitFieldInsn(opcode, owner, name, desc);
110: }
111: }
112:
113: public void visitMethodInsn(final int opcode, final String owner,
114: final String name, final String desc) {
115: if (opcode == INVOKEINTERFACE) {
116: minSize += 5;
117: maxSize += 5;
118: } else {
119: minSize += 3;
120: maxSize += 3;
121: }
122: if (mv != null) {
123: mv.visitMethodInsn(opcode, owner, name, desc);
124: }
125: }
126:
127: public void visitJumpInsn(final int opcode, final Label label) {
128: minSize += 3;
129: if (opcode == GOTO || opcode == JSR) {
130: maxSize += 5;
131: } else {
132: maxSize += 8;
133: }
134: if (mv != null) {
135: mv.visitJumpInsn(opcode, label);
136: }
137: }
138:
139: public void visitLdcInsn(final Object cst) {
140: if (cst instanceof Long || cst instanceof Double) {
141: minSize += 3;
142: maxSize += 3;
143: } else {
144: minSize += 2;
145: maxSize += 3;
146: }
147: if (mv != null) {
148: mv.visitLdcInsn(cst);
149: }
150: }
151:
152: public void visitIincInsn(final int var, final int increment) {
153: if (var > 255 || increment > 127 || increment < -128) {
154: minSize += 6;
155: maxSize += 6;
156: } else {
157: minSize += 3;
158: maxSize += 3;
159: }
160: if (mv != null) {
161: mv.visitIincInsn(var, increment);
162: }
163: }
164:
165: public void visitTableSwitchInsn(final int min, final int max,
166: final Label dflt, final Label[] labels) {
167: minSize += 13 + labels.length * 4;
168: maxSize += 16 + labels.length * 4;
169: if (mv != null) {
170: mv.visitTableSwitchInsn(min, max, dflt, labels);
171: }
172: }
173:
174: public void visitLookupSwitchInsn(final Label dflt,
175: final int[] keys, final Label[] labels) {
176: minSize += 9 + keys.length * 8;
177: maxSize += 12 + keys.length * 8;
178: if (mv != null) {
179: mv.visitLookupSwitchInsn(dflt, keys, labels);
180: }
181: }
182:
183: public void visitMultiANewArrayInsn(final String desc,
184: final int dims) {
185: minSize += 4;
186: maxSize += 4;
187: if (mv != null) {
188: mv.visitMultiANewArrayInsn(desc, dims);
189: }
190: }
191: }
|