From: adam Date: Sun, 8 May 2005 23:01:10 +0000 (+0000) Subject: version 0.2 X-Git-Url: http://git.megacz.com/?a=commitdiff_plain;h=f5ad8473e4a8be141c7d614412d7e0f9e5731904;p=org.ibex.arenaj.git version 0.2 darcs-hash:20050508230110-5007d-45494117392f3aa91f919d0756731bbc08284e92.gz --- diff --git a/Makefile b/Makefile index 828aeba..9c7e2c2 100644 --- a/Makefile +++ b/Makefile @@ -1,39 +1,17 @@ -#cp = lib/soot.jar:/Users/megacz/ibex.org/jar/org.ibex.core.jar:/Users/megacz/ibex.org/jar/org.ibex.util.jar:/Users/megacz/ibex.org/jar/org.ibex.js.jar:/Users/megacz/ibex.org/jar/org.ibex.net.jar:/Users/megacz/ibex.org/jar/org.ibex.io.jar:bin -sootcp = lib/soot.jar:/System/Library/Frameworks/JavaVM.framework/Versions/1.4.2/Classes/classes.jar +sootjars := jar/sootclasses-2.2.1.jar jar/jasminclasses-2.2.1.jar jar/polyglotclasses-1.3.jar +java := java -Djava.ext.dirs=jar +arenaj := ${java} -jar jar/org.ibex.arenaj.jar -# IVME Paper -doc/charts/%.pdf: doc/charts/%.dat doc/charts/%.gnuplot - cd doc/charts; gnuplot $*.gnuplot - cd doc/charts; chmod +x boxfill.pl; ./boxfill.pl -g -o unfilled.eps $*.eps - cd doc/charts; ps2pdf $*.eps +jar: ; mkdir -p jar +jar/sootclasses-2.2.1.jar: jar; cd jar; curl -C - -O http://www.sable.mcgill.ca/software/sootclasses-2.2.1.jar +jar/jasminclasses-2.2.1.jar: jar; cd jar; curl -C - -O http://www.sable.mcgill.ca/software/jasminclasses-2.2.1.jar +jar/polyglotclasses-1.3.jar: jar; cd jar; curl -C - -O http://www.sable.mcgill.ca/software/polyglotclasses-1.3.jar -#mainclass = edu.berkeley.cs.megacz.Test -#mainclass = org.ibex.graphics.Mesh +jar/org.ibex.arenaj.jar: jar/org.ibex.tool.jar + ${java} -jar jar/org.ibex.tool.jar -v -w -j jar/org.ibex.arenaj.jar -m org.ibex.arenaj.Main src -go: - javac -classpath lib/soot.jar:bin -d bin `find src/ -name \*.java` - mkdir -p in -# cd in; for A in /Users/megacz/ibex.org.arenaj/jar/*.jar; do jar xf $$A; done -# mkdir -p out -# java -cp bin:lib/soot.jar edu.berkeley.cs.megacz.Transformer -keep-line-number -app -i org.ibex.graphics -d out -cp ${sootcp}:in org.ibex.graphics.Mesh - java -cp bin:lib/soot.jar edu.berkeley.cs.megacz.Transformer \ - -keep-line-number \ +demo: jar/org.ibex.arenaj.jar + ${arenaj} \ -app -i org.ibex.graphics \ - -w \ -d out \ - -cp ${sootcp}:bin \ - -p cg enabled:false \ - -p cg.cha enabled:false \ - -p cg.spark enabled:false \ - -p cg.paddle enabled:false \ - -p wjap.ra enabled:false \ - -p wjap.umt enabled:false \ - -p wjap.uft enabled:false \ - -p wjap.tqt enabled:false \ - -p wjap.cgg enabled:false \ - edu.berkeley.cs.megacz.GCBench - - -# java -jar lib/soot.jar -app -i org.ibex.graphics -f d -d outsrc -cp ${sootcp}:out ${mainclass} -# cd out; find . -name \*.class -exec jad {} \; -# cat out/Test.jad + org.ibex.arenaj.Test diff --git a/doc/chart.pdf b/doc/chart.pdf new file mode 100644 index 0000000..613758a Binary files /dev/null and b/doc/chart.pdf differ diff --git a/doc/prezo.pdf b/doc/prezo.pdf new file mode 100644 index 0000000..c82bf02 Binary files /dev/null and b/doc/prezo.pdf differ diff --git a/src/edu/berkeley/cs/megacz/JArena.java b/src/edu/berkeley/cs/megacz/JArena.java deleted file mode 100644 index a9c5d9d..0000000 --- a/src/edu/berkeley/cs/megacz/JArena.java +++ /dev/null @@ -1,223 +0,0 @@ -package edu.berkeley.cs.megacz; - -import soot.*; -import soot.util.*; -import java.util.*; -import soot.toolkits.scalar.*; -import soot.jimple.*; -import soot.toolkits.graph.*; -import soot.*; -import soot.jimple.*; -import soot.toolkits.scalar.*; -import soot.toolkits.graph.*; -import soot.util.*; -import java.util.*; - -/** Tracks which locals are definitely non-null. - * Author: Patrick Lam (plam@sable.mcgill.ca) - * Based on BranchedRefVarsAnalysis by Janus Godard (janus@place.org). */ -class JArena extends ForwardBranchedFlowAnalysis { - - protected Object newInitialFlow() { return fullSet.clone(); } - protected Object entryInitialFlow() { return emptySet.clone(); } - private void addGen(Unit u, Value v) { ArraySparseSet l = (ArraySparseSet)unitToGenerateSet.get(u); l.add(v); } - private void addGensFor(DefinitionStmt u) { - Value lo = u.getLeftOp(); - Value ro = u.getRightOp(); - if (ro instanceof NewExpr || - ro instanceof NewArrayExpr || - ro instanceof NewMultiArrayExpr || - ro instanceof ThisRef || - ro instanceof CaughtExceptionRef) - addGen(u, lo); - } - - protected void copy(Object src, Object dest) { - FlowSet sourceSet = (FlowSet)src, destSet = (FlowSet) dest; - sourceSet.copy(destSet); - } - - protected void merge(Object src1, Object src2, Object dest) { - FlowSet srcSet1 = (FlowSet) src1; - FlowSet srcSet2 = (FlowSet) src2; - FlowSet destSet = (FlowSet) dest; - srcSet1.intersection(srcSet2, destSet); - } - - FlowSet fullSet, emptySet; - FlowUniverse allRefLocals; - Map unitToGenerateSet; - - protected void flowThrough(Object srcValue, Unit unit, List fallOut, List branchOuts) { - FlowSet dest; - FlowSet src = (FlowSet) srcValue; - Unit s = (Unit) unit; - - // Create working set. - dest = (FlowSet)src.clone(); - - // Take out kill set. - Iterator boxIt = s.getDefBoxes().iterator(); - while (boxIt.hasNext()) { - ValueBox box = (ValueBox) boxIt.next(); - Value value = box.getValue(); - if (value instanceof Local && value.getType() instanceof RefLikeType) - dest.remove(value); - } - - // Perform gen. - dest.union((FlowSet)unitToGenerateSet.get(unit), dest); - - // Handle copy statements: - // x = y && 'y' in src => add 'x' to dest - if (s instanceof DefinitionStmt) - { - DefinitionStmt as = (DefinitionStmt) s; - - Value ro = as.getRightOp(); - - // extract cast argument - if (ro instanceof CastExpr) ro = ((CastExpr) ro).getOp(); - - if (src.contains(ro) && as.getLeftOp() instanceof Local) - dest.add(as.getLeftOp()); - } - - // Copy the out value to the fallthrough box (don't need iterator) - { - Iterator it = fallOut.iterator(); - while (it.hasNext()) { - FlowSet fs = (FlowSet) (it.next()); - copy(dest, fs); - } - } - - // Copy the out value to all branch boxes. - { - Iterator it = branchOuts.iterator(); - while (it.hasNext()) { - FlowSet fs = (FlowSet) (it.next()); - copy(dest, fs); - } - } - - // Handle if statements by patching dest sets. - if (unit instanceof IfStmt) - { - Value cond = ((IfStmt)unit).getCondition(); - Value op1 = ((BinopExpr) cond).getOp1(); - Value op2 = ((BinopExpr) cond).getOp2(); - boolean isNeg = cond instanceof NeExpr; - Value toGen = null; - - // case 1: opN is a local and opM is NullConstant - // => opN nonnull on ne branch. - if (op1 instanceof Local && op2 instanceof NullConstant) - toGen = op1; - - if (op2 instanceof Local && op1 instanceof NullConstant) - toGen = op2; - - if (toGen != null) - { - Iterator it = null; - - // if (toGen != null) goto l1: on branch, toGen nonnull. - if (isNeg) - it = branchOuts.iterator(); - else - it = fallOut.iterator(); - - while(it.hasNext()) { - FlowSet fs = (FlowSet) (it.next()); - fs.add(toGen); - } - } - - // case 2: both ops are local and one op is non-null and testing equality - if (op1 instanceof Local && op2 instanceof Local && - cond instanceof EqExpr) - { - toGen = null; - - if (src.contains(op1)) - toGen = op2; - if (src.contains(op2)) - toGen = op1; - - if (toGen != null) - { - Iterator branchIt = branchOuts.iterator(); - while (branchIt.hasNext()) { - FlowSet fs = (FlowSet) (branchIt.next()); - fs.add(toGen); - } - } - } - } - } - - public JArena(UnitGraph g) { - super(g); - - unitToGenerateSet = new HashMap(); - - Body b = g.getBody(); - - List refLocals = new LinkedList(); - - // set up universe, empty, full sets. - - emptySet = new ArraySparseSet(); - fullSet = new ArraySparseSet(); - - // Find all locals in body. - Iterator localIt = b.getLocals().iterator(); - while (localIt.hasNext()) { - Local l = (Local)localIt.next(); - if (l.getType() instanceof RefLikeType) fullSet.add(l); - } - - // Create gen sets. - Iterator unitIt = b.getUnits().iterator(); - while (unitIt.hasNext()) { - Unit u = (Unit)unitIt.next(); - unitToGenerateSet.put(u, new ArraySparseSet()); - - if (u instanceof DefinitionStmt) { - Value lo = ((DefinitionStmt)u).getLeftOp(); - if (lo instanceof Local && lo.getType() instanceof RefLikeType) - addGensFor((DefinitionStmt)u); - } - - Iterator boxIt = u.getUseAndDefBoxes().iterator(); - while (boxIt.hasNext()) { - Value boxValue = ((ValueBox) boxIt.next()).getValue(); - Value base = null; - - if(boxValue instanceof InstanceFieldRef) { - base = ((InstanceFieldRef) (boxValue)).getBase(); - } else if (boxValue instanceof ArrayRef) { - base = ((ArrayRef) (boxValue)).getBase(); - } else if (boxValue instanceof InstanceInvokeExpr) { - base = ((InstanceInvokeExpr) boxValue).getBase(); - } else if (boxValue instanceof LengthExpr) { - base = ((LengthExpr) boxValue).getOp(); - } else if (u instanceof ThrowStmt) { - base = ((ThrowStmt)u).getOp(); - } else if (u instanceof MonitorStmt) { - base = ((MonitorStmt)u).getOp(); - } - - if (base != null && - base instanceof Local && - base.getType() instanceof RefLikeType) - addGen(u, base); - } - } - - // Call superclass method to do work. - doAnalysis(); - } -} - diff --git a/src/org/ibex/arenaj/GCBench.java b/src/org/ibex/arenaj/GCBench.java new file mode 100644 index 0000000..1507062 --- /dev/null +++ b/src/org/ibex/arenaj/GCBench.java @@ -0,0 +1,197 @@ +package org.ibex.arenaj; +// This is adapted from a benchmark written by John Ellis and Pete Kovac +// of Post Communications. +// It was modified by Hans Boehm of Silicon Graphics. +// +// This is no substitute for real applications. No actual application +// is likely to behave in exactly this way. However, this benchmark was +// designed to be more representative of real applications than other +// Java GC benchmarks of which we are aware. +// It attempts to model those properties of allocation requests that +// are important to current GC techniques. +// It is designed to be used either to obtain a single overall performance +// number, or to give a more detailed estimate of how collector +// performance varies with object lifetimes. It prints the time +// required to allocate and collect balanced binary trees of various +// sizes. Smaller trees result in shorter object lifetimes. Each cycle +// allocates roughly the same amount of memory. +// Two data structures are kept around during the entire process, so +// that the measured performance is representative of applications +// that maintain some live in-memory data. One of these is a tree +// containing many pointers. The other is a large array containing +// double precision floating point numbers. Both should be of comparable +// size. +// +// The results are only really meaningful together with a specification +// of how much memory was used. It is possible to trade memory for +// better time performance. This benchmark should be run in a 32 MB +// heap, though we don't currently know how to enforce that uniformly. +// +// Unlike the original Ellis and Kovac benchmark, we do not attempt +// measure pause times. This facility should eventually be added back +// in. There are several reasons for omitting it for now. The original +// implementation depended on assumptions about the thread scheduler +// that don't hold uniformly. The results really measure both the +// scheduler and GC. Pause time measurements tend to not fit well with +// current benchmark suites. As far as we know, none of the current +// commercial Java implementations seriously attempt to minimize GC pause +// times. +// +// Known deficiencies: +// - No way to check on memory use +// - No cyclic data structures +// - No attempt to measure variation with object size +// - Results are sensitive to locking cost, but we dont +// check for proper locking + +public class GCBench { + + public static final int kStretchTreeDepth = 18; // about 16Mb + public static final int kLongLivedTreeDepth = 16; // about 4Mb + public static final int kArraySize = 500000; // about 4Mb + public static final int kMinTreeDepth = 4; + public static final int kMaxTreeDepth = 16; + + public static int zap(Object o) { return o==null ? -1 : ((Integer)o).intValue(); } + + // Nodes used by a tree of a given size + static int TreeSize(int i) { + return ((1 << (i + 1)) - 1); + } + + // Number of iterations to use for a given tree depth + static int NumIters(int i) { + return 2 * TreeSize(kStretchTreeDepth) / TreeSize(i); + } + + // Build tree top down, assigning to older objects. + void Populate(int iDepth) { Populate(iDepth, new Node()); } + void Populate(int iDepth, Node thisNode) { + if (iDepth<=0) { + return; + } else { + iDepth--; + thisNode.left = new Node(); + thisNode.right = new Node(); + Populate (iDepth, thisNode.left); + Populate (iDepth, thisNode.right); + } + } + + // Build tree bottom-up + void doMakeTree(int iDepth) { MakeTree(iDepth); } + Node MakeTree(int iDepth) { + if (iDepth<=0) { + return new Node(); + } else { + Node l = MakeTree(iDepth-1); + Node r = MakeTree(iDepth-1); + Node ret = new Node(); + ret.left = l; + ret.right = r; + return ret; + } + } + + static void PrintDiagnostics() { + long lFreeMemory = Runtime.getRuntime().freeMemory(); + long lTotalMemory = Runtime.getRuntime().totalMemory(); + + System.out.print(" Total memory available=" + + lTotalMemory + " bytes"); + System.out.println(" Free memory=" + lFreeMemory + " bytes"); + } + + void TimeConstruction(int depth) { + Node root; + long tStart, tFinish; + int iNumIters = NumIters(depth); + GCBench tempTree; + + System.out.println("Creating " + iNumIters + + " trees of depth " + depth); + tStart = System.currentTimeMillis(); + for (int i = 0; i < iNumIters; ++i) { + tempTree = new GCBench(); + tempTree.Populate(depth); + tempTree = null; + } + tFinish = System.currentTimeMillis(); + System.out.println("\tTop down construction took " + + (tFinish - tStart) + "msecs"); + tStart = System.currentTimeMillis(); + for (int i = 0; i < iNumIters; ++i) { + tempTree = new GCBench(); + tempTree.doMakeTree(depth); + tempTree = null; + } + tFinish = System.currentTimeMillis(); + System.out.println("\tBottom up construction took " + + (tFinish - tStart) + "msecs"); + + } + + public static void main(String args[]) { + Node root; + Node longLivedTree; + Node tempTree; + long tStart, tFinish; + long tElapsed; + + + System.out.println("Garbage Collector Test"); + System.out.println( + " Stretching memory with a binary tree of depth " + + kStretchTreeDepth); + PrintDiagnostics(); + tStart = System.currentTimeMillis(); + + // Stretch the memory space quickly + GCBench gcb = new GCBench(); + gcb.doMakeTree(kStretchTreeDepth); + gcb = null; + + // Create a long lived object + System.out.println( + " Creating a long-lived binary tree of depth " + + kLongLivedTreeDepth); + GCBench ll = new GCBench(); + ll.Populate(kLongLivedTreeDepth); + + /* + // Create long-lived array, filling half of it + System.out.println( + " Creating a long-lived array of " + + kArraySize + " doubles"); + double array[] = new double[kArraySize]; + for (int i = 0; i < kArraySize/2; ++i) { + array[i] = 1.0/i; + } + */ + PrintDiagnostics(); + + for (int d = kMinTreeDepth; d <= kMaxTreeDepth; d += 2) { + ll.TimeConstruction(d); + } + /* + if (longLivedTree == null || array[1000] != 1.0/1000) + System.out.println("Failed"); + */ + // fake reference to LongLivedTree + // and array + // to keep them from being optimized away + + tFinish = System.currentTimeMillis(); + tElapsed = tFinish-tStart; + PrintDiagnostics(); + System.out.println("Completed in " + tElapsed + "ms."); + } + + private class Node implements Gladiator { + Node left, right; + int i, j; + //Node(Node l, Node r) { left = l; right = r; } + Node() { } + } + +} // class JavaGC diff --git a/src/org/ibex/arenaj/Gladiator.java b/src/org/ibex/arenaj/Gladiator.java new file mode 100644 index 0000000..1b043d5 --- /dev/null +++ b/src/org/ibex/arenaj/Gladiator.java @@ -0,0 +1,4 @@ +package org.ibex.arenaj; + +public interface Gladiator { +} diff --git a/src/edu/berkeley/cs/megacz/Transformer.java b/src/org/ibex/arenaj/Main.java similarity index 86% rename from src/edu/berkeley/cs/megacz/Transformer.java rename to src/org/ibex/arenaj/Main.java index 8473f80..27e2643 100644 --- a/src/edu/berkeley/cs/megacz/Transformer.java +++ b/src/org/ibex/arenaj/Main.java @@ -1,29 +1,53 @@ -package edu.berkeley.cs.megacz; +package org.ibex.arenaj; import soot.*; import soot.jimple.*; import soot.util.*; import java.io.*; import java.util.*; -public class Transformer extends SceneTransformer { +public class Main extends SceneTransformer { public static final int initialSize = 100; - private static Transformer instance = new Transformer(); - private Transformer() { - } - public static Transformer v() { return instance; } + private static Main instance = new Main(); + private Main() { } + public static Main v() { return instance; } - public static void main(String[] args) { + public static void main(String[] args) throws Exception { 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); + PackManager.v().getPack("wjtp").add(new Transform("wjtp.tx", Main.v())); + String[] args2 = new String[args.length + 11]; + System.arraycopy(args, 0, args2, 0, args.length-1); + String sootcp = + System.getProperty("java.class.path") + + File.pathSeparator + + System.getProperty("sun.boot.class.path"); + if (System.getProperty("java.ext.dirs") != null) { + StringTokenizer st = new StringTokenizer(File.pathSeparatorChar+"", System.getProperty("java.ext.dirs")); + while(st.hasMoreTokens()) { + File f = new File(st.nextToken()); + if (!f.exists() || !f.isDirectory()) continue; + String[] jars = f.list(); + for(int i=0; i")) 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); @@ -268,7 +290,6 @@ public class Transformer extends SceneTransformer { 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)); } } @@ -281,11 +302,9 @@ public class Transformer extends SceneTransformer { 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)); } } @@ -325,10 +344,8 @@ public class Transformer extends SceneTransformer { } 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); + SootClass mc = getParent(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); @@ -339,9 +356,7 @@ public class Transformer extends SceneTransformer { } 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(); + SootClass mc = getParent(((RefType)ce.getCastType()).getSootClass()); LinkedList list = new LinkedList(); list.add(Scene.v().getSootClass("java.lang.Object").getType()); SootMethodRef mr = Scene.v().makeMethodRef(mc, "zap", list, IntType.v(), true); @@ -356,7 +371,7 @@ public class Transformer extends SceneTransformer { SootFieldRef fr = ifr.getFieldRef(); Type t = fr.type(); if (isGladiatorFieldRef(fr)) { - SootClass mc = Scene.v().getMainClass(); + SootClass mc = getParent(fr.declaringClass()); SootFieldRef sf = getGladiatorField(fr).makeRef(); InstanceFieldRef sfr = Jimple.v().newInstanceFieldRef(body.getThisLocal(), sf); ArrayRef ar = Jimple.v().newArrayRef(viaLocal(sfr, body, s), ifr.getBase()); @@ -364,7 +379,7 @@ public class Transformer extends SceneTransformer { } if ((t instanceof RefType) && isGladiator(((RefType)t).getSootClass())) { SootClass tc = ((RefType)t).getSootClass(); - SootClass mc = Scene.v().getMainClass(); + SootClass mc = getParent(tc); ifr.setFieldRef(Scene.v().makeFieldRef(mc, fr.name(), IntType.v(), false)); } } diff --git a/src/edu/berkeley/cs/megacz/Test.java b/src/org/ibex/arenaj/Test.java similarity index 91% rename from src/edu/berkeley/cs/megacz/Test.java rename to src/org/ibex/arenaj/Test.java index eca2504..94d97e9 100644 --- a/src/edu/berkeley/cs/megacz/Test.java +++ b/src/org/ibex/arenaj/Test.java @@ -1,4 +1,4 @@ -package edu.berkeley.cs.megacz; +package org.ibex.arenaj; public class Test { public static void main(String[] s) {