// File RTCG7B.java --- measure time to generate (much) code // sestoft@itu.dk * 2002-09-17 // Using BCEL from http://jakarta.apache.org/bcel/ import org.apache.bcel.*; // Constants import org.apache.bcel.classfile.*; // JavaClass import org.apache.bcel.generic.*; // ClassGen, MethodGen, instructions import java.io.*; public class RTCG7B { public static void main(String[] args) throws IOException, NoSuchMethodException, IllegalAccessException, java.lang.reflect.InvocationTargetException { int count = Integer.parseInt(args[0]); int calls = Integer.parseInt(args[1]); ClassGen cg = new ClassGen("MyClass", "java.lang.Object", "", Constants.ACC_PUBLIC | Constants.ACC_SUPER, null); ConstantPoolGen cp = cg.getConstantPool(); Timer t = new Timer(); { // Build: public static void MyMethod1(int x) { ... } InstructionList il = new InstructionList(); MethodGen mg = new MethodGen(Constants.ACC_PUBLIC | Constants.ACC_STATIC, Type.VOID, new Type[] { Type.INT }, new String[] { "x" }, "MyMethod1", "MyClass", il, cp); Instruction iload = new ILOAD(0); Instruction iadd = new IADD(); il.append(iload); il.append(new ICONST(1)); il.append(iadd); for (int i=count; i>0; i--) { il.append(iload); il.append(iadd); } il.append(new RETURN()); // Compute stack depth and add method to the class mg.setMaxStack(); cg.addMethod(mg.getMethod()); } // Get the generated class JavaClass clazz = cg.getJavaClass(); // Output class file to array: byte[] classFile = clazz.getBytes(); // Load the class file into the JVM Class ty = new ArrayClassLoader().loadClass("MyClass", classFile); { java.lang.reflect.Method m = ty.getMethod("MyMethod1", new Class[] { int.class }); for (int i=calls; i>0; i--) { m.invoke(null, new Object[] { new Integer(count) }); } System.out.println("Generating " + 2*count + " instructions and making " + calls + " calls: " + t.Check() + " sec"); } } } // This is needed because defineClass is protected in java.lang.ClassLoader: class ArrayClassLoader extends ClassLoader { public Class loadClass(String name, byte[] classFile) { return defineClass(name, classFile, 0, classFile.length); } } // Crude timing utility ---------------------------------------- class Timer { private long start; public Timer() { start = System.currentTimeMillis(); } public double Check() { return (System.currentTimeMillis()-start)/1000.0; } }