changeset 15917:7c84f0ce7cae

Merge.
author Doug Simon <doug.simon@oracle.com>
date Mon, 26 May 2014 18:55:21 +0200
parents 6aa352b260f4 (current diff) 67e0015b21d6 (diff)
children 2977687e6db0
files mx/mx_graal.py mx/projects
diffstat 31 files changed, 684 insertions(+), 113 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/Constant.java	Mon May 26 18:55:06 2014 +0200
+++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/Constant.java	Mon May 26 18:55:21 2014 +0200
@@ -63,7 +63,7 @@
         assert NULL_OBJECT.isNull();
     }
 
-    protected Constant(Kind kind) {
+    protected Constant(PlatformKind kind) {
         super(kind);
     }
 
--- a/graal/com.oracle.graal.asm/src/com/oracle/graal/asm/Buffer.java	Mon May 26 18:55:06 2014 +0200
+++ b/graal/com.oracle.graal.asm/src/com/oracle/graal/asm/Buffer.java	Mon May 26 18:55:21 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
@@ -48,7 +48,7 @@
 
     /**
      * Closes this buffer. No extra data can be written to this buffer after this call.
-     * 
+     *
      * @param trimmedCopy if {@code true}, then a copy of the underlying byte array up to (but not
      *            including) {@code position()} is returned
      * @return the data in this buffer or a trimmed copy if {@code trimmedCopy} is {@code true}
@@ -68,7 +68,7 @@
 
     /**
      * Copies the data from this buffer into a given array.
-     * 
+     *
      * @param dst the destination array
      * @param off starting position in {@code dst}
      * @param len number of bytes to copy
@@ -114,7 +114,7 @@
     }
 
     public int emitByte(int b, int pos) {
-        assert NumUtil.isUByte(b);
+        assert NumUtil.isUByte(b) || NumUtil.isByte(b);
         int newPos = pos + 1;
         ensureSize(newPos);
         data[pos] = (byte) (b & 0xFF);
@@ -139,7 +139,7 @@
 
         @Override
         public int emitShort(int b, int pos) {
-            assert NumUtil.isUShort(b);
+            assert NumUtil.isUShort(b) || NumUtil.isShort(b);
             int newPos = pos + 2;
             ensureSize(pos + 2);
             data[pos] = (byte) ((b >> 8) & 0xFF);
@@ -188,7 +188,7 @@
 
         @Override
         public int emitShort(int b, int pos) {
-            assert NumUtil.isUShort(b);
+            assert NumUtil.isUShort(b) || NumUtil.isShort(b);
             int newPos = pos + 2;
             ensureSize(newPos);
             data[pos] = (byte) (b & 0xFF);
--- a/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64LIRGenerator.java	Mon May 26 18:55:06 2014 +0200
+++ b/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64LIRGenerator.java	Mon May 26 18:55:21 2014 +0200
@@ -131,13 +131,7 @@
 
     @Override
     public Variable emitMove(Value input) {
-        PlatformKind kind;
-        if (input instanceof Constant) {
-            kind = input.getKind().getStackKind();
-        } else {
-            kind = input.getPlatformKind();
-        }
-        Variable result = newVariable(kind);
+        Variable result = newVariable(input.getPlatformKind());
         emitMove(result, input);
         return result;
     }
@@ -248,18 +242,10 @@
     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:
-            case Long:
-            case Object:
-                append(new BranchOp(finalCondition, trueLabel, falseLabel, trueLabelProbability));
-                break;
-            case Float:
-            case Double:
-                append(new FloatBranchOp(finalCondition, unorderedIsTrue, trueLabel, falseLabel, trueLabelProbability));
-                break;
-            default:
-                throw GraalInternalError.shouldNotReachHere("" + left.getKind());
+        if (cmpKind == Kind.Float || cmpKind == Kind.Double) {
+            append(new FloatBranchOp(finalCondition, unorderedIsTrue, trueLabel, falseLabel, trueLabelProbability));
+        } else {
+            append(new BranchOp(finalCondition, trueLabel, falseLabel, trueLabelProbability));
         }
     }
 
@@ -267,18 +253,10 @@
                     double trueLabelProbability) {
         boolean mirrored = emitCompareMemory(cmpKind, left, right, state);
         Condition finalCondition = mirrored ? cond.mirror() : cond;
-        switch (left.getKind().getStackKind()) {
-            case Int:
-            case Long:
-            case Object:
-                append(new BranchOp(finalCondition, trueLabel, falseLabel, trueLabelProbability));
-                break;
-            case Float:
-            case Double:
-                append(new FloatBranchOp(finalCondition, unorderedIsTrue, trueLabel, falseLabel, trueLabelProbability));
-                break;
-            default:
-                throw GraalInternalError.shouldNotReachHere("" + left.getKind());
+        if (cmpKind == Kind.Float || cmpKind == Kind.Double) {
+            append(new FloatBranchOp(finalCondition, unorderedIsTrue, trueLabel, falseLabel, trueLabelProbability));
+        } else {
+            append(new BranchOp(finalCondition, trueLabel, falseLabel, trueLabelProbability));
         }
     }
 
@@ -299,18 +277,10 @@
         Condition finalCondition = mirrored ? cond.mirror() : cond;
 
         Variable result = newVariable(trueValue.getKind());
-        switch (left.getKind().getStackKind()) {
-            case Int:
-            case Long:
-            case Object:
-                append(new CondMoveOp(result, finalCondition, load(trueValue), loadNonConst(falseValue)));
-                break;
-            case Float:
-            case Double:
-                append(new FloatCondMoveOp(result, finalCondition, unorderedIsTrue, load(trueValue), load(falseValue)));
-                break;
-            default:
-                throw GraalInternalError.shouldNotReachHere("" + left.getKind());
+        if (cmpKind == Kind.Float || cmpKind == Kind.Double) {
+            append(new FloatCondMoveOp(result, finalCondition, unorderedIsTrue, load(trueValue), load(falseValue)));
+        } else {
+            append(new CondMoveOp(result, finalCondition, load(trueValue), loadNonConst(falseValue)));
         }
         return result;
     }
@@ -376,13 +346,13 @@
             emitCompareRegMemoryOp(cmpKind, left, b, state);
             mirrored = false;
         } else {
-            emitCompareMemoryConOp(cmpKind, b, a, state);
+            emitCompareMemoryConOp(cmpKind, b, (Constant) a, state);
             mirrored = true;
         }
         return mirrored;
     }
 
-    protected void emitCompareMemoryConOp(Kind kind, AMD64AddressValue address, Value value, LIRFrameState state) {
+    protected void emitCompareMemoryConOp(Kind kind, AMD64AddressValue address, Constant value, LIRFrameState state) {
         assert kind.getStackKind() == value.getKind().getStackKind();
         switch (kind) {
             case Byte:
@@ -399,6 +369,10 @@
             case Long:
                 append(new CompareMemoryOp(LCMP, kind, address, value, state));
                 break;
+            case Object:
+                assert value.isNull();
+                append(new CompareMemoryOp(ACMP, kind, address, value, state));
+                break;
             default:
                 throw GraalInternalError.shouldNotReachHere();
         }
--- a/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/AbstractObjectStamp.java	Mon May 26 18:55:06 2014 +0200
+++ b/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/AbstractObjectStamp.java	Mon May 26 18:55:21 2014 +0200
@@ -53,6 +53,12 @@
     }
 
     @Override
+    public Stamp constant(Constant c, MetaAccessProvider meta) {
+        ResolvedJavaType constType = c.isNull() ? null : meta.lookupJavaType(c);
+        return copyWith(constType, c.isNonNull(), c.isNonNull(), c.isNull());
+    }
+
+    @Override
     public boolean isLegal() {
         return !exactType || (type != null && (isConcreteType(type)));
     }
--- a/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/FloatStamp.java	Mon May 26 18:55:06 2014 +0200
+++ b/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/FloatStamp.java	Mon May 26 18:55:21 2014 +0200
@@ -54,6 +54,12 @@
     }
 
     @Override
+    public Stamp constant(Constant c, MetaAccessProvider meta) {
+        assert c.getKind().isNumericFloat() && c.getKind().getBitCount() == getBits();
+        return StampFactory.forConstant(c);
+    }
+
+    @Override
     public boolean isLegal() {
         return lowerBound <= upperBound || !nonNaN;
     }
--- a/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/IllegalStamp.java	Mon May 26 18:55:06 2014 +0200
+++ b/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/IllegalStamp.java	Mon May 26 18:55:21 2014 +0200
@@ -55,6 +55,11 @@
     }
 
     @Override
+    public Stamp constant(Constant c, MetaAccessProvider meta) {
+        throw GraalInternalError.shouldNotReachHere("illegal stamp has no value");
+    }
+
+    @Override
     public ResolvedJavaType javaType(MetaAccessProvider metaAccess) {
         throw GraalInternalError.shouldNotReachHere("illegal stamp has no Java type");
     }
--- a/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/IntegerStamp.java	Mon May 26 18:55:06 2014 +0200
+++ b/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/IntegerStamp.java	Mon May 26 18:55:21 2014 +0200
@@ -64,6 +64,12 @@
     }
 
     @Override
+    public Stamp constant(Constant c, MetaAccessProvider meta) {
+        long value = c.asLong();
+        return StampFactory.forInteger(getBits(), value, value);
+    }
+
+    @Override
     public boolean isLegal() {
         return lowerBound <= upperBound;
     }
--- a/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/Stamp.java	Mon May 26 18:55:06 2014 +0200
+++ b/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/Stamp.java	Mon May 26 18:55:21 2014 +0200
@@ -88,6 +88,15 @@
     public abstract Stamp illegal();
 
     /**
+     * If it is possible to represent single value stamps of this kind, this method returns the
+     * stamp representing the single value c. stamp.constant(c).asConstant() should be equal to c.
+     * <p>
+     * If it is not possible to represent single value stamps, this method returns a stamp that
+     * includes c, and is otherwise as narrow as possible.
+     */
+    public abstract Stamp constant(Constant c, MetaAccessProvider meta);
+
+    /**
      * Test whether two stamps have the same base type.
      */
     public abstract boolean isCompatible(Stamp other);
--- a/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/StampFactory.java	Mon May 26 18:55:06 2014 +0200
+++ b/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/StampFactory.java	Mon May 26 18:55:21 2014 +0200
@@ -195,7 +195,6 @@
     }
 
     public static Stamp forConstant(Constant value, MetaAccessProvider metaAccess) {
-        assert value.getKind() == Kind.Object;
         if (value.getKind() == Kind.Object) {
             ResolvedJavaType type = value.isNull() ? null : metaAccess.lookupJavaType(value);
             return new ObjectStamp(type, value.isNonNull(), value.isNonNull(), value.isNull());
--- a/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/VoidStamp.java	Mon May 26 18:55:06 2014 +0200
+++ b/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/VoidStamp.java	Mon May 26 18:55:21 2014 +0200
@@ -102,6 +102,11 @@
         return true;
     }
 
+    @Override
+    public Stamp constant(Constant c, MetaAccessProvider meta) {
+        throw GraalInternalError.shouldNotReachHere("void stamp has no value");
+    }
+
     private static VoidStamp instance = new VoidStamp();
 
     static VoidStamp getInstance() {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotCompare.java	Mon May 26 18:55:21 2014 +0200
@@ -0,0 +1,150 @@
+/*
+ * Copyright (c) 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.hotspot.amd64;
+
+import static com.oracle.graal.api.code.ValueUtil.*;
+import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*;
+
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.asm.amd64.*;
+import com.oracle.graal.compiler.common.*;
+import com.oracle.graal.hotspot.data.*;
+import com.oracle.graal.hotspot.meta.*;
+import com.oracle.graal.hotspot.nodes.type.*;
+import com.oracle.graal.lir.*;
+import com.oracle.graal.lir.amd64.*;
+import com.oracle.graal.lir.amd64.AMD64Move.MemOp;
+import com.oracle.graal.lir.asm.*;
+
+public class AMD64HotSpotCompare {
+
+    @Opcode("NCMP")
+    public static class HotSpotCompareNarrowOp extends AMD64LIRInstruction {
+
+        @Use({REG}) protected AllocatableValue x;
+        @Use({REG, STACK}) protected AllocatableValue y;
+
+        public HotSpotCompareNarrowOp(AllocatableValue x, AllocatableValue y) {
+            this.x = x;
+            this.y = y;
+        }
+
+        @Override
+        public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) {
+            if (isRegister(y)) {
+                masm.cmpl(asRegister(x), asRegister(y));
+            } else {
+                assert isStackSlot(y);
+                masm.cmpl(asRegister(x), (AMD64Address) crb.asAddress(y));
+            }
+        }
+
+        @Override
+        protected void verify() {
+            assert x.getPlatformKind() == NarrowOopStamp.NarrowOop && y.getPlatformKind() == NarrowOopStamp.NarrowOop;
+        }
+    }
+
+    @Opcode("CMP")
+    public static class HotSpotCompareConstantOp extends AMD64LIRInstruction {
+
+        @Use({REG}) protected AllocatableValue x;
+        protected Constant y;
+
+        public HotSpotCompareConstantOp(AllocatableValue x, Constant y) {
+            this.x = x;
+            this.y = y;
+        }
+
+        @Override
+        public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) {
+            assert isRegister(x);
+            if (HotSpotCompressedNullConstant.COMPRESSED_NULL.equals(y)) {
+                // compressed null
+                masm.testl(asRegister(x), asRegister(x));
+            } else if (y instanceof HotSpotObjectConstant) {
+                if (HotSpotObjectConstant.isCompressed(y)) {
+                    // compressed oop
+                    crb.recordInlineDataInCode(new OopData(0, HotSpotObjectConstant.asObject(y), true));
+                    masm.cmpl(asRegister(x), 0xDEADDEAD);
+                } else {
+                    // uncompressed oop
+                    AMD64Address patch = (AMD64Address) crb.recordDataReferenceInCode(new OopData(8, HotSpotObjectConstant.asObject(y), false));
+                    masm.cmpq(asRegister(x), patch);
+                }
+            } else if (y instanceof HotSpotMetaspaceConstant) {
+                if (y.getKind() == Kind.Int) {
+                    // compressed metaspace pointer
+                    crb.recordInlineDataInCode(new MetaspaceData(0, y.asInt(), HotSpotMetaspaceConstant.getMetaspaceObject(y), true));
+                    masm.cmpl(asRegister(x), y.asInt());
+                } else {
+                    // uncompressed metaspace pointer
+                    AMD64Address patch = (AMD64Address) crb.recordDataReferenceInCode(new MetaspaceData(8, y.asLong(), HotSpotObjectConstant.asObject(y), false));
+                    masm.cmpq(asRegister(x), patch);
+                }
+            } else {
+                throw GraalInternalError.shouldNotReachHere();
+            }
+        }
+    }
+
+    @Opcode("CMP")
+    public static class HotSpotCompareMemoryConstantOp extends MemOp {
+
+        protected Constant y;
+
+        public HotSpotCompareMemoryConstantOp(Kind kind, AMD64AddressValue x, Constant y, LIRFrameState state) {
+            super(kind, x, state);
+            this.y = y;
+        }
+
+        @Override
+        protected void emitMemAccess(CompilationResultBuilder crb, AMD64MacroAssembler masm) {
+            if (HotSpotCompressedNullConstant.COMPRESSED_NULL.equals(y)) {
+                // compressed null
+                masm.cmpl(address.toAddress(), 0);
+            } else if (y instanceof HotSpotObjectConstant) {
+                if (HotSpotObjectConstant.isCompressed(y) && crb.target.inlineObjects) {
+                    // compressed oop
+                    crb.recordInlineDataInCode(new OopData(0, HotSpotObjectConstant.asObject(y), true));
+                    masm.cmpl(address.toAddress(), 0xDEADDEAD);
+                } else {
+                    // uncompressed oop
+                    throw GraalInternalError.shouldNotReachHere();
+                }
+            } else if (y instanceof HotSpotMetaspaceConstant) {
+                if (y.getKind() == Kind.Int) {
+                    // compressed metaspace pointer
+                    crb.recordInlineDataInCode(new MetaspaceData(0, y.asInt(), HotSpotMetaspaceConstant.getMetaspaceObject(y), true));
+                    masm.cmpl(address.toAddress(), y.asInt());
+                } else {
+                    // uncompressed metaspace pointer
+                    throw GraalInternalError.shouldNotReachHere();
+                }
+            } else {
+                throw GraalInternalError.shouldNotReachHere();
+            }
+        }
+    }
+
+}
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerator.java	Mon May 26 18:55:06 2014 +0200
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerator.java	Mon May 26 18:55:21 2014 +0200
@@ -39,6 +39,7 @@
 import com.oracle.graal.compiler.common.calc.*;
 import com.oracle.graal.hotspot.*;
 import com.oracle.graal.hotspot.HotSpotVMConfig.CompressEncoding;
+import com.oracle.graal.hotspot.amd64.AMD64HotSpotMove.HotSpotStoreConstantOp;
 import com.oracle.graal.hotspot.data.*;
 import com.oracle.graal.hotspot.meta.*;
 import com.oracle.graal.hotspot.nodes.*;
@@ -55,7 +56,6 @@
 import com.oracle.graal.lir.amd64.AMD64Move.LoadOp;
 import com.oracle.graal.lir.amd64.AMD64Move.MoveFromRegOp;
 import com.oracle.graal.lir.amd64.AMD64Move.MoveToRegOp;
-import com.oracle.graal.lir.amd64.AMD64Move.StoreConstantOp;
 import com.oracle.graal.lir.amd64.AMD64Move.StoreOp;
 import com.oracle.graal.lir.asm.*;
 import com.oracle.graal.lir.gen.*;
@@ -480,7 +480,7 @@
         if (isConstant(inputVal)) {
             Constant c = asConstant(inputVal);
             if (canStoreConstant(c, false)) {
-                append(new StoreConstantOp(getMemoryKind(kind), storeAddress, c, state));
+                append(new HotSpotStoreConstantOp(getMemoryKind(kind), storeAddress, c, state));
                 return;
             }
         }
@@ -499,8 +499,7 @@
             Variable result = newVariable(Kind.Int);
             AllocatableValue base = Value.ILLEGAL;
             if (encoding.base != 0) {
-                base = newVariable(Kind.Long);
-                append(new AMD64Move.MoveToRegOp(Kind.Long, base, Constant.forLong(encoding.base)));
+                base = emitMove(Constant.forLong(encoding.base));
             }
             append(new AMD64HotSpotMove.CompressPointer(result, asAllocatable(pointer), base, encoding, nonNull));
             return result;
@@ -518,8 +517,7 @@
             Variable result = newVariable(Kind.Long);
             AllocatableValue base = Value.ILLEGAL;
             if (encoding.base != 0) {
-                base = newVariable(Kind.Long);
-                append(new AMD64Move.MoveToRegOp(Kind.Long, base, Constant.forLong(encoding.base)));
+                base = emitMove(Constant.forLong(encoding.base));
             }
             append(new AMD64HotSpotMove.UncompressPointer(result, asAllocatable(pointer), base, encoding, nonNull));
             return result;
@@ -528,7 +526,9 @@
 
     @Override
     protected AMD64LIRInstruction createMove(AllocatableValue dst, Value src) {
-        if (dst.getPlatformKind() == NarrowOopStamp.NarrowOop) {
+        if (src instanceof Constant) {
+            return new AMD64HotSpotMove.HotSpotLoadConstantOp(dst, (Constant) src);
+        } else if (dst.getPlatformKind() == NarrowOopStamp.NarrowOop) {
             if (isRegister(src) || isStackSlot(dst)) {
                 return new MoveFromRegOp(Kind.Int, dst, src);
             } else {
@@ -641,4 +641,35 @@
         assert address.getKind() == Kind.Object : address + " - " + address.getKind() + " not an object!";
         append(new AMD64Move.NullCheckOp(load(address), state));
     }
+
+    @Override
+    protected void emitCompareOp(PlatformKind cmpKind, Variable left, Value right) {
+        if (right instanceof HotSpotConstant) {
+            append(new AMD64HotSpotCompare.HotSpotCompareConstantOp(left, (Constant) right));
+        } else if (cmpKind == NarrowOopStamp.NarrowOop) {
+            append(new AMD64HotSpotCompare.HotSpotCompareNarrowOp(left, asAllocatable(right)));
+        } else {
+            super.emitCompareOp(cmpKind, left, right);
+        }
+    }
+
+    @Override
+    protected void emitCompareMemoryConOp(Kind kind, AMD64AddressValue address, Constant value, LIRFrameState state) {
+        if (value instanceof HotSpotConstant) {
+            append(new AMD64HotSpotCompare.HotSpotCompareMemoryConstantOp(kind, address, value, state));
+        } else {
+            super.emitCompareMemoryConOp(kind, address, value, state);
+        }
+    }
+
+    @Override
+    public boolean canInlineConstant(Constant c) {
+        if (HotSpotCompressedNullConstant.COMPRESSED_NULL.equals(c)) {
+            return true;
+        } else if (c instanceof HotSpotObjectConstant) {
+            return HotSpotObjectConstant.isCompressed(c);
+        } else {
+            return super.canInlineConstant(c);
+        }
+    }
 }
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotMove.java	Mon May 26 18:55:06 2014 +0200
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotMove.java	Mon May 26 18:55:21 2014 +0200
@@ -36,6 +36,7 @@
 import com.oracle.graal.hotspot.data.*;
 import com.oracle.graal.hotspot.meta.*;
 import com.oracle.graal.lir.*;
+import com.oracle.graal.lir.StandardOp.MoveOp;
 import com.oracle.graal.lir.amd64.*;
 import com.oracle.graal.lir.amd64.AMD64Move.LoadOp;
 import com.oracle.graal.lir.amd64.AMD64Move.StoreConstantOp;
@@ -75,6 +76,125 @@
         }
     }
 
+    public static class HotSpotLoadConstantOp extends AMD64LIRInstruction implements MoveOp {
+
+        @Def({REG, STACK}) private AllocatableValue result;
+        private final Constant input;
+
+        public HotSpotLoadConstantOp(AllocatableValue result, Constant input) {
+            this.result = result;
+            this.input = input;
+        }
+
+        @Override
+        public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) {
+            if (HotSpotCompressedNullConstant.COMPRESSED_NULL.equals(input)) {
+                if (isRegister(result)) {
+                    masm.movl(asRegister(result), 0);
+                } else {
+                    assert isStackSlot(result);
+                    masm.movl((AMD64Address) crb.asAddress(result), 0);
+                }
+            } else if (input instanceof HotSpotObjectConstant) {
+                boolean compressed = HotSpotObjectConstant.isCompressed(input);
+                OopData data = new OopData(compressed ? 4 : 8, HotSpotObjectConstant.asObject(input), compressed);
+                if (crb.target.inlineObjects) {
+                    crb.recordInlineDataInCode(data);
+                    if (isRegister(result)) {
+                        if (compressed) {
+                            masm.movl(asRegister(result), 0xDEADDEAD);
+                        } else {
+                            masm.movq(asRegister(result), 0xDEADDEADDEADDEADL);
+                        }
+                    } else {
+                        assert isStackSlot(result);
+                        if (compressed) {
+                            masm.movl((AMD64Address) crb.asAddress(result), 0xDEADDEAD);
+                        } else {
+                            throw GraalInternalError.shouldNotReachHere("Cannot store 64-bit constants to memory");
+                        }
+                    }
+                } else {
+                    if (isRegister(result)) {
+                        AMD64Address address = (AMD64Address) crb.recordDataReferenceInCode(data);
+                        if (compressed) {
+                            masm.movl(asRegister(result), address);
+                        } else {
+                            masm.movq(asRegister(result), address);
+                        }
+                    } else {
+                        throw GraalInternalError.shouldNotReachHere("Cannot directly store data patch to memory");
+                    }
+                }
+            } else if (input instanceof HotSpotMetaspaceConstant) {
+                assert input.getKind() == Kind.Int || input.getKind() == Kind.Long;
+                boolean compressed = input.getKind() == Kind.Int;
+                MetaspaceData data = new MetaspaceData(compressed ? 4 : 8, input.asLong(), HotSpotMetaspaceConstant.getMetaspaceObject(input), compressed);
+                crb.recordInlineDataInCode(data);
+                if (isRegister(result)) {
+                    if (compressed) {
+                        masm.movl(asRegister(result), input.asInt());
+                    } else {
+                        masm.movq(asRegister(result), input.asLong());
+                    }
+                } else {
+                    assert isStackSlot(result);
+                    if (compressed) {
+                        masm.movl((AMD64Address) crb.asAddress(result), input.asInt());
+                    } else {
+                        throw GraalInternalError.shouldNotReachHere("Cannot store 64-bit constants to memory");
+                    }
+                }
+            } else {
+                AMD64Move.move(crb, masm, result, input);
+            }
+        }
+
+        public Value getInput() {
+            return input;
+        }
+
+        public AllocatableValue getResult() {
+            return result;
+        }
+    }
+
+    public static class HotSpotStoreConstantOp extends StoreConstantOp {
+
+        public HotSpotStoreConstantOp(Kind kind, AMD64AddressValue address, Constant input, LIRFrameState state) {
+            super(kind, address, input, state);
+        }
+
+        @Override
+        public void emitMemAccess(CompilationResultBuilder crb, AMD64MacroAssembler masm) {
+            if (input.isNull() && kind == Kind.Int) {
+                // compressed null
+                masm.movl(address.toAddress(), 0);
+            } else if (input instanceof HotSpotObjectConstant) {
+                if (HotSpotObjectConstant.isCompressed(input) && crb.target.inlineObjects) {
+                    // compressed oop
+                    crb.recordInlineDataInCode(new OopData(0, HotSpotObjectConstant.asObject(input), true));
+                    masm.movl(address.toAddress(), 0xDEADDEAD);
+                } else {
+                    // uncompressed oop
+                    throw GraalInternalError.shouldNotReachHere("Cannot store 64-bit constants to memory");
+                }
+            } else if (input instanceof HotSpotMetaspaceConstant) {
+                if (input.getKind() == Kind.Int) {
+                    // compressed metaspace pointer
+                    crb.recordInlineDataInCode(new MetaspaceData(0, input.asInt(), HotSpotMetaspaceConstant.getMetaspaceObject(input), true));
+                    masm.movl(address.toAddress(), input.asInt());
+                } else {
+                    // uncompressed metaspace pointer
+                    throw GraalInternalError.shouldNotReachHere("Cannot store 64-bit constants to memory");
+                }
+            } else {
+                // primitive value
+                super.emitMemAccess(crb, masm);
+            }
+        }
+    }
+
     public static class CompressPointer extends AMD64LIRInstruction {
 
         private final CompressEncoding encoding;
--- a/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotLIRGenerator.java	Mon May 26 18:55:06 2014 +0200
+++ b/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotLIRGenerator.java	Mon May 26 18:55:21 2014 +0200
@@ -122,6 +122,9 @@
         HSAILAddressValue storeAddress = asAddressValue(address);
         if (isConstant(inputVal)) {
             Constant c = asConstant(inputVal);
+            if (HotSpotCompressedNullConstant.COMPRESSED_NULL.equals(c)) {
+                c = Constant.INT_0;
+            }
             if (canStoreConstant(c, false)) {
                 append(new StoreConstantOp(getMemoryKind(kind), storeAddress, c, state));
                 return;
@@ -224,7 +227,9 @@
     @Override
     protected HSAILLIRInstruction createMove(AllocatableValue dst, Value src) {
         if (dst.getPlatformKind() == NarrowOopStamp.NarrowOop) {
-            if (isRegister(src) || isStackSlot(dst)) {
+            if (HotSpotCompressedNullConstant.COMPRESSED_NULL.equals(src)) {
+                return new MoveToRegOp(Kind.Int, dst, Constant.INT_0);
+            } else if (isRegister(src) || isStackSlot(dst)) {
                 return new MoveFromRegOp(Kind.Int, dst, src);
             } else {
                 return new MoveToRegOp(Kind.Int, dst, src);
@@ -291,5 +296,4 @@
         emitMove(obj, address);
         append(new HSAILMove.NullCheckOp(obj, state));
     }
-
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotCompressedNullConstant.java	Mon May 26 18:55:21 2014 +0200
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 2014, 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.hotspot.meta;
+
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.hotspot.nodes.type.*;
+
+/**
+ * The compressed representation of the {@link Constant#NULL_OBJECT null constant}.
+ */
+public final class HotSpotCompressedNullConstant extends Constant implements HotSpotConstant {
+
+    private static final long serialVersionUID = 8906209595800783961L;
+
+    public static final Constant COMPRESSED_NULL = new HotSpotCompressedNullConstant();
+
+    private HotSpotCompressedNullConstant() {
+        super(NarrowOopStamp.NarrowOop);
+    }
+
+    @Override
+    public boolean isNull() {
+        return true;
+    }
+
+    @Override
+    public boolean isDefaultForKind() {
+        return true;
+    }
+
+    @Override
+    public Object asBoxedPrimitive() {
+        throw new IllegalArgumentException();
+    }
+
+    @Override
+    public int asInt() {
+        throw new IllegalArgumentException();
+    }
+
+    @Override
+    public boolean asBoolean() {
+        throw new IllegalArgumentException();
+    }
+
+    @Override
+    public long asLong() {
+        throw new IllegalArgumentException();
+    }
+
+    @Override
+    public float asFloat() {
+        throw new IllegalArgumentException();
+    }
+
+    @Override
+    public double asDouble() {
+        throw new IllegalArgumentException();
+    }
+
+    @Override
+    public String toValueString() {
+        return "null";
+    }
+
+    @Override
+    public int hashCode() {
+        return System.identityHashCode(this);
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        assert o == this || !(o instanceof HotSpotCompressedNullConstant) : "null constant is a singleton";
+        return o == this;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotConstant.java	Mon May 26 18:55:21 2014 +0200
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 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.hotspot.meta;
+
+/**
+ * Marker interface for hotspot specific constants.
+ */
+public interface HotSpotConstant {
+}
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotConstantReflectionProvider.java	Mon May 26 18:55:06 2014 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotConstantReflectionProvider.java	Mon May 26 18:55:21 2014 +0200
@@ -223,7 +223,7 @@
 
     @Override
     public ResolvedJavaType asJavaType(Constant constant) {
-        if (constant.getKind() == Kind.Object) {
+        if (constant instanceof HotSpotObjectConstant) {
             Object obj = HotSpotObjectConstant.asObject(constant);
             if (obj instanceof Class) {
                 return runtime.getHostProviders().getMetaAccess().lookupJavaType((Class<?>) obj);
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMetaAccessProvider.java	Mon May 26 18:55:06 2014 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMetaAccessProvider.java	Mon May 26 18:55:21 2014 +0200
@@ -51,7 +51,7 @@
     }
 
     public ResolvedJavaType lookupJavaType(Constant constant) {
-        if (constant.getKind() != Kind.Object || constant.isNull()) {
+        if (constant.isNull() || !(constant instanceof HotSpotObjectConstant)) {
             return null;
         }
         Object o = HotSpotObjectConstant.asObject(constant);
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMetaspaceConstant.java	Mon May 26 18:55:06 2014 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMetaspaceConstant.java	Mon May 26 18:55:21 2014 +0200
@@ -26,7 +26,7 @@
 
 import com.oracle.graal.api.meta.*;
 
-public final class HotSpotMetaspaceConstant extends PrimitiveConstant {
+public final class HotSpotMetaspaceConstant extends PrimitiveConstant implements HotSpotConstant {
 
     private static final long serialVersionUID = 1003463314013122983L;
 
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotObjectConstant.java	Mon May 26 18:55:06 2014 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotObjectConstant.java	Mon May 26 18:55:21 2014 +0200
@@ -23,12 +23,13 @@
 package com.oracle.graal.hotspot.meta;
 
 import com.oracle.graal.api.meta.*;
+import com.oracle.graal.hotspot.nodes.type.*;
 
 /**
  * Represents a constant non-{@code null} object reference, within the compiler and across the
  * compiler/runtime interface.
  */
-public final class HotSpotObjectConstant extends Constant {
+public final class HotSpotObjectConstant extends Constant implements HotSpotConstant {
 
     private static final long serialVersionUID = 3592151693708093496L;
 
@@ -36,7 +37,7 @@
         if (object == null) {
             return Constant.NULL_OBJECT;
         } else {
-            return new HotSpotObjectConstant(object);
+            return new HotSpotObjectConstant(object, false);
         }
     }
 
@@ -59,21 +60,41 @@
     public static Object asBoxedValue(Constant constant) {
         if (constant.isNull()) {
             return null;
-        } else if (constant.getKind() == Kind.Object) {
+        } else if (constant instanceof HotSpotObjectConstant) {
             return ((HotSpotObjectConstant) constant).object;
         } else {
             return constant.asBoxedPrimitive();
         }
     }
 
+    public static boolean isCompressed(Constant constant) {
+        if (constant.isNull()) {
+            return HotSpotCompressedNullConstant.NULL_OBJECT.equals(constant);
+        } else {
+            return ((HotSpotObjectConstant) constant).compressed;
+        }
+    }
+
     private final Object object;
+    private final boolean compressed;
 
-    private HotSpotObjectConstant(Object object) {
-        super(Kind.Object);
+    private HotSpotObjectConstant(Object object, boolean compressed) {
+        super(compressed ? NarrowOopStamp.NarrowOop : Kind.Object);
         this.object = object;
+        this.compressed = compressed;
         assert object != null;
     }
 
+    public Constant compress() {
+        assert !compressed;
+        return new HotSpotObjectConstant(object, true);
+    }
+
+    public Constant uncompress() {
+        assert compressed;
+        return new HotSpotObjectConstant(object, false);
+    }
+
     @Override
     public boolean isNull() {
         return false;
@@ -135,6 +156,6 @@
 
     @Override
     public String toString() {
-        return getKind().getJavaName() + "[" + Kind.Object.format(object) + "]";
+        return (compressed ? "NarrowOop" : getKind().getJavaName()) + "[" + Kind.Object.format(object) + "]";
     }
 }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotSuitesProvider.java	Mon May 26 18:55:06 2014 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotSuitesProvider.java	Mon May 26 18:55:21 2014 +0200
@@ -58,7 +58,7 @@
 
         if (ImmutableCode.getValue()) {
             // lowering introduces class constants, therefore it must be after lowering
-            ret.getHighTier().appendPhase(new LoadJavaMirrorWithKlassPhase(runtime.getConfig().classMirrorOffset));
+            ret.getHighTier().appendPhase(new LoadJavaMirrorWithKlassPhase(runtime.getConfig().classMirrorOffset, runtime.getConfig().getOopEncoding()));
             if (VerifyPhases.getValue()) {
                 ret.getHighTier().appendPhase(new AheadOfTimeVerificationPhase());
             }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/CompressionNode.java	Mon May 26 18:55:06 2014 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/CompressionNode.java	Mon May 26 18:55:21 2014 +0200
@@ -29,6 +29,7 @@
 import com.oracle.graal.graph.spi.*;
 import com.oracle.graal.hotspot.*;
 import com.oracle.graal.hotspot.HotSpotVMConfig.CompressEncoding;
+import com.oracle.graal.hotspot.meta.*;
 import com.oracle.graal.hotspot.nodes.type.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.calc.*;
@@ -39,7 +40,7 @@
  * Compress or uncompress an oop or metaspace pointer.
  */
 @NodeInfo(nameTemplate = "{p#op/s}")
-public final class CompressionNode extends FloatingNode implements LIRLowerable, Canonicalizable {
+public final class CompressionNode extends ConvertNode implements LIRLowerable, Canonicalizable {
 
     private enum CompressionOp {
         Compress,
@@ -49,13 +50,10 @@
     private final CompressionOp op;
     private final CompressEncoding encoding;
 
-    @Input private ValueNode input;
-
     private CompressionNode(CompressionOp op, ValueNode input, CompressEncoding encoding) {
-        super(mkStamp(op, input.stamp(), encoding));
+        super(mkStamp(op, input.stamp(), encoding), input);
         this.op = op;
         this.encoding = encoding;
-        this.input = input;
     }
 
     public static CompressionNode compress(ValueNode input, CompressEncoding encoding) {
@@ -66,6 +64,61 @@
         return input.graph().unique(new CompressionNode(CompressionOp.Uncompress, input, encoding));
     }
 
+    private static Constant compress(Constant c, CompressEncoding encoding) {
+        if (Constant.NULL_OBJECT.equals(c)) {
+            return HotSpotCompressedNullConstant.COMPRESSED_NULL;
+        } else if (c instanceof HotSpotObjectConstant) {
+            return ((HotSpotObjectConstant) c).compress();
+        } else if (c instanceof HotSpotMetaspaceConstant) {
+            assert c.getKind() == Kind.Long;
+            return HotSpotMetaspaceConstant.forMetaspaceObject(Kind.Int, encoding.compress(c.asLong()), HotSpotMetaspaceConstant.getMetaspaceObject(c));
+        } else {
+            throw GraalInternalError.shouldNotReachHere("invalid constant input for compress op: " + c);
+        }
+    }
+
+    private static Constant uncompress(Constant c, CompressEncoding encoding) {
+        if (HotSpotCompressedNullConstant.COMPRESSED_NULL.equals(c)) {
+            return Constant.NULL_OBJECT;
+        } else if (c instanceof HotSpotObjectConstant) {
+            return ((HotSpotObjectConstant) c).uncompress();
+        } else if (c instanceof HotSpotMetaspaceConstant) {
+            assert c.getKind() == Kind.Int;
+            return HotSpotMetaspaceConstant.forMetaspaceObject(Kind.Long, encoding.uncompress(c.asInt()), HotSpotMetaspaceConstant.getMetaspaceObject(c));
+        } else {
+            throw GraalInternalError.shouldNotReachHere("invalid constant input for uncompress op: " + c);
+        }
+    }
+
+    @Override
+    public Constant convert(Constant c) {
+        switch (op) {
+            case Compress:
+                return compress(c, encoding);
+            case Uncompress:
+                return uncompress(c, encoding);
+            default:
+                throw GraalInternalError.shouldNotReachHere();
+        }
+    }
+
+    @Override
+    public Constant reverse(Constant c) {
+        switch (op) {
+            case Compress:
+                return uncompress(c, encoding);
+            case Uncompress:
+                return compress(c, encoding);
+            default:
+                throw GraalInternalError.shouldNotReachHere();
+        }
+    }
+
+    @Override
+    public boolean isLossless() {
+        return true;
+    }
+
     private static Stamp mkStamp(CompressionOp op, Stamp input, CompressEncoding encoding) {
         switch (op) {
             case Compress:
@@ -93,20 +146,18 @@
         throw GraalInternalError.shouldNotReachHere(String.format("Unexpected input stamp %s", input));
     }
 
-    public ValueNode getInput() {
-        return input;
-    }
-
     public CompressEncoding getEncoding() {
         return encoding;
     }
 
     @Override
     public Node canonical(CanonicalizerTool tool) {
-        if (input instanceof CompressionNode) {
-            CompressionNode other = (CompressionNode) input;
+        if (getInput().isConstant()) {
+            return ConstantNode.forConstant(stamp(), evalConst(getInput().asConstant()), tool.getMetaAccess(), graph());
+        } else if (getInput() instanceof CompressionNode) {
+            CompressionNode other = (CompressionNode) getInput();
             if (op != other.op && encoding.equals(other.encoding)) {
-                return other.input;
+                return other.getInput();
             }
         }
         return this;
@@ -116,8 +167,8 @@
     public void generate(NodeLIRBuilderTool gen) {
         HotSpotLIRGenerator hsGen = (HotSpotLIRGenerator) gen.getLIRGeneratorTool();
         boolean nonNull;
-        if (input.stamp() instanceof ObjectStamp) {
-            nonNull = StampTool.isObjectNonNull(input.stamp());
+        if (getInput().stamp() instanceof ObjectStamp) {
+            nonNull = StampTool.isObjectNonNull(getInput().stamp());
         } else {
             // metaspace pointers are never null
             nonNull = true;
@@ -126,10 +177,10 @@
         Value result;
         switch (op) {
             case Compress:
-                result = hsGen.emitCompress(gen.operand(input), encoding, nonNull);
+                result = hsGen.emitCompress(gen.operand(getInput()), encoding, nonNull);
                 break;
             case Uncompress:
-                result = hsGen.emitUncompress(gen.operand(input), encoding, nonNull);
+                result = hsGen.emitUncompress(gen.operand(getInput()), encoding, nonNull);
                 break;
             default:
                 throw GraalInternalError.shouldNotReachHere();
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/phases/LoadJavaMirrorWithKlassPhase.java	Mon May 26 18:55:06 2014 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/phases/LoadJavaMirrorWithKlassPhase.java	Mon May 26 18:55:21 2014 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 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
@@ -27,7 +27,9 @@
 
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.compiler.common.type.*;
+import com.oracle.graal.hotspot.HotSpotVMConfig.*;
 import com.oracle.graal.hotspot.meta.*;
+import com.oracle.graal.hotspot.nodes.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.extended.*;
 import com.oracle.graal.phases.*;
@@ -39,22 +41,24 @@
  * directly. Instead the {@link Class} reference should be obtained from the {@code Klass} object.
  * The reason for this is, that in Class Data Sharing (CDS) a {@code Klass} object is mapped to a
  * fixed address in memory, but the {@code javaMirror} is not (which lives in the Java heap).
- * 
+ *
  * Lowering can introduce new {@link ConstantNode}s containing a {@link Class} reference, thus this
  * phase must be applied after {@link LoweringPhase}.
- * 
+ *
  * @see AheadOfTimeVerificationPhase
  */
 public class LoadJavaMirrorWithKlassPhase extends BasePhase<PhaseContext> {
 
     private final int classMirrorOffset;
+    private final CompressEncoding oopEncoding;
 
-    public LoadJavaMirrorWithKlassPhase(int classMirrorOffset) {
+    public LoadJavaMirrorWithKlassPhase(int classMirrorOffset, CompressEncoding oopEncoding) {
         this.classMirrorOffset = classMirrorOffset;
+        this.oopEncoding = oopEncoding;
     }
 
-    private FloatingReadNode getClassConstantReplacement(StructuredGraph graph, PhaseContext context, Constant constant) {
-        if (constant.getKind() == Kind.Object && HotSpotObjectConstant.asObject(constant) instanceof Class<?>) {
+    private ValueNode getClassConstantReplacement(StructuredGraph graph, PhaseContext context, Constant constant) {
+        if (constant instanceof HotSpotObjectConstant && HotSpotObjectConstant.asObject(constant) instanceof Class<?>) {
             MetaAccessProvider metaAccess = context.getMetaAccess();
             ResolvedJavaType type = metaAccess.lookupJavaType((Class<?>) HotSpotObjectConstant.asObject(constant));
             assert type instanceof HotSpotResolvedObjectType;
@@ -65,7 +69,12 @@
             Stamp stamp = StampFactory.exactNonNull(metaAccess.lookupJavaType(Class.class));
             LocationNode location = ConstantLocationNode.create(FINAL_LOCATION, Kind.Object, classMirrorOffset, graph);
             FloatingReadNode freadNode = graph.unique(new FloatingReadNode(klassNode, location, null, stamp));
-            return freadNode;
+
+            if (HotSpotObjectConstant.isCompressed(constant)) {
+                return CompressionNode.compress(freadNode, oopEncoding);
+            } else {
+                return freadNode;
+            }
         }
         return null;
     }
@@ -74,7 +83,7 @@
     protected void run(StructuredGraph graph, PhaseContext context) {
         for (ConstantNode node : getConstantNodes(graph)) {
             Constant constant = node.asConstant();
-            FloatingReadNode freadNode = getClassConstantReplacement(graph, context, constant);
+            ValueNode freadNode = getClassConstantReplacement(graph, context, constant);
             if (freadNode != null) {
                 node.replace(graph, freadNode);
             }
--- a/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Compare.java	Mon May 26 18:55:06 2014 +0200
+++ b/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Compare.java	Mon May 26 18:55:21 2014 +0200
@@ -84,7 +84,7 @@
         }
 
         @Override
-        public void emitMemAccess(CompilationResultBuilder crb, AMD64MacroAssembler masm) {
+        protected void emitMemAccess(CompilationResultBuilder crb, AMD64MacroAssembler masm) {
             if (isRegister(y)) {
                 switch (opcode) {
                     case BCMP:
@@ -129,6 +129,13 @@
                             throw GraalInternalError.shouldNotReachHere();
                         }
                         break;
+                    case ACMP:
+                        if (asConstant(y).isNull()) {
+                            masm.cmpq(address.toAddress(), 0);
+                        } else {
+                            throw GraalInternalError.shouldNotReachHere();
+                        }
+                        break;
                     default:
                         throw GraalInternalError.shouldNotReachHere();
                 }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ConstantNode.java	Mon May 26 18:55:06 2014 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ConstantNode.java	Mon May 26 18:55:21 2014 +0200
@@ -153,13 +153,7 @@
     }
 
     public static ConstantNode forConstant(Stamp stamp, Constant constant, MetaAccessProvider metaAccess, StructuredGraph graph) {
-        if (stamp instanceof PrimitiveStamp) {
-            return forPrimitive(stamp, constant, graph);
-        } else {
-            ConstantNode ret = forConstant(constant, metaAccess, graph);
-            assert ret.stamp().isCompatible(stamp);
-            return ret;
-        }
+        return graph.unique(new ConstantNode(constant, stamp.constant(constant, metaAccess)));
     }
 
     /**
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/CompareNode.java	Mon May 26 18:55:06 2014 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/CompareNode.java	Mon May 26 18:55:21 2014 +0200
@@ -126,14 +126,14 @@
             }
         } else if (x() instanceof ConvertNode && y().isConstant()) {
             ConvertNode convertX = (ConvertNode) x();
-            ConstantNode newY = canonicalConvertConstant(convertX, y().asConstant());
+            ConstantNode newY = canonicalConvertConstant(tool, convertX, y().asConstant());
             if (newY != null) {
                 setX(convertX.getInput());
                 setY(newY);
             }
         } else if (y() instanceof ConvertNode && x().isConstant()) {
             ConvertNode convertY = (ConvertNode) y();
-            ConstantNode newX = canonicalConvertConstant(convertY, x().asConstant());
+            ConstantNode newX = canonicalConvertConstant(tool, convertY, x().asConstant());
             if (newX != null) {
                 setX(newX);
                 setY(convertY.getInput());
@@ -142,11 +142,11 @@
         return this;
     }
 
-    private ConstantNode canonicalConvertConstant(ConvertNode convert, Constant constant) {
+    private ConstantNode canonicalConvertConstant(CanonicalizerTool tool, ConvertNode convert, Constant constant) {
         if (convert.preservesOrder(condition())) {
             Constant reverseConverted = convert.reverse(constant);
             if (convert.convert(reverseConverted).equals(constant)) {
-                return ConstantNode.forPrimitive(convert.getInput().stamp(), reverseConverted, convert.graph());
+                return ConstantNode.forConstant(convert.getInput().stamp(), reverseConverted, tool.getMetaAccess(), convert.graph());
             }
         }
         return null;
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/NarrowNode.java	Mon May 26 18:55:06 2014 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/NarrowNode.java	Mon May 26 18:55:21 2014 +0200
@@ -41,7 +41,8 @@
     }
 
     public static long narrow(long value, int resultBits) {
-        return value & IntegerStamp.defaultMask(resultBits);
+        long ret = value & IntegerStamp.defaultMask(resultBits);
+        return SignExtendNode.signExtend(ret, resultBits);
     }
 
     @Override
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.test/src/com/oracle/graal/test/GCAfterTestDecorator.java	Mon May 26 18:55:21 2014 +0200
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2014, 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.test;
+
+import org.junit.runner.*;
+
+public class GCAfterTestDecorator extends GraalJUnitRunListenerDecorator {
+
+    public GCAfterTestDecorator(GraalJUnitRunListener l) {
+        super(l);
+    }
+
+    @Override
+    public void testFinished(Description description) {
+        System.gc();
+        super.testFinished(description);
+    }
+}
--- a/graal/com.oracle.graal.test/src/com/oracle/graal/test/GraalJUnitCore.java	Mon May 26 18:55:06 2014 +0200
+++ b/graal/com.oracle.graal.test/src/com/oracle/graal/test/GraalJUnitCore.java	Mon May 26 18:55:21 2014 +0200
@@ -51,6 +51,7 @@
         boolean enableTiming = false;
         boolean color = false;
         boolean eagerStackTrace = false;
+        boolean gcAfterTest = false;
         for (String each : args) {
             if (each.charAt(0) == '-') {
                 // command line arguments
@@ -62,6 +63,8 @@
                     color = true;
                 } else if (each.contentEquals("-JUnitEagerStackTrace")) {
                     eagerStackTrace = true;
+                } else if (each.contentEquals("-JUnitGCAfterTest")) {
+                    gcAfterTest = true;
                 } else {
                     system.out().println("Unknown command line argument: " + each);
                 }
@@ -92,6 +95,9 @@
         if (eagerStackTrace) {
             graalListener = new EagerStackTraceDecorator(graalListener);
         }
+        if (gcAfterTest) {
+            graalListener = new GCAfterTestDecorator(graalListener);
+        }
         junitCore.addListener(GraalTextListener.createRunListener(graalListener));
         Result result = junitCore.run(classes.toArray(new Class[0]));
         for (Failure each : missingClasses) {
--- a/mx/mx_graal.py	Mon May 26 18:55:06 2014 +0200
+++ b/mx/mx_graal.py	Mon May 26 18:55:21 2014 +0200
@@ -970,7 +970,7 @@
         f_testfile.close()
         harness(projectscp, vmArgs)
 
-def _unittest(args, annotations, prefixcp="", whitelist=None, verbose=False, enable_timing=False, regex=None, color=False, eager_stacktrace=False):
+def _unittest(args, annotations, prefixcp="", whitelist=None, verbose=False, enable_timing=False, regex=None, color=False, eager_stacktrace=False, gc_after_test=False):
     mxdir = dirname(__file__)
     name = 'JUnitWrapper'
     javaSource = join(mxdir, name + '.java')
@@ -993,6 +993,8 @@
         coreArgs.append('-JUnitColor')
     if eager_stacktrace:
         coreArgs.append('-JUnitEagerStackTrace')
+    if gc_after_test:
+        coreArgs.append('-JUnitGCAfterTest')
 
 
     def harness(projectscp, vmArgs):
@@ -1025,6 +1027,7 @@
       --regex <regex>        run only testcases matching a regular expression
       --color                enable colors output
       --eager-stacktrace     print stacktrace eagerly
+      --gc-after-test        force a GC after each test
 
     To avoid conflicts with VM options '--' can be used as delimiter.
 
@@ -1067,6 +1070,7 @@
     parser.add_argument('--regex', help='run only testcases matching a regular expression', metavar='<regex>')
     parser.add_argument('--color', help='enable color output', action='store_true')
     parser.add_argument('--eager-stacktrace', help='print stacktrace eagerly', action='store_true')
+    parser.add_argument('--gc-after-test', help='force a GC after each test', action='store_true')
 
     ut_args = []
     delimiter = False
@@ -1824,7 +1828,7 @@
         out = args[0]
     elif len(args) > 1:
         mx.abort('jacocoreport takes only one argument : an output directory')
-    mx.run_java(['-jar', jacocoreport.get_path(True), '-in', 'jacoco.exec', '-g', join(_graal_home, 'graal'), out])
+    mx.run_java(['-jar', jacocoreport.get_path(True), '--in', 'jacoco.exec', '--out', out] + [p.dir for p in mx.projects()])
 
 def sl(args):
     """run an SL program"""
--- a/mx/projects	Mon May 26 18:55:06 2014 +0200
+++ b/mx/projects	Mon May 26 18:55:21 2014 +0200
@@ -36,8 +36,8 @@
 library@JACOCOAGENT@sha1=2f73a645b02e39290e577ce555f00b02004650b0
 
 library@JACOCOREPORT@path=lib/jacocoreport.jar
-library@JACOCOREPORT@urls=http://lafo.ssw.uni-linz.ac.at/jacoco/jacocoreport-0.7.1-1.jar
-library@JACOCOREPORT@sha1=0c5db714804416dd1df4d8110762136ce3d5c7dc
+library@JACOCOREPORT@urls=http://lafo.ssw.uni-linz.ac.at/jacoco/jacocoreport-0.7.1-2.jar
+library@JACOCOREPORT@sha1=a630436391832d697a12c8f7daef8655d7a1efd2
 
 library@DACAPO_SCALA@path=lib/dacapo-scala-0.1.0-20120216.jar
 library@DACAPO_SCALA@urls=http://repo.scalabench.org/snapshots/org/scalabench/benchmarks/scala-benchmark-suite/0.1.0-SNAPSHOT/scala-benchmark-suite-0.1.0-20120216.103539-3.jar