+++ /dev/null
-package edu.berkeley.cs.megacz;
-import soot.*;
-import soot.jimple.*;
-import soot.util.*;
-import java.io.*;
-import java.util.*;
-
-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 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 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("<init>", 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 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);
-
- 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);
- }
- 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);
- }
-
- 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());
- }
- }
-
- //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);
- }
- 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));
- }
- }
- }
- }
- 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<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;
- 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;
- }
-}