# HG changeset patch # User Christian Haeubl # Date 1341490193 -7200 # Node ID 8d0a6bceb112c1d80a279d934cc6c99535cd126d # Parent 66ec0bc36a379698a06097cef9521ef05c680c9d fixed result value for (high-level interpreter -> native -> Java transitions) diff -r 66ec0bc36a37 -r 8d0a6bceb112 graal/com.oracle.graal.interpreter/src/com/oracle/graal/interpreter/BytecodeInterpreter.java --- 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.*; /** - * - *

Implementation notes

- *
  • Native methods are invoked using standard java reflection.
  • - * - *

    Features:

    - * - * - *

    Limitations:

    - * - *
  • 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.
  • + * 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 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; diff -r 66ec0bc36a37 -r 8d0a6bceb112 graal/com.oracle.graal.interpreter/src/com/oracle/graal/interpreter/InterpreterFrame.java --- 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(); } diff -r 66ec0bc36a37 -r 8d0a6bceb112 src/share/vm/graal/graalVMToInterpreter.cpp --- 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()); } } diff -r 66ec0bc36a37 -r 8d0a6bceb112 src/share/vm/runtime/javaCalls.cpp --- 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