You are viewing a plain text version of this content. The canonical link for it is here.
Posted to bcel-dev@jakarta.apache.org by tc...@apache.org on 2008/02/02 22:06:08 UTC
svn commit: r617895 - in /jakarta/bcel/trunk/src:
main/java/org/apache/bcel/generic/ test/java/org/apache/bcel/
Author: tcurdt
Date: Sat Feb 2 13:06:04 2008
New Revision: 617895
URL: http://svn.apache.org/viewvc?rev=617895&view=rev
Log:
performance improvements submitted by markus.gaisbauer@gmail.com
http://issues.apache.org/bugzilla/show_bug.cgi?id=44340
Added:
jakarta/bcel/trunk/src/test/java/org/apache/bcel/NanoTimer.java (with props)
jakarta/bcel/trunk/src/test/java/org/apache/bcel/PerformanceTest.java (with props)
Modified:
jakarta/bcel/trunk/src/main/java/org/apache/bcel/generic/ConstantPoolGen.java
jakarta/bcel/trunk/src/main/java/org/apache/bcel/generic/FieldInstruction.java
jakarta/bcel/trunk/src/main/java/org/apache/bcel/generic/Instruction.java
jakarta/bcel/trunk/src/main/java/org/apache/bcel/generic/InstructionList.java
jakarta/bcel/trunk/src/main/java/org/apache/bcel/generic/InvokeInstruction.java
jakarta/bcel/trunk/src/main/java/org/apache/bcel/generic/Type.java
Modified: jakarta/bcel/trunk/src/main/java/org/apache/bcel/generic/ConstantPoolGen.java
URL: http://svn.apache.org/viewvc/jakarta/bcel/trunk/src/main/java/org/apache/bcel/generic/ConstantPoolGen.java?rev=617895&r1=617894&r2=617895&view=diff
==============================================================================
--- jakarta/bcel/trunk/src/main/java/org/apache/bcel/generic/ConstantPoolGen.java (original)
+++ jakarta/bcel/trunk/src/main/java/org/apache/bcel/generic/ConstantPoolGen.java Sat Feb 2 13:06:04 2008
@@ -50,8 +50,8 @@
*/
public class ConstantPoolGen implements java.io.Serializable {
- protected int size = 1024; // Inital size, sufficient in most cases
- protected Constant[] constants = new Constant[size];
+ protected int size;
+ protected Constant[] constants;
protected int index = 1; // First entry (0) used by JVM
private static final String METHODREF_DELIM = ":";
private static final String IMETHODREF_DELIM = "#";
@@ -75,14 +75,17 @@
* @param cs array of given constants, new ones will be appended
*/
public ConstantPoolGen(Constant[] cs) {
- if (cs.length > size) {
- size = cs.length;
- constants = new Constant[size];
- }
+ StringBuffer sb = new StringBuffer(256);
+
+ size = Math.max(256, cs.length + 64);
+ constants = new Constant[size];
+
System.arraycopy(cs, 0, constants, 0, cs.length);
if (cs.length > 0) {
index = cs.length;
}
+
+
for (int i = 1; i < index; i++) {
Constant c = constants[i];
if (c instanceof ConstantString) {
@@ -103,7 +106,13 @@
ConstantNameAndType n = (ConstantNameAndType) c;
ConstantUtf8 u8 = (ConstantUtf8) constants[n.getNameIndex()];
ConstantUtf8 u8_2 = (ConstantUtf8) constants[n.getSignatureIndex()];
- String key = u8.getBytes() + NAT_DELIM + u8_2.getBytes();
+
+ sb.append(u8.getBytes());
+ sb.append(NAT_DELIM);
+ sb.append(u8_2.getBytes());
+ String key = sb.toString();
+ sb.delete(0, sb.length());
+
if (!n_a_t_table.containsKey(key)) {
n_a_t_table.put(key, new Index(i));
}
@@ -129,7 +138,15 @@
} else if (c instanceof ConstantFieldref) {
delim = FIELDREF_DELIM;
}
- String key = class_name + delim + method_name + delim + signature;
+
+ sb.append(class_name);
+ sb.append(delim);
+ sb.append(method_name);
+ sb.append(delim);
+ sb.append(signature);
+ String key = sb.toString();
+ sb.delete(0, sb.length());
+
if (!cp_table.containsKey(key)) {
cp_table.put(key, new Index(i));
}
@@ -150,6 +167,8 @@
* Create empty constant pool.
*/
public ConstantPoolGen() {
+ size = 256;
+ constants = new Constant[size];
}
Modified: jakarta/bcel/trunk/src/main/java/org/apache/bcel/generic/FieldInstruction.java
URL: http://svn.apache.org/viewvc/jakarta/bcel/trunk/src/main/java/org/apache/bcel/generic/FieldInstruction.java?rev=617895&r1=617894&r2=617895&view=diff
==============================================================================
--- jakarta/bcel/trunk/src/main/java/org/apache/bcel/generic/FieldInstruction.java (original)
+++ jakarta/bcel/trunk/src/main/java/org/apache/bcel/generic/FieldInstruction.java Sat Feb 2 13:06:04 2008
@@ -54,7 +54,7 @@
/** @return size of field (1 or 2)
*/
protected int getFieldSize( ConstantPoolGen cpg ) {
- return getType(cpg).getSize();
+ return Type.getTypeSize(getSignature(cpg));
}
Modified: jakarta/bcel/trunk/src/main/java/org/apache/bcel/generic/Instruction.java
URL: http://svn.apache.org/viewvc/jakarta/bcel/trunk/src/main/java/org/apache/bcel/generic/Instruction.java?rev=617895&r1=617894&r2=617895&view=diff
==============================================================================
--- jakarta/bcel/trunk/src/main/java/org/apache/bcel/generic/Instruction.java (original)
+++ jakarta/bcel/trunk/src/main/java/org/apache/bcel/generic/Instruction.java Sat Feb 2 13:06:04 2008
@@ -153,53 +153,309 @@
if (InstructionConstants.INSTRUCTIONS[opcode] != null) {
return InstructionConstants.INSTRUCTIONS[opcode]; // Used predefined immutable object, if available
}
- /* Find appropiate class, instantiate an (empty) instruction object
- * and initialize it by hand.
- */
- Class clazz;
- try {
- clazz = Class.forName(className(opcode));
- } catch (ClassNotFoundException cnfe) {
- // If a class by that name does not exist, the opcode is illegal.
- // Note that IMPDEP1, IMPDEP2, BREAKPOINT are also illegal in a sense.
- throw new ClassGenException("Illegal opcode detected.");
- }
- try {
- obj = (Instruction) clazz.newInstance();
- if (wide
- && !((obj instanceof LocalVariableInstruction) || (obj instanceof IINC) || (obj instanceof RET))) {
- throw new Exception("Illegal opcode after wide: " + opcode);
- }
- obj.setOpcode(opcode);
- obj.initFromFile(bytes, wide); // Do further initializations, if any
- // Byte code offset set in InstructionList
- } catch (Exception e) {
- throw new ClassGenException(e.toString());
- }
- return obj;
- }
-
-
- private static final String className( short opcode ) {
- String name = Constants.OPCODE_NAMES[opcode].toUpperCase(Locale.ENGLISH);
- /* ICONST_0, etc. will be shortened to ICONST, etc., since ICONST_0 and the like
- * are not implemented (directly).
- */
- try {
- int len = name.length();
- char ch1 = name.charAt(len - 2), ch2 = name.charAt(len - 1);
- if ((ch1 == '_') && (ch2 >= '0') && (ch2 <= '5')) {
- name = name.substring(0, len - 2);
- }
- if (name.equals("ICONST_M1")) {
- name = "ICONST";
- }
- } catch (StringIndexOutOfBoundsException e) {
- System.err.println(e);
- }
- return "org.apache.bcel.generic." + name;
- }
+
+ switch (opcode) {
+ case Constants.BIPUSH:
+ obj = new BIPUSH();
+ break;
+ case Constants.SIPUSH:
+ obj = new SIPUSH();
+ break;
+ case Constants.LDC:
+ obj = new LDC();
+ break;
+ case Constants.LDC_W:
+ obj = new LDC_W();
+ break;
+ case Constants.LDC2_W:
+ obj = new LDC2_W();
+ break;
+ case Constants.ILOAD:
+ obj = new ILOAD();
+ break;
+ case Constants.LLOAD:
+ obj = new LLOAD();
+ break;
+ case Constants.FLOAD:
+ obj = new FLOAD();
+ break;
+ case Constants.DLOAD:
+ obj = new DLOAD();
+ break;
+ case Constants.ALOAD:
+ obj = new ALOAD();
+ break;
+ case Constants.ILOAD_0:
+ obj = new ILOAD(0);
+ break;
+ case Constants.ILOAD_1:
+ obj = new ILOAD(1);
+ break;
+ case Constants.ILOAD_2:
+ obj = new ILOAD(2);
+ break;
+ case Constants.ILOAD_3:
+ obj = new ILOAD(3);
+ break;
+ case Constants.LLOAD_0:
+ obj = new LLOAD(0);
+ break;
+ case Constants.LLOAD_1:
+ obj = new LLOAD(1);
+ break;
+ case Constants.LLOAD_2:
+ obj = new LLOAD(2);
+ break;
+ case Constants.LLOAD_3:
+ obj = new LLOAD(3);
+ break;
+ case Constants.FLOAD_0:
+ obj = new FLOAD(0);
+ break;
+ case Constants.FLOAD_1:
+ obj = new FLOAD(1);
+ break;
+ case Constants.FLOAD_2:
+ obj = new FLOAD(2);
+ break;
+ case Constants.FLOAD_3:
+ obj = new FLOAD(3);
+ break;
+ case Constants.DLOAD_0:
+ obj = new DLOAD(0);
+ break;
+ case Constants.DLOAD_1:
+ obj = new DLOAD(1);
+ break;
+ case Constants.DLOAD_2:
+ obj = new DLOAD(2);
+ break;
+ case Constants.DLOAD_3:
+ obj = new DLOAD(3);
+ break;
+ case Constants.ALOAD_0:
+ obj = new ALOAD(0);
+ break;
+ case Constants.ALOAD_1:
+ obj = new ALOAD(1);
+ break;
+ case Constants.ALOAD_2:
+ obj = new ALOAD(2);
+ break;
+ case Constants.ALOAD_3:
+ obj = new ALOAD(3);
+ break;
+ case Constants.ISTORE:
+ obj = new ISTORE();
+ break;
+ case Constants.LSTORE:
+ obj = new LSTORE();
+ break;
+ case Constants.FSTORE:
+ obj = new FSTORE();
+ break;
+ case Constants.DSTORE:
+ obj = new DSTORE();
+ break;
+ case Constants.ASTORE:
+ obj = new ASTORE();
+ break;
+ case Constants.ISTORE_0:
+ obj = new ISTORE(0);
+ break;
+ case Constants.ISTORE_1:
+ obj = new ISTORE(1);
+ break;
+ case Constants.ISTORE_2:
+ obj = new ISTORE(2);
+ break;
+ case Constants.ISTORE_3:
+ obj = new ISTORE(3);
+ break;
+ case Constants.LSTORE_0:
+ obj = new LSTORE(0);
+ break;
+ case Constants.LSTORE_1:
+ obj = new LSTORE(1);
+ break;
+ case Constants.LSTORE_2:
+ obj = new LSTORE(2);
+ break;
+ case Constants.LSTORE_3:
+ obj = new LSTORE(3);
+ break;
+ case Constants.FSTORE_0:
+ obj = new FSTORE(0);
+ break;
+ case Constants.FSTORE_1:
+ obj = new FSTORE(1);
+ break;
+ case Constants.FSTORE_2:
+ obj = new FSTORE(2);
+ break;
+ case Constants.FSTORE_3:
+ obj = new FSTORE(3);
+ break;
+ case Constants.DSTORE_0:
+ obj = new DSTORE(0);
+ break;
+ case Constants.DSTORE_1:
+ obj = new DSTORE(1);
+ break;
+ case Constants.DSTORE_2:
+ obj = new DSTORE(2);
+ break;
+ case Constants.DSTORE_3:
+ obj = new DSTORE(3);
+ break;
+ case Constants.ASTORE_0:
+ obj = new ASTORE(0);
+ break;
+ case Constants.ASTORE_1:
+ obj = new ASTORE(1);
+ break;
+ case Constants.ASTORE_2:
+ obj = new ASTORE(2);
+ break;
+ case Constants.ASTORE_3:
+ obj = new ASTORE(3);
+ break;
+ case Constants.IINC:
+ obj = new IINC();
+ break;
+ case Constants.IFEQ:
+ obj = new IFEQ();
+ break;
+ case Constants.IFNE:
+ obj = new IFNE();
+ break;
+ case Constants.IFLT:
+ obj = new IFLT();
+ break;
+ case Constants.IFGE:
+ obj = new IFGE();
+ break;
+ case Constants.IFGT:
+ obj = new IFGT();
+ break;
+ case Constants.IFLE:
+ obj = new IFLE();
+ break;
+ case Constants.IF_ICMPEQ:
+ obj = new IF_ICMPEQ();
+ break;
+ case Constants.IF_ICMPNE:
+ obj = new IF_ICMPNE();
+ break;
+ case Constants.IF_ICMPLT:
+ obj = new IF_ICMPLT();
+ break;
+ case Constants.IF_ICMPGE:
+ obj = new IF_ICMPGE();
+ break;
+ case Constants.IF_ICMPGT:
+ obj = new IF_ICMPGT();
+ break;
+ case Constants.IF_ICMPLE:
+ obj = new IF_ICMPLE();
+ break;
+ case Constants.IF_ACMPEQ:
+ obj = new IF_ACMPEQ();
+ break;
+ case Constants.IF_ACMPNE:
+ obj = new IF_ACMPNE();
+ break;
+ case Constants.GOTO:
+ obj = new GOTO();
+ break;
+ case Constants.JSR:
+ obj = new JSR();
+ break;
+ case Constants.RET:
+ obj = new RET();
+ break;
+ case Constants.TABLESWITCH:
+ obj = new TABLESWITCH();
+ break;
+ case Constants.LOOKUPSWITCH:
+ obj = new LOOKUPSWITCH();
+ break;
+ case Constants.GETSTATIC:
+ obj = new GETSTATIC();
+ break;
+ case Constants.PUTSTATIC:
+ obj = new PUTSTATIC();
+ break;
+ case Constants.GETFIELD:
+ obj = new GETFIELD();
+ break;
+ case Constants.PUTFIELD:
+ obj = new PUTFIELD();
+ break;
+ case Constants.INVOKEVIRTUAL:
+ obj = new INVOKEVIRTUAL();
+ break;
+ case Constants.INVOKESPECIAL:
+ obj = new INVOKESPECIAL();
+ break;
+ case Constants.INVOKESTATIC:
+ obj = new INVOKESTATIC();
+ break;
+ case Constants.INVOKEINTERFACE:
+ obj = new INVOKEINTERFACE();
+ break;
+ case Constants.NEW:
+ obj = new NEW();
+ break;
+ case Constants.NEWARRAY:
+ obj = new NEWARRAY();
+ break;
+ case Constants.ANEWARRAY:
+ obj = new ANEWARRAY();
+ break;
+ case Constants.CHECKCAST:
+ obj = new CHECKCAST();
+ break;
+ case Constants.INSTANCEOF:
+ obj = new INSTANCEOF();
+ break;
+ case Constants.MULTIANEWARRAY:
+ obj = new MULTIANEWARRAY();
+ break;
+ case Constants.IFNULL:
+ obj = new IFNULL();
+ break;
+ case Constants.IFNONNULL:
+ obj = new IFNONNULL();
+ break;
+ case Constants.GOTO_W:
+ obj = new GOTO_W();
+ break;
+ case Constants.JSR_W:
+ obj = new JSR_W();
+ break;
+ case Constants.BREAKPOINT:
+ obj = new BREAKPOINT();
+ break;
+ case Constants.IMPDEP1:
+ obj = new IMPDEP1();
+ break;
+ case Constants.IMPDEP2:
+ obj = new IMPDEP2();
+ break;
+ default:
+ throw new ClassGenException("Illegal opcode detected.");
+ }
+
+ if (wide
+ && !((obj instanceof LocalVariableInstruction) || (obj instanceof IINC) || (obj instanceof RET))) {
+ throw new ClassGenException("Illegal opcode after wide: " + opcode);
+ }
+ obj.setOpcode(opcode);
+ obj.initFromFile(bytes, wide); // Do further initializations, if any
+ return obj;
+ }
/**
* This method also gives right results for instructions whose
Modified: jakarta/bcel/trunk/src/main/java/org/apache/bcel/generic/InstructionList.java
URL: http://svn.apache.org/viewvc/jakarta/bcel/trunk/src/main/java/org/apache/bcel/generic/InstructionList.java?rev=617895&r1=617894&r2=617895&view=diff
==============================================================================
--- jakarta/bcel/trunk/src/main/java/org/apache/bcel/generic/InstructionList.java (original)
+++ jakarta/bcel/trunk/src/main/java/org/apache/bcel/generic/InstructionList.java Sat Feb 2 13:06:04 2008
@@ -140,8 +140,15 @@
* @return target position's instruction handle if available
*/
public InstructionHandle findHandle( int pos ) {
- InstructionHandle[] ihs = getInstructionHandles();
- return findHandle(ihs, byte_positions, length, pos);
+ int[] positions = byte_positions;
+ InstructionHandle ih = start;
+ for (int i = 0; i < length; i++) {
+ if(positions[i] == pos) {
+ return ih;
+ }
+ ih = ih.next;
+ }
+ return null;
}
Modified: jakarta/bcel/trunk/src/main/java/org/apache/bcel/generic/InvokeInstruction.java
URL: http://svn.apache.org/viewvc/jakarta/bcel/trunk/src/main/java/org/apache/bcel/generic/InvokeInstruction.java?rev=617895&r1=617894&r2=617895&view=diff
==============================================================================
--- jakarta/bcel/trunk/src/main/java/org/apache/bcel/generic/InvokeInstruction.java (original)
+++ jakarta/bcel/trunk/src/main/java/org/apache/bcel/generic/InvokeInstruction.java Sat Feb 2 13:06:04 2008
@@ -63,18 +63,15 @@
* @return Number of words consumed from stack by this instruction
*/
public int consumeStack( ConstantPoolGen cpg ) {
- String signature = getSignature(cpg);
- Type[] args = Type.getArgumentTypes(signature);
int sum;
if (opcode == Constants.INVOKESTATIC) {
sum = 0;
} else {
sum = 1; // this reference
}
- int n = args.length;
- for (int i = 0; i < n; i++) {
- sum += args[i].getSize();
- }
+
+ String signature = getSignature(cpg);
+ sum += Type.getArgumentTypesSize(signature);
return sum;
}
@@ -85,7 +82,8 @@
* @return Number of words produced onto stack by this instruction
*/
public int produceStack( ConstantPoolGen cpg ) {
- return getReturnType(cpg).getSize();
+ String signature = getSignature(cpg);
+ return Type.getReturnTypeSize(signature);
}
Modified: jakarta/bcel/trunk/src/main/java/org/apache/bcel/generic/Type.java
URL: http://svn.apache.org/viewvc/jakarta/bcel/trunk/src/main/java/org/apache/bcel/generic/Type.java?rev=617895&r1=617894&r2=617895&view=diff
==============================================================================
--- jakarta/bcel/trunk/src/main/java/org/apache/bcel/generic/Type.java (original)
+++ jakarta/bcel/trunk/src/main/java/org/apache/bcel/generic/Type.java Sat Feb 2 13:06:04 2008
@@ -307,4 +307,63 @@
sb.append(getType(meth.getReturnType()).getSignature());
return sb.toString();
}
+
+ private static int size(int coded) {
+ return coded & 3;
+ }
+
+ private static int consumed(int coded) {
+ return coded >> 2;
+ }
+
+ private static int encode(int size, int consumed) {
+ return consumed << 2 | size;
+ }
+
+ static int getArgumentTypesSize( String signature ) {
+ int res = 0;
+ int index;
+ Type[] types;
+ try { // Read all declarations between for `(' and `)'
+ if (signature.charAt(0) != '(') {
+ throw new ClassFormatException("Invalid method signature: " + signature);
+ }
+ index = 1; // current string position
+ while (signature.charAt(index) != ')') {
+ int coded = getTypeSize(signature.substring(index));
+ res += size(coded);
+ index += consumed(coded);
+ }
+ } catch (StringIndexOutOfBoundsException e) { // Should never occur
+ throw new ClassFormatException("Invalid method signature: " + signature);
+ }
+ return res;
+ }
+
+ static final int getTypeSize( String signature ) throws StringIndexOutOfBoundsException {
+ byte type = Utility.typeOfSignature(signature);
+ if (type <= Constants.T_VOID) {
+ return encode(BasicType.getType(type).getSize(), 1);
+ } else if (type == Constants.T_ARRAY) {
+ int dim = 0;
+ do { // Count dimensions
+ dim++;
+ } while (signature.charAt(dim) == '[');
+ // Recurse, but just once, if the signature is ok
+ int consumed = consumed(getTypeSize(signature.substring(dim)));
+ return encode(1, dim + consumed);
+ } else { // type == T_REFERENCE
+ int index = signature.indexOf(';'); // Look for closing `;'
+ if (index < 0) {
+ throw new ClassFormatException("Invalid signature: " + signature);
+ }
+ return encode(1, index + 1);
+ }
+ }
+
+
+ static int getReturnTypeSize(String signature) {
+ int index = signature.lastIndexOf(')') + 1;
+ return getTypeSize(signature.substring(index));
+ }
}
Added: jakarta/bcel/trunk/src/test/java/org/apache/bcel/NanoTimer.java
URL: http://svn.apache.org/viewvc/jakarta/bcel/trunk/src/test/java/org/apache/bcel/NanoTimer.java?rev=617895&view=auto
==============================================================================
--- jakarta/bcel/trunk/src/test/java/org/apache/bcel/NanoTimer.java (added)
+++ jakarta/bcel/trunk/src/test/java/org/apache/bcel/NanoTimer.java Sat Feb 2 13:06:04 2008
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2000-2004 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.bcel;
+
+public class NanoTimer {
+
+ private long time = 0;
+
+ public NanoTimer start() {
+ time -= System.nanoTime();
+ return this;
+ }
+
+ public void stop() {
+ time += System.nanoTime();
+ }
+
+ public void subtract(NanoTimer o) {
+ time -= o.time;
+ }
+
+ public void reset() {
+ time = 0;
+ }
+
+ /**
+ * May ony be called after stop has been called as many times as start.
+ */
+ public String toString() {
+ return ((double) (time) / 1000000000) + " s";
+ }
+
+
+
+}
Propchange: jakarta/bcel/trunk/src/test/java/org/apache/bcel/NanoTimer.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: jakarta/bcel/trunk/src/test/java/org/apache/bcel/NanoTimer.java
------------------------------------------------------------------------------
svn:keywords = Date Revision Author HeadURL Id
Propchange: jakarta/bcel/trunk/src/test/java/org/apache/bcel/NanoTimer.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: jakarta/bcel/trunk/src/test/java/org/apache/bcel/PerformanceTest.java
URL: http://svn.apache.org/viewvc/jakarta/bcel/trunk/src/test/java/org/apache/bcel/PerformanceTest.java?rev=617895&view=auto
==============================================================================
--- jakarta/bcel/trunk/src/test/java/org/apache/bcel/PerformanceTest.java (added)
+++ jakarta/bcel/trunk/src/test/java/org/apache/bcel/PerformanceTest.java Sat Feb 2 13:06:04 2008
@@ -0,0 +1,136 @@
+/*
+ * Copyright 2000-2004 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.bcel;
+
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Enumeration;
+import java.util.Locale;
+import java.util.jar.JarEntry;
+import java.util.jar.JarFile;
+
+import junit.framework.TestCase;
+
+import org.apache.bcel.classfile.ClassParser;
+import org.apache.bcel.classfile.JavaClass;
+import org.apache.bcel.classfile.Method;
+import org.apache.bcel.generic.ClassGen;
+import org.apache.bcel.generic.InstructionList;
+import org.apache.bcel.generic.MethodGen;
+
+public final class PerformanceTest extends TestCase {
+
+ private static byte[] read(final InputStream is) throws IOException {
+ if (is == null) {
+ throw new IOException("Class not found");
+ }
+ byte[] b = new byte[is.available()];
+ int len = 0;
+ while (true) {
+ int n = is.read(b, len, b.length - len);
+ if (n == -1) {
+ if (len < b.length) {
+ byte[] c = new byte[len];
+ System.arraycopy(b, 0, c, 0, len);
+ b = c;
+ }
+ return b;
+ }
+ len += n;
+ if (len == b.length) {
+ byte[] c = new byte[b.length + 1000];
+ System.arraycopy(b, 0, c, 0, len);
+ b = c;
+ }
+ }
+ }
+
+ private static void test(int fraction) throws IOException {
+ NanoTimer total = new NanoTimer();
+ NanoTimer parseTime = new NanoTimer();
+ NanoTimer cgenTime = new NanoTimer();
+ NanoTimer mgenTime = new NanoTimer();
+ NanoTimer mserTime = new NanoTimer();
+ NanoTimer serTime = new NanoTimer();
+
+ total.start();
+
+ String javaHome = System.getProperty("java.home");
+
+ JarFile jar = new JarFile(javaHome + "/lib/dt.jar");
+ Enumeration en = jar.entries();
+ int i = 0;
+
+ while (en.hasMoreElements()) {
+ JarEntry e = (JarEntry) en.nextElement();
+ if (e.getName().endsWith(".class") && i++ % fraction == 0) {
+ InputStream in = jar.getInputStream(e);
+ byte[] bytes = read(in);
+
+ parseTime.start();
+ JavaClass clazz = new ClassParser(new ByteArrayInputStream(bytes), e.getName())
+ .parse();
+ parseTime.stop();
+
+ cgenTime.start();
+ ClassGen cg = new ClassGen(clazz);
+ cgenTime.stop();
+
+ Method[] methods = cg.getMethods();
+ for (int j = 0; j < methods.length; j++) {
+ Method m = methods[j];
+
+ mgenTime.start();
+ MethodGen mg = new MethodGen(m, cg.getClassName(), cg.getConstantPool());
+ InstructionList il = mg.getInstructionList();
+ mgenTime.stop();
+
+ mserTime.start();
+ if (il != null) {
+ mg.getInstructionList().setPositions();
+ mg.setMaxLocals();
+ mg.setMaxStack();
+ }
+ cg.replaceMethod(m, mg.getMethod());
+ mserTime.stop();
+ }
+
+ serTime.start();
+ cg.getJavaClass().getBytes();
+ serTime.stop();
+ }
+ }
+
+ total.stop();
+ System.out.println("ClassParser.parse: " + parseTime);
+ System.out.println("ClassGen.init: " + cgenTime);
+ System.out.println("MethodGen.init: " + mgenTime);
+ System.out.println("MethodGen.getMethod: " + mserTime);
+ System.out.println("ClassGen.getJavaClass.getBytes: " + serTime);
+ System.out.println("Total: " + total);
+ System.out.println();
+ }
+
+ public void testPerformance() throws IOException {
+ test(1);
+ test(1);
+ test(1);
+ }
+
+}
Propchange: jakarta/bcel/trunk/src/test/java/org/apache/bcel/PerformanceTest.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: jakarta/bcel/trunk/src/test/java/org/apache/bcel/PerformanceTest.java
------------------------------------------------------------------------------
svn:keywords = Date Revision Author HeadURL Id
Propchange: jakarta/bcel/trunk/src/test/java/org/apache/bcel/PerformanceTest.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
---------------------------------------------------------------------
To unsubscribe, e-mail: bcel-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: bcel-dev-help@jakarta.apache.org