package org.codehaus.groovy.gjit.agent; import java.lang.instrument.ClassFileTransformer; import java.lang.instrument.IllegalClassFormatException; import java.security.ProtectionDomain; import org.codehaus.groovy.gjit.Optimiser; import org.codehaus.groovy.gjit.PreProcess; import org.codehaus.groovy.gjit.agent.instrumentor.CallSiteArrayInstrumentor; import org.codehaus.groovy.gjit.agent.instrumentor.MetaClassInstumentor; import org.objectweb.asm.ClassReader; import org.objectweb.asm.ClassWriter; public class Transformer implements ClassFileTransformer { public Transformer() { super(); } public byte[] transform(ClassLoader loader, String className, Class<?> classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer) throws IllegalClassFormatException { // // check the condition which class is going to be transform // do transformation // if(className.equals("groovy/lang/MetaClassImpl")) { return instrumentingMetaClass(classfileBuffer); }else if(className.equals("org/codehaus/groovy/runtime/callsite/CallSiteArray")) { return instrumentingCallSiteArray(classfileBuffer); } else if(className.startsWith("java") || className.startsWith("sun") || className.startsWith("soot")) { return classfileBuffer; } else { return optimisingGroovyClass(classfileBuffer); } } private byte[] optimisingGroovyClass(byte[] classfileBuffer) { try { PreProcess cv = PreProcess.perform(classfileBuffer); if(cv.isGroovyClassFile()==false) { return classfileBuffer; } else { // if it's a groovy compiled class, try optimising return Optimiser.perform(cv, classfileBuffer); } } catch(Throwable e) { e.printStackTrace(); return classfileBuffer; } } private byte[] instrumentingCallSiteArray(byte[] classfileBuffer) { ClassReader cr = new ClassReader(classfileBuffer); ClassWriter cw = new ClassWriter(cr, ClassWriter.COMPUTE_MAXS); CallSiteArrayInstrumentor csai = new CallSiteArrayInstrumentor(cw); cr.accept(csai, 0); return cw.toByteArray(); } private byte[] instrumentingMetaClass(byte[] classfileBuffer) { ClassReader cr = new ClassReader(classfileBuffer); ClassWriter cw = new ClassWriter(cr, ClassWriter.COMPUTE_MAXS); MetaClassInstumentor mci = new MetaClassInstumentor(cw); cr.accept(mci, 0); return cw.toByteArray(); } }