X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;ds=sidebyside;f=src%2Fedu%2Fberkeley%2Fcs%2Fmegacz%2FTransformer.java;h=8473f8008696b8f0af0d972550a460f1f8450d75;hb=251e990674d9861b29d569abe3648cad09355107;hp=7c49c405c0062de85a352dc2e360bd9171d32879;hpb=d82239f6ad1be37c08754310a5ca8eb1bd10ea67;p=org.ibex.arenaj.git diff --git a/src/edu/berkeley/cs/megacz/Transformer.java b/src/edu/berkeley/cs/megacz/Transformer.java index 7c49c40..8473f80 100644 --- a/src/edu/berkeley/cs/megacz/Transformer.java +++ b/src/edu/berkeley/cs/megacz/Transformer.java @@ -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,35 +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("", 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("", 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("", 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("", 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); } @@ -90,25 +117,110 @@ public class Transformer extends BodyTransformer { } boolean done = false; - public void internalTransform(Body bz, String phaseName, Map options) { - System.out.println("============= " + phaseName); + 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("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()); + } } + //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 (m.hasActiveBody()) m.setActiveBody(fixBody(m.getActiveBody())); + if (isGladiator(c) && m.getName().equals("")) continue; + if (m.hasActiveBody() && !m.isStatic()) m.setActiveBody(fixBody(m.getActiveBody())); if (m.getName().equals("")) continue; if (m.getName().equals("")) continue; //if (map.get(m) != null) continue; @@ -124,7 +236,19 @@ public class Transformer extends BodyTransformer { } Type t = m.getReturnType(); c.removeMethod(m); - SootMethod meth = new SootMethod(m.getName(), l2, isGladiatorType(t) ? IntType.v() : t, m.getModifiers()); + 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); } @@ -134,28 +258,69 @@ public class Transformer extends BodyTransformer { protected Body fixBody(Body body) { this.body = body; Chain units = body.getUnits(); - Iterator stmtIt = units.snapshotIterator(); for(Iterator it = body.getLocals().snapshotIterator(); it.hasNext();) { Local l = (Local)it.next(); if (isGladiatorType(l.getType())) l.setType(IntType.v()); } - 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; SootMethodRef mr = ie.getMethodRef(); if (isGladiator(mr.declaringClass())) { body.getUnits().remove(s); + qq = 0; break; } - ie.setMethodRef(convert(mr)); + mr = convert(mr); + ie.setMethodRef(mr); + for(int i=0; i", 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; @@ -164,35 +329,44 @@ 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)); + } } } }