changeset 14986:bb7e5331280d

Merge.
author Christian Humer <christian.humer@gmail.com>
date Sat, 05 Apr 2014 03:19:27 +0200
parents cceed4ebedb9 (current diff) a00b26a70011 (diff)
children 3b318ba935d5
files
diffstat 116 files changed, 1251 insertions(+), 1063 deletions(-) [+]
line wrap: on
line diff
--- a/.hgignore	Sat Apr 05 03:18:48 2014 +0200
+++ b/.hgignore	Sat Apr 05 03:19:27 2014 +0200
@@ -70,7 +70,7 @@
 .idea/
 ^cscope.out
 ^tags
-graal.src.zip$
+graal.src.zip*
 syntax: glob
 *.bgv
 core.*
--- a/graal/com.oracle.graal.asm.amd64/src/com/oracle/graal/asm/amd64/AMD64Assembler.java	Sat Apr 05 03:18:48 2014 +0200
+++ b/graal/com.oracle.graal.asm.amd64/src/com/oracle/graal/asm/amd64/AMD64Assembler.java	Sat Apr 05 03:19:27 2014 +0200
@@ -163,7 +163,7 @@
 
     /**
      * Constructs an assembler for the AMD64 architecture.
-     * 
+     *
      * @param registerConfig the register configuration used to bind {@link Register#Frame} and
      *            {@link Register#CallerFrame} to physical registers. This value can be null if this
      *            assembler instance will not be used to assemble instructions using these logical
@@ -183,44 +183,90 @@
         return r.encoding & 0x7;
     }
 
-    private void emitArith(int op1, int op2, Register dst, int imm32) {
-        emitArith(op1, op2, dst, imm32, false);
+    private void emitArithImm8(int op, Register dst, int imm8) {
+        int encode = prefixAndEncode(op, dst.encoding, true);
+        emitByte(0x80);
+        emitByte(0xC0 | encode);
+        emitByte(imm8);
+    }
+
+    private void emitArithImm16(int op, Register dst, int imm16) {
+        emitByte(0x66);
+        int encode = prefixAndEncode(op, dst.encoding);
+        if (isByte(imm16)) {
+            emitByte(0x83); // imm8 sign extend
+            emitByte(0xC0 | encode);
+            emitByte(imm16 & 0xFF);
+        } else {
+            emitByte(0x81);
+            emitByte(0xC0 | encode);
+            emitShort(imm16);
+        }
     }
 
-    private void emitArith(int op1, int op2, Register dst, int imm32, boolean force32Imm) {
-        assert isUByte(op1) && isUByte(op2) : "wrong opcode";
-        assert (op1 & 0x01) == 1 : "should be 32bit operation";
-        assert (op1 & 0x02) == 0 : "sign-extension bit should not be set";
-        if (isByte(imm32) && !force32Imm) {
-            emitByte(op1 | 0x02); // set sign bit
-            emitByte(op2 | encode(dst));
+    private void emitArithImm32(int op, Register dst, int imm32) {
+        int encode = prefixAndEncode(op, dst.encoding);
+        if (isByte(imm32)) {
+            emitByte(0x83); // imm8 sign extend
+            emitByte(0xC0 | encode);
             emitByte(imm32 & 0xFF);
         } else {
-            emitByte(op1);
-            emitByte(op2 | encode(dst));
+            emitByte(0x81);
+            emitByte(0xC0 | encode);
+            emitInt(imm32);
+        }
+    }
+
+    private void emitArithImm32q(int op, Register dst, int imm32) {
+        emitArithImm32q(op, dst, imm32, false);
+    }
+
+    private void emitArithImm32q(int op, Register dst, int imm32, boolean force32Imm) {
+        int encode = prefixqAndEncode(op, dst.encoding);
+        if (isByte(imm32) && !force32Imm) {
+            emitByte(0x83); // imm8 sign extend
+            emitByte(0xC0 | encode);
+            emitByte(imm32 & 0xFF);
+        } else {
+            emitByte(0x81);
+            emitByte(0xC0 | encode);
             emitInt(imm32);
         }
     }
 
     // immediate-to-memory forms
-    private void emitArithOperand(int op1, int op2, AMD64Address adr, int imm32) {
-        assert (op1 & 0x01) == 1 : "should be 32bit operation";
-        assert (op1 & 0x02) == 0 : "sign-extension bit should not be set";
-        if (isByte(imm32)) {
-            emitByte(op1 | 0x02); // set sign bit
-            emitOperandHelper(op2, adr);
-            emitByte(imm32 & 0xFF);
+    private void emitArithImm8(int op, AMD64Address adr, int imm8) {
+        prefix(adr);
+        emitByte(0x80);
+        emitOperandHelper(op, adr);
+        emitByte(imm8);
+    }
+
+    private void emitArithImm16(int op, AMD64Address adr, int imm16) {
+        emitByte(0x66);
+        prefix(adr);
+        if (isByte(imm16)) {
+            emitByte(0x83); // imm8 sign extend
+            emitOperandHelper(op, adr);
+            emitByte(imm16 & 0xFF);
         } else {
-            emitByte(op1);
-            emitOperandHelper(op2, adr);
-            emitInt(imm32);
+            emitByte(0x81);
+            emitOperandHelper(op, adr);
+            emitShort(imm16);
         }
     }
 
-    private void emitArith(int op1, int op2, Register dst, Register src) {
-        assert isUByte(op1) && isUByte(op2) : "wrong opcode";
-        emitByte(op1);
-        emitByte(op2 | encode(dst) << 3 | encode(src));
+    private void emitArithImm32(int op, AMD64Address adr, int imm32) {
+        prefix(adr);
+        if (isByte(imm32)) {
+            emitByte(0x83); // imm8 sign extend
+            emitOperandHelper(op, adr);
+            emitByte(imm32 & 0xFF);
+        } else {
+            emitByte(0x81);
+            emitOperandHelper(op, adr);
+            emitInt(imm32);
+        }
     }
 
     protected void emitOperandHelper(Register reg, AMD64Address addr) {
@@ -333,13 +379,11 @@
     }
 
     public final void addl(AMD64Address dst, int imm32) {
-        prefix(dst);
-        emitArithOperand(0x81, 0, dst, imm32);
+        emitArithImm32(0, dst, imm32);
     }
 
     public final void addl(Register dst, int imm32) {
-        prefix(dst);
-        emitArith(0x81, 0xC0, dst, imm32);
+        emitArithImm32(0, dst, imm32);
     }
 
     public final void addl(Register dst, AMD64Address src) {
@@ -349,8 +393,9 @@
     }
 
     public final void addl(Register dst, Register src) {
-        prefixAndEncode(dst.encoding, src.encoding);
-        emitArith(0x03, 0xC0, dst, src);
+        int encode = prefixAndEncode(dst.encoding, src.encoding);
+        emitByte(0x03);
+        emitByte(0xC0 | encode);
     }
 
     private void addrNop4() {
@@ -424,8 +469,7 @@
     }
 
     public final void andl(Register dst, int imm32) {
-        prefix(dst);
-        emitArith(0x81, 0xE0, dst, imm32);
+        emitArithImm32(4, dst, imm32);
     }
 
     public final void andl(Register dst, AMD64Address src) {
@@ -435,8 +479,9 @@
     }
 
     public final void andl(Register dst, Register src) {
-        prefixAndEncode(dst.encoding, src.encoding);
-        emitArith(0x23, 0xC0, dst, src);
+        int encode = prefixAndEncode(dst.encoding, src.encoding);
+        emitByte(0x23);
+        emitByte(0xC0 | encode);
     }
 
     public final void bsfq(Register dst, Register src) {
@@ -509,14 +554,56 @@
         emitOperandHelper(dst, src);
     }
 
+    public final void cmpb(Register dst, int imm8) {
+        emitArithImm8(7, dst, imm8);
+    }
+
+    public final void cmpb(Register dst, Register src) {
+        int encode = prefixAndEncode(dst.encoding, src.encoding, true);
+        emitByte(0x3A);
+        emitByte(0xC0 | encode);
+    }
+
+    public final void cmpb(Register dst, AMD64Address src) {
+        prefix(src, dst, true);
+        emitByte(0x3A);
+        emitOperandHelper(dst, src);
+    }
+
+    public final void cmpb(AMD64Address dst, int imm8) {
+        emitArithImm8(7, dst, imm8);
+    }
+
+    public final void cmpw(Register dst, int imm16) {
+        emitArithImm16(7, dst, imm16);
+    }
+
+    public final void cmpw(Register dst, Register src) {
+        emitByte(0x66);
+        int encode = prefixAndEncode(dst.encoding, src.encoding);
+        emitByte(0x3B);
+        emitByte(0xC0 | encode);
+    }
+
+    public final void cmpw(Register dst, AMD64Address src) {
+        emitByte(0x66);
+        prefix(src, dst);
+        emitByte(0x3B);
+        emitOperandHelper(dst, src);
+    }
+
+    public final void cmpw(AMD64Address dst, int imm16) {
+        emitArithImm16(7, dst, imm16);
+    }
+
     public final void cmpl(Register dst, int imm32) {
-        prefix(dst);
-        emitArith(0x81, 0xF8, dst, imm32);
+        emitArithImm32(7, dst, imm32);
     }
 
     public final void cmpl(Register dst, Register src) {
-        prefixAndEncode(dst.encoding, src.encoding);
-        emitArith(0x3B, 0xC0, dst, src);
+        int encode = prefixAndEncode(dst.encoding, src.encoding);
+        emitByte(0x3B);
+        emitByte(0xC0 | encode);
     }
 
     public final void cmpl(Register dst, AMD64Address src) {
@@ -526,10 +613,7 @@
     }
 
     public final void cmpl(AMD64Address dst, int imm32) {
-        prefix(dst);
-        emitByte(0x81);
-        emitOperandHelper(7, dst);
-        emitInt(imm32);
+        emitArithImm32(7, dst, imm32);
     }
 
     // The 32-bit cmpxchg compares the value at adr with the contents of X86.rax,
@@ -1425,8 +1509,7 @@
     }
 
     public final void orl(Register dst, int imm32) {
-        prefix(dst);
-        emitArith(0x81, 0xC8, dst, imm32);
+        emitArithImm32(1, dst, imm32);
     }
 
     public final void orl(Register dst, AMD64Address src) {
@@ -1436,8 +1519,9 @@
     }
 
     public final void orl(Register dst, Register src) {
-        prefixAndEncode(dst.encoding, src.encoding);
-        emitArith(0x0B, 0xC0, dst, src);
+        int encode = prefixAndEncode(dst.encoding, src.encoding);
+        emitByte(0x0B);
+        emitByte(0xC0 | encode);
     }
 
     public final void popcntl(Register dst, AMD64Address src) {
@@ -1595,13 +1679,11 @@
     }
 
     public final void subl(AMD64Address dst, int imm32) {
-        prefix(dst);
-        emitArithOperand(0x81, 5, dst, imm32);
+        emitArithImm32(5, dst, imm32);
     }
 
     public final void subl(Register dst, int imm32) {
-        prefix(dst);
-        emitArith(0x81, 0xE8, dst, imm32);
+        emitArithImm32(5, dst, imm32);
     }
 
     public final void subl(Register dst, AMD64Address src) {
@@ -1611,8 +1693,9 @@
     }
 
     public final void subl(Register dst, Register src) {
-        prefixAndEncode(dst.encoding, src.encoding);
-        emitArith(0x2B, 0xC0, dst, src);
+        int encode = prefixAndEncode(dst.encoding, src.encoding);
+        emitByte(0x2B);
+        emitByte(0xC0 | encode);
     }
 
     public final void subsd(Register dst, Register src) {
@@ -1678,8 +1761,9 @@
     }
 
     public final void testl(Register dst, Register src) {
-        prefixAndEncode(dst.encoding, src.encoding);
-        emitArith(0x85, 0xC0, dst, src);
+        int encode = prefixAndEncode(dst.encoding, src.encoding);
+        emitByte(0x85);
+        emitByte(0xC0 | encode);
     }
 
     public final void testl(Register dst, AMD64Address src) {
@@ -1720,8 +1804,7 @@
     }
 
     public final void xorl(Register dst, int imm32) {
-        prefix(dst);
-        emitArith(0x81, 0xF0, dst, imm32);
+        emitArithImm32(6, dst, imm32);
     }
 
     public final void xorl(Register dst, AMD64Address src) {
@@ -1731,8 +1814,9 @@
     }
 
     public final void xorl(Register dst, Register src) {
-        prefixAndEncode(dst.encoding, src.encoding);
-        emitArith(0x33, 0xC0, dst, src);
+        int encode = prefixAndEncode(dst.encoding, src.encoding);
+        emitByte(0x33);
+        emitByte(0xC0 | encode);
     }
 
     public final void andpd(Register dst, Register src) {
@@ -1880,7 +1964,7 @@
     /**
      * Creates prefix and the encoding of the lower 6 bits of the ModRM-Byte. It emits an operand
      * prefix. If the given operands exceed 3 bits, the 4th bit is encoded in the prefix.
-     * 
+     *
      * @param regEncoding the encoding of the register part of the ModRM-Byte
      * @param rmEncoding the encoding of the r/m part of the ModRM-Byte
      * @return the lower 6 bits of the ModRM-Byte that should be emitted
@@ -1907,12 +1991,6 @@
         return regEnc << 3 | rmEnc;
     }
 
-    private void prefix(Register reg) {
-        if (reg.encoding >= 8) {
-            emitByte(Prefix.REXB);
-        }
-    }
-
     private static boolean needsRex(Register reg) {
         return reg.encoding >= MinEncodingNeedsRex;
     }
@@ -2016,8 +2094,7 @@
     }
 
     public final void addq(Register dst, int imm32) {
-        prefixqAndEncode(dst.encoding);
-        emitArith(0x81, 0xC0, dst, imm32);
+        emitArithImm32q(0, dst, imm32);
     }
 
     public final void addq(Register dst, AMD64Address src) {
@@ -2027,13 +2104,13 @@
     }
 
     public final void addq(Register dst, Register src) {
-        prefixqAndEncode(dst.encoding, src.encoding);
-        emitArith(0x03, 0xC0, dst, src);
+        int encode = prefixqAndEncode(dst.encoding, src.encoding);
+        emitByte(0x03);
+        emitByte(0xC0 | encode);
     }
 
     public final void andq(Register dst, int imm32) {
-        prefixqAndEncode(dst.encoding);
-        emitArith(0x81, 0xE0, dst, imm32);
+        emitArithImm32q(4, dst, imm32);
     }
 
     public final void andq(Register dst, AMD64Address src) {
@@ -2043,8 +2120,9 @@
     }
 
     public final void andq(Register dst, Register src) {
-        prefixqAndEncode(dst.encoding, src.encoding);
-        emitArith(0x23, 0xC0, dst, src);
+        int encode = prefixqAndEncode(dst.encoding, src.encoding);
+        emitByte(0x23);
+        emitByte(0xC0 | encode);
     }
 
     public final void bswapq(Register reg) {
@@ -2080,13 +2158,13 @@
     }
 
     public final void cmpq(Register dst, int imm32) {
-        prefixqAndEncode(dst.encoding);
-        emitArith(0x81, 0xF8, dst, imm32);
+        emitArithImm32q(7, dst, imm32);
     }
 
     public final void cmpq(Register dst, Register src) {
-        prefixqAndEncode(dst.encoding, src.encoding);
-        emitArith(0x3B, 0xC0, dst, src);
+        int encode = prefixqAndEncode(dst.encoding, src.encoding);
+        emitByte(0x3B);
+        emitByte(0xC0 | encode);
     }
 
     public final void cmpq(Register dst, AMD64Address src) {
@@ -2307,8 +2385,7 @@
     }
 
     public final void orq(Register dst, int imm32) {
-        prefixqAndEncode(dst.encoding);
-        emitArith(0x81, 0xC8, dst, imm32);
+        emitArithImm32q(1, dst, imm32);
     }
 
     public final void orq(Register dst, AMD64Address src) {
@@ -2318,8 +2395,9 @@
     }
 
     public final void orq(Register dst, Register src) {
-        prefixqAndEncode(dst.encoding, src.encoding);
-        emitArith(0x0B, 0xC0, dst, src);
+        int encode = prefixqAndEncode(dst.encoding, src.encoding);
+        emitByte(0x0B);
+        emitByte(0xC0 | encode);
     }
 
     public final void sarq(Register dst, int imm8) {
@@ -2383,8 +2461,7 @@
     }
 
     private void subq(Register dst, int imm32, boolean force32Imm) {
-        prefixqAndEncode(dst.encoding);
-        emitArith(0x81, 0xE8, dst, imm32, force32Imm);
+        emitArithImm32q(5, dst, imm32, force32Imm);
     }
 
     public final void subq(Register dst, AMD64Address src) {
@@ -2394,8 +2471,9 @@
     }
 
     public final void subq(Register dst, Register src) {
-        prefixqAndEncode(dst.encoding, src.encoding);
-        emitArith(0x2B, 0xC0, dst, src);
+        int encode = prefixqAndEncode(dst.encoding, src.encoding);
+        emitByte(0x2B);
+        emitByte(0xC0 | encode);
     }
 
     public final void testq(Register dst, int imm32) {
@@ -2415,8 +2493,9 @@
     }
 
     public final void testq(Register dst, Register src) {
-        prefixqAndEncode(dst.encoding, src.encoding);
-        emitArith(0x85, 0xC0, dst, src);
+        int encode = prefixqAndEncode(dst.encoding, src.encoding);
+        emitByte(0x85);
+        emitByte(0xC0 | encode);
     }
 
     public final void testq(Register dst, AMD64Address src) {
@@ -2433,13 +2512,13 @@
     }
 
     public final void xorq(Register dst, int imm32) {
-        prefixqAndEncode(dst.encoding);
-        emitArith(0x81, 0xF0, dst, imm32);
+        emitArithImm32q(6, dst, imm32);
     }
 
     public final void xorq(Register dst, Register src) {
-        prefixqAndEncode(dst.encoding, src.encoding);
-        emitArith(0x33, 0xC0, dst, src);
+        int encode = prefixqAndEncode(dst.encoding, src.encoding);
+        emitByte(0x33);
+        emitByte(0xC0 | encode);
     }
 
     public final void xorq(Register dst, AMD64Address src) {
--- a/graal/com.oracle.graal.baseline/src/com/oracle/graal/baseline/BaselineBytecodeParser.java	Sat Apr 05 03:18:48 2014 +0200
+++ b/graal/com.oracle.graal.baseline/src/com/oracle/graal/baseline/BaselineBytecodeParser.java	Sat Apr 05 03:19:27 2014 +0200
@@ -354,6 +354,12 @@
     }
 
     @Override
+    protected void genGoto() {
+        assert currentBlock.numNormalSuccessors() == 1;
+        gen.emitJump(LabelRef.forSuccessor(lirGenRes.getLIR(), currentBlock, 0));
+    }
+
+    @Override
     protected Value genObjectEquals(Value x, Value y) {
         // TODO Auto-generated method stub
         throw GraalInternalError.unimplemented("Auto-generated method stub");
@@ -371,7 +377,7 @@
         BciBlock trueBlock = currentBlock.getSuccessors().get(0);
         BciBlock falseBlock = currentBlock.getSuccessors().get(1);
         if (trueBlock == falseBlock) {
-            appendGoto(createTarget(trueBlock, frameState));
+            gen.emitJump(LabelRef.forSuccessor(lirGenRes.getLIR(), currentBlock, 0));
             return;
         }
 
@@ -390,21 +396,10 @@
             }
         }
 
-        // the mirroring and negation operations get the condition into canonical form
-        boolean mirror = cond.canonicalMirror();
-        boolean negate = cond.canonicalNegate();
-
-        Value a = mirror ? y : x;
-        Value b = mirror ? x : y;
+        LabelRef trueDestination = LabelRef.forSuccessor(lirGenRes.getLIR(), currentBlock, 0);
+        LabelRef falseDestination = LabelRef.forSuccessor(lirGenRes.getLIR(), currentBlock, 1);
 
-        LabelRef trueDestination = LabelRef.forSuccessor(lirGenRes.getLIR(), trueBlock, 0);
-        LabelRef falseDestination = LabelRef.forSuccessor(lirGenRes.getLIR(), falseBlock, 1);
-
-        if (negate) {
-            gen.emitCompareBranch(a, b, cond, false, falseDestination, trueDestination, 1 - probability);
-        } else {
-            gen.emitCompareBranch(a, b, cond, false, trueDestination, falseDestination, probability);
-        }
+        gen.emitCompareBranch(x.getKind(), x, y, cond, false, trueDestination, falseDestination, probability);
     }
 
     @Override
@@ -582,12 +577,6 @@
     }
 
     @Override
-    protected Value createTarget(BciBlock trueBlock, AbstractFrameStateBuilder<Value> state) {
-        // TODO Auto-generated method stub
-        throw GraalInternalError.unimplemented("Auto-generated method stub");
-    }
-
-    @Override
     protected Value createBlockTarget(double probability, BciBlock bciBlock, AbstractFrameStateBuilder<Value> stateAfter) {
         // TODO Auto-generated method stub
         throw GraalInternalError.unimplemented("Auto-generated method stub");
@@ -595,6 +584,7 @@
 
     @Override
     protected void processBlock(BciBlock block) {
+        currentBlock = block;
         iterateBytecodesForBlock(block);
     }
 
@@ -630,17 +620,19 @@
 
             processBytecode(bci, opcode);
 
+            if (gen.hasBlockEnd(currentBlock)) {
+                break;
+            }
+
             stream.next();
             bci = stream.currentBCI();
 
             if (bci < endBCI) {
                 if (bci > block.endBci) {
-                    if (block.numNormalSuccessors() == 1) {
-                        assert !block.getSuccessor(0).isExceptionEntry;
-                        // we fell through to the next block, add a goto and break
-                        LabelRef label = LabelRef.forSuccessor(lirGenRes.getLIR(), block.getSuccessor(0), 0);
-                        gen.emitJump(label);
-                    }
+                    assert block.numNormalSuccessors() == 1;
+                    assert !block.getSuccessor(0).isExceptionEntry;
+                    // we fell through to the next block, add a goto and break
+                    genGoto();
                     break;
                 }
             }
--- a/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64LIRGenerator.java	Sat Apr 05 03:18:48 2014 +0200
+++ b/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64LIRGenerator.java	Sat Apr 05 03:19:27 2014 +0200
@@ -246,8 +246,8 @@
     }
 
     @Override
-    public void emitCompareBranch(Value left, Value right, Condition cond, boolean unorderedIsTrue, LabelRef trueLabel, LabelRef falseLabel, double trueLabelProbability) {
-        boolean mirrored = emitCompare(left, right);
+    public void emitCompareBranch(PlatformKind cmpKind, Value left, Value right, Condition cond, boolean unorderedIsTrue, LabelRef trueLabel, LabelRef falseLabel, double trueLabelProbability) {
+        boolean mirrored = emitCompare(cmpKind, left, right);
         Condition finalCondition = mirrored ? cond.mirror() : cond;
         switch (left.getKind().getStackKind()) {
             case Int:
@@ -276,8 +276,8 @@
     }
 
     @Override
-    public Variable emitConditionalMove(Value left, Value right, Condition cond, boolean unorderedIsTrue, Value trueValue, Value falseValue) {
-        boolean mirrored = emitCompare(left, right);
+    public Variable emitConditionalMove(PlatformKind cmpKind, Value left, Value right, Condition cond, boolean unorderedIsTrue, Value trueValue, Value falseValue) {
+        boolean mirrored = emitCompare(cmpKind, left, right);
         Condition finalCondition = mirrored ? cond.mirror() : cond;
 
         Variable result = newVariable(trueValue.getKind());
@@ -314,8 +314,16 @@
         }
     }
 
-    protected void emitCompareOp(Variable left, Value right) {
-        switch (left.getKind().getStackKind()) {
+    protected void emitCompareOp(PlatformKind cmpKind, Variable left, Value right) {
+        switch ((Kind) cmpKind) {
+            case Byte:
+            case Boolean:
+                append(new CompareOp(BCMP, left, right));
+                break;
+            case Short:
+            case Char:
+                append(new CompareOp(SCMP, left, right));
+                break;
             case Int:
                 append(new CompareOp(ICMP, left, right));
                 break;
@@ -337,8 +345,16 @@
     }
 
     protected void emitCompareMemoryConOp(Kind kind, AMD64AddressValue address, Value value, LIRFrameState state) {
-        assert kind == value.getKind();
+        assert kind.getStackKind() == value.getKind().getStackKind();
         switch (kind) {
+            case Byte:
+            case Boolean:
+                append(new CompareMemoryOp(BCMP, kind, address, value, state));
+                break;
+            case Short:
+            case Char:
+                append(new CompareMemoryOp(SCMP, kind, address, value, state));
+                break;
             case Int:
                 append(new CompareMemoryOp(ICMP, kind, address, value, state));
                 break;
@@ -353,6 +369,14 @@
     protected void emitCompareRegMemoryOp(Kind kind, Value value, AMD64AddressValue address, LIRFrameState state) {
         AMD64Compare opcode = null;
         switch (kind) {
+            case Byte:
+            case Boolean:
+                opcode = BCMP;
+                break;
+            case Short:
+            case Char:
+                opcode = SCMP;
+                break;
             case Int:
                 opcode = ICMP;
                 break;
@@ -382,7 +406,7 @@
      * @param b the right operand of the comparison
      * @return true if the left and right operands were switched, false otherwise
      */
-    private boolean emitCompare(Value a, Value b) {
+    private boolean emitCompare(PlatformKind cmpKind, Value a, Value b) {
         Variable left;
         Value right;
         boolean mirrored;
@@ -395,7 +419,7 @@
             right = loadNonConst(b);
             mirrored = false;
         }
-        emitCompareOp(left, right);
+        emitCompareOp(cmpKind, left, right);
         return mirrored;
     }
 
--- a/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64MemoryPeephole.java	Sat Apr 05 03:18:48 2014 +0200
+++ b/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64MemoryPeephole.java	Sat Apr 05 03:19:27 2014 +0200
@@ -77,7 +77,7 @@
     }
 
     protected AMD64AddressValue makeAddress(Access access) {
-        return (AMD64AddressValue) access.nullCheckLocation().generateAddress(gen, gen.operand(access.object()));
+        return (AMD64AddressValue) access.accessLocation().generateAddress(gen, gen.operand(access.object()));
     }
 
     protected Value emitBinaryMemory(AMD64Arithmetic op, boolean commutative, ValueNode x, ValueNode y, Access access) {
@@ -90,7 +90,7 @@
             }
         }
         ensureEvaluated(other);
-        return gen.getLIRGenerator().emitBinaryMemory(op, access.nullCheckLocation().getValueKind(), gen.getLIRGeneratorTool().asAllocatable(gen.operand(other)), makeAddress(access), getState(access));
+        return gen.getLIRGenerator().emitBinaryMemory(op, access.accessLocation().getValueKind(), gen.getLIRGeneratorTool().asAllocatable(gen.operand(other)), makeAddress(access), getState(access));
     }
 
     /**
@@ -129,7 +129,7 @@
 
     @Override
     public Value emitAddMemory(ValueNode x, ValueNode y, Access access) {
-        switch (access.nullCheckLocation().getValueKind()) {
+        switch (access.accessLocation().getValueKind()) {
             case Int:
                 return emitBinaryMemory(IADD, true, x, y, access);
             case Long:
@@ -145,7 +145,7 @@
 
     @Override
     public Value emitSubMemory(ValueNode x, ValueNode y, Access access) {
-        switch (access.nullCheckLocation().getValueKind()) {
+        switch (access.accessLocation().getValueKind()) {
             case Int:
                 return emitBinaryMemory(ISUB, false, x, y, access);
             case Long:
@@ -161,7 +161,7 @@
 
     @Override
     public Value emitMulMemory(ValueNode x, ValueNode y, Access access) {
-        switch (access.nullCheckLocation().getValueKind()) {
+        switch (access.accessLocation().getValueKind()) {
             case Int:
                 return emitBinaryMemory(IMUL, true, x, y, access);
             case Long:
@@ -187,7 +187,7 @@
 
     @Override
     public Value emitAndMemory(ValueNode x, ValueNode y, Access access) {
-        Kind kind = access.nullCheckLocation().getValueKind();
+        Kind kind = access.accessLocation().getValueKind();
         switch (kind) {
             case Int:
                 return emitBinaryMemory(IAND, true, x, y, access);
@@ -224,7 +224,7 @@
 
     @Override
     public Value emitOrMemory(ValueNode x, ValueNode y, Access access) {
-        switch (access.nullCheckLocation().getValueKind()) {
+        switch (access.accessLocation().getValueKind()) {
             case Int:
                 return emitBinaryMemory(IOR, true, x, y, access);
             case Long:
@@ -236,7 +236,7 @@
 
     @Override
     public Value emitXorMemory(ValueNode x, ValueNode y, Access access) {
-        switch (access.nullCheckLocation().getValueKind()) {
+        switch (access.accessLocation().getValueKind()) {
             case Int:
                 return emitBinaryMemory(IXOR, true, x, y, access);
             case Long:
@@ -249,7 +249,7 @@
     @Override
     public Value emitReinterpretMemory(Stamp stamp, Access access) {
         PlatformKind to = gen.getLIRGenerator().getPlatformKind(stamp);
-        Kind from = access.nullCheckLocation().getValueKind();
+        Kind from = access.accessLocation().getValueKind();
         assert to != from : "should have been eliminated";
 
         /*
@@ -355,7 +355,7 @@
     @Override
     public Value emitZeroExtendMemory(int inputBits, int resultBits, Access access) {
         assert resultBits == 32 || resultBits == 64;
-        Kind memoryKind = access.nullCheckLocation().getValueKind();
+        Kind memoryKind = access.accessLocation().getValueKind();
         if (memoryKind.getBitCount() != inputBits && !memoryKind.isUnsigned()) {
             // The memory being read from is signed and smaller than the result size so
             // this is a sign extension to inputBits followed by a zero extension to resultBits
@@ -399,7 +399,7 @@
 
     private boolean emitIntegerTestBranchMemory(ValueNode left, ValueNode right, Access access, LabelRef trueLabel, LabelRef falseLabel, double trueLabelProbability) {
         ValueNode other = selectOtherInput(left, right, access);
-        Kind kind = access.nullCheckLocation().getValueKind();
+        Kind kind = access.accessLocation().getValueKind();
         if (other.isConstant()) {
             if (kind != kind.getStackKind()) {
                 return false;
@@ -439,7 +439,7 @@
     protected boolean emitCompareBranchMemory(ValueNode left, ValueNode right, Access access, Condition cond, boolean unorderedIsTrue, LabelRef trueLabel, LabelRef falseLabel,
                     double trueLabelProbability) {
         ValueNode other = selectOtherInput(left, right, access);
-        Kind kind = access.nullCheckLocation().getValueKind();
+        Kind kind = access.accessLocation().getValueKind();
         boolean mirrored = false;
 
         if (other.isConstant()) {
@@ -458,19 +458,11 @@
                     return false;
                 }
             }
-            if (kind != kind.getStackKind()) {
-                Debug.log("Skipping constant compares for stack kinds");
-                return false;
-            }
             ensureEvaluated(other);
             gen.getLIRGenerator().emitCompareMemoryConOp(kind, makeAddress(access), constant, getState(access));
             mirrored = uncast(right) == access;
         } else {
-            if (kind != kind.getStackKind()) {
-                // Register compares only work for stack kinds
-                Debug.log("Register compares only work for stack kinds");
-                return false;
-            } else if (kind == Kind.Object) {
+            if (kind == Kind.Object) {
                 // Can't compare against objects since they require encode/decode
                 Debug.log("Skipping compares for Object kinds");
                 return false;
--- a/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64NodeLIRBuilder.java	Sat Apr 05 03:18:48 2014 +0200
+++ b/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64NodeLIRBuilder.java	Sat Apr 05 03:19:27 2014 +0200
@@ -72,7 +72,7 @@
                 FixedWithNextNode fixedWithNextNode = (FixedWithNextNode) node;
                 if (((fixedWithNextNode instanceof IntegerDivNode) || (fixedWithNextNode instanceof IntegerRemNode)) && fixedWithNextNode.getClass() != divRem.getClass()) {
                     FixedBinaryNode otherDivRem = (FixedBinaryNode) fixedWithNextNode;
-                    if (otherDivRem.x() == divRem.x() && otherDivRem.y() == divRem.y() && operand(otherDivRem) == null) {
+                    if (otherDivRem.x() == divRem.x() && otherDivRem.y() == divRem.y() && !hasOperand(otherDivRem)) {
                         Value[] results = ((AMD64LIRGenerator) gen).emitIntegerDivRem(operand(divRem.x()), operand(divRem.y()), (DeoptimizingNode) valueNode);
                         if (divRem instanceof IntegerDivNode) {
                             setResult(divRem, results[0]);
--- a/graal/com.oracle.graal.compiler.hsail.test.infra/src/com/oracle/graal/compiler/hsail/test/infra/GraalKernelTester.java	Sat Apr 05 03:18:48 2014 +0200
+++ b/graal/com.oracle.graal.compiler.hsail.test.infra/src/com/oracle/graal/compiler/hsail/test/infra/GraalKernelTester.java	Sat Apr 05 03:19:27 2014 +0200
@@ -34,6 +34,7 @@
 import java.lang.reflect.*;
 
 import org.junit.*;
+import static org.junit.Assume.*;
 
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
@@ -54,7 +55,7 @@
         super(getHSAILBackend().isDeviceInitialized());
     }
 
-    private static HSAILHotSpotBackend getHSAILBackend() {
+    protected static HSAILHotSpotBackend getHSAILBackend() {
         Backend backend = runtime().getBackend(HSAIL.class);
         Assume.assumeTrue(backend instanceof HSAILHotSpotBackend);
         return (HSAILHotSpotBackend) backend;
@@ -102,6 +103,13 @@
         return (canGenerateCalls && canExecuteCalls);
     }
 
+    /**
+     * Determines if the runtime has the capabilities required by this test.
+     */
+    protected boolean supportsRequiredCapabilities() {
+        return true;
+    }
+
     @Override
     protected void dispatchKernelOkra(int range, Object... args) {
         HSAILHotSpotBackend backend = getHSAILBackend();
@@ -140,6 +148,7 @@
     @Override
     public void testGeneratedHsail() {
         try (OverrideScope s = getOverrideScope()) {
+            assumeTrue(supportsRequiredCapabilities());
             super.testGeneratedHsail();
         }
     }
--- a/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/BoundsCatchBase.java	Sat Apr 05 03:18:48 2014 +0200
+++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/BoundsCatchBase.java	Sat Apr 05 03:19:27 2014 +0200
@@ -55,6 +55,11 @@
     }
 
     @Override
+    protected boolean supportsRequiredCapabilities() {
+        return getHSAILBackend().getRuntime().getConfig().useHSAILDeoptimization;
+    }
+
+    @Override
     public void runTest() {
         setupArrays();
 
--- a/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/SingleExceptionTestBase.java	Sat Apr 05 03:18:48 2014 +0200
+++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/SingleExceptionTestBase.java	Sat Apr 05 03:19:27 2014 +0200
@@ -26,7 +26,7 @@
 import com.oracle.graal.compiler.hsail.test.infra.GraalKernelTester;
 
 /**
- * 
+ *
  * @author ecaspole
  */
 public abstract class SingleExceptionTestBase extends GraalKernelTester {
@@ -35,6 +35,11 @@
     @Result String exceptionString;
     @Result StackTraceElement firstStackTraceElement;
 
+    @Override
+    protected boolean supportsRequiredCapabilities() {
+        return getHSAILBackend().getRuntime().getConfig().useHSAILDeoptimization;
+    }
+
     void recordException(Exception e) {
         // for now we just test that the class the of the exception
         // matches for the java and gpu side
--- a/graal/com.oracle.graal.compiler.hsail/src/com/oracle/graal/compiler/hsail/HSAILLIRGenerator.java	Sat Apr 05 03:18:48 2014 +0200
+++ b/graal/com.oracle.graal.compiler.hsail/src/com/oracle/graal/compiler/hsail/HSAILLIRGenerator.java	Sat Apr 05 03:19:27 2014 +0200
@@ -193,7 +193,8 @@
     }
 
     @Override
-    public void emitCompareBranch(Value left, Value right, Condition cond, boolean unorderedIsTrue, LabelRef trueDestination, LabelRef falseDestination, double trueDestinationProbability) {
+    public void emitCompareBranch(PlatformKind cmpKind, Value left, Value right, Condition cond, boolean unorderedIsTrue, LabelRef trueDestination, LabelRef falseDestination,
+                    double trueDestinationProbability) {
         // We don't have to worry about mirroring the condition on HSAIL.
         Condition finalCondition = cond;
         Variable result = newVariable(left.getKind());
@@ -224,7 +225,7 @@
     }
 
     @Override
-    public Variable emitConditionalMove(Value left, Value right, Condition cond, boolean unorderedIsTrue, Value trueValue, Value falseValue) {
+    public Variable emitConditionalMove(PlatformKind cmpKind, Value left, Value right, Condition cond, boolean unorderedIsTrue, Value trueValue, Value falseValue) {
         Condition finalCondition = cond;
         Variable result = newVariable(trueValue.getKind());
         Kind kind = left.getKind().getStackKind();
--- a/graal/com.oracle.graal.compiler.ptx/src/com/oracle/graal/compiler/ptx/PTXLIRGenerator.java	Sat Apr 05 03:18:48 2014 +0200
+++ b/graal/com.oracle.graal.compiler.ptx/src/com/oracle/graal/compiler/ptx/PTXLIRGenerator.java	Sat Apr 05 03:19:27 2014 +0200
@@ -265,7 +265,8 @@
     }
 
     @Override
-    public void emitCompareBranch(Value left, Value right, Condition cond, boolean unorderedIsTrue, LabelRef trueDestination, LabelRef falseDestination, double trueDestinationProbability) {
+    public void emitCompareBranch(PlatformKind cmpKind, Value left, Value right, Condition cond, boolean unorderedIsTrue, LabelRef trueDestination, LabelRef falseDestination,
+                    double trueDestinationProbability) {
         switch (left.getKind().getStackKind()) {
             case Int:
                 append(new CompareOp(ICMP, cond, left, right, nextPredRegNum));
@@ -305,7 +306,7 @@
     }
 
     @Override
-    public Variable emitConditionalMove(Value left, Value right, Condition cond, boolean unorderedIsTrue, Value trueValue, Value falseValue) {
+    public Variable emitConditionalMove(PlatformKind cmpKind, Value left, Value right, Condition cond, boolean unorderedIsTrue, Value trueValue, Value falseValue) {
 
         Condition finalCondition = LIRValueUtil.isVariable(right) ? cond.mirror() : cond;
 
@@ -837,7 +838,7 @@
             // Store result in global memory whose location is loadVar
             emitStoreReturnValue(operand.getKind(), loadVar, operand, null);
         }
-        append(new ReturnOp(operand));
+        emitReturnNoVal();
     }
 
     void emitReturnNoVal() {
--- a/graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCLIRGenerator.java	Sat Apr 05 03:18:48 2014 +0200
+++ b/graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCLIRGenerator.java	Sat Apr 05 03:19:27 2014 +0200
@@ -233,7 +233,8 @@
     }
 
     @Override
-    public void emitCompareBranch(Value left, Value right, Condition cond, boolean unorderedIsTrue, LabelRef trueDestination, LabelRef falseDestination, double trueDestinationProbability) {
+    public void emitCompareBranch(PlatformKind cmpKind, Value left, Value right, Condition cond, boolean unorderedIsTrue, LabelRef trueDestination, LabelRef falseDestination,
+                    double trueDestinationProbability) {
         boolean mirrored = emitCompare(left, right);
         Condition finalCondition = mirrored ? cond.mirror() : cond;
         Kind kind = left.getKind().getStackKind();
@@ -278,7 +279,7 @@
     }
 
     @Override
-    public Variable emitConditionalMove(Value left, Value right, Condition cond, boolean unorderedIsTrue, Value trueValue, Value falseValue) {
+    public Variable emitConditionalMove(PlatformKind cmpKind, Value left, Value right, Condition cond, boolean unorderedIsTrue, Value trueValue, Value falseValue) {
         boolean mirrored = emitCompare(left, right);
         Condition finalCondition = mirrored ? cond.mirror() : cond;
 
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/PhiCreationTests.java	Sat Apr 05 03:18:48 2014 +0200
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/PhiCreationTests.java	Sat Apr 05 03:19:27 2014 +0200
@@ -41,7 +41,7 @@
     @Test
     public void test1() {
         StructuredGraph graph = parse("test1Snippet");
-        Assert.assertFalse(graph.getNodes().filter(PhiNode.class).iterator().hasNext());
+        Assert.assertFalse(graph.getNodes().filter(ValuePhiNode.class).iterator().hasNext());
     }
 
     public static int test1Snippet(int a) {
@@ -54,7 +54,7 @@
     @Test
     public void test2() {
         StructuredGraph graph = parse("test2Snippet");
-        Assert.assertFalse(graph.getNodes().filter(PhiNode.class).iterator().hasNext());
+        Assert.assertFalse(graph.getNodes().filter(ValuePhiNode.class).iterator().hasNext());
     }
 
     public static int test2Snippet(int a) {
@@ -68,7 +68,7 @@
     public void test3() {
         StructuredGraph graph = parse("test3Snippet");
         Debug.dump(graph, "Graph");
-        Assert.assertFalse(graph.getNodes().filter(PhiNode.class).iterator().hasNext());
+        Assert.assertFalse(graph.getNodes().filter(ValuePhiNode.class).iterator().hasNext());
     }
 
     public static int test3Snippet(int a) {
@@ -84,7 +84,7 @@
     public void test4() {
         StructuredGraph graph = parse("test4Snippet");
         Debug.dump(graph, "Graph");
-        Assert.assertFalse(graph.getNodes().filter(PhiNode.class).iterator().hasNext());
+        Assert.assertFalse(graph.getNodes().filter(ValuePhiNode.class).iterator().hasNext());
     }
 
     public static int test4Snippet(int a) {
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/EAMergingTest.java	Sat Apr 05 03:18:48 2014 +0200
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/EAMergingTest.java	Sat Apr 05 03:19:27 2014 +0200
@@ -34,7 +34,7 @@
     public void testSimpleMerge() {
         testEscapeAnalysis("simpleMergeSnippet", null, false);
         assertEquals(1, returnNodes.size());
-        assertTrue(returnNodes.get(0).result() instanceof PhiNode);
+        assertTrue(returnNodes.get(0).result() instanceof ValuePhiNode);
         PhiNode phi = (PhiNode) returnNodes.get(0).result();
         assertTrue(phi.valueAt(0) instanceof ParameterNode);
         assertTrue(phi.valueAt(1) instanceof ParameterNode);
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/PEAReadEliminationTest.java	Sat Apr 05 03:18:48 2014 +0200
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/PEAReadEliminationTest.java	Sat Apr 05 03:19:27 2014 +0200
@@ -164,7 +164,7 @@
         ValueNode result = getReturn("testBadLoopSnippet").result();
         assertEquals(0, graph.getNodes().filter(LoadFieldNode.class).count());
         assertTrue(result instanceof ProxyNode);
-        assertTrue(((ProxyNode) result).value() instanceof PhiNode);
+        assertTrue(((ProxyNode) result).value() instanceof ValuePhiNode);
     }
 
     @SuppressWarnings("all")
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/UnsafeEATest.java	Sat Apr 05 03:18:48 2014 +0200
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/UnsafeEATest.java	Sat Apr 05 03:19:27 2014 +0200
@@ -87,7 +87,7 @@
     public void testMergedDouble() {
         testEscapeAnalysis("testMergedDoubleSnippet", null, false);
         Assert.assertEquals(1, returnNodes.size());
-        Assert.assertTrue(returnNodes.get(0).result() instanceof PhiNode);
+        Assert.assertTrue(returnNodes.get(0).result() instanceof ValuePhiNode);
         PhiNode phi = (PhiNode) returnNodes.get(0).result();
         Assert.assertTrue(phi.valueAt(0) instanceof LoadFieldNode);
         Assert.assertTrue(phi.valueAt(1) instanceof LoadFieldNode);
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/LinearScan.java	Sat Apr 05 03:18:48 2014 +0200
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/LinearScan.java	Sat Apr 05 03:19:27 2014 +0200
@@ -887,7 +887,6 @@
     private static NodeLIRBuilder getNodeLIRGeneratorFromDebugContext() {
         if (Debug.isEnabled()) {
             NodeLIRBuilder lirGen = Debug.contextLookup(NodeLIRBuilder.class);
-            assert lirGen != null;
             return lirGen;
         }
         return null;
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/LIRGenerator.java	Sat Apr 05 03:18:48 2014 +0200
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/LIRGenerator.java	Sat Apr 05 03:19:27 2014 +0200
@@ -315,11 +315,6 @@
 
     public void append(LIRInstruction op) {
         if (printIRWithLIR && !TTY.isSuppressed()) {
-            // if (currentInstruction != null && lastInstructionPrinted != currentInstruction) {
-            // lastInstructionPrinted = currentInstruction;
-            // InstructionPrinter ip = new InstructionPrinter(TTY.out());
-            // ip.printInstructionListing(currentInstruction);
-            // }
             TTY.println(op.toStringWithIdPrefix());
             TTY.println();
         }
@@ -327,6 +322,14 @@
         res.getLIR().getLIRforBlock(currentBlock).add(op);
     }
 
+    public boolean hasBlockEnd(AbstractBlock<?> block) {
+        List<LIRInstruction> ops = getResult().getLIR().getLIRforBlock(block);
+        if (ops.size() == 0) {
+            return false;
+        }
+        return ops.get(ops.size() - 1) instanceof BlockEndOp;
+    }
+
     public final void doBlockStart(AbstractBlock<?> block) {
         if (printIRWithLIR) {
             TTY.print(block.toString());
@@ -364,13 +367,14 @@
 
     public abstract void emitJump(LabelRef label);
 
-    public abstract void emitCompareBranch(Value left, Value right, Condition cond, boolean unorderedIsTrue, LabelRef trueDestination, LabelRef falseDestination, double trueDestinationProbability);
+    public abstract void emitCompareBranch(PlatformKind cmpKind, Value left, Value right, Condition cond, boolean unorderedIsTrue, LabelRef trueDestination, LabelRef falseDestination,
+                    double trueDestinationProbability);
 
     public abstract void emitOverflowCheckBranch(LabelRef overflow, LabelRef noOverflow, double overflowProbability);
 
     public abstract void emitIntegerTestBranch(Value left, Value right, LabelRef trueDestination, LabelRef falseDestination, double trueSuccessorProbability);
 
-    public abstract Variable emitConditionalMove(Value leftVal, Value right, Condition cond, boolean unorderedIsTrue, Value trueValue, Value falseValue);
+    public abstract Variable emitConditionalMove(PlatformKind cmpKind, Value leftVal, Value right, Condition cond, boolean unorderedIsTrue, Value trueValue, Value falseValue);
 
     public abstract Variable emitIntegerTestMove(Value leftVal, Value right, Value trueValue, Value falseValue);
 
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/NodeLIRBuilder.java	Sat Apr 05 03:18:48 2014 +0200
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/NodeLIRBuilder.java	Sat Apr 05 03:19:27 2014 +0200
@@ -37,10 +37,8 @@
 import com.oracle.graal.debug.Debug.Scope;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.lir.*;
-import com.oracle.graal.lir.StandardOp.BlockEndOp;
 import com.oracle.graal.lir.StandardOp.JumpOp;
 import com.oracle.graal.nodes.*;
-import com.oracle.graal.nodes.PhiNode.PhiType;
 import com.oracle.graal.nodes.calc.*;
 import com.oracle.graal.nodes.cfg.*;
 import com.oracle.graal.nodes.extended.*;
@@ -227,7 +225,7 @@
             }
         }
 
-        if (!hasBlockEnd(block)) {
+        if (!gen.hasBlockEnd(block)) {
             NodeClassIterable successors = block.getEndNode().successors();
             assert successors.count() == block.getSuccessorCount();
             if (block.getSuccessorCount() != 1) {
@@ -392,14 +390,6 @@
 
     protected abstract boolean peephole(ValueNode valueNode);
 
-    private boolean hasBlockEnd(Block block) {
-        List<LIRInstruction> ops = gen.getResult().getLIR().getLIRforBlock(block);
-        if (ops.size() == 0) {
-            return false;
-        }
-        return ops.get(ops.size() - 1) instanceof BlockEndOp;
-    }
-
     private void doRoot(ValueNode instr) {
         if (gen.traceLevel >= 2) {
             TTY.println("Emitting LIR for instruction " + instr);
@@ -473,9 +463,9 @@
         }
         PhiResolver resolver = new PhiResolver(gen);
         for (PhiNode phi : merge.phis()) {
-            if (phi.type() == PhiType.Value) {
+            if (phi instanceof ValuePhiNode) {
                 ValueNode curVal = phi.valueAt(pred);
-                resolver.move(operandForPhi(phi), operand(curVal));
+                resolver.move(operandForPhi((ValuePhiNode) phi), operand(curVal));
             }
         }
         resolver.dispose();
@@ -487,8 +477,7 @@
         return gen.getPlatformKind(phi.stamp());
     }
 
-    private Value operandForPhi(PhiNode phi) {
-        assert phi.type() == PhiType.Value : "wrong phi type: " + phi;
+    private Value operandForPhi(ValuePhiNode phi) {
         Value result = getOperand(phi);
         if (result == null) {
             // allocate a variable for this phi
@@ -520,11 +509,13 @@
     }
 
     private void emitNullCheckBranch(IsNullNode node, LabelRef trueSuccessor, LabelRef falseSuccessor, double trueSuccessorProbability) {
-        gen.emitCompareBranch(operand(node.object()), Constant.NULL_OBJECT, Condition.EQ, false, trueSuccessor, falseSuccessor, trueSuccessorProbability);
+        PlatformKind kind = gen.getPlatformKind(node.object().stamp());
+        gen.emitCompareBranch(kind, operand(node.object()), Constant.NULL_OBJECT, Condition.EQ, false, trueSuccessor, falseSuccessor, trueSuccessorProbability);
     }
 
     public void emitCompareBranch(CompareNode compare, LabelRef trueSuccessor, LabelRef falseSuccessor, double trueSuccessorProbability) {
-        gen.emitCompareBranch(operand(compare.x()), operand(compare.y()), compare.condition(), compare.unorderedIsTrue(), trueSuccessor, falseSuccessor, trueSuccessorProbability);
+        PlatformKind kind = gen.getPlatformKind(compare.x().stamp());
+        gen.emitCompareBranch(kind, operand(compare.x()), operand(compare.y()), compare.condition(), compare.unorderedIsTrue(), trueSuccessor, falseSuccessor, trueSuccessorProbability);
     }
 
     public void emitIntegerTestBranch(IntegerTestNode test, LabelRef trueSuccessor, LabelRef falseSuccessor, double trueSuccessorProbability) {
@@ -546,10 +537,12 @@
     public Variable emitConditional(LogicNode node, Value trueValue, Value falseValue) {
         if (node instanceof IsNullNode) {
             IsNullNode isNullNode = (IsNullNode) node;
-            return gen.emitConditionalMove(operand(isNullNode.object()), Constant.NULL_OBJECT, Condition.EQ, false, trueValue, falseValue);
+            PlatformKind kind = gen.getPlatformKind(isNullNode.object().stamp());
+            return gen.emitConditionalMove(kind, operand(isNullNode.object()), Constant.NULL_OBJECT, Condition.EQ, false, trueValue, falseValue);
         } else if (node instanceof CompareNode) {
             CompareNode compare = (CompareNode) node;
-            return gen.emitConditionalMove(operand(compare.x()), operand(compare.y()), compare.condition(), compare.unorderedIsTrue(), trueValue, falseValue);
+            PlatformKind kind = gen.getPlatformKind(compare.x().stamp());
+            return gen.emitConditionalMove(kind, operand(compare.x()), operand(compare.y()), compare.condition(), compare.unorderedIsTrue(), trueValue, falseValue);
         } else if (node instanceof LogicConstantNode) {
             return gen.emitMove(((LogicConstantNode) node).getValue() ? trueValue : falseValue);
         } else if (node instanceof IntegerTestNode) {
@@ -635,7 +628,8 @@
             if (keyCount == 1) {
                 assert defaultTarget != null;
                 double probability = x.probability(x.keySuccessor(0));
-                gen.emitCompareBranch(gen.load(operand(x.value())), x.keyAt(0), Condition.EQ, false, getLIRBlock(x.keySuccessor(0)), defaultTarget, probability);
+                PlatformKind kind = gen.getPlatformKind(x.value().stamp());
+                gen.emitCompareBranch(kind, gen.load(operand(x.value())), x.keyAt(0), Condition.EQ, false, getLIRBlock(x.keySuccessor(0)), defaultTarget, probability);
             } else {
                 LabelRef[] keyTargets = new LabelRef[keyCount];
                 Constant[] keyConstants = new Constant[keyCount];
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/PhiResolver.java	Sat Apr 05 03:18:48 2014 +0200
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/PhiResolver.java	Sat Apr 05 03:19:27 2014 +0200
@@ -32,7 +32,7 @@
 import com.oracle.graal.nodes.*;
 
 /**
- * Converts {@link PhiNode} instructions into moves.
+ * Converts {@link ValuePhiNode} instructions into moves.
  * 
  * Resolves cycles:
  * 
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotMemoryPeephole.java	Sat Apr 05 03:18:48 2014 +0200
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotMemoryPeephole.java	Sat Apr 05 03:19:27 2014 +0200
@@ -86,7 +86,7 @@
                     double trueLabelProbability) {
         if (HotSpotGraalRuntime.runtime().getConfig().useCompressedOops) {
             ValueNode other = selectOtherInput(left, right, access);
-            Kind kind = access.nullCheckLocation().getValueKind();
+            Kind kind = access.accessLocation().getValueKind();
 
             if (other.isConstant() && kind == Kind.Object && access.isCompressible()) {
                 ensureEvaluated(other);
--- a/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotBackend.java	Sat Apr 05 03:18:48 2014 +0200
+++ b/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotBackend.java	Sat Apr 05 03:19:27 2014 +0200
@@ -431,7 +431,7 @@
     public void emitCode(CompilationResultBuilder crb, LIR lir, ResolvedJavaMethod method) {
         assert method != null : lir + " is not associated with a method";
 
-        boolean usesDeoptInfo = true;     // TODO: make this conditional on something?
+        boolean useHSAILDeoptimization = getRuntime().getConfig().useHSAILDeoptimization;
 
         // Emit the prologue.
         HSAILAssembler asm = (HSAILAssembler) crb.asm;
@@ -513,13 +513,13 @@
         for (int i = 0; i < totalParamCount; i++) {
             String str = "align 8 kernarg_" + paramHsailSizes[i] + " " + paramNames[i];
 
-            if (usesDeoptInfo || (i != totalParamCount - 1)) {
+            if (useHSAILDeoptimization || (i != totalParamCount - 1)) {
                 str += ",";
             }
             asm.emitString(str);
         }
 
-        if (usesDeoptInfo) {
+        if (useHSAILDeoptimization) {
             // add in the deoptInfo parameter
             asm.emitString("kernarg_u64 " + asm.getDeoptInfoName());
         }
@@ -542,14 +542,10 @@
         String workItemReg = "$s" + Integer.toString(asRegister(cc.getArgument(nonConstantParamCount)).encoding());
         asm.emitString("workitemabsid_u32 " + workItemReg + ", 0;");
 
-        final int offsetToDeoptSaveStates = getRuntime().getConfig().hsailSaveStatesOffset0;
-        final int sizeofKernelDeopt = getRuntime().getConfig().hsailSaveStatesOffset1 - getRuntime().getConfig().hsailSaveStatesOffset0;
         final int offsetToDeopt = getRuntime().getConfig().hsailDeoptOffset;
-        final int offsetToNeverRanArray = getRuntime().getConfig().hsailNeverRanArrayOffset;
-        final int offsetToDeoptNextIndex = getRuntime().getConfig().hsailDeoptNextIndexOffset;
         final String deoptInProgressLabel = "@LHandleDeoptInProgress";
 
-        if (usesDeoptInfo) {
+        if (useHSAILDeoptimization) {
             AllocatableValue scratch64 = HSAIL.d16.asValue(Kind.Object);
             AllocatableValue scratch32 = HSAIL.s34.asValue(Kind.Int);
             HSAILAddress deoptInfoAddr = new HSAILAddressValue(Kind.Int, scratch64, offsetToDeopt).toAddress();
@@ -631,15 +627,19 @@
         asm.emitString(spillsegStringFinal, spillsegDeclarationPosition);
         // Emit the epilogue.
 
-        final int offsetToDeoptimizationWorkItem = getRuntime().getConfig().hsailDeoptimizationWorkItem;
-        final int offsetToDeoptimizationReason = getRuntime().getConfig().hsailDeoptimizationReason;
-        final int offsetToDeoptimizationFrame = getRuntime().getConfig().hsailDeoptimizationFrame;
-        final int offsetToFramePc = getRuntime().getConfig().hsailFramePcOffset;
-        final int offsetToNumSaves = getRuntime().getConfig().hsailFrameNumSRegOffset;
-        final int offsetToSaveArea = getRuntime().getConfig().hsailFrameSaveAreaOffset;
+        // TODO: keep track of whether we need it
+        if (useHSAILDeoptimization) {
+            final int offsetToDeoptSaveStates = getRuntime().getConfig().hsailSaveStatesOffset0;
+            final int sizeofKernelDeopt = getRuntime().getConfig().hsailSaveStatesOffset1 - getRuntime().getConfig().hsailSaveStatesOffset0;
+            final int offsetToNeverRanArray = getRuntime().getConfig().hsailNeverRanArrayOffset;
+            final int offsetToDeoptNextIndex = getRuntime().getConfig().hsailDeoptNextIndexOffset;
+            final int offsetToDeoptimizationWorkItem = getRuntime().getConfig().hsailDeoptimizationWorkItem;
+            final int offsetToDeoptimizationReason = getRuntime().getConfig().hsailDeoptimizationReason;
+            final int offsetToDeoptimizationFrame = getRuntime().getConfig().hsailDeoptimizationFrame;
+            final int offsetToFramePc = getRuntime().getConfig().hsailFramePcOffset;
+            final int offsetToNumSaves = getRuntime().getConfig().hsailFrameNumSRegOffset;
+            final int offsetToSaveArea = getRuntime().getConfig().hsailFrameSaveAreaOffset;
 
-        // TODO: keep track of whether we need it
-        if (usesDeoptInfo) {
             AllocatableValue scratch64 = HSAIL.d16.asValue(Kind.Object);
             AllocatableValue cuSaveAreaPtr = HSAIL.d17.asValue(Kind.Object);
             AllocatableValue waveMathScratch1 = HSAIL.d18.asValue(Kind.Object);
@@ -773,6 +773,11 @@
             // and emit the return
             crb.frameContext.leave(crb);
             asm.exit();
+        } else {
+            // Deoptimization is explicitly off, so emit simple return
+            asm.emitString0(asm.getDeoptLabelName() + ":\n");
+            asm.emitComment("// No deoptimization");
+            asm.emitString("ret;");
         }
 
         asm.emitString0("}; \n");
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConfig.java	Sat Apr 05 03:18:48 2014 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConfig.java	Sat Apr 05 03:19:27 2014 +0200
@@ -611,10 +611,9 @@
             nameOffset = vmStructs.get("Flag::_name").getOffset();
             addrOffset = vmStructs.get("Flag::_addr").getOffset();
 
-            // TODO use the following after we switched to JDK 8
-            assert vmTypes.get("bool").getSize() == Byte.SIZE / Byte.SIZE; // TODO Byte.BYTES;
-            assert vmTypes.get("intx").getSize() == Long.SIZE / Byte.SIZE; // TODO Long.BYTES;
-            assert vmTypes.get("uintx").getSize() == Long.SIZE / Byte.SIZE; // TODO Long.BYTES;
+            assert vmTypes.get("bool").getSize() == Byte.BYTES;
+            assert vmTypes.get("intx").getSize() == Long.BYTES;
+            assert vmTypes.get("uintx").getSize() == Long.BYTES;
         }
 
         public Iterator<Flags.Flag> iterator() {
@@ -1004,6 +1003,8 @@
     @HotSpotVMField(name = "ThreadShadow::_pending_deoptimization", type = "int", get = HotSpotVMField.Type.OFFSET) @Stable public int pendingDeoptimizationOffset;
     @HotSpotVMField(name = "ThreadShadow::_pending_failed_speculation", type = "oop", get = HotSpotVMField.Type.OFFSET) @Stable public int pendingFailedSpeculationOffset;
 
+    @HotSpotVMFlag(name = "UseHSAILDeoptimization") @Stable public boolean useHSAILDeoptimization;
+
     /**
      * Offsets of Hsail deoptimization fields (defined in gpu_hsail.hpp). Used to propagate
      * exceptions from Hsail back to C++ runtime.
@@ -1107,6 +1108,7 @@
     @HotSpotVMConstant(name = "JVM_CONSTANT_MethodHandleInError") @Stable public int jvmConstantMethodHandleInError;
     @HotSpotVMConstant(name = "JVM_CONSTANT_MethodType") @Stable public int jvmConstantMethodType;
     @HotSpotVMConstant(name = "JVM_CONSTANT_MethodTypeInError") @Stable public int jvmConstantMethodTypeInError;
+    @HotSpotVMConstant(name = "JVM_CONSTANT_InvokeDynamic") @Stable public int jvmConstantInvokeDynamic;
 
     @HotSpotVMConstant(name = "HeapWordSize") @Stable public int heapWordSize;
 
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVMImpl.java	Sat Apr 05 03:18:48 2014 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVMImpl.java	Sat Apr 05 03:19:27 2014 +0200
@@ -151,7 +151,7 @@
 
     @Override
     public Object executeCompiledMethod(Object arg1, Object arg2, Object arg3, HotSpotInstalledCode hotspotInstalledCode) throws InvalidInstalledCodeException {
-        return executeCompiledMethodIntrinsic(arg1, arg2, arg3, hotspotInstalledCode);
+        return executeCompiledMethodVarargs(new Object[]{arg1, arg2, arg3}, hotspotInstalledCode);
     }
 
     public synchronized native void notifyCompilationStatistics(int id, HotSpotResolvedJavaMethod method, boolean osr, int processedBytecodes, long time, long timeUnitsPerSecond,
@@ -161,15 +161,6 @@
 
     public native void resetCompilationStatistics();
 
-    /**
-     * Direct call to the given nmethod with three object arguments and an object return value. This
-     * method does not have an implementation on the C++ side, but its entry points (from
-     * interpreter and from compiled code) are directly pointing to a manually generated assembly
-     * stub that does the necessary argument shuffling and a tail call via an indirect jump to the
-     * verified entry point of the given native method.
-     */
-    public static native Object executeCompiledMethodIntrinsic(Object arg1, Object arg2, Object arg3, HotSpotInstalledCode hotspotInstalledCode) throws InvalidInstalledCodeException;
-
     public native long[] collectCounters();
 
     public native boolean isMature(long method);
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotConstantPool.java	Sat Apr 05 03:18:48 2014 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotConstantPool.java	Sat Apr 05 03:19:27 2014 +0200
@@ -61,7 +61,8 @@
         MethodHandle(config().jvmConstantMethodHandle),
         MethodHandleInError(config().jvmConstantMethodHandleInError),
         MethodType(config().jvmConstantMethodType),
-        MethodTypeInError(config().jvmConstantMethodTypeInError);
+        MethodTypeInError(config().jvmConstantMethodTypeInError),
+        InvokeDynamic(config().jvmConstantInvokeDynamic);
         // @formatter:on
 
         private final int value;
@@ -95,7 +96,7 @@
 
     /**
      * Gets the holder for this constant pool as {@link HotSpotResolvedObjectType}.
-     * 
+     *
      * @return holder for this constant pool
      */
     private HotSpotResolvedObjectType getHolder() {
@@ -106,7 +107,7 @@
     /**
      * Converts a raw index from the bytecodes to a constant pool index by adding a
      * {@link HotSpotVMConfig#constantPoolCpCacheIndexTag constant}.
-     * 
+     *
      * @param rawIndex index from the bytecode
      * @param opcode bytecode to convert the index for
      * @return constant pool index
@@ -126,8 +127,39 @@
     }
 
     /**
+     * Decode a constant pool cache index to a constant pool index.
+     *
+     * See {@code ConstantPool::decode_cpcache_index}.
+     *
+     * @param index constant pool cache index
+     * @return decoded index
+     */
+    private static int decodeConstantPoolCacheIndex(int index) {
+        if (isInvokedynamicIndex(index)) {
+            return decodeInvokedynamicIndex(index);
+        } else {
+            return index - runtime().getConfig().constantPoolCpCacheIndexTag;
+        }
+    }
+
+    /**
+     * See {@code ConstantPool::is_invokedynamic_index}.
+     */
+    private static boolean isInvokedynamicIndex(int index) {
+        return index < 0;
+    }
+
+    /**
+     * See {@code ConstantPool::decode_invokedynamic_index}.
+     */
+    private static int decodeInvokedynamicIndex(int i) {
+        assert isInvokedynamicIndex(i) : i;
+        return ~i;
+    }
+
+    /**
      * Gets the constant pool tag at index {@code index}.
-     * 
+     *
      * @param index constant pool index
      * @return constant pool tag
      */
@@ -141,7 +173,7 @@
 
     /**
      * Gets the constant pool entry at index {@code index}.
-     * 
+     *
      * @param index constant pool index
      * @return constant pool entry
      */
@@ -152,7 +184,7 @@
 
     /**
      * Gets the integer constant pool entry at index {@code index}.
-     * 
+     *
      * @param index constant pool index
      * @return integer constant pool entry at index
      */
@@ -163,7 +195,7 @@
 
     /**
      * Gets the long constant pool entry at index {@code index}.
-     * 
+     *
      * @param index constant pool index
      * @return long constant pool entry
      */
@@ -174,7 +206,7 @@
 
     /**
      * Gets the float constant pool entry at index {@code index}.
-     * 
+     *
      * @param index constant pool index
      * @return float constant pool entry
      */
@@ -185,7 +217,7 @@
 
     /**
      * Gets the double constant pool entry at index {@code index}.
-     * 
+     *
      * @param index constant pool index
      * @return float constant pool entry
      */
@@ -196,7 +228,7 @@
 
     /**
      * Gets the {@code JVM_CONSTANT_NameAndType} constant pool entry at index {@code index}.
-     * 
+     *
      * @param index constant pool index
      * @return {@code JVM_CONSTANT_NameAndType} constant pool entry
      */
@@ -208,7 +240,7 @@
     /**
      * Gets the {@code JVM_CONSTANT_NameAndType} reference index constant pool entry at index
      * {@code index}.
-     * 
+     *
      * @param index constant pool index
      * @return {@code JVM_CONSTANT_NameAndType} reference constant pool entry
      */
@@ -219,7 +251,7 @@
     /**
      * Gets the name of a {@code JVM_CONSTANT_NameAndType} constant pool entry at index
      * {@code index}.
-     * 
+     *
      * @param index constant pool index
      * @return name as {@link String}
      */
@@ -232,7 +264,7 @@
     /**
      * Gets the name reference index of a {@code JVM_CONSTANT_NameAndType} constant pool entry at
      * index {@code index}.
-     * 
+     *
      * @param index constant pool index
      * @return name reference index
      */
@@ -245,7 +277,7 @@
     /**
      * Gets the signature of a {@code JVM_CONSTANT_NameAndType} constant pool entry at index
      * {@code index}.
-     * 
+     *
      * @param index constant pool index
      * @return signature as {@link String}
      */
@@ -258,7 +290,7 @@
     /**
      * Gets the signature reference index of a {@code JVM_CONSTANT_NameAndType} constant pool entry
      * at index {@code index}.
-     * 
+     *
      * @param index constant pool index
      * @return signature reference index
      */
@@ -270,7 +302,7 @@
 
     /**
      * Gets the klass reference index constant pool entry at index {@code index}.
-     * 
+     *
      * @param index constant pool index
      * @return klass reference index
      */
@@ -281,7 +313,7 @@
     /**
      * Gets the uncached klass reference index constant pool entry at index {@code index}. See:
      * {@code ConstantPool::uncached_klass_ref_index_at}.
-     * 
+     *
      * @param index constant pool index
      * @return klass reference index
      */
@@ -294,7 +326,7 @@
 
     /**
      * Asserts that the constant pool index {@code index} is in the bounds of the constant pool.
-     * 
+     *
      * @param index constant pool index
      */
     private void assertBounds(int index) {
@@ -303,7 +335,7 @@
 
     /**
      * Asserts that the constant pool tag at index {@code index} is equal to {@code tag}.
-     * 
+     *
      * @param index constant pool index
      * @param tag expected tag
      */
@@ -371,7 +403,7 @@
     /**
      * Gets a {@link JavaType} corresponding a given metaspace Klass or a metaspace Symbol depending
      * on the {@link HotSpotVMConfig#compilerToVMKlassTag tag}.
-     * 
+     *
      * @param metaspacePointer either a metaspace Klass or a metaspace Symbol
      */
     private static JavaType getJavaType(final long metaspacePointer) {
@@ -462,6 +494,11 @@
             case Bytecodes.LDC2_W:
                 index = cpi;
                 break;
+            case Bytecodes.INVOKEDYNAMIC:
+                // invokedynamic instructions point to a constant pool cache entry.
+                index = decodeConstantPoolCacheIndex(cpi);
+                index = runtime().getCompilerToVM().constantPoolRemapInstructionOperandFromCache(metaspaceConstantPool, index);
+                break;
             default:
                 index = toConstantPoolIndex(cpi, opcode);
                 index = runtime().getCompilerToVM().constantPoolRemapInstructionOperandFromCache(metaspaceConstantPool, index);
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotNmethod.java	Sat Apr 05 03:18:48 2014 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotNmethod.java	Sat Apr 05 03:19:27 2014 +0200
@@ -28,7 +28,6 @@
 
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
-import com.oracle.graal.hotspot.bridge.*;
 
 /**
  * Implementation of {@link InstalledCode} for code installed as an nmethod. The nmethod stores a
@@ -95,7 +94,7 @@
     @Override
     public Object execute(Object arg1, Object arg2, Object arg3) throws InvalidInstalledCodeException {
         assert checkThreeObjectArgs();
-        return CompilerToVMImpl.executeCompiledMethodIntrinsic(arg1, arg2, arg3, this);
+        return runtime().getCompilerToVM().executeCompiledMethod(arg1, arg2, arg3, this);
     }
 
     protected boolean checkThreeObjectArgs() {
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedObjectType.java	Sat Apr 05 03:18:48 2014 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedObjectType.java	Sat Apr 05 03:19:27 2014 +0200
@@ -62,7 +62,7 @@
 
     /**
      * Gets the Graal mirror from a HotSpot metaspace Klass native object.
-     * 
+     *
      * @param metaspaceKlass a metaspace Klass object boxed in a {@link Constant}
      * @return the {@link ResolvedJavaType} corresponding to {@code klassConstant}
      */
@@ -73,7 +73,7 @@
 
     /**
      * Gets the Graal mirror from a HotSpot metaspace Klass native object.
-     * 
+     *
      * @param metaspaceKlass a metaspace Klass object
      * @return the {@link ResolvedJavaType} corresponding to {@code metaspaceKlass}
      */
@@ -86,13 +86,13 @@
 
     /**
      * Creates the Graal mirror for a {@link Class} object.
-     * 
+     *
      * <p>
      * <b>NOTE</b>: Creating an instance of this class does not install the mirror for the
      * {@link Class} type. Use {@link #fromClass(Class)}, {@link #fromMetaspaceKlass(Constant)} or
      * {@link #fromMetaspaceKlass(long)} instead.
      * </p>
-     * 
+     *
      * @param javaClass the Class to create the mirror for
      */
     public HotSpotResolvedObjectType(Class<?> javaClass) {
@@ -185,7 +185,7 @@
     /**
      * Returns if type {@code type} is a leaf class. This is the case if the
      * {@code Klass::_subklass} field of the underlying class is zero.
-     * 
+     *
      * @return true if the type is a leaf class
      */
     private boolean isLeafClass() {
@@ -195,7 +195,7 @@
     /**
      * Returns the {@code Klass::_subklass} field of the underlying metaspace klass for the given
      * type {@code type}.
-     * 
+     *
      * @return value of the subklass field as metaspace klass pointer
      */
     private long getSubklass() {
@@ -312,7 +312,7 @@
     /**
      * Returns the value of the state field {@code InstanceKlass::_init_state} of the metaspace
      * klass.
-     * 
+     *
      * @return state field value of this type
      */
     private int getState() {
@@ -476,7 +476,7 @@
 
         /**
          * Creates a field info for the field in the fields array at index {@code index}.
-         * 
+         *
          * @param index index to the fields array
          */
         public FieldInfo(int index) {
@@ -484,8 +484,7 @@
             // Get Klass::_fields
             final long metaspaceFields = unsafe.getAddress(metaspaceKlass() + config.instanceKlassFieldsOffset);
             assert config.fieldInfoFieldSlots == 6 : "revisit the field parsing code";
-            metaspaceData = metaspaceFields + config.arrayU2DataOffset + config.fieldInfoFieldSlots * 2 * index;  // TODO
-            // Short.BYTES
+            metaspaceData = metaspaceFields + config.arrayU2DataOffset + config.fieldInfoFieldSlots * Short.BYTES * index;
         }
 
         private int getAccessFlags() {
@@ -513,7 +512,7 @@
          * on top an array of Java shorts.
          */
         private int readFieldSlot(int index) {
-            return unsafe.getChar(metaspaceData + 2 * index);  // TODO Short.BYTES
+            return unsafe.getChar(metaspaceData + Short.BYTES * index);
         }
 
         /**
@@ -578,8 +577,7 @@
                     }
                 }
 
-                // TODO use in 1.8: fieldsArray.sort(new OffsetComparator());
-                Collections.sort(fieldsArray, new OffsetComparator());
+                fieldsArray.sort(new OffsetComparator());
 
                 HotSpotResolvedJavaField[] myFields = fieldsArray.toArray(new HotSpotResolvedJavaField[0]);
 
@@ -614,7 +612,7 @@
     /**
      * Returns the actual field count of this class's internal {@code InstanceKlass::_fields} array
      * by walking the array and discounting the generic signature slots at the end of the array.
-     * 
+     *
      * <p>
      * See {@code FieldStreamBase::init_generic_signature_start_slot}
      */
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotSignature.java	Sat Apr 05 03:18:48 2014 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotSignature.java	Sat Apr 05 03:19:27 2014 +0200
@@ -127,13 +127,30 @@
         return argSlots + (withReceiver ? 1 : 0);
     }
 
+    private static boolean checkValidCache(JavaType type, ResolvedJavaType accessingClass) {
+        if (!(type instanceof ResolvedJavaType)) {
+            return false;
+        }
+
+        if (type instanceof HotSpotResolvedObjectType) {
+            HotSpotResolvedObjectType resolved = (HotSpotResolvedObjectType) type;
+            if (accessingClass == null) {
+                return resolved.mirror().getClassLoader() == null;
+            } else {
+                return resolved.mirror().getClassLoader() == ((HotSpotResolvedObjectType) accessingClass).mirror().getClassLoader();
+            }
+        }
+
+        return true;
+    }
+
     @Override
     public JavaType getParameterType(int index, ResolvedJavaType accessingClass) {
         if (parameterTypes == null) {
             parameterTypes = new JavaType[parameters.size()];
         }
         JavaType type = parameterTypes[index];
-        if (type == null || !(type instanceof ResolvedJavaType)) {
+        if (!checkValidCache(type, accessingClass)) {
             type = runtime().lookupType(parameters.get(index), (HotSpotResolvedObjectType) accessingClass, false);
             parameterTypes[index] = type;
         }
@@ -152,7 +169,7 @@
 
     @Override
     public JavaType getReturnType(ResolvedJavaType accessingClass) {
-        if (returnTypeCache == null || !(returnTypeCache instanceof ResolvedJavaType)) {
+        if (!checkValidCache(returnTypeCache, accessingClass)) {
             returnTypeCache = runtime().lookupType(returnType, (HotSpotResolvedObjectType) accessingClass, false);
         }
         return returnTypeCache;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/CurrentJavaThreadNode.java	Sat Apr 05 03:18:48 2014 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/CurrentJavaThreadNode.java	Sat Apr 05 03:19:27 2014 +0200
@@ -25,10 +25,12 @@
 import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*;
 
 import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.hotspot.*;
 import com.oracle.graal.nodes.calc.*;
 import com.oracle.graal.nodes.spi.*;
+import com.oracle.graal.nodes.type.*;
 import com.oracle.graal.word.*;
 
 /**
@@ -36,8 +38,8 @@
  */
 public final class CurrentJavaThreadNode extends FloatingNode implements LIRLowerable {
 
-    private CurrentJavaThreadNode() {
-        super(null);
+    private CurrentJavaThreadNode(Kind kind) {
+        super(StampFactory.forKind(kind));
     }
 
     @Override
@@ -55,7 +57,7 @@
     }
 
     @NodeIntrinsic(setStampFromReturnType = true)
-    public static Word get() {
+    public static Word get(@SuppressWarnings("unused") @ConstantNodeParameter Kind kind) {
         return Word.unsigned(unsafeReadWord(Thread.currentThread(), eetopOffset()));
     }
 }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ThreadSubstitutions.java	Sat Apr 05 03:18:48 2014 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ThreadSubstitutions.java	Sat Apr 05 03:19:27 2014 +0200
@@ -45,12 +45,12 @@
 
     @MethodSubstitution
     public static Thread currentThread() {
-        return PiNode.piCastNonNull(CurrentJavaThreadNode.get().readObject(threadObjectOffset(), LocationIdentity.FINAL_LOCATION), Thread.class);
+        return PiNode.piCastNonNull(CurrentJavaThreadNode.get(getWordKind()).readObject(threadObjectOffset(), LocationIdentity.FINAL_LOCATION), Thread.class);
     }
 
     @MethodSubstitution(isStatic = false)
     public static boolean isInterrupted(final Thread thisObject, boolean clearInterrupted) {
-        Word javaThread = CurrentJavaThreadNode.get();
+        Word javaThread = CurrentJavaThreadNode.get(getWordKind());
         Object thread = javaThread.readObject(threadObjectOffset(), LocationIdentity.FINAL_LOCATION);
         if (thisObject == thread) {
             Word osThread = javaThread.readWord(osThreadOffset(), LocationIdentity.FINAL_LOCATION);
--- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/AbstractBytecodeParser.java	Sat Apr 05 03:18:48 2014 +0200
+++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/AbstractBytecodeParser.java	Sat Apr 05 03:19:27 2014 +0200
@@ -505,11 +505,7 @@
         frameState.storeLocal(index, append(genIntegerAdd(Kind.Int, x, y)));
     }
 
-    private void genGoto() {
-        appendGoto(createTarget(currentBlock.getSuccessors().get(0), frameState));
-        // assert currentBlock.numNormalSuccessors() == 1;
-        assert currentBlock.getSuccessors().size() == 1;
-    }
+    protected abstract void genGoto();
 
     protected abstract T genObjectEquals(T x, T y);
 
@@ -911,24 +907,12 @@
 
     protected abstract T append(T v);
 
-    private boolean isNeverExecutedCode(double probability) {
+    protected boolean isNeverExecutedCode(double probability) {
         return probability == 0 && optimisticOpts.removeNeverExecutedCode() && entryBCI == StructuredGraph.INVOCATION_ENTRY_BCI;
     }
 
     protected abstract T genDeoptimization();
 
-    protected T createTarget(double probability, BciBlock block, AbstractFrameStateBuilder<T> stateAfter) {
-        assert probability >= 0 && probability <= 1.01 : probability;
-        if (isNeverExecutedCode(probability)) {
-            return genDeoptimization();
-        } else {
-            assert block != null;
-            return createTarget(block, stateAfter);
-        }
-    }
-
-    protected abstract T createTarget(BciBlock trueBlock, AbstractFrameStateBuilder<T> state);
-
     /**
      * Returns a block begin node with the specified state. If the specified probability is 0, the
      * block deoptimizes immediately.
--- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java	Sat Apr 05 03:18:48 2014 +0200
+++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java	Sat Apr 05 03:19:27 2014 +0200
@@ -569,6 +569,12 @@
             }
 
             @Override
+            protected void genGoto() {
+                appendGoto(createTarget(currentBlock.getSuccessors().get(0), frameState));
+                assert currentBlock.numNormalSuccessors() == 1;
+            }
+
+            @Override
             protected ValueNode genObjectEquals(ValueNode x, ValueNode y) {
                 return new ObjectEqualsNode(x, y);
             }
@@ -1007,15 +1013,17 @@
                 return currentGraph.add(new DeoptimizeNode(InvalidateReprofile, UnreachedCode));
             }
 
-            @Override
             protected FixedNode createTarget(double probability, BciBlock block, AbstractFrameStateBuilder<ValueNode> stateAfter) {
-                ValueNode fixed = super.createTarget(probability, block, stateAfter);
-                assert fixed instanceof FixedNode;
-                return (FixedNode) fixed;
+                assert probability >= 0 && probability <= 1.01 : probability;
+                if (isNeverExecutedCode(probability)) {
+                    return (FixedNode) genDeoptimization();
+                } else {
+                    assert block != null;
+                    return createTarget(block, stateAfter);
+                }
 
             }
 
-            @Override
             protected FixedNode createTarget(BciBlock block, AbstractFrameStateBuilder<ValueNode> abstractState) {
                 assert abstractState instanceof HIRFrameStateBuilder;
                 HIRFrameStateBuilder state = (HIRFrameStateBuilder) abstractState;
--- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/HIRFrameStateBuilder.java	Sat Apr 05 03:18:48 2014 +0200
+++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/HIRFrameStateBuilder.java	Sat Apr 05 03:19:27 2014 +0200
@@ -192,7 +192,7 @@
 
         } else if (block.isPhiAtMerge(currentValue)) {
             if (otherValue == null || otherValue.isDeleted() || currentValue.getKind() != otherValue.getKind()) {
-                propagateDelete((PhiNode) currentValue);
+                propagateDelete((ValuePhiNode) currentValue);
                 return null;
             }
             ((PhiNode) currentValue).addInput(otherValue);
@@ -204,7 +204,7 @@
                 return null;
             }
 
-            PhiNode phi = graph.addWithoutUnique(new PhiNode(currentValue.stamp().unrestricted(), block));
+            ValuePhiNode phi = graph.addWithoutUnique(new ValuePhiNode(currentValue.stamp().unrestricted(), block));
             for (int i = 0; i < block.phiPredecessorCount(); i++) {
                 phi.addInput(currentValue);
             }
@@ -218,16 +218,16 @@
     }
 
     private void propagateDelete(FloatingNode node) {
-        assert node instanceof PhiNode || node instanceof ProxyNode;
+        assert node instanceof ValuePhiNode || node instanceof ProxyNode;
         if (node.isDeleted()) {
             return;
         }
         // Collect all phi functions that use this phi so that we can delete them recursively (after
         // we delete ourselves to avoid circles).
-        List<FloatingNode> propagateUsages = node.usages().filter(FloatingNode.class).filter(isA(PhiNode.class).or(ProxyNode.class)).snapshot();
+        List<FloatingNode> propagateUsages = node.usages().filter(FloatingNode.class).filter(isA(ValuePhiNode.class).or(ProxyNode.class)).snapshot();
 
         // Remove the phi function from all FrameStates where it is used and then delete it.
-        assert node.usages().filter(isNotA(FrameState.class).nor(PhiNode.class).nor(ProxyNode.class)).isEmpty() : "phi function that gets deletes must only be used in frame states";
+        assert node.usages().filter(isNotA(FrameState.class).nor(ValuePhiNode.class).nor(ProxyNode.class)).isEmpty() : "phi function that gets deletes must only be used in frame states";
         node.replaceAtUsages(null);
         node.safeDelete();
 
@@ -296,13 +296,13 @@
         }
     }
 
-    private PhiNode createLoopPhi(MergeNode block, ValueNode value) {
+    private ValuePhiNode createLoopPhi(MergeNode block, ValueNode value) {
         if (value == null) {
             return null;
         }
         assert !block.isPhiAtMerge(value) : "phi function for this block already created";
 
-        PhiNode phi = graph.addWithoutUnique(new PhiNode(value.stamp().unrestricted(), block));
+        ValuePhiNode phi = graph.addWithoutUnique(new ValuePhiNode(value.stamp().unrestricted(), block));
         phi.addInput(value);
         return phi;
     }
@@ -310,7 +310,7 @@
     public void cleanupDeletedPhis() {
         for (int i = 0; i < localsSize(); i++) {
             if (localAt(i) != null && localAt(i).isDeleted()) {
-                assert localAt(i) instanceof PhiNode || localAt(i) instanceof ProxyNode : "Only phi and value proxies can be deleted during parsing: " + localAt(i);
+                assert localAt(i) instanceof ValuePhiNode || localAt(i) instanceof ProxyNode : "Only phi and value proxies can be deleted during parsing: " + localAt(i);
                 storeLocal(i, null);
             }
         }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/jdk/Unsafe_compareAndSwapNullCheck.java	Sat Apr 05 03:19:27 2014 +0200
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2008, 2014, 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.jtt.jdk;
+
+import org.junit.*;
+
+import sun.misc.*;
+
+import com.oracle.graal.jtt.*;
+
+public class Unsafe_compareAndSwapNullCheck extends JTTTest {
+
+    static final Unsafe unsafe = UnsafeAccess01.getUnsafe();
+    static final long valueOffset;
+    static {
+        try {
+            valueOffset = unsafe.objectFieldOffset(Unsafe_compareAndSwap.class.getDeclaredField("value"));
+        } catch (Exception ex) {
+            throw new Error(ex);
+        }
+    }
+
+    long value;
+    long lng;
+
+    public static void test(Unsafe_compareAndSwapNullCheck u, long expected, long newValue) {
+        @SuppressWarnings("unused")
+        long l = u.lng;
+        unsafe.compareAndSwapLong(u, valueOffset, expected, newValue);
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        runTest(EMPTY, false, true, "test", null, 1L, 2L);
+    }
+}
--- a/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Compare.java	Sat Apr 05 03:18:48 2014 +0200
+++ b/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Compare.java	Sat Apr 05 03:19:27 2014 +0200
@@ -34,6 +34,8 @@
 import com.oracle.graal.lir.asm.*;
 
 public enum AMD64Compare {
+    BCMP,
+    SCMP,
     ICMP,
     LCMP,
     ACMP,
@@ -59,8 +61,10 @@
         @Override
         protected void verify() {
             super.verify();
-            assert (name().startsWith("I") && x.getKind().getStackKind() == Kind.Int && y.getKind().getStackKind() == Kind.Int) ||
-                            (name().startsWith("L") && x.getKind() == Kind.Long && y.getKind() == Kind.Long) || (name().startsWith("A") && x.getKind() == Kind.Object && y.getKind() == Kind.Object) ||
+            assert (name().startsWith("B") && x.getKind().getStackKind() == Kind.Int && y.getKind().getStackKind() == Kind.Int) ||
+                            (name().startsWith("S") && x.getKind().getStackKind() == Kind.Int && y.getKind().getStackKind() == Kind.Int) ||
+                            (name().startsWith("I") && x.getKind() == Kind.Int && y.getKind() == Kind.Int) || (name().startsWith("L") && x.getKind() == Kind.Long && y.getKind() == Kind.Long) ||
+                            (name().startsWith("A") && x.getKind() == Kind.Object && y.getKind() == Kind.Object) ||
                             (name().startsWith("F") && x.getKind() == Kind.Float && y.getKind() == Kind.Float) || (name().startsWith("D") && x.getKind() == Kind.Double && y.getKind() == Kind.Double);
         }
     }
@@ -82,6 +86,12 @@
         public void emitMemAccess(CompilationResultBuilder crb, AMD64MacroAssembler masm) {
             if (isRegister(y)) {
                 switch (opcode) {
+                    case BCMP:
+                        masm.cmpb(asIntReg(y), address.toAddress());
+                        break;
+                    case SCMP:
+                        masm.cmpw(asIntReg(y), address.toAddress());
+                        break;
                     case ICMP:
                         masm.cmpl(asIntReg(y), address.toAddress());
                         break;
@@ -102,6 +112,12 @@
                 }
             } else if (isConstant(y)) {
                 switch (opcode) {
+                    case BCMP:
+                        masm.cmpb(address.toAddress(), crb.asIntConst(y));
+                        break;
+                    case SCMP:
+                        masm.cmpw(address.toAddress(), crb.asIntConst(y));
+                        break;
                     case ICMP:
                         masm.cmpl(address.toAddress(), crb.asIntConst(y));
                         break;
@@ -128,6 +144,12 @@
     public static void emit(CompilationResultBuilder crb, AMD64MacroAssembler masm, AMD64Compare opcode, Value x, Value y) {
         if (isRegister(x) && isRegister(y)) {
             switch (opcode) {
+                case BCMP:
+                    masm.cmpb(asIntReg(x), asIntReg(y));
+                    break;
+                case SCMP:
+                    masm.cmpw(asIntReg(x), asIntReg(y));
+                    break;
                 case ICMP:
                     masm.cmpl(asIntReg(x), asIntReg(y));
                     break;
@@ -149,6 +171,20 @@
         } else if (isRegister(x) && isConstant(y)) {
             boolean isZero = ((Constant) y).isDefaultForKind();
             switch (opcode) {
+                case BCMP:
+                    if (isZero) {
+                        masm.testl(asIntReg(x), asIntReg(x));
+                    } else {
+                        masm.cmpb(asIntReg(x), crb.asIntConst(y));
+                    }
+                    break;
+                case SCMP:
+                    if (isZero) {
+                        masm.testl(asIntReg(x), asIntReg(x));
+                    } else {
+                        masm.cmpw(asIntReg(x), crb.asIntConst(y));
+                    }
+                    break;
                 case ICMP:
                     if (isZero) {
                         masm.testl(asIntReg(x), asIntReg(x));
@@ -181,6 +217,12 @@
             }
         } else if (isRegister(x) && isStackSlot(y)) {
             switch (opcode) {
+                case BCMP:
+                    masm.cmpb(asIntReg(x), (AMD64Address) crb.asByteAddr(y));
+                    break;
+                case SCMP:
+                    masm.cmpw(asIntReg(x), (AMD64Address) crb.asShortAddr(y));
+                    break;
                 case ICMP:
                     masm.cmpl(asIntReg(x), (AMD64Address) crb.asIntAddr(y));
                     break;
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/asm/CompilationResultBuilder.java	Sat Apr 05 03:18:48 2014 +0200
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/asm/CompilationResultBuilder.java	Sat Apr 05 03:19:27 2014 +0200
@@ -37,7 +37,7 @@
 
 /**
  * Fills in a {@link CompilationResult} as its code is being assembled.
- * 
+ *
  * @see CompilationResultBuilderFactory
  */
 public class CompilationResultBuilder {
@@ -264,6 +264,16 @@
         return recordDataReferenceInCode((Constant) value, 8);
     }
 
+    public AbstractAddress asByteAddr(Value value) {
+        assert value.getKind() == Kind.Byte || value.getKind() == Kind.Boolean;
+        return asAddress(value);
+    }
+
+    public AbstractAddress asShortAddr(Value value) {
+        assert value.getKind() == Kind.Short || value.getKind() == Kind.Char;
+        return asAddress(value);
+    }
+
     public AbstractAddress asIntAddr(Value value) {
         assert value.getKind() == Kind.Int;
         return asAddress(value);
--- a/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/BasicInductionVariable.java	Sat Apr 05 03:18:48 2014 +0200
+++ b/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/BasicInductionVariable.java	Sat Apr 05 03:19:27 2014 +0200
@@ -29,12 +29,12 @@
 
 public class BasicInductionVariable extends InductionVariable {
 
-    private PhiNode phi;
+    private ValuePhiNode phi;
     private ValueNode init;
     private ValueNode rawStride;
     private IntegerArithmeticNode op;
 
-    public BasicInductionVariable(LoopEx loop, PhiNode phi, ValueNode init, ValueNode rawStride, IntegerArithmeticNode op) {
+    public BasicInductionVariable(LoopEx loop, ValuePhiNode phi, ValueNode init, ValueNode rawStride, IntegerArithmeticNode op) {
         super(loop);
         this.phi = phi;
         this.init = init;
@@ -71,7 +71,7 @@
     }
 
     @Override
-    public PhiNode valueNode() {
+    public ValuePhiNode valueNode() {
         return phi;
     }
 
--- a/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/InductionVariables.java	Sat Apr 05 03:18:48 2014 +0200
+++ b/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/InductionVariables.java	Sat Apr 05 03:19:27 2014 +0200
@@ -54,7 +54,7 @@
             }
             ValueNode stride = addSub(backValue, phi);
             if (stride != null) {
-                BasicInductionVariable biv = new BasicInductionVariable(loop, phi, phi.valueAt(forwardEnd), stride, (IntegerArithmeticNode) backValue);
+                BasicInductionVariable biv = new BasicInductionVariable(loop, (ValuePhiNode) phi, phi.valueAt(forwardEnd), stride, (IntegerArithmeticNode) backValue);
                 ivs.put(phi, biv);
                 bivs.add(biv);
             }
--- a/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopFragment.java	Sat Apr 05 03:18:48 2014 +0200
+++ b/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopFragment.java	Sat Apr 05 03:19:27 2014 +0200
@@ -330,18 +330,14 @@
                 ProxyNode newVpn = getDuplicatedNode(vpn);
                 if (newVpn != null) {
                     PhiNode phi;
-                    switch (vpn.type()) {
-                        case Value:
-                            phi = graph.addWithoutUnique(new PhiNode(vpn.stamp(), merge));
-                            break;
-                        case Guard:
-                            phi = graph.addWithoutUnique(new PhiNode(vpn.type(), merge));
-                            break;
-                        case Memory:
-                            phi = graph.addWithoutUnique(new MemoryPhiNode(merge, ((MemoryProxyNode) vpn).getLocationIdentity()));
-                            break;
-                        default:
-                            throw GraalInternalError.shouldNotReachHere();
+                    if (vpn instanceof ValueProxyNode) {
+                        phi = graph.addWithoutUnique(new ValuePhiNode(vpn.stamp(), merge));
+                    } else if (vpn instanceof GuardProxyNode) {
+                        phi = graph.addWithoutUnique(new GuardPhiNode(merge));
+                    } else if (vpn instanceof MemoryProxyNode) {
+                        phi = graph.addWithoutUnique(new MemoryPhiNode(merge, ((MemoryProxyNode) vpn).getLocationIdentity()));
+                    } else {
+                        throw GraalInternalError.shouldNotReachHere();
                     }
                     phi.addInput(vpn);
                     phi.addInput(newVpn);
--- a/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopFragmentInside.java	Sat Apr 05 03:18:48 2014 +0200
+++ b/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopFragmentInside.java	Sat Apr 05 03:19:27 2014 +0200
@@ -24,11 +24,10 @@
 
 import java.util.*;
 
+import com.oracle.graal.graph.*;
 import com.oracle.graal.graph.Graph.DuplicationReplacement;
-import com.oracle.graal.graph.*;
 import com.oracle.graal.graph.iterators.*;
 import com.oracle.graal.nodes.*;
-import com.oracle.graal.nodes.PhiNode.PhiType;
 import com.oracle.graal.nodes.VirtualState.NodeClosure;
 import com.oracle.graal.nodes.util.*;
 
@@ -41,7 +40,7 @@
      * peeling case. In the unrolling case they will be used as the value that replace the loop-phis
      * of the duplicated inside fragment
      */
-    private Map<PhiNode, ValueNode> mergedInitializers;
+    private Map<ValuePhiNode, ValueNode> mergedInitializers;
     private final DuplicationReplacement dataFixBefore = new DuplicationReplacement() {
 
         @Override
@@ -168,18 +167,14 @@
 
     private static PhiNode patchPhi(StructuredGraph graph, PhiNode phi, MergeNode merge) {
         PhiNode ret;
-        switch (phi.type()) {
-            case Value:
-                ret = new PhiNode(phi.stamp(), merge);
-                break;
-            case Guard:
-                ret = new PhiNode(PhiType.Guard, merge);
-                break;
-            case Memory:
-                ret = new MemoryPhiNode(merge, ((MemoryPhiNode) phi).getLocationIdentity());
-                break;
-            default:
-                throw GraalInternalError.shouldNotReachHere();
+        if (phi instanceof ValuePhiNode) {
+            ret = new ValuePhiNode(phi.stamp(), merge);
+        } else if (phi instanceof GuardPhiNode) {
+            ret = new GuardPhiNode(merge);
+        } else if (phi instanceof MemoryPhiNode) {
+            ret = new MemoryPhiNode(merge, ((MemoryPhiNode) phi).getLocationIdentity());
+        } else {
+            throw GraalInternalError.shouldNotReachHere();
         }
         return graph.addWithoutUnique(ret);
     }
@@ -219,7 +214,7 @@
             for (int i = 0; i < phi.valueCount(); i++) {
                 ValueNode v = phi.valueAt(i);
                 if (loopBegin.isPhiAtMerge(v)) {
-                    PhiNode newV = peel.getDuplicatedNode((PhiNode) v);
+                    PhiNode newV = peel.getDuplicatedNode((ValuePhiNode) v);
                     if (newV != null) {
                         phi.setValueAt(i, newV);
                     }
@@ -230,7 +225,7 @@
 
     /**
      * Gets the corresponding value in this fragment.
-     * 
+     *
      * @param b original value
      * @return corresponding value in the peel
      */
@@ -308,7 +303,7 @@
                         }
                     });
                 }
-                mergedInitializers.put(phi, initializer);
+                mergedInitializers.put((ValuePhiNode) phi, initializer);
             }
         }
         return newExit;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/GuardPhiNode.java	Sat Apr 05 03:19:27 2014 +0200
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2009, 2014, 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.nodes;
+
+import com.oracle.graal.graph.*;
+import com.oracle.graal.nodes.extended.*;
+import com.oracle.graal.nodes.type.*;
+
+@NodeInfo(nameTemplate = "GuardPhi({i#values})")
+public class GuardPhiNode extends PhiNode implements GuardingNode {
+
+    @Input final NodeInputList<ValueNode> values = new NodeInputList<>(this);
+
+    public GuardPhiNode(MergeNode merge) {
+        super(StampFactory.dependency(), merge);
+    }
+
+    @Override
+    public NodeInputList<ValueNode> values() {
+        return values;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/GuardProxyNode.java	Sat Apr 05 03:19:27 2014 +0200
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2012, 2014, 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.nodes;
+
+import com.oracle.graal.nodes.extended.*;
+import com.oracle.graal.nodes.type.*;
+
+public class GuardProxyNode extends ProxyNode implements GuardingNode {
+
+    @Input private ValueNode value;
+
+    public GuardProxyNode(ValueNode value, AbstractBeginNode proxyPoint) {
+        super(StampFactory.dependency(), proxyPoint);
+        this.value = value;
+    }
+
+    @Override
+    public ValueNode value() {
+        return value;
+    }
+}
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/IfNode.java	Sat Apr 05 03:18:48 2014 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/IfNode.java	Sat Apr 05 03:19:27 2014 +0200
@@ -31,7 +31,6 @@
 import com.oracle.graal.graph.*;
 import com.oracle.graal.graph.iterators.*;
 import com.oracle.graal.graph.spi.*;
-import com.oracle.graal.nodes.PhiNode.PhiType;
 import com.oracle.graal.nodes.calc.*;
 import com.oracle.graal.nodes.extended.*;
 import com.oracle.graal.nodes.java.*;
@@ -514,12 +513,12 @@
             return false;
         }
         Node singleUsage = mergeUsages.first();
-        if (!(singleUsage instanceof PhiNode) || (singleUsage != compare.x() && singleUsage != compare.y())) {
+        if (!(singleUsage instanceof ValuePhiNode) || (singleUsage != compare.x() && singleUsage != compare.y())) {
             return false;
         }
 
         // Ensure phi is used by at most the comparison and the merge's frame state (if any)
-        PhiNode phi = (PhiNode) singleUsage;
+        ValuePhiNode phi = (ValuePhiNode) singleUsage;
         NodeIterable<Node> phiUsages = phi.usages();
         if (phiUsages.count() > 2) {
             return false;
@@ -650,7 +649,7 @@
                 // removed
                 MergeNode newMerge = graph().add(new MergeNode());
                 PhiNode oldPhi = (PhiNode) oldMerge.usages().first();
-                PhiNode newPhi = graph().addWithoutUnique(new PhiNode(oldPhi.stamp(), newMerge));
+                PhiNode newPhi = graph().addWithoutUnique(new ValuePhiNode(oldPhi.stamp(), newMerge));
 
                 for (AbstractEndNode end : ends) {
                     newPhi.addInput(phiValues.get(end));
@@ -687,7 +686,7 @@
 
         if (node instanceof PhiNode) {
             PhiNode phi = (PhiNode) node;
-            if (phi.merge() == merge && phi.type() == PhiType.Value && phi.valueCount() == merge.forwardEndCount()) {
+            if (phi.merge() == merge && phi instanceof ValuePhiNode && phi.valueCount() == merge.forwardEndCount()) {
                 Constant[] result = new Constant[merge.forwardEndCount()];
                 int i = 0;
                 for (ValueNode n : phi.values()) {
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/MemoryPhiNode.java	Sat Apr 05 03:18:48 2014 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/MemoryPhiNode.java	Sat Apr 05 03:19:27 2014 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2014, 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
@@ -23,22 +23,25 @@
 package com.oracle.graal.nodes;
 
 import com.oracle.graal.api.meta.*;
+import com.oracle.graal.graph.*;
 import com.oracle.graal.nodes.extended.*;
+import com.oracle.graal.nodes.type.*;
 
 /**
  * The {@code PhiNode} represents the merging of dataflow in the memory graph.
  */
 public class MemoryPhiNode extends PhiNode implements MemoryNode {
 
-    private final LocationIdentity identity;
+    @Input final NodeInputList<ValueNode> values = new NodeInputList<>(this);
+    private final LocationIdentity locationIdentity;
 
-    public MemoryPhiNode(MergeNode merge, LocationIdentity identity) {
-        super(PhiType.Memory, merge);
-        this.identity = identity;
+    public MemoryPhiNode(MergeNode merge, LocationIdentity locationIdentity) {
+        super(StampFactory.dependency(), merge);
+        this.locationIdentity = locationIdentity;
     }
 
     public LocationIdentity getLocationIdentity() {
-        return identity;
+        return locationIdentity;
     }
 
     public MemoryCheckpoint asMemoryCheckpoint() {
@@ -48,4 +51,9 @@
     public MemoryPhiNode asMemoryPhi() {
         return this;
     }
+
+    @Override
+    public NodeInputList<ValueNode> values() {
+        return values;
+    }
 }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/MemoryProxyNode.java	Sat Apr 05 03:18:48 2014 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/MemoryProxyNode.java	Sat Apr 05 03:19:27 2014 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2014, 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
@@ -23,20 +23,27 @@
 package com.oracle.graal.nodes;
 
 import com.oracle.graal.api.meta.*;
-import com.oracle.graal.nodes.PhiNode.PhiType;
 import com.oracle.graal.nodes.extended.*;
 import com.oracle.graal.nodes.spi.*;
+import com.oracle.graal.nodes.type.*;
 
 public class MemoryProxyNode extends ProxyNode implements MemoryProxy, LIRLowerable {
 
+    @Input private ValueNode value;
     private final LocationIdentity identity;
 
     public MemoryProxyNode(ValueNode value, AbstractBeginNode exit, LocationIdentity identity) {
-        super(value, exit, PhiType.Memory);
+        super(StampFactory.dependency(), exit);
+        this.value = value;
         assert value instanceof MemoryNode;
         this.identity = identity;
     }
 
+    @Override
+    public ValueNode value() {
+        return value;
+    }
+
     public LocationIdentity getLocationIdentity() {
         return identity;
     }
@@ -47,14 +54,10 @@
 
     @Override
     public boolean verify() {
-        assert value() instanceof MemoryNode;
+        assert value() instanceof MemoryNode : this + " " + value();
         return super.verify();
     }
 
-    public static MemoryProxyNode forMemory(MemoryNode value, AbstractBeginNode exit, LocationIdentity location, StructuredGraph graph) {
-        return graph.unique(new MemoryProxyNode(ValueNodeUtil.asNode(value), exit, location));
-    }
-
     public MemoryNode getOriginalMemoryNode() {
         return (MemoryNode) value();
     }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/MergeNode.java	Sat Apr 05 03:18:48 2014 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/MergeNode.java	Sat Apr 05 03:19:27 2014 +0200
@@ -210,7 +210,7 @@
                 }
             }
 
-            PhiNode returnValuePhi = returnNode.result() == null || !isPhiAtMerge(returnNode.result()) ? null : (PhiNode) returnNode.result();
+            ValuePhiNode returnValuePhi = returnNode.result() == null || !isPhiAtMerge(returnNode.result()) ? null : (ValuePhiNode) returnNode.result();
             List<AbstractEndNode> endNodes = forwardEnds().snapshot();
             for (AbstractEndNode end : endNodes) {
                 ReturnNode newReturn = graph().add(new ReturnNode(returnValuePhi == null ? returnNode.result() : returnValuePhi.valueAt(end)));
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/PhiNode.java	Sat Apr 05 03:18:48 2014 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/PhiNode.java	Sat Apr 05 03:19:27 2014 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2014, 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
@@ -25,61 +25,18 @@
 import com.oracle.graal.graph.*;
 import com.oracle.graal.graph.spi.*;
 import com.oracle.graal.nodes.calc.*;
-import com.oracle.graal.nodes.extended.*;
 import com.oracle.graal.nodes.type.*;
 
-/**
- * The {@code PhiNode} represents the merging of dataflow in the graph. It refers to a merge and a
- * variable.
- */
-@NodeInfo(nameTemplate = "{p#type/s}Phi({i#values})")
-public class PhiNode extends FloatingNode implements Canonicalizable, GuardingNode {
-
-    public static enum PhiType {
-        Value(null), // normal value phis
-        Guard(StampFactory.dependency()),
-        Memory(StampFactory.dependency());
-
-        public final Stamp stamp;
-
-        PhiType(Stamp stamp) {
-            this.stamp = stamp;
-        }
-    }
+public abstract class PhiNode extends FloatingNode {
 
     @Input(notDataflow = true) private MergeNode merge;
-    @Input private final NodeInputList<ValueNode> values = new NodeInputList<>(this);
-    private final PhiType type;
 
-    /**
-     * Create a value phi ({@link PhiType#Value}) with the specified stamp.
-     * 
-     * @param stamp the stamp of the value
-     * @param merge the merge that the new phi belongs to
-     */
-    public PhiNode(Stamp stamp, MergeNode merge) {
+    protected PhiNode(Stamp stamp, MergeNode merge) {
         super(stamp);
-        assert stamp != StampFactory.forVoid();
-        this.type = PhiType.Value;
         this.merge = merge;
     }
 
-    /**
-     * Create a non-value phi ({@link PhiType#Memory} with the specified kind.
-     * 
-     * @param type the type of the new phi
-     * @param merge the merge that the new phi belongs to
-     */
-    public PhiNode(PhiType type, MergeNode merge) {
-        super(type.stamp);
-        assert type.stamp != null : merge + " " + type;
-        this.type = type;
-        this.merge = merge;
-    }
-
-    public PhiType type() {
-        return type;
-    }
+    public abstract NodeInputList<ValueNode> values();
 
     public MergeNode merge() {
         return merge;
@@ -90,23 +47,6 @@
         merge = x;
     }
 
-    public NodeInputList<ValueNode> values() {
-        return values;
-    }
-
-    @Override
-    public boolean inferStamp() {
-        if (type == PhiType.Value) {
-            return inferPhiStamp();
-        } else {
-            return false;
-        }
-    }
-
-    public boolean inferPhiStamp() {
-        return updateStamp(StampTool.meet(values()));
-    }
-
     @Override
     public boolean verify() {
         assertTrue(merge() != null, "missing merge");
@@ -117,29 +57,29 @@
     /**
      * Get the instruction that produces the value associated with the i'th predecessor of the
      * merge.
-     * 
+     *
      * @param i the index of the predecessor
      * @return the instruction that produced the value in the i'th predecessor
      */
     public ValueNode valueAt(int i) {
-        return values.get(i);
+        return values().get(i);
     }
 
     /**
      * Sets the value at the given index and makes sure that the values list is large enough.
-     * 
+     *
      * @param i the index at which to set the value
      * @param x the new phi input value for the given location
      */
     public void initializeValueAt(int i, ValueNode x) {
         while (values().size() <= i) {
-            values.add(null);
+            values().add(null);
         }
-        values.set(i, x);
+        values().set(i, x);
     }
 
     public void setValueAt(int i, ValueNode x) {
-        values.set(i, x);
+        values().set(i, x);
     }
 
     public ValueNode valueAt(AbstractEndNode pred) {
@@ -148,15 +88,15 @@
 
     /**
      * Get the number of inputs to this phi (i.e. the number of predecessors to the merge).
-     * 
+     *
      * @return the number of inputs in this phi
      */
     public int valueCount() {
-        return values.size();
+        return values().size();
     }
 
     public void clearValues() {
-        values.clear();
+        values().clear();
     }
 
     @Override
@@ -169,24 +109,20 @@
                 }
                 str.append(valueAt(i) == null ? "-" : valueAt(i).toString(Verbosity.Id));
             }
-            if (type == PhiType.Value) {
-                return super.toString(Verbosity.Name) + "(" + str + ")";
-            } else {
-                return type + super.toString(Verbosity.Name) + "(" + str + ")";
-            }
+            return super.toString(Verbosity.Name) + "(" + str + ")";
         } else {
             return super.toString(verbosity);
         }
     }
 
     public void addInput(ValueNode x) {
-        assert !(x instanceof PhiNode) || ((PhiNode) x).merge() instanceof LoopBeginNode || ((PhiNode) x).merge() != this.merge();
-        assert x.stamp().isCompatible(stamp()) || type != PhiType.Value;
-        values.add(x);
+        assert !(x instanceof ValuePhiNode) || ((ValuePhiNode) x).merge() instanceof LoopBeginNode || ((ValuePhiNode) x).merge() != this.merge();
+        assert !(this instanceof ValuePhiNode) || x.stamp().isCompatible(stamp());
+        values().add(x);
     }
 
     public void removeInput(int index) {
-        values.remove(index);
+        values().remove(index);
     }
 
     public ValueNode singleValue() {
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ProxyNode.java	Sat Apr 05 03:18:48 2014 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ProxyNode.java	Sat Apr 05 03:19:27 2014 +0200
@@ -22,87 +22,56 @@
  */
 package com.oracle.graal.nodes;
 
+import com.oracle.graal.api.meta.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.graph.Node.ValueNumberable;
-import com.oracle.graal.graph.spi.*;
-import com.oracle.graal.nodes.PhiNode.PhiType;
 import com.oracle.graal.nodes.calc.*;
 import com.oracle.graal.nodes.extended.*;
 import com.oracle.graal.nodes.spi.*;
+import com.oracle.graal.nodes.type.*;
 
 /**
- * A value proxy that is inserted in the frame state of a loop exit for any value that is created
- * inside the loop (i.e. was not live on entry to the loop) and is (potentially) used after the
- * loop.
+ * A proxy is inserted at loop exits for any value that is created inside the loop (i.e. was not
+ * live on entry to the loop) and is (potentially) used after the loop.
  */
-@NodeInfo(nameTemplate = "{p#type/s}Proxy")
-public class ProxyNode extends FloatingNode implements IterableNodeType, ValueNumberable, Canonicalizable, Virtualizable, ValueAndStampProxy, GuardingNode {
+public abstract class ProxyNode extends FloatingNode implements IterableNodeType, ValueNumberable, ValueAndStampProxy {
 
     @Input(notDataflow = true) private AbstractBeginNode proxyPoint;
-    @Input private ValueNode value;
-    private final PhiType type;
 
-    public ProxyNode(ValueNode value, AbstractBeginNode exit, PhiType type) {
-        super(type == PhiType.Value ? value.stamp() : type.stamp);
-        this.type = type;
-        assert exit != null;
-        this.proxyPoint = exit;
-        this.value = value;
+    public ProxyNode(Stamp stamp, AbstractBeginNode proxyPoint) {
+        super(stamp);
+        assert proxyPoint != null;
+        this.proxyPoint = proxyPoint;
     }
 
-    public ValueNode value() {
-        return value;
-    }
-
-    @Override
-    public boolean inferStamp() {
-        return updateStamp(value.stamp());
-    }
+    public abstract ValueNode value();
 
     public AbstractBeginNode proxyPoint() {
         return proxyPoint;
     }
 
-    public PhiType type() {
-        return type;
-    }
-
     @Override
     public boolean verify() {
-        assert value != null;
+        assert value() != null;
         assert proxyPoint != null;
-        assert !(value instanceof ProxyNode) || ((ProxyNode) value).proxyPoint != proxyPoint;
+        assert !(value() instanceof ProxyNode) || ((ProxyNode) value()).proxyPoint != proxyPoint;
         return super.verify();
     }
 
     @Override
-    public Node canonical(CanonicalizerTool tool) {
-        if (type == PhiType.Value && value.isConstant()) {
-            return value;
-        }
-        return this;
+    public ValueNode getOriginalValue() {
+        return value();
+    }
+
+    public static MemoryProxyNode forMemory(MemoryNode value, AbstractBeginNode exit, LocationIdentity location, StructuredGraph graph) {
+        return graph.unique(new MemoryProxyNode(ValueNodeUtil.asNode(value), exit, location));
     }
 
-    @Override
-    public void virtualize(VirtualizerTool tool) {
-        if (type == PhiType.Value) {
-            State state = tool.getObjectState(value);
-            if (state != null && state.getState() == EscapeState.Virtual) {
-                tool.replaceWithVirtual(state.getVirtualObject());
-            }
-        }
+    public static ValueProxyNode forValue(ValueNode value, AbstractBeginNode exit, StructuredGraph graph) {
+        return graph.unique(new ValueProxyNode(value, exit));
     }
 
-    public static ProxyNode forGuard(ValueNode value, AbstractBeginNode exit, StructuredGraph graph) {
-        return graph.unique(new ProxyNode(value, exit, PhiType.Guard));
-    }
-
-    public static ProxyNode forValue(ValueNode value, AbstractBeginNode exit, StructuredGraph graph) {
-        return graph.unique(new ProxyNode(value, exit, PhiType.Value));
-    }
-
-    @Override
-    public ValueNode getOriginalValue() {
-        return value;
+    public static GuardProxyNode forGuard(ValueNode value, AbstractBeginNode exit, StructuredGraph graph) {
+        return graph.unique(new GuardProxyNode(value, exit));
     }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ValuePhiNode.java	Sat Apr 05 03:19:27 2014 +0200
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2009, 2014, 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.nodes;
+
+import com.oracle.graal.graph.*;
+import com.oracle.graal.graph.spi.*;
+import com.oracle.graal.nodes.type.*;
+
+/**
+ * The {@code PhiNode} represents the merging of dataflow in the graph. It refers to a merge and a
+ * variable.
+ */
+@NodeInfo(nameTemplate = "ValuePhi({i#values})")
+public class ValuePhiNode extends PhiNode implements Canonicalizable {
+
+    @Input final NodeInputList<ValueNode> values = new NodeInputList<>(this);
+
+    /**
+     * Create a value phi with the specified stamp.
+     *
+     * @param stamp the stamp of the value
+     * @param merge the merge that the new phi belongs to
+     */
+    public ValuePhiNode(Stamp stamp, MergeNode merge) {
+        super(stamp, merge);
+        assert stamp != StampFactory.forVoid();
+    }
+
+    @Override
+    public NodeInputList<ValueNode> values() {
+        return values;
+    }
+
+    @Override
+    public boolean inferStamp() {
+        return inferPhiStamp();
+    }
+
+    public boolean inferPhiStamp() {
+        return updateStamp(StampTool.meet(values()));
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ValueProxyNode.java	Sat Apr 05 03:19:27 2014 +0200
@@ -0,0 +1,63 @@
+/*
+ * 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.nodes;
+
+import com.oracle.graal.graph.*;
+import com.oracle.graal.graph.spi.*;
+import com.oracle.graal.nodes.spi.*;
+
+public class ValueProxyNode extends ProxyNode implements Canonicalizable, Virtualizable {
+
+    @Input private ValueNode value;
+
+    public ValueProxyNode(ValueNode value, AbstractBeginNode proxyPoint) {
+        super(value.stamp(), proxyPoint);
+        this.value = value;
+    }
+
+    @Override
+    public ValueNode value() {
+        return value;
+    }
+
+    @Override
+    public boolean inferStamp() {
+        return updateStamp(value.stamp());
+    }
+
+    @Override
+    public Node canonical(CanonicalizerTool tool) {
+        if (value.isConstant()) {
+            return value;
+        }
+        return this;
+    }
+
+    @Override
+    public void virtualize(VirtualizerTool tool) {
+        State state = tool.getObjectState(value);
+        if (state != null && state.getState() == EscapeState.Virtual) {
+            tool.replaceWithVirtual(state.getVirtualObject());
+        }
+    }
+}
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatConvertNode.java	Sat Apr 05 03:18:48 2014 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatConvertNode.java	Sat Apr 05 03:19:27 2014 +0200
@@ -206,7 +206,7 @@
     }
 
     public boolean generate(MemoryArithmeticLIRLowerer gen, Access access) {
-        Kind kind = access.nullCheckLocation().getValueKind();
+        Kind kind = access.accessLocation().getValueKind();
         if (kind != kind.getStackKind()) {
             // Doesn't work for subword operations
             return false;
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/SignExtendNode.java	Sat Apr 05 03:18:48 2014 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/SignExtendNode.java	Sat Apr 05 03:19:27 2014 +0200
@@ -111,7 +111,7 @@
 
     @Override
     public boolean generate(MemoryArithmeticLIRLowerer gen, Access access) {
-        Value result = gen.emitSignExtendMemory(access, access.nullCheckLocation().getValueKind().getBitCount(), getResultBits());
+        Value result = gen.emitSignExtendMemory(access, access.accessLocation().getValueKind().getBitCount(), getResultBits());
         if (result != null) {
             gen.setResult(this, result);
         }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/Access.java	Sat Apr 05 03:18:48 2014 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/Access.java	Sat Apr 05 03:19:27 2014 +0200
@@ -28,6 +28,8 @@
 
     ValueNode object();
 
-    LocationNode nullCheckLocation();
+    LocationNode accessLocation();
+
+    boolean canNullCheck();
 
 }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/FixedAccessNode.java	Sat Apr 05 03:18:48 2014 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/FixedAccessNode.java	Sat Apr 05 03:19:27 2014 +0200
@@ -27,8 +27,7 @@
 
 /**
  * Accesses a value at an memory address specified by an {@linkplain #object object} and a
- * {@linkplain #nullCheckLocation() location}. The access does not include a null check on the
- * object.
+ * {@linkplain #accessLocation() location}. The access does not include a null check on the object.
  */
 public abstract class FixedAccessNode extends DeoptimizingFixedWithNextNode implements Access, GuardingNode {
 
@@ -52,7 +51,7 @@
         return (LocationNode) location;
     }
 
-    public LocationNode nullCheckLocation() {
+    public LocationNode accessLocation() {
         return (LocationNode) location;
     }
 
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/FloatingAccessNode.java	Sat Apr 05 03:18:48 2014 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/FloatingAccessNode.java	Sat Apr 05 03:19:27 2014 +0200
@@ -41,7 +41,7 @@
         return location;
     }
 
-    public LocationNode nullCheckLocation() {
+    public LocationNode accessLocation() {
         return location;
     }
 
@@ -73,5 +73,9 @@
         return compressible;
     }
 
+    public boolean canNullCheck() {
+        return true;
+    }
+
     public abstract FixedAccessNode asFixedNode();
 }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/FloatingReadNode.java	Sat Apr 05 03:18:48 2014 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/FloatingReadNode.java	Sat Apr 05 03:19:27 2014 +0200
@@ -76,7 +76,7 @@
 
     @Override
     public FixedAccessNode asFixedNode() {
-        return graph().add(new ReadNode(object(), nullCheckLocation(), stamp(), getGuard(), getBarrierType(), isCompressible()));
+        return graph().add(new ReadNode(object(), accessLocation(), stamp(), getGuard(), getBarrierType(), isCompressible()));
     }
 
     @Override
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/JavaReadNode.java	Sat Apr 05 03:18:48 2014 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/JavaReadNode.java	Sat Apr 05 03:19:27 2014 +0200
@@ -39,4 +39,8 @@
     public void lower(LoweringTool tool) {
         tool.getLowerer().lower(this, tool);
     }
+
+    public boolean canNullCheck() {
+        return true;
+    }
 }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/JavaWriteNode.java	Sat Apr 05 03:18:48 2014 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/JavaWriteNode.java	Sat Apr 05 03:19:27 2014 +0200
@@ -38,4 +38,8 @@
     public void lower(LoweringTool tool) {
         tool.getLowerer().lower(this, tool);
     }
+
+    public boolean canNullCheck() {
+        return true;
+    }
 }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ReadNode.java	Sat Apr 05 03:18:48 2014 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ReadNode.java	Sat Apr 05 03:19:27 2014 +0200
@@ -164,4 +164,8 @@
             }
         }
     }
+
+    public boolean canNullCheck() {
+        return true;
+    }
 }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/WriteNode.java	Sat Apr 05 03:18:48 2014 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/WriteNode.java	Sat Apr 05 03:19:27 2014 +0200
@@ -82,4 +82,8 @@
             }
         }
     }
+
+    public boolean canNullCheck() {
+        return true;
+    }
 }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/LoadFieldNode.java	Sat Apr 05 03:18:48 2014 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/LoadFieldNode.java	Sat Apr 05 03:19:27 2014 +0200
@@ -41,7 +41,7 @@
 
     /**
      * Creates a new LoadFieldNode instance.
-     * 
+     *
      * @param object the receiver object
      * @param field the compiler interface field
      */
@@ -97,7 +97,7 @@
     }
 
     private PhiNode asPhi(MetaAccessProvider metaAccess) {
-        if (!isStatic() && Modifier.isFinal(field.getModifiers()) && object() instanceof PhiNode && ((PhiNode) object()).values().filter(NodePredicates.isNotA(ConstantNode.class)).isEmpty()) {
+        if (!isStatic() && Modifier.isFinal(field.getModifiers()) && object() instanceof ValuePhiNode && ((ValuePhiNode) object()).values().filter(NodePredicates.isNotA(ConstantNode.class)).isEmpty()) {
             PhiNode phi = (PhiNode) object();
             Constant[] constants = new Constant[phi.valueCount()];
             for (int i = 0; i < phi.valueCount(); i++) {
@@ -107,7 +107,7 @@
                 }
                 constants[i] = constantValue;
             }
-            PhiNode newPhi = graph().addWithoutUnique(new PhiNode(stamp(), phi.merge()));
+            PhiNode newPhi = graph().addWithoutUnique(new ValuePhiNode(stamp(), phi.merge()));
             for (int i = 0; i < phi.valueCount(); i++) {
                 newPhi.addInput(ConstantNode.forConstant(constants[i], metaAccess, graph()));
             }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/LoweredCompareAndSwapNode.java	Sat Apr 05 03:18:48 2014 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/LoweredCompareAndSwapNode.java	Sat Apr 05 03:19:27 2014 +0200
@@ -71,6 +71,10 @@
         return location().getLocationIdentity();
     }
 
+    public boolean canNullCheck() {
+        return false;
+    }
+
     @Override
     public void generate(NodeLIRBuilderTool gen) {
         gen.visitCompareAndSwap(this, location().generateAddress(gen, gen.operand(object())));
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/Stamp.java	Sat Apr 05 03:18:48 2014 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/Stamp.java	Sat Apr 05 03:19:27 2014 +0200
@@ -52,15 +52,15 @@
     public abstract Kind getStackKind();
 
     /**
-     * Gets a platform dependend {@link PlatformKind} that can be used to store a value of this
+     * Gets a platform dependent {@link PlatformKind} that can be used to store a value of this
      * stamp.
      */
     public abstract PlatformKind getPlatformKind(LIRTypeTool tool);
 
     /**
      * Returns the union of this stamp and the given stamp. Typically used to create stamps for
-     * {@link PhiNode}s.
-     * 
+     * {@link ValuePhiNode}s.
+     *
      * @param other The stamp that will enlarge this stamp.
      * @return The union of this stamp and the given stamp.
      */
@@ -68,7 +68,7 @@
 
     /**
      * Returns the intersection of this stamp and the given stamp.
-     * 
+     *
      * @param other The stamp that will tighten this stamp.
      * @return The intersection of this stamp and the given stamp.
      */
@@ -94,7 +94,7 @@
     /**
      * If this stamp represents a single value, the methods returns this single value. It returns
      * null otherwise.
-     * 
+     *
      * @return the constant corresponding to the single value of this stamp and null if this stamp
      *         can represent less or more than one value.
      */
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ConditionalEliminationPhase.java	Sat Apr 05 03:18:48 2014 +0200
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ConditionalEliminationPhase.java	Sat Apr 05 03:19:27 2014 +0200
@@ -30,7 +30,6 @@
 import com.oracle.graal.debug.Debug.Scope;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.nodes.*;
-import com.oracle.graal.nodes.PhiNode.PhiType;
 import com.oracle.graal.nodes.calc.*;
 import com.oracle.graal.nodes.extended.*;
 import com.oracle.graal.nodes.java.*;
@@ -197,7 +196,7 @@
             // this piece of code handles phis
             if (!(merge instanceof LoopBeginNode)) {
                 for (PhiNode phi : merge.phis()) {
-                    if (phi.type() == PhiType.Value && phi.getKind() == Kind.Object) {
+                    if (phi instanceof ValuePhiNode && phi.getKind() == Kind.Object) {
                         ValueNode firstValue = phi.valueAt(0);
                         ResolvedJavaType type = getNodeType(firstValue);
                         boolean nonNull = knownNonNull.contains(firstValue);
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/DeoptimizationGroupingPhase.java	Sat Apr 05 03:18:48 2014 +0200
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/DeoptimizationGroupingPhase.java	Sat Apr 05 03:19:27 2014 +0200
@@ -56,8 +56,8 @@
                     if (target instanceof AbstractDeoptimizeNode) {
                         merge = graph.add(new MergeNode());
                         EndNode firstEnd = graph.add(new EndNode());
-                        reasonActionPhi = graph.addWithoutUnique(new PhiNode(StampFactory.forKind(Kind.Int), merge));
-                        speculationPhi = graph.addWithoutUnique(new PhiNode(StampFactory.forKind(Kind.Object), merge));
+                        reasonActionPhi = graph.addWithoutUnique(new ValuePhiNode(StampFactory.forKind(Kind.Int), merge));
+                        speculationPhi = graph.addWithoutUnique(new ValuePhiNode(StampFactory.forKind(Kind.Object), merge));
                         merge.addForwardEnd(firstEnd);
                         reasonActionPhi.addInput(((AbstractDeoptimizeNode) target).getActionAndReason(context.getMetaAccess()));
                         speculationPhi.addInput(((AbstractDeoptimizeNode) target).getSpeculation(context.getMetaAccess()));
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/GuardLoweringPhase.java	Sat Apr 05 03:18:48 2014 +0200
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/GuardLoweringPhase.java	Sat Apr 05 03:19:27 2014 +0200
@@ -45,7 +45,7 @@
 /**
  * This phase lowers {@link GuardNode GuardNodes} into corresponding control-flow structure and
  * {@link DeoptimizeNode DeoptimizeNodes}.
- * 
+ *
  * This allow to enter the {@link GuardsStage#FIXED_DEOPTS FIXED_DEOPTS} stage of the graph where
  * all node that may cause deoptimization are fixed.
  * <p>
@@ -89,24 +89,26 @@
         }
 
         private void processAccess(Access access) {
-            GuardNode guard = nullGuarded.get(access.object());
-            if (guard != null && isImplicitNullCheck(access.nullCheckLocation())) {
-                metricImplicitNullCheck.increment();
-                access.setGuard(guard.getGuard());
-                FixedAccessNode fixedAccess;
-                if (access instanceof FloatingAccessNode) {
-                    fixedAccess = ((FloatingAccessNode) access).asFixedNode();
-                    replaceCurrent(fixedAccess.asNode());
-                } else {
-                    fixedAccess = (FixedAccessNode) access;
+            if (access.canNullCheck()) {
+                GuardNode guard = nullGuarded.get(access.object());
+                if (guard != null && isImplicitNullCheck(access.accessLocation())) {
+                    metricImplicitNullCheck.increment();
+                    access.setGuard(guard.getGuard());
+                    FixedAccessNode fixedAccess;
+                    if (access instanceof FloatingAccessNode) {
+                        fixedAccess = ((FloatingAccessNode) access).asFixedNode();
+                        replaceCurrent(fixedAccess);
+                    } else {
+                        fixedAccess = (FixedAccessNode) access;
+                    }
+                    fixedAccess.setNullCheck(true);
+                    LogicNode condition = guard.condition();
+                    guard.replaceAndDelete(fixedAccess);
+                    if (condition.usages().isEmpty()) {
+                        GraphUtil.killWithUnusedFloatingInputs(condition);
+                    }
+                    nullGuarded.remove(fixedAccess.object());
                 }
-                fixedAccess.setNullCheck(true);
-                LogicNode condition = guard.condition();
-                guard.replaceAndDelete(fixedAccess.asNode());
-                if (condition.usages().isEmpty()) {
-                    GraphUtil.killWithUnusedFloatingInputs(condition);
-                }
-                nullGuarded.remove(fixedAccess.object());
             }
         }
 
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningUtil.java	Sat Apr 05 03:18:48 2014 +0200
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningUtil.java	Sat Apr 05 03:19:27 2014 +0200
@@ -628,7 +628,7 @@
 
             PhiNode returnValuePhi = null;
             if (invoke.asNode().getKind() != Kind.Void) {
-                returnValuePhi = graph.addWithoutUnique(new PhiNode(invoke.asNode().stamp().unrestricted(), returnMerge));
+                returnValuePhi = graph.addWithoutUnique(new ValuePhiNode(invoke.asNode().stamp().unrestricted(), returnMerge));
             }
 
             MergeNode exceptionMerge = null;
@@ -641,7 +641,7 @@
 
                 FixedNode exceptionSux = exceptionEdge.next();
                 graph.addBeforeFixed(exceptionSux, exceptionMerge);
-                exceptionObjectPhi = graph.addWithoutUnique(new PhiNode(StampFactory.forKind(Kind.Object), exceptionMerge));
+                exceptionObjectPhi = graph.addWithoutUnique(new ValuePhiNode(StampFactory.forKind(Kind.Object), exceptionMerge));
                 exceptionMerge.setStateAfter(exceptionEdge.stateAfter().duplicateModified(invoke.stateAfter().bci, true, Kind.Object, exceptionObjectPhi));
             }
 
@@ -1489,7 +1489,7 @@
 
             if (returnNode.result() != null) {
                 if (returnValuePhi == null) {
-                    returnValuePhi = merge.graph().addWithoutUnique(new PhiNode(returnNode.result().stamp().unrestricted(), merge));
+                    returnValuePhi = merge.graph().addWithoutUnique(new ValuePhiNode(returnNode.result().stamp().unrestricted(), merge));
                 }
                 returnValuePhi.addInput(returnNode.result());
             }
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ReadEliminationPhase.java	Sat Apr 05 03:18:48 2014 +0200
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ReadEliminationPhase.java	Sat Apr 05 03:19:27 2014 +0200
@@ -60,9 +60,9 @@
             WriteNode other = (WriteNode) lastLocationAccess;
             return other.object() == n.object() && other.location() == n.location();
         }
-        if (lastLocationAccess instanceof PhiNode) {
+        if (lastLocationAccess instanceof MemoryPhiNode) {
             visited.mark(ValueNodeUtil.asNode(lastLocationAccess));
-            for (ValueNode value : ((PhiNode) lastLocationAccess).values()) {
+            for (ValueNode value : ((MemoryPhiNode) lastLocationAccess).values()) {
                 if (!isWrites(n, (MemoryNode) value, visited)) {
                     return false;
                 }
@@ -85,9 +85,9 @@
         if (lastLocationAccess instanceof WriteNode) {
             return ((WriteNode) lastLocationAccess).value();
         }
-        if (lastLocationAccess instanceof PhiNode) {
-            PhiNode phi = (PhiNode) lastLocationAccess;
-            PhiNode newPhi = phi.graph().addWithoutUnique(new PhiNode(n.stamp().unrestricted(), phi.merge()));
+        if (lastLocationAccess instanceof MemoryPhiNode) {
+            MemoryPhiNode phi = (MemoryPhiNode) lastLocationAccess;
+            ValuePhiNode newPhi = phi.graph().addWithoutUnique(new ValuePhiNode(n.stamp().unrestricted(), phi.merge()));
             nodeMap.set(phi, newPhi);
             for (ValueNode value : phi.values()) {
                 newPhi.addInput(getValue(n, (MemoryNode) value, nodeMap));
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/RemoveValueProxyPhase.java	Sat Apr 05 03:18:48 2014 +0200
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/RemoveValueProxyPhase.java	Sat Apr 05 03:19:27 2014 +0200
@@ -23,7 +23,6 @@
 package com.oracle.graal.phases.common;
 
 import com.oracle.graal.nodes.*;
-import com.oracle.graal.nodes.PhiNode.*;
 import com.oracle.graal.phases.*;
 
 public class RemoveValueProxyPhase extends Phase {
@@ -31,7 +30,7 @@
     @Override
     protected void run(StructuredGraph graph) {
         for (ProxyNode vpn : graph.getNodes(ProxyNode.class)) {
-            if (vpn.type() == PhiType.Value) {
+            if (vpn instanceof ValueProxyNode) {
                 graph.replaceFloating(vpn, vpn.value());
             }
         }
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/TailDuplicationPhase.java	Sat Apr 05 03:18:48 2014 +0200
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/TailDuplicationPhase.java	Sat Apr 05 03:19:27 2014 +0200
@@ -486,7 +486,7 @@
                             // introduce a new phi
                             PhiNode newPhi = bottomPhis.get(node);
                             if (newPhi == null) {
-                                newPhi = graph.addWithoutUnique(new PhiNode(node.stamp().unrestricted(), newBottomMerge));
+                                newPhi = graph.addWithoutUnique(new ValuePhiNode(node.stamp().unrestricted(), newBottomMerge));
                                 bottomPhis.put(node, newPhi);
                                 newPhi.addInput(node);
                             }
--- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/graph/InferStamps.java	Sat Apr 05 03:18:48 2014 +0200
+++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/graph/InferStamps.java	Sat Apr 05 03:19:27 2014 +0200
@@ -47,7 +47,7 @@
          * when the phi function performs the "meet" operator on its input stamps.
          */
         for (Node n : graph.getNodes()) {
-            if (n instanceof PhiNode || n instanceof ValueAndStampProxy) {
+            if (n instanceof ValuePhiNode || n instanceof ValueAndStampProxy) {
                 ValueNode node = (ValueNode) n;
                 if (ObjectStamp.isObject(node.stamp())) {
                     assert !(node.stamp() instanceof IllegalStamp) : "We assume all Phi and Proxy stamps are legal before the analysis";
@@ -84,7 +84,7 @@
 
     private static boolean checkNoIllegalStamp(StructuredGraph graph) {
         for (Node n : graph.getNodes()) {
-            if (n instanceof PhiNode || n instanceof ValueAndStampProxy) {
+            if (n instanceof ValuePhiNode || n instanceof ValueAndStampProxy) {
                 ValueNode node = (ValueNode) n;
                 assert !(node.stamp() instanceof IllegalStamp) : "Stamp is illegal after analysis. This is not necessarily an error, but a condition that we want to investigate (and then maybe relax or remove the assertion).";
             }
--- a/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/CFGPrinter.java	Sat Apr 05 03:18:48 2014 +0200
+++ b/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/CFGPrinter.java	Sat Apr 05 03:19:27 2014 +0200
@@ -159,7 +159,7 @@
     }
 
     private void scheduleInputs(Node node, Block nodeBlock) {
-        if (node instanceof PhiNode) {
+        if (node instanceof ValuePhiNode) {
             PhiNode phi = (PhiNode) node;
             assert nodeBlock.getBeginNode() == phi.merge();
             for (Block pred : nodeBlock.getPredecessors()) {
@@ -289,7 +289,7 @@
         assert !printedNodes.isMarked(node);
         printedNodes.mark(node);
 
-        if (!(node instanceof PhiNode)) {
+        if (!(node instanceof ValuePhiNode)) {
             for (Node input : node.inputs()) {
                 if (!inFixedSchedule(input) && !printedNodes.isMarked(input)) {
                     printNode(input, true);
--- a/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/HexCodeFile.java	Sat Apr 05 03:18:48 2014 +0200
+++ b/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/HexCodeFile.java	Sat Apr 05 03:19:27 2014 +0200
@@ -39,23 +39,23 @@
  *
  * <pre>
  *     HexCodeFile ::= Platform Delim HexCode Delim (OptionalSection Delim)*
- * 
+ *
  *     OptionalSection ::= Comment | OperandComment | JumpTable | LookupTable
- * 
+ *
  *     Platform ::= "Platform" ISA WordWidth
- * 
+ *
  *     HexCode ::= "HexCode" StartAddress HexDigits
- * 
+ *
  *     Comment ::= "Comment" Position String
- * 
+ *
  *     OperandComment ::= "OperandComment" Position String
- * 
+ *
  *     JumpTable ::= "JumpTable" Position EntrySize Low High
- * 
+ *
  *     LookupTable ::= "LookupTable" Position NPairs KeySize OffsetSize
- * 
+ *
  *     Position, EntrySize, Low, High, NPairs KeySize OffsetSize ::= int
- * 
+ *
  *     Delim := "&lt;||@"
  * </pre>
  *
@@ -184,15 +184,19 @@
      * Formats a byte array as a string of hex digits.
      */
     public static String hexCodeString(byte[] code) {
-        StringBuilder sb = new StringBuilder(code.length * 2);
-        for (int b : code) {
-            String hex = Integer.toHexString(b & 0xff);
-            if (hex.length() == 1) {
-                sb.append('0');
+        if (code == null) {
+            return "";
+        } else {
+            StringBuilder sb = new StringBuilder(code.length * 2);
+            for (int b : code) {
+                String hex = Integer.toHexString(b & 0xff);
+                if (hex.length() == 1) {
+                    sb.append('0');
+                }
+                sb.append(hex);
             }
-            sb.append(hex);
+            return sb.toString();
         }
-        return sb.toString();
     }
 
     /**
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/NodeIntrinsificationPhase.java	Sat Apr 05 03:18:48 2014 +0200
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/NodeIntrinsificationPhase.java	Sat Apr 05 03:19:27 2014 +0200
@@ -32,9 +32,10 @@
 import com.oracle.graal.debug.*;
 import com.oracle.graal.debug.internal.*;
 import com.oracle.graal.graph.*;
-import com.oracle.graal.graph.Node.*;
+import com.oracle.graal.graph.Node.ConstantNodeParameter;
+import com.oracle.graal.graph.Node.InjectedNodeParameter;
+import com.oracle.graal.graph.Node.NodeIntrinsic;
 import com.oracle.graal.nodes.*;
-import com.oracle.graal.nodes.PhiNode.PhiType;
 import com.oracle.graal.nodes.calc.*;
 import com.oracle.graal.nodes.extended.*;
 import com.oracle.graal.nodes.java.*;
@@ -387,8 +388,8 @@
             }
         } else if (usage instanceof ProxyNode) {
             ProxyNode proxy = (ProxyNode) usage;
-            assert proxy.type() == PhiType.Value;
-            ProxyNode newProxy = graph.unique(new ProxyNode((ValueNode) intrinsifiedNode, proxy.proxyPoint(), PhiType.Value));
+            assert proxy instanceof ValueProxyNode;
+            ProxyNode newProxy = ProxyNode.forValue((ValueNode) intrinsifiedNode, proxy.proxyPoint(), graph);
             for (Node proxyUsage : usage.usages().snapshot()) {
                 checkCheckCastUsage(graph, newProxy, proxy, proxyUsage);
             }
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/SnippetTemplate.java	Sat Apr 05 03:18:48 2014 +0200
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/SnippetTemplate.java	Sat Apr 05 03:19:27 2014 +0200
@@ -1110,7 +1110,7 @@
     private void propagateStamp(Node node) {
         if (node instanceof PhiNode) {
             PhiNode phi = (PhiNode) node;
-            if (phi.inferPhiStamp()) {
+            if (phi.inferStamp()) {
                 for (Node usage : node.usages()) {
                     propagateStamp(usage);
                 }
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/DirectObjectStoreNode.java	Sat Apr 05 03:18:48 2014 +0200
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/DirectObjectStoreNode.java	Sat Apr 05 03:19:27 2014 +0200
@@ -59,7 +59,9 @@
     @Override
     public void lower(LoweringTool tool) {
         IndexedLocationNode location = IndexedLocationNode.create(locationIdentity, value.getKind(), displacement, offset, graph(), 1);
-        WriteNode write = graph().add(new WriteNode(object, value, location, BarrierType.NONE, value.getKind() == Kind.Object));
+        JavaWriteNode write = graph().add(new JavaWriteNode(object, value, location, BarrierType.NONE, value.getKind() == Kind.Object, false));
         graph().replaceFixedWithFixed(this, write);
+
+        tool.getLowerer().lower(write, tool);
     }
 }
--- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PEReadEliminationClosure.java	Sat Apr 05 03:18:48 2014 +0200
+++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PEReadEliminationClosure.java	Sat Apr 05 03:19:27 2014 +0200
@@ -30,7 +30,6 @@
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.nodes.*;
-import com.oracle.graal.nodes.PhiNode.PhiType;
 import com.oracle.graal.nodes.cfg.*;
 import com.oracle.graal.nodes.extended.*;
 import com.oracle.graal.nodes.java.*;
@@ -114,7 +113,7 @@
             if (initialState.getReadCache().get(entry.getKey()) != entry.getValue()) {
                 ValueNode value = exitState.getReadCache(entry.getKey().object, entry.getKey().identity, this);
                 if (!(value instanceof ProxyNode) || ((ProxyNode) value).proxyPoint() != exitNode) {
-                    ProxyNode proxy = new ProxyNode(value, exitNode, PhiType.Value);
+                    ProxyNode proxy = new ValueProxyNode(value, exitNode);
                     effects.addFloatingNode(proxy, "readCacheProxy");
                     entry.setValue(proxy);
                 }
--- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PartialEscapeClosure.java	Sat Apr 05 03:18:48 2014 +0200
+++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PartialEscapeClosure.java	Sat Apr 05 03:19:27 2014 +0200
@@ -29,7 +29,6 @@
 import com.oracle.graal.debug.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.nodes.*;
-import com.oracle.graal.nodes.PhiNode.PhiType;
 import com.oracle.graal.nodes.VirtualState.NodeClosure;
 import com.oracle.graal.nodes.cfg.*;
 import com.oracle.graal.nodes.extended.*;
@@ -248,7 +247,7 @@
                     ValueNode value = obj.getEntry(i);
                     if (!(value instanceof VirtualObjectNode || value.isConstant())) {
                         if (exitNode.loopBegin().isPhiAtMerge(value) || initialObj == null || !initialObj.isVirtual() || initialObj.getEntry(i) != value) {
-                            ProxyNode proxy = new ProxyNode(value, exitNode, PhiType.Value);
+                            ProxyNode proxy = new ValueProxyNode(value, exitNode);
                             obj.setEntry(i, proxy);
                             effects.addFloatingNode(proxy, "virtualProxy");
                         }
@@ -258,7 +257,7 @@
                 if (initialObj == null || initialObj.isVirtual()) {
                     ProxyNode proxy = proxies.get(obj.virtual);
                     if (proxy == null) {
-                        proxy = new ProxyNode(obj.getMaterializedValue(), exitNode, PhiType.Value);
+                        proxy = new ValueProxyNode(obj.getMaterializedValue(), exitNode);
                         effects.addFloatingNode(proxy, "proxy");
                     } else {
                         effects.replaceFirstInput(proxy, proxy.value(), obj.getMaterializedValue());
@@ -281,34 +280,34 @@
 
     protected class MergeProcessor extends EffectsClosure<BlockT>.MergeProcessor {
 
-        private final HashMap<Object, PhiNode> materializedPhis = new HashMap<>();
-        private final IdentityHashMap<ValueNode, PhiNode[]> valuePhis = new IdentityHashMap<>();
-        private final IdentityHashMap<PhiNode, VirtualObjectNode> valueObjectVirtuals = new IdentityHashMap<>();
+        private final HashMap<Object, ValuePhiNode> materializedPhis = new HashMap<>();
+        private final IdentityHashMap<ValueNode, ValuePhiNode[]> valuePhis = new IdentityHashMap<>();
+        private final IdentityHashMap<ValuePhiNode, VirtualObjectNode> valueObjectVirtuals = new IdentityHashMap<>();
 
         public MergeProcessor(Block mergeBlock) {
             super(mergeBlock);
         }
 
         protected <T> PhiNode getCachedPhi(T virtual, Stamp stamp) {
-            PhiNode result = materializedPhis.get(virtual);
+            ValuePhiNode result = materializedPhis.get(virtual);
             if (result == null) {
-                result = new PhiNode(stamp, merge);
+                result = new ValuePhiNode(stamp, merge);
                 materializedPhis.put(virtual, result);
             }
             return result;
         }
 
         private PhiNode[] getValuePhis(ValueNode key, int entryCount) {
-            PhiNode[] result = valuePhis.get(key);
+            ValuePhiNode[] result = valuePhis.get(key);
             if (result == null) {
-                result = new PhiNode[entryCount];
+                result = new ValuePhiNode[entryCount];
                 valuePhis.put(key, result);
             }
             assert result.length == entryCount;
             return result;
         }
 
-        private VirtualObjectNode getValueObjectVirtual(PhiNode phi, VirtualObjectNode virtual) {
+        private VirtualObjectNode getValueObjectVirtual(ValuePhiNode phi, VirtualObjectNode virtual) {
             VirtualObjectNode result = valueObjectVirtuals.get(phi);
             if (result == null) {
                 result = virtual.duplicate();
@@ -380,8 +379,8 @@
                 }
 
                 for (PhiNode phi : merge.phis()) {
-                    if (usages.isMarked(phi) && phi.type() == PhiType.Value) {
-                        materialized |= processPhi(phi, states, virtualObjTemp);
+                    if (usages.isMarked(phi) && phi instanceof ValuePhiNode) {
+                        materialized |= processPhi((ValuePhiNode) phi, states, virtualObjTemp);
                     }
                 }
                 if (materialized) {
@@ -466,7 +465,7 @@
                     for (int i = 1; i < objStates.length; i++) {
                         ValueNode[] fields = objStates[i].getEntries();
                         if (phis[valueIndex] == null && values[valueIndex] != fields[valueIndex]) {
-                            phis[valueIndex] = new PhiNode(values[valueIndex].stamp().unrestricted(), merge);
+                            phis[valueIndex] = new ValuePhiNode(values[valueIndex].stamp().unrestricted(), merge);
                         }
                     }
                     if (twoSlotKinds != null && twoSlotKinds[valueIndex] != null) {
@@ -556,7 +555,7 @@
          *            and therefore also exist in the merged state
          * @return true if materialization happened during the merge, false otherwise
          */
-        private boolean processPhi(PhiNode phi, List<BlockT> states, Set<VirtualObjectNode> mergedVirtualObjects) {
+        private boolean processPhi(ValuePhiNode phi, List<BlockT> states, Set<VirtualObjectNode> mergedVirtualObjects) {
             aliases.set(phi, null);
             assert states.size() == phi.valueCount();
 
--- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/ReadEliminationClosure.java	Sat Apr 05 03:18:48 2014 +0200
+++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/ReadEliminationClosure.java	Sat Apr 05 03:19:27 2014 +0200
@@ -29,7 +29,6 @@
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.nodes.*;
-import com.oracle.graal.nodes.PhiNode.PhiType;
 import com.oracle.graal.nodes.cfg.*;
 import com.oracle.graal.nodes.extended.*;
 import com.oracle.graal.nodes.java.*;
@@ -175,7 +174,7 @@
     protected void processLoopExit(LoopExitNode exitNode, ReadEliminationBlockState initialState, ReadEliminationBlockState exitState, GraphEffectList effects) {
         for (Map.Entry<CacheEntry<?>, ValueNode> entry : exitState.getReadCache().entrySet()) {
             if (initialState.getReadCache().get(entry.getKey()) != entry.getValue()) {
-                ProxyNode proxy = new ProxyNode(exitState.getCacheEntry(entry.getKey()), exitNode, PhiType.Value);
+                ProxyNode proxy = new ValueProxyNode(exitState.getCacheEntry(entry.getKey()), exitNode);
                 effects.addFloatingNode(proxy, "readCacheProxy");
                 entry.setValue(proxy);
             }
@@ -194,16 +193,16 @@
 
     private class ReadEliminationMergeProcessor extends EffectsClosure<ReadEliminationBlockState>.MergeProcessor {
 
-        private final HashMap<Object, PhiNode> materializedPhis = new HashMap<>();
+        private final HashMap<Object, ValuePhiNode> materializedPhis = new HashMap<>();
 
         public ReadEliminationMergeProcessor(Block mergeBlock) {
             super(mergeBlock);
         }
 
         protected <T> PhiNode getCachedPhi(T virtual, Stamp stamp) {
-            PhiNode result = materializedPhis.get(virtual);
+            ValuePhiNode result = materializedPhis.get(virtual);
             if (result == null) {
-                result = new PhiNode(stamp, merge);
+                result = new ValuePhiNode(stamp, merge);
                 materializedPhis.put(virtual, result);
             }
             return result;
--- a/graal/com.oracle.graal.word/src/com/oracle/graal/word/phases/WordTypeVerificationPhase.java	Sat Apr 05 03:18:48 2014 +0200
+++ b/graal/com.oracle.graal.word/src/com/oracle/graal/word/phases/WordTypeVerificationPhase.java	Sat Apr 05 03:19:27 2014 +0200
@@ -90,9 +90,9 @@
                     verify(!isWord(node) || ((ObjectEqualsNode) usage).y() != node, node, usage, "cannot use word type in comparison");
                 } else if (usage instanceof ArrayLengthNode) {
                     verify(!isWord(node) || ((ArrayLengthNode) usage).array() != node, node, usage, "cannot get array length from word value");
-                } else if (usage instanceof PhiNode) {
+                } else if (usage instanceof ValuePhiNode) {
                     if (!(node instanceof MergeNode)) {
-                        PhiNode phi = (PhiNode) usage;
+                        ValuePhiNode phi = (ValuePhiNode) usage;
                         for (ValueNode input : phi.values()) {
                             verify(isWord(node) == isWord(input), node, input, "cannot merge word and non-word values");
                         }
--- a/make/bsd/makefiles/mapfile-vers-debug	Sat Apr 05 03:18:48 2014 +0200
+++ b/make/bsd/makefiles/mapfile-vers-debug	Sat Apr 05 03:19:27 2014 +0200
@@ -221,8 +221,6 @@
                 _JVM_SetLength
                 _JVM_SetNativeThreadName
                 _JVM_SetPrimitiveArrayElement
-                # Preserved so that Graal repo can link against a JDK7 libjava.so works
-                _JVM_SetProtectionDomain
                 _JVM_SetSockOpt
                 _JVM_SetThreadPriority
                 _JVM_Sleep
--- a/make/bsd/makefiles/mapfile-vers-product	Sat Apr 05 03:18:48 2014 +0200
+++ b/make/bsd/makefiles/mapfile-vers-product	Sat Apr 05 03:19:27 2014 +0200
@@ -221,8 +221,6 @@
                 _JVM_SetLength
                 _JVM_SetNativeThreadName
                 _JVM_SetPrimitiveArrayElement
-                # Preserved so that Graal repo can link against a JDK7 libjava.so works
-                _JVM_SetProtectionDomain
                 _JVM_SetSockOpt
                 _JVM_SetThreadPriority
                 _JVM_Sleep
--- a/make/linux/makefiles/mapfile-vers-debug	Sat Apr 05 03:18:48 2014 +0200
+++ b/make/linux/makefiles/mapfile-vers-debug	Sat Apr 05 03:19:27 2014 +0200
@@ -223,8 +223,6 @@
                 JVM_SetLength;
                 JVM_SetNativeThreadName;
                 JVM_SetPrimitiveArrayElement;
-                # Preserved so that Graal repo can link against a JDK7 libjava.so works
-                JVM_SetProtectionDomain;
                 JVM_SetSockOpt;
                 JVM_SetThreadPriority;
                 JVM_Sleep;
--- a/make/linux/makefiles/mapfile-vers-product	Sat Apr 05 03:18:48 2014 +0200
+++ b/make/linux/makefiles/mapfile-vers-product	Sat Apr 05 03:19:27 2014 +0200
@@ -223,8 +223,6 @@
                 JVM_SetLength;
                 JVM_SetNativeThreadName;
                 JVM_SetPrimitiveArrayElement;
-                # Preserved so that Graal repo can link against a JDK7 libjava.so works
-                JVM_SetProtectionDomain;
                 JVM_SetSockOpt;
                 JVM_SetThreadPriority;
                 JVM_Sleep;
--- a/mx/mx_graal.py	Sat Apr 05 03:18:48 2014 +0200
+++ b/mx/mx_graal.py	Sat Apr 05 03:19:27 2014 +0200
@@ -404,15 +404,6 @@
     graalJar = graalDist.path
     jdks = _jdksDir()
 
-    m2Install = mx.get_env('MAVEN_INSTALL_GRAAL_JAR', None)
-    if m2Install and m2Install.lower() == 'true':
-        cmd = ['mvn', 'install:install-file', '-q',
-               '-Dfile=' + graalJar, '-DgroupId=com.oracle.graal', '-DartifactId=graal',
-               '-Dversion=1.0-SNAPSHOT', '-Dpackaging=jar']
-        if graalDist.sourcesPath:
-            cmd = cmd + ['-Dsources=' + graalDist.sourcesPath]
-        mx.run(cmd)
-
     if exists(jdks):
         for e in os.listdir(jdks):
             jreLibDir = join(jdks, e, 'jre', 'lib')
@@ -1363,6 +1354,18 @@
 
     def _blackhole(x):
         mx.logv(x[:-1])
+
+
+    # (Re)install graal.jar into the local m2 repository since the micros-graal
+    # benchmarks have it as a dependency
+    graalDist = mx.distribution('GRAAL')
+    cmd = ['mvn', 'install:install-file', '-q',
+           '-Dfile=' + graalDist.path, '-DgroupId=com.oracle.graal', '-DartifactId=graal',
+           '-Dversion=1.0-SNAPSHOT', '-Dpackaging=jar']
+    if graalDist.sourcesPath:
+        cmd = cmd + ['-Dsources=' + graalDist.sourcesPath]
+    mx.run(cmd)
+
     mx.log("Building benchmarks...")
     mx.run(['mvn', 'package'], cwd=jmhPath, out=_blackhole)
 
--- a/mxtool/.pylintrc	Sat Apr 05 03:18:48 2014 +0200
+++ b/mxtool/.pylintrc	Sat Apr 05 03:19:27 2014 +0200
@@ -44,7 +44,7 @@
         too-many-lines,missing-docstring,no-init,no-self-use,too-many-statements,
         too-many-locals,too-few-public-methods,too-many-instance-attributes,
         too-many-arguments,too-many-branches,too-many-public-methods,
-        abstract-method,F0401
+        multiple-statements,abstract-method,F0401
 
 # F0401: http://www.logilab.org/ticket/9386
 
--- a/mxtool/mx.py	Sat Apr 05 03:18:48 2014 +0200
+++ b/mxtool/mx.py	Sat Apr 05 03:19:27 2014 +0200
@@ -65,9 +65,8 @@
         self.suite = suite
         self.name = name
         self.path = path.replace('/', os.sep)
-        self.sourcesPath = sourcesPath.replace('/', os.sep) if sourcesPath else None
-        if not isabs(self.path):
-            self.path = join(suite.dir, self.path)
+        self.path = _make_absolute(self.path, suite.dir)
+        self.sourcesPath = _make_absolute(sourcesPath.replace('/', os.sep), suite.dir) if sourcesPath else None
         self.deps = deps
         self.update_listeners = set()
         self.excludedLibs = excludedLibs
@@ -359,6 +358,14 @@
                     print >> fp, ap
         return outOfDate
 
+def _make_absolute(path, prefix):
+    """
+    Makes 'path' absolute if it isn't already by prefixing 'prefix'
+    """
+    if not isabs(path):
+        return join(prefix, path)
+    return path
+
 def _download_file_with_sha1(name, path, urls, sha1, sha1path, resolve, mustExist, sources=False):
     def _download_lib():
         print 'Downloading ' + ("Sources " if sources else "") + name + ' from ' + str(urls)
@@ -429,9 +436,7 @@
 
 
     def get_path(self, resolve):
-        path = self.path
-        if not isabs(path):
-            path = join(self.suite.dir, path)
+        path = _make_absolute(self.path, self.suite.dir)
         sha1path = path + '.sha1'
 
         includedInJDK = getattr(self, 'includedInJDK', None)
@@ -442,11 +447,9 @@
 
 
     def get_source_path(self, resolve):
-        path = self.sourcePath
-        if path is None:
+        if self.path is None:
             return None
-        if not isabs(path):
-            path = join(self.suite.dir, path)
+        path = _make_absolute(self.path, self.suite.dir)
         sha1path = path + '.sha1'
 
         return _download_file_with_sha1(self.name, path, self.sourceUrls, self.sourceSha1, sha1path, resolve, len(self.sourceUrls) != 0, sources=True)
@@ -2168,25 +2171,43 @@
     parser.add_argument('names', nargs=REMAINDER, metavar='[<project>|@<distribution>]...')
     args = parser.parse_args(args)
 
+
+    class Archive:
+        def __init__(self, path):
+            self.path = path
+
+        def __enter__(self):
+            if self.path:
+                fd, tmp = tempfile.mkstemp(suffix='', prefix=basename(self.path) + '.', dir=dirname(self.path))
+                self.tmpFd = fd
+                self.tmpPath = tmp
+                self.zf = zipfile.ZipFile(tmp, 'w')
+            else:
+                self.tmpFd = None
+                self.tmpPath = None
+                self.zf = None
+            return self
+
+        def __exit__(self, exc_type, exc_value, traceback):
+            if self.zf:
+                self.zf.close()
+                os.close(self.tmpFd)
+                # Correct the permissions on the temporary file which is created with restrictive permissions
+                os.chmod(self.tmpPath, 0o666 & ~currentUmask)
+                # Atomic on Unix
+                shutil.move(self.tmpPath, self.path)
+
     archives = []
     for name in args.names:
         if name.startswith('@'):
             dname = name[1:]
             d = distribution(dname)
-            fd, tmp = tempfile.mkstemp(suffix='', prefix=basename(d.path) + '.', dir=dirname(d.path))
-            if d.sourcesPath:
-                sourcesFd, sourcesTmp = tempfile.mkstemp(suffix='', prefix=basename(d.sourcesPath) + '.', dir=dirname(d.sourcesPath))
-            else:
-                sourcesTmp = None
-            services = tempfile.mkdtemp(suffix='', prefix=basename(d.path) + '.', dir=dirname(d.path))
-
-            def overwriteCheck(zf, arcname, source):
-                if arcname in zf.namelist():
-                    log('warning: ' + d.path + ': overwriting ' + arcname + ' [source: ' + source + ']')
-
-            try:
-                zf = zipfile.ZipFile(tmp, 'w')
-                szf = zipfile.ZipFile(sourcesTmp, 'w') if sourcesTmp else None
+            with Archive(d.path) as arc, Archive(d.sourcesPath) as srcArc:
+                services = {}
+                def overwriteCheck(zf, arcname, source):
+                    if arcname in zf.namelist():
+                        log('warning: ' + d.path + ': overwriting ' + arcname + ' [source: ' + source + ']')
+
                 for dep in d.sorted_deps(includeLibs=True):
                     if dep.isLibrary():
                         l = dep
@@ -2198,18 +2219,17 @@
                             with zipfile.ZipFile(lpath, 'r') as lp:
                                 for arcname in lp.namelist():
                                     if arcname.startswith('META-INF/services/') and not arcname == 'META-INF/services/':
-                                        f = arcname[len('META-INF/services/'):].replace('/', os.sep)
-                                        with open(join(services, f), 'a') as outfile:
-                                            for line in lp.read(arcname).splitlines():
-                                                outfile.write(line)
+                                        service = arcname[len('META-INF/services/'):]
+                                        assert '/' not in service
+                                        services.setdefault(service, []).extend(lp.read(arcname).splitlines())
                                     else:
-                                        overwriteCheck(zf, arcname, lpath + '!' + arcname)
-                                        zf.writestr(arcname, lp.read(arcname))
-                        if szf and libSourcePath:
+                                        overwriteCheck(arc.zf, arcname, lpath + '!' + arcname)
+                                        arc.zf.writestr(arcname, lp.read(arcname))
+                        if srcArc.zf and libSourcePath:
                             with zipfile.ZipFile(libSourcePath, 'r') as lp:
                                 for arcname in lp.namelist():
-                                    overwriteCheck(szf, arcname, lpath + '!' + arcname)
-                                    szf.writestr(arcname, lp.read(arcname))
+                                    overwriteCheck(srcArc.zf, arcname, lpath + '!' + arcname)
+                                    srcArc.zf.writestr(arcname, lp.read(arcname))
                     else:
                         p = dep
                         # skip a  Java project if its Java compliance level is "higher" than the configured JDK
@@ -2223,79 +2243,47 @@
                         for root, _, files in os.walk(outputDir):
                             relpath = root[len(outputDir) + 1:]
                             if relpath == join('META-INF', 'services'):
-                                for f in files:
-                                    with open(join(services, f), 'a') as outfile:
-                                        with open(join(root, f), 'r') as infile:
-                                            for line in infile:
-                                                outfile.write(line)
+                                for service in files:
+                                    with open(join(root, service), 'r') as fp:
+                                        services.setdefault(service, []).extend([provider.strip() for provider in fp.readlines()])
                             elif relpath == join('META-INF', 'providers'):
-                                for f in files:
-                                    with open(join(root, f), 'r') as infile:
-                                        for line in infile:
-                                            with open(join(services, line.strip()), 'a') as outfile:
-                                                outfile.write(f + '\n')
+                                for provider in files:
+                                    with open(join(root, provider), 'r') as fp:
+                                        for service in fp:
+                                            services.setdefault(service.strip(), []).append(provider)
                             else:
                                 for f in files:
                                     arcname = join(relpath, f).replace(os.sep, '/')
-                                    overwriteCheck(zf, arcname, join(root, f))
-                                    zf.write(join(root, f), arcname)
-                        if szf:
+                                    overwriteCheck(arc.zf, arcname, join(root, f))
+                                    arc.zf.write(join(root, f), arcname)
+                        if srcArc.zf:
                             for srcDir in p.source_dirs():
                                 for root, _, files in os.walk(srcDir):
                                     relpath = root[len(srcDir) + 1:]
                                     for f in files:
                                         if f.endswith('.java'):
                                             arcname = join(relpath, f).replace(os.sep, '/')
-                                            overwriteCheck(szf, arcname, join(root, f))
-                                            szf.write(join(root, f), arcname)
-
-                for f in os.listdir(services):
-                    arcname = join('META-INF', 'services', f).replace(os.sep, '/')
-                    zf.write(join(services, f), arcname)
-                zf.close()
-                os.close(fd)
-                shutil.rmtree(services)
-                # Atomic on Unix
-                shutil.move(tmp, d.path)
-                # Correct the permissions on the temporary file which is created with restrictive permissions
-                os.chmod(d.path, 0o666 & ~currentUmask)
-                archives.append(d.path)
-
-                if szf:
-                    szf.close()
-                    os.close(sourcesFd)
-                    shutil.move(sourcesTmp, d.sourcesPath)
-                    os.chmod(d.sourcesPath, 0o666 & ~currentUmask)
-
-                d.notify_updated()
-            finally:
-                if exists(tmp):
-                    os.remove(tmp)
-                if exists(services):
-                    shutil.rmtree(services)
+                                            overwriteCheck(srcArc.zf, arcname, join(root, f))
+                                            srcArc.zf.write(join(root, f), arcname)
+
+                for service, providers in services.iteritems():
+                    arcname = 'META-INF/services/' + service
+                    arc.zf.writestr(arcname, '\n'.join(providers))
+
+            d.notify_updated()
+            archives.append(d.path)
 
         else:
             p = project(name)
             outputDir = p.output_dir()
-            fd, tmp = tempfile.mkstemp(suffix='', prefix=p.name, dir=p.dir)
-            try:
-                zf = zipfile.ZipFile(tmp, 'w')
+            with Archive(join(p.dir, p.name + '.jar')) as arc:
                 for root, _, files in os.walk(outputDir):
                     for f in files:
                         relpath = root[len(outputDir) + 1:]
                         arcname = join(relpath, f).replace(os.sep, '/')
-                        zf.write(join(root, f), arcname)
-                zf.close()
-                os.close(fd)
-                # Atomic on Unix
-                jarFile = join(p.dir, p.name + '.jar')
-                shutil.move(tmp, jarFile)
-                # Correct the permissions on the temporary file which is created with restrictive permissions
-                os.chmod(jarFile, 0o666 & ~currentUmask)
-                archives.append(jarFile)
-            finally:
-                if exists(tmp):
-                    os.remove(tmp)
+                        arc.zf.write(join(root, f), arcname)
+                archives.append(arc.path)
+
     return archives
 
 def canonicalizeprojects(args):
@@ -2880,11 +2868,10 @@
                     if not path or (not exists(path) and not dep.mustExist):
                         continue
 
-                    if not isabs(path):
-                        # Relative paths for "lib" class path entries have various semantics depending on the Eclipse
-                        # version being used (e.g. see https://bugs.eclipse.org/bugs/show_bug.cgi?id=274737) so it's
-                        # safest to simply use absolute paths.
-                        path = join(p.suite.dir, path)
+                    # Relative paths for "lib" class path entries have various semantics depending on the Eclipse
+                    # version being used (e.g. see https://bugs.eclipse.org/bugs/show_bug.cgi?id=274737) so it's
+                    # safest to simply use absolute paths.
+                    path = _make_absolute(path, p.suite.dir)
 
                     attributes = {'exported' : 'true', 'kind' : 'lib', 'path' : path}
 
@@ -3039,11 +3026,10 @@
                             if dep.mustExist:
                                 path = dep.get_path(resolve=True)
                                 if path:
-                                    if not isabs(path):
-                                        # Relative paths for "lib" class path entries have various semantics depending on the Eclipse
-                                        # version being used (e.g. see https://bugs.eclipse.org/bugs/show_bug.cgi?id=274737) so it's
-                                        # safest to simply use absolute paths.
-                                        path = join(p.suite.dir, path)
+                                    # Relative paths for "lib" class path entries have various semantics depending on the Eclipse
+                                    # version being used (e.g. see https://bugs.eclipse.org/bugs/show_bug.cgi?id=274737) so it's
+                                    # safest to simply use absolute paths.
+                                    path = _make_absolute(path, p.suite.dir)
                                     out.element('factorypathentry', {'kind' : 'EXTJAR', 'id' : path, 'enabled' : 'true', 'runInBatchMode' : 'false'})
                                     files.append(path)
                     else:
--- a/src/cpu/sparc/vm/interpreterGenerator_sparc.hpp	Sat Apr 05 03:18:48 2014 +0200
+++ b/src/cpu/sparc/vm/interpreterGenerator_sparc.hpp	Sat Apr 05 03:19:27 2014 +0200
@@ -33,9 +33,6 @@
 
   address generate_normal_entry(bool synchronized);
   address generate_native_entry(bool synchronized);
-#ifdef GRAAL
-  address generate_execute_compiled_method_entry();
-#endif
  address generate_abstract_entry(void);
   address generate_math_entry(AbstractInterpreter::MethodKind kind);
   address generate_empty_entry(void);
--- a/src/cpu/sparc/vm/interpreter_sparc.cpp	Sat Apr 05 03:18:48 2014 +0200
+++ b/src/cpu/sparc/vm/interpreter_sparc.cpp	Sat Apr 05 03:19:27 2014 +0200
@@ -381,9 +381,6 @@
     case Interpreter::zerolocals_synchronized: synchronized = true;                                                        break;
     case Interpreter::native                 : entry_point = ((InterpreterGenerator*)this)->generate_native_entry(false);  break;
     case Interpreter::native_synchronized    : entry_point = ((InterpreterGenerator*)this)->generate_native_entry(true);   break;
-#ifdef GRAAL
-    case Interpreter::execute_compiled_method: entry_point = ((InterpreterGenerator*)this)->generate_execute_compiled_method_entry();   break;
-#endif
     case Interpreter::empty                  : entry_point = ((InterpreterGenerator*)this)->generate_empty_entry();        break;
     case Interpreter::accessor               : entry_point = ((InterpreterGenerator*)this)->generate_accessor_entry();     break;
     case Interpreter::abstract               : entry_point = ((InterpreterGenerator*)this)->generate_abstract_entry();     break;
--- a/src/cpu/sparc/vm/sharedRuntime_sparc.cpp	Sat Apr 05 03:18:48 2014 +0200
+++ b/src/cpu/sparc/vm/sharedRuntime_sparc.cpp	Sat Apr 05 03:19:27 2014 +0200
@@ -1821,31 +1821,6 @@
   verify_oop_args(masm, method, sig_bt, regs);
   vmIntrinsics::ID iid = method->intrinsic_id();
 
-#ifdef GRAAL
-  if (iid == vmIntrinsics::_CompilerToVMImpl_executeCompiledMethod) {
-    // We are called from compiled code here. The three object arguments
-    // are already in the correct registers (j_rarg0, jrarg1, jrarg2). The
-    // fourth argument (j_rarg3) is a pointer to the HotSpotInstalledCode object.
-
-    // Load the nmethod pointer from the HotSpotInstalledCode object
-//    __ movq(j_rarg3, Address(j_rarg3, sizeof(oopDesc)));
-
-    // Check whether the nmethod was invalidated
-//    __ testq(j_rarg3, j_rarg3);
-//    Label invalid_nmethod;
-//    __ jcc(Assembler::zero, invalid_nmethod);
-
-    // Perform a tail call to the verified entry point of the nmethod.
-//    __ jmp(Address(j_rarg3, nmethod::verified_entry_point_offset()));
-
-//    __ bind(invalid_nmethod);
-
-//    __ jump(RuntimeAddress(StubRoutines::throw_InvalidInstalledCodeException_entry()));
-    __ stop("_CompilerToVMImpl_executeCompiledMethod not implemented");
-    return;
-  }
-#endif
-
   // Now write the args into the outgoing interpreter space
   bool     has_receiver   = false;
   Register receiver_reg   = noreg;
--- a/src/cpu/sparc/vm/stubGenerator_sparc.cpp	Sat Apr 05 03:18:48 2014 +0200
+++ b/src/cpu/sparc/vm/stubGenerator_sparc.cpp	Sat Apr 05 03:19:27 2014 +0200
@@ -3347,7 +3347,6 @@
     // These entry points require SharedInfo::stack0 to be set up in non-core builds
     StubRoutines::_throw_AbstractMethodError_entry         = generate_throw_exception("AbstractMethodError throw_exception",          CAST_FROM_FN_PTR(address, SharedRuntime::throw_AbstractMethodError));
     StubRoutines::_throw_IncompatibleClassChangeError_entry= generate_throw_exception("IncompatibleClassChangeError throw_exception", CAST_FROM_FN_PTR(address, SharedRuntime::throw_IncompatibleClassChangeError));
-    StubRoutines::_throw_InvalidInstalledCodeException_entry= generate_throw_exception("InvalidInstalledCodeException throw_exception", CAST_FROM_FN_PTR(address, SharedRuntime::throw_InvalidInstalledCodeException));
     StubRoutines::_throw_NullPointerException_at_call_entry= generate_throw_exception("NullPointerException at call throw_exception", CAST_FROM_FN_PTR(address, SharedRuntime::throw_NullPointerException_at_call));
 
     StubRoutines::_handler_for_unsafe_access_entry =
--- a/src/cpu/sparc/vm/templateInterpreter_sparc.cpp	Sat Apr 05 03:18:48 2014 +0200
+++ b/src/cpu/sparc/vm/templateInterpreter_sparc.cpp	Sat Apr 05 03:19:27 2014 +0200
@@ -804,18 +804,6 @@
   return generate_accessor_entry();
 }
 
-#ifdef GRAAL
-
-// Interpreter stub for calling a compiled method with 3 object arguments
-address InterpreterGenerator::generate_execute_compiled_method_entry() {
-  address entry_point = __ pc();
-
-  __ stop("graal-sparc unimp");
-
-  return entry_point;
-}
-
-#endif
 
 //
 // Interpreter stub for calling a native method. (asm interpreter)
--- a/src/cpu/x86/vm/interpreterGenerator_x86.hpp	Sat Apr 05 03:18:48 2014 +0200
+++ b/src/cpu/x86/vm/interpreterGenerator_x86.hpp	Sat Apr 05 03:19:27 2014 +0200
@@ -36,9 +36,6 @@
 
   address generate_normal_entry(bool synchronized);
   address generate_native_entry(bool synchronized);
-#ifdef GRAAL
-  address generate_execute_compiled_method_entry();
-#endif
   address generate_abstract_entry(void);
   address generate_math_entry(AbstractInterpreter::MethodKind kind);
   address generate_empty_entry(void);
--- a/src/cpu/x86/vm/sharedRuntime_x86_64.cpp	Sat Apr 05 03:18:48 2014 +0200
+++ b/src/cpu/x86/vm/sharedRuntime_x86_64.cpp	Sat Apr 05 03:19:27 2014 +0200
@@ -1677,30 +1677,6 @@
   verify_oop_args(masm, method, sig_bt, regs);
   vmIntrinsics::ID iid = method->intrinsic_id();
 
-#ifdef GRAAL
-  if (iid == vmIntrinsics::_CompilerToVMImpl_executeCompiledMethod) {
-    // We are called from compiled code here. The three object arguments
-    // are already in the correct registers (j_rarg0, jrarg1, jrarg2). The
-    // fourth argument (j_rarg3) is a pointer to the HotSpotInstalledCode object.
-
-    // Load the nmethod pointer from the HotSpotInstalledCode object
-    __ movq(j_rarg4, Address(j_rarg3, sizeof(oopDesc)));
-
-    // Check whether the nmethod was invalidated
-    __ testq(j_rarg4, j_rarg4);
-    Label invalid_nmethod;
-    __ jcc(Assembler::zero, invalid_nmethod);
-
-    // Perform a tail call to the verified entry point of the nmethod.
-    __ jmp(Address(j_rarg4, nmethod::verified_entry_point_offset()));
-
-    __ bind(invalid_nmethod);
-
-    __ jump(RuntimeAddress(StubRoutines::throw_InvalidInstalledCodeException_entry()));
-    return;
-  }
-#endif
-
   // Now write the args into the outgoing interpreter space
   bool     has_receiver   = false;
   Register receiver_reg   = noreg;
--- a/src/cpu/x86/vm/stubGenerator_x86_32.cpp	Sat Apr 05 03:18:48 2014 +0200
+++ b/src/cpu/x86/vm/stubGenerator_x86_32.cpp	Sat Apr 05 03:19:27 2014 +0200
@@ -2988,7 +2988,6 @@
     // and need to be relocatable, so they each fabricate a RuntimeStub internally.
     StubRoutines::_throw_AbstractMethodError_entry         = generate_throw_exception("AbstractMethodError throw_exception",          CAST_FROM_FN_PTR(address, SharedRuntime::throw_AbstractMethodError));
     StubRoutines::_throw_IncompatibleClassChangeError_entry= generate_throw_exception("IncompatibleClassChangeError throw_exception", CAST_FROM_FN_PTR(address, SharedRuntime::throw_IncompatibleClassChangeError));
-    StubRoutines::_throw_InvalidInstalledCodeException_entry         = generate_throw_exception("InvalidInstalledCodeException throw_exception", CAST_FROM_FN_PTR(address, SharedRuntime::throw_InvalidInstalledCodeException));
     StubRoutines::_throw_NullPointerException_at_call_entry= generate_throw_exception("NullPointerException at call throw_exception", CAST_FROM_FN_PTR(address, SharedRuntime::throw_NullPointerException_at_call));
 
     //------------------------------------------------------------------------------------------------------------------------
--- a/src/cpu/x86/vm/stubGenerator_x86_64.cpp	Sat Apr 05 03:18:48 2014 +0200
+++ b/src/cpu/x86/vm/stubGenerator_x86_64.cpp	Sat Apr 05 03:19:27 2014 +0200
@@ -3860,12 +3860,6 @@
                                                 SharedRuntime::
                                                 throw_IncompatibleClassChangeError));
 
-    StubRoutines::_throw_InvalidInstalledCodeException_entry =
-      generate_throw_exception("InvalidInstalledCodeException throw_exception",
-                               CAST_FROM_FN_PTR(address,
-                                                SharedRuntime::
-                                                throw_InvalidInstalledCodeException));
-
     StubRoutines::_throw_NullPointerException_at_call_entry =
       generate_throw_exception("NullPointerException at call throw_exception",
                                CAST_FROM_FN_PTR(address,
--- a/src/cpu/x86/vm/templateInterpreter_x86_64.cpp	Sat Apr 05 03:18:48 2014 +0200
+++ b/src/cpu/x86/vm/templateInterpreter_x86_64.cpp	Sat Apr 05 03:19:27 2014 +0200
@@ -45,9 +45,6 @@
 #include "runtime/vframeArray.hpp"
 #include "utilities/debug.hpp"
 #include "utilities/macros.hpp"
-#ifdef GRAAL
-#include "graal/graalJavaAccess.hpp"
-#endif
 
 #define __ _masm->
 
@@ -852,65 +849,6 @@
   return generate_accessor_entry();
 }
 
-#ifdef GRAAL
-
-// Interpreter stub for calling a compiled method with 3 object arguments
-address InterpreterGenerator::generate_execute_compiled_method_entry() {
-  address entry_point = __ pc();
-
-  // Pick up the return address
-  __ movptr(rax, Address(rsp, 0));
-
-  // Must preserve original SP for loading incoming arguments because
-  // we need to align the outgoing SP for compiled code.
-  __ movptr(r11, rsp);
-
-  // Move first object argument from interpreter calling convention to compiled
-  // code calling convention.
-  __ movq(j_rarg0, Address(r11, Interpreter::stackElementSize*4));
-
-  // Move second object argument.
-  __ movq(j_rarg1, Address(r11, Interpreter::stackElementSize*3));
-
-  // Move third object argument.
-  __ movq(j_rarg2, Address(r11, Interpreter::stackElementSize*2));
-
-  // Load the raw pointer to the HotSpotInstalledCode object.
-  __ movq(j_rarg3, Address(r11, Interpreter::stackElementSize));
-
-  // Load the nmethod pointer from the HotSpotInstalledCode object
-  __ movq(j_rarg3, Address(j_rarg3, sizeof(oopDesc)));
-
-  // Check whether the nmethod was invalidated
-  __ testq(j_rarg3, j_rarg3);
-  Label invalid_nmethod;
-  __ jcc(Assembler::zero, invalid_nmethod);
-
-  // Ensure compiled code always sees stack at proper alignment
-  __ andptr(rsp, -16);
-
-  // push the return address and misalign the stack that youngest frame always sees
-  // as far as the placement of the call instruction
-  __ push(rax);
-
-  // Perform a tail call to the verified entry point of the nmethod.
-  __ jmp(Address(j_rarg3, nmethod::verified_entry_point_offset()));
-
-  __ bind(invalid_nmethod);
-
-  //  pop return address, reset last_sp to NULL
-  __ empty_expression_stack();
-  __ restore_bcp();      // rsi must be correct for exception handler   (was destroyed)
-  __ restore_locals();   // make sure locals pointer is correct as well (was destroyed)
-  __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::throw_InvalidInstalledCodeException));
-  // the call_VM checks for exception, so we should never return here.
-  __ should_not_reach_here();
-
-  return entry_point;
-}
-
-#endif
-
 /**
  * Method entry for static native methods:
  *   int java.util.zip.CRC32.update(int crc, int b)
@@ -1702,9 +1640,6 @@
   switch (kind) {
   case Interpreter::zerolocals             :                                                      break;
   case Interpreter::zerolocals_synchronized: synchronized = true;                                 break;
-#ifdef GRAAL
-  case Interpreter::execute_compiled_method: entry_point = ig_this->generate_execute_compiled_method_entry(); break;
-#endif
   case Interpreter::native                 : entry_point = ig_this->generate_native_entry(false); break;
   case Interpreter::native_synchronized    : entry_point = ig_this->generate_native_entry(true);  break;
   case Interpreter::empty                  : entry_point = ig_this->generate_empty_entry();       break;
--- a/src/gpu/hsail/vm/gpu_hsail.cpp	Sat Apr 05 03:18:48 2014 +0200
+++ b/src/gpu/hsail/vm/gpu_hsail.cpp	Sat Apr 05 03:19:27 2014 +0200
@@ -133,10 +133,6 @@
   }
 }
 
-
-// for experimentation
-static bool useDeoptInfo = true;
-
 jboolean Hsail::execute_kernel_void_1d_internal(address kernel, int dimX, jobject args_handle, methodHandle& mh, nmethod *nm, jobject oops_save_handle, TRAPS) {
 
   ResourceMark rm(THREAD);
@@ -145,9 +141,8 @@
   // Reset the kernel arguments
   _okra_clearargs(kernel);
 
-  
   HSAILDeoptimizationInfo* e;
-  if (useDeoptInfo) {
+  if (UseHSAILDeoptimization) {
     e = new (ResourceObj::C_HEAP, mtInternal) HSAILDeoptimizationInfo();
     e->set_never_ran_array(NEW_C_HEAP_ARRAY(jboolean, dimX, mtInternal));
     memset(e->never_ran_array(), 0, dimX * sizeof(jboolean));
@@ -168,150 +163,161 @@
   }
 
   // Run the kernel
-  bool success = _okra_execute_with_range(kernel, dimX);
-  // check if any workitem requested a deopt
-  // currently we only support at most one such workitem
-
-
-  int deoptcode = e->deopt_occurred();
-  if (useDeoptInfo &&  deoptcode != 0) {
-    if (deoptcode != 1) {
-      // error condition detected in deopt code
-      char msg[200];
-      sprintf(msg, "deopt error detected, slot for workitem %d was not empty", -1*(deoptcode + 1));
-      guarantee(deoptcode == 1, msg);
-    }
-    if (TraceGPUInteraction) {
-      tty->print_cr("deopt happened.");
-      HSAILKernelDeoptimization * pdeopt = &e->_deopt_save_states[0];
-      tty->print_cr("first deopter was workitem %d", pdeopt->workitem());
-    }
+  bool success = false;
+  {
+    TraceTime t1("execute kernel", TraceGPUInteraction);
+    success = _okra_execute_with_range(kernel, dimX);
+  }
 
-    // Before handling any deopting workitems, save the pointers from
-    // the hsail frames in oops_save so they get adjusted by any
-    // GC. Need to do this before leaving thread_in_vm mode.
-    // resolve handle only needed once here (not exiting vm mode)
-    objArrayOop oopsSaveArray = (objArrayOop) JNIHandles::resolve(oops_save_handle);
+  if (UseHSAILDeoptimization) {
+    // check if any workitem requested a deopt
+    // currently we only support at most one such workitem
+    int deoptcode = e->deopt_occurred();
+    if (deoptcode != 0) {
+      if (deoptcode != 1) {
+        // error condition detected in deopt code
+        char msg[200];
+        sprintf(msg, "deopt error detected, slot for workitem %d was not empty", -1 * (deoptcode + 1));
+        guarantee(deoptcode == 1, msg);
+      }
 
-    // since slots are allocated from the beginning, we know how far to look
-    assert(e->num_deopts() < MAX_DEOPT_SAVE_STATES_SIZE, "deopt save state overflow");
-    for (int k = 0; k < e->num_deopts(); k++) {
-      HSAILKernelDeoptimization * pdeopt = &e->_deopt_save_states[k];
-      jint workitem = pdeopt->workitem();
-      if (workitem != -1) {      
-        // this is a workitem that deopted
-        HSAILFrame *hsailFrame = pdeopt->first_frame();
-        int dregOopMap = hsailFrame->dreg_oops_map();
-        for (int bit = 0; bit < 16; bit++) {
-          if ((dregOopMap & (1 << bit)) != 0) {
-            // the dregister at this bit is an oop, save it in the array
-            int index = k * 16 + bit;
-            void* saved_oop = (void*) hsailFrame->get_d_reg(bit);
-            oopsSaveArray->obj_at_put(index, (oop) saved_oop);
-          }
-        }
-      }
-    }   
+      {
+        TraceTime t3("handle deoptimizing workitems", TraceGPUInteraction);
 
-    // Handle any deopting workitems. 
-    int count_deoptimized = 0;
-    for (int k = 0; k < e->num_deopts(); k++) {
-      HSAILKernelDeoptimization * pdeopt = &e->_deopt_save_states[k];
-    
-      jint workitem = pdeopt->workitem();
-      if (workitem != -1) {      
-        int deoptId = pdeopt->pc_offset();
-        HSAILFrame *hsailFrame = pdeopt->first_frame();
+        if (TraceGPUInteraction) {
+          tty->print_cr("deopt happened.");
+          HSAILKernelDeoptimization * pdeopt = &e->_deopt_save_states[0];
+          tty->print_cr("first deopter was workitem %d", pdeopt->workitem());
+        }
 
-        // update the hsailFrame from the oopsSaveArray
-        // re-resolve the handle
-        oopsSaveArray = (objArrayOop) JNIHandles::resolve(oops_save_handle);
+        // Before handling any deopting workitems, save the pointers from
+        // the hsail frames in oops_save so they get adjusted by any
+        // GC. Need to do this before leaving thread_in_vm mode.
+        // resolve handle only needed once here (not exiting vm mode)
+        objArrayOop oopsSaveArray = (objArrayOop) JNIHandles::resolve(oops_save_handle);
 
-        int dregOopMap = hsailFrame->dreg_oops_map();
-        for (int bit = 0; bit < 16; bit++) {
-          if ((dregOopMap & (1 << bit)) != 0) {
-            // the dregister at this bit is an oop, retrieve it from array and put back in frame
-            int index = k * 16 + bit;
-            void * dregValue = (void *) oopsSaveArray->obj_at(index);
-            void * oldDregValue = (void *) hsailFrame->get_d_reg(bit);
-            assert((oldDregValue != 0 ? dregValue != 0 : dregValue == 0) , "bad dregValue retrieved");
-            if (TraceGPUInteraction) {
-              if (dregValue != oldDregValue) {
-                tty->print_cr("oop moved for $d%d, workitem %d, slot %d, old=%p, new=%p", bit, workitem, k, oldDregValue, dregValue);
+        // since slots are allocated from the beginning, we know how far to look
+        assert(e->num_deopts() < MAX_DEOPT_SAVE_STATES_SIZE, "deopt save state overflow");
+        for (int k = 0; k < e->num_deopts(); k++) {
+          HSAILKernelDeoptimization * pdeopt = &e->_deopt_save_states[k];
+          jint workitem = pdeopt->workitem();
+          if (workitem != -1) {
+            // this is a workitem that deopted
+            HSAILFrame *hsailFrame = pdeopt->first_frame();
+            int dregOopMap = hsailFrame->dreg_oops_map();
+            for (int bit = 0; bit < 16; bit++) {
+              if ((dregOopMap & (1 << bit)) != 0) {
+                // the dregister at this bit is an oop, save it in the array
+                int index = k * 16 + bit;
+                void* saved_oop = (void*) hsailFrame->get_d_reg(bit);
+                oopsSaveArray->obj_at_put(index, (oop) saved_oop);
               }
             }
-            hsailFrame->put_d_reg(bit, (jlong) dregValue);
-          }
-        }
-       
-        JavaValue result(T_VOID);
-        JavaCallArguments javaArgs;
-        javaArgs.set_alternative_target(nm);
-        javaArgs.push_int(deoptId);
-        javaArgs.push_long((jlong) hsailFrame);
-
-        // override the deoptimization action with Action_none until we decide
-        // how to handle the other actions.
-        int myActionReason = Deoptimization::make_trap_request(Deoptimization::trap_request_reason(pdeopt->reason()), Deoptimization::Action_none);
-        javaArgs.push_int(myActionReason);
-        javaArgs.push_oop((oop)NULL);
-        if (TraceGPUInteraction) {
-          int dregOopMap = hsailFrame->dreg_oops_map();
-          tty->print_cr("[HSAIL] Deoptimizing to host for workitem=%d (slot=%d) with deoptId=%d, frame=" INTPTR_FORMAT ", actionAndReason=%d, dregOopMap=%04x", workitem, k, deoptId, hsailFrame, myActionReason, dregOopMap);
-          // show the registers containing references
-          for (int bit = 0; bit < 16; bit++) {
-            if ((dregOopMap & (1 << bit)) != 0) {
-              tty->print_cr("  oop $d%d = %p", bit, hsailFrame->get_d_reg(bit));
-            }
           }
         }
-        JavaCalls::call(&result, mh, &javaArgs, THREAD);
-        count_deoptimized++;
+
+        // Handle any deopting workitems.
+        int count_deoptimized = 0;
+        for (int k = 0; k < e->num_deopts(); k++) {
+          HSAILKernelDeoptimization * pdeopt = &e->_deopt_save_states[k];
+
+          jint workitem = pdeopt->workitem();
+          if (workitem != -1) {
+            int deoptId = pdeopt->pc_offset();
+            HSAILFrame *hsailFrame = pdeopt->first_frame();
+
+            // update the hsailFrame from the oopsSaveArray
+            // re-resolve the handle
+            oopsSaveArray = (objArrayOop) JNIHandles::resolve(oops_save_handle);
+
+            int dregOopMap = hsailFrame->dreg_oops_map();
+            for (int bit = 0; bit < 16; bit++) {
+              if ((dregOopMap & (1 << bit)) != 0) {
+                // the dregister at this bit is an oop, retrieve it from array and put back in frame
+                int index = k * 16 + bit;
+                void * dregValue = (void *) oopsSaveArray->obj_at(index);
+                void * oldDregValue = (void *) hsailFrame->get_d_reg(bit);
+                assert((oldDregValue != 0 ? dregValue != 0 : dregValue == 0), "bad dregValue retrieved");
+                if (TraceGPUInteraction) {
+                  if (dregValue != oldDregValue) {
+                    tty->print_cr("oop moved for $d%d, workitem %d, slot %d, old=%p, new=%p", bit, workitem, k, oldDregValue, dregValue);
+                  }
+                }
+                hsailFrame->put_d_reg(bit, (jlong) dregValue);
+              }
+            }
+
+            JavaValue result(T_VOID);
+            JavaCallArguments javaArgs;
+            javaArgs.set_alternative_target(nm);
+            javaArgs.push_int(deoptId);
+            javaArgs.push_long((jlong) hsailFrame);
+
+            // override the deoptimization action with Action_none until we decide
+            // how to handle the other actions.
+            int myActionReason = Deoptimization::make_trap_request(Deoptimization::trap_request_reason(pdeopt->reason()), Deoptimization::Action_none);
+            javaArgs.push_int(myActionReason);
+            javaArgs.push_oop((oop) NULL);
+            if (TraceGPUInteraction) {
+              int dregOopMap = hsailFrame->dreg_oops_map();
+              tty->print_cr("[HSAIL] Deoptimizing to host for workitem=%d (slot=%d) with deoptId=%d, frame=" INTPTR_FORMAT ", actionAndReason=%d, dregOopMap=%04x", workitem, k, deoptId, hsailFrame, myActionReason, dregOopMap);
+              // show the registers containing references
+              for (int bit = 0; bit < 16; bit++) {
+                if ((dregOopMap & (1 << bit)) != 0) {
+                  tty->print_cr("  oop $d%d = %p", bit, hsailFrame->get_d_reg(bit));
+                }
+              }
+            }
+            JavaCalls::call(&result, mh, &javaArgs, THREAD);
+            count_deoptimized++;
+          }
+        }
+        if (TraceGPUInteraction) {
+          tty->print_cr("[HSAIL] Deoptimizing to host completed for %d workitems", count_deoptimized);
+        }
       }
-    }    
-    if (TraceGPUInteraction) {
-      tty->print_cr("[HSAIL] Deoptimizing to host completed for %d workitems", count_deoptimized);
+
+      {
+        TraceTime t3("handle never-rans", TraceGPUInteraction);
+
+        // Handle any never_ran workitems if there were any
+        int count_never_ran = 0;
+        bool handleNeverRansHere = true;
+        // turn off verbose trace stuff for javacall arg setup
+        bool savedTraceGPUInteraction = TraceGPUInteraction;
+        TraceGPUInteraction = false;
+        jboolean *never_ran_array = e->never_ran_array();
+        if (handleNeverRansHere) {
+          for (int k = 0; k < dimX; k++) {
+            if (never_ran_array[k]) {
+              // run it as a javaCall
+              KlassHandle methKlass = mh->method_holder();
+              Thread* THREAD = Thread::current();
+              JavaValue result(T_VOID);
+              JavaCallArguments javaArgs;
+              // re-resolve the args_handle here
+              objArrayOop resolvedArgsArray = (objArrayOop) JNIHandles::resolve(args_handle);
+              // This object sets up the javaCall arguments
+              // the way argsArray is set up, this should work for instance methods as well
+              // (the receiver will be the first oop pushed)
+              HSAILJavaCallArguments hjca(&javaArgs, k, mh->signature(), resolvedArgsArray, mh->is_static());
+              if (mh->is_static()) {
+                JavaCalls::call_static(&result, methKlass, mh->name(), mh->signature(), &javaArgs, THREAD);
+              } else {
+                JavaCalls::call_virtual(&result, methKlass, mh->name(), mh->signature(), &javaArgs, THREAD);
+              }
+              count_never_ran++;
+            }
+          }
+          TraceGPUInteraction = savedTraceGPUInteraction;
+          if (TraceGPUInteraction) {
+            tty->print_cr("%d workitems never ran, have been run via JavaCall", count_never_ran);
+            showRanges(never_ran_array, dimX);
+          }
+        } // end of never-ran handling
+      }
     }
 
-    // Handle any never_ran workitems if there were any
-    int count_never_ran = 0;
-    bool handleNeverRansHere = true;
-    // turn off verbose trace stuff for javacall arg setup
-    bool savedTraceGPUInteraction = TraceGPUInteraction;
-    TraceGPUInteraction = false;
-    jboolean *never_ran_array = e->never_ran_array();
-    if (handleNeverRansHere) {
-      for (int k = 0; k < dimX; k++) {
-        if (never_ran_array[k]) {
-          // run it as a javaCall
-          KlassHandle methKlass = mh->method_holder();
-          Thread* THREAD = Thread::current();
-          JavaValue result(T_VOID);
-          JavaCallArguments javaArgs;
-          // re-resolve the args_handle here
-          objArrayOop resolvedArgsArray = (objArrayOop) JNIHandles::resolve(args_handle);
-          // This object sets up the javaCall arguments
-          // the way argsArray is set up, this should work for instance methods as well
-          // (the receiver will be the first oop pushed)
-          HSAILJavaCallArguments hjca(&javaArgs, k, mh->signature(), resolvedArgsArray, mh->is_static());
-          if (mh->is_static()) {
-            JavaCalls::call_static(&result, methKlass, mh->name(), mh->signature(), &javaArgs, THREAD);
-          } else {
-            JavaCalls::call_virtual(&result, methKlass, mh->name(), mh->signature(), &javaArgs, THREAD);
-          }
-          count_never_ran++;
-        }
-      }
-      TraceGPUInteraction = savedTraceGPUInteraction;
-      if (TraceGPUInteraction) {
-        tty->print_cr("%d workitems never ran, have been run via JavaCall", count_never_ran);
-        showRanges(never_ran_array, dimX);
-      }
-    } // end of never-ran handling
-
-  }
-
-  if (useDeoptInfo) {
     FREE_C_HEAP_ARRAY(jboolean, e->never_ran_array(), mtInternal);
     delete e;
   }
--- a/src/gpu/hsail/vm/hsailKernelArguments.hpp	Sat Apr 05 03:18:48 2014 +0200
+++ b/src/gpu/hsail/vm/hsailKernelArguments.hpp	Sat Apr 05 03:19:27 2014 +0200
@@ -79,11 +79,13 @@
         assert(pushed == true, "arg push failed");
     }
     virtual void pushTrailingArgs() {
-        // Last argument is the exception info block
-        if (TraceGPUInteraction) {
-            tty->print_cr("[HSAIL] exception block=" PTR_FORMAT, _exceptionHolder);
+        if (UseHSAILDeoptimization) {
+            // Last argument is the exception info block
+            if (TraceGPUInteraction) {
+                tty->print_cr("[HSAIL] exception block=" PTR_FORMAT, _exceptionHolder);
+            }
+            pushObject(_exceptionHolder);
         }
-        pushObject(_exceptionHolder);
     }
 
     // For kernel arguments we don't pass the final int parameter
--- a/src/share/vm/classfile/vmSymbols.hpp	Sat Apr 05 03:18:48 2014 +0200
+++ b/src/share/vm/classfile/vmSymbols.hpp	Sat Apr 05 03:19:27 2014 +0200
@@ -1154,9 +1154,6 @@
   do_intrinsic(_Double_valueOf,           java_lang_Double,       valueOf_name, Double_valueOf_signature, F_S)          \
    do_name(     Double_valueOf_signature,                        "(D)Ljava/lang/Double;")                               \
                                                                                                                         \
-  do_intrinsic(_CompilerToVMImpl_executeCompiledMethod,           com_oracle_graal_hotspot_bridge_CompilerToVMImpl, executeCompiledMethod_name, CompilerToVMImpl_executeCompiledMethod_signature, F_SN)\
-   do_name(     CompilerToVMImpl_executeCompiledMethod_signature, "(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Lcom/oracle/graal/hotspot/meta/HotSpotInstalledCode;)Ljava/lang/Object;")                               \
-   do_name(     executeCompiledMethod_name,                       "executeCompiledMethodIntrinsic")                     \
     /*end*/
 
 
--- a/src/share/vm/code/nmethod.cpp	Sat Apr 05 03:18:48 2014 +0200
+++ b/src/share/vm/code/nmethod.cpp	Sat Apr 05 03:19:27 2014 +0200
@@ -1972,7 +1972,7 @@
   // should not get GC'd.  Skip the first few bytes of oops on
   // not-entrant methods.
   address low_boundary = verified_entry_point();
-  if (is_not_entrant() || is_zombie()) {
+  if (is_not_entrant()) {
     low_boundary += NativeJump::instruction_size;
     // %%% Note:  On SPARC we patch only a 4-byte trap, not a full NativeJump.
     // (See comment above.)
--- a/src/share/vm/compiler/compileBroker.cpp	Sat Apr 05 03:18:48 2014 +0200
+++ b/src/share/vm/compiler/compileBroker.cpp	Sat Apr 05 03:19:27 2014 +0200
@@ -1255,7 +1255,7 @@
   assert(method->method_holder()->oop_is_instance(), "not an instance method");
   assert(osr_bci == InvocationEntryBci || (0 <= osr_bci && osr_bci < method->code_size()), "bci out of range");
   assert(!method->is_abstract() && (osr_bci == InvocationEntryBci || !method->is_native()), "cannot compile abstract/native methods");
-  assert(!method->method_holder()->is_not_initialized() || method->intrinsic_id() == vmIntrinsics::_CompilerToVMImpl_executeCompiledMethod, "method holder must be initialized");
+  assert(!method->method_holder()->is_not_initialized(), "method holder must be initialized");
   // allow any levels for WhiteBox
   assert(WhiteBoxAPI || TieredCompilation || comp_level == CompLevel_highest_tier, "only CompLevel_highest_tier must be used in non-tiered");
   // return quickly if possible
--- a/src/share/vm/graal/graalGlobals.hpp	Sat Apr 05 03:18:48 2014 +0200
+++ b/src/share/vm/graal/graalGlobals.hpp	Sat Apr 05 03:19:27 2014 +0200
@@ -85,6 +85,9 @@
   develop(bool, TraceUncollectedSpeculations, false,                        \
           "Print message when a failed speculation was not collected")      \
                                                                             \
+  product(bool, UseHSAILDeoptimization, true,                               \
+          "Code gen and runtime support for deoptimizing HSAIL kernels")    \
+                                                                            \
   product(bool, GPUOffload, false,                                          \
           "Offload execution to GPU whenever possible")                     \
                                                                             \
--- a/src/share/vm/interpreter/abstractInterpreter.hpp	Sat Apr 05 03:18:48 2014 +0200
+++ b/src/share/vm/interpreter/abstractInterpreter.hpp	Sat Apr 05 03:19:27 2014 +0200
@@ -82,9 +82,6 @@
     zerolocals_synchronized,                                    // method needs locals initialization & is synchronized
     native,                                                     // native method
     native_synchronized,                                        // native method & is synchronized
-#ifdef GRAAL
-    execute_compiled_method,                                    // direct call to compiled method address
-#endif
     empty,                                                      // empty method (code: _return)
     accessor,                                                   // accessor method (code: _aload_0, _getfield, _(a|i)return)
     abstract,                                                   // abstract method (throws an AbstractMethodException)
--- a/src/share/vm/interpreter/interpreter.cpp	Sat Apr 05 03:18:48 2014 +0200
+++ b/src/share/vm/interpreter/interpreter.cpp	Sat Apr 05 03:19:27 2014 +0200
@@ -188,13 +188,6 @@
   // Method handle primitive?
   if (m->is_method_handle_intrinsic()) {
     vmIntrinsics::ID id = m->intrinsic_id();
-#ifdef GRAAL
-    if (id == vmIntrinsics::_CompilerToVMImpl_executeCompiledMethod) {
-      // Special method kind for directly executing the verified entry point
-      // of a given nmethod.
-      return AbstractInterpreter::execute_compiled_method;
-    }
-#endif
     assert(MethodHandles::is_signature_polymorphic(id), "must match an intrinsic");
     MethodKind kind = (MethodKind)( method_handle_invoke_FIRST +
                                     ((int)id - vmIntrinsics::FIRST_MH_SIG_POLY) );
@@ -305,9 +298,6 @@
     case zerolocals_synchronized: tty->print("zerolocals_synchronized"); break;
     case native                 : tty->print("native"                 ); break;
     case native_synchronized    : tty->print("native_synchronized"    ); break;
-#ifdef GRAAL
-    case execute_compiled_method: tty->print("execute_compiled_method"); break;
-#endif
     case empty                  : tty->print("empty"                  ); break;
     case accessor               : tty->print("accessor"               ); break;
     case abstract               : tty->print("abstract"               ); break;
--- a/src/share/vm/interpreter/interpreterRuntime.cpp	Sat Apr 05 03:18:48 2014 +0200
+++ b/src/share/vm/interpreter/interpreterRuntime.cpp	Sat Apr 05 03:19:27 2014 +0200
@@ -500,11 +500,6 @@
   THROW(vmSymbols::java_lang_IncompatibleClassChangeError());
 IRT_END
 
-
-IRT_ENTRY(void, InterpreterRuntime::throw_InvalidInstalledCodeException(JavaThread* thread))
-  THROW(vmSymbols::com_oracle_graal_api_code_InvalidInstalledCodeException());
-IRT_END
-
 //------------------------------------------------------------------------------------------------------------------------
 // Fields
 //
--- a/src/share/vm/interpreter/interpreterRuntime.hpp	Sat Apr 05 03:18:48 2014 +0200
+++ b/src/share/vm/interpreter/interpreterRuntime.hpp	Sat Apr 05 03:19:27 2014 +0200
@@ -89,7 +89,6 @@
   // Exceptions thrown by the interpreter
   static void    throw_AbstractMethodError(JavaThread* thread);
   static void    throw_IncompatibleClassChangeError(JavaThread* thread);
-  static void    throw_InvalidInstalledCodeException(JavaThread* thread);
   static void    throw_StackOverflowError(JavaThread* thread);
   static void    throw_ArrayIndexOutOfBoundsException(JavaThread* thread, char* name, jint index);
   static void    throw_ClassCastException(JavaThread* thread, oopDesc* obj);
--- a/src/share/vm/interpreter/templateInterpreter.cpp	Sat Apr 05 03:18:48 2014 +0200
+++ b/src/share/vm/interpreter/templateInterpreter.cpp	Sat Apr 05 03:19:27 2014 +0200
@@ -369,9 +369,6 @@
   method_entry(zerolocals)
   method_entry(zerolocals_synchronized)
   method_entry(empty)
-#ifdef GRAAL
-  method_entry(execute_compiled_method)
-#endif
   method_entry(accessor)
   method_entry(abstract)
   method_entry(java_lang_math_sin  )
--- a/src/share/vm/oops/method.cpp	Sat Apr 05 03:18:48 2014 +0200
+++ b/src/share/vm/oops/method.cpp	Sat Apr 05 03:19:27 2014 +0200
@@ -742,13 +742,10 @@
 
 bool Method::is_always_compilable() const {
   // Generated adapters must be compiled
-  if (is_method_handle_intrinsic()) {
-    bool is_executeCompiled = intrinsic_id() == vmIntrinsics::_CompilerToVMImpl_executeCompiledMethod;
-    if (is_synthetic() || is_executeCompiled) {
-      assert(!is_not_c1_compilable() || is_executeCompiled, "sanity check");
-      assert(!is_not_c2_compilable() || is_executeCompiled, "sanity check");
-      return true;
-    }
+  if (is_method_handle_intrinsic() && is_synthetic()) {
+    assert(!is_not_c1_compilable(), "sanity check");
+    assert(!is_not_c2_compilable(), "sanity check");
+    return true;
   }
 
   return false;
@@ -892,14 +889,6 @@
 
   // ONLY USE the h_method now as make_adapter may have blocked
 
-#ifdef GRAAL
-  // Check for special intrinsic that executes a compiled method.
-  if (h_method->intrinsic_id() == vmIntrinsics::_CompilerToVMImpl_executeCompiledMethod) {
-    // Actively install the stub for calling the intrinsic from compiled code.
-    CompileBroker::compile_method(h_method, InvocationEntryBci, CompLevel_highest_tier,
-                                  methodHandle(), CompileThreshold, "executeCompiledMethod", CHECK);
-  }
-#endif
 }
 
 address Method::make_adapters(methodHandle mh, TRAPS) {
@@ -1053,7 +1042,7 @@
 bool Method::is_method_handle_intrinsic() const {
   vmIntrinsics::ID iid = intrinsic_id();
   return (MethodHandles::is_signature_polymorphic(iid) &&
-          MethodHandles::is_signature_polymorphic_intrinsic(iid)) || iid == vmIntrinsics::_CompilerToVMImpl_executeCompiledMethod;
+          MethodHandles::is_signature_polymorphic_intrinsic(iid));
 }
 
 bool Method::has_member_arg() const {
--- a/src/share/vm/prims/jvm.cpp	Sat Apr 05 03:18:48 2014 +0200
+++ b/src/share/vm/prims/jvm.cpp	Sat Apr 05 03:19:27 2014 +0200
@@ -1121,18 +1121,6 @@
   return (jobject) JNIHandles::make_local(env, pd);
 JVM_END
 
-// Preserved in Graal repo so that linking against a JDK7 libjava.so works
-JVM_ENTRY(void, JVM_SetProtectionDomain(JNIEnv *env, jclass cls, jobject protection_domain))
-  JVMWrapper("JVM_SetProtectionDomain");
-
-  ResourceMark rm(THREAD);
-  const char* msg = "Obsolete JVM_SetProtectionDomain function called";
-  size_t buflen = strlen(msg);
-  char* buf = NEW_RESOURCE_ARRAY_IN_THREAD(THREAD, char, buflen);
-  jio_snprintf(buf, buflen, msg);
-  THROW_MSG(vmSymbols::java_lang_LinkageError(), buf);
-JVM_END
-
 static bool is_authorized(Handle context, instanceKlassHandle klass, TRAPS) {
   // If there is a security manager and protection domain, check the access
   // in the protection domain, otherwise it is authorized.
--- a/src/share/vm/prims/jvm.h	Sat Apr 05 03:18:48 2014 +0200
+++ b/src/share/vm/prims/jvm.h	Sat Apr 05 03:19:27 2014 +0200
@@ -477,11 +477,6 @@
 JNIEXPORT jboolean JNICALL
 JVM_IsArrayClass(JNIEnv *env, jclass cls);
 
-// Preserved in Graal repo so that linking against a JDK7 libjava.so works
-JNIEXPORT void JNICALL
-JVM_SetProtectionDomain(JNIEnv *env, jclass cls, jobject protection_domain);
-
-
 JNIEXPORT jboolean JNICALL
 JVM_IsPrimitiveClass(JNIEnv *env, jclass cls);
 
--- a/src/share/vm/runtime/mutexLocker.cpp	Sat Apr 05 03:18:48 2014 +0200
+++ b/src/share/vm/runtime/mutexLocker.cpp	Sat Apr 05 03:19:27 2014 +0200
@@ -280,6 +280,7 @@
   def(JfrStream_lock               , Mutex,   nonleaf+2,   true);
   def(JfrStacktrace_lock           , Mutex,   special,     true );
 #endif
+
 }
 
 GCMutexLocker::GCMutexLocker(Monitor * mutex) {
--- a/src/share/vm/runtime/sharedRuntime.cpp	Sat Apr 05 03:18:48 2014 +0200
+++ b/src/share/vm/runtime/sharedRuntime.cpp	Sat Apr 05 03:19:27 2014 +0200
@@ -752,11 +752,6 @@
   throw_and_post_jvmti_exception(thread, vmSymbols::java_lang_IncompatibleClassChangeError(), "vtable stub");
 JRT_END
 
-JRT_ENTRY(void, SharedRuntime::throw_InvalidInstalledCodeException(JavaThread* thread))
-  // These errors occur only at call sites
-  throw_and_post_jvmti_exception(thread, vmSymbols::com_oracle_graal_api_code_InvalidInstalledCodeException());
-JRT_END
-
 JRT_ENTRY(void, SharedRuntime::throw_ArithmeticException(JavaThread* thread))
   throw_and_post_jvmti_exception(thread, vmSymbols::java_lang_ArithmeticException(), "/ by zero");
 JRT_END
--- a/src/share/vm/runtime/sharedRuntime.hpp	Sat Apr 05 03:18:48 2014 +0200
+++ b/src/share/vm/runtime/sharedRuntime.hpp	Sat Apr 05 03:19:27 2014 +0200
@@ -186,7 +186,6 @@
   };
   static void    throw_AbstractMethodError(JavaThread* thread);
   static void    throw_IncompatibleClassChangeError(JavaThread* thread);
-  static void    throw_InvalidInstalledCodeException(JavaThread* thread);
   static void    throw_ArithmeticException(JavaThread* thread);
   static void    throw_NullPointerException(JavaThread* thread);
   static void    throw_NullPointerException_at_call(JavaThread* thread);
--- a/src/share/vm/runtime/stubRoutines.cpp	Sat Apr 05 03:18:48 2014 +0200
+++ b/src/share/vm/runtime/stubRoutines.cpp	Sat Apr 05 03:19:27 2014 +0200
@@ -51,7 +51,6 @@
 address StubRoutines::_forward_exception_entry                  = NULL;
 address StubRoutines::_throw_AbstractMethodError_entry          = NULL;
 address StubRoutines::_throw_IncompatibleClassChangeError_entry = NULL;
-address StubRoutines::_throw_InvalidInstalledCodeException_entry = NULL;
 address StubRoutines::_throw_NullPointerException_at_call_entry = NULL;
 address StubRoutines::_throw_StackOverflowError_entry           = NULL;
 address StubRoutines::_handler_for_unsafe_access_entry          = NULL;
--- a/src/share/vm/runtime/stubRoutines.hpp	Sat Apr 05 03:18:48 2014 +0200
+++ b/src/share/vm/runtime/stubRoutines.hpp	Sat Apr 05 03:19:27 2014 +0200
@@ -128,7 +128,6 @@
   static address _catch_exception_entry;
   static address _throw_AbstractMethodError_entry;
   static address _throw_IncompatibleClassChangeError_entry;
-  static address _throw_InvalidInstalledCodeException_entry;
   static address _throw_NullPointerException_at_call_entry;
   static address _throw_StackOverflowError_entry;
   static address _handler_for_unsafe_access_entry;
@@ -273,7 +272,6 @@
   // Implicit exceptions
   static address throw_AbstractMethodError_entry()         { return _throw_AbstractMethodError_entry; }
   static address throw_IncompatibleClassChangeError_entry(){ return _throw_IncompatibleClassChangeError_entry; }
-  static address throw_InvalidInstalledCodeException_entry(){ return _throw_InvalidInstalledCodeException_entry; }
   static address throw_NullPointerException_at_call_entry(){ return _throw_NullPointerException_at_call_entry; }
   static address throw_StackOverflowError_entry()          { return _throw_StackOverflowError_entry; }