X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=src%2Fedu%2Fberkeley%2Fcs%2Fmegacz%2FTransformer.java;h=8473f8008696b8f0af0d972550a460f1f8450d75;hb=251e990674d9861b29d569abe3648cad09355107;hp=513e0fa801604a4afc38885274b1ebd7d4230f48;hpb=0baf4f123d065336c4c084b15b0806e785a56dff;p=org.ibex.arenaj.git diff --git a/src/edu/berkeley/cs/megacz/Transformer.java b/src/edu/berkeley/cs/megacz/Transformer.java index 513e0fa..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,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("", 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); } @@ -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("")) 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; + //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", 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; } }