1 package edu.berkeley.cs.megacz;
8 public class Transformer extends SceneTransformer {
10 private static Transformer instance = new Transformer();
11 private Transformer() {
13 public static Transformer v() { return instance; }
15 public static void main(String[] args) {
16 if(args.length == 0) {
17 System.out.println("Syntax: java " + v().getClass().getName() + " [soot options]");
20 //PackManager.v().allPacks().add(v());
21 PackManager.v().getPack("wjtp").add(new Transform("wjtp.tx", Transformer.v()));
22 // Just in case, resolve the PrintStream SootClass.
23 Scene.v().addBasicClass("java.io.PrintStream",SootClass.SIGNATURES);
28 public static Local viaLocal(Value v, Body b, Unit u) {
29 Local l = Jimple.v().newLocal("tmpRef" + (tfr++), v.getType());
31 b.getUnits().insertBefore(Jimple.v().newAssignStmt(l, v), u);
35 HashMap map = new HashMap();
36 HashSet size_added = new HashSet();
38 public boolean isGladiator(SootClass c) { return c.implementsInterface("edu.berkeley.cs.megacz.Gladiator"); }
39 public boolean isGladiatorField(SootField f)
40 { return isGladiator(f.getDeclaringClass()) && !f.getName().equals("this") && f.getName().indexOf('$')==-1; }
41 public boolean isGladiatorFieldRef(SootFieldRef f) {
42 return isGladiator(f.declaringClass()) && !f.name().equals("this") && f.name().indexOf('$')==-1;
44 public SootField getGladiatorField(SootField f) { return getGladiatorField(f.makeRef()); }
45 public SootField getGladiatorField(SootFieldRef f) {
46 SootClass c = f.declaringClass();
47 SootClass oc = Scene.v().getSootClass(c.getName().substring(0, c.getName().lastIndexOf('$')));
48 String sig = f.declaringClass().getName()+"."+f.name();
49 if (map.get(sig) != null) return (SootField)map.get(sig);
51 if (t instanceof RefType && isGladiator(((RefType)t).getSootClass())) t = IntType.v();
52 SootField nf = new SootField(c.getShortName().substring(c.getShortName().lastIndexOf('$')+1) + "$" + f.name(),
56 Body body = oc.getMethod("<init>", new LinkedList()).getActiveBody();
57 Expr newArr = Jimple.v().newNewArrayExpr(t, IntConstant.v(100000));
58 Local newArrLocal = Jimple.v().newLocal("tmpRef" + (tfr++), f.type().makeArrayType());
59 body.getLocals().add(newArrLocal);
60 InstanceFieldRef ifr = Jimple.v().newInstanceFieldRef(body.getThisLocal(), nf.makeRef());
61 body.getUnits().addFirst(Jimple.v().newAssignStmt(ifr, newArrLocal));
62 body.getUnits().addFirst(Jimple.v().newAssignStmt(newArrLocal, newArr));
68 public SootFieldRef getGladiatorFieldSizeRef(SootClass c) {
69 SootClass mc = Scene.v().getMainClass();
70 String name = c.getShortName().substring(c.getShortName().lastIndexOf('$')+1) + "_size";
71 if (map.get(c) == null) {
72 SootField f = new SootField(name, IntType.v());
75 Body body = mc.getMethod("<init>", new LinkedList()).getActiveBody();
76 InstanceFieldRef ifr = Jimple.v().newInstanceFieldRef(body.getThisLocal(), f.makeRef());
77 body.getUnits().addFirst(Jimple.v().newAssignStmt(ifr, IntConstant.v(0)));
81 return Scene.v().makeFieldRef(mc, name, IntType.v(), false);
83 public SootFieldRef getGladiatorFieldMaxRef(SootClass c) {
84 SootClass mc = Scene.v().getMainClass();
85 String name = c.getShortName().substring(c.getShortName().lastIndexOf('$')+1) + "_max";
86 if (map.get(c) == null) {
87 SootField f = new SootField(name, IntType.v());
90 Body body = mc.getMethod("<init>", new LinkedList()).getActiveBody();
91 InstanceFieldRef ifr = Jimple.v().newInstanceFieldRef(body.getThisLocal(), f.makeRef());
92 body.getUnits().addFirst(Jimple.v().newAssignStmt(ifr, IntConstant.v(0)));
96 return Scene.v().makeFieldRef(mc, name, IntType.v(), false);
99 public boolean isGladiatorType(Type t) {
100 return (t instanceof RefType) && isGladiator(((RefType)t).getSootClass());
103 public SootMethodRef convert(SootMethodRef mr) {
104 List l = mr.parameterTypes();
105 List l2 = new LinkedList();
106 for(Iterator it2 = l.iterator(); it2.hasNext();) {
107 Type t = (Type)it2.next();
108 l2.add(isGladiatorType(t) ? IntType.v() : t);
110 return Scene.v().makeMethodRef(mr.declaringClass(),
113 isGladiatorType(mr.returnType()) ? IntType.v() : mr.returnType(),
117 boolean done = false;
118 public void internalTransform(String phaseName, Map options) {
119 System.out.println("=============");
122 //nuke(Scene.v().getSootClass("edu.berkeley.cs.megacz.Test$Inner"));
123 //nuke(Scene.v().getSootClass("edu.berkeley.cs.megacz.Test"));
124 //nuke(Scene.v().getSootClass("org.ibex.graphics.Mesh"));
125 //nuke(Scene.v().getSootClass("org.ibex.graphics.Mesh$Triangle"));
126 fixClass(Scene.v().getSootClass("edu.berkeley.cs.megacz.GCBench"));
127 nuke(Scene.v().getSootClass("edu.berkeley.cs.megacz.GCBench$Node"));
128 nuke(Scene.v().getSootClass("edu.berkeley.cs.megacz.GCBench"));
131 public void fixClass(SootClass sc) {
132 SootClass mc = Scene.v().getMainClass();
133 String incFuncName = sc.getShortName().substring(sc.getShortName().lastIndexOf('$')+1) + "$$inc";
134 SootMethod method = new SootMethod(incFuncName, new LinkedList(),
135 IntType.v(), Modifier.PRIVATE,
137 mc.addMethod(method);
138 method.setActiveBody(body = Jimple.v().newBody(method));
139 body.setMethod(method);
140 ((JimpleBody)body).insertIdentityStmts();
141 InstanceFieldRef sfr = Jimple.v().newInstanceFieldRef(body.getThisLocal(), getGladiatorFieldSizeRef(sc));
142 InstanceFieldRef maxField = Jimple.v().newInstanceFieldRef(body.getThisLocal(), getGladiatorFieldMaxRef(sc));
143 Local l = Jimple.v().newLocal("tmpRef" + (tfr++), IntType.v());
144 body.getLocals().add(l);
145 Local l2 = Jimple.v().newLocal("tmpRef" + (tfr++), IntType.v());
146 body.getLocals().add(l2);
147 Local l3 = Jimple.v().newLocal("tmpRef" + (tfr++), IntType.v());
148 body.getLocals().add(l3);
149 body.getUnits().add(Jimple.v().newAssignStmt(l, sfr));
150 body.getUnits().add(Jimple.v().newAssignStmt(l2, Jimple.v().newAddExpr(l, IntConstant.v(1))));
151 body.getUnits().add(Jimple.v().newAssignStmt(l3, maxField));
153 body.getUnits().add(Jimple.v().newIfStmt(Jimple.v().newLtExpr(l2, l3),
154 Jimple.v().newReturnStmt(l2)));
156 body.getUnits().add(Jimple.v().newReturnStmt(l2));
160 public void nuke(SootClass c) {
161 for(Iterator it = c.getFields().iterator(); it.hasNext();) {
162 SootField f = (SootField)it.next();
163 Type t = f.getType();
164 if (t instanceof RefType) {
165 RefType rt = (RefType)t;
166 SootClass sc = rt.getSootClass();
167 if (isGladiator(sc)) f.setType(IntType.v());
168 } else if (t instanceof ArrayType) {
169 ArrayType at = (ArrayType)t;
170 t = at.getElementType();
171 if (!(t instanceof RefType)) continue;
172 RefType rt = (RefType)t;
173 SootClass sc = rt.getSootClass();
174 if (isGladiator(sc)) f.setType(IntType.v().makeArrayType());
178 //if (isGladiator(c)) fixClass(c);
180 List list = new LinkedList(); list.addAll(c.getMethods());
181 for(Iterator it = list.iterator(); it.hasNext();) {
182 SootMethod m = (SootMethod)it.next();
183 if (m.hasActiveBody() && !m.isStatic()) m.setActiveBody(fixBody(m.getActiveBody()));
184 if (m.getName().equals("<init>")) continue;
185 if (m.getName().equals("<clinit>")) continue;
186 //if (map.get(m) != null) continue;
187 //map.put(m, Boolean.TRUE);
188 System.out.println(m.getName() + " -- " + m.getActiveBody());
189 List l2 = new LinkedList();
190 List l = m.getParameterTypes();
191 for(Iterator it2 = l.iterator(); it2.hasNext();) {
192 Type t = (Type)it2.next();
194 l2.add(isGladiatorType(t) ? IntType.v() : t);
195 //if (isGladiatorType(t)) System.out.println("ought to swap " + t);
197 Type t = m.getReturnType();
199 if (isGladiatorType(t)) {
201 Body bod = m.getActiveBody();
202 for(Iterator stmtIt = bod.getUnits().snapshotIterator(); stmtIt.hasNext();) {
203 Stmt s = (Stmt) stmtIt.next();
204 if (s instanceof ReturnStmt) {
205 if (((ReturnStmt)s).getOp().getType() instanceof NullType) {
206 ((ReturnStmt)s).getOpBox().setValue(IntConstant.v(-1));
211 SootMethod meth = new SootMethod(m.getName(), l2, t, m.getModifiers());
212 meth.setActiveBody(m.getActiveBody());
218 protected Body fixBody(Body body) {
220 Chain units = body.getUnits();
221 for(Iterator it = body.getLocals().snapshotIterator(); it.hasNext();) {
222 Local l = (Local)it.next();
223 if (isGladiatorType(l.getType())) l.setType(IntType.v());
225 for(int qq=0; qq<2; qq++) for(Iterator stmtIt = units.snapshotIterator(); stmtIt.hasNext();) {
226 Stmt s = (Stmt) stmtIt.next();
227 List l = s.getUseAndDefBoxes();
228 if (s instanceof DefinitionStmt) {
229 DefinitionStmt ds = (DefinitionStmt)s;
230 if (ds.getLeftOp().getType() instanceof PrimType && ds.getRightOp().getType() instanceof NullType) {
231 System.out.println("*************************");
232 ds.getRightOpBox().setValue(IntConstant.v(-1));
235 for(Iterator it = l.iterator(); it.hasNext();) {
236 Object o = it.next();
237 if (o instanceof ValueBox) {
238 ValueBox vb = (ValueBox)o;
239 Value v = vb.getValue();
241 if (v instanceof BinopExpr) {
242 BinopExpr boe = (BinopExpr)v;
243 if (boe.getOp1().getType() instanceof PrimType && boe.getOp2().getType() instanceof NullType) {
244 System.out.println("*************************");
245 boe.setOp2(IntConstant.v(-1));
247 if (boe.getOp2().getType() instanceof PrimType && boe.getOp1().getType() instanceof NullType) {
248 System.out.println("*************************");
249 boe.setOp1(IntConstant.v(-1));
253 if (v instanceof InvokeExpr) {
254 InvokeExpr ie = (InvokeExpr)v;
255 SootMethodRef mr = ie.getMethodRef();
256 if (isGladiator(mr.declaringClass())) {
257 body.getUnits().remove(s);
263 for(int i=0; i<ie.getArgCount(); i++) {
264 ValueBox b = ie.getArgBox(i);
265 Value val = b.getValue();
266 if (mr.parameterType(i) instanceof RefType && val.getType() instanceof PrimType) {
267 SootClass intClass = Scene.v().getSootClass("java.lang.Integer");
268 List typelist = new LinkedList();
269 typelist.add(IntType.v());
270 SootMethod intMethod = intClass.getMethod("<init>", typelist);
271 Local loc = viaLocal(Jimple.v().newNewExpr(RefType.v(intClass)), body, s);
272 List list = new LinkedList();
274 units.insertBefore(Jimple.v().newInvokeStmt(Jimple.v().newSpecialInvokeExpr(loc,
280 if (val != null && val.getType() instanceof NullType && mr.parameterType(i) instanceof IntType) {
281 b.setValue(IntConstant.v(-1));
285 } else if (v instanceof NewExpr) {
286 NewExpr ne = (NewExpr)v;
287 if (isGladiatorType(ne.getBaseType())) {
288 System.out.println("******");
289 SootClass mc = Scene.v().getMainClass();
290 SootClass sc = ((RefType)ne.getBaseType()).getSootClass();
291 System.out.println(sc);
292 String incFuncName = sc.getShortName().substring(sc.getShortName().lastIndexOf('$')+1) + "$$inc";
293 SootMethodRef smr = Scene.v().makeMethodRef(mc, incFuncName, new LinkedList(), IntType.v(), false);
294 Expr invokeExpr = Jimple.v().newSpecialInvokeExpr(body.getThisLocal(), smr);
295 Local ll = viaLocal(invokeExpr, body, s);
299 } else if (v instanceof CastExpr) {
300 CastExpr ce = (CastExpr)v;
301 if (isGladiatorType(ce.getCastType())) {
302 //SootClass intClass = Scene.v().getSootClass("java.lang.Integer");
303 //SootClass intClass = Scene.v().getSootClass("java.lang.Integer");
304 SootClass mc = Scene.v().getMainClass();
305 LinkedList list = new LinkedList();
306 list.add(Scene.v().getSootClass("java.lang.Object").getType());
307 SootMethodRef mr = Scene.v().makeMethodRef(mc, "zap", list, IntType.v(), true);
308 Local loc = viaLocal(ce.getOp(), body, s);
309 List list2 = new LinkedList();
311 vb.setValue(viaLocal(Jimple.v().newStaticInvokeExpr(mr, list2), body, s));
314 } else if (v instanceof InstanceFieldRef) {
315 InstanceFieldRef ifr = (InstanceFieldRef)v;
316 SootFieldRef fr = ifr.getFieldRef();
318 if (isGladiatorFieldRef(fr)) {
319 SootClass mc = Scene.v().getMainClass();
320 SootFieldRef sf = getGladiatorField(fr).makeRef();
321 InstanceFieldRef sfr = Jimple.v().newInstanceFieldRef(body.getThisLocal(), sf);
322 ArrayRef ar = Jimple.v().newArrayRef(viaLocal(sfr, body, s), ifr.getBase());
325 if ((t instanceof RefType) && isGladiator(((RefType)t).getSootClass())) {
326 SootClass tc = ((RefType)t).getSootClass();
327 SootClass mc = Scene.v().getMainClass();
328 ifr.setFieldRef(Scene.v().makeFieldRef(mc, fr.name(), IntType.v(), false));