/************************************************************************************** * Copyright (c) Jonas Bon�r, Alexandre Vasseur. All rights reserved. * * http://aspectwerkz.codehaus.org * * ---------------------------------------------------------------------------------- * * The software in this package is published under the terms of the LGPL license * * a copy of which has been included with this distribution in the license.txt file. * **************************************************************************************/ package test.weavebench; import org.codehaus.aspectwerkz.transform.inlining.AsmHelper; import org.codehaus.aspectwerkz.transform.AspectWerkzPreProcessor; import org.codehaus.aspectwerkz.hook.impl.WeavingClassLoader; import org.codehaus.aspectwerkz.definition.SystemDefinition; import org.codehaus.aspectwerkz.definition.DeploymentScope; import org.codehaus.aspectwerkz.definition.SystemDefinitionContainer; import org.codehaus.aspectwerkz.definition.DefinitionParserHelper; import org.objectweb.asm.ClassVisitor; import org.objectweb.asm.Opcodes; import org.objectweb.asm.Type; import org.objectweb.asm.MethodVisitor; import org.objectweb.asm.ClassWriter; import java.net.URL; import java.net.URLClassLoader; import java.io.File; import java.util.HashSet; import java.util.Set; import java.lang.reflect.Method; /** * @author <a href="mailto:alex AT gnilux DOT com">Alexandre Vasseur</a> */ public class GenerateClasses implements Opcodes { private final static String DUMP_DIR = "_dump2"; private final static String CLASS_NAME_PREFIX = "test/weavebench/Generated_"; public int m_classCount; public int m_count; public GenerateClasses(int classCount, int methodCount) { m_classCount = classCount; m_count = methodCount; } public void generate() throws Throwable { for (int i = 0; i < m_classCount; i++) { ClassWriter cv = AsmHelper.newClassWriter(true); String className = CLASS_NAME_PREFIX + i; cv.visit( AsmHelper.JAVA_VERSION, ACC_PUBLIC + ACC_SUPER + ACC_SYNTHETIC, className, null, Object.class.getName().replace('.', '/'), new String[]{IGenerated.class.getName().replace('.', '/')} ); MethodVisitor mv = cv.visitMethod( ACC_PUBLIC, "<init>", "()V", null, new String[0] ); mv.visitVarInsn(ALOAD, 0); mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V"); mv.visitVarInsn(ALOAD, 0); mv.visitInsn(RETURN); mv.visitMaxs(0, 0); for (int m = 0; m < m_count; m++) { mv = cv.visitMethod( (m==0)?ACC_PUBLIC: ACC_PRIVATE,//TODO change to private to have wrapper, public for no wrappers "method_" + m, "()I", null, new String[0] ); // call next method if (m != m_count-1) { mv.visitVarInsn(ALOAD, 0); mv.visitMethodInsn(INVOKEVIRTUAL, className, "method_" + (m+1), "()I"); } AsmHelper.loadIntegerConstant(mv, m); mv.visitInsn(IRETURN); mv.visitMaxs(0, 0); } cv.visitEnd(); AsmHelper.dumpClass(DUMP_DIR, className, cv); } } public static void main(String args[]) throws Throwable { Thread.sleep(3000); int CLASS_COUNT = 400; int METHOD_COUNT = 200; int JP_COUNT = (METHOD_COUNT*2 -1/*last method has no call jp*/ + 1/*init exec*/)*CLASS_COUNT; GenerateClasses me = new GenerateClasses(CLASS_COUNT, METHOD_COUNT); System.out.println("********* Bench for"); System.out.println(" classes: " + CLASS_COUNT); System.out.println(" methods: " + METHOD_COUNT); System.out.println(" jps: " + JP_COUNT); System.out.println("*************************************"); me.generate(); // ClassLoader custom_1 = new URLClassLoader( // new URL[]{(new File(DUMP_DIR)).toURL()}, // GenerateClasses.class.getClassLoader() // ); // bench("No weaver hooked in", custom_1, CLASS_COUNT, 0); // // ClassLoader custom_2 = new WeavingClassLoader( // new URL[]{(new File(DUMP_DIR)).toURL()}, // GenerateClasses.class.getClassLoader() // ); // bench("Weaver hooked in and match none", custom_2, CLASS_COUNT, 0); ClassLoader custom_3 = new WeavingClassLoader( new URL[]{(new File(DUMP_DIR)).toURL()}, GenerateClasses.class.getClassLoader() ); SystemDefinition sd = SystemDefinitionContainer.getVirtualDefinitionAt(custom_3); sd.addDeploymentScope(DeploymentScope.MATCH_ALL); DefinitionParserHelper.attachDeploymentScopeDefsToVirtualAdvice(sd); Set defs = new HashSet(); defs.add(sd); SystemDefinitionContainer.deployDefinitions(custom_3, defs); bench("Weaver hooked in and match all", custom_3, CLASS_COUNT, JP_COUNT); } public static void bench(String label, ClassLoader loader, int classCount, int jpCount) throws Throwable { System.out.println("*************************************"); System.out.print(label); System.out.println(" "); long t = System.currentTimeMillis(); Class[] classes = new Class[classCount]; for (int i = 0; i < classCount; i++) { classes[i] = Class.forName((CLASS_NAME_PREFIX+i).replace('/','.'), false, loader); } System.out.println(" Total load time = " + (System.currentTimeMillis() - t)); long t2 = System.currentTimeMillis(); for (int i = 0; i < classCount; i++) { Class gen = classes[i]; Method m0 = gen.getMethod("method_0", new Class[]{}); Object res = m0.invoke(gen.newInstance(), new Object[]{}); //System.out.print(i); } System.out.println(""); long execTimeNotWarmedUp = System.currentTimeMillis() - t2; System.out.println(" Exec time = " + execTimeNotWarmedUp); System.out.println(" Total time = " + (System.currentTimeMillis() - t)); if (jpCount > 0) System.out.println(" Exec / jp ratio (ns) = " + execTimeNotWarmedUp * 1000 / jpCount); t2 = System.currentTimeMillis(); for (int i = 0; i < classCount; i++) { Class gen = classes[i]; Method m0 = gen.getMethod("method_0", new Class[]{}); Object res = m0.invoke(gen.newInstance(), new Object[]{}); } System.out.println(" Exec time warmed up = " + (System.currentTimeMillis() - t2)); } }