changeset 18228:ab489bac3bc8

Correct the bci used by stateDuring in ForeignCallNode
author Tom Rodriguez <tom.rodriguez@oracle.com>
date Mon, 03 Nov 2014 10:17:24 -0800
parents bcb1e5c232d8
children e04712c8928a
files graal/com.oracle.graal.bytecode/src/com/oracle/graal/bytecode/Bytecodes.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/HotSpotReplacementsUtil.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/FrameState.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/Invoke.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/InvokeNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ForeignCallNode.java graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/InliningUtil.java graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/info/MultiTypeGuardInlineInfo.java mx/suite.py
diffstat 9 files changed, 308 insertions(+), 248 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.bytecode/src/com/oracle/graal/bytecode/Bytecodes.java	Fri Oct 31 12:22:06 2014 -0700
+++ b/graal/com.oracle.graal.bytecode/src/com/oracle/graal/bytecode/Bytecodes.java	Mon Nov 03 10:17:24 2014 -0800
@@ -32,7 +32,7 @@
  * "http://java.sun.com/docs/books/jvms/second_edition/html/VMSpecTOC.doc.html"> Java Virtual
  * Machine Specification</a>, and a set of <i>extended</i> bytecodes that support low-level
  * programming, for example, memory barriers.
- * 
+ *
  * The extended bytecodes are one or three bytes in size. The one-byte bytecodes follow the values
  * in the standard set, with no gap. The three-byte extended bytecodes share a common first byte and
  * carry additional instruction-specific information in the second and third bytes.
@@ -250,7 +250,7 @@
 
     /**
      * The last opcode defined by the JVM specification. To iterate over all JVM bytecodes:
-     * 
+     *
      * <pre>
      * for (int opcode = 0; opcode &lt;= Bytecodes.LAST_JVM_OPCODE; ++opcode) {
      *     //
@@ -357,219 +357,225 @@
      */
     private static final int[] lengthArray = new int[256];
 
+    /**
+     * An array that maps from a bytecode value to the number of slots pushed on the stack by the
+     * corresponding instruction.
+     */
+    private static final int[] stackEffectArray = new int[256];
+
     // Checkstyle: stop
     // @formatter:off
     static {
-        def(NOP                 , "nop"             , "b"    );
-        def(ACONST_NULL         , "aconst_null"     , "b"    );
-        def(ICONST_M1           , "iconst_m1"       , "b"    );
-        def(ICONST_0            , "iconst_0"        , "b"    );
-        def(ICONST_1            , "iconst_1"        , "b"    );
-        def(ICONST_2            , "iconst_2"        , "b"    );
-        def(ICONST_3            , "iconst_3"        , "b"    );
-        def(ICONST_4            , "iconst_4"        , "b"    );
-        def(ICONST_5            , "iconst_5"        , "b"    );
-        def(LCONST_0            , "lconst_0"        , "b"    );
-        def(LCONST_1            , "lconst_1"        , "b"    );
-        def(FCONST_0            , "fconst_0"        , "b"    );
-        def(FCONST_1            , "fconst_1"        , "b"    );
-        def(FCONST_2            , "fconst_2"        , "b"    );
-        def(DCONST_0            , "dconst_0"        , "b"    );
-        def(DCONST_1            , "dconst_1"        , "b"    );
-        def(BIPUSH              , "bipush"          , "bc"   );
-        def(SIPUSH              , "sipush"          , "bcc"  );
-        def(LDC                 , "ldc"             , "bi"   , TRAP);
-        def(LDC_W               , "ldc_w"           , "bii"  , TRAP);
-        def(LDC2_W              , "ldc2_w"          , "bii"  , TRAP);
-        def(ILOAD               , "iload"           , "bi"   , LOAD);
-        def(LLOAD               , "lload"           , "bi"   , LOAD);
-        def(FLOAD               , "fload"           , "bi"   , LOAD);
-        def(DLOAD               , "dload"           , "bi"   , LOAD);
-        def(ALOAD               , "aload"           , "bi"   , LOAD);
-        def(ILOAD_0             , "iload_0"         , "b"    , LOAD);
-        def(ILOAD_1             , "iload_1"         , "b"    , LOAD);
-        def(ILOAD_2             , "iload_2"         , "b"    , LOAD);
-        def(ILOAD_3             , "iload_3"         , "b"    , LOAD);
-        def(LLOAD_0             , "lload_0"         , "b"    , LOAD);
-        def(LLOAD_1             , "lload_1"         , "b"    , LOAD);
-        def(LLOAD_2             , "lload_2"         , "b"    , LOAD);
-        def(LLOAD_3             , "lload_3"         , "b"    , LOAD);
-        def(FLOAD_0             , "fload_0"         , "b"    , LOAD);
-        def(FLOAD_1             , "fload_1"         , "b"    , LOAD);
-        def(FLOAD_2             , "fload_2"         , "b"    , LOAD);
-        def(FLOAD_3             , "fload_3"         , "b"    , LOAD);
-        def(DLOAD_0             , "dload_0"         , "b"    , LOAD);
-        def(DLOAD_1             , "dload_1"         , "b"    , LOAD);
-        def(DLOAD_2             , "dload_2"         , "b"    , LOAD);
-        def(DLOAD_3             , "dload_3"         , "b"    , LOAD);
-        def(ALOAD_0             , "aload_0"         , "b"    , LOAD);
-        def(ALOAD_1             , "aload_1"         , "b"    , LOAD);
-        def(ALOAD_2             , "aload_2"         , "b"    , LOAD);
-        def(ALOAD_3             , "aload_3"         , "b"    , LOAD);
-        def(IALOAD              , "iaload"          , "b"    , TRAP);
-        def(LALOAD              , "laload"          , "b"    , TRAP);
-        def(FALOAD              , "faload"          , "b"    , TRAP);
-        def(DALOAD              , "daload"          , "b"    , TRAP);
-        def(AALOAD              , "aaload"          , "b"    , TRAP);
-        def(BALOAD              , "baload"          , "b"    , TRAP);
-        def(CALOAD              , "caload"          , "b"    , TRAP);
-        def(SALOAD              , "saload"          , "b"    , TRAP);
-        def(ISTORE              , "istore"          , "bi"   , STORE);
-        def(LSTORE              , "lstore"          , "bi"   , STORE);
-        def(FSTORE              , "fstore"          , "bi"   , STORE);
-        def(DSTORE              , "dstore"          , "bi"   , STORE);
-        def(ASTORE              , "astore"          , "bi"   , STORE);
-        def(ISTORE_0            , "istore_0"        , "b"    , STORE);
-        def(ISTORE_1            , "istore_1"        , "b"    , STORE);
-        def(ISTORE_2            , "istore_2"        , "b"    , STORE);
-        def(ISTORE_3            , "istore_3"        , "b"    , STORE);
-        def(LSTORE_0            , "lstore_0"        , "b"    , STORE);
-        def(LSTORE_1            , "lstore_1"        , "b"    , STORE);
-        def(LSTORE_2            , "lstore_2"        , "b"    , STORE);
-        def(LSTORE_3            , "lstore_3"        , "b"    , STORE);
-        def(FSTORE_0            , "fstore_0"        , "b"    , STORE);
-        def(FSTORE_1            , "fstore_1"        , "b"    , STORE);
-        def(FSTORE_2            , "fstore_2"        , "b"    , STORE);
-        def(FSTORE_3            , "fstore_3"        , "b"    , STORE);
-        def(DSTORE_0            , "dstore_0"        , "b"    , STORE);
-        def(DSTORE_1            , "dstore_1"        , "b"    , STORE);
-        def(DSTORE_2            , "dstore_2"        , "b"    , STORE);
-        def(DSTORE_3            , "dstore_3"        , "b"    , STORE);
-        def(ASTORE_0            , "astore_0"        , "b"    , STORE);
-        def(ASTORE_1            , "astore_1"        , "b"    , STORE);
-        def(ASTORE_2            , "astore_2"        , "b"    , STORE);
-        def(ASTORE_3            , "astore_3"        , "b"    , STORE);
-        def(IASTORE             , "iastore"         , "b"    , TRAP);
-        def(LASTORE             , "lastore"         , "b"    , TRAP);
-        def(FASTORE             , "fastore"         , "b"    , TRAP);
-        def(DASTORE             , "dastore"         , "b"    , TRAP);
-        def(AASTORE             , "aastore"         , "b"    , TRAP);
-        def(BASTORE             , "bastore"         , "b"    , TRAP);
-        def(CASTORE             , "castore"         , "b"    , TRAP);
-        def(SASTORE             , "sastore"         , "b"    , TRAP);
-        def(POP                 , "pop"             , "b"    );
-        def(POP2                , "pop2"            , "b"    );
-        def(DUP                 , "dup"             , "b"    );
-        def(DUP_X1              , "dup_x1"          , "b"    );
-        def(DUP_X2              , "dup_x2"          , "b"    );
-        def(DUP2                , "dup2"            , "b"    );
-        def(DUP2_X1             , "dup2_x1"         , "b"    );
-        def(DUP2_X2             , "dup2_x2"         , "b"    );
-        def(SWAP                , "swap"            , "b"    );
-        def(IADD                , "iadd"            , "b"    , COMMUTATIVE | ASSOCIATIVE);
-        def(LADD                , "ladd"            , "b"    , COMMUTATIVE | ASSOCIATIVE);
-        def(FADD                , "fadd"            , "b"    , COMMUTATIVE | ASSOCIATIVE);
-        def(DADD                , "dadd"            , "b"    , COMMUTATIVE | ASSOCIATIVE);
-        def(ISUB                , "isub"            , "b"    );
-        def(LSUB                , "lsub"            , "b"    );
-        def(FSUB                , "fsub"            , "b"    );
-        def(DSUB                , "dsub"            , "b"    );
-        def(IMUL                , "imul"            , "b"    , COMMUTATIVE | ASSOCIATIVE);
-        def(LMUL                , "lmul"            , "b"    , COMMUTATIVE | ASSOCIATIVE);
-        def(FMUL                , "fmul"            , "b"    , COMMUTATIVE | ASSOCIATIVE);
-        def(DMUL                , "dmul"            , "b"    , COMMUTATIVE | ASSOCIATIVE);
-        def(IDIV                , "idiv"            , "b"    , TRAP);
-        def(LDIV                , "ldiv"            , "b"    , TRAP);
-        def(FDIV                , "fdiv"            , "b"    );
-        def(DDIV                , "ddiv"            , "b"    );
-        def(IREM                , "irem"            , "b"    , TRAP);
-        def(LREM                , "lrem"            , "b"    , TRAP);
-        def(FREM                , "frem"            , "b"    );
-        def(DREM                , "drem"            , "b"    );
-        def(INEG                , "ineg"            , "b"    );
-        def(LNEG                , "lneg"            , "b"    );
-        def(FNEG                , "fneg"            , "b"    );
-        def(DNEG                , "dneg"            , "b"    );
-        def(ISHL                , "ishl"            , "b"    );
-        def(LSHL                , "lshl"            , "b"    );
-        def(ISHR                , "ishr"            , "b"    );
-        def(LSHR                , "lshr"            , "b"    );
-        def(IUSHR               , "iushr"           , "b"    );
-        def(LUSHR               , "lushr"           , "b"    );
-        def(IAND                , "iand"            , "b"    , COMMUTATIVE | ASSOCIATIVE);
-        def(LAND                , "land"            , "b"    , COMMUTATIVE | ASSOCIATIVE);
-        def(IOR                 , "ior"             , "b"    , COMMUTATIVE | ASSOCIATIVE);
-        def(LOR                 , "lor"             , "b"    , COMMUTATIVE | ASSOCIATIVE);
-        def(IXOR                , "ixor"            , "b"    , COMMUTATIVE | ASSOCIATIVE);
-        def(LXOR                , "lxor"            , "b"    , COMMUTATIVE | ASSOCIATIVE);
-        def(IINC                , "iinc"            , "bic"  , LOAD | STORE);
-        def(I2L                 , "i2l"             , "b"    );
-        def(I2F                 , "i2f"             , "b"    );
-        def(I2D                 , "i2d"             , "b"    );
-        def(L2I                 , "l2i"             , "b"    );
-        def(L2F                 , "l2f"             , "b"    );
-        def(L2D                 , "l2d"             , "b"    );
-        def(F2I                 , "f2i"             , "b"    );
-        def(F2L                 , "f2l"             , "b"    );
-        def(F2D                 , "f2d"             , "b"    );
-        def(D2I                 , "d2i"             , "b"    );
-        def(D2L                 , "d2l"             , "b"    );
-        def(D2F                 , "d2f"             , "b"    );
-        def(I2B                 , "i2b"             , "b"    );
-        def(I2C                 , "i2c"             , "b"    );
-        def(I2S                 , "i2s"             , "b"    );
-        def(LCMP                , "lcmp"            , "b"    );
-        def(FCMPL               , "fcmpl"           , "b"    );
-        def(FCMPG               , "fcmpg"           , "b"    );
-        def(DCMPL               , "dcmpl"           , "b"    );
-        def(DCMPG               , "dcmpg"           , "b"    );
-        def(IFEQ                , "ifeq"            , "boo"  , FALL_THROUGH | BRANCH);
-        def(IFNE                , "ifne"            , "boo"  , FALL_THROUGH | BRANCH);
-        def(IFLT                , "iflt"            , "boo"  , FALL_THROUGH | BRANCH);
-        def(IFGE                , "ifge"            , "boo"  , FALL_THROUGH | BRANCH);
-        def(IFGT                , "ifgt"            , "boo"  , FALL_THROUGH | BRANCH);
-        def(IFLE                , "ifle"            , "boo"  , FALL_THROUGH | BRANCH);
-        def(IF_ICMPEQ           , "if_icmpeq"       , "boo"  , COMMUTATIVE | FALL_THROUGH | BRANCH);
-        def(IF_ICMPNE           , "if_icmpne"       , "boo"  , COMMUTATIVE | FALL_THROUGH | BRANCH);
-        def(IF_ICMPLT           , "if_icmplt"       , "boo"  , FALL_THROUGH | BRANCH);
-        def(IF_ICMPGE           , "if_icmpge"       , "boo"  , FALL_THROUGH | BRANCH);
-        def(IF_ICMPGT           , "if_icmpgt"       , "boo"  , FALL_THROUGH | BRANCH);
-        def(IF_ICMPLE           , "if_icmple"       , "boo"  , FALL_THROUGH | BRANCH);
-        def(IF_ACMPEQ           , "if_acmpeq"       , "boo"  , COMMUTATIVE | FALL_THROUGH | BRANCH);
-        def(IF_ACMPNE           , "if_acmpne"       , "boo"  , COMMUTATIVE | FALL_THROUGH | BRANCH);
-        def(GOTO                , "goto"            , "boo"  , STOP | BRANCH);
-        def(JSR                 , "jsr"             , "boo"  , STOP | BRANCH);
-        def(RET                 , "ret"             , "bi"   , STOP);
-        def(TABLESWITCH         , "tableswitch"     , ""     , STOP);
-        def(LOOKUPSWITCH        , "lookupswitch"    , ""     , STOP);
-        def(IRETURN             , "ireturn"         , "b"    , TRAP | STOP);
-        def(LRETURN             , "lreturn"         , "b"    , TRAP | STOP);
-        def(FRETURN             , "freturn"         , "b"    , TRAP | STOP);
-        def(DRETURN             , "dreturn"         , "b"    , TRAP | STOP);
-        def(ARETURN             , "areturn"         , "b"    , TRAP | STOP);
-        def(RETURN              , "return"          , "b"    , TRAP | STOP);
-        def(GETSTATIC           , "getstatic"       , "bjj"  , TRAP | FIELD_READ);
-        def(PUTSTATIC           , "putstatic"       , "bjj"  , TRAP | FIELD_WRITE);
-        def(GETFIELD            , "getfield"        , "bjj"  , TRAP | FIELD_READ);
-        def(PUTFIELD            , "putfield"        , "bjj"  , TRAP | FIELD_WRITE);
-        def(INVOKEVIRTUAL       , "invokevirtual"   , "bjj"  , TRAP | INVOKE);
-        def(INVOKESPECIAL       , "invokespecial"   , "bjj"  , TRAP | INVOKE);
-        def(INVOKESTATIC        , "invokestatic"    , "bjj"  , TRAP | INVOKE);
-        def(INVOKEINTERFACE     , "invokeinterface" , "bjja_", TRAP | INVOKE);
-        def(INVOKEDYNAMIC       , "invokedynamic"   , "bjjjj", TRAP | INVOKE);
-        def(NEW                 , "new"             , "bii"  , TRAP);
-        def(NEWARRAY            , "newarray"        , "bc"   , TRAP);
-        def(ANEWARRAY           , "anewarray"       , "bii"  , TRAP);
-        def(ARRAYLENGTH         , "arraylength"     , "b"    , TRAP);
-        def(ATHROW              , "athrow"          , "b"    , TRAP | STOP);
-        def(CHECKCAST           , "checkcast"       , "bii"  , TRAP);
-        def(INSTANCEOF          , "instanceof"      , "bii"  , TRAP);
-        def(MONITORENTER        , "monitorenter"    , "b"    , TRAP);
-        def(MONITOREXIT         , "monitorexit"     , "b"    , TRAP);
-        def(WIDE                , "wide"            , ""     );
-        def(MULTIANEWARRAY      , "multianewarray"  , "biic" , TRAP);
-        def(IFNULL              , "ifnull"          , "boo"  , FALL_THROUGH | BRANCH);
-        def(IFNONNULL           , "ifnonnull"       , "boo"  , FALL_THROUGH | BRANCH);
-        def(GOTO_W              , "goto_w"          , "boooo", STOP | BRANCH);
-        def(JSR_W               , "jsr_w"           , "boooo", STOP | BRANCH);
-        def(BREAKPOINT          , "breakpoint"      , "b"    , TRAP);
+        def(NOP                 , "nop"             , "b"    ,  0);
+        def(ACONST_NULL         , "aconst_null"     , "b"    ,  1);
+        def(ICONST_M1           , "iconst_m1"       , "b"    ,  1);
+        def(ICONST_0            , "iconst_0"        , "b"    ,  1);
+        def(ICONST_1            , "iconst_1"        , "b"    ,  1);
+        def(ICONST_2            , "iconst_2"        , "b"    ,  1);
+        def(ICONST_3            , "iconst_3"        , "b"    ,  1);
+        def(ICONST_4            , "iconst_4"        , "b"    ,  1);
+        def(ICONST_5            , "iconst_5"        , "b"    ,  1);
+        def(LCONST_0            , "lconst_0"        , "b"    ,  2);
+        def(LCONST_1            , "lconst_1"        , "b"    ,  2);
+        def(FCONST_0            , "fconst_0"        , "b"    ,  1);
+        def(FCONST_1            , "fconst_1"        , "b"    ,  1);
+        def(FCONST_2            , "fconst_2"        , "b"    ,  1);
+        def(DCONST_0            , "dconst_0"        , "b"    ,  2);
+        def(DCONST_1            , "dconst_1"        , "b"    ,  2);
+        def(BIPUSH              , "bipush"          , "bc"   ,  1);
+        def(SIPUSH              , "sipush"          , "bcc"  ,  1);
+        def(LDC                 , "ldc"             , "bi"   ,  1, TRAP);
+        def(LDC_W               , "ldc_w"           , "bii"  ,  1, TRAP);
+        def(LDC2_W              , "ldc2_w"          , "bii"  ,  2, TRAP);
+        def(ILOAD               , "iload"           , "bi"   ,  1, LOAD);
+        def(LLOAD               , "lload"           , "bi"   ,  2, LOAD);
+        def(FLOAD               , "fload"           , "bi"   ,  1, LOAD);
+        def(DLOAD               , "dload"           , "bi"   ,  2, LOAD);
+        def(ALOAD               , "aload"           , "bi"   ,  1, LOAD);
+        def(ILOAD_0             , "iload_0"         , "b"    ,  1, LOAD);
+        def(ILOAD_1             , "iload_1"         , "b"    ,  1, LOAD);
+        def(ILOAD_2             , "iload_2"         , "b"    ,  1, LOAD);
+        def(ILOAD_3             , "iload_3"         , "b"    ,  1, LOAD);
+        def(LLOAD_0             , "lload_0"         , "b"    ,  2, LOAD);
+        def(LLOAD_1             , "lload_1"         , "b"    ,  2, LOAD);
+        def(LLOAD_2             , "lload_2"         , "b"    ,  2, LOAD);
+        def(LLOAD_3             , "lload_3"         , "b"    ,  2, LOAD);
+        def(FLOAD_0             , "fload_0"         , "b"    ,  1, LOAD);
+        def(FLOAD_1             , "fload_1"         , "b"    ,  1, LOAD);
+        def(FLOAD_2             , "fload_2"         , "b"    ,  1, LOAD);
+        def(FLOAD_3             , "fload_3"         , "b"    ,  1, LOAD);
+        def(DLOAD_0             , "dload_0"         , "b"    ,  2, LOAD);
+        def(DLOAD_1             , "dload_1"         , "b"    ,  2, LOAD);
+        def(DLOAD_2             , "dload_2"         , "b"    ,  2, LOAD);
+        def(DLOAD_3             , "dload_3"         , "b"    ,  2, LOAD);
+        def(ALOAD_0             , "aload_0"         , "b"    ,  1, LOAD);
+        def(ALOAD_1             , "aload_1"         , "b"    ,  1, LOAD);
+        def(ALOAD_2             , "aload_2"         , "b"    ,  1, LOAD);
+        def(ALOAD_3             , "aload_3"         , "b"    ,  1, LOAD);
+        def(IALOAD              , "iaload"          , "b"    , -1, TRAP);
+        def(LALOAD              , "laload"          , "b"    ,  0, TRAP);
+        def(FALOAD              , "faload"          , "b"    , -1, TRAP);
+        def(DALOAD              , "daload"          , "b"    ,  0, TRAP);
+        def(AALOAD              , "aaload"          , "b"    , -1, TRAP);
+        def(BALOAD              , "baload"          , "b"    , -1, TRAP);
+        def(CALOAD              , "caload"          , "b"    , -1, TRAP);
+        def(SALOAD              , "saload"          , "b"    , -1, TRAP);
+        def(ISTORE              , "istore"          , "bi"   , -1, STORE);
+        def(LSTORE              , "lstore"          , "bi"   , -2, STORE);
+        def(FSTORE              , "fstore"          , "bi"   , -1, STORE);
+        def(DSTORE              , "dstore"          , "bi"   , -2, STORE);
+        def(ASTORE              , "astore"          , "bi"   , -1, STORE);
+        def(ISTORE_0            , "istore_0"        , "b"    , -1, STORE);
+        def(ISTORE_1            , "istore_1"        , "b"    , -1, STORE);
+        def(ISTORE_2            , "istore_2"        , "b"    , -1, STORE);
+        def(ISTORE_3            , "istore_3"        , "b"    , -1, STORE);
+        def(LSTORE_0            , "lstore_0"        , "b"    , -2, STORE);
+        def(LSTORE_1            , "lstore_1"        , "b"    , -2, STORE);
+        def(LSTORE_2            , "lstore_2"        , "b"    , -2, STORE);
+        def(LSTORE_3            , "lstore_3"        , "b"    , -2, STORE);
+        def(FSTORE_0            , "fstore_0"        , "b"    , -1, STORE);
+        def(FSTORE_1            , "fstore_1"        , "b"    , -1, STORE);
+        def(FSTORE_2            , "fstore_2"        , "b"    , -1, STORE);
+        def(FSTORE_3            , "fstore_3"        , "b"    , -1, STORE);
+        def(DSTORE_0            , "dstore_0"        , "b"    , -2, STORE);
+        def(DSTORE_1            , "dstore_1"        , "b"    , -2, STORE);
+        def(DSTORE_2            , "dstore_2"        , "b"    , -2, STORE);
+        def(DSTORE_3            , "dstore_3"        , "b"    , -2, STORE);
+        def(ASTORE_0            , "astore_0"        , "b"    , -1, STORE);
+        def(ASTORE_1            , "astore_1"        , "b"    , -1, STORE);
+        def(ASTORE_2            , "astore_2"        , "b"    , -1, STORE);
+        def(ASTORE_3            , "astore_3"        , "b"    , -1, STORE);
+        def(IASTORE             , "iastore"         , "b"    , -3, TRAP);
+        def(LASTORE             , "lastore"         , "b"    , -4, TRAP);
+        def(FASTORE             , "fastore"         , "b"    , -3, TRAP);
+        def(DASTORE             , "dastore"         , "b"    , -4, TRAP);
+        def(AASTORE             , "aastore"         , "b"    , -3, TRAP);
+        def(BASTORE             , "bastore"         , "b"    , -3, TRAP);
+        def(CASTORE             , "castore"         , "b"    , -3, TRAP);
+        def(SASTORE             , "sastore"         , "b"    , -3, TRAP);
+        def(POP                 , "pop"             , "b"    , -1);
+        def(POP2                , "pop2"            , "b"    , -2);
+        def(DUP                 , "dup"             , "b"    ,  1);
+        def(DUP_X1              , "dup_x1"          , "b"    ,  1);
+        def(DUP_X2              , "dup_x2"          , "b"    ,  1);
+        def(DUP2                , "dup2"            , "b"    ,  2);
+        def(DUP2_X1             , "dup2_x1"         , "b"    ,  2);
+        def(DUP2_X2             , "dup2_x2"         , "b"    ,  2);
+        def(SWAP                , "swap"            , "b"    ,  0);
+        def(IADD                , "iadd"            , "b"    , -1, COMMUTATIVE | ASSOCIATIVE);
+        def(LADD                , "ladd"            , "b"    , -2, COMMUTATIVE | ASSOCIATIVE);
+        def(FADD                , "fadd"            , "b"    , -1, COMMUTATIVE | ASSOCIATIVE);
+        def(DADD                , "dadd"            , "b"    , -2, COMMUTATIVE | ASSOCIATIVE);
+        def(ISUB                , "isub"            , "b"    , -1);
+        def(LSUB                , "lsub"            , "b"    , -2);
+        def(FSUB                , "fsub"            , "b"    , -1);
+        def(DSUB                , "dsub"            , "b"    , -2);
+        def(IMUL                , "imul"            , "b"    , -1, COMMUTATIVE | ASSOCIATIVE);
+        def(LMUL                , "lmul"            , "b"    , -2, COMMUTATIVE | ASSOCIATIVE);
+        def(FMUL                , "fmul"            , "b"    , -1, COMMUTATIVE | ASSOCIATIVE);
+        def(DMUL                , "dmul"            , "b"    , -2, COMMUTATIVE | ASSOCIATIVE);
+        def(IDIV                , "idiv"            , "b"    , -1, TRAP);
+        def(LDIV                , "ldiv"            , "b"    , -2, TRAP);
+        def(FDIV                , "fdiv"            , "b"    , -1);
+        def(DDIV                , "ddiv"            , "b"    , -2);
+        def(IREM                , "irem"            , "b"    , -1, TRAP);
+        def(LREM                , "lrem"            , "b"    , -2, TRAP);
+        def(FREM                , "frem"            , "b"    , -1);
+        def(DREM                , "drem"            , "b"    , -2);
+        def(INEG                , "ineg"            , "b"    ,  0);
+        def(LNEG                , "lneg"            , "b"    ,  0);
+        def(FNEG                , "fneg"            , "b"    ,  0);
+        def(DNEG                , "dneg"            , "b"    ,  0);
+        def(ISHL                , "ishl"            , "b"    , -1);
+        def(LSHL                , "lshl"            , "b"    , -1);
+        def(ISHR                , "ishr"            , "b"    , -1);
+        def(LSHR                , "lshr"            , "b"    , -1);
+        def(IUSHR               , "iushr"           , "b"    , -1);
+        def(LUSHR               , "lushr"           , "b"    , -1);
+        def(IAND                , "iand"            , "b"    , -1, COMMUTATIVE | ASSOCIATIVE);
+        def(LAND                , "land"            , "b"    , -2, COMMUTATIVE | ASSOCIATIVE);
+        def(IOR                 , "ior"             , "b"    , -1, COMMUTATIVE | ASSOCIATIVE);
+        def(LOR                 , "lor"             , "b"    , -2, COMMUTATIVE | ASSOCIATIVE);
+        def(IXOR                , "ixor"            , "b"    , -1, COMMUTATIVE | ASSOCIATIVE);
+        def(LXOR                , "lxor"            , "b"    , -2, COMMUTATIVE | ASSOCIATIVE);
+        def(IINC                , "iinc"            , "bic"  ,  0, LOAD | STORE);
+        def(I2L                 , "i2l"             , "b"    ,  1);
+        def(I2F                 , "i2f"             , "b"    ,  0);
+        def(I2D                 , "i2d"             , "b"    ,  1);
+        def(L2I                 , "l2i"             , "b"    , -1);
+        def(L2F                 , "l2f"             , "b"    , -1);
+        def(L2D                 , "l2d"             , "b"    ,  0);
+        def(F2I                 , "f2i"             , "b"    ,  0);
+        def(F2L                 , "f2l"             , "b"    ,  1);
+        def(F2D                 , "f2d"             , "b"    ,  1);
+        def(D2I                 , "d2i"             , "b"    , -1);
+        def(D2L                 , "d2l"             , "b"    ,  0);
+        def(D2F                 , "d2f"             , "b"    , -1);
+        def(I2B                 , "i2b"             , "b"    ,  0);
+        def(I2C                 , "i2c"             , "b"    ,  0);
+        def(I2S                 , "i2s"             , "b"    ,  0);
+        def(LCMP                , "lcmp"            , "b"    , -3);
+        def(FCMPL               , "fcmpl"           , "b"    , -1);
+        def(FCMPG               , "fcmpg"           , "b"    , -1);
+        def(DCMPL               , "dcmpl"           , "b"    , -3);
+        def(DCMPG               , "dcmpg"           , "b"    , -3);
+        def(IFEQ                , "ifeq"            , "boo"  , -1, FALL_THROUGH | BRANCH);
+        def(IFNE                , "ifne"            , "boo"  , -1, FALL_THROUGH | BRANCH);
+        def(IFLT                , "iflt"            , "boo"  , -1, FALL_THROUGH | BRANCH);
+        def(IFGE                , "ifge"            , "boo"  , -1, FALL_THROUGH | BRANCH);
+        def(IFGT                , "ifgt"            , "boo"  , -1, FALL_THROUGH | BRANCH);
+        def(IFLE                , "ifle"            , "boo"  , -1, FALL_THROUGH | BRANCH);
+        def(IF_ICMPEQ           , "if_icmpeq"       , "boo"  , -2, COMMUTATIVE | FALL_THROUGH | BRANCH);
+        def(IF_ICMPNE           , "if_icmpne"       , "boo"  , -2, COMMUTATIVE | FALL_THROUGH | BRANCH);
+        def(IF_ICMPLT           , "if_icmplt"       , "boo"  , -2, FALL_THROUGH | BRANCH);
+        def(IF_ICMPGE           , "if_icmpge"       , "boo"  , -2, FALL_THROUGH | BRANCH);
+        def(IF_ICMPGT           , "if_icmpgt"       , "boo"  , -2, FALL_THROUGH | BRANCH);
+        def(IF_ICMPLE           , "if_icmple"       , "boo"  , -2, FALL_THROUGH | BRANCH);
+        def(IF_ACMPEQ           , "if_acmpeq"       , "boo"  , -2, COMMUTATIVE | FALL_THROUGH | BRANCH);
+        def(IF_ACMPNE           , "if_acmpne"       , "boo"  , -2, COMMUTATIVE | FALL_THROUGH | BRANCH);
+        def(GOTO                , "goto"            , "boo"  ,  0, STOP | BRANCH);
+        def(JSR                 , "jsr"             , "boo"  ,  0, STOP | BRANCH);
+        def(RET                 , "ret"             , "bi"   ,  0, STOP);
+        def(TABLESWITCH         , "tableswitch"     , ""     , -1, STOP);
+        def(LOOKUPSWITCH        , "lookupswitch"    , ""     , -1, STOP);
+        def(IRETURN             , "ireturn"         , "b"    , -1, TRAP | STOP);
+        def(LRETURN             , "lreturn"         , "b"    , -2, TRAP | STOP);
+        def(FRETURN             , "freturn"         , "b"    , -1, TRAP | STOP);
+        def(DRETURN             , "dreturn"         , "b"    , -2, TRAP | STOP);
+        def(ARETURN             , "areturn"         , "b"    , -1, TRAP | STOP);
+        def(RETURN              , "return"          , "b"    ,  0, TRAP | STOP);
+        def(GETSTATIC           , "getstatic"       , "bjj"  ,  1, TRAP | FIELD_READ);
+        def(PUTSTATIC           , "putstatic"       , "bjj"  , -1, TRAP | FIELD_WRITE);
+        def(GETFIELD            , "getfield"        , "bjj"  ,  0, TRAP | FIELD_READ);
+        def(PUTFIELD            , "putfield"        , "bjj"  , -2, TRAP | FIELD_WRITE);
+        def(INVOKEVIRTUAL       , "invokevirtual"   , "bjj"  , -1, TRAP | INVOKE);
+        def(INVOKESPECIAL       , "invokespecial"   , "bjj"  , -1, TRAP | INVOKE);
+        def(INVOKESTATIC        , "invokestatic"    , "bjj"  ,  0, TRAP | INVOKE);
+        def(INVOKEINTERFACE     , "invokeinterface" , "bjja_", -1, TRAP | INVOKE);
+        def(INVOKEDYNAMIC       , "invokedynamic"   , "bjjjj",  0, TRAP | INVOKE);
+        def(NEW                 , "new"             , "bii"  ,  1, TRAP);
+        def(NEWARRAY            , "newarray"        , "bc"   ,  0, TRAP);
+        def(ANEWARRAY           , "anewarray"       , "bii"  ,  0, TRAP);
+        def(ARRAYLENGTH         , "arraylength"     , "b"    ,  0, TRAP);
+        def(ATHROW              , "athrow"          , "b"    , -1, TRAP | STOP);
+        def(CHECKCAST           , "checkcast"       , "bii"  ,  0, TRAP);
+        def(INSTANCEOF          , "instanceof"      , "bii"  ,  0, TRAP);
+        def(MONITORENTER        , "monitorenter"    , "b"    , -1, TRAP);
+        def(MONITOREXIT         , "monitorexit"     , "b"    , -1, TRAP);
+        def(WIDE                , "wide"            , ""     ,  0);
+        def(MULTIANEWARRAY      , "multianewarray"  , "biic" ,  1, TRAP);
+        def(IFNULL              , "ifnull"          , "boo"  , -1, FALL_THROUGH | BRANCH);
+        def(IFNONNULL           , "ifnonnull"       , "boo"  , -1, FALL_THROUGH | BRANCH);
+        def(GOTO_W              , "goto_w"          , "boooo",  0, STOP | BRANCH);
+        def(JSR_W               , "jsr_w"           , "boooo",  0, STOP | BRANCH);
+        def(BREAKPOINT          , "breakpoint"      , "b"    ,  0, TRAP);
     }
     // @formatter:on
     // Checkstyle: resume
 
     /**
      * Determines if an opcode is commutative.
-     * 
+     *
      * @param opcode the opcode to check
      * @return {@code true} iff commutative
      */
@@ -579,7 +585,7 @@
 
     /**
      * Gets the length of an instruction denoted by a given opcode.
-     * 
+     *
      * @param opcode an instruction opcode
      * @return the length of the instruction denoted by {@code opcode}. If {@code opcode} is an
      *         illegal instruction or denotes a variable length instruction (e.g.
@@ -590,8 +596,21 @@
     }
 
     /**
+     * Gets the effect on the depth of the expression stack of an instruction denoted by a given
+     * opcode.
+     *
+     * @param opcode an instruction opcode
+     * @return the change in the stack caused by the instruction denoted by {@code opcode}. If
+     *         {@code opcode} is an illegal instruction then 0 is returned. Note that invoke
+     *         instructions may pop more arguments so this value is a minimum stack effect.
+     */
+    public static int stackEffectOf(int opcode) {
+        return stackEffectArray[opcode & 0xff];
+    }
+
+    /**
      * Gets the lower-case mnemonic for a given opcode.
-     * 
+     *
      * @param opcode an opcode
      * @return the mnemonic for {@code opcode} or {@code "<illegal opcode: " + opcode + ">"} if
      *         {@code opcode} is not a legal opcode
@@ -606,7 +625,7 @@
 
     /**
      * Allocation-free version of {@linkplain #nameOf(int)}.
-     * 
+     *
      * @param opcode an opcode.
      * @return the mnemonic for {@code opcode} or {@code "<illegal opcode>"} if {@code opcode} is
      *         not a legal opcode.
@@ -621,7 +640,7 @@
 
     /**
      * Gets the opcode corresponding to a given mnemonic.
-     * 
+     *
      * @param name an opcode mnemonic
      * @return the opcode corresponding to {@code mnemonic}
      * @throws IllegalArgumentException if {@code name} does not denote a valid opcode
@@ -637,7 +656,7 @@
 
     /**
      * Determines if a given opcode denotes an instruction that can cause an implicit exception.
-     * 
+     *
      * @param opcode an opcode to test
      * @return {@code true} iff {@code opcode} can cause an implicit exception, {@code false}
      *         otherwise
@@ -649,7 +668,7 @@
     /**
      * Determines if a given opcode denotes an instruction that loads a local variable to the
      * operand stack.
-     * 
+     *
      * @param opcode an opcode to test
      * @return {@code true} iff {@code opcode} loads a local variable to the operand stack,
      *         {@code false} otherwise
@@ -661,7 +680,7 @@
     /**
      * Determines if a given opcode denotes an instruction that ends a basic block and does not let
      * control flow fall through to its lexical successor.
-     * 
+     *
      * @param opcode an opcode to test
      * @return {@code true} iff {@code opcode} properly ends a basic block
      */
@@ -672,7 +691,7 @@
     /**
      * Determines if a given opcode denotes an instruction that stores a value to a local variable
      * after popping it from the operand stack.
-     * 
+     *
      * @param opcode an opcode to test
      * @return {@code true} iff {@code opcode} stores a value to a local variable, {@code false}
      *         otherwise
@@ -684,7 +703,7 @@
     /**
      * Determines if a given opcode denotes an instruction that stores a value to a local variable
      * after popping it from the operand stack.
-     * 
+     *
      * @param opcode an opcode to test
      * @return {@code true} iff {@code opcode} stores a value to a local variable, {@code false}
      *         otherwise
@@ -695,7 +714,7 @@
 
     /**
      * Determines if a given opcode is an instruction that delimits a basic block.
-     * 
+     *
      * @param opcode an opcode to test
      * @return {@code true} iff {@code opcode} delimits a basic block
      */
@@ -707,7 +726,7 @@
      * Determines if a given opcode is an instruction that has a 2 or 4 byte operand that is an
      * offset to another instruction in the same method. This does not include the
      * {@linkplain #TABLESWITCH switch} instructions.
-     * 
+     *
      * @param opcode an opcode to test
      * @return {@code true} iff {@code opcode} is a branch instruction with a single operand
      */
@@ -717,7 +736,7 @@
 
     /**
      * Determines if a given opcode denotes a conditional branch.
-     * 
+     *
      * @param opcode
      * @return {@code true} iff {@code opcode} is a conditional branch
      */
@@ -729,7 +748,7 @@
      * Gets the arithmetic operator name for a given opcode. If {@code opcode} does not denote an
      * arithmetic instruction, then the {@linkplain #nameOf(int) name} of the opcode is returned
      * instead.
-     * 
+     *
      * @param op an opcode
      * @return the arithmetic operator name
      */
@@ -789,26 +808,27 @@
 
     /**
      * Defines a bytecode by entering it into the arrays that record its name, length and flags.
-     * 
+     *
      * @param name instruction name (should be lower case)
      * @param format encodes the length of the instruction
      */
-    private static void def(int opcode, String name, String format) {
-        def(opcode, name, format, 0);
+    private static void def(int opcode, String name, String format, int stackEffect) {
+        def(opcode, name, format, stackEffect, 0);
     }
 
     /**
      * Defines a bytecode by entering it into the arrays that record its name, length and flags.
-     * 
+     *
      * @param name instruction name (lower case)
      * @param format encodes the length of the instruction
      * @param flags the set of {@link Flags} associated with the instruction
      */
-    private static void def(int opcode, String name, String format, int flags) {
+    private static void def(int opcode, String name, String format, int stackEffect, int flags) {
         assert nameArray[opcode] == null : "opcode " + opcode + " is already bound to name " + nameArray[opcode];
         nameArray[opcode] = name;
         int instructionLength = format.length();
         lengthArray[opcode] = instructionLength;
+        stackEffectArray[opcode] = stackEffect;
         Bytecodes.flagsArray[opcode] = flags;
 
         assert !isConditionalBranch(opcode) || isBranch(opcode) : "a conditional branch must also be a branch";
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/HotSpotReplacementsUtil.java	Fri Oct 31 12:22:06 2014 -0700
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/HotSpotReplacementsUtil.java	Mon Nov 03 10:17:24 2014 -0800
@@ -781,11 +781,8 @@
         return identityHashCode(IDENTITY_HASHCODE, x);
     }
 
-    @SuppressWarnings("unused")
     @NodeIntrinsic(ForeignCallNode.class)
-    public static int identityHashCode(@ConstantNodeParameter ForeignCallDescriptor descriptor, Object object) {
-        return System.identityHashCode(object);
-    }
+    public static native int identityHashCode(@ConstantNodeParameter ForeignCallDescriptor descriptor, Object object);
 
     @Fold
     public static int verifiedEntryPointOffset() {
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/FrameState.java	Fri Oct 31 12:22:06 2014 -0700
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/FrameState.java	Mon Nov 03 10:17:24 2014 -0800
@@ -26,6 +26,7 @@
 
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
+import com.oracle.graal.bytecode.*;
 import com.oracle.graal.debug.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.graph.iterators.*;
@@ -53,7 +54,7 @@
      */
     protected boolean rethrowException;
 
-    protected boolean duringCall;
+    protected final boolean duringCall;
 
     @OptionalInput(value = InputType.State) FrameState outerFrameState;
 
@@ -179,10 +180,6 @@
         return duringCall;
     }
 
-    public void setDuringCall(boolean b) {
-        this.duringCall = b;
-    }
-
     public ResolvedJavaMethod method() {
         return method;
     }
@@ -239,20 +236,30 @@
      * stack and the values in pushedValues pushed on the stack. The pushedValues will be formatted
      * correctly in slot encoding: a long or double will be followed by a null slot.
      */
+    public FrameState duplicateModifiedDuringCall(int newBci, Kind popKind, ValueNode... pushedValues) {
+        return duplicateModified(newBci, rethrowException, true, popKind, pushedValues);
+    }
+
     public FrameState duplicateModified(int newBci, boolean newRethrowException, Kind popKind, ValueNode... pushedValues) {
-        return duplicateModified(newBci, method, newRethrowException, popKind, pushedValues);
+        return duplicateModified(newBci, newRethrowException, duringCall, popKind, pushedValues);
+    }
+
+    /**
+     * Creates a copy of this frame state with the top of stack replaced with with
+     * {@code pushedValue} which must be of type {@code popKind}.
+     */
+    public FrameState duplicateModified(Kind popKind, ValueNode pushedValue) {
+        assert pushedValue != null && pushedValue.getKind() == popKind;
+        return duplicateModified(bci, rethrowException, duringCall, popKind, pushedValue);
     }
 
     /**
      * Creates a copy of this frame state with one stack element of type popKind popped from the
      * stack and the values in pushedValues pushed on the stack. The pushedValues will be formatted
-     * correctly in slot encoding: a long or double will be followed by a null slot.
+     * correctly in slot encoding: a long or double will be followed by a null slot. The bci will be
+     * changed to newBci.
      */
-    public FrameState duplicateModified(Kind popKind, ValueNode... pushedValues) {
-        return duplicateModified(bci, method, rethrowException, popKind, pushedValues);
-    }
-
-    private FrameState duplicateModified(int newBci, ResolvedJavaMethod newMethod, boolean newRethrowException, Kind popKind, ValueNode... pushedValues) {
+    private FrameState duplicateModified(int newBci, boolean newRethrowException, boolean newDuringCall, Kind popKind, ValueNode... pushedValues) {
         ArrayList<ValueNode> copy = new ArrayList<>(values.subList(0, localsSize + stackSize));
         if (popKind != Kind.Void) {
             if (stackAt(stackSize() - 1) == null) {
@@ -271,7 +278,30 @@
         int newStackSize = copy.size() - localsSize;
         copy.addAll(values.subList(localsSize + stackSize, values.size()));
 
-        return graph().add(FrameState.create(outerFrameState(), newMethod, newBci, copy, localsSize, newStackSize, newRethrowException, false, monitorIds, virtualObjectMappings));
+        assert checkStackDepth(bci, stackSize, duringCall, newBci, newStackSize, newDuringCall);
+        return graph().add(FrameState.create(outerFrameState(), method, newBci, copy, localsSize, newStackSize, newRethrowException, newDuringCall, monitorIds, virtualObjectMappings));
+    }
+
+    /**
+     * Perform a few sanity checks on the transformation of the stack state. The current expectation
+     * is that a stateAfter is being transformed into a stateDuring, so the stack depth may change.
+     */
+    private boolean checkStackDepth(int oldBci, int oldStackSize, boolean oldDuringCall, int newBci, int newStackSize, boolean newDuringCall) {
+        /*
+         * It would be nice to have a complete check of the shape of the FrameState based on a
+         * dataflow of the bytecodes but for now just check for obvious expression stack depth
+         * mistakes.
+         */
+        byte[] codes = method.getCode();
+        byte newCode = codes[newBci];
+        if (oldBci == newBci) {
+            assert oldStackSize == newStackSize || oldDuringCall != newDuringCall : "bci is unchanged, stack depth shouldn't change";
+        } else {
+            byte oldCode = codes[oldBci];
+            assert Bytecodes.lengthOf(newCode) + newBci == oldBci || Bytecodes.lengthOf(oldCode) + oldBci == newBci : "expecting roll back or forward";
+        }
+        assert !newDuringCall || Bytecodes.isInvoke(newCode) || newStackSize + Bytecodes.stackEffectOf(newCode) >= 0 : "stack underflow at " + Bytecodes.nameOf(newCode);
+        return true;
     }
 
     /**
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/Invoke.java	Fri Oct 31 12:22:06 2014 -0700
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/Invoke.java	Mon Nov 03 10:17:24 2014 -0800
@@ -84,8 +84,7 @@
 
     @Override
     default void computeStateDuring(FrameState stateAfter) {
-        FrameState newStateDuring = stateAfter.duplicateModified(bci(), stateAfter.rethrowException(), asNode().getKind());
-        newStateDuring.setDuringCall(true);
+        FrameState newStateDuring = stateAfter.duplicateModifiedDuringCall(bci(), asNode().getKind());
         setStateDuring(newStateDuring);
     }
 
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/InvokeNode.java	Fri Oct 31 12:22:06 2014 -0700
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/InvokeNode.java	Mon Nov 03 10:17:24 2014 -0800
@@ -164,6 +164,10 @@
             StateSplit stateSplit = (StateSplit) node;
             stateSplit.setStateAfter(currentStateAfter);
         }
+        if (node instanceof ForeignCallNode) {
+            ForeignCallNode foreign = (ForeignCallNode) node;
+            foreign.setBci(bci());
+        }
         if (node instanceof FixedWithNextNode) {
             graph().replaceFixedWithFixed(this, (FixedWithNextNode) node);
         } else if (node instanceof ControlSinkNode) {
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ForeignCallNode.java	Fri Oct 31 12:22:06 2014 -0700
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ForeignCallNode.java	Mon Nov 03 10:17:24 2014 -0800
@@ -43,6 +43,7 @@
     protected final ForeignCallsProvider foreignCalls;
 
     protected final ForeignCallDescriptor descriptor;
+    protected int bci = BytecodeFrame.UNKNOWN_BCI;
 
     public static ForeignCallNode create(@InjectedNodeParameter ForeignCallsProvider foreignCalls, ForeignCallDescriptor descriptor, ValueNode... arguments) {
         return new ForeignCallNode(foreignCalls, descriptor, arguments);
@@ -128,12 +129,22 @@
         this.stateDuring = stateDuring;
     }
 
+    /**
+     * Set the {@code bci} of the invoke bytecode for use when converting a stateAfter into a
+     * stateDuring.
+     */
+    public void setBci(int bci) {
+        this.bci = bci;
+    }
+
     @Override
     public void computeStateDuring(FrameState currentStateAfter) {
         FrameState newStateDuring;
         if ((currentStateAfter.stackSize() > 0 && currentStateAfter.stackAt(currentStateAfter.stackSize() - 1) == this) ||
                         (currentStateAfter.stackSize() > 1 && currentStateAfter.stackAt(currentStateAfter.stackSize() - 2) == this)) {
-            newStateDuring = currentStateAfter.duplicateModified(currentStateAfter.bci, currentStateAfter.rethrowException(), this.getKind());
+            // The result of this call is on the top of stack, so roll back to the previous bci.
+            assert bci != BytecodeFrame.UNKNOWN_BCI;
+            newStateDuring = currentStateAfter.duplicateModifiedDuringCall(bci, this.getKind());
         } else {
             newStateDuring = currentStateAfter;
         }
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/InliningUtil.java	Fri Oct 31 12:22:06 2014 -0700
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/InliningUtil.java	Mon Nov 03 10:17:24 2014 -0800
@@ -410,8 +410,7 @@
                         assert frameState.bci != BytecodeFrame.AFTER_EXCEPTION_BCI && frameState.bci != BytecodeFrame.BEFORE_BCI && frameState.bci != BytecodeFrame.AFTER_EXCEPTION_BCI &&
                                         frameState.bci != BytecodeFrame.UNWIND_BCI : frameState.bci;
                         if (outerFrameState == null) {
-                            outerFrameState = stateAtReturn.duplicateModified(invoke.bci(), stateAtReturn.rethrowException(), invokeReturnKind);
-                            outerFrameState.setDuringCall(true);
+                            outerFrameState = stateAtReturn.duplicateModifiedDuringCall(invoke.bci(), invokeReturnKind);
                         }
                         frameState.setOuterFrameState(outerFrameState);
                     }
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/info/MultiTypeGuardInlineInfo.java	Fri Oct 31 12:22:06 2014 -0700
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/info/MultiTypeGuardInlineInfo.java	Mon Nov 03 10:17:24 2014 -0800
@@ -498,7 +498,7 @@
 
             ExceptionObjectNode newExceptionEdge = (ExceptionObjectNode) exceptionEdge.copyWithInputs();
             // set new state (pop old exception object, push new one)
-            newExceptionEdge.setStateAfter(stateAfterException.duplicateModified(stateAfterException.bci, stateAfterException.rethrowException(), Kind.Object, newExceptionEdge));
+            newExceptionEdge.setStateAfter(stateAfterException.duplicateModified(Kind.Object, newExceptionEdge));
 
             AbstractEndNode endNode = graph.add(EndNode.create());
             newExceptionEdge.setNext(endNode);
--- a/mx/suite.py	Fri Oct 31 12:22:06 2014 -0700
+++ b/mx/suite.py	Mon Nov 03 10:17:24 2014 -0800
@@ -679,6 +679,7 @@
         "com.oracle.graal.graph",
         "com.oracle.graal.api.replacements",
         "com.oracle.graal.lir",
+        "com.oracle.graal.bytecode",
       ],
       "checkstyle" : "com.oracle.graal.graph",
       "javaCompliance" : "1.8",
@@ -830,7 +831,6 @@
       "sourceDirs" : ["src"],
       "dependencies" : [
         "com.oracle.graal.phases",
-        "com.oracle.graal.bytecode",
       ],
       "checkstyle" : "com.oracle.graal.graph",
       "javaCompliance" : "1.8",