# HG changeset patch # User Christian Haeubl # Date 1359968768 -3600 # Node ID 37b70037965632df9ad2dfed508b657ab10ead73 # Parent 149092d59dd0e93c93bbcadafdb6e19af39bb0b6 removed interpreter api diff -r 149092d59dd0 -r 37b700379656 graal/com.oracle.graal.interpreter/overview.html --- a/graal/com.oracle.graal.interpreter/overview.html Fri Feb 01 17:25:39 2013 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,36 +0,0 @@ - - - - - - - - -Documentation for the com.oracle.graal.interpreter project. - - - diff -r 149092d59dd0 -r 37b700379656 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 Fri Feb 01 17:25:39 2013 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1679 +0,0 @@ -/* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.graal.interpreter; - -import java.lang.reflect.*; -import java.util.*; - -import com.oracle.graal.api.interpreter.*; -import com.oracle.graal.api.meta.*; -import com.oracle.graal.api.runtime.*; -import com.oracle.graal.bytecode.*; - -/** - * 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 { - - private static final String OPTION_MAX_STACK_SIZE = "maxStackSize"; - private static final boolean TRACE = false; - private static final boolean TRACE_BYTE_CODE = false; - - private static final int DEFAULT_MAX_STACK_SIZE = 1500; - - private static final int NEXT = -1; - private static final int BRANCH = -2; - private static final int RETURN = -3; - private static final int CALL = -4; - - private InterpreterFrame callFrame; - - private Map methodDelegates; - - private int maxStackFrames; - - private ResolvedJavaMethod rootMethod; - private RuntimeInterpreterInterface runtimeInterface; - private MetaAccessProvider metaAccessProvider; - - public boolean initialize(String args) { - methodDelegates = new HashMap<>(); - maxStackFrames = DEFAULT_MAX_STACK_SIZE; - - GraalRuntime runtime = Graal.getRuntime(); - this.runtimeInterface = runtime.getCapability(RuntimeInterpreterInterface.class); - if (this.runtimeInterface == null) { - throw new UnsupportedOperationException("The provided Graal runtime does not support the required capability " + RuntimeInterpreterInterface.class.getName() + "."); - } - this.metaAccessProvider = runtime.getCapability(MetaAccessProvider.class); - if (this.metaAccessProvider == null) { - throw new UnsupportedOperationException("The provided Graal runtime does not support the required capability " + MetaAccessProvider.class.getName() + "."); - } - - this.rootMethod = resolveRootMethod(); - registerDelegates(); - return parseArguments(args); - } - - @Override - public void setOption(String name, String value) { - if (name != null && name.equals(OPTION_MAX_STACK_SIZE)) { - this.maxStackFrames = Integer.parseInt(value); - } - } - - 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, runtimeInterface)); - 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") - private boolean parseArguments(String stringArgs) { - // TODO: parse the arguments - return true; - } - - public void setMaxStackFrames(int maxStackSize) { - this.maxStackFrames = maxStackSize; - } - - public int getMaxStackFrames() { - return maxStackFrames; - } - - public void addDelegate(Method method, InterpreterCallable callable) { - ResolvedJavaMethod resolvedMethod = metaAccessProvider.lookupJavaMethod(method); - if (methodDelegates.containsKey(resolvedMethod)) { - throw new IllegalArgumentException("Delegate for method " + method + " already added."); - } - - methodDelegates.put(resolvedMethod, new MethodRedirectionInfo(callable)); - } - - public void removeDelegate(Method method) { - methodDelegates.remove(metaAccessProvider.lookupJavaMethod(method)); - } - - @Override - public Object execute(ResolvedJavaMethod method, Object... boxedArguments) throws Throwable { - try { - boolean receiver = hasReceiver(method); - Signature signature = method.getSignature(); - assert boxedArguments != null; - assert signature.getParameterCount(receiver) == boxedArguments.length; - - if (TRACE) { - trace(0, "Executing root method " + method); - } - - InterpreterFrame rootFrame = new InterpreterFrame(rootMethod, signature.getParameterSlots(true)); - rootFrame.pushObject(this); - rootFrame.pushObject(method); - rootFrame.pushObject(boxedArguments); - - int index = 0; - if (receiver) { - pushAsObject(rootFrame, Kind.Object, boxedArguments[index]); - index++; - } - - for (int i = 0; index < boxedArguments.length; i++, index++) { - pushAsObject(rootFrame, signature.getParameterKind(i), boxedArguments[index]); - } - - InterpreterFrame frame = rootFrame.create(method, receiver); - executeRoot(rootFrame, frame); - return popAsObject(rootFrame, signature.getReturnKind()); - } catch (Exception e) { - // TODO (chaeubl): remove this exception handler (only used for debugging) - throw e; - } - } - - public Object execute(Method javaMethod, Object... boxedArguments) throws Throwable { - return execute(metaAccessProvider.lookupJavaMethod(javaMethod), boxedArguments); - } - - private boolean hasReceiver(ResolvedJavaMethod method) { - return !Modifier.isStatic(method.getModifiers()); - } - - private void executeRoot(InterpreterFrame root, InterpreterFrame frame) throws Throwable { - // TODO reflection redirection - InterpreterFrame prevFrame = frame; - InterpreterFrame currentFrame = frame; - BytecodeStream bs = new BytecodeStream(currentFrame.getMethod().getCode()); - if (TRACE) { - traceCall(frame, "Call"); - } - while (currentFrame != root) { - if (prevFrame != currentFrame) { - bs = new BytecodeStream(currentFrame.getMethod().getCode()); - } - bs.setBCI(currentFrame.getBCI()); - - prevFrame = currentFrame; - currentFrame = loop(root, prevFrame, bs); - } - assert callFrame == null; - } - - private InterpreterFrame loop(InterpreterFrame root, final InterpreterFrame frame, final BytecodeStream bs) throws Throwable { - try { - while (true) { - int result = executeInstruction(frame, bs); - switch (result) { - case NEXT: - bs.next(); - break; - case RETURN: - return popFrame(frame); - case CALL: - return allocateFrame(frame, bs); - case BRANCH: - bs.setBCI(bs.readBranchDest()); - break; - default: - // the outcome depends on stack values - assert result >= 0 : "negative branch target"; - bs.setBCI(result); - break; - } - } - } catch (Throwable t) { - if (TRACE) { - traceOp(frame, "Exception " + t.toString()); - } - updateStackTrace(frame, t); - - // frame bci needs to be in sync when handling exceptions - frame.setBCI(bs.currentBCI()); - - InterpreterFrame handlerFrame = handleThrowable(root, frame, t); - if (handlerFrame == null) { - // matched root we just throw it again. - throw t; - } else { - if (TRACE) { - traceOp(frame, "Handler found " + handlerFrame.getMethod() + ":" + handlerFrame.getBCI()); - } - // update bci from frame - bs.setBCI(handlerFrame.getBCI()); - - // continue execution on the found frame - return handlerFrame; - } - } finally { - // TODO may be not necessary. - frame.setBCI(bs.currentBCI()); - } - } - - private int executeInstruction(InterpreterFrame frame, BytecodeStream bs) throws Throwable { - if (TRACE_BYTE_CODE) { - traceOp(frame, bs.currentBCI() + ": " + Bytecodes.baseNameOf(bs.currentBC())); - } - switch (bs.currentBC()) { - case Bytecodes.NOP: - break; - case Bytecodes.ACONST_NULL: - frame.pushObject(null); - break; - case Bytecodes.ICONST_M1: - frame.pushInt(-1); - break; - case Bytecodes.ICONST_0: - frame.pushInt(0); - break; - case Bytecodes.ICONST_1: - frame.pushInt(1); - break; - case Bytecodes.ICONST_2: - frame.pushInt(2); - break; - case Bytecodes.ICONST_3: - frame.pushInt(3); - break; - case Bytecodes.ICONST_4: - frame.pushInt(4); - break; - case Bytecodes.ICONST_5: - frame.pushInt(5); - break; - case Bytecodes.LCONST_0: - frame.pushLong(0L); - break; - case Bytecodes.LCONST_1: - frame.pushLong(1L); - break; - case Bytecodes.FCONST_0: - frame.pushFloat(0.0F); - break; - case Bytecodes.FCONST_1: - frame.pushFloat(1.0F); - break; - case Bytecodes.FCONST_2: - frame.pushFloat(2.0F); - break; - case Bytecodes.DCONST_0: - frame.pushDouble(0.0D); - break; - case Bytecodes.DCONST_1: - frame.pushDouble(1.0D); - break; - case Bytecodes.BIPUSH: - frame.pushInt(bs.readByte()); - break; - case Bytecodes.SIPUSH: - frame.pushInt(bs.readShort()); - break; - case Bytecodes.LDC: - case Bytecodes.LDC_W: - case Bytecodes.LDC2_W: - pushCPConstant(frame, bs.readCPI()); - break; - case Bytecodes.ILOAD: - frame.pushInt(frame.getInt(frame.resolveLocalIndex(bs.readLocalIndex()))); - break; - case Bytecodes.LLOAD: - frame.pushLong(frame.getLong(frame.resolveLocalIndex(bs.readLocalIndex()))); - break; - case Bytecodes.FLOAD: - frame.pushFloat(frame.getFloat(frame.resolveLocalIndex(bs.readLocalIndex()))); - break; - case Bytecodes.DLOAD: - frame.pushDouble(frame.getDouble(frame.resolveLocalIndex(bs.readLocalIndex()))); - break; - case Bytecodes.ALOAD: - frame.pushObject(frame.getObject(frame.resolveLocalIndex(bs.readLocalIndex()))); - break; - case Bytecodes.ILOAD_0: - frame.pushInt(frame.getInt(frame.resolveLocalIndex(0))); - break; - case Bytecodes.ILOAD_1: - frame.pushInt(frame.getInt(frame.resolveLocalIndex(1))); - break; - case Bytecodes.ILOAD_2: - frame.pushInt(frame.getInt(frame.resolveLocalIndex(2))); - break; - case Bytecodes.ILOAD_3: - frame.pushInt(frame.getInt(frame.resolveLocalIndex(3))); - break; - case Bytecodes.LLOAD_0: - frame.pushLong(frame.getLong(frame.resolveLocalIndex(0))); - break; - case Bytecodes.LLOAD_1: - frame.pushLong(frame.getLong(frame.resolveLocalIndex(1))); - break; - case Bytecodes.LLOAD_2: - frame.pushLong(frame.getLong(frame.resolveLocalIndex(2))); - break; - case Bytecodes.LLOAD_3: - frame.pushLong(frame.getLong(frame.resolveLocalIndex(3))); - break; - case Bytecodes.FLOAD_0: - frame.pushFloat(frame.getFloat(frame.resolveLocalIndex(0))); - break; - case Bytecodes.FLOAD_1: - frame.pushFloat(frame.getFloat(frame.resolveLocalIndex(1))); - break; - case Bytecodes.FLOAD_2: - frame.pushFloat(frame.getFloat(frame.resolveLocalIndex(2))); - break; - case Bytecodes.FLOAD_3: - frame.pushFloat(frame.getFloat(frame.resolveLocalIndex(3))); - break; - case Bytecodes.DLOAD_0: - frame.pushDouble(frame.getDouble(frame.resolveLocalIndex(0))); - break; - case Bytecodes.DLOAD_1: - frame.pushDouble(frame.getDouble(frame.resolveLocalIndex(1))); - break; - case Bytecodes.DLOAD_2: - frame.pushDouble(frame.getDouble(frame.resolveLocalIndex(2))); - break; - case Bytecodes.DLOAD_3: - frame.pushDouble(frame.getDouble(frame.resolveLocalIndex(3))); - break; - case Bytecodes.ALOAD_0: - frame.pushObject(frame.getObject(frame.resolveLocalIndex(0))); - break; - case Bytecodes.ALOAD_1: - frame.pushObject(frame.getObject(frame.resolveLocalIndex(1))); - break; - case Bytecodes.ALOAD_2: - frame.pushObject(frame.getObject(frame.resolveLocalIndex(2))); - break; - case Bytecodes.ALOAD_3: - frame.pushObject(frame.getObject(frame.resolveLocalIndex(3))); - break; - case Bytecodes.IALOAD: - frame.pushInt(runtimeInterface.getArrayInt(frame.popInt(), frame.popObject())); - break; - case Bytecodes.LALOAD: - frame.pushLong(runtimeInterface.getArrayLong(frame.popInt(), frame.popObject())); - break; - case Bytecodes.FALOAD: - frame.pushFloat(runtimeInterface.getArrayFloat(frame.popInt(), frame.popObject())); - break; - case Bytecodes.DALOAD: - frame.pushDouble(runtimeInterface.getArrayDouble(frame.popInt(), frame.popObject())); - break; - case Bytecodes.AALOAD: - frame.pushObject(runtimeInterface.getArrayObject(frame.popInt(), frame.popObject())); - break; - case Bytecodes.BALOAD: - frame.pushInt(runtimeInterface.getArrayByte(frame.popInt(), frame.popObject())); - break; - case Bytecodes.CALOAD: - frame.pushInt(runtimeInterface.getArrayChar(frame.popInt(), frame.popObject())); - break; - 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: - frame.setLong(frame.resolveLocalIndex(bs.readLocalIndex()), frame.popLong()); - break; - case Bytecodes.FSTORE: - frame.setFloat(frame.resolveLocalIndex(bs.readLocalIndex()), frame.popFloat()); - break; - case Bytecodes.DSTORE: - frame.setDouble(frame.resolveLocalIndex(bs.readLocalIndex()), frame.popDouble()); - break; - case Bytecodes.ASTORE: - frame.setObject(frame.resolveLocalIndex(bs.readLocalIndex()), frame.popObject()); - break; - case Bytecodes.ISTORE_0: - frame.setInt(frame.resolveLocalIndex(0), frame.popInt()); - break; - case Bytecodes.ISTORE_1: - frame.setInt(frame.resolveLocalIndex(1), frame.popInt()); - break; - case Bytecodes.ISTORE_2: - frame.setInt(frame.resolveLocalIndex(2), frame.popInt()); - break; - case Bytecodes.ISTORE_3: - frame.setInt(frame.resolveLocalIndex(3), frame.popInt()); - break; - case Bytecodes.LSTORE_0: - frame.setLong(frame.resolveLocalIndex(0), frame.popLong()); - break; - case Bytecodes.LSTORE_1: - frame.setLong(frame.resolveLocalIndex(1), frame.popLong()); - break; - case Bytecodes.LSTORE_2: - frame.setLong(frame.resolveLocalIndex(2), frame.popLong()); - break; - case Bytecodes.LSTORE_3: - frame.setLong(frame.resolveLocalIndex(3), frame.popLong()); - break; - case Bytecodes.FSTORE_0: - frame.setFloat(frame.resolveLocalIndex(0), frame.popFloat()); - break; - case Bytecodes.FSTORE_1: - frame.setFloat(frame.resolveLocalIndex(1), frame.popFloat()); - break; - case Bytecodes.FSTORE_2: - frame.setFloat(frame.resolveLocalIndex(2), frame.popFloat()); - break; - case Bytecodes.FSTORE_3: - frame.setFloat(frame.resolveLocalIndex(3), frame.popFloat()); - break; - case Bytecodes.DSTORE_0: - frame.setDouble(frame.resolveLocalIndex(0), frame.popDouble()); - break; - case Bytecodes.DSTORE_1: - frame.setDouble(frame.resolveLocalIndex(1), frame.popDouble()); - break; - case Bytecodes.DSTORE_2: - frame.setDouble(frame.resolveLocalIndex(2), frame.popDouble()); - break; - case Bytecodes.DSTORE_3: - frame.setDouble(frame.resolveLocalIndex(3), frame.popDouble()); - break; - case Bytecodes.ASTORE_0: - frame.setObject(frame.resolveLocalIndex(0), frame.popObject()); - break; - case Bytecodes.ASTORE_1: - frame.setObject(frame.resolveLocalIndex(1), frame.popObject()); - break; - case Bytecodes.ASTORE_2: - frame.setObject(frame.resolveLocalIndex(2), frame.popObject()); - break; - case Bytecodes.ASTORE_3: - frame.setObject(frame.resolveLocalIndex(3), frame.popObject()); - break; - case Bytecodes.IASTORE: - runtimeInterface.setArrayInt(frame.popInt(), frame.popInt(), frame.popObject()); - break; - case Bytecodes.LASTORE: - runtimeInterface.setArrayLong(frame.popLong(), frame.popInt(), frame.popObject()); - break; - case Bytecodes.FASTORE: - runtimeInterface.setArrayFloat(frame.popFloat(), frame.popInt(), frame.popObject()); - break; - case Bytecodes.DASTORE: - runtimeInterface.setArrayDouble(frame.popDouble(), frame.popInt(), frame.popObject()); - break; - case Bytecodes.AASTORE: - runtimeInterface.setArrayObject(frame.popObject(), frame.popInt(), frame.popObject()); - break; - case Bytecodes.BASTORE: - runtimeInterface.setArrayByte((byte) frame.popInt(), frame.popInt(), frame.popObject()); - break; - case Bytecodes.CASTORE: - runtimeInterface.setArrayChar((char) frame.popInt(), frame.popInt(), frame.popObject()); - break; - case Bytecodes.SASTORE: - runtimeInterface.setArrayShort((short) frame.popInt(), frame.popInt(), frame.popObject()); - break; - case Bytecodes.POP: - frame.popVoid(1); - break; - case Bytecodes.POP2: - frame.popVoid(2); - break; - case Bytecodes.DUP: - frame.dup(1); - break; - case Bytecodes.DUP_X1: - frame.dupx1(); - break; - case Bytecodes.DUP_X2: - frame.dupx2(); - break; - case Bytecodes.DUP2: - frame.dup(2); - break; - case Bytecodes.DUP2_X1: - frame.dup2x1(); - break; - case Bytecodes.DUP2_X2: - frame.dup2x2(); - break; - case Bytecodes.SWAP: - frame.swapSingle(); - break; - case Bytecodes.IADD: - frame.pushInt(frame.popInt() + frame.popInt()); - break; - case Bytecodes.LADD: - frame.pushLong(frame.popLong() + frame.popLong()); - break; - case Bytecodes.FADD: - frame.pushFloat(frame.popFloat() + frame.popFloat()); - break; - case Bytecodes.DADD: - frame.pushDouble(frame.popDouble() + frame.popDouble()); - break; - case Bytecodes.ISUB: - frame.pushInt(-frame.popInt() + frame.popInt()); - break; - case Bytecodes.LSUB: - frame.pushLong(-frame.popLong() + frame.popLong()); - break; - case Bytecodes.FSUB: - frame.pushFloat(-frame.popFloat() + frame.popFloat()); - break; - case Bytecodes.DSUB: - frame.pushDouble(-frame.popDouble() + frame.popDouble()); - break; - case Bytecodes.IMUL: - frame.pushInt(frame.popInt() * frame.popInt()); - break; - case Bytecodes.LMUL: - frame.pushLong(frame.popLong() * frame.popLong()); - break; - case Bytecodes.FMUL: - frame.pushFloat(frame.popFloat() * frame.popFloat()); - break; - case Bytecodes.DMUL: - frame.pushDouble(frame.popDouble() * frame.popDouble()); - break; - case Bytecodes.IDIV: - divInt(frame); - break; - case Bytecodes.LDIV: - divLong(frame); - break; - case Bytecodes.FDIV: - divFloat(frame); - break; - case Bytecodes.DDIV: - divDouble(frame); - break; - case Bytecodes.IREM: - remInt(frame); - break; - case Bytecodes.LREM: - remLong(frame); - break; - case Bytecodes.FREM: - remFloat(frame); - break; - case Bytecodes.DREM: - remDouble(frame); - break; - case Bytecodes.INEG: - frame.pushInt(-frame.popInt()); - break; - case Bytecodes.LNEG: - frame.pushLong(-frame.popLong()); - break; - case Bytecodes.FNEG: - frame.pushFloat(-frame.popFloat()); - break; - case Bytecodes.DNEG: - frame.pushDouble(-frame.popDouble()); - break; - case Bytecodes.ISHL: - shiftLeftInt(frame); - break; - case Bytecodes.LSHL: - shiftLeftLong(frame); - break; - case Bytecodes.ISHR: - shiftRightSignedInt(frame); - break; - case Bytecodes.LSHR: - shiftRightSignedLong(frame); - break; - case Bytecodes.IUSHR: - shiftRightUnsignedInt(frame); - break; - case Bytecodes.LUSHR: - shiftRightUnsignedLong(frame); - break; - case Bytecodes.IAND: - frame.pushInt(frame.popInt() & frame.popInt()); - break; - case Bytecodes.LAND: - frame.pushLong(frame.popLong() & frame.popLong()); - break; - case Bytecodes.IOR: - frame.pushInt(frame.popInt() | frame.popInt()); - break; - case Bytecodes.LOR: - frame.pushLong(frame.popLong() | frame.popLong()); - break; - case Bytecodes.IXOR: - frame.pushInt(frame.popInt() ^ frame.popInt()); - break; - case Bytecodes.LXOR: - frame.pushLong(frame.popLong() ^ frame.popLong()); - break; - case Bytecodes.IINC: - iinc(frame, bs); - break; - case Bytecodes.I2L: - frame.pushLong(frame.popInt()); - break; - case Bytecodes.I2F: - frame.pushFloat(frame.popInt()); - break; - case Bytecodes.I2D: - frame.pushDouble(frame.popInt()); - break; - case Bytecodes.L2I: - frame.pushInt((int) frame.popLong()); - break; - case Bytecodes.L2F: - frame.pushFloat(frame.popLong()); - break; - case Bytecodes.L2D: - frame.pushDouble(frame.popLong()); - break; - case Bytecodes.F2I: - frame.pushInt((int) frame.popFloat()); - break; - case Bytecodes.F2L: - frame.pushLong((long) frame.popFloat()); - break; - case Bytecodes.F2D: - frame.pushDouble(frame.popFloat()); - break; - case Bytecodes.D2I: - frame.pushInt((int) frame.popDouble()); - break; - case Bytecodes.D2L: - frame.pushLong((long) frame.popDouble()); - break; - case Bytecodes.D2F: - frame.pushFloat((float) frame.popDouble()); - break; - case Bytecodes.I2B: - frame.pushInt((byte) frame.popInt()); - break; - case Bytecodes.I2C: - frame.pushInt((char) frame.popInt()); - break; - case Bytecodes.I2S: - frame.pushInt((short) frame.popInt()); - break; - case Bytecodes.LCMP: - compareLong(frame); - break; - case Bytecodes.FCMPL: - compareFloatLess(frame); - break; - case Bytecodes.FCMPG: - compareFloatGreater(frame); - break; - case Bytecodes.DCMPL: - compareDoubleLess(frame); - break; - case Bytecodes.DCMPG: - compareDoubleGreater(frame); - break; - case Bytecodes.IFEQ: - if (frame.popInt() == 0) { - return BRANCH; - } - break; - case Bytecodes.IFNE: - if (frame.popInt() != 0) { - return BRANCH; - } - break; - case Bytecodes.IFLT: - if (frame.popInt() < 0) { - return BRANCH; - } - break; - case Bytecodes.IFGE: - if (frame.popInt() >= 0) { - return BRANCH; - } - break; - case Bytecodes.IFGT: - if (frame.popInt() > 0) { - return BRANCH; - } - break; - case Bytecodes.IFLE: - if (frame.popInt() <= 0) { - return BRANCH; - } - break; - case Bytecodes.IF_ICMPEQ: - if (frame.popInt() == frame.popInt()) { - return BRANCH; - } - break; - case Bytecodes.IF_ICMPNE: - if (frame.popInt() != frame.popInt()) { - return BRANCH; - } - break; - case Bytecodes.IF_ICMPLT: - if (frame.popInt() > frame.popInt()) { - return BRANCH; - } - break; - case Bytecodes.IF_ICMPGE: - if (frame.popInt() <= frame.popInt()) { - return BRANCH; - } - break; - case Bytecodes.IF_ICMPGT: - if (frame.popInt() < frame.popInt()) { - return BRANCH; - } - break; - case Bytecodes.IF_ICMPLE: - if (frame.popInt() >= frame.popInt()) { - return BRANCH; - } - break; - case Bytecodes.IF_ACMPEQ: - if (frame.popObject() == frame.popObject()) { - return BRANCH; - } - break; - case Bytecodes.IF_ACMPNE: - if (frame.popObject() != frame.popObject()) { - return BRANCH; - } - break; - case Bytecodes.GOTO: - case Bytecodes.GOTO_W: - return BRANCH; - case Bytecodes.JSR: - case Bytecodes.JSR_W: - frame.pushInt(bs.currentBCI()); - return BRANCH; - case Bytecodes.RET: - return frame.getInt(frame.resolveLocalIndex(bs.readLocalIndex())); - case Bytecodes.TABLESWITCH: - return tableSwitch(frame, bs); - case Bytecodes.LOOKUPSWITCH: - return lookupSwitch(frame, bs); - case Bytecodes.IRETURN: - frame.getParentFrame().pushInt(frame.popInt()); - return RETURN; - case Bytecodes.LRETURN: - frame.getParentFrame().pushLong(frame.popLong()); - return RETURN; - case Bytecodes.FRETURN: - frame.getParentFrame().pushFloat(frame.popFloat()); - return RETURN; - case Bytecodes.DRETURN: - frame.getParentFrame().pushDouble(frame.popDouble()); - return RETURN; - case Bytecodes.ARETURN: - frame.getParentFrame().pushObject(frame.popObject()); - return RETURN; - case Bytecodes.RETURN: - return RETURN; - case Bytecodes.GETSTATIC: - getField(frame, null, bs.currentBC(), bs.readCPI()); - break; - case Bytecodes.PUTSTATIC: - putStatic(frame, bs.readCPI()); - break; - case Bytecodes.GETFIELD: - getField(frame, nullCheck(frame.popObject()), bs.currentBC(), bs.readCPI()); - break; - case Bytecodes.PUTFIELD: - putField(frame, bs.readCPI()); - break; - case Bytecodes.INVOKEVIRTUAL: - callFrame = invokeVirtual(frame, bs.readCPI()); - if (callFrame == null) { - break; - } - return CALL; - case Bytecodes.INVOKESPECIAL: - callFrame = invokeSpecial(frame, bs.readCPI()); - if (callFrame == null) { - break; - } - return CALL; - case Bytecodes.INVOKESTATIC: - callFrame = invokeStatic(frame, bs.readCPI()); - if (callFrame == null) { - break; - } - return CALL; - case Bytecodes.INVOKEINTERFACE: - callFrame = invokeInterface(frame, bs.readCPI()); - if (callFrame == null) { - break; - } - return CALL; - case Bytecodes.XXXUNUSEDXXX: - assert false : "unused bytecode used. behaviour unspecified."; - // nop - break; - case Bytecodes.NEW: - frame.pushObject(allocateInstance(frame, bs.readCPI())); - break; - case Bytecodes.NEWARRAY: - frame.pushObject(allocateNativeArray(frame, bs.readByte())); - break; - case Bytecodes.ANEWARRAY: - frame.pushObject(allocateArray(frame, bs.readCPI())); - break; - case Bytecodes.ARRAYLENGTH: - frame.pushInt(Array.getLength(nullCheck(frame.popObject()))); - break; - 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: - instanceOf(frame, bs.readCPI()); - break; - case Bytecodes.MONITORENTER: - runtimeInterface.monitorEnter(frame.popObject()); - break; - case Bytecodes.MONITOREXIT: - runtimeInterface.monitorExit(frame.popObject()); - break; - case Bytecodes.WIDE: - assert false; - break; - case Bytecodes.MULTIANEWARRAY: - frame.pushObject(allocateMultiArray(frame, bs.readCPI(), bs.readUByte(bs.currentBCI() + 3))); - break; - case Bytecodes.IFNULL: - if (frame.popObject() == null) { - return BRANCH; - } - break; - case Bytecodes.IFNONNULL: - if (frame.popObject() != null) { - return BRANCH; - } - break; - case Bytecodes.BREAKPOINT: - assert false : "no breakpoints supported at this time."; - break; // nop - } - return NEXT; - } - - private InterpreterFrame handleThrowable(InterpreterFrame root, InterpreterFrame frame, Throwable t) { - ExceptionHandler handler; - InterpreterFrame currentFrame = frame; - do { - handler = resolveExceptionHandlers(currentFrame, currentFrame.getBCI(), t); - if (handler == null) { - // no handler found pop frame - // and continue searching - currentFrame = popFrame(currentFrame); - } else { - // found a handler -> execute it - currentFrame.setBCI(handler.getHandlerBCI()); - currentFrame.popStack(); - currentFrame.pushObject(t); - return currentFrame; - } - } while (handler == null && currentFrame != root); - - // will throw exception up the interpreter - return null; - } - - private void updateStackTrace(InterpreterFrame frame, Throwable t) { - StackTraceElement[] elements = getBackTrace(frame, t); - if (elements != null) { - setStackTrace(frame, t, elements); - setBackTrace(frame, t, null); - } else { - setBackTrace(frame, t, createStackTraceElements(frame, runtimeInterface)); - } - } - - private void setStackTrace(InterpreterFrame frame, Throwable t, StackTraceElement[] stackTrace) { - runtimeInterface.setFieldObject(stackTrace, t, findThrowableField(frame, "stackTrace")); - } - - private StackTraceElement[] getBackTrace(InterpreterFrame frame, Throwable t) { - Object value = runtimeInterface.getFieldObject(t, findThrowableField(frame, "backtrace")); - if (value instanceof StackTraceElement[]) { - return (StackTraceElement[]) value; - } - return null; - } - - private void setBackTrace(InterpreterFrame frame, Throwable t, StackTraceElement[] backtrace) { - runtimeInterface.setFieldObject(backtrace, t, findThrowableField(frame, "backtrace")); - } - - private ExceptionHandler resolveExceptionHandlers(InterpreterFrame frame, int bci, Throwable t) { - ExceptionHandler[] handlers = frame.getMethod().getExceptionHandlers(); - for (int i = 0; i < handlers.length; i++) { - ExceptionHandler handler = handlers[i]; - if (bci >= handler.getStartBCI() && bci <= handler.getEndBCI()) { - ResolvedJavaType catchType = null; - if (!handler.isCatchAll()) { - // exception handlers are similar to instanceof bytecodes, so we pass instanceof - catchType = resolveType(frame, Bytecodes.INSTANCEOF, (char) handler.catchTypeCPI()); - } - - if (catchType == null || catchType.isInstance(Constant.forObject(t))) { - // the first found exception handler is our exception handler - return handler; - } - } - } - return null; - } - - private Class mirror(ResolvedJavaType type) { - return runtimeInterface.getMirror(type); - } - - private InterpreterFrame allocateFrame(InterpreterFrame frame, BytecodeStream bs) { - try { - InterpreterFrame nextFrame = this.callFrame; - - assert nextFrame != null; - assert nextFrame.getParentFrame() == frame; - - // store bci when leaving method - frame.setBCI(bs.currentBCI()); - - if (TRACE) { - traceCall(nextFrame, "Call"); - } - if (Modifier.isSynchronized(nextFrame.getMethod().getModifiers())) { - if (TRACE) { - traceOp(frame, "Method monitor enter"); - } - if (Modifier.isStatic(nextFrame.getMethod().getModifiers())) { - runtimeInterface.monitorEnter(mirror(nextFrame.getMethod().getDeclaringClass())); - } else { - Object enterObject = nextFrame.getObject(frame.resolveLocalIndex(0)); - assert enterObject != null; - runtimeInterface.monitorEnter(enterObject); - } - } - - return nextFrame; - } finally { - callFrame = null; - bs.next(); - } - } - - private InterpreterFrame popFrame(InterpreterFrame frame) { - InterpreterFrame parent = frame.getParentFrame(); - if (Modifier.isSynchronized(frame.getMethod().getModifiers())) { - if (TRACE) { - traceOp(frame, "Method monitor exit"); - } - if (Modifier.isStatic(frame.getMethod().getModifiers())) { - runtimeInterface.monitorExit(mirror(frame.getMethod().getDeclaringClass())); - } else { - Object exitObject = frame.getObject(frame.resolveLocalIndex(0)); - if (exitObject != null) { - runtimeInterface.monitorExit(exitObject); - } - } - } - if (TRACE) { - traceCall(frame, "Ret"); - } - - frame.dispose(); - return parent; - } - - private void traceOp(InterpreterFrame frame, String opName) { - trace(frame.depth(), opName); - } - - private void traceCall(InterpreterFrame frame, String type) { - trace(frame.depth(), type + " " + frame.getMethod() + " - " + frame.getMethod().getSignature()); - } - - private void trace(int level, String message) { - StringBuilder builder = new StringBuilder(); - for (int i = 0; i < level; i++) { - builder.append(" "); - } - builder.append(message); - System.out.println(builder); - } - - private void divInt(InterpreterFrame frame) { - int dividend = frame.popInt(); - int divisor = frame.popInt(); - frame.pushInt(divisor / dividend); - } - - private void divLong(InterpreterFrame frame) { - long dividend = frame.popLong(); - long divisor = frame.popLong(); - frame.pushLong(divisor / dividend); - } - - private void divFloat(InterpreterFrame frame) { - float dividend = frame.popFloat(); - float divisor = frame.popFloat(); - frame.pushFloat(divisor / dividend); - } - - private void divDouble(InterpreterFrame frame) { - double dividend = frame.popDouble(); - double divisor = frame.popDouble(); - frame.pushDouble(divisor / dividend); - } - - private void remInt(InterpreterFrame frame) { - int dividend = frame.popInt(); - int divisor = frame.popInt(); - frame.pushInt(divisor % dividend); - } - - private void remLong(InterpreterFrame frame) { - long dividend = frame.popLong(); - long divisor = frame.popLong(); - frame.pushLong(divisor % dividend); - } - - private void remFloat(InterpreterFrame frame) { - float dividend = frame.popFloat(); - float divisor = frame.popFloat(); - frame.pushFloat(divisor % dividend); - } - - private void remDouble(InterpreterFrame frame) { - double dividend = frame.popDouble(); - double divisor = frame.popDouble(); - frame.pushDouble(divisor % dividend); - } - - private void shiftLeftInt(InterpreterFrame frame) { - int bits = frame.popInt(); - int value = frame.popInt(); - frame.pushInt(value << bits); - } - - private void shiftLeftLong(InterpreterFrame frame) { - int bits = frame.popInt(); - long value = frame.popLong(); - frame.pushLong(value << bits); - } - - private void shiftRightSignedInt(InterpreterFrame frame) { - int bits = frame.popInt(); - int value = frame.popInt(); - frame.pushInt(value >> bits); - } - - private void shiftRightSignedLong(InterpreterFrame frame) { - int bits = frame.popInt(); - long value = frame.popLong(); - frame.pushLong(value >> bits); - } - - private void shiftRightUnsignedInt(InterpreterFrame frame) { - int bits = frame.popInt(); - int value = frame.popInt(); - frame.pushInt(value >>> bits); - } - - private void shiftRightUnsignedLong(InterpreterFrame frame) { - int bits = frame.popInt(); - long value = frame.popLong(); - frame.pushLong(value >>> bits); - } - - private int lookupSwitch(InterpreterFrame frame, BytecodeStream bs) { - return lookupSearch(new BytecodeLookupSwitch(bs, bs.currentBCI()), frame.popInt()); - } - - /** - * Binary search implementation for the lookup switch. - */ - private int lookupSearch(BytecodeLookupSwitch switchHelper, int key) { - int low = 0; - int high = switchHelper.numberOfCases() - 1; - while (low <= high) { - int mid = (low + high) >>> 1; - int midVal = switchHelper.keyAt(mid); - - if (midVal < key) { - low = mid + 1; - } else if (midVal > key) { - high = mid - 1; - } else { - return switchHelper.bci() + switchHelper.offsetAt(mid); // key found - } - } - return switchHelper.defaultTarget(); // key not found. - } - - private int tableSwitch(InterpreterFrame frame, BytecodeStream bs) { - BytecodeTableSwitch switchHelper = new BytecodeTableSwitch(bs, bs.currentBCI()); - - int low = switchHelper.lowKey(); - int high = switchHelper.highKey(); - - assert low <= high; - - int index = frame.popInt(); - if (index < low || index > high) { - return switchHelper.defaultTarget(); - } else { - return switchHelper.targetAt(index - low); - } - } - - private void checkCast(InterpreterFrame frame, char cpi) { - frame.pushObject(mirror(resolveType(frame, Bytecodes.CHECKCAST, cpi)).cast(frame.popObject())); - } - - private ResolvedJavaType resolveType(InterpreterFrame frame, int opcode, char cpi) { - ConstantPool constantPool = frame.getConstantPool(); - constantPool.loadReferencedType(cpi, opcode); - return constantPool.lookupType(cpi, opcode).resolve(frame.getMethod().getDeclaringClass()); - } - - private ResolvedJavaType resolveType(InterpreterFrame frame, Class javaClass) { - return metaAccessProvider.lookupJavaType(javaClass).resolve(frame.getMethod().getDeclaringClass()); - } - - private ResolvedJavaMethod resolveMethod(InterpreterFrame frame, int opcode, char cpi) { - ConstantPool constantPool = frame.getConstantPool(); - constantPool.loadReferencedType(cpi, opcode); - return (ResolvedJavaMethod) constantPool.lookupMethod(cpi, opcode); - } - - private ResolvedJavaField resolveField(InterpreterFrame frame, int opcode, char cpi) { - ConstantPool constantPool = frame.getConstantPool(); - constantPool.loadReferencedType(cpi, opcode); - return (ResolvedJavaField) constantPool.lookupField(cpi, opcode); - } - - private void instanceOf(InterpreterFrame frame, char cpi) { - frame.pushInt(resolveType(frame, Bytecodes.INSTANCEOF, cpi).isInstance(Constant.forObject(frame.popObject())) ? 1 : 0); - } - - private void pushCPConstant(InterpreterFrame frame, char cpi) { - ResolvedJavaMethod method = frame.getMethod(); - Object constant = method.getConstantPool().lookupConstant(cpi); - - if (constant instanceof Constant) { - Constant c = ((Constant) constant); - switch (c.getKind()) { - case Int: - frame.pushInt(c.asInt()); - break; - case Float: - frame.pushFloat(c.asFloat()); - break; - case Object: - frame.pushObject(c.asObject()); - break; - case Double: - frame.pushDouble(c.asDouble()); - break; - case Long: - frame.pushLong(c.asLong()); - break; - default: - assert false : "unspecified case"; - } - } else if (constant instanceof JavaType) { - frame.pushObject(mirror(((JavaType) constant).resolve(method.getDeclaringClass()))); - } else { - assert false : "unexpected case"; - } - } - - private void compareLong(InterpreterFrame frame) { - long y = frame.popLong(); - long x = frame.popLong(); - frame.pushInt((x < y) ? -1 : ((x == y) ? 0 : 1)); - } - - private void compareDoubleGreater(InterpreterFrame frame) { - double y = frame.popDouble(); - double x = frame.popDouble(); - frame.pushInt(x < y ? -1 : ((x == y) ? 0 : 1)); - } - - private void compareDoubleLess(InterpreterFrame frame) { - double y = frame.popDouble(); - double x = frame.popDouble(); - frame.pushInt(x > y ? 1 : ((x == y) ? 0 : -1)); - } - - private void compareFloatGreater(InterpreterFrame frame) { - float y = frame.popFloat(); - float x = frame.popFloat(); - frame.pushInt(x < y ? -1 : ((x == y) ? 0 : 1)); - } - - private void compareFloatLess(InterpreterFrame frame) { - float y = frame.popFloat(); - float x = frame.popFloat(); - frame.pushInt(x > y ? 1 : ((x == y) ? 0 : -1)); - } - - private Object nullCheck(Object value) { - if (value == null) { - throw new NullPointerException(); - } - return value; - } - - private InterpreterFrame invokeStatic(InterpreterFrame frame, char cpi) throws Throwable { - return invoke(frame, resolveMethod(frame, Bytecodes.INVOKESTATIC, cpi), null); - } - - private InterpreterFrame invokeInterface(InterpreterFrame frame, char cpi) throws Throwable { - return resolveAndInvoke(frame, resolveMethod(frame, Bytecodes.INVOKEINTERFACE, cpi)); - } - - private InterpreterFrame resolveAndInvoke(InterpreterFrame parent, ResolvedJavaMethod m) throws Throwable { - Object receiver = nullCheck(parent.peekReceiver(m)); - - ResolvedJavaMethod method = resolveType(parent, receiver.getClass()).resolveMethod(m); - - if (method == null) { - throw new AbstractMethodError(); - } - - return invoke(parent, method, receiver); - } - - private InterpreterFrame invokeVirtual(InterpreterFrame frame, char cpi) throws Throwable { - ResolvedJavaMethod m = resolveMethod(frame, Bytecodes.INVOKEVIRTUAL, cpi); - if (Modifier.isFinal(m.getModifiers())) { - return invoke(frame, m, nullCheck(frame.peekReceiver(m))); - } else { - return resolveAndInvoke(frame, m); - } - } - - private InterpreterFrame invokeSpecial(InterpreterFrame frame, char cpi) throws Throwable { - ResolvedJavaMethod m = resolveMethod(frame, Bytecodes.INVOKESPECIAL, cpi); - return invoke(frame, m, nullCheck(frame.peekReceiver(m))); - } - - private Object[] popArgumentsAsObject(InterpreterFrame frame, ResolvedJavaMethod method, boolean hasReceiver) { - Signature signature = method.getSignature(); - int argumentCount = method.getSignature().getParameterCount(hasReceiver); - Object[] parameters = new Object[argumentCount]; - - int lastSignatureIndex = hasReceiver ? 1 : 0; - for (int i = argumentCount - 1; i >= lastSignatureIndex; i--) { - ResolvedJavaType type = signature.getParameterType(i - lastSignatureIndex, method.getDeclaringClass()).resolve(method.getDeclaringClass()); - parameters[i] = popAsObject(frame, type.getKind()); - } - - if (hasReceiver) { - parameters[0] = frame.popObject(); - } - return parameters; - } - - private InterpreterFrame invoke(InterpreterFrame caller, ResolvedJavaMethod method, Object receiver) throws Throwable { - if (caller.depth() >= maxStackFrames) { - throw new StackOverflowError("Maximum callstack of " + maxStackFrames + " exceeded."); - } - - if (Modifier.isNative(method.getModifiers())) { - return invokeNativeMethodViaVM(caller, method, receiver != null); - } else { - MethodRedirectionInfo redirectedMethod = methodDelegates.get(method); - if (redirectedMethod != null) { - return invokeRedirectedMethodViaVM(caller, method, redirectedMethod, receiver != null); - } else { - return invokeOptimized(caller, method, receiver != null); - } - } - } - - private InterpreterFrame invokeNativeMethodViaVM(InterpreterFrame caller, ResolvedJavaMethod method, boolean hasReceiver) throws Throwable { - assert !methodDelegates.containsKey(method) : "must not be redirected"; - if (TRACE) { - traceCall(caller, "Native " + method); - } - - // mark the current thread as high level and execute the native method - Object[] parameters = popArgumentsAsObject(caller, method, hasReceiver); - Object returnValue = runtimeInterface.invoke(method, parameters); - pushAsObject(caller, method.getSignature().getReturnKind(), returnValue); - - return null; - } - - private InterpreterFrame invokeRedirectedMethodViaVM(InterpreterFrame caller, ResolvedJavaMethod originalMethod, MethodRedirectionInfo redirectionInfo, boolean hasReceiver) throws Throwable { - assert methodDelegates.containsKey(originalMethod) : "must be redirected"; - if (TRACE) { - traceCall(caller, "Delegate " + originalMethod); - } - - // 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 returnValue = redirectionInfo.getTargetMethod().invoke(redirectionInfo.getReceiver(), parameters); - pushAsObject(caller, originalMethod.getSignature().getReturnKind(), returnValue); - - return null; - } - - private InterpreterFrame invokeOptimized(InterpreterFrame parent, ResolvedJavaMethod method, boolean hasReceiver) throws Throwable { - return parent.create(method, hasReceiver); - } - - private Object allocateMultiArray(InterpreterFrame frame, char cpi, int dimension) { - ResolvedJavaType type = getLastDimensionType(resolveType(frame, Bytecodes.MULTIANEWARRAY, cpi)); - - int[] dimensions = new int[dimension]; - for (int i = dimension - 1; i >= 0; i--) { - dimensions[i] = frame.popInt(); - } - return Array.newInstance(mirror(type), dimensions); - } - - private ResolvedJavaType getLastDimensionType(ResolvedJavaType type) { - ResolvedJavaType result = type; - while (result.isArray()) { - result = result.getComponentType(); - } - return result; - } - - private Object allocateArray(InterpreterFrame frame, char cpi) { - ResolvedJavaType type = resolveType(frame, Bytecodes.ANEWARRAY, cpi); - return Array.newInstance(runtimeInterface.getMirror(type), frame.popInt()); - } - - private Object allocateNativeArray(InterpreterFrame frame, byte cpi) { - // the constants for the cpi are loosely defined and no real cpi indices. - switch (cpi) { - case 4: - return new byte[frame.popInt()]; - case 8: - return new byte[frame.popInt()]; - case 5: - return new char[frame.popInt()]; - case 7: - return new double[frame.popInt()]; - case 6: - return new float[frame.popInt()]; - case 10: - return new int[frame.popInt()]; - case 11: - return new long[frame.popInt()]; - case 9: - return new short[frame.popInt()]; - default: - assert false : "unexpected case"; - return null; - } - } - - private Object allocateInstance(InterpreterFrame frame, char cpi) throws InstantiationException { - return runtimeInterface.newObject(resolveType(frame, Bytecodes.NEW, cpi)); - } - - private void iinc(InterpreterFrame frame, BytecodeStream bs) { - int index = frame.resolveLocalIndex(bs.readLocalIndex()); - frame.setInt(index, frame.getInt(index) + bs.readIncrement()); - } - - private void putStatic(InterpreterFrame frame, char cpi) { - putFieldStatic(frame, resolveField(frame, Bytecodes.PUTSTATIC, cpi)); - } - - private void putField(InterpreterFrame frame, char cpi) { - putFieldVirtual(frame, resolveField(frame, Bytecodes.PUTFIELD, cpi)); - } - - private void putFieldStatic(InterpreterFrame frame, ResolvedJavaField field) { - switch (field.getKind()) { - case Boolean: - case Byte: - case Char: - case Short: - case Int: - runtimeInterface.setFieldInt(frame.popInt(), null, field); - break; - case Double: - runtimeInterface.setFieldDouble(frame.popDouble(), null, field); - break; - case Float: - runtimeInterface.setFieldFloat(frame.popFloat(), null, field); - break; - case Long: - runtimeInterface.setFieldLong(frame.popLong(), null, field); - break; - case Object: - runtimeInterface.setFieldObject(frame.popObject(), null, field); - break; - default: - assert false : "unexpected case"; - } - } - - private void putFieldVirtual(InterpreterFrame frame, ResolvedJavaField field) { - switch (field.getKind()) { - case Boolean: - case Byte: - case Char: - case Short: - case Int: - runtimeInterface.setFieldInt(frame.popInt(), nullCheck(frame.popObject()), field); - break; - case Double: - runtimeInterface.setFieldDouble(frame.popDouble(), nullCheck(frame.popObject()), field); - break; - case Float: - runtimeInterface.setFieldFloat(frame.popFloat(), nullCheck(frame.popObject()), field); - break; - case Long: - runtimeInterface.setFieldLong(frame.popLong(), nullCheck(frame.popObject()), field); - break; - case Object: - runtimeInterface.setFieldObject(frame.popObject(), nullCheck(frame.popObject()), field); - break; - default: - assert false : "unexpected case"; - } - } - - private void getField(InterpreterFrame frame, Object base, int opcode, char cpi) { - ResolvedJavaField field = resolveField(frame, opcode, cpi); - switch (field.getKind()) { - case Boolean: - frame.pushInt(runtimeInterface.getFieldBoolean(base, field) ? 1 : 0); - break; - case Byte: - frame.pushInt(runtimeInterface.getFieldByte(base, field)); - break; - case Char: - frame.pushInt(runtimeInterface.getFieldChar(base, field)); - break; - case Short: - frame.pushInt(runtimeInterface.getFieldShort(base, field)); - break; - case Int: - frame.pushInt(runtimeInterface.getFieldInt(base, field)); - break; - case Double: - frame.pushDouble(runtimeInterface.getFieldDouble(base, field)); - break; - case Float: - frame.pushFloat(runtimeInterface.getFieldFloat(base, field)); - break; - case Long: - frame.pushLong(runtimeInterface.getFieldLong(base, field)); - break; - case Object: - frame.pushObject(runtimeInterface.getFieldObject(base, field)); - break; - default: - assert false : "unexpected case"; - } - } - - private int pushAsObject(InterpreterFrame frame, Kind typeKind, Object value) { - switch (typeKind) { - case Int: - frame.pushInt((int) value); - break; - case Long: - frame.pushLong((long) value); - return 2; - case Boolean: - frame.pushInt(((boolean) value) ? 1 : 0); - break; - case Byte: - frame.pushInt((byte) value); - break; - case Char: - frame.pushInt((char) value); - break; - case Double: - frame.pushDouble((double) value); - return 2; - case Float: - frame.pushFloat((float) value); - break; - case Short: - frame.pushInt((short) value); - break; - case Object: - frame.pushObject(value); - break; - case Void: - return 0; - default: - assert false : "case not specified"; - } - return 1; - } - - private Object popAsObject(InterpreterFrame frame, Kind typeKind) { - switch (typeKind) { - case Boolean: - return frame.popInt() == 1 ? true : false; - case Byte: - return (byte) frame.popInt(); - case Char: - return (char) frame.popInt(); - case Double: - return frame.popDouble(); - case Int: - return frame.popInt(); - case Float: - return frame.popFloat(); - case Long: - return frame.popLong(); - case Short: - return (short) frame.popInt(); - case Object: - return frame.popObject(); - case Void: - return null; - default: - assert false : "unexpected case"; - } - return null; - } - - private ResolvedJavaMethod resolveRootMethod() { - try { - return metaAccessProvider.lookupJavaMethod(BytecodeInterpreter.class.getDeclaredMethod("execute", Method.class, Object[].class)); - } catch (Exception e) { - throw new RuntimeException(e); - } - } - - private static Method findMethod(Class clazz, String name, Class... parameters) { - try { - return clazz.getDeclaredMethod(name, parameters); - } catch (Exception e) { - throw new RuntimeException(e); - } - } - - private static StackTraceElement[] createStackTraceElements(InterpreterFrame frame, RuntimeInterpreterInterface runtimeInterface) { - InterpreterFrame tmp = frame; - List elements = new ArrayList<>(); - boolean first = false; // filter only first stack elements - while (tmp != null) { - if (first || !filterStackElement(tmp, runtimeInterface)) { - first = true; - elements.add(tmp.getMethod().asStackTraceElement(tmp.getBCI())); - } - tmp = tmp.getParentFrame(); - } - return elements.toArray(new StackTraceElement[elements.size()]); - } - - private static boolean filterStackElement(InterpreterFrame frame, RuntimeInterpreterInterface runtimeInterface) { - return Throwable.class.isAssignableFrom(runtimeInterface.getMirror(frame.getMethod().getDeclaringClass())); - } - - private ResolvedJavaField findThrowableField(InterpreterFrame frame, String name) { - ResolvedJavaType throwableType = resolveType(frame, Throwable.class); - ResolvedJavaField[] fields = throwableType.getInstanceFields(false); - for (int i = 0; i < fields.length; i++) { - if (fields[i].getName().equals(name)) { - return fields[i]; - } - } - assert false; - return null; - } - - private class MethodRedirectionInfo { - - private InterpreterCallable receiver; - private Method method; - - public MethodRedirectionInfo(InterpreterCallable instance) { - this.receiver = instance; - this.method = resolveMethod(instance); - } - - public InterpreterCallable getReceiver() { - return receiver; - } - - public Method getTargetMethod() { - return method; - } - - private Method resolveMethod(InterpreterCallable instance) { - try { - return instance.getClass().getMethod(InterpreterCallable.INTERPRETER_CALLABLE_INVOKE_NAME, InterpreterCallable.INTERPRETER_CALLABLE_INVOKE_SIGNATURE); - } catch (NoSuchMethodException e) { - throw new InterpreterException(e); - } catch (SecurityException e) { - throw new InterpreterException(e); - } - } - } -} diff -r 149092d59dd0 -r 37b700379656 graal/com.oracle.graal.interpreter/src/com/oracle/graal/interpreter/Frame.java --- a/graal/com.oracle.graal.interpreter/src/com/oracle/graal/interpreter/Frame.java Fri Feb 01 17:25:39 2013 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,134 +0,0 @@ -/* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.graal.interpreter; - -import java.lang.reflect.*; - -import sun.misc.*; - -public class Frame { - - public static final Object[] EMPTY_ARRAY = new Object[0]; - public static final int PARENT_FRAME_SLOT = 0; - public static final int MIN_FRAME_SIZE = 1; - private static final Unsafe unsafe = getUnsafe(); - - protected final Object[] locals; - protected final long[] primitiveLocals; - - public Frame(int numLocals, Frame parent) { - assert numLocals >= MIN_FRAME_SIZE; - this.locals = new Object[numLocals]; - this.locals[PARENT_FRAME_SLOT] = parent; - this.primitiveLocals = new long[numLocals]; - } - - public Frame(int numLocals) { - this(numLocals, null); - } - - public Object getObject(int index) { - return locals[index]; - } - - public void setObject(int index, Object value) { - locals[index] = value; - } - - public float getFloat(int index) { - return unsafe.getFloat(primitiveLocals, (long) index * Unsafe.ARRAY_LONG_INDEX_SCALE + Unsafe.ARRAY_LONG_BASE_OFFSET); - } - - public void setFloat(int index, float value) { - unsafe.putFloat(primitiveLocals, (long) index * Unsafe.ARRAY_LONG_INDEX_SCALE + Unsafe.ARRAY_LONG_BASE_OFFSET, value); - } - - public long getLong(int index) { - return unsafe.getLong(primitiveLocals, (long) index * Unsafe.ARRAY_LONG_INDEX_SCALE + Unsafe.ARRAY_LONG_BASE_OFFSET); - } - - public void setLong(int index, long value) { - unsafe.putLong(primitiveLocals, (long) index * Unsafe.ARRAY_LONG_INDEX_SCALE + Unsafe.ARRAY_LONG_BASE_OFFSET, value); - } - - public int getInt(int index) { - return unsafe.getInt(primitiveLocals, (long) index * Unsafe.ARRAY_LONG_INDEX_SCALE + Unsafe.ARRAY_LONG_BASE_OFFSET); - } - - public void setInt(int index, int value) { - unsafe.putInt(primitiveLocals, (long) index * Unsafe.ARRAY_LONG_INDEX_SCALE + Unsafe.ARRAY_LONG_BASE_OFFSET, value); - } - - public double getDouble(int index) { - return unsafe.getDouble(primitiveLocals, (long) index * Unsafe.ARRAY_LONG_INDEX_SCALE + Unsafe.ARRAY_LONG_BASE_OFFSET); - } - - public void setDouble(int index, double value) { - unsafe.putDouble(primitiveLocals, (long) index * Unsafe.ARRAY_LONG_INDEX_SCALE + Unsafe.ARRAY_LONG_BASE_OFFSET, value); - } - - public static Frame getParentFrame(Frame frame, int level) { - assert level >= 0; - if (level == 0) { - return frame; - } else { - return getParentFrame((Frame) frame.getObject(PARENT_FRAME_SLOT), level - 1); - } - } - - public static Frame getTopFrame(Frame frame) { - Frame parentFrame = (Frame) frame.getObject(PARENT_FRAME_SLOT); - if (parentFrame == null) { - return frame; - } else { - return getTopFrame(parentFrame); - } - } - - public static Object[] getArguments(Frame frame, int argOffset) { - return (Object[]) frame.getObject(argOffset); - } - - public int size() { - return locals.length; - } - - @SuppressWarnings("unused") - private boolean indexExists(int index) { - return index >= 0 && index < locals.length; - } - - private static Unsafe getUnsafe() { - try { - return Unsafe.getUnsafe(); - } catch (SecurityException e) { - } - try { - Field theUnsafeInstance = Unsafe.class.getDeclaredField("theUnsafe"); - theUnsafeInstance.setAccessible(true); - return (Unsafe) theUnsafeInstance.get(Unsafe.class); - } catch (Exception e) { - throw new RuntimeException("exception while trying to get Unsafe.theUnsafe via reflection:", e); - } - } -} diff -r 149092d59dd0 -r 37b700379656 graal/com.oracle.graal.interpreter/src/com/oracle/graal/interpreter/InterpreterCallable.java --- a/graal/com.oracle.graal.interpreter/src/com/oracle/graal/interpreter/InterpreterCallable.java Fri Feb 01 17:25:39 2013 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,35 +0,0 @@ -/* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.graal.interpreter; - -import com.oracle.graal.api.meta.*; - -public interface InterpreterCallable { - - // static final fields - String INTERPRETER_CALLABLE_INVOKE_NAME = "invoke"; - Class[] INTERPRETER_CALLABLE_INVOKE_SIGNATURE = {InterpreterFrame.class, ResolvedJavaMethod.class, Object[].class}; - - // methods - Object invoke(InterpreterFrame caller, ResolvedJavaMethod method, Object[] arguments) throws Throwable; -} diff -r 149092d59dd0 -r 37b700379656 graal/com.oracle.graal.interpreter/src/com/oracle/graal/interpreter/InterpreterException.java --- a/graal/com.oracle.graal.interpreter/src/com/oracle/graal/interpreter/InterpreterException.java Fri Feb 01 17:25:39 2013 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,41 +0,0 @@ -/* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.graal.interpreter; - -/** - * Thrown if executed byte code caused an error in {@link BytecodeInterpreter}. The actual execution - * exception is accessible using {@link #getCause()} or {@link #getExecutionThrowable()}. - */ -public class InterpreterException extends RuntimeException { - - private static final long serialVersionUID = 1L; - - public InterpreterException(Throwable cause) { - super(cause); - } - - public Throwable getExecutionThrowable() { - return getCause(); - } - -} diff -r 149092d59dd0 -r 37b700379656 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 Fri Feb 01 17:25:39 2013 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,353 +0,0 @@ -/* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.graal.interpreter; - -import java.util.*; - -import com.oracle.graal.api.meta.*; - -public class InterpreterFrame extends Frame { - - public static final int BASE_LENGTH = 3; - - private static final int METHOD_FRAME_SLOT = 1; - private static final int BCI_FRAME_SLOT = 2; - - private static final int DOUBLE = 2; - 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, 0); - } - - private InterpreterFrame(ResolvedJavaMethod method, InterpreterFrame parent, int additionalStackSpace, int depth) { - super(method.getMaxLocals() + method.getMaxStackSize() + 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, this.depth + 1); - int length = method.getSignature().getParameterSlots(hasReceiver); - - frame.pushVoid(method.getMaxLocals()); - if (length > 0) { - copyArguments(frame, length); - popVoid(length); - } - - return frame; - } - - public int resolveLocalIndex(int index) { - return BASE_LENGTH + index; - } - - public int depth() { - return depth; - } - - private int stackTos() { - return BASE_LENGTH + getMethod().getMaxLocals(); - } - - private void copyArguments(InterpreterFrame dest, int length) { - System.arraycopy(locals, tosSingle(length - 1), dest.locals, BASE_LENGTH, length); - System.arraycopy(primitiveLocals, tosSingle(length - 1), dest.primitiveLocals, BASE_LENGTH, length); - } - - public Object peekReceiver(ResolvedJavaMethod method) { - return getObject(tosSingle(method.getSignature().getParameterSlots(false))); - } - - public void pushBoth(Object oValue, int intValue) { - incrementTos(SINGLE); - setObject(tosSingle(0), oValue); - setInt(tosSingle(0), intValue); - } - - public void pushBoth(Object oValue, long longValue) { - incrementTos(SINGLE); - setObject(tosSingle(0), oValue); - setLong(tosSingle(0), longValue); - } - - public void pushObject(Object value) { - incrementTos(SINGLE); - setObject(tosSingle(0), value); - } - - public void pushInt(int value) { - incrementTos(SINGLE); - setInt(tosSingle(0), value); - } - - public void pushDouble(double value) { - incrementTos(DOUBLE); - setDouble(tosDouble(0), value); - } - - public void pushFloat(float value) { - incrementTos(SINGLE); - setFloat(tosSingle(0), value); - } - - public void pushLong(long value) { - incrementTos(DOUBLE); - setLong(tosDouble(0), value); - } - - public int popInt() { - int value = getInt(tosSingle(0)); - decrementTos(SINGLE); - return value; - } - - public double popDouble() { - double value = getDouble(tosDouble(0)); - decrementTos(DOUBLE); - return value; - } - - public float popFloat() { - float value = getFloat(tosSingle(0)); - decrementTos(SINGLE); - return value; - } - - public long popLong() { - long value = getLong(tosDouble(0)); - decrementTos(DOUBLE); - return value; - } - - public Object popObject() { - Object value = getObject(tosSingle(0)); - decrementTos(SINGLE); - return value; - } - - public void swapSingle() { - int tmpInt = getInt(tosSingle(1)); - Object tmpObject = getObject(tosSingle(1)); - - setInt(tosSingle(1), getInt(tosSingle(0))); - setObject(tosSingle(1), getObject(tosSingle(0))); - - setInt(tosSingle(0), tmpInt); - setObject(tosSingle(0), tmpObject); - } - - public void dupx1() { - long tosLong = getLong(tosSingle(0)); - Object tosObject = getObject(tosSingle(0)); - - swapSingle(); - - pushBoth(tosObject, tosLong); - } - - public void dup2x1() { - long tosLong2 = getLong(tosSingle(2)); - Object tosObject2 = getObject(tosSingle(2)); - long tosLong1 = getLong(tosSingle(1)); - Object tosObject1 = getObject(tosSingle(1)); - long tosLong0 = getLong(tosSingle(0)); - Object tosObject0 = getObject(tosSingle(0)); - - popVoid(3); - - pushBoth(tosObject1, tosLong1); - pushBoth(tosObject0, tosLong0); - - pushBoth(tosObject2, tosLong2); - - pushBoth(tosObject1, tosLong1); - pushBoth(tosObject0, tosLong0); - } - - public void dup2x2() { - long tosLong3 = getLong(tosSingle(3)); - Object tosObject3 = getObject(tosSingle(3)); - long tosLong2 = getLong(tosSingle(2)); - Object tosObject2 = getObject(tosSingle(2)); - long tosLong1 = getLong(tosSingle(1)); - Object tosObject1 = getObject(tosSingle(1)); - long tosLong0 = getLong(tosSingle(0)); - Object tosObject0 = getObject(tosSingle(0)); - - popVoid(4); - - pushBoth(tosObject1, tosLong1); - pushBoth(tosObject0, tosLong0); - - pushBoth(tosObject3, tosLong3); - pushBoth(tosObject2, tosLong2); - - pushBoth(tosObject1, tosLong1); - pushBoth(tosObject0, tosLong0); - } - - public void dupx2() { - long tosLong2 = getLong(tosSingle(2)); - Object tosObject2 = getObject(tosSingle(2)); - long tosLong1 = getLong(tosSingle(1)); - Object tosObject1 = getObject(tosSingle(1)); - long tosLong0 = getLong(tosSingle(0)); - Object tosObject0 = getObject(tosSingle(0)); - - popVoid(3); - - pushBoth(tosObject0, tosLong0); - pushBoth(tosObject2, tosLong2); - pushBoth(tosObject1, tosLong1); - pushBoth(tosObject0, tosLong0); - } - - public void dup(int length) { - assert length > 0; - for (int i = 0; i < length; i++) { - long valueN1 = getLong(tosSingle(length - i - 1)); - Object valueO1 = getObject(tosSingle(length - i - 1)); - - pushVoid(1); - - setLong(tosSingle(0), valueN1); - setObject(tosSingle(0), valueO1); - } - } - - private void incrementTos(int size) { - tos += size; - } - - private void decrementTos(int size) { - assert tos - size >= stackTos(); - tos -= size; - } - - private int tosDouble(int offset) { - assert offset >= 0; - return tos - DOUBLE - (offset * DOUBLE); - } - - private int tosSingle(int offset) { - assert offset >= 0; - return tos - SINGLE - offset; - } - - public int getStackTop() { - return tos; - } - - public void pushVoid(int count) { - incrementTos(count * SINGLE); - } - - public void popVoid(int count) { - decrementTos(count * SINGLE); - } - - public ConstantPool getConstantPool() { - return getMethod().getConstantPool(); - } - - private void setMethod(ResolvedJavaMethod method) { - setObject(METHOD_FRAME_SLOT, method); - } - - public ResolvedJavaMethod getMethod() { - return (ResolvedJavaMethod) getObject(METHOD_FRAME_SLOT); - } - - public void setBCI(int bci) { - setInt(BCI_FRAME_SLOT, bci); - } - - public int getBCI() { - return getInt(BCI_FRAME_SLOT); - } - - public void pushTo(InterpreterFrame childFrame, int argumentSlots) { - System.arraycopy(locals, tos - argumentSlots, childFrame.locals, InterpreterFrame.MIN_FRAME_SIZE, argumentSlots); - - System.arraycopy(primitiveLocals, tos - argumentSlots, childFrame.primitiveLocals, InterpreterFrame.MIN_FRAME_SIZE, argumentSlots); - popVoid(argumentSlots); - } - - public InterpreterFrame getParentFrame() { - return (InterpreterFrame) getObject(PARENT_FRAME_SLOT); - } - - public void dispose() { - // Clear out references in locals array. - Arrays.fill(locals, null); - } - - @Override - public String toString() { - ResolvedJavaMethod method = getMethod(); - StringBuilder b = new StringBuilder(getMethod().asStackTraceElement(getBCI()).toString()); - for (int i = 0; i < tos; i++) { - Object object = getObject(tosSingle(i)); - long primitive = getLong(tosSingle(i)); - - String objectString = null; - if (object != null) { - objectString = object.getClass().getSimpleName() + "@" + Integer.toHexString(object.hashCode()); - } - String primitiveString = "0x" + Long.toHexString(primitive).toUpperCase(); - String typeString; - - int index = tosSingle(i); - if (index == METHOD_FRAME_SLOT) { - typeString = "method"; - } else if (index == BCI_FRAME_SLOT) { - typeString = "bci"; - } else if (index == PARENT_FRAME_SLOT) { - typeString = "parent"; - } else if (index < BASE_LENGTH + method.getMaxLocals()) { - typeString = "var " + (index - BASE_LENGTH); - } else { - typeString = "local"; - } - b.append(String.format("%n [%d] %7s Primitive: %10s Object: %s", index, typeString, primitiveString, objectString)); - } - if (getParentFrame() != null) { - b.append("\n").append(getParentFrame().toString()); - } - return b.toString(); - } - - public void popStack() { - // TODO(chumer): prevent popping local variables. - popVoid(tos - stackTos()); - } - -} diff -r 149092d59dd0 -r 37b700379656 mx/projects --- a/mx/projects Fri Feb 01 17:25:39 2013 +0100 +++ b/mx/projects Mon Feb 04 10:06:08 2013 +0100 @@ -55,13 +55,6 @@ project@com.oracle.graal.api.code@checkstyle=com.oracle.graal.graph project@com.oracle.graal.api.code@javaCompliance=1.7 -# graal.api.interpreter -project@com.oracle.graal.api.interpreter@subDir=graal -project@com.oracle.graal.api.interpreter@sourceDirs=src -project@com.oracle.graal.api.interpreter@dependencies=com.oracle.graal.api.meta -project@com.oracle.graal.api.interpreter@checkstyle=com.oracle.graal.graph -project@com.oracle.graal.api.interpreter@javaCompliance=1.7 - # graal.amd64 project@com.oracle.graal.amd64@subDir=graal project@com.oracle.graal.amd64@sourceDirs=src @@ -72,7 +65,7 @@ # graal.hotspot project@com.oracle.graal.hotspot@subDir=graal project@com.oracle.graal.hotspot@sourceDirs=src -project@com.oracle.graal.hotspot@dependencies=com.oracle.graal.snippets,com.oracle.graal.api.interpreter,com.oracle.graal.api.runtime,com.oracle.graal.printer +project@com.oracle.graal.hotspot@dependencies=com.oracle.graal.snippets,com.oracle.graal.api.runtime,com.oracle.graal.printer project@com.oracle.graal.hotspot@checkstyle=com.oracle.graal.graph project@com.oracle.graal.hotspot@javaCompliance=1.7 @@ -165,13 +158,6 @@ project@com.oracle.graal.nodes@checkstyle=com.oracle.graal.graph project@com.oracle.graal.nodes@javaCompliance=1.7 -# graal.interpreter -project@com.oracle.graal.interpreter@subDir=graal -project@com.oracle.graal.interpreter@sourceDirs=src -project@com.oracle.graal.interpreter@dependencies=com.oracle.graal.api.interpreter,com.oracle.graal.bytecode,com.oracle.graal.api.runtime -project@com.oracle.graal.interpreter@checkstyle=com.oracle.graal.graph -project@com.oracle.graal.interpreter@javaCompliance=1.7 - # graal.phases project@com.oracle.graal.phases@subDir=graal project@com.oracle.graal.phases@sourceDirs=src