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");