+ 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;