changeset 15909:e43591136d9f

Support for compressed constants.
author Roland Schatz <roland.schatz@oracle.com>
date Mon, 26 May 2014 16:09:53 +0200
parents 70bb8df01b6e
children 79a0d9065849
files graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/Constant.java graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64LIRGenerator.java graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/StampFactory.java graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerator.java graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotMove.java graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotLIRGenerator.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotCompressedNullConstant.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotConstant.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotConstantReflectionProvider.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMetaAccessProvider.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMetaspaceConstant.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotObjectConstant.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotSuitesProvider.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/phases/LoadJavaMirrorWithKlassPhase.java
diffstat 14 files changed, 319 insertions(+), 36 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/Constant.java	Fri May 23 17:21:37 2014 +0200
+++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/Constant.java	Mon May 26 16:09:53 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.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64LIRGenerator.java	Fri May 23 17:21:37 2014 +0200
+++ b/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64LIRGenerator.java	Mon May 26 16:09:53 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;
     }
--- a/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/StampFactory.java	Fri May 23 17:21:37 2014 +0200
+++ b/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/StampFactory.java	Mon May 26 16:09:53 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.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerator.java	Fri May 23 17:21:37 2014 +0200
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerator.java	Mon May 26 16:09:53 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,15 @@
         assert address.getKind() == Kind.Object : address + " - " + address.getKind() + " not an object!";
         append(new AMD64Move.NullCheckOp(load(address), 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	Fri May 23 17:21:37 2014 +0200
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotMove.java	Mon May 26 16:09:53 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	Fri May 23 17:21:37 2014 +0200
+++ b/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotLIRGenerator.java	Mon May 26 16:09:53 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 16:09:53 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 16:09:53 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	Fri May 23 17:21:37 2014 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotConstantReflectionProvider.java	Mon May 26 16:09:53 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	Fri May 23 17:21:37 2014 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMetaAccessProvider.java	Mon May 26 16:09:53 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	Fri May 23 17:21:37 2014 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMetaspaceConstant.java	Mon May 26 16:09:53 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	Fri May 23 17:21:37 2014 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotObjectConstant.java	Mon May 26 16:09:53 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	Fri May 23 17:21:37 2014 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotSuitesProvider.java	Mon May 26 16:09:53 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/phases/LoadJavaMirrorWithKlassPhase.java	Fri May 23 17:21:37 2014 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/phases/LoadJavaMirrorWithKlassPhase.java	Mon May 26 16:09:53 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);
             }