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=8cf610f990270da78fe50d98d2ef6895a2ef8b6c;hpb=676aba2a0f719cd699230fe35f2a72c0eef1207f;p=org.ibex.arenaj.git diff --git a/src/edu/berkeley/cs/megacz/Transformer.java b/src/edu/berkeley/cs/megacz/Transformer.java index 8cf610f..8473f80 100644 --- a/src/edu/berkeley/cs/megacz/Transformer.java +++ b/src/edu/berkeley/cs/megacz/Transformer.java @@ -5,152 +5,372 @@ import soot.util.*; import java.io.*; import java.util.*; -public class Transformer { - public static void main(String[] args) - { - if(args.length == 0) - { - System.out.println("Syntax: java ashes.examples.countgotos.Main [soot options]"); - System.exit(0); - } - - PackManager.v().getPack("jtp").add(new Transform("jtp.instrumenter", GotoInstrumenter.v())); +public class Transformer extends SceneTransformer { + + public static final int initialSize = 100; + private static Transformer instance = new 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().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); } - static class GotoInstrumenter extends BodyTransformer { - private static GotoInstrumenter instance = new GotoInstrumenter(); - private GotoInstrumenter() {} + static int tfr = 0; + public static Local viaLocal(Value v, Body b, Unit u) { + Local l = Jimple.v().newLocal("tmpRef" + (tfr++), v.getType()); + b.getLocals().add(l); + b.getUnits().insertBefore(Jimple.v().newAssignStmt(l, v), u); + return l; + } + + HashMap map = new HashMap(); + HashSet size_added = new HashSet(); - public static GotoInstrumenter v() { return instance; } + 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 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('$'))); + 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(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(sig, nf); + return nf; + } - private boolean addedFieldToMainClassAndLoadedPrintStream = false; - private SootClass javaIoPrintStream; + 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(name) == null) { + SootField f = new SootField(name, IntType.v()); + mc.addField(f); - private Local addTmpRef(Body body) { - Local tmpRef = Jimple.v().newLocal("tmpRef", RefType.v("java.io.PrintStream")); - body.getLocals().add(tmpRef); - return tmpRef; + 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); } - - private Local addTmpLong(Body body) { - Local tmpLong = Jimple.v().newLocal("tmpLong", LongType.v()); - body.getLocals().add(tmpLong); - return tmpLong; + 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); } + return Scene.v().makeFieldRef(mc, name, IntType.v(), false); + } + + public boolean isGladiatorType(Type t) { + return (t instanceof RefType) && isGladiator(((RefType)t).getSootClass()); + } + + 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); + } - private void addStmtsToBefore(Chain units, Stmt s, SootField gotoCounter, Local tmpRef, Local tmpLong) - { - // insert "tmpRef = java.lang.System.out;" - units.insertBefore(Jimple.v().newAssignStmt( - tmpRef, Jimple.v().newStaticFieldRef( - Scene.v().getField("").makeRef())), s); - - // insert "tmpLong = gotoCounter;" - units.insertBefore(Jimple.v().newAssignStmt(tmpLong, - Jimple.v().newStaticFieldRef(gotoCounter.makeRef())), s); - - // insert "tmpRef.println(tmpLong);" - SootMethod toCall = javaIoPrintStream.getMethod("void println(long)"); - units.insertBefore(Jimple.v().newInvokeStmt( - Jimple.v().newVirtualInvokeExpr(tmpRef, toCall.makeRef(), tmpLong)), s); + 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) { + 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()); + } } - protected void internalTransform(Body body, String phaseName, Map options) { - SootClass sClass = body.getMethod().getDeclaringClass(); - SootField gotoCounter = null; - boolean addedLocals = false; - Local tmpRef = null, tmpLong = null; - Chain units = body.getUnits(); - - System.out.println("sClass is " + sClass); - - // Add code at the end of the main method to print out the - // gotoCounter (this only works in simple cases, because you may have multiple returns or System.exit()'s ) - synchronized(this) - { - if (!Scene.v().getMainClass(). - declaresMethod("void main(java.lang.String[])")) - throw new RuntimeException("couldn't find main() in mainClass"); - - if (addedFieldToMainClassAndLoadedPrintStream) - gotoCounter = Scene.v().getMainClass().getFieldByName("gotoCount"); - else - { - // Add gotoCounter field - gotoCounter = new SootField("gotoCount", LongType.v(), - Modifier.STATIC); - Scene.v().getMainClass().addField(gotoCounter); - - javaIoPrintStream = Scene.v().getSootClass("java.io.PrintStream"); - - addedFieldToMainClassAndLoadedPrintStream = true; + //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); + } + Type t = m.getReturnType(); + 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)); } + } } - - // Add code to increase goto counter each time a goto is encountered - { - boolean isMainMethod = body.getMethod().getSubSignature().equals("void main(java.lang.String[])"); - - Local tmpLocal = Jimple.v().newLocal("tmp", LongType.v()); - body.getLocals().add(tmpLocal); - - Iterator stmtIt = units.snapshotIterator(); - - while(stmtIt.hasNext()) - { - Stmt s = (Stmt) stmtIt.next(); - - if(s instanceof GotoStmt) - { - AssignStmt toAdd1 = Jimple.v().newAssignStmt(tmpLocal, - Jimple.v().newStaticFieldRef(gotoCounter.makeRef())); - AssignStmt toAdd2 = Jimple.v().newAssignStmt(tmpLocal, - Jimple.v().newAddExpr(tmpLocal, LongConstant.v(1L))); - AssignStmt toAdd3 = Jimple.v().newAssignStmt(Jimple.v().newStaticFieldRef(gotoCounter.makeRef()), - tmpLocal); - - // insert "tmpLocal = gotoCounter;" - units.insertBefore(toAdd1, s); - - // insert "tmpLocal = tmpLocal + 1L;" - units.insertBefore(toAdd2, s); - - // insert "gotoCounter = tmpLocal;" - units.insertBefore(toAdd3, s); - } - else if (s instanceof InvokeStmt) - { - InvokeExpr iexpr = (InvokeExpr) ((InvokeStmt)s).getInvokeExpr(); - if (iexpr instanceof StaticInvokeExpr) - { - SootMethod target = ((StaticInvokeExpr)iexpr).getMethod(); - - if (target.getSignature().equals("")) - { - if (!addedLocals) - { - tmpRef = addTmpRef(body); tmpLong = addTmpLong(body); - addedLocals = true; - } - addStmtsToBefore(units, s, gotoCounter, tmpRef, tmpLong); - } - } + } + 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()); + } + 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; + } + 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); } - else if (isMainMethod && (s instanceof ReturnStmt || s instanceof ReturnVoidStmt)) - { - if (!addedLocals) - { - tmpRef = addTmpRef(body); tmpLong = addTmpLong(body); - addedLocals = true; - } - addStmtsToBefore(units, s, gotoCounter, tmpRef, tmpLong); + 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; + if (isGladiatorType(ne.getBaseType())) { + System.out.println("******"); + SootClass mc = Scene.v().getMainClass(); + SootClass sc = ((RefType)ne.getBaseType()).getSootClass(); + System.out.println(sc); + 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 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(); + 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)); + } + + } 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(); + 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; } }