checkpoint
[org.ibex.arenaj.git] / src / edu / berkeley / cs / megacz / Transformer.java
index 513e0fa..8473f80 100644 (file)
@@ -5,18 +5,22 @@ import soot.util.*;
 import java.io.*;
 import java.util.*;
 
-public class Transformer extends BodyTransformer {    
+public class Transformer extends SceneTransformer {    
+
+    public static final int initialSize = 100;
 
     private static Transformer instance = new Transformer();
-    private Transformer() {}
+    private Transformer() {
+    }
     public static Transformer v() { return instance; }
-
+   
     public static void main(String[] args)  {
         if(args.length == 0) {
             System.out.println("Syntax: java " + v().getClass().getName() + " [soot options]");
             System.exit(0);
-        }            
-        PackManager.v().getPack("jtp").add(new Transform("jtp.instrumenter", Transformer.v()));
+        }
+        //PackManager.v().allPacks().add(v());
+        PackManager.v().getPack("wjtp").add(new Transform("wjtp.tx", Transformer.v()));
        // Just in case, resolve the PrintStream SootClass.
        Scene.v().addBasicClass("java.io.PrintStream",SootClass.SIGNATURES);
         soot.Main.main(args);
@@ -36,34 +40,58 @@ public class Transformer extends BodyTransformer {
     public boolean isGladiator(SootClass c) { return c.implementsInterface("edu.berkeley.cs.megacz.Gladiator"); }
     public boolean isGladiatorField(SootField f)
         { return isGladiator(f.getDeclaringClass()) && !f.getName().equals("this") && f.getName().indexOf('$')==-1; }
-    public SootField getGladiatorField(SootField f) {
-        SootClass c  = f.getDeclaringClass();
+    public boolean isGladiatorFieldRef(SootFieldRef f) {
+        return isGladiator(f.declaringClass()) && !f.name().equals("this") && f.name().indexOf('$')==-1;
+    }
+    public SootField getGladiatorField(SootField f) { return getGladiatorField(f.makeRef()); }
+    public SootField getGladiatorField(SootFieldRef f) {
+        SootClass c  = f.declaringClass();
         SootClass oc = Scene.v().getSootClass(c.getName().substring(0, c.getName().lastIndexOf('$')));
-        if (map.get(f) != null) return (SootField)map.get(f);
-        SootField nf = new SootField(c.getShortName().substring(c.getShortName().lastIndexOf('$')+1) + "$" + f.getName(),
-                                     f.getType().makeArrayType(),
-                                     f.getModifiers());
+        String sig = f.declaringClass().getName()+"."+f.name();
+        if (map.get(sig) != null) return (SootField)map.get(sig);
+        Type t = f.type();
+        if (t instanceof RefType && isGladiator(((RefType)t).getSootClass())) t = IntType.v();
+        SootField nf = new SootField(c.getShortName().substring(c.getShortName().lastIndexOf('$')+1) + "$" + f.name(),
+                                     t.makeArrayType(),
+                                     0);
         oc.addField(nf);
         Body body = oc.getMethod("<init>", new LinkedList()).getActiveBody();
-        Expr newArr = Jimple.v().newNewArrayExpr(f.getType(), IntConstant.v(1000));
-        Local newArrLocal = Jimple.v().newLocal("tmpRef" + (tfr++), f.getType().makeArrayType());
+        Expr newArr = Jimple.v().newNewArrayExpr(t, IntConstant.v(initialSize));
+        Local newArrLocal = Jimple.v().newLocal("tmpRef" + (tfr++), f.type().makeArrayType());
         body.getLocals().add(newArrLocal);
         InstanceFieldRef ifr = Jimple.v().newInstanceFieldRef(body.getThisLocal(), nf.makeRef());
         body.getUnits().addFirst(Jimple.v().newAssignStmt(ifr, newArrLocal));
         body.getUnits().addFirst(Jimple.v().newAssignStmt(newArrLocal, newArr));
-        map.put(f, nf);
+        map.put(sig, nf);
         return nf;
     }
 
+    private Body body;
     public SootFieldRef getGladiatorFieldSizeRef(SootClass c) {
         SootClass mc = Scene.v().getMainClass();
-        String name = c.getShortName().substring(c.getShortName().lastIndexOf('$')+1) + "_size";
-        if (map.get(c) == null) {
+        String name = c.getShortName().substring(c.getShortName().lastIndexOf('$')+1) + "$$size";
+        if (map.get(name) == null) {
             SootField f = new SootField(name, IntType.v());
             mc.addField(f);
-        Body body = mc.getMethod("<init>", new LinkedList()).getActiveBody();
-        InstanceFieldRef ifr = Jimple.v().newInstanceFieldRef(body.getThisLocal(), f.makeRef());
-        body.getUnits().addFirst(Jimple.v().newAssignStmt(ifr, IntConstant.v(0)));
+
+            Body body = mc.getMethod("<init>", new LinkedList()).getActiveBody();
+            InstanceFieldRef ifr = Jimple.v().newInstanceFieldRef(body.getThisLocal(), f.makeRef());
+            body.getUnits().addFirst(Jimple.v().newAssignStmt(ifr, IntConstant.v(0)));
+
+            map.put(c, f);
+        }
+        return Scene.v().makeFieldRef(mc, name, IntType.v(), false);
+    }
+    public SootFieldRef getGladiatorFieldMaxRef(SootClass c) {
+        SootClass mc = Scene.v().getMainClass();
+        String name = c.getShortName().substring(c.getShortName().lastIndexOf('$')+1) + "$$max";
+        if (map.get(name) == null) {
+            SootField f = new SootField(name, IntType.v());
+            mc.addField(f);
+
+            Body body = mc.getMethod("<init>", new LinkedList()).getActiveBody();
+            InstanceFieldRef ifr = Jimple.v().newInstanceFieldRef(body.getThisLocal(), f.makeRef());
+            body.getUnits().addFirst(Jimple.v().newAssignStmt(ifr, IntConstant.v(initialSize)));
 
             map.put(c, f);
         }
@@ -74,55 +102,225 @@ public class Transformer extends BodyTransformer {
         return (t instanceof RefType) && isGladiator(((RefType)t).getSootClass());
     }
 
-    protected void internalTransform(Body body, String phaseName, Map options) {
-        SootClass c = body.getMethod().getDeclaringClass();
+    public SootMethodRef convert(SootMethodRef mr) {
+        List l = mr.parameterTypes();
+        List l2 = new LinkedList();
+        for(Iterator it2 = l.iterator(); it2.hasNext();) {
+            Type t = (Type)it2.next();
+            l2.add(isGladiatorType(t) ? IntType.v() : t);
+        }
+        return Scene.v().makeMethodRef(mr.declaringClass(),
+                                       mr.name(),
+                                       l2,
+                                       isGladiatorType(mr.returnType()) ? IntType.v() : mr.returnType(),
+                                       mr.isStatic());
+    }
+
+    boolean done = false;
+    public void internalTransform(String phaseName, Map options) {
+        System.out.println("=============");
+        if (done) return;
+        done = true;
+        //nuke(Scene.v().getSootClass("edu.berkeley.cs.megacz.Test$Inner"));
+        //nuke(Scene.v().getSootClass("edu.berkeley.cs.megacz.Test"));
+        //nuke(Scene.v().getSootClass("org.ibex.graphics.Mesh"));
+        //nuke(Scene.v().getSootClass("org.ibex.graphics.Mesh$Triangle"));
+        fixClass(Scene.v().getSootClass("edu.berkeley.cs.megacz.GCBench$Node"));
+        nuke(Scene.v().getSootClass("edu.berkeley.cs.megacz.GCBench$Node"));
+        nuke(Scene.v().getSootClass("edu.berkeley.cs.megacz.GCBench"));
+    }
+
+    public void fixClass(SootClass sc) {
+        SootClass mc = Scene.v().getMainClass();
+        String incFuncName = sc.getShortName().substring(sc.getShortName().lastIndexOf('$')+1) + "$$inc";
+        SootMethod method = new SootMethod(incFuncName, new LinkedList(),
+                                           IntType.v(), Modifier.PRIVATE,
+                                           new LinkedList());
+        mc.addMethod(method);
+        method.setActiveBody(body = Jimple.v().newBody(method));
+        body.setMethod(method);
+        ((JimpleBody)body).insertIdentityStmts();
+        Local l = Jimple.v().newLocal("tmpRef" + (tfr++), IntType.v());
+        body.getLocals().add(l);
+        Local l2 = Jimple.v().newLocal("tmpRef" + (tfr++), IntType.v());
+        body.getLocals().add(l2);
+        Local l3 = Jimple.v().newLocal("tmpRef" + (tfr++), IntType.v());
+        body.getLocals().add(l3);
+        InstanceFieldRef sfr = Jimple.v().newInstanceFieldRef(body.getThisLocal(), getGladiatorFieldSizeRef(sc));
+        body.getUnits().add(Jimple.v().newAssignStmt(l, sfr));
+        body.getUnits().add(Jimple.v().newAssignStmt(l2, Jimple.v().newAddExpr(l, IntConstant.v(1))));
+        InstanceFieldRef maxField = Jimple.v().newInstanceFieldRef(body.getThisLocal(), getGladiatorFieldMaxRef(sc));
+        body.getUnits().add(Jimple.v().newAssignStmt(l3, maxField));
+        Stmt stmt = Jimple.v().newReturnStmt(l2);
+        body.getUnits().add(Jimple.v().newIfStmt(Jimple.v().newLtExpr(l2, l3), stmt));
 
+        Local l4 = Jimple.v().newLocal("tmpRef" + (tfr++), IntType.v());
+        body.getLocals().add(l4);
+        body.getUnits().add(Jimple.v().newAssignStmt(l4, Jimple.v().newShlExpr(l3, IntConstant.v(1))));
+        body.getUnits().add(Jimple.v().newAssignStmt(maxField, l4));
+
+        for(Iterator it = sc.getFields().iterator(); it.hasNext();) {
+            SootField f = getGladiatorField((SootField)it.next());
+            InstanceFieldRef ifr = Jimple.v().newInstanceFieldRef(body.getThisLocal(), f.makeRef());
+            Local ll0 = Jimple.v().newLocal("tmpRef" + (tfr++), f.getType());
+            body.getLocals().add(ll0);
+            body.getUnits().add(Jimple.v().newAssignStmt(ll0, ifr));
+            Local ll = Jimple.v().newLocal("tmpRef" + (tfr++), f.getType());
+            body.getLocals().add(ll);
+            body.getUnits().add(Jimple.v().newAssignStmt(ll,
+                                                         Jimple.v().newNewArrayExpr(((ArrayType)f.getType()).getElementType(),
+                                                                                    l4)));
+            Type ot = Scene.v().getSootClass("java.lang.Object").getType();
+            List types = new LinkedList();
+            types.add(ot);
+            types.add(IntType.v());
+            types.add(ot);
+            types.add(IntType.v());
+            types.add(IntType.v());
+            SootMethodRef arrayCopy =
+                Scene.v().makeMethodRef(Scene.v().getSootClass("java.lang.System"),
+                                        "arraycopy",
+                                        types,
+                                        VoidType.v(),
+                                        true);
+            List args = new LinkedList();
+            args.add(ll0);
+            args.add(IntConstant.v(0));
+            args.add(ll);
+            args.add(IntConstant.v(0));
+            args.add(l3);
+            body.getUnits().add(Jimple.v().newInvokeStmt(Jimple.v().newStaticInvokeExpr(arrayCopy, args)));
+            body.getUnits().add(Jimple.v().newAssignStmt(ifr,ll));
+        }
+
+        body.getUnits().add(stmt);
+    }
+
+    public void nuke(SootClass c) {
         for(Iterator it = c.getFields().iterator(); it.hasNext();) {
             SootField f = (SootField)it.next();
             Type t = f.getType();
-            if (!(t instanceof RefType)) continue;
-            if (isGladiator(((RefType)t).getSootClass())) f.setType(IntType.v());
+            if (t instanceof RefType) {
+                RefType rt = (RefType)t;
+                SootClass sc = rt.getSootClass();
+                if (isGladiator(sc)) f.setType(IntType.v());
+            } else if (t instanceof ArrayType) {
+                ArrayType at = (ArrayType)t;
+                t = at.getElementType();
+                if (!(t instanceof RefType)) continue;                
+                RefType rt = (RefType)t;
+                SootClass sc = rt.getSootClass();
+                if (isGladiator(sc)) f.setType(IntType.v().makeArrayType());
+            }
         }
 
-        for(Iterator it = c.methodIterator(); it.hasNext();) {
+        //if (isGladiator(c)) fixClass(c);
+
+        List list = new LinkedList(); list.addAll(c.getMethods());
+        for(Iterator it = list.iterator(); it.hasNext();) {
             SootMethod m = (SootMethod)it.next();
+            if (isGladiator(c) && m.getName().equals("<init>")) continue;
+            if (m.hasActiveBody() && !m.isStatic()) m.setActiveBody(fixBody(m.getActiveBody()));
+            if (m.getName().equals("<init>")) continue;
+            if (m.getName().equals("<clinit>")) continue;
+            //if (map.get(m) != null) continue;
+            //map.put(m, Boolean.TRUE);
             System.out.println(m.getName() + " -- " + m.getActiveBody());
-            /*
             List l2 = new LinkedList();
             List l = m.getParameterTypes();
             for(Iterator it2 = l.iterator(); it2.hasNext();) {
                 Type t = (Type)it2.next();
+                //l2.add(t);
                 l2.add(isGladiatorType(t) ? IntType.v() : t);
+                //if (isGladiatorType(t)) System.out.println("ought to swap " + t);
             }
-            m.setParameterTypes(l2);
             Type t = m.getReturnType();
-            m.setReturnType(isGladiatorType(t) ? IntType.v() : t);
-            */
+            c.removeMethod(m);
+            if (isGladiatorType(t)) {
+                t = IntType.v();
+                Body bod = m.getActiveBody();
+                for(Iterator stmtIt = bod.getUnits().snapshotIterator(); stmtIt.hasNext();) {
+                    Stmt s = (Stmt) stmtIt.next();
+                    if (s instanceof ReturnStmt) {
+                        if (((ReturnStmt)s).getOp().getType() instanceof NullType) {
+                            ((ReturnStmt)s).getOpBox().setValue(IntConstant.v(-1));
+                        }
+                    }
+                }
+            }
+            SootMethod meth = new SootMethod(m.getName(), l2, t, m.getModifiers());
+            meth.setActiveBody(m.getActiveBody());
+            c.addMethod(meth);
         }
 
+    }
+
+    protected Body fixBody(Body body) {
+        this.body = body;
+        Chain units = body.getUnits();
         for(Iterator it = body.getLocals().snapshotIterator(); it.hasNext();) {
             Local l = (Local)it.next();
             if (isGladiatorType(l.getType())) l.setType(IntType.v());
         }
-
-        Chain units = body.getUnits();
-        Iterator stmtIt = units.snapshotIterator();
-        while(stmtIt.hasNext()) {
+        for(int qq=0; qq<2; qq++) for(Iterator stmtIt = units.snapshotIterator(); stmtIt.hasNext();) {
             Stmt s = (Stmt) stmtIt.next();
             List l = s.getUseAndDefBoxes();
+            if (s instanceof DefinitionStmt) {
+                DefinitionStmt ds = (DefinitionStmt)s;
+                if (ds.getLeftOp().getType() instanceof PrimType && ds.getRightOp().getType() instanceof NullType) {
+                    System.out.println("*************************");
+                    ds.getRightOpBox().setValue(IntConstant.v(-1));
+                }
+            }
             for(Iterator it = l.iterator(); it.hasNext();) {
                 Object o = it.next();
                 if (o instanceof ValueBox) {
                     ValueBox vb = (ValueBox)o;
                     Value v = vb.getValue();
+                    
+                    if (v instanceof BinopExpr) {
+                        BinopExpr boe = (BinopExpr)v;
+                        if (boe.getOp1().getType() instanceof PrimType && boe.getOp2().getType() instanceof NullType) {
+                            System.out.println("*************************");
+                            boe.setOp2(IntConstant.v(-1));
+                        }
+                        if (boe.getOp2().getType() instanceof PrimType && boe.getOp1().getType() instanceof NullType) {
+                            System.out.println("*************************");
+                            boe.setOp1(IntConstant.v(-1));
+                        }
+                    }
 
                     if (v instanceof InvokeExpr) {
                         InvokeExpr ie = (InvokeExpr)v;
-                        SootMethod m = ie.getMethod();
-                        if (isGladiator(m.getDeclaringClass())) {
+                        SootMethodRef mr = ie.getMethodRef();
+                        if (isGladiator(mr.declaringClass())) {
                             body.getUnits().remove(s);
+                            qq = 0;
                             break;
                         }
+                        mr = convert(mr);
+                        ie.setMethodRef(mr);
+                        for(int i=0; i<ie.getArgCount(); i++) {
+                            ValueBox b = ie.getArgBox(i);
+                            Value val = b.getValue();
+                            if (mr.parameterType(i) instanceof RefType && val.getType() instanceof PrimType) {
+                                SootClass intClass = Scene.v().getSootClass("java.lang.Integer");
+                                List typelist = new LinkedList();
+                                typelist.add(IntType.v());
+                                SootMethod intMethod = intClass.getMethod("<init>", typelist);
+                                Local loc = viaLocal(Jimple.v().newNewExpr(RefType.v(intClass)), body, s);
+                                List list = new LinkedList();
+                                list.add(val);
+                                units.insertBefore(Jimple.v().newInvokeStmt(Jimple.v().newSpecialInvokeExpr(loc,
+                                                                                                            intMethod.makeRef(),
+                                                                                                            list)),
+                                                   s);
+                                b.setValue(loc);
+                            }
+                            if (val != null && val.getType() instanceof NullType && mr.parameterType(i) instanceof IntType) {
+                                b.setValue(IntConstant.v(-1));
+                            }
+                        }
 
                     } else if (v instanceof NewExpr) {
                         NewExpr ne = (NewExpr)v;
@@ -131,38 +329,48 @@ public class Transformer extends BodyTransformer {
                             SootClass mc = Scene.v().getMainClass();
                             SootClass sc = ((RefType)ne.getBaseType()).getSootClass();
                             System.out.println(sc);
-                            InstanceFieldRef sfr = Jimple.v().newInstanceFieldRef(body.getThisLocal(),
-                                                                                  getGladiatorFieldSizeRef(sc));
-                            Local ll = viaLocal(sfr, body, s);
-                            Local ll2 = Jimple.v().newLocal("tmpRef" + (tfr++), IntType.v());
-                            body.getLocals().add(ll2);
-                            Stmt stmt = Jimple.v().newAssignStmt(ll2, Jimple.v().newAddExpr(ll, IntConstant.v(1)));
-                            units.insertBefore(stmt, s);
-                            units.insertAfter(Jimple.v().newAssignStmt(sfr, ll2), stmt);
+                            String incFuncName = sc.getShortName().substring(sc.getShortName().lastIndexOf('$')+1) + "$$inc";
+                            SootMethodRef smr = Scene.v().makeMethodRef(mc, incFuncName, new LinkedList(), IntType.v(), false);
+                            Expr invokeExpr = Jimple.v().newSpecialInvokeExpr(body.getThisLocal(), smr);
+                            Local ll = viaLocal(invokeExpr, body, s);
                             vb.setValue(ll);
                         }
 
-                    } else if (v instanceof InstanceFieldRef) {
-                        InstanceFieldRef ifr = (InstanceFieldRef)v;
-                        Type t = ifr.getType();
-                        if ((t instanceof RefType) && isGladiator(((RefType)t).getSootClass())) {
-                            SootClass tc = ((RefType)t).getSootClass();
+                    } else if (v instanceof CastExpr) {
+                        CastExpr ce = (CastExpr)v;
+                        if (isGladiatorType(ce.getCastType())) {
+                            //SootClass intClass = Scene.v().getSootClass("java.lang.Integer");
+                            //SootClass intClass = Scene.v().getSootClass("java.lang.Integer");
                             SootClass mc = Scene.v().getMainClass();
-                            SootFieldRef fr = Scene.v().makeFieldRef(mc, "z", IntType.v(), false);
-                            ifr.setFieldRef(fr);
+                            LinkedList list = new LinkedList();
+                            list.add(Scene.v().getSootClass("java.lang.Object").getType());
+                            SootMethodRef mr = Scene.v().makeMethodRef(mc, "zap", list, IntType.v(), true);
+                            Local loc = viaLocal(ce.getOp(), body, s);
+                            List list2 = new LinkedList();
+                            list2.add(loc);
+                            vb.setValue(viaLocal(Jimple.v().newStaticInvokeExpr(mr, list2), body, s));
                         }
-                        SootField f = ifr.getField();
-                        if (isGladiatorField(f)) {
-                            f = getGladiatorField(f);
+
+                    } else if (v instanceof InstanceFieldRef) {
+                        InstanceFieldRef ifr = (InstanceFieldRef)v;
+                        SootFieldRef fr = ifr.getFieldRef();
+                        Type t = fr.type();
+                        if (isGladiatorFieldRef(fr)) {
                             SootClass mc = Scene.v().getMainClass();
-                            SootField sf = mc.getField(f.getName(), f.getType());
-                            InstanceFieldRef sfr = Jimple.v().newInstanceFieldRef(body.getThisLocal(), sf.makeRef());
+                            SootFieldRef sf = getGladiatorField(fr).makeRef();
+                            InstanceFieldRef sfr = Jimple.v().newInstanceFieldRef(body.getThisLocal(), sf);
                             ArrayRef ar = Jimple.v().newArrayRef(viaLocal(sfr, body, s), ifr.getBase());
                             vb.setValue(ar);
                         }
+                        if ((t instanceof RefType) && isGladiator(((RefType)t).getSootClass())) {
+                            SootClass tc = ((RefType)t).getSootClass();
+                            SootClass mc = Scene.v().getMainClass();
+                            ifr.setFieldRef(Scene.v().makeFieldRef(mc, fr.name(), IntType.v(), false));
+                        }
                     }
                 }
             }
         }
+        return body;
     }
 }