Mercurial > hg > truffle
changeset 3219:e41017cddf3a
more comments on examples, extended deopt example
author | Lukas Stadler <lukas.stadler@jku.at> |
---|---|
date | Thu, 14 Jul 2011 15:41:13 +0200 |
parents | 3d66094eeda1 |
children | 9518546712e1 |
files | graal/com.oracle.max.graal.examples/runexample.sh graal/com.oracle.max.graal.examples/src/com/oracle/max/graal/examples/deopt/DeoptExample.java graal/com.oracle.max.graal.examples/src/com/oracle/max/graal/examples/deopt/DeoptHandler.java graal/com.oracle.max.graal.examples/src/com/oracle/max/graal/examples/deopt/FrameModifierImpl.java graal/com.oracle.max.graal.examples/src/com/oracle/max/graal/examples/opt/OptimizerImpl.java |
diffstat | 5 files changed, 98 insertions(+), 30 deletions(-) [+] |
line wrap: on
line diff
--- a/graal/com.oracle.max.graal.examples/runexample.sh Thu Jul 14 10:33:35 2011 +0200 +++ b/graal/com.oracle.max.graal.examples/runexample.sh Thu Jul 14 15:41:13 2011 +0200 @@ -18,6 +18,6 @@ TEST=$1 shift ant -f create_examples.xml -COMMAND="${JDK7}/bin/java -client -d64 -graal -Xmx1g -esa -G:Extend -G:Plot -G:CacheGraphs -XX:+PrintCompilation -Xcomp -XX:CompileOnly=examples -XX:CompileCommand=quiet -XX:CompileCommand=exclude,*,<init> -XX:CompileCommand=exclude,*,run -XX:CompileCommand=exclude,com.oracle.max.graal.examples.Main::main $* -jar examples.jar ${TEST}" +COMMAND="${JDK7}/bin/java -client -d64 -graal -Xmx1g -esa -ea -G:Extend -G:CacheGraphs -XX:+PrintCompilation -Xcomp -XX:CompileOnly=examples -XX:CompileCommand=quiet -XX:CompileCommand=exclude,*,<init> -XX:CompileCommand=exclude,*,<clinit> -XX:CompileCommand=exclude,*,run -XX:CompileCommand=exclude,com.oracle.max.graal.examples.Main::main $* -jar examples.jar ${TEST}" # echo $COMMAND $COMMAND
--- a/graal/com.oracle.max.graal.examples/src/com/oracle/max/graal/examples/deopt/DeoptExample.java Thu Jul 14 10:33:35 2011 +0200 +++ b/graal/com.oracle.max.graal.examples/src/com/oracle/max/graal/examples/deopt/DeoptExample.java Thu Jul 14 15:41:13 2011 +0200 @@ -32,20 +32,20 @@ System.out.println(); System.out.println("Running Deopt Example"); long start = System.currentTimeMillis(); - System.out.println("result1=" + test()); + System.out.println("result1=" + new DeoptExample().test()); System.out.println("time=" + (System.currentTimeMillis() - start) + "ms"); } - private static int test() { + private int test() { try { - return testDeopt(3000000); + return testDeopt(90000); } catch (IllegalStateException e) { System.out.println(e.getMessage()); return 0; } } - private static int testDeopt(int n) { + private int testDeopt(int n) { int sum = 0; for (int i = 0; i < n; i = SafeAddExample.safeAdd(i, 1)) { sum = SafeAddExample.safeAdd(sum, i);
--- a/graal/com.oracle.max.graal.examples/src/com/oracle/max/graal/examples/deopt/DeoptHandler.java Thu Jul 14 10:33:35 2011 +0200 +++ b/graal/com.oracle.max.graal.examples/src/com/oracle/max/graal/examples/deopt/DeoptHandler.java Thu Jul 14 15:41:13 2011 +0200 @@ -22,14 +22,58 @@ */ package com.oracle.max.graal.examples.deopt; +import java.lang.reflect.*; + +import com.sun.cri.ri.*; + public class DeoptHandler { + /** + * Deoptimization handler method for methods with a void return parameter. + */ + public void handle_void(RiMethod method, int bci, Object[] values, int numLocals, int numStack, int numLocks) { + handle(method, bci, values, numLocals, numStack, numLocks); + } - public static int test(int bci, Object[] values) { - System.out.println("values at bci " + bci + ": "); - for (Object value : values) { - System.out.print(value + " "); + /** + * Deoptimization handler method for methods with an int return parameter. + */ + public int handle_int(RiMethod method, int bci, Object[] values, int numLocals, int numStack, int numLocks) { + handle(method, bci, values, numLocals, numStack, numLocks); + return 123; + } + + /** + * Deoptimization handler method for methods with an object return parameter. + */ + public Object handle_object(RiMethod method, int bci, Object[] values, int numLocals, int numStack, int numLocks) { + handle(method, bci, values, numLocals, numStack, numLocks); + return null; + } + + /** + * Deoptimization handler method: prints the current state of the method execution. + */ + public int handle(RiMethod method, int bci, Object[] values, int numLocals, int numStack, int numLocks) { + System.out.printf("Deoptimization: %s@%d", method.name(), bci); + int p = 0; + System.out.print("\nArguments: "); + int argCount = method.signature().argumentCount(!Modifier.isStatic(method.accessFlags())); + for (int i = 0; i < argCount; i++) { + System.out.printf("%s ", values[p++]); + } + System.out.print("\nLocals: "); + for (int i = argCount; i < numLocals; i++) { + System.out.printf("%s ", values[p++]); + } + System.out.print("\nExpression stack: "); + for (int i = 0; i < numStack; i++) { + System.out.printf("%s ", values[p++]); + } + System.out.print("\nLocks: "); + for (int i = 0; i < numLocks; i++) { + System.out.printf("%s ", values[p++]); } System.out.println(); return 2;
--- a/graal/com.oracle.max.graal.examples/src/com/oracle/max/graal/examples/deopt/FrameModifierImpl.java Thu Jul 14 10:33:35 2011 +0200 +++ b/graal/com.oracle.max.graal.examples/src/com/oracle/max/graal/examples/deopt/FrameModifierImpl.java Thu Jul 14 15:41:13 2011 +0200 @@ -22,38 +22,54 @@ */ package com.oracle.max.graal.examples.deopt; +import java.util.*; + import com.oracle.max.graal.extensions.*; import com.sun.cri.ci.*; +import com.sun.cri.ci.CiVirtualObject.*; import com.sun.cri.ri.*; public class FrameModifierImpl implements FrameModifier { + private static DeoptHandler HANDLER = new DeoptHandler(); @Override public CiFrame getFrame(RiRuntime runtime, CiFrame frame) { - try { - DeoptHandler.class.getMethod("test", Integer.TYPE, Object[].class); - } catch (Exception e) { - e.printStackTrace(); - return frame; - } if (frame.method.name().equals("testDeopt")) { + // get the handler method RiType type = runtime.getType(DeoptHandler.class); - RiMethod method = type.getMethod("test", "(I[Ljava/lang/Object;)I"); - System.out.println("Size: " + method.maxLocals() + " " + method.maxStackSize()); - RiType arrayType = runtime.getType(Object.class).arrayOf(); - CiValue[] values = new CiValue[frame.values.length]; - for (int i = 0; i < values.length; i++) { - values[i] = CiVirtualObject.proxy(runtime, frame.values[i], i + 2); + CiKind returnKind = frame.method.signature().returnKind(); + String methodName = "handle_" + returnKind; + String methodSignature = "(Lcom/sun/cri/ri/RiMethod;I[Ljava/lang/Object;III)" + returnKind.signatureChar(); + RiMethod handlerMethod = type.getMethod(methodName, methodSignature); + assert handlerMethod != null : methodName + " not found..."; + + // put the current state (local vars, expressions, etc.) into an array + CiVirtualObjectFactory factory = new CiVirtualObjectFactory(runtime); + ArrayList<CiValue> originalValues = new ArrayList<CiValue>(); + for (int i = 0; i < frame.values.length; i += frame.values[i].kind.sizeInSlots()) { + originalValues.add(factory.proxy(frame.values[i])); } - CiVirtualObject local = CiVirtualObject.get(arrayType, values, 0); - CiValue[] values2 = new CiValue[method.maxLocals()]; - values2[0] = CiConstant.forInt(frame.bci); - values2[1] = local; - for (int i = 2; i < values2.length; i++) { - values2[i] = CiValue.IllegalValue; + CiValue boxedValues = factory.arrayProxy(runtime.getType(Object[].class), originalValues.toArray(new CiValue[originalValues.size()])); + + // build the list of arguments + CiValue[] newValues = new CiValue[handlerMethod.maxLocals()]; + int p = 0; + newValues[p++] = CiConstant.forObject(HANDLER); // receiver + newValues[p++] = CiConstant.forObject(frame.method); // method that caused deoptimization + newValues[p++] = CiConstant.forInt(frame.bci); // bytecode index + newValues[p++] = boxedValues; // original locals, expression stack and locks + newValues[p++] = CiConstant.forInt(frame.numLocals); // number of locals + newValues[p++] = CiConstant.forInt(frame.numStack); // size of expression stack + newValues[p++] = CiConstant.forInt(frame.numLocks); // number of locks + + // fill the rest of the local variables with zeros + while (p < newValues.length) { + newValues[p++] = CiValue.IllegalValue; } - return new CiFrame((CiFrame) frame.caller, method, 0, false, values2, method.maxLocals(), 0, 0); + + // ... and return a new frame that points to the start of the handler method + return new CiFrame((CiFrame) frame.caller, handlerMethod, /*bci*/ 0, false, newValues, handlerMethod.maxLocals(), 0, 0); } return frame; }
--- a/graal/com.oracle.max.graal.examples/src/com/oracle/max/graal/examples/opt/OptimizerImpl.java Thu Jul 14 10:33:35 2011 +0200 +++ b/graal/com.oracle.max.graal.examples/src/com/oracle/max/graal/examples/opt/OptimizerImpl.java Thu Jul 14 15:41:13 2011 +0200 @@ -36,8 +36,10 @@ @Override public void optimize(RiRuntime runtime, Graph graph) { + // iterate over all instanceof of SafeAddNode in the graph for (SafeAddNode safeAdd : graph.getNodes(SafeAddNode.class)) { if (!canOverflow(safeAdd)) { + // if an overflow is impossible: replace with normal add IntegerAdd add = new IntegerAdd(CiKind.Int, safeAdd.x(), safeAdd.y(), graph); safeAdd.replaceAndDelete(add); } @@ -45,11 +47,15 @@ } private boolean canOverflow(SafeAddNode safeAdd) { + // if this SafeAddNode always adds 1 ... if (safeAdd.y().isConstant() && safeAdd.y().asConstant().asLong() == 1) { + // ... to a phi ... if (safeAdd.x() instanceof Phi) { Phi phi = (Phi) safeAdd.x(); + // ... that belongs to a loop and merges into itself ... if (phi.merge() instanceof LoopBegin && phi.valueAt(1) == safeAdd) { LoopBegin loopBegin = (LoopBegin) phi.merge(); + // ... then do the heavy analysis. return canOverflow(phi, loopBegin); } } @@ -58,14 +64,16 @@ } private boolean canOverflow(Phi phi, LoopBegin loopBegin) { - NodeBitMap nodes = LoopUtil.markUpCFG(loopBegin); NodeBitMap exits = LoopUtil.computeLoopExits(loopBegin, nodes); + // look at all loop exits: for (Node exit : exits) { TTY.println("exit: " + exit); Node pred = exit.predecessors().get(0); + // if this exit is an If node ... if (pred instanceof If) { If ifNode = (If) pred; + // ... which compares ... if (ifNode.compare() instanceof Compare) { Compare compare = (Compare) ifNode.compare(); Condition cond = compare.condition(); @@ -74,6 +82,7 @@ if (ifNode.trueSuccessor() == pred) { cond = cond.negate(); } + // ... the phi against a value, then this phi cannot overflow. if (cond == Condition.LT && x == phi) { return false; } @@ -81,7 +90,6 @@ return false; } } - } } TTY.println("can overflow");