package org.codehaus.groovy.gjit; import java.io.File; import java.io.RandomAccessFile; import java.util.Map; import org.objectweb.asm.ClassAdapter; import org.objectweb.asm.ClassReader; import org.objectweb.asm.ClassVisitor; import org.objectweb.asm.ClassWriter; import org.objectweb.asm.MethodVisitor; import org.objectweb.asm.tree.MethodNode; public class Optimiser extends ClassAdapter { private ConstantPack pack; private String[] siteNames; private Map<String, MethodNode> methods; private String owner; public Optimiser(ClassVisitor cv) { super(cv); } public Optimiser(ClassVisitor cv, Map<String, MethodNode> methods) { super(cv); this.methods = methods; } enum State { START, FOUND_COMPARE, FOUND_CALLSITE_VAR, LOAD_CALLSITE_VAR }; @Override public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) { MethodNode mn = methods.get(name+desc); if(mn != null) { try { //DebugUtils.println("method name: " + name + desc); //if(name.equals("bottomUpTree"))// || name.equals("itemCheck")) //if(name.equals("main")) new SecondTransformer(owner, mn, pack, siteNames).transform(); } catch (Throwable e) { e.printStackTrace(); } mn.accept(cv); return mn; } else { return super.visitMethod(access, name, desc, signature, exceptions); } } @Override public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) { this.owner = name; pack = ConstantRecord.v().get(this.owner); siteNames = CallSiteArrayPack.v().get(this.owner); super.visit(version, access, name, signature, superName, interfaces); } public static void main(String[] args) throws Throwable { RandomAccessFile r = new RandomAccessFile(new File("C:\\groovy-ck1\\gjit\\subject\\" +args[0]+".class"), "r"); byte[] bytes = new byte[(int) r.length()]; r.readFully(bytes); // ClassReader cr = new ClassReader(bytes); // PreProcess cv = new PreProcess(new EmptyVisitor()); // //final int mode = 0; final int mode = ClassReader.SKIP_DEBUG; // cr.accept(cv, mode); PreProcess cv = PreProcess.perform(bytes, mode); if(cv.isGroovyClassFile()) { ClassReader cr = new ClassReader(bytes); ClassWriter cw = new ClassWriter(cr, ClassWriter.COMPUTE_MAXS); Optimiser cv2 = new Optimiser(cw, cv.getMethods()); cr.accept(cv2, mode); byte[] outBytes = cw.toByteArray(); try { new File("C:\\groovy-ck1\\gjit\\subject\\out\\"+args[0]+".class").delete(); } catch(Throwable e){} RandomAccessFile ro = new RandomAccessFile(new File("C:\\groovy-ck1\\gjit\\subject\\out\\"+args[0]+".class"), "rw"); ro.write(outBytes); ro.close(); } } public static byte[] perform(PreProcess cv, byte[] classfileBuffer) { return perform(cv, classfileBuffer, 0); } public static byte[] perform(PreProcess cv, byte[] classfileBuffer, int mode) { ClassReader cr = new ClassReader(classfileBuffer); ClassWriter cw = new ClassWriter(cr, ClassWriter.COMPUTE_MAXS); Optimiser cv2 = new Optimiser(cw, cv.getMethods()); cr.accept(cv2, mode); return cw.toByteArray(); } }