changeset 18482:b8a622c3e99f

Move raw memory access operations to a separate interface.
author Roland Schatz <roland.schatz@oracle.com>
date Thu, 20 Nov 2014 17:00:19 +0100
parents f91e40c4bb47
children d7cc487d1325
files graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ConstantReflectionProvider.java graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/MemoryAccessProvider.java graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/IllegalStamp.java graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/ObjectStamp.java graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/PrimitiveStamp.java graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/Stamp.java graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/VoidStamp.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/HotSpotMemoryAccessProviderImpl.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/type/KlassPointerStamp.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/type/MethodPointerStamp.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/type/NarrowOopStamp.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/KlassLayoutHelperNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ReadNode.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleConstantReflectionProvider.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/typesystem/CustomizedUnsafeLoadFinalNode.java
diffstat 16 files changed, 270 insertions(+), 196 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ConstantReflectionProvider.java	Thu Nov 20 15:23:46 2014 +0100
+++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ConstantReflectionProvider.java	Thu Nov 20 17:00:19 2014 +0100
@@ -105,38 +105,6 @@
     JavaConstant readStableFieldValue(JavaField field, JavaConstant receiver, boolean isDefaultStable);
 
     /**
-     * Reads a value of this kind using a base address and a displacement. No bounds checking or
-     * type checking is performed. Returns {@code null} if the value is not available at this point.
-     *
-     * @param base the base address from which the value is read.
-     * @param displacement the displacement within the object in bytes
-     * @return the read value encapsulated in a {@link JavaConstant} object, or {@code null} if the
-     *         value cannot be read.
-     */
-    JavaConstant readUnsafeConstant(Kind kind, JavaConstant base, long displacement);
-
-    /**
-     * Reads a primitive value using a base address and a displacement.
-     *
-     * @param kind the {@link Kind} of the returned {@link JavaConstant} object
-     * @param base the base address from which the value is read
-     * @param displacement the displacement within the object in bytes
-     * @param bits the number of bits to read from memory
-     * @return the read value encapsulated in a {@link Constant} object of {@link Kind} kind
-     */
-    JavaConstant readRawConstant(Kind kind, Constant base, long displacement, int bits);
-
-    /**
-     * Reads a pointer value using a base address and a displacement.
-     *
-     * @param type the {@link PointerType} of the returned {@link Constant} object
-     * @param base the base address from which the value is read
-     * @param displacement the displacement within the object in bytes
-     * @return the read value encapsulated in a {@link Constant} object
-     */
-    Constant readPointerConstant(PointerType type, Constant base, long displacement);
-
-    /**
      * Converts the given {@link Kind#isPrimitive() primitive} constant to a boxed
      * {@link Kind#Object object} constant, according to the Java boxing rules. Returns {@code null}
      * if the source is is not a primitive constant, or the boxed value is not available at this
@@ -168,4 +136,9 @@
      * Gets access to the internals of {@link MethodHandle}.
      */
     MethodHandleAccessProvider getMethodHandleAccess();
+
+    /**
+     * Gets raw memory access.
+     */
+    MemoryAccessProvider getMemoryAccessProvider();
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/MemoryAccessProvider.java	Thu Nov 20 17:00:19 2014 +0100
@@ -0,0 +1,61 @@
+/*
+ * 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.api.meta;
+
+/**
+ * Provides memory access operations for the target VM.
+ */
+public interface MemoryAccessProvider extends Remote {
+
+    /**
+     * Reads a value of this kind using a base address and a displacement. No bounds checking or
+     * type checking is performed. Returns {@code null} if the value is not available at this point.
+     *
+     * @param base the base address from which the value is read.
+     * @param displacement the displacement within the object in bytes
+     * @return the read value encapsulated in a {@link JavaConstant} object, or {@code null} if the
+     *         value cannot be read.
+     */
+    JavaConstant readUnsafeConstant(Kind kind, JavaConstant base, long displacement);
+
+    /**
+     * Reads a primitive value using a base address and a displacement.
+     *
+     * @param kind the {@link Kind} of the returned {@link JavaConstant} object
+     * @param base the base address from which the value is read
+     * @param displacement the displacement within the object in bytes
+     * @param bits the number of bits to read from memory
+     * @return the read value encapsulated in a {@link JavaConstant} object of {@link Kind} kind
+     */
+    JavaConstant readPrimitiveConstant(Kind kind, Constant base, long displacement, int bits);
+
+    /**
+     * Reads a pointer value using a base address and a displacement.
+     *
+     * @param type the {@link PointerType} of the returned {@link Constant} object
+     * @param base the base address from which the value is read
+     * @param displacement the displacement within the object in bytes
+     * @return the read value encapsulated in a {@link Constant} object
+     */
+    Constant readPointerConstant(PointerType type, Constant base, long displacement);
+}
--- a/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/IllegalStamp.java	Thu Nov 20 15:23:46 2014 +0100
+++ b/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/IllegalStamp.java	Thu Nov 20 17:00:19 2014 +0100
@@ -90,7 +90,7 @@
     }
 
     @Override
-    public Constant readConstant(ConstantReflectionProvider provider, Constant base, long displacement) {
+    public Constant readConstant(MemoryAccessProvider provider, Constant base, long displacement) {
         throw GraalInternalError.shouldNotReachHere("can't read values of illegal stamp");
     }
 
--- a/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/ObjectStamp.java	Thu Nov 20 15:23:46 2014 +0100
+++ b/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/ObjectStamp.java	Thu Nov 20 17:00:19 2014 +0100
@@ -75,7 +75,7 @@
     }
 
     @Override
-    public Constant readConstant(ConstantReflectionProvider provider, Constant base, long displacement) {
+    public Constant readConstant(MemoryAccessProvider provider, Constant base, long displacement) {
         return provider.readPointerConstant(PointerType.Object, base, displacement);
     }
 }
--- a/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/PrimitiveStamp.java	Thu Nov 20 15:23:46 2014 +0100
+++ b/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/PrimitiveStamp.java	Thu Nov 20 17:00:19 2014 +0100
@@ -52,8 +52,8 @@
     }
 
     @Override
-    public Constant readConstant(ConstantReflectionProvider provider, Constant base, long displacement) {
-        return provider.readRawConstant(getStackKind(), base, displacement, getBits());
+    public Constant readConstant(MemoryAccessProvider provider, Constant base, long displacement) {
+        return provider.readPrimitiveConstant(getStackKind(), base, displacement, getBits());
     }
 
     @Override
--- a/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/Stamp.java	Thu Nov 20 15:23:46 2014 +0100
+++ b/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/Stamp.java	Thu Nov 20 17:00:19 2014 +0100
@@ -116,7 +116,7 @@
         return null;
     }
 
-    public abstract Constant readConstant(ConstantReflectionProvider provider, Constant base, long displacement);
+    public abstract Constant readConstant(MemoryAccessProvider provider, Constant base, long displacement);
 
     /**
      * Tries to improve this stamp with the stamp given as parameter. If successful, returns the new
--- a/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/VoidStamp.java	Thu Nov 20 15:23:46 2014 +0100
+++ b/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/VoidStamp.java	Thu Nov 20 17:00:19 2014 +0100
@@ -103,7 +103,7 @@
     }
 
     @Override
-    public Constant readConstant(ConstantReflectionProvider provider, Constant base, long displacement) {
+    public Constant readConstant(MemoryAccessProvider provider, Constant base, long displacement) {
         throw GraalInternalError.shouldNotReachHere("can't read values of void stamp");
     }
 
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotConstantReflectionProvider.java	Thu Nov 20 15:23:46 2014 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotConstantReflectionProvider.java	Thu Nov 20 17:00:19 2014 +0100
@@ -23,7 +23,6 @@
 package com.oracle.graal.hotspot.meta;
 
 import static com.oracle.graal.compiler.common.GraalOptions.*;
-import static com.oracle.graal.compiler.common.UnsafeAccess.*;
 import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*;
 
 import java.lang.reflect.*;
@@ -47,10 +46,12 @@
 
     protected final HotSpotGraalRuntime runtime;
     protected final HotSpotMethodHandleAccessProvider methodHandleAccess;
+    protected final HotSpotMemoryAccessProviderImpl memoryAccess;
 
     public HotSpotConstantReflectionProvider(HotSpotGraalRuntime runtime) {
         this.runtime = runtime;
         this.methodHandleAccess = new HotSpotMethodHandleAccessProvider(this);
+        this.memoryAccess = new HotSpotMemoryAccessProviderImpl(runtime);
     }
 
     public MethodHandleAccessProvider getMethodHandleAccess() {
@@ -58,6 +59,11 @@
     }
 
     @Override
+    public MemoryAccessProvider getMemoryAccessProvider() {
+        return memoryAccess;
+    }
+
+    @Override
     public Boolean constantEquals(Constant x, Constant y) {
         if (x == y) {
             return true;
@@ -91,140 +97,6 @@
         return null;
     }
 
-    private static long readRawValue(Constant baseConstant, long initialDisplacement, int bits) {
-        Object base;
-        long displacement;
-        if (baseConstant instanceof JavaConstant) {
-            JavaConstant javaConstant = (JavaConstant) baseConstant;
-            if (javaConstant instanceof HotSpotObjectConstantImpl) {
-                base = ((HotSpotObjectConstantImpl) javaConstant).object();
-                displacement = initialDisplacement;
-            } else if (javaConstant.getKind().isNumericInteger()) {
-                long baseLong = javaConstant.asLong();
-                assert baseLong != 0;
-                displacement = initialDisplacement + baseLong;
-                base = null;
-            } else {
-                throw GraalInternalError.shouldNotReachHere();
-            }
-        } else {
-            throw GraalInternalError.shouldNotReachHere();
-        }
-
-        long rawValue;
-        switch (bits) {
-            case 8:
-                rawValue = base == null ? unsafe.getByte(displacement) : unsafe.getByte(base, displacement);
-                break;
-            case 16:
-                rawValue = base == null ? unsafe.getShort(displacement) : unsafe.getShort(base, displacement);
-                break;
-            case 32:
-                rawValue = base == null ? unsafe.getInt(displacement) : unsafe.getInt(base, displacement);
-                break;
-            case 64:
-                rawValue = base == null ? unsafe.getLong(displacement) : unsafe.getLong(base, displacement);
-                break;
-            default:
-                throw GraalInternalError.shouldNotReachHere();
-        }
-        return rawValue;
-    }
-
-    private Object readRawObject(Constant baseConstant, long displacement, boolean compressed) {
-        if (baseConstant instanceof HotSpotObjectConstantImpl) {
-            assert compressed == runtime.getConfig().useCompressedOops;
-            return unsafe.getObject(((HotSpotObjectConstantImpl) baseConstant).object(), displacement);
-        } else if (baseConstant instanceof HotSpotMetaspaceConstant) {
-            Object metaspaceObject = HotSpotMetaspaceConstantImpl.getMetaspaceObject(baseConstant);
-            if (metaspaceObject instanceof HotSpotResolvedObjectTypeImpl) {
-                assert !compressed : "unexpected compressed read from Klass*";
-                if (displacement == runtime.getConfig().classMirrorOffset) {
-                    return ((HotSpotResolvedObjectTypeImpl) metaspaceObject).mirror();
-                } else if (displacement == runtime.getConfig().arrayKlassComponentMirrorOffset) {
-                    return ((HotSpotResolvedObjectTypeImpl) metaspaceObject).mirror().getComponentType();
-                } else if (displacement == runtime.getConfig().instanceKlassNodeClassOffset) {
-                    return NodeClass.get(((HotSpotResolvedObjectTypeImpl) metaspaceObject).mirror());
-                }
-            }
-            throw GraalInternalError.shouldNotReachHere("read from unknown Klass* offset " + displacement);
-        } else {
-            throw GraalInternalError.shouldNotReachHere("unexpected base pointer: " + (baseConstant == null ? "null" : baseConstant.toString()));
-        }
-    }
-
-    @Override
-    public JavaConstant readUnsafeConstant(Kind kind, JavaConstant baseConstant, long displacement) {
-        if (kind == Kind.Object) {
-            Object o = readRawObject(baseConstant, displacement, runtime.getConfig().useCompressedOops);
-            return HotSpotObjectConstantImpl.forObject(o);
-        } else {
-            return readRawConstant(kind, baseConstant, displacement, kind.getByteCount() * 8);
-        }
-    }
-
-    @Override
-    public JavaConstant readRawConstant(Kind kind, Constant baseConstant, long initialDisplacement, int bits) {
-        try {
-            long rawValue = readRawValue(baseConstant, initialDisplacement, bits);
-            switch (kind) {
-                case Boolean:
-                    return JavaConstant.forBoolean(rawValue != 0);
-                case Byte:
-                    return JavaConstant.forByte((byte) rawValue);
-                case Char:
-                    return JavaConstant.forChar((char) rawValue);
-                case Short:
-                    return JavaConstant.forShort((short) rawValue);
-                case Int:
-                    return JavaConstant.forInt((int) rawValue);
-                case Long:
-                    return JavaConstant.forLong(rawValue);
-                case Float:
-                    return JavaConstant.forFloat(Float.intBitsToFloat((int) rawValue));
-                case Double:
-                    return JavaConstant.forDouble(Double.longBitsToDouble(rawValue));
-                default:
-                    throw GraalInternalError.shouldNotReachHere("unsupported kind: " + kind);
-            }
-        } catch (NullPointerException e) {
-            return null;
-        }
-    }
-
-    public Constant readPointerConstant(PointerType type, Constant base, long displacement) {
-        switch (type) {
-            case Object:
-                return HotSpotObjectConstantImpl.forObject(readRawObject(base, displacement, false));
-            case Type:
-                long klass = readRawValue(base, displacement, runtime.getTarget().wordSize * 8);
-                HotSpotResolvedObjectType metaKlass = HotSpotResolvedObjectTypeImpl.fromMetaspaceKlass(klass);
-                return HotSpotMetaspaceConstantImpl.forMetaspaceObject(runtime.getTarget().wordKind, klass, metaKlass, false);
-            case Method:
-                long method = readRawValue(base, displacement, runtime.getTarget().wordSize * 8);
-                HotSpotResolvedJavaMethod metaMethod = HotSpotResolvedJavaMethodImpl.fromMetaspace(method);
-                return HotSpotMetaspaceConstantImpl.forMetaspaceObject(runtime.getTarget().wordKind, method, metaMethod, false);
-            default:
-                throw GraalInternalError.shouldNotReachHere();
-        }
-    }
-
-    public Constant readNarrowPointerConstant(PointerType type, Constant base, long displacement) {
-        switch (type) {
-            case Object:
-                return HotSpotObjectConstantImpl.forObject(readRawObject(base, displacement, true), true);
-            case Type:
-                int compressed = (int) readRawValue(base, displacement, 32);
-                long klass = runtime.getConfig().getKlassEncoding().uncompress(compressed);
-                HotSpotResolvedObjectType metaKlass = HotSpotResolvedObjectTypeImpl.fromMetaspaceKlass(klass);
-                return HotSpotMetaspaceConstantImpl.forMetaspaceObject(Kind.Int, compressed, metaKlass, true);
-            case Method:
-                // there are no compressed method pointers
-            default:
-                throw GraalInternalError.shouldNotReachHere();
-        }
-    }
-
     @Override
     public JavaConstant readArrayElement(JavaConstant array, int index) {
         if (array.getKind() != Kind.Object || array.isNull()) {
@@ -362,13 +234,13 @@
             assert hotspotField.isStatic();
             HotSpotResolvedJavaType holder = (HotSpotResolvedJavaType) hotspotField.getDeclaringClass();
             if (holder.isInitialized()) {
-                return readUnsafeConstant(hotspotField.getKind(), HotSpotObjectConstantImpl.forObject(holder.mirror()), hotspotField.offset());
+                return memoryAccess.readUnsafeConstant(hotspotField.getKind(), HotSpotObjectConstantImpl.forObject(holder.mirror()), hotspotField.offset());
             }
             return null;
         } else {
             assert !hotspotField.isStatic();
             assert receiver.isNonNull() && hotspotField.isInObject(((HotSpotObjectConstantImpl) receiver).object());
-            return readUnsafeConstant(hotspotField.getKind(), receiver, hotspotField.offset());
+            return memoryAccess.readUnsafeConstant(hotspotField.getKind(), receiver, hotspotField.offset());
         }
     }
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMemoryAccessProviderImpl.java	Thu Nov 20 17:00:19 2014 +0100
@@ -0,0 +1,176 @@
+/*
+ * Copyright (c) 2011, 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 static com.oracle.graal.compiler.common.UnsafeAccess.*;
+
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.compiler.common.*;
+import com.oracle.graal.graph.*;
+import com.oracle.graal.hotspot.*;
+
+/**
+ * HotSpot implementation of {@link MemoryAccessProvider}.
+ */
+public class HotSpotMemoryAccessProviderImpl implements MemoryAccessProvider {
+
+    protected final HotSpotGraalRuntime runtime;
+
+    public HotSpotMemoryAccessProviderImpl(HotSpotGraalRuntime runtime) {
+        this.runtime = runtime;
+    }
+
+    private static long readRawValue(Constant baseConstant, long initialDisplacement, int bits) {
+        Object base;
+        long displacement;
+        if (baseConstant instanceof JavaConstant) {
+            JavaConstant javaConstant = (JavaConstant) baseConstant;
+            if (javaConstant instanceof HotSpotObjectConstantImpl) {
+                base = ((HotSpotObjectConstantImpl) javaConstant).object();
+                displacement = initialDisplacement;
+            } else if (javaConstant.getKind().isNumericInteger()) {
+                long baseLong = javaConstant.asLong();
+                assert baseLong != 0;
+                displacement = initialDisplacement + baseLong;
+                base = null;
+            } else {
+                throw GraalInternalError.shouldNotReachHere();
+            }
+        } else {
+            throw GraalInternalError.shouldNotReachHere();
+        }
+
+        long rawValue;
+        switch (bits) {
+            case 8:
+                rawValue = base == null ? unsafe.getByte(displacement) : unsafe.getByte(base, displacement);
+                break;
+            case 16:
+                rawValue = base == null ? unsafe.getShort(displacement) : unsafe.getShort(base, displacement);
+                break;
+            case 32:
+                rawValue = base == null ? unsafe.getInt(displacement) : unsafe.getInt(base, displacement);
+                break;
+            case 64:
+                rawValue = base == null ? unsafe.getLong(displacement) : unsafe.getLong(base, displacement);
+                break;
+            default:
+                throw GraalInternalError.shouldNotReachHere();
+        }
+        return rawValue;
+    }
+
+    private Object readRawObject(Constant baseConstant, long displacement, boolean compressed) {
+        if (baseConstant instanceof HotSpotObjectConstantImpl) {
+            assert compressed == runtime.getConfig().useCompressedOops;
+            return unsafe.getObject(((HotSpotObjectConstantImpl) baseConstant).object(), displacement);
+        } else if (baseConstant instanceof HotSpotMetaspaceConstant) {
+            Object metaspaceObject = HotSpotMetaspaceConstantImpl.getMetaspaceObject(baseConstant);
+            if (metaspaceObject instanceof HotSpotResolvedObjectTypeImpl) {
+                assert !compressed : "unexpected compressed read from Klass*";
+                if (displacement == runtime.getConfig().classMirrorOffset) {
+                    return ((HotSpotResolvedObjectTypeImpl) metaspaceObject).mirror();
+                } else if (displacement == runtime.getConfig().arrayKlassComponentMirrorOffset) {
+                    return ((HotSpotResolvedObjectTypeImpl) metaspaceObject).mirror().getComponentType();
+                } else if (displacement == runtime.getConfig().instanceKlassNodeClassOffset) {
+                    return NodeClass.get(((HotSpotResolvedObjectTypeImpl) metaspaceObject).mirror());
+                }
+            }
+            throw GraalInternalError.shouldNotReachHere("read from unknown Klass* offset " + displacement);
+        } else {
+            throw GraalInternalError.shouldNotReachHere("unexpected base pointer: " + (baseConstant == null ? "null" : baseConstant.toString()));
+        }
+    }
+
+    @Override
+    public JavaConstant readUnsafeConstant(Kind kind, JavaConstant baseConstant, long displacement) {
+        if (kind == Kind.Object) {
+            Object o = readRawObject(baseConstant, displacement, runtime.getConfig().useCompressedOops);
+            return HotSpotObjectConstantImpl.forObject(o);
+        } else {
+            return readPrimitiveConstant(kind, baseConstant, displacement, kind.getByteCount() * 8);
+        }
+    }
+
+    @Override
+    public JavaConstant readPrimitiveConstant(Kind kind, Constant baseConstant, long initialDisplacement, int bits) {
+        try {
+            long rawValue = readRawValue(baseConstant, initialDisplacement, bits);
+            switch (kind) {
+                case Boolean:
+                    return JavaConstant.forBoolean(rawValue != 0);
+                case Byte:
+                    return JavaConstant.forByte((byte) rawValue);
+                case Char:
+                    return JavaConstant.forChar((char) rawValue);
+                case Short:
+                    return JavaConstant.forShort((short) rawValue);
+                case Int:
+                    return JavaConstant.forInt((int) rawValue);
+                case Long:
+                    return JavaConstant.forLong(rawValue);
+                case Float:
+                    return JavaConstant.forFloat(Float.intBitsToFloat((int) rawValue));
+                case Double:
+                    return JavaConstant.forDouble(Double.longBitsToDouble(rawValue));
+                default:
+                    throw GraalInternalError.shouldNotReachHere("unsupported kind: " + kind);
+            }
+        } catch (NullPointerException e) {
+            return null;
+        }
+    }
+
+    public Constant readPointerConstant(PointerType type, Constant base, long displacement) {
+        switch (type) {
+            case Object:
+                return HotSpotObjectConstantImpl.forObject(readRawObject(base, displacement, false));
+            case Type:
+                long klass = readRawValue(base, displacement, runtime.getTarget().wordSize * 8);
+                HotSpotResolvedObjectType metaKlass = HotSpotResolvedObjectTypeImpl.fromMetaspaceKlass(klass);
+                return HotSpotMetaspaceConstantImpl.forMetaspaceObject(runtime.getTarget().wordKind, klass, metaKlass, false);
+            case Method:
+                long method = readRawValue(base, displacement, runtime.getTarget().wordSize * 8);
+                HotSpotResolvedJavaMethod metaMethod = HotSpotResolvedJavaMethodImpl.fromMetaspace(method);
+                return HotSpotMetaspaceConstantImpl.forMetaspaceObject(runtime.getTarget().wordKind, method, metaMethod, false);
+            default:
+                throw GraalInternalError.shouldNotReachHere();
+        }
+    }
+
+    public Constant readNarrowPointerConstant(PointerType type, Constant base, long displacement) {
+        switch (type) {
+            case Object:
+                return HotSpotObjectConstantImpl.forObject(readRawObject(base, displacement, true), true);
+            case Type:
+                int compressed = (int) readRawValue(base, displacement, 32);
+                long klass = runtime.getConfig().getKlassEncoding().uncompress(compressed);
+                HotSpotResolvedObjectType metaKlass = HotSpotResolvedObjectTypeImpl.fromMetaspaceKlass(klass);
+                return HotSpotMetaspaceConstantImpl.forMetaspaceObject(Kind.Int, compressed, metaKlass, true);
+            case Method:
+                // there are no compressed method pointers
+            default:
+                throw GraalInternalError.shouldNotReachHere();
+        }
+    }
+}
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/type/KlassPointerStamp.java	Thu Nov 20 15:23:46 2014 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/type/KlassPointerStamp.java	Thu Nov 20 17:00:19 2014 +0100
@@ -91,9 +91,9 @@
     }
 
     @Override
-    public Constant readConstant(ConstantReflectionProvider provider, Constant base, long displacement) {
+    public Constant readConstant(MemoryAccessProvider provider, Constant base, long displacement) {
         if (isCompressed()) {
-            return ((HotSpotConstantReflectionProvider) provider).readNarrowPointerConstant(PointerType.Type, base, displacement);
+            return ((HotSpotMemoryAccessProviderImpl) provider).readNarrowPointerConstant(PointerType.Type, base, displacement);
         } else {
             return provider.readPointerConstant(PointerType.Type, base, displacement);
         }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/type/MethodPointerStamp.java	Thu Nov 20 15:23:46 2014 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/type/MethodPointerStamp.java	Thu Nov 20 17:00:19 2014 +0100
@@ -48,7 +48,7 @@
     }
 
     @Override
-    public Constant readConstant(ConstantReflectionProvider provider, Constant base, long displacement) {
+    public Constant readConstant(MemoryAccessProvider provider, Constant base, long displacement) {
         return provider.readPointerConstant(PointerType.Method, base, displacement);
     }
 
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/type/NarrowOopStamp.java	Thu Nov 20 15:23:46 2014 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/type/NarrowOopStamp.java	Thu Nov 20 17:00:19 2014 +0100
@@ -80,8 +80,8 @@
     }
 
     @Override
-    public Constant readConstant(ConstantReflectionProvider provider, Constant base, long displacement) {
-        return ((HotSpotConstantReflectionProvider) provider).readNarrowPointerConstant(PointerType.Object, base, displacement);
+    public Constant readConstant(MemoryAccessProvider provider, Constant base, long displacement) {
+        return ((HotSpotMemoryAccessProviderImpl) provider).readNarrowPointerConstant(PointerType.Object, base, displacement);
     }
 
     @Override
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/KlassLayoutHelperNode.java	Thu Nov 20 15:23:46 2014 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/KlassLayoutHelperNode.java	Thu Nov 20 17:00:19 2014 +0100
@@ -95,7 +95,7 @@
             if (klass.isConstant()) {
                 long base = klass.asJavaConstant().asLong();
                 if (base != 0L) {
-                    Constant constant = stamp().readConstant(tool.getConstantReflection(), klass.asJavaConstant(), runtime().getConfig().klassLayoutHelperOffset);
+                    Constant constant = stamp().readConstant(tool.getConstantReflection().getMemoryAccessProvider(), klass.asJavaConstant(), runtime().getConfig().klassLayoutHelperOffset);
                     return ConstantNode.forConstant(stamp(), constant, tool.getMetaAccess());
                 }
             }
@@ -107,7 +107,7 @@
                     HotSpotResolvedObjectType type = (HotSpotResolvedObjectType) ostamp.type();
                     if (type != null && type.isArray() && !type.getComponentType().isPrimitive()) {
                         // The layout for all object arrays is the same.
-                        Constant constant = stamp().readConstant(tool.getConstantReflection(), type.klass(), runtime().getConfig().klassLayoutHelperOffset);
+                        Constant constant = stamp().readConstant(tool.getConstantReflection().getMemoryAccessProvider(), type.klass(), runtime().getConfig().klassLayoutHelperOffset);
                         return ConstantNode.forConstant(stamp(), constant, tool.getMetaAccess());
                     }
                 }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ReadNode.java	Thu Nov 20 15:23:46 2014 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ReadNode.java	Thu Nov 20 17:00:19 2014 +0100
@@ -122,7 +122,7 @@
             if (metaAccess != null && object != null && object.isConstant() && !object.isNullConstant()) {
                 if ((location.getLocationIdentity().isImmutable()) && location instanceof ConstantLocationNode) {
                     long displacement = ((ConstantLocationNode) location).getDisplacement();
-                    Constant constant = read.stamp().readConstant(tool.getConstantReflection(), object.asConstant(), displacement);
+                    Constant constant = read.stamp().readConstant(tool.getConstantReflection().getMemoryAccessProvider(), object.asConstant(), displacement);
                     if (constant != null) {
                         return ConstantNode.forConstant(read.stamp(), constant, metaAccess);
                     }
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleConstantReflectionProvider.java	Thu Nov 20 15:23:46 2014 +0100
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleConstantReflectionProvider.java	Thu Nov 20 17:00:19 2014 +0100
@@ -88,18 +88,6 @@
         return graalConstantReflection.readStableFieldValue(field, receiver, isDefaultStable);
     }
 
-    public JavaConstant readUnsafeConstant(Kind kind, JavaConstant base, long displacement) {
-        return graalConstantReflection.readUnsafeConstant(kind, base, displacement);
-    }
-
-    public JavaConstant readRawConstant(Kind kind, Constant base, long displacement, int bits) {
-        return graalConstantReflection.readRawConstant(kind, base, displacement, bits);
-    }
-
-    public Constant readPointerConstant(PointerType type, Constant base, long displacement) {
-        return graalConstantReflection.readPointerConstant(type, base, displacement);
-    }
-
     public JavaConstant boxPrimitive(JavaConstant source) {
         return graalConstantReflection.boxPrimitive(source);
     }
@@ -119,4 +107,8 @@
     public MethodHandleAccessProvider getMethodHandleAccess() {
         return graalConstantReflection.getMethodHandleAccess();
     }
+
+    public MemoryAccessProvider getMemoryAccessProvider() {
+        return graalConstantReflection.getMemoryAccessProvider();
+    }
 }
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/typesystem/CustomizedUnsafeLoadFinalNode.java	Thu Nov 20 15:23:46 2014 +0100
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/typesystem/CustomizedUnsafeLoadFinalNode.java	Thu Nov 20 17:00:19 2014 +0100
@@ -64,7 +64,7 @@
     @Override
     public Node canonical(CanonicalizerTool tool) {
         if (object.isConstant() && !object.isNullConstant() && offset.isConstant() && condition.isConstant() && condition.asJavaConstant().asInt() == 1) {
-            JavaConstant constant = tool.getConstantReflection().readUnsafeConstant(accessKind, object.asJavaConstant(), offset.asJavaConstant().asLong());
+            JavaConstant constant = tool.getConstantReflection().getMemoryAccessProvider().readUnsafeConstant(accessKind, object.asJavaConstant(), offset.asJavaConstant().asLong());
             return ConstantNode.forConstant(constant, tool.getMetaAccess());
         }
         return this;