changeset 5765:8d0a6bceb112

fixed result value for (high-level interpreter -> native -> Java transitions)
author Christian Haeubl <haeubl@ssw.jku.at>
date Thu, 05 Jul 2012 14:09:53 +0200
parents 66ec0bc36a37
children 99567466b008
files graal/com.oracle.graal.interpreter/src/com/oracle/graal/interpreter/BytecodeInterpreter.java graal/com.oracle.graal.interpreter/src/com/oracle/graal/interpreter/InterpreterFrame.java src/share/vm/graal/graalVMToInterpreter.cpp src/share/vm/runtime/javaCalls.cpp
diffstat 4 files changed, 342 insertions(+), 344 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.interpreter/src/com/oracle/graal/interpreter/BytecodeInterpreter.java	Wed Jul 04 22:01:03 2012 +0200
+++ b/graal/com.oracle.graal.interpreter/src/com/oracle/graal/interpreter/BytecodeInterpreter.java	Thu Jul 05 14:09:53 2012 +0200
@@ -31,17 +31,8 @@
 import com.oracle.graal.bytecode.*;
 
 /**
- *
- * <h1>Implementation notes</h1>
- * <li>Native methods are invoked using standard java reflection.</li>
- *
- * <h1>Features:</h1>
- *
- *
- * <h1>Limitations:</h1>
- *
- * <li>The interpreter is not able to recognize a native method that calls a java method.
- *  In that case the java method will be interpreted directly on the vm interpreter.</li>
+ * High-level bytecode interpreter that executes on top of Java. Java native methods
+ * are executed using the {@link com.oracle.graal.api.interpreter.RuntimeInterpreterInterface}.
  */
 @SuppressWarnings("static-method")
 public final class BytecodeInterpreter implements Interpreter {
@@ -62,7 +53,6 @@
     private Map<ResolvedJavaMethod, MethodRedirectionInfo> methodDelegates;
 
     private int maxStackFrames;
-    private int stackFrameDepth;
 
     private ResolvedJavaMethod rootMethod;
     private RuntimeInterpreterInterface runtimeInterface;
@@ -95,36 +85,39 @@
     }
 
     private void registerDelegates() {
-       addDelegate(findMethod(Throwable.class, "fillInStackTrace"), new InterpreterCallable() {
-        @Override
-        public Object invoke(InterpreterFrame caller, ResolvedJavaMethod method, Object[] arguments) throws Throwable {
-            setBackTrace(caller, (Throwable) arguments[0], createStackTraceElements(caller));
-            return null;
-        }
-       });
-       addDelegate(findMethod(Throwable.class, "getStackTraceDepth"), new InterpreterCallable() {
-           @Override
-           public Object invoke(InterpreterFrame caller, ResolvedJavaMethod method, Object[] arguments) throws Throwable {
-               StackTraceElement[] elements = getBackTrace(caller, (Throwable) arguments[0]);
-               if (elements != null) {
-                   return elements.length;
-               }
-               return 0;
-           }
-       });
-       addDelegate(findMethod(Throwable.class, "getStackTraceElement", int.class), new InterpreterCallable() {
-           @Override
-           public Object invoke(InterpreterFrame caller, ResolvedJavaMethod method, Object[] arguments) throws Throwable {
-               StackTraceElement[] elements = getBackTrace(caller, (Throwable) arguments[0]);
-               if (elements != null) {
-                   Integer index = (Integer) arguments[0];
-                   if (index != null) {
-                       return elements[index];
-                   }
-               }
-               return null;
-           }
-       });
+        addDelegate(findMethod(Throwable.class, "fillInStackTrace"), new InterpreterCallable() {
+
+            @Override
+            public Object invoke(InterpreterFrame caller, ResolvedJavaMethod method, Object[] arguments) throws Throwable {
+                setBackTrace(caller, (Throwable) arguments[0], createStackTraceElements(caller));
+                return null;
+            }
+        });
+        addDelegate(findMethod(Throwable.class, "getStackTraceDepth"), new InterpreterCallable() {
+
+            @Override
+            public Object invoke(InterpreterFrame caller, ResolvedJavaMethod method, Object[] arguments) throws Throwable {
+                StackTraceElement[] elements = getBackTrace(caller, (Throwable) arguments[0]);
+                if (elements != null) {
+                    return elements.length;
+                }
+                return 0;
+            }
+        });
+        addDelegate(findMethod(Throwable.class, "getStackTraceElement", int.class), new InterpreterCallable() {
+
+            @Override
+            public Object invoke(InterpreterFrame caller, ResolvedJavaMethod method, Object[] arguments) throws Throwable {
+                StackTraceElement[] elements = getBackTrace(caller, (Throwable) arguments[0]);
+                if (elements != null) {
+                    Integer index = (Integer) arguments[0];
+                    if (index != null) {
+                        return elements[index];
+                    }
+                }
+                return null;
+            }
+        });
     }
 
     @SuppressWarnings("unused")
@@ -162,6 +155,10 @@
             assert boxedArguments != null;
             assert signature.argumentCount(receiver) == boxedArguments.length;
 
+            if (TRACE) {
+                trace(0, "Executing root method " + method);
+            }
+
             InterpreterFrame rootFrame = new InterpreterFrame(rootMethod, signature.argumentSlots(true));
             rootFrame.pushObject(this);
             rootFrame.pushObject(method);
@@ -173,7 +170,7 @@
                 index++;
             }
 
-            for (int i = 0; i < boxedArguments.length; i++, index++) {
+            for (int i = 0; index < boxedArguments.length; i++, index++) {
                 pushAsObject(rootFrame, signature.argumentKindAt(i), boxedArguments[index]);
             }
 
@@ -181,6 +178,7 @@
             executeRoot(rootFrame, frame);
             return popAsObject(rootFrame, signature.returnKind());
         } catch (Exception e) {
+            // TODO (chaeubl): remove this exception handler (only used for debugging)
             throw e;
         }
     }
@@ -194,9 +192,7 @@
     }
 
     private void executeRoot(InterpreterFrame root, InterpreterFrame frame) throws Throwable {
-        //TODO reflection redirection
-        stackFrameDepth = 0;
-
+        // TODO reflection redirection
         InterpreterFrame prevFrame = frame;
         InterpreterFrame currentFrame = frame;
         BytecodeStream bs = new BytecodeStream(currentFrame.getMethod().code());
@@ -220,17 +216,17 @@
             while (true) {
                 int result = executeInstruction(frame, bs);
                 switch (result) {
-                    case NEXT :
+                    case NEXT:
                         bs.next();
                         break;
-                    case RETURN :
+                    case RETURN:
                         return popFrame(frame);
                     case CALL:
                         return allocateFrame(frame, bs);
-                    case BRANCH :
+                    case BRANCH:
                         bs.setBCI(bs.readBranchDest());
                         break;
-                    default :
+                    default:
                         // the outcome depends on stack values
                         assert result >= 0 : "negative branch target";
                         bs.setBCI(result);
@@ -239,7 +235,7 @@
             }
         } catch (Throwable t) {
             if (TRACE) {
-                traceOp("Exception " + t.toString());
+                traceOp(frame, "Exception " + t.toString());
             }
             updateStackTrace(frame, t);
 
@@ -252,7 +248,7 @@
                 throw t;
             } else {
                 if (TRACE) {
-                    traceOp("Handler found " + handlerFrame.getMethod() + ":" + handlerFrame.getBCI());
+                    traceOp(frame, "Handler found " + handlerFrame.getMethod() + ":" + handlerFrame.getBCI());
                 }
                 // update bci from frame
                 bs.setBCI(handlerFrame.getBCI());
@@ -268,79 +264,80 @@
 
     private int executeInstruction(InterpreterFrame frame, BytecodeStream bs) throws Throwable {
         if (TRACE_BYTE_CODE) {
-            traceOp(bs.currentBCI() + ": " + Bytecodes.baseNameOf(bs.currentBC()));
+            traceOp(frame, bs.currentBCI() + ": " + Bytecodes.baseNameOf(bs.currentBC()));
         }
-        switch(bs.currentBC()) {
-            case Bytecodes.NOP            : break;
-            case Bytecodes.ACONST_NULL    :
+        switch (bs.currentBC()) {
+            case Bytecodes.NOP:
+                break;
+            case Bytecodes.ACONST_NULL:
                 frame.pushObject(null);
                 break;
-            case Bytecodes.ICONST_M1      :
+            case Bytecodes.ICONST_M1:
                 frame.pushInt(-1);
                 break;
-            case Bytecodes.ICONST_0       :
+            case Bytecodes.ICONST_0:
                 frame.pushInt(0);
                 break;
-            case Bytecodes.ICONST_1       :
+            case Bytecodes.ICONST_1:
                 frame.pushInt(1);
                 break;
-            case Bytecodes.ICONST_2       :
+            case Bytecodes.ICONST_2:
                 frame.pushInt(2);
                 break;
-            case Bytecodes.ICONST_3       :
+            case Bytecodes.ICONST_3:
                 frame.pushInt(3);
                 break;
-            case Bytecodes.ICONST_4       :
+            case Bytecodes.ICONST_4:
                 frame.pushInt(4);
                 break;
-            case Bytecodes.ICONST_5       :
+            case Bytecodes.ICONST_5:
                 frame.pushInt(5);
                 break;
-            case Bytecodes.LCONST_0       :
+            case Bytecodes.LCONST_0:
                 frame.pushLong(0L);
                 break;
-            case Bytecodes.LCONST_1       :
+            case Bytecodes.LCONST_1:
                 frame.pushLong(1L);
                 break;
-            case Bytecodes.FCONST_0       :
+            case Bytecodes.FCONST_0:
                 frame.pushFloat(0.0F);
                 break;
-            case Bytecodes.FCONST_1       :
+            case Bytecodes.FCONST_1:
                 frame.pushFloat(1.0F);
                 break;
-            case Bytecodes.FCONST_2       :
+            case Bytecodes.FCONST_2:
                 frame.pushFloat(2.0F);
                 break;
-            case Bytecodes.DCONST_0       :
+            case Bytecodes.DCONST_0:
                 frame.pushDouble(0.0D);
                 break;
-            case Bytecodes.DCONST_1       :
+            case Bytecodes.DCONST_1:
                 frame.pushDouble(1.0D);
                 break;
-            case Bytecodes.BIPUSH         :
+            case Bytecodes.BIPUSH:
                 frame.pushInt(bs.readByte());
                 break;
-            case Bytecodes.SIPUSH         :
+            case Bytecodes.SIPUSH:
                 frame.pushInt(bs.readShort());
                 break;
-            case Bytecodes.LDC            :
-            case Bytecodes.LDC_W          :
-            case Bytecodes.LDC2_W         :
+            case Bytecodes.LDC:
+            case Bytecodes.LDC_W:
+            case Bytecodes.LDC2_W:
                 pushCPConstant(frame, bs.readCPI());
                 break;
-            case Bytecodes.ILOAD          :
+            case Bytecodes.ILOAD:
                 frame.pushInt(frame.getInt(frame.resolveLocalIndex(bs.readLocalIndex())));
                 break;
-            case Bytecodes.LLOAD          :
+            case Bytecodes.LLOAD:
                 frame.pushLong(frame.getLong(frame.resolveLocalIndex(bs.readLocalIndex())));
                 break;
-            case Bytecodes.FLOAD          :
+            case Bytecodes.FLOAD:
                 frame.pushFloat(frame.getFloat(frame.resolveLocalIndex(bs.readLocalIndex())));
                 break;
-            case Bytecodes.DLOAD          :
+            case Bytecodes.DLOAD:
                 frame.pushDouble(frame.getDouble(frame.resolveLocalIndex(bs.readLocalIndex())));
                 break;
-            case Bytecodes.ALOAD          :
+            case Bytecodes.ALOAD:
                 frame.pushObject(frame.getObject(frame.resolveLocalIndex(bs.readLocalIndex())));
                 break;
             case Bytecodes.ILOAD_0:
@@ -355,441 +352,441 @@
             case Bytecodes.ILOAD_3:
                 frame.pushInt(frame.getInt(frame.resolveLocalIndex(3)));
                 break;
-            case Bytecodes.LLOAD_0        :
+            case Bytecodes.LLOAD_0:
                 frame.pushLong(frame.getLong(frame.resolveLocalIndex(0)));
                 break;
-            case Bytecodes.LLOAD_1        :
+            case Bytecodes.LLOAD_1:
                 frame.pushLong(frame.getLong(frame.resolveLocalIndex(1)));
                 break;
-            case Bytecodes.LLOAD_2        :
+            case Bytecodes.LLOAD_2:
                 frame.pushLong(frame.getLong(frame.resolveLocalIndex(2)));
                 break;
-            case Bytecodes.LLOAD_3        :
+            case Bytecodes.LLOAD_3:
                 frame.pushLong(frame.getLong(frame.resolveLocalIndex(3)));
                 break;
-            case Bytecodes.FLOAD_0        :
+            case Bytecodes.FLOAD_0:
                 frame.pushFloat(frame.getFloat(frame.resolveLocalIndex(0)));
                 break;
-            case Bytecodes.FLOAD_1        :
+            case Bytecodes.FLOAD_1:
                 frame.pushFloat(frame.getFloat(frame.resolveLocalIndex(1)));
                 break;
-            case Bytecodes.FLOAD_2        :
+            case Bytecodes.FLOAD_2:
                 frame.pushFloat(frame.getFloat(frame.resolveLocalIndex(2)));
                 break;
-            case Bytecodes.FLOAD_3        :
+            case Bytecodes.FLOAD_3:
                 frame.pushFloat(frame.getFloat(frame.resolveLocalIndex(3)));
                 break;
-            case Bytecodes.DLOAD_0        :
+            case Bytecodes.DLOAD_0:
                 frame.pushDouble(frame.getDouble(frame.resolveLocalIndex(0)));
                 break;
-            case Bytecodes.DLOAD_1        :
+            case Bytecodes.DLOAD_1:
                 frame.pushDouble(frame.getDouble(frame.resolveLocalIndex(1)));
                 break;
-            case Bytecodes.DLOAD_2        :
+            case Bytecodes.DLOAD_2:
                 frame.pushDouble(frame.getDouble(frame.resolveLocalIndex(2)));
                 break;
-            case Bytecodes.DLOAD_3        :
+            case Bytecodes.DLOAD_3:
                 frame.pushDouble(frame.getDouble(frame.resolveLocalIndex(3)));
                 break;
-            case Bytecodes.ALOAD_0        :
+            case Bytecodes.ALOAD_0:
                 frame.pushObject(frame.getObject(frame.resolveLocalIndex(0)));
                 break;
-            case Bytecodes.ALOAD_1        :
+            case Bytecodes.ALOAD_1:
                 frame.pushObject(frame.getObject(frame.resolveLocalIndex(1)));
                 break;
-            case Bytecodes.ALOAD_2        :
+            case Bytecodes.ALOAD_2:
                 frame.pushObject(frame.getObject(frame.resolveLocalIndex(2)));
                 break;
-            case Bytecodes.ALOAD_3        :
+            case Bytecodes.ALOAD_3:
                 frame.pushObject(frame.getObject(frame.resolveLocalIndex(3)));
                 break;
-            case Bytecodes.IALOAD         :
+            case Bytecodes.IALOAD:
                 frame.pushInt(runtimeInterface.getArrayInt(frame.popInt(), frame.popObject()));
                 break;
-            case Bytecodes.LALOAD         :
+            case Bytecodes.LALOAD:
                 frame.pushLong(runtimeInterface.getArrayLong(frame.popInt(), frame.popObject()));
                 break;
-            case Bytecodes.FALOAD         :
+            case Bytecodes.FALOAD:
                 frame.pushFloat(runtimeInterface.getArrayFloat(frame.popInt(), frame.popObject()));
                 break;
-            case Bytecodes.DALOAD         :
+            case Bytecodes.DALOAD:
                 frame.pushDouble(runtimeInterface.getArrayDouble(frame.popInt(), frame.popObject()));
                 break;
-            case Bytecodes.AALOAD         :
+            case Bytecodes.AALOAD:
                 frame.pushObject(runtimeInterface.getArrayObject(frame.popInt(), frame.popObject()));
                 break;
-            case Bytecodes.BALOAD         :
+            case Bytecodes.BALOAD:
                 frame.pushInt(runtimeInterface.getArrayByte(frame.popInt(), frame.popObject()));
                 break;
-            case Bytecodes.CALOAD         :
+            case Bytecodes.CALOAD:
                 frame.pushInt(runtimeInterface.getArrayChar(frame.popInt(), frame.popObject()));
                 break;
-             case Bytecodes.SALOAD:
+            case Bytecodes.SALOAD:
                 frame.pushInt(runtimeInterface.getArrayShort(frame.popInt(), frame.popObject()));
                 break;
             case Bytecodes.ISTORE:
                 frame.setInt(frame.resolveLocalIndex(bs.readLocalIndex()), frame.popInt());
                 break;
-            case Bytecodes.LSTORE         :
+            case Bytecodes.LSTORE:
                 frame.setLong(frame.resolveLocalIndex(bs.readLocalIndex()), frame.popLong());
                 break;
-            case Bytecodes.FSTORE         :
+            case Bytecodes.FSTORE:
                 frame.setFloat(frame.resolveLocalIndex(bs.readLocalIndex()), frame.popFloat());
                 break;
-            case Bytecodes.DSTORE         :
+            case Bytecodes.DSTORE:
                 frame.setDouble(frame.resolveLocalIndex(bs.readLocalIndex()), frame.popDouble());
                 break;
-            case Bytecodes.ASTORE         :
+            case Bytecodes.ASTORE:
                 frame.setObject(frame.resolveLocalIndex(bs.readLocalIndex()), frame.popObject());
                 break;
-            case Bytecodes.ISTORE_0       :
+            case Bytecodes.ISTORE_0:
                 frame.setInt(frame.resolveLocalIndex(0), frame.popInt());
                 break;
-            case Bytecodes.ISTORE_1       :
+            case Bytecodes.ISTORE_1:
                 frame.setInt(frame.resolveLocalIndex(1), frame.popInt());
                 break;
-            case Bytecodes.ISTORE_2       :
+            case Bytecodes.ISTORE_2:
                 frame.setInt(frame.resolveLocalIndex(2), frame.popInt());
                 break;
-            case Bytecodes.ISTORE_3       :
+            case Bytecodes.ISTORE_3:
                 frame.setInt(frame.resolveLocalIndex(3), frame.popInt());
                 break;
-            case Bytecodes.LSTORE_0       :
+            case Bytecodes.LSTORE_0:
                 frame.setLong(frame.resolveLocalIndex(0), frame.popLong());
                 break;
-            case Bytecodes.LSTORE_1       :
+            case Bytecodes.LSTORE_1:
                 frame.setLong(frame.resolveLocalIndex(1), frame.popLong());
                 break;
-            case Bytecodes.LSTORE_2       :
+            case Bytecodes.LSTORE_2:
                 frame.setLong(frame.resolveLocalIndex(2), frame.popLong());
                 break;
-            case Bytecodes.LSTORE_3       :
+            case Bytecodes.LSTORE_3:
                 frame.setLong(frame.resolveLocalIndex(3), frame.popLong());
                 break;
-            case Bytecodes.FSTORE_0       :
+            case Bytecodes.FSTORE_0:
                 frame.setFloat(frame.resolveLocalIndex(0), frame.popFloat());
                 break;
-            case Bytecodes.FSTORE_1       :
+            case Bytecodes.FSTORE_1:
                 frame.setFloat(frame.resolveLocalIndex(1), frame.popFloat());
                 break;
-            case Bytecodes.FSTORE_2       :
+            case Bytecodes.FSTORE_2:
                 frame.setFloat(frame.resolveLocalIndex(2), frame.popFloat());
                 break;
-            case Bytecodes.FSTORE_3       :
+            case Bytecodes.FSTORE_3:
                 frame.setFloat(frame.resolveLocalIndex(3), frame.popFloat());
                 break;
-            case Bytecodes.DSTORE_0       :
+            case Bytecodes.DSTORE_0:
                 frame.setDouble(frame.resolveLocalIndex(0), frame.popDouble());
                 break;
-            case Bytecodes.DSTORE_1       :
+            case Bytecodes.DSTORE_1:
                 frame.setDouble(frame.resolveLocalIndex(1), frame.popDouble());
                 break;
-            case Bytecodes.DSTORE_2       :
+            case Bytecodes.DSTORE_2:
                 frame.setDouble(frame.resolveLocalIndex(2), frame.popDouble());
                 break;
-            case Bytecodes.DSTORE_3       :
+            case Bytecodes.DSTORE_3:
                 frame.setDouble(frame.resolveLocalIndex(3), frame.popDouble());
                 break;
-            case Bytecodes.ASTORE_0       :
+            case Bytecodes.ASTORE_0:
                 frame.setObject(frame.resolveLocalIndex(0), frame.popObject());
                 break;
-            case Bytecodes.ASTORE_1       :
+            case Bytecodes.ASTORE_1:
                 frame.setObject(frame.resolveLocalIndex(1), frame.popObject());
                 break;
-            case Bytecodes.ASTORE_2       :
+            case Bytecodes.ASTORE_2:
                 frame.setObject(frame.resolveLocalIndex(2), frame.popObject());
                 break;
-            case Bytecodes.ASTORE_3       :
+            case Bytecodes.ASTORE_3:
                 frame.setObject(frame.resolveLocalIndex(3), frame.popObject());
                 break;
-            case Bytecodes.IASTORE        :
+            case Bytecodes.IASTORE:
                 runtimeInterface.setArrayInt(frame.popInt(), frame.popInt(), frame.popObject());
                 break;
-            case Bytecodes.LASTORE        :
+            case Bytecodes.LASTORE:
                 runtimeInterface.setArrayLong(frame.popLong(), frame.popInt(), frame.popObject());
                 break;
-            case Bytecodes.FASTORE        :
+            case Bytecodes.FASTORE:
                 runtimeInterface.setArrayFloat(frame.popFloat(), frame.popInt(), frame.popObject());
                 break;
-            case Bytecodes.DASTORE        :
+            case Bytecodes.DASTORE:
                 runtimeInterface.setArrayDouble(frame.popDouble(), frame.popInt(), frame.popObject());
                 break;
-            case Bytecodes.AASTORE        :
+            case Bytecodes.AASTORE:
                 runtimeInterface.setArrayObject(frame.popObject(), frame.popInt(), frame.popObject());
                 break;
-            case Bytecodes.BASTORE        :
+            case Bytecodes.BASTORE:
                 runtimeInterface.setArrayByte((byte) frame.popInt(), frame.popInt(), frame.popObject());
                 break;
-            case Bytecodes.CASTORE        :
+            case Bytecodes.CASTORE:
                 runtimeInterface.setArrayChar((char) frame.popInt(), frame.popInt(), frame.popObject());
                 break;
-            case Bytecodes.SASTORE        :
+            case Bytecodes.SASTORE:
                 runtimeInterface.setArrayShort((short) frame.popInt(), frame.popInt(), frame.popObject());
                 break;
-            case Bytecodes.POP            :
+            case Bytecodes.POP:
                 frame.popVoid(1);
                 break;
-            case Bytecodes.POP2           :
+            case Bytecodes.POP2:
                 frame.popVoid(2);
                 break;
-            case Bytecodes.DUP            :
+            case Bytecodes.DUP:
                 frame.dup(1);
                 break;
-            case Bytecodes.DUP_X1         :
+            case Bytecodes.DUP_X1:
                 frame.dupx1();
                 break;
-            case Bytecodes.DUP_X2         :
+            case Bytecodes.DUP_X2:
                 frame.dupx2();
                 break;
-            case Bytecodes.DUP2           :
+            case Bytecodes.DUP2:
                 frame.dup(2);
                 break;
-            case Bytecodes.DUP2_X1        :
+            case Bytecodes.DUP2_X1:
                 frame.dup2x1();
                 break;
-            case Bytecodes.DUP2_X2        :
+            case Bytecodes.DUP2_X2:
                 frame.dup2x2();
                 break;
-            case Bytecodes.SWAP           :
+            case Bytecodes.SWAP:
                 frame.swapSingle();
                 break;
-            case Bytecodes.IADD           :
+            case Bytecodes.IADD:
                 frame.pushInt(frame.popInt() + frame.popInt());
                 break;
-            case Bytecodes.LADD           :
+            case Bytecodes.LADD:
                 frame.pushLong(frame.popLong() + frame.popLong());
                 break;
-            case Bytecodes.FADD           :
+            case Bytecodes.FADD:
                 frame.pushFloat(frame.popFloat() + frame.popFloat());
                 break;
-            case Bytecodes.DADD           :
+            case Bytecodes.DADD:
                 frame.pushDouble(frame.popDouble() + frame.popDouble());
                 break;
-            case Bytecodes.ISUB           :
+            case Bytecodes.ISUB:
                 frame.pushInt(-frame.popInt() + frame.popInt());
                 break;
-            case Bytecodes.LSUB           :
+            case Bytecodes.LSUB:
                 frame.pushLong(-frame.popLong() + frame.popLong());
                 break;
-            case Bytecodes.FSUB           :
+            case Bytecodes.FSUB:
                 frame.pushFloat(-frame.popFloat() + frame.popFloat());
                 break;
-            case Bytecodes.DSUB           :
+            case Bytecodes.DSUB:
                 frame.pushDouble(-frame.popDouble() + frame.popDouble());
                 break;
-            case Bytecodes.IMUL           :
+            case Bytecodes.IMUL:
                 frame.pushInt(frame.popInt() * frame.popInt());
                 break;
-            case Bytecodes.LMUL           :
+            case Bytecodes.LMUL:
                 frame.pushLong(frame.popLong() * frame.popLong());
                 break;
-            case Bytecodes.FMUL           :
+            case Bytecodes.FMUL:
                 frame.pushFloat(frame.popFloat() * frame.popFloat());
                 break;
-            case Bytecodes.DMUL           :
+            case Bytecodes.DMUL:
                 frame.pushDouble(frame.popDouble() * frame.popDouble());
                 break;
-            case Bytecodes.IDIV           :
+            case Bytecodes.IDIV:
                 divInt(frame);
                 break;
-            case Bytecodes.LDIV           :
+            case Bytecodes.LDIV:
                 divLong(frame);
                 break;
-            case Bytecodes.FDIV           :
+            case Bytecodes.FDIV:
                 divFloat(frame);
                 break;
-            case Bytecodes.DDIV           :
+            case Bytecodes.DDIV:
                 divDouble(frame);
                 break;
-            case Bytecodes.IREM           :
+            case Bytecodes.IREM:
                 remInt(frame);
                 break;
-            case Bytecodes.LREM           :
+            case Bytecodes.LREM:
                 remLong(frame);
                 break;
-            case Bytecodes.FREM           :
+            case Bytecodes.FREM:
                 remFloat(frame);
                 break;
-            case Bytecodes.DREM           :
+            case Bytecodes.DREM:
                 remDouble(frame);
                 break;
-            case Bytecodes.INEG           :
+            case Bytecodes.INEG:
                 frame.pushInt(-frame.popInt());
                 break;
-            case Bytecodes.LNEG           :
+            case Bytecodes.LNEG:
                 frame.pushLong(-frame.popLong());
                 break;
-            case Bytecodes.FNEG           :
+            case Bytecodes.FNEG:
                 frame.pushFloat(-frame.popFloat());
                 break;
-            case Bytecodes.DNEG           :
+            case Bytecodes.DNEG:
                 frame.pushDouble(-frame.popDouble());
                 break;
-            case Bytecodes.ISHL           :
+            case Bytecodes.ISHL:
                 shiftLeftInt(frame);
                 break;
-            case Bytecodes.LSHL           :
+            case Bytecodes.LSHL:
                 shiftLeftLong(frame);
                 break;
-            case Bytecodes.ISHR           :
+            case Bytecodes.ISHR:
                 shiftRightSignedInt(frame);
                 break;
-            case Bytecodes.LSHR           :
+            case Bytecodes.LSHR:
                 shiftRightSignedLong(frame);
                 break;
-            case Bytecodes.IUSHR          :
+            case Bytecodes.IUSHR:
                 shiftRightUnsignedInt(frame);
                 break;
-            case Bytecodes.LUSHR          :
+            case Bytecodes.LUSHR:
                 shiftRightUnsignedLong(frame);
                 break;
-            case Bytecodes.IAND           :
+            case Bytecodes.IAND:
                 frame.pushInt(frame.popInt() & frame.popInt());
                 break;
-            case Bytecodes.LAND           :
+            case Bytecodes.LAND:
                 frame.pushLong(frame.popLong() & frame.popLong());
                 break;
-            case Bytecodes.IOR            :
+            case Bytecodes.IOR:
                 frame.pushInt(frame.popInt() | frame.popInt());
                 break;
-            case Bytecodes.LOR            :
+            case Bytecodes.LOR:
                 frame.pushLong(frame.popLong() | frame.popLong());
                 break;
-            case Bytecodes.IXOR           :
+            case Bytecodes.IXOR:
                 frame.pushInt(frame.popInt() ^ frame.popInt());
                 break;
-            case Bytecodes.LXOR           :
+            case Bytecodes.LXOR:
                 frame.pushLong(frame.popLong() ^ frame.popLong());
                 break;
-            case Bytecodes.IINC           :
+            case Bytecodes.IINC:
                 iinc(frame, bs);
                 break;
-            case Bytecodes.I2L            :
+            case Bytecodes.I2L:
                 frame.pushLong(frame.popInt());
                 break;
-            case Bytecodes.I2F            :
+            case Bytecodes.I2F:
                 frame.pushFloat(frame.popInt());
                 break;
-            case Bytecodes.I2D            :
+            case Bytecodes.I2D:
                 frame.pushDouble(frame.popInt());
                 break;
-            case Bytecodes.L2I            :
+            case Bytecodes.L2I:
                 frame.pushInt((int) frame.popLong());
                 break;
-            case Bytecodes.L2F            :
+            case Bytecodes.L2F:
                 frame.pushFloat(frame.popLong());
                 break;
-            case Bytecodes.L2D            :
+            case Bytecodes.L2D:
                 frame.pushDouble(frame.popLong());
                 break;
-            case Bytecodes.F2I            :
+            case Bytecodes.F2I:
                 frame.pushInt((int) frame.popFloat());
                 break;
-            case Bytecodes.F2L            :
+            case Bytecodes.F2L:
                 frame.pushLong((long) frame.popFloat());
                 break;
-            case Bytecodes.F2D            :
+            case Bytecodes.F2D:
                 frame.pushDouble(frame.popFloat());
                 break;
-            case Bytecodes.D2I            :
+            case Bytecodes.D2I:
                 frame.pushInt((int) frame.popDouble());
                 break;
-            case Bytecodes.D2L            :
+            case Bytecodes.D2L:
                 frame.pushLong((long) frame.popDouble());
                 break;
-            case Bytecodes.D2F            :
+            case Bytecodes.D2F:
                 frame.pushFloat((float) frame.popDouble());
                 break;
-            case Bytecodes.I2B            :
+            case Bytecodes.I2B:
                 frame.pushInt((byte) frame.popInt());
                 break;
-            case Bytecodes.I2C            :
+            case Bytecodes.I2C:
                 frame.pushInt((char) frame.popInt());
                 break;
-            case Bytecodes.I2S            :
+            case Bytecodes.I2S:
                 frame.pushInt((short) frame.popInt());
                 break;
-            case Bytecodes.LCMP           :
+            case Bytecodes.LCMP:
                 compareLong(frame);
                 break;
-            case Bytecodes.FCMPL          :
+            case Bytecodes.FCMPL:
                 compareFloatLess(frame);
                 break;
-            case Bytecodes.FCMPG          :
+            case Bytecodes.FCMPG:
                 compareFloatGreater(frame);
                 break;
-            case Bytecodes.DCMPL          :
+            case Bytecodes.DCMPL:
                 compareDoubleLess(frame);
                 break;
-            case Bytecodes.DCMPG          :
+            case Bytecodes.DCMPG:
                 compareDoubleGreater(frame);
                 break;
-            case Bytecodes.IFEQ           :
+            case Bytecodes.IFEQ:
                 if (frame.popInt() == 0) {
                     return BRANCH;
                 }
                 break;
-            case Bytecodes.IFNE           :
+            case Bytecodes.IFNE:
                 if (frame.popInt() != 0) {
                     return BRANCH;
                 }
                 break;
-            case Bytecodes.IFLT           :
+            case Bytecodes.IFLT:
                 if (frame.popInt() < 0) {
                     return BRANCH;
                 }
                 break;
-            case Bytecodes.IFGE           :
+            case Bytecodes.IFGE:
                 if (frame.popInt() >= 0) {
                     return BRANCH;
                 }
                 break;
-            case Bytecodes.IFGT           :
+            case Bytecodes.IFGT:
                 if (frame.popInt() > 0) {
                     return BRANCH;
                 }
                 break;
-            case Bytecodes.IFLE           :
+            case Bytecodes.IFLE:
                 if (frame.popInt() <= 0) {
                     return BRANCH;
                 }
                 break;
-            case Bytecodes.IF_ICMPEQ      :
+            case Bytecodes.IF_ICMPEQ:
                 if (frame.popInt() == frame.popInt()) {
                     return BRANCH;
                 }
                 break;
-            case Bytecodes.IF_ICMPNE      :
+            case Bytecodes.IF_ICMPNE:
                 if (frame.popInt() != frame.popInt()) {
                     return BRANCH;
                 }
                 break;
-            case Bytecodes.IF_ICMPLT      :
+            case Bytecodes.IF_ICMPLT:
                 if (frame.popInt() > frame.popInt()) {
                     return BRANCH;
                 }
                 break;
-            case Bytecodes.IF_ICMPGE      :
+            case Bytecodes.IF_ICMPGE:
                 if (frame.popInt() <= frame.popInt()) {
                     return BRANCH;
                 }
                 break;
-            case Bytecodes.IF_ICMPGT      :
+            case Bytecodes.IF_ICMPGT:
                 if (frame.popInt() < frame.popInt()) {
                     return BRANCH;
                 }
                 break;
-            case Bytecodes.IF_ICMPLE      :
+            case Bytecodes.IF_ICMPLE:
                 if (frame.popInt() >= frame.popInt()) {
                     return BRANCH;
                 }
                 break;
-            case Bytecodes.IF_ACMPEQ      :
+            case Bytecodes.IF_ACMPEQ:
                 if (frame.popObject() == frame.popObject()) {
                     return BRANCH;
                 }
                 break;
-            case Bytecodes.IF_ACMPNE      :
+            case Bytecodes.IF_ACMPNE:
                 if (frame.popObject() != frame.popObject()) {
                     return BRANCH;
                 }
@@ -797,58 +794,58 @@
             case Bytecodes.GOTO:
             case Bytecodes.GOTO_W:
                 return BRANCH;
-            case Bytecodes.JSR            :
-            case Bytecodes.JSR_W          :
+            case Bytecodes.JSR:
+            case Bytecodes.JSR_W:
                 frame.pushInt(bs.currentBCI());
                 return BRANCH;
-            case Bytecodes.RET            :
+            case Bytecodes.RET:
                 return frame.getInt(frame.resolveLocalIndex(bs.readLocalIndex()));
-            case Bytecodes.TABLESWITCH    :
+            case Bytecodes.TABLESWITCH:
                 return tableSwitch(frame, bs);
-            case Bytecodes.LOOKUPSWITCH   :
+            case Bytecodes.LOOKUPSWITCH:
                 return lookupSwitch(frame, bs);
-            case Bytecodes.IRETURN        :
+            case Bytecodes.IRETURN:
                 frame.getParentFrame().pushInt(frame.popInt());
                 return RETURN;
-            case Bytecodes.LRETURN        :
+            case Bytecodes.LRETURN:
                 frame.getParentFrame().pushLong(frame.popLong());
                 return RETURN;
-            case Bytecodes.FRETURN        :
+            case Bytecodes.FRETURN:
                 frame.getParentFrame().pushFloat(frame.popFloat());
                 return RETURN;
-            case Bytecodes.DRETURN        :
+            case Bytecodes.DRETURN:
                 frame.getParentFrame().pushDouble(frame.popDouble());
                 return RETURN;
-            case Bytecodes.ARETURN        :
+            case Bytecodes.ARETURN:
                 frame.getParentFrame().pushObject(frame.popObject());
                 return RETURN;
-            case Bytecodes.RETURN         :
+            case Bytecodes.RETURN:
                 return RETURN;
-            case Bytecodes.GETSTATIC      :
+            case Bytecodes.GETSTATIC:
                 getField(frame, null, bs.currentBC(), bs.readCPI());
                 break;
-            case Bytecodes.PUTSTATIC      :
+            case Bytecodes.PUTSTATIC:
                 putStatic(frame, bs.readCPI());
                 break;
             case Bytecodes.GETFIELD:
                 getField(frame, nullCheck(frame.popObject()), bs.currentBC(), bs.readCPI());
                 break;
-            case Bytecodes.PUTFIELD       :
+            case Bytecodes.PUTFIELD:
                 putField(frame, bs.readCPI());
                 break;
-            case Bytecodes.INVOKEVIRTUAL  :
+            case Bytecodes.INVOKEVIRTUAL:
                 callFrame = invokeVirtual(frame, bs.readCPI());
                 if (callFrame == null) {
                     break;
                 }
                 return CALL;
-            case Bytecodes.INVOKESPECIAL  :
+            case Bytecodes.INVOKESPECIAL:
                 callFrame = invokeSpecial(frame, bs.readCPI());
                 if (callFrame == null) {
                     break;
                 }
                 return CALL;
-            case Bytecodes.INVOKESTATIC   :
+            case Bytecodes.INVOKESTATIC:
                 callFrame = invokeStatic(frame, bs.readCPI());
                 if (callFrame == null) {
                     break;
@@ -860,53 +857,57 @@
                     break;
                 }
                 return CALL;
-            case Bytecodes.XXXUNUSEDXXX   :
+            case Bytecodes.XXXUNUSEDXXX:
                 assert false : "unused bytecode used. behaviour unspecified.";
                 // nop
                 break;
-            case Bytecodes.NEW            :
+            case Bytecodes.NEW:
                 frame.pushObject(allocateInstance(frame, bs.readCPI()));
                 break;
-            case Bytecodes.NEWARRAY       :
+            case Bytecodes.NEWARRAY:
                 frame.pushObject(allocateNativeArray(frame, bs.readByte()));
                 break;
-            case Bytecodes.ANEWARRAY      :
+            case Bytecodes.ANEWARRAY:
                 frame.pushObject(allocateArray(frame, bs.readCPI()));
                 break;
-            case Bytecodes.ARRAYLENGTH    :
+            case Bytecodes.ARRAYLENGTH:
                 frame.pushInt(Array.getLength(nullCheck(frame.popObject())));
                 break;
-            case Bytecodes.ATHROW         :
-                throw (Throwable) frame.popObject();
-            case Bytecodes.CHECKCAST      :
+            case Bytecodes.ATHROW:
+                Throwable t = (Throwable) frame.popObject();
+                if ("break".equals(t.getMessage())) {
+                    t.printStackTrace();
+                }
+                throw t;
+            case Bytecodes.CHECKCAST:
                 checkCast(frame, bs.readCPI());
                 break;
-            case Bytecodes.INSTANCEOF     :
+            case Bytecodes.INSTANCEOF:
                 instanceOf(frame, bs.readCPI());
                 break;
-            case Bytecodes.MONITORENTER   :
+            case Bytecodes.MONITORENTER:
                 runtimeInterface.monitorEnter(frame.popObject());
                 break;
-            case Bytecodes.MONITOREXIT    :
+            case Bytecodes.MONITOREXIT:
                 runtimeInterface.monitorExit(frame.popObject());
                 break;
-            case Bytecodes.WIDE           :
+            case Bytecodes.WIDE:
                 assert false;
                 break;
-            case Bytecodes.MULTIANEWARRAY :
+            case Bytecodes.MULTIANEWARRAY:
                 frame.pushObject(allocateMultiArray(frame, bs.readCPI(), bs.readUByte(bs.currentBCI() + 3)));
                 break;
-            case Bytecodes.IFNULL         :
+            case Bytecodes.IFNULL:
                 if (frame.popObject() == null) {
                     return BRANCH;
                 }
                 break;
-            case Bytecodes.IFNONNULL      :
+            case Bytecodes.IFNONNULL:
                 if (frame.popObject() != null) {
                     return BRANCH;
                 }
                 break;
-            case Bytecodes.BREAKPOINT     :
+            case Bytecodes.BREAKPOINT:
                 assert false : "no breakpoints supported at this time.";
                 break; // nop
         }
@@ -945,9 +946,8 @@
         }
     }
 
-
     private void setStackTrace(InterpreterFrame frame, Throwable t, StackTraceElement[] stackTrace) {
-      runtimeInterface.setFieldObject(stackTrace, t,  findThrowableField(frame, "stackTrace"));
+        runtimeInterface.setFieldObject(stackTrace, t, findThrowableField(frame, "stackTrace"));
     }
 
     private StackTraceElement[] getBackTrace(InterpreterFrame frame, Throwable t) {
@@ -973,10 +973,9 @@
                     catchType = resolveType(frame, Bytecodes.INSTANCEOF, (char) handler.catchTypeCPI());
                 }
 
-                if (catchType == null
-                                || catchType.toJava().isInstance(t)) {
+                if (catchType == null || catchType.toJava().isInstance(t)) {
                     // the first found exception handler is our exception handler
-                   return handler;
+                    return handler;
                 }
             }
         }
@@ -985,8 +984,6 @@
 
     private InterpreterFrame allocateFrame(InterpreterFrame frame, BytecodeStream bs) {
         try {
-            stackFrameDepth++;
-
             InterpreterFrame nextFrame = this.callFrame;
 
             assert nextFrame != null;
@@ -1000,7 +997,7 @@
             }
             if (Modifier.isSynchronized(nextFrame.getMethod().accessFlags())) {
                 if (TRACE) {
-                    traceOp("Method monitor enter");
+                    traceOp(frame, "Method monitor enter");
                 }
                 if (Modifier.isStatic(nextFrame.getMethod().accessFlags())) {
                     runtimeInterface.monitorEnter(nextFrame.getMethod().holder().toJava());
@@ -1022,7 +1019,7 @@
         InterpreterFrame parent = frame.getParentFrame();
         if (Modifier.isSynchronized(frame.getMethod().accessFlags())) {
             if (TRACE) {
-                traceOp("Method monitor exit");
+                traceOp(frame, "Method monitor exit");
             }
             if (Modifier.isStatic(frame.getMethod().accessFlags())) {
                 runtimeInterface.monitorExit(frame.getMethod().holder().toJava());
@@ -1036,19 +1033,17 @@
         if (TRACE) {
             traceCall(frame, "Ret");
         }
-        stackFrameDepth--;
 
         frame.dispose();
         return parent;
     }
 
-    private void traceOp(String opName) {
-        trace(stackFrameDepth + 1, opName);
+    private void traceOp(InterpreterFrame frame, String opName) {
+        trace(frame.depth(), opName);
     }
 
     private void traceCall(InterpreterFrame frame, String type) {
-        trace(stackFrameDepth, type + " " +
-                        frame.getMethod() + " - " + frame.getMethod().signature().asString());
+        trace(frame.depth(), type + " " + frame.getMethod() + " - " + frame.getMethod().signature().asString());
     }
 
     private void trace(int level, String message) {
@@ -1060,7 +1055,6 @@
         System.out.println(builder);
     }
 
-
     private void divInt(InterpreterFrame frame) {
         int dividend = frame.popInt();
         int divisor = frame.popInt();
@@ -1085,7 +1079,6 @@
         frame.pushDouble(divisor / dividend);
     }
 
-
     private void remInt(InterpreterFrame frame) {
         int dividend = frame.popInt();
         int divisor = frame.popInt();
@@ -1147,8 +1140,7 @@
     }
 
     private int lookupSwitch(InterpreterFrame frame, BytecodeStream bs) {
-        return lookupSearch(
-                        new BytecodeLookupSwitch(bs, bs.currentBCI()), frame.popInt());
+        return lookupSearch(new BytecodeLookupSwitch(bs, bs.currentBCI()), frame.popInt());
     }
 
     /**
@@ -1169,7 +1161,7 @@
                 return switchHelper.bci() + switchHelper.offsetAt(mid); // key found
             }
         }
-        return switchHelper.defaultTarget();  // key not found.
+        return switchHelper.defaultTarget(); // key not found.
     }
 
     private int tableSwitch(InterpreterFrame frame, BytecodeStream bs) {
@@ -1198,7 +1190,7 @@
         return constantPool.lookupType(cpi, opcode).resolve(frame.getMethod().holder());
     }
 
-    private ResolvedJavaType resolveType(InterpreterFrame frame, Class<?> javaClass) {
+    private ResolvedJavaType resolveType(InterpreterFrame frame, Class< ? > javaClass) {
         return metaAccessProvider.getResolvedJavaType(javaClass).resolve(frame.getMethod().holder());
     }
 
@@ -1215,9 +1207,7 @@
     }
 
     private void instanceOf(InterpreterFrame frame, char cpi) {
-        frame.pushInt(resolveType(frame, Bytecodes.INSTANCEOF, cpi).
-                        toJava().isInstance(frame.popObject())
-                        ? 1 : 0);
+        frame.pushInt(resolveType(frame, Bytecodes.INSTANCEOF, cpi).toJava().isInstance(frame.popObject()) ? 1 : 0);
     }
 
     private void pushCPConstant(InterpreterFrame frame, char cpi) {
@@ -1227,7 +1217,7 @@
         if (constant instanceof Constant) {
             Constant c = ((Constant) constant);
             switch (c.kind) {
-                case Int :
+                case Int:
                     frame.pushInt(c.asInt());
                     break;
                 case Float:
@@ -1236,10 +1226,10 @@
                 case Object:
                     frame.pushObject(c.asObject());
                     break;
-                case Double :
+                case Double:
                     frame.pushDouble(c.asDouble());
                     break;
-                case Long :
+                case Long:
                     frame.pushLong(c.asLong());
                     break;
                 default:
@@ -1288,6 +1278,7 @@
         }
         return value;
     }
+
     private InterpreterFrame invokeStatic(InterpreterFrame frame, char cpi) throws Throwable {
         return invoke(frame, resolveMethod(frame, Bytecodes.INVOKESTATIC, cpi), null);
     }
@@ -1340,7 +1331,7 @@
     }
 
     private InterpreterFrame invoke(InterpreterFrame caller, ResolvedJavaMethod method, Object receiver) throws Throwable {
-        if (stackFrameDepth >= maxStackFrames) {
+        if (caller.depth() >= maxStackFrames) {
             throw new StackOverflowError("Maximum callstack of " + maxStackFrames + " exceeded.");
         }
 
@@ -1378,7 +1369,7 @@
 
         // current thread is low level and we also execute the target method in the low-level interpreter
         Object[] originalCalleeParameters = popArgumentsAsObject(caller, originalMethod, hasReceiver);
-        Object[] parameters = new Object[] {caller, originalMethod, originalCalleeParameters};
+        Object[] parameters = new Object[]{caller, originalMethod, originalCalleeParameters};
         Object returnValue = redirectionInfo.getTargetMethod().invoke(redirectionInfo.getReceiver(), parameters);
         pushAsObject(caller, originalMethod.signature().returnKind(), returnValue);
 
@@ -1415,21 +1406,21 @@
     private Object allocateNativeArray(InterpreterFrame frame, byte cpi) {
         // the constants for the cpi are loosely defined and no real cpi indices.
         switch (cpi) {
-            case 4 :
+            case 4:
                 return new byte[frame.popInt()];
-            case 8 :
+            case 8:
                 return new byte[frame.popInt()];
-            case 5 :
+            case 5:
                 return new char[frame.popInt()];
-            case 7 :
+            case 7:
                 return new double[frame.popInt()];
-            case 6 :
+            case 6:
                 return new float[frame.popInt()];
-            case 10 :
+            case 10:
                 return new int[frame.popInt()];
-            case 11 :
+            case 11:
                 return new long[frame.popInt()];
-            case 9 :
+            case 9:
                 return new short[frame.popInt()];
             default:
                 assert false : "unexpected case";
@@ -1456,52 +1447,52 @@
 
     private void putFieldStatic(InterpreterFrame frame, ResolvedJavaField field) {
         switch (field.kind()) {
-            case Boolean :
-            case Byte :
-            case Char :
-            case Short :
-            case Int :
+            case Boolean:
+            case Byte:
+            case Char:
+            case Short:
+            case Int:
                 runtimeInterface.setFieldInt(frame.popInt(), null, field);
                 break;
-            case Double :
+            case Double:
                 runtimeInterface.setFieldDouble(frame.popDouble(), null, field);
                 break;
-            case Float :
+            case Float:
                 runtimeInterface.setFieldFloat(frame.popFloat(), null, field);
                 break;
-            case Long :
+            case Long:
                 runtimeInterface.setFieldLong(frame.popLong(), null, field);
                 break;
-            case Object :
+            case Object:
                 runtimeInterface.setFieldObject(frame.popObject(), null, field);
                 break;
-            default :
+            default:
                 assert false : "unexpected case";
         }
     }
 
     private void putFieldVirtual(InterpreterFrame frame, ResolvedJavaField field) {
         switch (field.kind()) {
-            case Boolean :
-            case Byte :
-            case Char :
-            case Short :
-            case Int :
+            case Boolean:
+            case Byte:
+            case Char:
+            case Short:
+            case Int:
                 runtimeInterface.setFieldInt(frame.popInt(), nullCheck(frame.popObject()), field);
                 break;
-            case Double :
+            case Double:
                 runtimeInterface.setFieldDouble(frame.popDouble(), nullCheck(frame.popObject()), field);
                 break;
-            case Float :
+            case Float:
                 runtimeInterface.setFieldFloat(frame.popFloat(), nullCheck(frame.popObject()), field);
                 break;
-            case Long :
+            case Long:
                 runtimeInterface.setFieldLong(frame.popLong(), nullCheck(frame.popObject()), field);
                 break;
-            case Object :
+            case Object:
                 runtimeInterface.setFieldObject(frame.popObject(), nullCheck(frame.popObject()), field);
                 break;
-            default :
+            default:
                 assert false : "unexpected case";
         }
     }
@@ -1509,71 +1500,70 @@
     private void getField(InterpreterFrame frame, Object base, int opcode, char cpi) {
         ResolvedJavaField field = resolveField(frame, opcode, cpi);
         switch (field.kind()) {
-            case Boolean :
+            case Boolean:
                 frame.pushInt(runtimeInterface.getFieldBoolean(base, field) ? 1 : 0);
                 break;
-            case Byte :
+            case Byte:
                 frame.pushInt(runtimeInterface.getFieldByte(base, field));
                 break;
-            case Char :
+            case Char:
                 frame.pushInt(runtimeInterface.getFieldChar(base, field));
                 break;
-            case Short :
+            case Short:
                 frame.pushInt(runtimeInterface.getFieldShort(base, field));
                 break;
-            case Int :
+            case Int:
                 frame.pushInt(runtimeInterface.getFieldInt(base, field));
                 break;
-            case Double :
+            case Double:
                 frame.pushDouble(runtimeInterface.getFieldDouble(base, field));
                 break;
-            case Float :
+            case Float:
                 frame.pushFloat(runtimeInterface.getFieldFloat(base, field));
                 break;
-            case Long :
+            case Long:
                 frame.pushLong(runtimeInterface.getFieldLong(base, field));
                 break;
-            case Object :
+            case Object:
                 frame.pushObject(runtimeInterface.getFieldObject(base, field));
                 break;
-            default :
+            default:
                 assert false : "unexpected case";
         }
     }
 
-
     private int pushAsObject(InterpreterFrame frame, Kind typeKind, Object value) {
-        switch(typeKind) {
-            case Int :
+        switch (typeKind) {
+            case Int:
                 frame.pushInt((int) value);
                 break;
-            case Long :
+            case Long:
                 frame.pushLong((long) value);
                 return 2;
-            case Boolean :
+            case Boolean:
                 frame.pushInt(((boolean) value) ? 1 : 0);
                 break;
-            case Byte :
+            case Byte:
                 frame.pushInt((byte) value);
                 break;
-            case Char :
+            case Char:
                 frame.pushInt((char) value);
                 break;
-            case Double :
+            case Double:
                 frame.pushDouble((double) value);
                 return 2;
-            case Float :
+            case Float:
                 frame.pushFloat((float) value);
                 break;
-            case Short :
+            case Short:
                 frame.pushInt((short) value);
                 break;
-            case Object :
+            case Object:
                 frame.pushObject(value);
                 break;
-            case Void :
+            case Void:
                 return 0;
-            default :
+            default:
                 assert false : "case not specified";
         }
         return 1;
@@ -1581,27 +1571,27 @@
 
     private Object popAsObject(InterpreterFrame frame, Kind typeKind) {
         switch (typeKind) {
-            case Boolean :
+            case Boolean:
                 return frame.popInt() == 1 ? true : false;
-            case Byte :
+            case Byte:
                 return (byte) frame.popInt();
-            case Char :
+            case Char:
                 return (char) frame.popInt();
-            case Double :
+            case Double:
                 return frame.popDouble();
-            case Int :
+            case Int:
                 return frame.popInt();
-            case Float :
+            case Float:
                 return frame.popFloat();
-            case Long :
+            case Long:
                 return frame.popLong();
-            case Short :
+            case Short:
                 return (short) frame.popInt();
-            case Object :
+            case Object:
                 return frame.popObject();
-            case Void :
+            case Void:
                 return null;
-            default :
+            default:
                 assert false : "unexpected case";
         }
         return null;
@@ -1615,7 +1605,7 @@
         }
     }
 
-    private static Method findMethod(Class<?> clazz, String name, Class<?> ... parameters) {
+    private static Method findMethod(Class< ? > clazz, String name, Class< ? >... parameters) {
         try {
             return clazz.getDeclaredMethod(name, parameters);
         } catch (Exception e) {
@@ -1654,6 +1644,7 @@
     }
 
     private class MethodRedirectionInfo {
+
         private InterpreterCallable receiver;
         private Method method;
 
--- a/graal/com.oracle.graal.interpreter/src/com/oracle/graal/interpreter/InterpreterFrame.java	Wed Jul 04 22:01:03 2012 +0200
+++ b/graal/com.oracle.graal.interpreter/src/com/oracle/graal/interpreter/InterpreterFrame.java	Thu Jul 05 14:09:53 2012 +0200
@@ -37,21 +37,23 @@
     private static final int SINGLE = 1;
 
     /** Pointer to the top-most stack frame element. */
+    private int depth;
     private int tos;
 
     public InterpreterFrame(ResolvedJavaMethod method, int additionalStackSpace) {
-        this(method, null, additionalStackSpace);
+        this(method, null, additionalStackSpace, 0);
     }
 
-    private InterpreterFrame(ResolvedJavaMethod method, InterpreterFrame parent, int additionalStackSpace) {
+    private InterpreterFrame(ResolvedJavaMethod method, InterpreterFrame parent, int additionalStackSpace, int depth) {
         super(method.maxLocals() + method.maxStackSize() + BASE_LENGTH + additionalStackSpace, parent);
         setMethod(method);
         setBCI(0);
+        this.depth = depth;
         this.tos = BASE_LENGTH;
     }
 
     public InterpreterFrame create(ResolvedJavaMethod method, boolean hasReceiver) {
-        InterpreterFrame frame = new InterpreterFrame(method, this, 0);
+        InterpreterFrame frame = new InterpreterFrame(method, this, 0, this.depth + 1);
         int length = method.signature().argumentSlots(hasReceiver);
 
         frame.pushVoid(method.maxLocals());
@@ -67,6 +69,10 @@
         return BASE_LENGTH + index;
     }
 
+    public int depth() {
+        return depth;
+    }
+
     private int stackTos() {
         return BASE_LENGTH + getMethod().maxLocals();
     }
--- a/src/share/vm/graal/graalVMToInterpreter.cpp	Wed Jul 04 22:01:03 2012 +0200
+++ b/src/share/vm/graal/graalVMToInterpreter.cpp	Thu Jul 05 14:09:53 2012 +0200
@@ -237,7 +237,7 @@
   if (is_java_primitive(expected_result_type)) {
     unbox_primitive(&boxed_result, result);
   } else if (expected_result_type == T_OBJECT || expected_result_type == T_ARRAY) {
-    result->set_jobject(result->get_jobject());
+    result->set_jobject(boxed_result.get_jobject());
   }
 }
 
--- a/src/share/vm/runtime/javaCalls.cpp	Wed Jul 04 22:01:03 2012 +0200
+++ b/src/share/vm/runtime/javaCalls.cpp	Thu Jul 05 14:09:53 2012 +0200
@@ -445,6 +445,7 @@
   if (thread->high_level_interpreter_in_vm() && !method->is_native() && Interpreter::contains(entry_point)) {
     assert(nm == NULL || !nm->is_alive(), "otherwise nm should be invoked");
     VMToInterpreter::execute(result, m, args, result->get_type(), thread);
+    oop_result_flag = false; // result already holds the correct value
   } else
 #endif
   // do call