// File RTCG7.java --- measure time to generate (much) code // sestoft@itu.dk * 2002-09 // Using the gnu.bytecode package from http://www.gnu.org/software/kawa import gnu.bytecode.*; import java.io.*; public class RTCG7 { 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]); ClassType co = new ClassType("MyClass"); co.setSuper("java.lang.Object"); co.setModifiers(Access.PUBLIC); Timer t = new Timer(); { // Build: public static void MyMethod1(int x) { ... } Method mo = co.addMethod("MyMethod1"); mo.setSignature("(I)V"); mo.setModifiers(Access.PUBLIC | Access.STATIC); mo.initCode(); // Obtain a JVM code generator jvmg CodeAttr jvmg = mo.getCode(); Scope scope = mo.pushScope(); Variable lvar0 = scope.addVariable(jvmg, Type.int_type, "x"); Label start = new Label(jvmg); start.define(jvmg); jvmg.emitLoad(lvar0); jvmg.emitPushInt(1); jvmg.emitAdd('I'); for (int i=count; i>0; i--) { jvmg.emitLoad(lvar0); jvmg.emitAdd('I'); } mo.popScope(); jvmg.emitReturn(); } // Output class file to array: byte[] classFile = co.writeToArray(); // 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; } }