changeset 18362:ea0fbb571466

Use pointer stamps in LoadHub and LoadMethod. Introduce explicit casts between Word and metaspace pointers.
author Roland Schatz <roland.schatz@oracle.com>
date Thu, 13 Nov 2014 11:12:25 +0100
parents 6ac7e9c85be6
children 9cbed4622c3c 656331a61829
files graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ResolvedJavaMethod.java graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ResolvedJavaType.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/AMD64HotSpotNodeLIRBuilder.java graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/replacements/HSAILNewObjectSnippets.java graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/AheadOfTimeCompilationTest.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/DefaultHotSpotLoweringProvider.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/HotSpotResolvedObjectType.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/CompressionNode.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/NewArrayStubCall.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/NewInstanceStubCall.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/type/NarrowPointerStamp.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/phases/LoadJavaMirrorWithKlassPhase.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ArrayCopySnippets.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/CheckCastDynamicSnippets.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/HotSpotNodeSubstitutions.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/HotSpotReplacementsUtil.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/InstanceOfSnippets.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/MonitorSnippets.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/NewObjectSnippets.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ObjectSubstitutions.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/TypeCheckSnippetUtils.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/NewArrayStub.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/NewInstanceStub.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/StubUtil.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ConstantNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/IntegerSwitchNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/LoadHubNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/LoadMethodNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/SwitchNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/LoadIndexedNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/TypeSwitchNode.java graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/info/MultiTypeGuardInlineInfo.java graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/info/TypeGuardInlineInfo.java graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/SnippetTemplate.java graal/com.oracle.graal.word/src/com/oracle/graal/word/ComparableWord.java graal/com.oracle.graal.word/src/com/oracle/graal/word/MethodPointer.java graal/com.oracle.graal.word/src/com/oracle/graal/word/Pointer.java graal/com.oracle.graal.word/src/com/oracle/graal/word/TypePointer.java graal/com.oracle.graal.word/src/com/oracle/graal/word/Word.java graal/com.oracle.graal.word/src/com/oracle/graal/word/nodes/LoadIndexedPointerNode.java graal/com.oracle.graal.word/src/com/oracle/graal/word/nodes/WordCastNode.java graal/com.oracle.graal.word/src/com/oracle/graal/word/phases/WordTypeRewriterPhase.java
diffstat 44 files changed, 410 insertions(+), 198 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ResolvedJavaMethod.java	Wed Nov 12 16:59:39 2014 +0100
+++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ResolvedJavaMethod.java	Thu Nov 13 11:12:25 2014 +0100
@@ -221,7 +221,7 @@
      *
      * @return a constant representing a reference to this method
      */
-    JavaConstant getEncoding();
+    Constant getEncoding();
 
     /**
      * Checks if this method is present in the virtual table for subtypes of the specified
--- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ResolvedJavaType.java	Wed Nov 12 16:59:39 2014 +0100
+++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ResolvedJavaType.java	Thu Nov 13 11:12:25 2014 +0100
@@ -42,7 +42,7 @@
      * Gets the runtime representation of the "hub" of this type--that is, the closest part of the
      * type representation which is typically stored in the object header.
      */
-    JavaConstant getObjectHub();
+    Constant getObjectHub();
 
     /**
      * Checks whether this type has a finalizer method.
--- a/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/StampFactory.java	Wed Nov 12 16:59:39 2014 +0100
+++ b/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/StampFactory.java	Thu Nov 13 11:12:25 2014 +0100
@@ -81,8 +81,11 @@
         }
 
         pointerStampCache[PointerType.Object.ordinal()] = objectStamp;
-        pointerStampCache[PointerType.Type.ordinal()] = new PointerStamp(PointerType.Type);
-        pointerStampCache[PointerType.Method.ordinal()] = new PointerStamp(PointerType.Method);
+        for (PointerType t : PointerType.values()) {
+            if (t != PointerType.Object) {
+                pointerStampCache[t.ordinal()] = new PointerStamp(t);
+            }
+        }
     }
 
     /**
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotNodeLIRBuilder.java	Wed Nov 12 16:59:39 2014 +0100
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotNodeLIRBuilder.java	Thu Nov 13 11:12:25 2014 +0100
@@ -133,7 +133,7 @@
 
         for (ParameterNode param : graph.getNodes(ParameterNode.class)) {
             Value paramValue = params[param.index()];
-            assert paramValue.getKind() == param.getKind().getStackKind();
+            assert paramValue.getLIRKind().equals(getLIRGeneratorTool().getLIRKind(param.stamp()));
             setResult(param, gen.emitMove(paramValue));
         }
     }
--- a/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/replacements/HSAILNewObjectSnippets.java	Wed Nov 12 16:59:39 2014 +0100
+++ b/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/replacements/HSAILNewObjectSnippets.java	Thu Nov 13 11:12:25 2014 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -159,7 +159,7 @@
         return result;
     }
 
-    protected static Object addressToFormattedObject(Word addr, @ConstantParameter int size, Word hub, Word prototypeMarkWord, @ConstantParameter boolean fillContents,
+    protected static Object addressToFormattedObject(Word addr, @ConstantParameter int size, TypePointer hub, Word prototypeMarkWord, @ConstantParameter boolean fillContents,
                     @ConstantParameter String typeContext) {
         Object result = formatObject(hub, size, addr, prototypeMarkWord, fillContents, true, true);
         profileAllocation("instance", size, typeContext);
@@ -167,7 +167,7 @@
     }
 
     @Snippet
-    public static Object allocateInstanceAtomic(@ConstantParameter int size, Word hub, Word prototypeMarkWord, @ConstantParameter boolean fillContents, @ConstantParameter String typeContext) {
+    public static Object allocateInstanceAtomic(@ConstantParameter int size, TypePointer hub, Word prototypeMarkWord, @ConstantParameter boolean fillContents, @ConstantParameter String typeContext) {
         boolean haveResult = false;
         if (useTLAB()) {
             // inlining this manually here because it resulted in better fastpath codegen
@@ -206,7 +206,7 @@
     }
 
     @Snippet
-    public static Object allocateArrayAtomic(Word hub, int length, Word prototypeMarkWord, @ConstantParameter int headerSize, @ConstantParameter int log2ElementSize,
+    public static Object allocateArrayAtomic(TypePointer hub, int length, Word prototypeMarkWord, @ConstantParameter int headerSize, @ConstantParameter int log2ElementSize,
                     @ConstantParameter boolean fillContents, @ConstantParameter boolean maybeUnroll, @ConstantParameter String typeContext) {
         if (!belowThan(length, MAX_ARRAY_FAST_PATH_ALLOCATION_LENGTH)) {
             // This handles both negative array sizes and very large array sizes
@@ -215,7 +215,7 @@
         return allocateArrayAtomicImpl(hub, length, prototypeMarkWord, headerSize, log2ElementSize, fillContents, maybeUnroll, typeContext);
     }
 
-    protected static Object addressToFormattedArray(Word addr, int allocationSize, int length, int headerSize, Word hub, Word prototypeMarkWord, boolean fillContents, boolean maybeUnroll,
+    protected static Object addressToFormattedArray(Word addr, int allocationSize, int length, int headerSize, TypePointer hub, Word prototypeMarkWord, boolean fillContents, boolean maybeUnroll,
                     @ConstantParameter String typeContext) {
         // we are not in a stub so we can set useSnippetCounters to true
         Object result = formatArray(hub, allocationSize, length, headerSize, addr, prototypeMarkWord, fillContents, maybeUnroll, true);
@@ -223,7 +223,8 @@
         return piArrayCast(verifyOop(result), length, StampFactory.forNodeIntrinsic());
     }
 
-    private static Object allocateArrayAtomicImpl(Word hub, int length, Word prototypeMarkWord, int headerSize, int log2ElementSize, boolean fillContents, boolean maybeUnroll, String typeContext) {
+    private static Object allocateArrayAtomicImpl(TypePointer hub, int length, Word prototypeMarkWord, int headerSize, int log2ElementSize, boolean fillContents, boolean maybeUnroll,
+                    String typeContext) {
         int alignment = wordSize();
         int allocationSize = computeArrayAllocationSize(length, alignment, headerSize, log2ElementSize);
         boolean haveResult = false;
@@ -282,7 +283,7 @@
             StructuredGraph graph = newInstanceNode.graph();
             HotSpotResolvedObjectType type = (HotSpotResolvedObjectType) newInstanceNode.instanceClass();
             assert !type.isArray();
-            ConstantNode hub = ConstantNode.forConstant(type.klass(), providers.getMetaAccess(), graph);
+            ConstantNode hub = ConstantNode.forConstant(StampFactory.forPointer(PointerType.Type), type.klass(), providers.getMetaAccess(), graph);
             int size = instanceSize(type);
 
             Arguments args = new Arguments(allocateInstance, graph.getGuardsStage(), tool.getLoweringStage());
@@ -305,7 +306,7 @@
             ResolvedJavaType elementType = newArrayNode.elementType();
             HotSpotResolvedObjectType arrayType = (HotSpotResolvedObjectType) elementType.getArrayClass();
             Kind elementKind = elementType.getKind();
-            ConstantNode hub = ConstantNode.forConstant(arrayType.klass(), providers.getMetaAccess(), graph);
+            ConstantNode hub = ConstantNode.forConstant(StampFactory.forPointer(PointerType.Type), arrayType.klass(), providers.getMetaAccess(), graph);
             final int headerSize = HotSpotGraalRuntime.getArrayBaseOffset(elementKind);
             // lowerer extends HotSpotLoweringProvider so we can just use that
             HotSpotLoweringProvider lowerer = (HotSpotLoweringProvider) providers.getLowerer();
--- a/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/AheadOfTimeCompilationTest.java	Wed Nov 12 16:59:39 2014 +0100
+++ b/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/AheadOfTimeCompilationTest.java	Thu Nov 13 11:12:25 2014 +0100
@@ -33,6 +33,7 @@
 import com.oracle.graal.api.code.CallingConvention.Type;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.api.runtime.*;
+import com.oracle.graal.compiler.common.type.*;
 import com.oracle.graal.compiler.test.*;
 import com.oracle.graal.graph.iterators.*;
 import com.oracle.graal.hotspot.meta.*;
@@ -67,7 +68,8 @@
     public void testStaticFinalObjectAOT() {
         StructuredGraph result = compile("getStaticFinalObject", true);
         assertDeepEquals(1, getConstantNodes(result).count());
-        assertDeepEquals(getCodeCache().getTarget().wordKind, getConstantNodes(result).first().getKind());
+        Stamp constantStamp = getConstantNodes(result).first().stamp();
+        Assert.assertTrue(constantStamp instanceof AbstractPointerStamp && ((AbstractPointerStamp) constantStamp).getType() == PointerType.Type);
         assertDeepEquals(2, result.getNodes(FloatingReadNode.class).count());
         assertDeepEquals(0, result.getNodes().filter(ReadNode.class).count());
     }
@@ -121,7 +123,8 @@
         StructuredGraph result = compile("getPrimitiveClassObject", true);
         NodeIterable<ConstantNode> filter = getConstantNodes(result);
         assertDeepEquals(1, filter.count());
-        assertDeepEquals(getCodeCache().getTarget().wordKind, filter.first().getKind());
+        Stamp constantStamp = filter.first().stamp();
+        Assert.assertTrue(constantStamp instanceof AbstractPointerStamp && ((AbstractPointerStamp) constantStamp).getType() == PointerType.Type);
 
         assertDeepEquals(2, result.getNodes(FloatingReadNode.class).count());
         assertDeepEquals(0, result.getNodes().filter(ReadNode.class).count());
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/DefaultHotSpotLoweringProvider.java	Wed Nov 12 16:59:39 2014 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/DefaultHotSpotLoweringProvider.java	Thu Nov 13 11:12:25 2014 +0100
@@ -396,7 +396,8 @@
         assert vtableEntryOffset > 0;
         // We use LocationNode.ANY_LOCATION for the reads that access the vtable
         // entry as HotSpot does not guarantee that this is a final value.
-        ReadNode metaspaceMethod = graph.add(ReadNode.create(hub, ConstantLocationNode.create(ANY_LOCATION, wordKind, vtableEntryOffset, graph), StampFactory.forKind(wordKind), BarrierType.NONE));
+        Stamp methodStamp = StampFactory.forPointer(PointerType.Method);
+        ReadNode metaspaceMethod = graph.add(ReadNode.create(hub, ConstantLocationNode.create(ANY_LOCATION, wordKind, vtableEntryOffset, graph), methodStamp, BarrierType.NONE));
         return metaspaceMethod;
     }
 
@@ -409,9 +410,9 @@
 
         Stamp hubStamp;
         if (config.useCompressedClassPointers) {
-            hubStamp = StampFactory.forInteger(32);
+            hubStamp = new NarrowPointerStamp(PointerType.Type, config.getKlassEncoding());
         } else {
-            hubStamp = StampFactory.forKind(wordKind);
+            hubStamp = StampFactory.forPointer(PointerType.Type);
         }
 
         FloatingReadNode memoryRead = graph.unique(FloatingReadNode.create(object, location, null, hubStamp, guard, BarrierType.NONE));
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotConstantReflectionProvider.java	Wed Nov 12 16:59:39 2014 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotConstantReflectionProvider.java	Thu Nov 13 11:12:25 2014 +0100
@@ -164,10 +164,6 @@
     public Constant readPointerConstant(PointerType type, Constant base, long displacement) {
         switch (type) {
             case Object:
-                if (base instanceof PrimitiveConstant && !(base instanceof HotSpotMetaspaceConstant)) {
-                    // FIXME: we lost a metaspace annotation somewhere
-                    return null;
-                }
                 return HotSpotObjectConstantImpl.forObject(readRawObject(base, displacement, false));
             case Type:
                 long klass = readRawValue(base, displacement, runtime.getTarget().wordSize * 8);
@@ -185,10 +181,6 @@
     public Constant readNarrowPointerConstant(PointerType type, Constant base, long displacement) {
         switch (type) {
             case Object:
-                if (base instanceof PrimitiveConstant && !(base instanceof HotSpotMetaspaceConstant)) {
-                    // FIXME: we lost a metaspace annotation somewhere
-                    return null;
-                }
                 return HotSpotObjectConstantImpl.forObject(readRawObject(base, displacement, true), true);
             case Type:
                 int compressed = (int) readRawValue(base, displacement, 32);
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedObjectType.java	Wed Nov 12 16:59:39 2014 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedObjectType.java	Thu Nov 13 11:12:25 2014 +0100
@@ -80,7 +80,7 @@
     /**
      * Gets the metaspace Klass boxed in a {@link JavaConstant}.
      */
-    JavaConstant klass();
+    Constant klass();
 
     boolean isPrimaryType();
 
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/CompressionNode.java	Wed Nov 12 16:59:39 2014 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/CompressionNode.java	Thu Nov 13 11:12:25 2014 +0100
@@ -140,10 +140,9 @@
                 if (input instanceof ObjectStamp) {
                     // compressed oop
                     return NarrowOopStamp.compressed((ObjectStamp) input, encoding);
-                } else if (input instanceof IntegerStamp) {
+                } else if (input instanceof PointerStamp) {
                     // compressed metaspace pointer
-                    assert PrimitiveStamp.getBits(input) == 64;
-                    return StampFactory.forInteger(32);
+                    return new NarrowPointerStamp(((PointerStamp) input).getType(), encoding);
                 }
                 break;
             case Uncompress:
@@ -151,10 +150,9 @@
                     // oop
                     assert encoding.equals(((NarrowOopStamp) input).getEncoding());
                     return ((NarrowOopStamp) input).uncompressed();
-                } else if (input instanceof IntegerStamp) {
+                } else if (input instanceof NarrowPointerStamp) {
                     // metaspace pointer
-                    assert PrimitiveStamp.getBits(input) == 32;
-                    return StampFactory.forInteger(64);
+                    return StampFactory.forPointer(((NarrowPointerStamp) input).getType());
                 }
                 break;
         }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/NewArrayStubCall.java	Wed Nov 12 16:59:39 2014 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/NewArrayStubCall.java	Thu Nov 13 11:12:25 2014 +0100
@@ -72,5 +72,5 @@
     }
 
     @NodeIntrinsic
-    public static native Object call(Word hub, int length);
+    public static native Object call(TypePointer hub, int length);
 }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/NewInstanceStubCall.java	Wed Nov 12 16:59:39 2014 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/NewInstanceStubCall.java	Thu Nov 13 11:12:25 2014 +0100
@@ -70,5 +70,5 @@
     }
 
     @NodeIntrinsic
-    public static native Object call(Word hub);
+    public static native Object call(TypePointer hub);
 }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/type/NarrowPointerStamp.java	Wed Nov 12 16:59:39 2014 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/type/NarrowPointerStamp.java	Thu Nov 13 11:12:25 2014 +0100
@@ -96,4 +96,9 @@
     public boolean isLegal() {
         return true;
     }
+
+    @Override
+    public String toString() {
+        return "narrow " + super.toString();
+    }
 }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/phases/LoadJavaMirrorWithKlassPhase.java	Wed Nov 12 16:59:39 2014 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/phases/LoadJavaMirrorWithKlassPhase.java	Thu Nov 13 11:12:25 2014 +0100
@@ -66,7 +66,7 @@
             if (c != null) {
                 MetaAccessProvider metaAccess = context.getMetaAccess();
                 ResolvedJavaType type = c;
-                JavaConstant klass;
+                Constant klass;
                 LocationNode location;
                 if (type instanceof HotSpotResolvedObjectType) {
                     location = ConstantLocationNode.create(CLASS_MIRROR_LOCATION, Kind.Object, classMirrorOffset, graph);
@@ -92,7 +92,7 @@
                     }
                     location = ConstantLocationNode.create(FINAL_LOCATION, Kind.Object, typeField.offset(), graph);
                 }
-                ConstantNode klassNode = ConstantNode.forConstant(klass, metaAccess, graph);
+                ConstantNode klassNode = ConstantNode.forConstant(StampFactory.forPointer(PointerType.Type), klass, metaAccess, graph);
 
                 Stamp stamp = StampFactory.exactNonNull(metaAccess.lookupJavaType(Class.class));
                 FloatingReadNode freadNode = graph.unique(FloatingReadNode.create(klassNode, location, null, stamp));
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ArrayCopySnippets.java	Wed Nov 12 16:59:39 2014 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ArrayCopySnippets.java	Thu Nov 13 11:12:25 2014 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
+ * 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
@@ -93,7 +93,7 @@
         UnsafeArrayCopyNode.arraycopy(nonNullSrc, srcPos, nonNullDest, destPos, length, baseKind);
     }
 
-    private static int checkArrayType(Word hub) {
+    private static int checkArrayType(Pointer hub) {
         int layoutHelper = readLayoutHelper(hub);
         if (probability(SLOW_PATH_PROBABILITY, layoutHelper >= 0)) {
             DeoptimizeNode.deopt(DeoptimizationAction.None, DeoptimizationReason.RuntimeConstraint);
@@ -183,8 +183,8 @@
     public static void arraycopy(Object src, int srcPos, Object dest, int destPos, int length) {
         Object nonNullSrc = guardingNonNull(src);
         Object nonNullDest = guardingNonNull(dest);
-        Word srcHub = loadHub(nonNullSrc);
-        Word destHub = loadHub(nonNullDest);
+        Pointer srcHub = loadHub(nonNullSrc);
+        Pointer destHub = loadHub(nonNullDest);
         if (probability(FAST_PATH_PROBABILITY, srcHub.equal(destHub)) && probability(FAST_PATH_PROBABILITY, nonNullSrc != nonNullDest)) {
             int layoutHelper = checkArrayType(srcHub);
             final boolean isObjectArray = ((layoutHelper & layoutHelperElementTypePrimitiveInPlace()) == 0);
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/CheckCastDynamicSnippets.java	Wed Nov 12 16:59:39 2014 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/CheckCastDynamicSnippets.java	Thu Nov 13 11:12:25 2014 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -56,7 +56,7 @@
             isNull.inc();
         } else {
             GuardingNode anchorNode = SnippetAnchorNode.anchor();
-            Word objectHub = loadHubIntrinsic(object, getWordKind(), anchorNode);
+            Pointer objectHub = Word.fromTypePointer(loadHubIntrinsic(object, anchorNode));
             if (!checkUnknownSubType(hub, objectHub)) {
                 DeoptimizeNode.deopt(InvalidateReprofile, ClassCastException);
             }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/HotSpotNodeSubstitutions.java	Wed Nov 12 16:59:39 2014 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/HotSpotNodeSubstitutions.java	Thu Nov 13 11:12:25 2014 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * 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
@@ -41,7 +41,7 @@
         // HotSpot creates the NodeClass for each Node subclass while initializing it
         // so we are guaranteed to read a non-null value here. As long as NodeClass
         // is final, the stamp of the PiNode below will automatically be exact.
-        Word klass = loadHub(node);
+        Pointer klass = loadHub(node);
         return piCastNonNull(klass.readObject(Word.signed(instanceKlassNodeClassOffset()), KLASS_NODE_CLASS), NodeClass.class);
     }
 }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/HotSpotReplacementsUtil.java	Wed Nov 12 16:59:39 2014 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/HotSpotReplacementsUtil.java	Thu Nov 13 11:12:25 2014 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -297,7 +297,7 @@
         return config().klassLayoutHelperOffset;
     }
 
-    public static int readLayoutHelper(Word hub) {
+    public static int readLayoutHelper(Pointer hub) {
         return hub.readInt(klassLayoutHelperOffset(), KLASS_LAYOUT_HELPER_LOCATION);
     }
 
@@ -349,7 +349,7 @@
         return config().hubOffset;
     }
 
-    public static void initializeObjectHeader(Word memory, Word markWord, Word hub) {
+    public static void initializeObjectHeader(Word memory, Word markWord, TypePointer hub) {
         memory.writeWord(markOffset(), markWord, MARK_WORD_LOCATION);
         StoreHubNode.write(memory, hub);
     }
@@ -540,8 +540,8 @@
     /**
      * Loads the hub of an object (without null checking it first).
      */
-    public static Word loadHub(Object object) {
-        return loadHubIntrinsic(object, getWordKind());
+    public static Pointer loadHub(Object object) {
+        return Word.fromTypePointer(loadHubIntrinsic(object));
     }
 
     public static Object verifyOop(Object object) {
@@ -587,15 +587,14 @@
     }
 
     @SuppressWarnings("unused")
-    @NodeIntrinsic(value = LoadHubNode.class, setStampFromReturnType = true)
-    public static Word loadHubIntrinsic(Object object, @ConstantNodeParameter Kind word, GuardingNode anchor) {
-        return Word.unsigned(unsafeReadKlassPointer(object));
+    @NodeIntrinsic(value = LoadHubNode.class)
+    public static TypePointer loadHubIntrinsic(Object object, GuardingNode anchor) {
+        return Word.unsigned(unsafeReadKlassPointer(object)).toTypePointer();
     }
 
-    @SuppressWarnings("unused")
-    @NodeIntrinsic(value = LoadHubNode.class, setStampFromReturnType = true)
-    public static Word loadHubIntrinsic(Object object, @ConstantNodeParameter Kind word) {
-        return Word.unsigned(unsafeReadKlassPointer(object));
+    @NodeIntrinsic(value = LoadHubNode.class)
+    public static TypePointer loadHubIntrinsic(Object object) {
+        return Word.unsigned(unsafeReadKlassPointer(object)).toTypePointer();
     }
 
     @Fold
@@ -620,11 +619,11 @@
      * @param hub the hub of an InstanceKlass
      * @return true is the InstanceKlass represented by hub is fully initialized
      */
-    public static boolean isInstanceKlassFullyInitialized(Word hub) {
+    public static boolean isInstanceKlassFullyInitialized(Pointer hub) {
         return readInstanceKlassState(hub) == instanceKlassStateFullyInitialized();
     }
 
-    private static byte readInstanceKlassState(Word hub) {
+    private static byte readInstanceKlassState(Pointer hub) {
         return hub.readByte(instanceKlassInitStateOffset(), CLASS_STATE_LOCATION);
     }
 
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/InstanceOfSnippets.java	Wed Nov 12 16:59:39 2014 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/InstanceOfSnippets.java	Thu Nov 13 11:12:25 2014 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -80,7 +80,7 @@
      * @see #hintHitProbabilityThresholdForDeoptimizingSnippet()
      */
     @Snippet
-    public static Object instanceofWithProfile(Object object, @VarargsParameter Word[] hints, @VarargsParameter boolean[] hintIsPositive, Object trueValue, Object falseValue,
+    public static Object instanceofWithProfile(Object object, @VarargsParameter TypePointer[] hints, @VarargsParameter boolean[] hintIsPositive, Object trueValue, Object falseValue,
                     @ConstantParameter boolean nullSeen) {
         if (probability(NOT_FREQUENT_PROBABILITY, object == null)) {
             isNull.inc();
@@ -92,13 +92,13 @@
             return falseValue;
         }
         GuardingNode anchorNode = SnippetAnchorNode.anchor();
-        Word objectHub = loadHubIntrinsic(object, getWordKind(), anchorNode);
+        TypePointer objectHub = loadHubIntrinsic(object, anchorNode);
         // if we get an exact match: succeed immediately
         ExplodeLoopNode.explodeLoop();
         for (int i = 0; i < hints.length; i++) {
-            Word hintHub = hints[i];
+            TypePointer hintHub = hints[i];
             boolean positive = hintIsPositive[i];
-            if (probability(NOT_FREQUENT_PROBABILITY, hintHub.equal(objectHub))) {
+            if (probability(NOT_FREQUENT_PROBABILITY, Word.equal(hintHub, objectHub))) {
                 hintsHit.inc();
                 return positive ? trueValue : falseValue;
             }
@@ -115,14 +115,14 @@
      * A test against a final type.
      */
     @Snippet
-    public static Object instanceofExact(Object object, Word exactHub, Object trueValue, Object falseValue) {
+    public static Object instanceofExact(Object object, TypePointer exactHub, Object trueValue, Object falseValue) {
         if (probability(NOT_FREQUENT_PROBABILITY, object == null)) {
             isNull.inc();
             return falseValue;
         }
         GuardingNode anchorNode = SnippetAnchorNode.anchor();
-        Word objectHub = loadHubIntrinsic(object, getWordKind(), anchorNode);
-        if (probability(LIKELY_PROBABILITY, objectHub.notEqual(exactHub))) {
+        TypePointer objectHub = loadHubIntrinsic(object, anchorNode);
+        if (probability(LIKELY_PROBABILITY, Word.notEqual(objectHub, exactHub))) {
             exactMiss.inc();
             return falseValue;
         }
@@ -134,14 +134,14 @@
      * A test against a primary type.
      */
     @Snippet
-    public static Object instanceofPrimary(Word hub, Object object, @ConstantParameter int superCheckOffset, Object trueValue, Object falseValue) {
+    public static Object instanceofPrimary(TypePointer hub, Object object, @ConstantParameter int superCheckOffset, Object trueValue, Object falseValue) {
         if (probability(NOT_FREQUENT_PROBABILITY, object == null)) {
             isNull.inc();
             return falseValue;
         }
         GuardingNode anchorNode = SnippetAnchorNode.anchor();
-        Word objectHub = loadHubIntrinsic(object, getWordKind(), anchorNode);
-        if (probability(NOT_LIKELY_PROBABILITY, objectHub.readWord(superCheckOffset, PRIMARY_SUPERS_LOCATION).notEqual(hub))) {
+        Pointer objectHub = Word.fromTypePointer(loadHubIntrinsic(object, anchorNode));
+        if (probability(NOT_LIKELY_PROBABILITY, objectHub.readWord(superCheckOffset, PRIMARY_SUPERS_LOCATION).notEqual(Word.fromTypePointer(hub)))) {
             displayMiss.inc();
             return falseValue;
         }
@@ -153,24 +153,24 @@
      * A test against a restricted secondary type type.
      */
     @Snippet
-    public static Object instanceofSecondary(Word hub, Object object, @VarargsParameter Word[] hints, @VarargsParameter boolean[] hintIsPositive, Object trueValue, Object falseValue) {
+    public static Object instanceofSecondary(TypePointer hub, Object object, @VarargsParameter TypePointer[] hints, @VarargsParameter boolean[] hintIsPositive, Object trueValue, Object falseValue) {
         if (probability(NOT_FREQUENT_PROBABILITY, object == null)) {
             isNull.inc();
             return falseValue;
         }
         GuardingNode anchorNode = SnippetAnchorNode.anchor();
-        Word objectHub = loadHubIntrinsic(object, getWordKind(), anchorNode);
+        Pointer objectHub = Word.fromTypePointer(loadHubIntrinsic(object, anchorNode));
         // if we get an exact match: succeed immediately
         ExplodeLoopNode.explodeLoop();
         for (int i = 0; i < hints.length; i++) {
-            Word hintHub = hints[i];
+            Pointer hintHub = Word.fromTypePointer(hints[i]);
             boolean positive = hintIsPositive[i];
             if (probability(NOT_FREQUENT_PROBABILITY, hintHub.equal(objectHub))) {
                 hintsHit.inc();
                 return positive ? trueValue : falseValue;
             }
         }
-        if (!checkSecondarySubType(hub, objectHub)) {
+        if (!checkSecondarySubType(Word.fromTypePointer(hub), objectHub)) {
             return falseValue;
         }
         return trueValue;
@@ -187,7 +187,7 @@
         }
         GuardingNode anchorNode = SnippetAnchorNode.anchor();
         Word hub = loadWordFromObject(mirror, klassOffset(), CLASS_KLASS_LOCATION);
-        Word objectHub = loadHubIntrinsic(object, getWordKind(), anchorNode);
+        Pointer objectHub = Word.fromTypePointer(loadHubIntrinsic(object, anchorNode));
         if (hub.equal(0) || !checkUnknownSubType(hub, objectHub)) {
             return falseValue;
         }
@@ -226,7 +226,7 @@
                 ValueNode object = instanceOf.getValue();
                 TypeCheckHints hintInfo = new TypeCheckHints(instanceOf.type(), instanceOf.profile(), tool.assumptions(), TypeCheckMinProfileHitProbability.getValue(), TypeCheckMaxHints.getValue());
                 final HotSpotResolvedObjectType type = (HotSpotResolvedObjectType) instanceOf.type();
-                ConstantNode hub = ConstantNode.forConstant(type.klass(), providers.getMetaAccess(), instanceOf.graph());
+                ConstantNode hub = ConstantNode.forConstant(StampFactory.forPointer(PointerType.Type), type.klass(), providers.getMetaAccess(), instanceOf.graph());
 
                 Arguments args;
 
@@ -235,13 +235,12 @@
                     Hints hints = createHints(hintInfo, providers.getMetaAccess(), false, graph);
                     args = new Arguments(instanceofWithProfile, graph.getGuardsStage(), tool.getLoweringStage());
                     args.add("object", object);
-                    Kind wordKind = providers.getCodeCache().getTarget().wordKind;
-                    args.addVarargs("hints", Word.class, StampFactory.forKind(wordKind), hints.hubs);
+                    args.addVarargs("hints", TypePointer.class, StampFactory.forPointer(PointerType.Type), hints.hubs);
                     args.addVarargs("hintIsPositive", boolean.class, StampFactory.forKind(Kind.Boolean), hints.isPositive);
                 } else if (hintInfo.exact != null) {
                     args = new Arguments(instanceofExact, graph.getGuardsStage(), tool.getLoweringStage());
                     args.add("object", object);
-                    args.add("exactHub", ConstantNode.forConstant(((HotSpotResolvedObjectType) hintInfo.exact).klass(), providers.getMetaAccess(), graph));
+                    args.add("exactHub", ConstantNode.forConstant(StampFactory.forPointer(PointerType.Type), ((HotSpotResolvedObjectType) hintInfo.exact).klass(), providers.getMetaAccess(), graph));
                 } else if (type.isPrimaryType()) {
                     args = new Arguments(instanceofPrimary, graph.getGuardsStage(), tool.getLoweringStage());
                     args.add("hub", hub);
@@ -252,7 +251,7 @@
                     args = new Arguments(instanceofSecondary, graph.getGuardsStage(), tool.getLoweringStage());
                     args.add("hub", hub);
                     args.add("object", object);
-                    args.addVarargs("hints", Word.class, StampFactory.forKind(getWordKind()), hints.hubs);
+                    args.addVarargs("hints", TypePointer.class, StampFactory.forPointer(PointerType.Type), hints.hubs);
                     args.addVarargs("hintIsPositive", boolean.class, StampFactory.forKind(Kind.Boolean), hints.isPositive);
                 }
                 args.add("trueValue", replacer.trueValue);
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/MonitorSnippets.java	Wed Nov 12 16:59:39 2014 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/MonitorSnippets.java	Thu Nov 13 11:12:25 2014 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -128,7 +128,7 @@
             } else {
                 // The bias pattern is present in the object's mark word. Need to check
                 // whether the bias owner and the epoch are both still current.
-                Word hub = loadHubIntrinsic(object, getWordKind(), anchorNode);
+                Pointer hub = Word.fromTypePointer(loadHubIntrinsic(object, anchorNode));
                 final Word prototypeMarkWord = hub.readWord(prototypeMarkWordOffset(), PROTOTYPE_MARK_WORD_LOCATION);
                 final Word thread = registerAsWord(threadRegister);
                 final Word tmp = prototypeMarkWord.or(thread).xor(mark).and(~ageMaskInPlace());
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/NewObjectSnippets.java	Wed Nov 12 16:59:39 2014 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/NewObjectSnippets.java	Thu Nov 13 11:12:25 2014 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -130,7 +130,7 @@
     }
 
     @Snippet
-    public static Object allocateInstance(@ConstantParameter int size, Word hub, Word prototypeMarkWord, @ConstantParameter boolean fillContents, @ConstantParameter Register threadRegister,
+    public static Object allocateInstance(@ConstantParameter int size, TypePointer hub, Word prototypeMarkWord, @ConstantParameter boolean fillContents, @ConstantParameter Register threadRegister,
                     @ConstantParameter boolean constantSize, @ConstantParameter String typeContext) {
         Object result;
         Word thread = registerAsWord(threadRegister);
@@ -163,7 +163,7 @@
                  */
                 if (probability(FAST_PATH_PROBABILITY, (layoutHelper & 1) == 0)) {
                     Word prototypeMarkWord = hub.readWord(prototypeMarkWordOffset(), PROTOTYPE_MARK_WORD_LOCATION);
-                    return allocateInstance(layoutHelper, hub, prototypeMarkWord, fillContents, threadRegister, false, typeContext);
+                    return allocateInstance(layoutHelper, hub.toTypePointer(), prototypeMarkWord, fillContents, threadRegister, false, typeContext);
                 }
             }
         }
@@ -176,12 +176,12 @@
     public static final int MAX_ARRAY_FAST_PATH_ALLOCATION_LENGTH = 0x00FFFFFF;
 
     @Snippet
-    public static Object allocateArray(Word hub, int length, Word prototypeMarkWord, @ConstantParameter int headerSize, @ConstantParameter int log2ElementSize,
+    public static Object allocateArray(TypePointer hub, int length, Word prototypeMarkWord, @ConstantParameter int headerSize, @ConstantParameter int log2ElementSize,
                     @ConstantParameter boolean fillContents, @ConstantParameter Register threadRegister, @ConstantParameter boolean maybeUnroll, @ConstantParameter String typeContext) {
         return allocateArrayImpl(hub, length, prototypeMarkWord, headerSize, log2ElementSize, fillContents, threadRegister, maybeUnroll, typeContext, false);
     }
 
-    private static Object allocateArrayImpl(Word hub, int length, Word prototypeMarkWord, int headerSize, int log2ElementSize, boolean fillContents, @ConstantParameter Register threadRegister,
+    private static Object allocateArrayImpl(TypePointer hub, int length, Word prototypeMarkWord, int headerSize, int log2ElementSize, boolean fillContents, @ConstantParameter Register threadRegister,
                     @ConstantParameter boolean maybeUnroll, String typeContext, boolean skipNegativeCheck) {
         Object result;
         int alignment = wordSize();
@@ -241,7 +241,7 @@
         int log2ElementSize = (layoutHelper >> layoutHelperLog2ElementSizeShift()) & layoutHelperLog2ElementSizeMask();
         Word prototypeMarkWord = hub.readWord(prototypeMarkWordOffset(), PROTOTYPE_MARK_WORD_LOCATION);
 
-        return allocateArrayImpl(hub, length, prototypeMarkWord, headerSize, log2ElementSize, fillContents, threadRegister, false, "dynamic type", true);
+        return allocateArrayImpl(hub.toTypePointer(), length, prototypeMarkWord, headerSize, log2ElementSize, fillContents, threadRegister, false, "dynamic type", true);
     }
 
     /**
@@ -335,15 +335,15 @@
      * Formats some allocated memory with an object header and zeroes out the rest. Disables asserts
      * since they can't be compiled in stubs.
      */
-    public static Object formatObjectForStub(Word hub, int size, Word memory, Word compileTimePrototypeMarkWord) {
+    public static Object formatObjectForStub(TypePointer hub, int size, Word memory, Word compileTimePrototypeMarkWord) {
         return formatObject(hub, size, memory, compileTimePrototypeMarkWord, true, false, false);
     }
 
     /**
      * Formats some allocated memory with an object header and zeroes out the rest.
      */
-    protected static Object formatObject(Word hub, int size, Word memory, Word compileTimePrototypeMarkWord, boolean fillContents, boolean constantSize, boolean useSnippetCounters) {
-        Word prototypeMarkWord = useBiasedLocking() ? hub.readWord(prototypeMarkWordOffset(), PROTOTYPE_MARK_WORD_LOCATION) : compileTimePrototypeMarkWord;
+    protected static Object formatObject(TypePointer hub, int size, Word memory, Word compileTimePrototypeMarkWord, boolean fillContents, boolean constantSize, boolean useSnippetCounters) {
+        Word prototypeMarkWord = useBiasedLocking() ? Word.fromTypePointer(hub).readWord(prototypeMarkWordOffset(), PROTOTYPE_MARK_WORD_LOCATION) : compileTimePrototypeMarkWord;
         initializeObjectHeader(memory, prototypeMarkWord, hub);
         if (fillContents) {
             zeroMemory(size, memory, constantSize, instanceHeaderSize(), false, useSnippetCounters);
@@ -354,7 +354,7 @@
     /**
      * Formats some allocated memory with an object header and zeroes out the rest.
      */
-    public static Object formatArray(Word hub, int allocationSize, int length, int headerSize, Word memory, Word prototypeMarkWord, boolean fillContents, boolean maybeUnroll,
+    public static Object formatArray(TypePointer hub, int allocationSize, int length, int headerSize, Word memory, Word prototypeMarkWord, boolean fillContents, boolean maybeUnroll,
                     boolean useSnippetCounters) {
         memory.writeInt(arrayLengthOffset(), length, INIT_LOCATION);
         /*
@@ -387,7 +387,7 @@
             StructuredGraph graph = newInstanceNode.graph();
             HotSpotResolvedObjectType type = (HotSpotResolvedObjectType) newInstanceNode.instanceClass();
             assert !type.isArray();
-            ConstantNode hub = ConstantNode.forConstant(type.klass(), providers.getMetaAccess(), graph);
+            ConstantNode hub = ConstantNode.forConstant(StampFactory.forPointer(PointerType.Type), type.klass(), providers.getMetaAccess(), graph);
             int size = instanceSize(type);
 
             Arguments args = new Arguments(allocateInstance, graph.getGuardsStage(), tool.getLoweringStage());
@@ -412,7 +412,7 @@
             ResolvedJavaType elementType = newArrayNode.elementType();
             HotSpotResolvedObjectType arrayType = (HotSpotResolvedObjectType) elementType.getArrayClass();
             Kind elementKind = elementType.getKind();
-            ConstantNode hub = ConstantNode.forConstant(arrayType.klass(), providers.getMetaAccess(), graph);
+            ConstantNode hub = ConstantNode.forConstant(StampFactory.forPointer(PointerType.Type), arrayType.klass(), providers.getMetaAccess(), graph);
             final int headerSize = HotSpotGraalRuntime.getArrayBaseOffset(elementKind);
             HotSpotLoweringProvider lowerer = (HotSpotLoweringProvider) providers.getLowerer();
             int log2ElementSize = CodeUtil.log2(lowerer.arrayScalingFactor(elementKind));
@@ -465,7 +465,7 @@
                 dims[i] = newmultiarrayNode.dimension(i);
             }
             HotSpotResolvedObjectType type = (HotSpotResolvedObjectType) newmultiarrayNode.type();
-            ConstantNode hub = ConstantNode.forConstant(type.klass(), providers.getMetaAccess(), graph);
+            ConstantNode hub = ConstantNode.forConstant(StampFactory.forPointer(PointerType.Type), type.klass(), providers.getMetaAccess(), graph);
 
             Arguments args = new Arguments(newmultiarray, graph.getGuardsStage(), tool.getLoweringStage());
             args.add("hub", hub);
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ObjectSubstitutions.java	Wed Nov 12 16:59:39 2014 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ObjectSubstitutions.java	Thu Nov 13 11:12:25 2014 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -39,7 +39,7 @@
     @MacroSubstitution(macro = ObjectGetClassNode.class, isStatic = false, forced = true)
     @MethodSubstitution(isStatic = false, forced = true)
     public static Class<?> getClass(final Object thisObj) {
-        Word hub = loadHub(thisObj);
+        Pointer hub = loadHub(thisObj);
         return piCastExactNonNull(hub.readObject(Word.signed(classMirrorOffset()), CLASS_MIRROR_LOCATION), Class.class);
     }
 
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/TypeCheckSnippetUtils.java	Wed Nov 12 16:59:39 2014 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/TypeCheckSnippetUtils.java	Thu Nov 13 11:12:25 2014 +0100
@@ -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
@@ -30,6 +30,7 @@
 
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
+import com.oracle.graal.compiler.common.type.*;
 import com.oracle.graal.hotspot.meta.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.replacements.*;
@@ -42,7 +43,7 @@
  */
 public class TypeCheckSnippetUtils {
 
-    static boolean checkSecondarySubType(Word t, Word s) {
+    static boolean checkSecondarySubType(Pointer t, Pointer s) {
         // if (S.cache == T) return true
         if (s.readWord(secondarySuperCacheOffset(), SECONDARY_SUPER_CACHE_LOCATION).equal(t)) {
             cacheHit.inc();
@@ -52,7 +53,7 @@
         return checkSelfAndSupers(t, s);
     }
 
-    static boolean checkUnknownSubType(Word t, Word s) {
+    static boolean checkUnknownSubType(Pointer t, Pointer s) {
         // int off = T.offset
         int superCheckOffset = t.readInt(superCheckOffsetOffset(), KLASS_SUPER_CHECK_OFFSET_LOCATION);
         boolean primary = superCheckOffset != secondarySuperCacheOffset();
@@ -76,7 +77,7 @@
         return checkSelfAndSupers(t, s);
     }
 
-    private static boolean checkSelfAndSupers(Word t, Word s) {
+    private static boolean checkSelfAndSupers(Pointer t, Pointer s) {
         // if (T == S) return true
         if (s.equal(t)) {
             T_equals_S.inc();
@@ -125,7 +126,7 @@
         int index = 0;
         for (int i = 0; i < hubs.length; i++) {
             if (!positiveOnly || hints.hints[i].positive) {
-                hubs[index] = ConstantNode.forConstant(((HotSpotResolvedObjectType) hints.hints[i].type).klass(), metaAccess, graph);
+                hubs[index] = ConstantNode.forConstant(StampFactory.forPointer(PointerType.Type), ((HotSpotResolvedObjectType) hints.hints[i].type).klass(), metaAccess, graph);
                 isPositive[index] = hints.hints[i].positive;
                 index++;
             }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/NewArrayStub.java	Wed Nov 12 16:59:39 2014 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/NewArrayStub.java	Thu Nov 13 11:12:25 2014 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -29,6 +29,7 @@
 
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
+import com.oracle.graal.compiler.common.type.*;
 import com.oracle.graal.graph.Node.ConstantNodeParameter;
 import com.oracle.graal.graph.Node.NodeIntrinsic;
 import com.oracle.graal.hotspot.*;
@@ -63,7 +64,7 @@
         Arguments args = new Arguments(stub, GuardsStage.FLOATING_GUARDS, LoweringTool.StandardLoweringStage.HIGH_TIER);
         args.add("hub", null);
         args.add("length", null);
-        args.addConst("intArrayHub", intArrayType.klass());
+        args.addConst("intArrayHub", intArrayType.klass(), StampFactory.forPointer(PointerType.Type));
         args.addConst("threadRegister", providers.getRegisters().getThreadRegister());
         return args;
     }
@@ -82,8 +83,8 @@
      * @param intArrayHub the hub for {@code int[].class}
      */
     @Snippet
-    private static Object newArray(Word hub, int length, @ConstantParameter Word intArrayHub, @ConstantParameter Register threadRegister) {
-        int layoutHelper = hub.readInt(klassLayoutHelperOffset(), KLASS_LAYOUT_HELPER_LOCATION);
+    private static Object newArray(TypePointer hub, int length, @ConstantParameter TypePointer intArrayHub, @ConstantParameter Register threadRegister) {
+        int layoutHelper = Word.fromTypePointer(hub).readInt(klassLayoutHelperOffset(), KLASS_LAYOUT_HELPER_LOCATION);
         int log2ElementSize = (layoutHelper >> layoutHelperLog2ElementSizeShift()) & layoutHelperLog2ElementSizeMask();
         int headerSize = (layoutHelper >> layoutHelperHeaderSizeShift()) & layoutHelperHeaderSizeMask();
         int elementKind = (layoutHelper >> layoutHelperElementTypeShift()) & layoutHelperElementTypeMask();
@@ -92,7 +93,7 @@
             printf("newArray: element kind %d\n", elementKind);
             printf("newArray: array length %d\n", length);
             printf("newArray: array size %d\n", sizeInBytes);
-            printf("newArray: hub=%p\n", hub.rawValue());
+            printf("newArray: hub=%p\n", Word.fromTypePointer(hub).rawValue());
         }
 
         // check that array length is small enough for fast path.
@@ -115,8 +116,8 @@
         return verifyObject(getAndClearObjectResult(thread));
     }
 
-    public static final ForeignCallDescriptor NEW_ARRAY_C = newDescriptor(NewArrayStub.class, "newArrayC", void.class, Word.class, Word.class, int.class);
+    public static final ForeignCallDescriptor NEW_ARRAY_C = newDescriptor(NewArrayStub.class, "newArrayC", void.class, Word.class, TypePointer.class, int.class);
 
     @NodeIntrinsic(StubForeignCallNode.class)
-    public static native void newArrayC(@ConstantNodeParameter ForeignCallDescriptor newArrayC, Word thread, Word hub, int length);
+    public static native void newArrayC(@ConstantNodeParameter ForeignCallDescriptor newArrayC, Word thread, TypePointer hub, int length);
 }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/NewInstanceStub.java	Wed Nov 12 16:59:39 2014 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/NewInstanceStub.java	Thu Nov 13 11:12:25 2014 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -29,6 +29,7 @@
 
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
+import com.oracle.graal.compiler.common.type.*;
 import com.oracle.graal.graph.Node.ConstantNodeParameter;
 import com.oracle.graal.graph.Node.NodeIntrinsic;
 import com.oracle.graal.hotspot.*;
@@ -62,7 +63,7 @@
 
         Arguments args = new Arguments(stub, GuardsStage.FLOATING_GUARDS, LoweringTool.StandardLoweringStage.HIGH_TIER);
         args.add("hub", null);
-        args.addConst("intArrayHub", intArrayType.klass());
+        args.addConst("intArrayHub", intArrayType.klass(), StampFactory.forPointer(PointerType.Type));
         args.addConst("threadRegister", providers.getRegisters().getThreadRegister());
         return args;
     }
@@ -95,18 +96,19 @@
      * @param intArrayHub the hub for {@code int[].class}
      */
     @Snippet
-    private static Object newInstance(Word hub, @ConstantParameter Word intArrayHub, @ConstantParameter Register threadRegister) {
+    private static Object newInstance(TypePointer hub, @ConstantParameter TypePointer intArrayHub, @ConstantParameter Register threadRegister) {
         /*
          * The type is known to be an instance so Klass::_layout_helper is the instance size as a
          * raw number
          */
-        int sizeInBytes = hub.readInt(klassLayoutHelperOffset(), KLASS_LAYOUT_HELPER_LOCATION);
+        Pointer hubPtr = Word.fromTypePointer(hub);
+        int sizeInBytes = hubPtr.readInt(klassLayoutHelperOffset(), KLASS_LAYOUT_HELPER_LOCATION);
         Word thread = registerAsWord(threadRegister);
         if (!forceSlowPath() && inlineContiguousAllocationSupported()) {
-            if (isInstanceKlassFullyInitialized(hub)) {
+            if (isInstanceKlassFullyInitialized(hubPtr)) {
                 Word memory = refillAllocate(thread, intArrayHub, sizeInBytes, logging());
                 if (memory.notEqual(0)) {
-                    Word prototypeMarkWord = hub.readWord(prototypeMarkWordOffset(), PROTOTYPE_MARK_WORD_LOCATION);
+                    Word prototypeMarkWord = hubPtr.readWord(prototypeMarkWordOffset(), PROTOTYPE_MARK_WORD_LOCATION);
                     NewObjectSnippets.formatObjectForStub(hub, sizeInBytes, memory, prototypeMarkWord);
                     return verifyObject(memory.toObject());
                 }
@@ -132,7 +134,7 @@
      * @return the newly allocated, uninitialized chunk of memory, or {@link Word#zero()} if the
      *         operation was unsuccessful
      */
-    static Word refillAllocate(Word thread, Word intArrayHub, int sizeInBytes, boolean log) {
+    static Word refillAllocate(Word thread, TypePointer intArrayHub, int sizeInBytes, boolean log) {
         // If G1 is enabled, the "eden" allocation space is not the same always
         // and therefore we have to go to slowpath to allocate a new TLAB.
         if (useG1GC()) {
@@ -255,8 +257,8 @@
         return Boolean.getBoolean("graal.newInstanceStub.forceSlowPath");
     }
 
-    public static final ForeignCallDescriptor NEW_INSTANCE_C = newDescriptor(NewInstanceStub.class, "newInstanceC", void.class, Word.class, Word.class);
+    public static final ForeignCallDescriptor NEW_INSTANCE_C = newDescriptor(NewInstanceStub.class, "newInstanceC", void.class, Word.class, TypePointer.class);
 
     @NodeIntrinsic(StubForeignCallNode.class)
-    public static native void newInstanceC(@ConstantNodeParameter ForeignCallDescriptor newInstanceC, Word thread, Word hub);
+    public static native void newInstanceC(@ConstantNodeParameter ForeignCallDescriptor newInstanceC, Word thread, TypePointer hub);
 }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/StubUtil.java	Wed Nov 12 16:59:39 2014 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/StubUtil.java	Thu Nov 13 11:12:25 2014 +0100
@@ -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
@@ -229,7 +229,7 @@
                     fatal("oop not in heap: %p", oop.rawValue());
                 }
 
-                Word klass = loadHubIntrinsic(object, getWordKind(), anchorNode);
+                Pointer klass = Word.fromTypePointer(loadHubIntrinsic(object, anchorNode));
                 if (klass.equal(Word.zero())) {
                     fatal("klass for oop %p is null", oop.rawValue());
                 }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ConstantNode.java	Wed Nov 12 16:59:39 2014 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ConstantNode.java	Thu Nov 13 11:12:25 2014 +0100
@@ -61,11 +61,24 @@
 
     protected ConstantNode(Constant value, Stamp stamp) {
         super(stamp);
-        assert stamp != null;
+        assert stamp != null && isCompatible(value, stamp);
         this.value = value;
         ConstantNodes.increment();
     }
 
+    private static boolean isCompatible(Constant value, Stamp stamp) {
+        if (value instanceof VMConstant) {
+            assert stamp instanceof AbstractPointerStamp;
+        } else if (value instanceof PrimitiveConstant) {
+            if (((PrimitiveConstant) value).getKind() == Kind.Illegal) {
+                assert stamp instanceof IllegalStamp;
+            } else {
+                assert stamp instanceof PrimitiveStamp;
+            }
+        }
+        return true;
+    }
+
     /**
      * @return the constant value represented by this node
      */
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/IntegerSwitchNode.java	Wed Nov 12 16:59:39 2014 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/IntegerSwitchNode.java	Thu Nov 13 11:12:25 2014 +0100
@@ -60,7 +60,7 @@
         assert keySuccessors.length == keys.length + 1;
         assert keySuccessors.length == keyProbabilities.length;
         this.keys = keys;
-        assert assertValues();
+        assert value.stamp() instanceof PrimitiveStamp && value.stamp().getStackKind().isNumericInteger();
         assert assertSorted();
     }
 
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/LoadHubNode.java	Wed Nov 12 16:59:39 2014 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/LoadHubNode.java	Thu Nov 13 11:12:25 2014 +0100
@@ -41,29 +41,25 @@
         return value;
     }
 
-    public static LoadHubNode create(ValueNode value, Kind kind) {
-        return new LoadHubNode(value, kind);
+    public static LoadHubNode create(ValueNode value) {
+        return new LoadHubNode(value);
     }
 
-    protected LoadHubNode(ValueNode value, Kind kind) {
-        super(getKind(kind), null);
+    protected LoadHubNode(ValueNode value) {
+        super(StampFactory.forPointer(PointerType.Type), null);
         this.value = value;
     }
 
-    public static LoadHubNode create(ValueNode value, Kind kind, ValueNode guard) {
-        return new LoadHubNode(value, kind, guard);
+    public static LoadHubNode create(ValueNode value, ValueNode guard) {
+        return new LoadHubNode(value, guard);
     }
 
-    protected LoadHubNode(ValueNode value, Kind kind, ValueNode guard) {
-        super(getKind(kind), (GuardingNode) guard);
+    protected LoadHubNode(ValueNode value, ValueNode guard) {
+        super(StampFactory.forPointer(PointerType.Type), (GuardingNode) guard);
         assert value != guard;
         this.value = value;
     }
 
-    private static Stamp getKind(Kind kind) {
-        return kind == Kind.Object ? StampFactory.objectNonNull() : StampFactory.forKind(kind);
-    }
-
     @Override
     public void lower(LoweringTool tool) {
         tool.getLowerer().lower(this, tool);
@@ -88,7 +84,7 @@
             }
 
             if (exactType != null) {
-                return ConstantNode.forConstant(exactType.getObjectHub(), metaAccess);
+                return ConstantNode.forConstant(stamp(), exactType.getObjectHub(), metaAccess);
             }
         }
         return this;
@@ -98,8 +94,8 @@
     public void virtualize(VirtualizerTool tool) {
         State state = tool.getObjectState(value);
         if (state != null) {
-            JavaConstant constantHub = state.getVirtualObject().type().getObjectHub();
-            tool.replaceWithValue(ConstantNode.forConstant(constantHub, tool.getMetaAccessProvider(), graph()));
+            Constant constantHub = state.getVirtualObject().type().getObjectHub();
+            tool.replaceWithValue(ConstantNode.forConstant(stamp(), constantHub, tool.getMetaAccessProvider(), graph()));
         }
     }
 }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/LoadMethodNode.java	Wed Nov 12 16:59:39 2014 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/LoadMethodNode.java	Thu Nov 13 11:12:25 2014 +0100
@@ -45,12 +45,12 @@
         return hub;
     }
 
-    public static LoadMethodNode create(ResolvedJavaMethod method, ResolvedJavaType receiverType, ValueNode hub, Kind kind) {
-        return new LoadMethodNode(method, receiverType, hub, kind);
+    public static LoadMethodNode create(ResolvedJavaMethod method, ResolvedJavaType receiverType, ValueNode hub) {
+        return new LoadMethodNode(method, receiverType, hub);
     }
 
-    protected LoadMethodNode(ResolvedJavaMethod method, ResolvedJavaType receiverType, ValueNode hub, Kind kind) {
-        super(kind == Kind.Object ? StampFactory.objectNonNull() : StampFactory.forKind(kind));
+    protected LoadMethodNode(ResolvedJavaMethod method, ResolvedJavaType receiverType, ValueNode hub) {
+        super(StampFactory.forPointer(PointerType.Method));
         this.receiverType = receiverType;
         this.hub = hub;
         this.method = method;
@@ -76,7 +76,7 @@
                 ResolvedJavaMethod resolvedMethod = type.findUniqueConcreteMethod(method);
                 if (resolvedMethod != null && !type.isInterface() && method.getDeclaringClass().isAssignableFrom(type)) {
                     tool.assumptions().recordConcreteMethod(method, type, resolvedMethod);
-                    return ConstantNode.forConstant(resolvedMethod.getEncoding(), tool.getMetaAccess());
+                    return ConstantNode.forConstant(stamp(), resolvedMethod.getEncoding(), tool.getMetaAccess());
                 }
             }
         }
@@ -104,7 +104,7 @@
              */
             return ConstantNode.forConstant(JavaConstant.NULL_OBJECT, null);
         } else {
-            return ConstantNode.forConstant(newMethod.getEncoding(), tool.getMetaAccess());
+            return ConstantNode.forConstant(stamp(), newMethod.getEncoding(), tool.getMetaAccess());
         }
     }
 
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/SwitchNode.java	Wed Nov 12 16:59:39 2014 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/SwitchNode.java	Thu Nov 13 11:12:25 2014 +0100
@@ -52,7 +52,7 @@
      */
     public SwitchNode(ValueNode value, BeginNode[] successors, int[] keySuccessors, double[] keyProbabilities) {
         super(StampFactory.forVoid());
-        assert value.getKind() == Kind.Int || value.getKind() == Kind.Long || value.getKind() == Kind.Object : value.getKind() + " key not supported by SwitchNode";
+        assert value.stamp().getStackKind().isNumericInteger() || value.stamp() instanceof AbstractPointerStamp : value.stamp() + " key not supported by SwitchNode";
         assert keySuccessors.length == keyProbabilities.length;
         this.successors = new NodeSuccessorList<>(this, successors);
         this.value = value;
@@ -71,15 +71,6 @@
         return true;
     }
 
-    protected boolean assertValues() {
-        Kind kind = value.getKind();
-        for (int i = 0; i < keyCount(); i++) {
-            JavaConstant key = keyAt(i);
-            assert key.getKind() == kind;
-        }
-        return true;
-    }
-
     @Override
     public double probability(BeginNode successor) {
         double sum = 0;
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/LoadIndexedNode.java	Wed Nov 12 16:59:39 2014 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/LoadIndexedNode.java	Thu Nov 13 11:12:25 2014 +0100
@@ -43,11 +43,11 @@
      * @param elementKind the element type
      */
     public static LoadIndexedNode create(ValueNode array, ValueNode index, Kind elementKind) {
-        return new LoadIndexedNode(array, index, elementKind);
+        return new LoadIndexedNode(createStamp(array, elementKind), array, index, elementKind);
     }
 
-    protected LoadIndexedNode(ValueNode array, ValueNode index, Kind elementKind) {
-        super(createStamp(array, elementKind), array, index, elementKind);
+    protected LoadIndexedNode(Stamp stamp, ValueNode array, ValueNode index, Kind elementKind) {
+        super(stamp, array, index, elementKind);
     }
 
     private static Stamp createStamp(ValueNode array, Kind kind) {
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/TypeSwitchNode.java	Wed Nov 12 16:59:39 2014 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/TypeSwitchNode.java	Thu Nov 13 11:12:25 2014 +0100
@@ -61,7 +61,7 @@
         assert successors.length <= keys.length + 1;
         assert keySuccessors.length == keyProbabilities.length;
         this.keys = keys;
-        assert assertValues();
+        assert value.stamp() instanceof AbstractPointerStamp;
         assert assertKeys();
     }
 
@@ -105,7 +105,7 @@
 
     @Override
     public JavaConstant keyAt(int index) {
-        return keys[index].getObjectHub();
+        return (JavaConstant) keys[index].getObjectHub();
     }
 
     @Override
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/info/MultiTypeGuardInlineInfo.java	Wed Nov 12 16:59:39 2014 +0100
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/info/MultiTypeGuardInlineInfo.java	Thu Nov 13 11:12:25 2014 +0100
@@ -41,7 +41,7 @@
 import com.oracle.graal.nodes.util.*;
 import com.oracle.graal.phases.common.*;
 import com.oracle.graal.phases.common.inlining.*;
-import com.oracle.graal.phases.common.inlining.info.elem.Inlineable;
+import com.oracle.graal.phases.common.inlining.info.elem.*;
 import com.oracle.graal.phases.tiers.*;
 import com.oracle.graal.phases.util.*;
 
@@ -343,10 +343,7 @@
     private boolean createDispatchOnTypeBeforeInvoke(StructuredGraph graph, BeginNode[] successors, boolean invokeIsOnlySuccessor, MetaAccessProvider metaAccess) {
         assert ptypes.size() >= 1;
         ValueNode nonNullReceiver = InliningUtil.nonNullReceiver(invoke);
-        Constant hubConstant = ((MethodCallTargetNode) invoke.callTarget()).targetMethod().getDeclaringClass().getObjectHub();
-        Stamp hubStamp = ((StampProvider) hubConstant).stamp();
-        Kind hubKind = hubStamp.getStackKind();
-        LoadHubNode hub = graph.unique(LoadHubNode.create(nonNullReceiver, hubKind));
+        LoadHubNode hub = graph.unique(LoadHubNode.create(nonNullReceiver));
 
         if (!invokeIsOnlySuccessor && chooseMethodDispatch()) {
             assert successors.length == concretes.size() + 1;
@@ -357,9 +354,9 @@
             double[] probability = new double[concretes.size()];
             for (int i = 0; i < concretes.size(); ++i) {
                 ResolvedJavaMethod firstMethod = concretes.get(i);
-                JavaConstant firstMethodConstant = firstMethod.getEncoding();
+                Constant firstMethodConstant = firstMethod.getEncoding();
 
-                ConstantNode firstMethodConstantNode = ConstantNode.forConstant(firstMethodConstant, metaAccess, graph);
+                ConstantNode firstMethodConstantNode = ConstantNode.forConstant(StampFactory.forPointer(PointerType.Method), firstMethodConstant, metaAccess, graph);
                 constantMethods[i] = firstMethodConstantNode;
                 double concretesProbability = concretesProbabilities.get(i);
                 assert concretesProbability >= 0.0;
@@ -377,7 +374,7 @@
             ResolvedJavaType receiverType = invoke.getReceiverType();
             FixedNode lastSucc = successors[concretes.size()];
             for (int i = concretes.size() - 1; i >= 0; --i) {
-                LoadMethodNode method = graph.add(LoadMethodNode.create(concretes.get(i), receiverType, hub, constantMethods[i].getKind()));
+                LoadMethodNode method = graph.add(LoadMethodNode.create(concretes.get(i), receiverType, hub));
                 CompareNode methodCheck = CompareNode.createCompareNode(graph, Condition.EQ, method, constantMethods[i]);
                 IfNode ifNode = graph.add(IfNode.create(methodCheck, successors[i], lastSucc, probability[i]));
                 method.setNext(ifNode);
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/info/TypeGuardInlineInfo.java	Wed Nov 12 16:59:39 2014 +0100
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/info/TypeGuardInlineInfo.java	Thu Nov 13 11:12:25 2014 +0100
@@ -103,8 +103,8 @@
 
     private void createGuard(StructuredGraph graph, MetaAccessProvider metaAccess) {
         ValueNode nonNullReceiver = InliningUtil.nonNullReceiver(invoke);
-        ConstantNode typeHub = ConstantNode.forConstant(type.getObjectHub(), metaAccess, graph);
-        LoadHubNode receiverHub = graph.unique(LoadHubNode.create(nonNullReceiver, typeHub.getKind()));
+        LoadHubNode receiverHub = graph.unique(LoadHubNode.create(nonNullReceiver));
+        ConstantNode typeHub = ConstantNode.forConstant(receiverHub.stamp(), type.getObjectHub(), metaAccess, graph);
 
         CompareNode typeCheck = CompareNode.createCompareNode(graph, Condition.EQ, receiverHub, typeHub);
         FixedGuardNode guard = graph.add(FixedGuardNode.create(typeCheck, DeoptimizationReason.TypeCheckedInliningViolated, DeoptimizationAction.InvalidateReprofile));
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/SnippetTemplate.java	Wed Nov 12 16:59:39 2014 +0100
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/SnippetTemplate.java	Thu Nov 13 11:12:25 2014 +0100
@@ -242,6 +242,7 @@
         protected final SnippetInfo info;
         protected final CacheKey cacheKey;
         protected final Object[] values;
+        protected final Stamp[] constStamps;
 
         protected int nextParamIdx;
 
@@ -249,6 +250,7 @@
             this.info = info;
             this.cacheKey = new CacheKey(info, guardsStage, loweringStage);
             this.values = new Object[info.getParameterCount()];
+            this.constStamps = new Stamp[info.getParameterCount()];
         }
 
         public Arguments add(String name, Object value) {
@@ -259,8 +261,13 @@
         }
 
         public Arguments addConst(String name, Object value) {
+            return addConst(name, value, null);
+        }
+
+        public Arguments addConst(String name, Object value, Stamp stamp) {
             assert check(name, true, false);
             values[nextParamIdx] = value;
+            constStamps[nextParamIdx] = stamp;
             cacheKey.setParam(nextParamIdx, value);
             nextParamIdx++;
             return this;
@@ -575,13 +582,19 @@
             if (args.info.isConstantParameter(i)) {
                 Object arg = args.values[i];
                 Kind kind = signature.getParameterKind(i);
-                JavaConstant constantArg;
-                if (arg instanceof JavaConstant) {
-                    constantArg = (JavaConstant) arg;
+                ConstantNode constantNode;
+                if (arg instanceof Constant) {
+                    Stamp stamp = args.constStamps[i];
+                    if (stamp == null) {
+                        assert arg instanceof JavaConstant : "could not determine type of constant " + arg;
+                        constantNode = ConstantNode.forConstant((JavaConstant) arg, metaAccess, snippetCopy);
+                    } else {
+                        constantNode = ConstantNode.forConstant(stamp, (Constant) arg, metaAccess, snippetCopy);
+                    }
                 } else {
-                    constantArg = snippetReflection.forBoxed(kind, arg);
+                    constantNode = ConstantNode.forConstant(snippetReflection.forBoxed(kind, arg), metaAccess, snippetCopy);
                 }
-                nodeReplacements.put(snippetGraph.getParameter(i), ConstantNode.forConstant(constantArg, metaAccess, snippetCopy));
+                nodeReplacements.put(snippetGraph.getParameter(i), constantNode);
             } else if (args.info.isVarargsParameter(i)) {
                 Varargs varargs = (Varargs) args.values[i];
                 VarargsPlaceholderNode placeholder = snippetCopy.unique(VarargsPlaceholderNode.create(varargs, providers.getMetaAccess()));
--- a/graal/com.oracle.graal.word/src/com/oracle/graal/word/ComparableWord.java	Wed Nov 12 16:59:39 2014 +0100
+++ b/graal/com.oracle.graal.word/src/com/oracle/graal/word/ComparableWord.java	Thu Nov 13 11:12:25 2014 +0100
@@ -26,7 +26,7 @@
 
     /**
      * Compares this word with the specified value.
-     * 
+     *
      * @param val value to which this word is to be compared.
      * @return {@code this == val}
      */
@@ -34,7 +34,7 @@
 
     /**
      * Compares this word with the specified value.
-     * 
+     *
      * @param val value to which this word is to be compared.
      * @return {@code this != val}
      */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.word/src/com/oracle/graal/word/MethodPointer.java	Thu Nov 13 11:12:25 2014 +0100
@@ -0,0 +1,31 @@
+/*
+ * 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.word;
+
+import com.oracle.graal.api.meta.*;
+
+/**
+ * Marker interface for a metaspace pointer to a method.
+ */
+public interface MethodPointer extends TrustedInterface {
+}
--- a/graal/com.oracle.graal.word/src/com/oracle/graal/word/Pointer.java	Wed Nov 12 16:59:39 2014 +0100
+++ b/graal/com.oracle.graal.word/src/com/oracle/graal/word/Pointer.java	Thu Nov 13 11:12:25 2014 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -46,6 +46,10 @@
      */
     Object toObject();
 
+    TypePointer toTypePointer();
+
+    MethodPointer toMethodPointer();
+
     /**
      * Reads the memory at address {@code (this + offset)}. Both the base address and offset are in
      * bytes.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.word/src/com/oracle/graal/word/TypePointer.java	Thu Nov 13 11:12:25 2014 +0100
@@ -0,0 +1,31 @@
+/*
+ * 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.word;
+
+import com.oracle.graal.api.meta.*;
+
+/**
+ * Marker interface for a metaspace pointer to a type.
+ */
+public interface TypePointer extends TrustedInterface {
+}
--- a/graal/com.oracle.graal.word/src/com/oracle/graal/word/Word.java	Wed Nov 12 16:59:39 2014 +0100
+++ b/graal/com.oracle.graal.word/src/com/oracle/graal/word/Word.java	Thu Nov 13 11:12:25 2014 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -72,8 +72,11 @@
          FROM_UNSIGNED,
          FROM_SIGNED,
          FROM_OBJECT,
+         FROM_POINTER,
          FROM_ARRAY,
          TO_OBJECT,
+         TO_METHOD_POINTER,
+         TO_TYPE_POINTER,
          TO_RAW_VALUE,
     }
      // @formatter:on
@@ -173,6 +176,12 @@
     @Operation(opcode = Opcode.FROM_OBJECT)
     public static native Pointer fromObject(Object val);
 
+    @Operation(opcode = Opcode.FROM_POINTER)
+    public static native Pointer fromMethodPointer(MethodPointer val);
+
+    @Operation(opcode = Opcode.FROM_POINTER)
+    public static native Pointer fromTypePointer(TypePointer val);
+
     @Operation(opcode = Opcode.FROM_ARRAY)
     public static native Pointer fromArray(Object oop, Object location);
 
@@ -181,6 +190,26 @@
     public native Object toObject();
 
     @Override
+    @Operation(opcode = Opcode.TO_METHOD_POINTER)
+    public native MethodPointer toMethodPointer();
+
+    @Override
+    @Operation(opcode = Opcode.TO_TYPE_POINTER)
+    public native TypePointer toTypePointer();
+
+    @Operation(opcode = Opcode.COMPARISON, condition = Condition.EQ)
+    public static native boolean equal(MethodPointer a, MethodPointer b);
+
+    @Operation(opcode = Opcode.COMPARISON, condition = Condition.EQ)
+    public static native boolean equal(TypePointer a, TypePointer b);
+
+    @Operation(opcode = Opcode.COMPARISON, condition = Condition.NE)
+    public static native boolean notEqual(MethodPointer a, MethodPointer b);
+
+    @Operation(opcode = Opcode.COMPARISON, condition = Condition.NE)
+    public static native boolean notEqual(TypePointer a, TypePointer b);
+
+    @Override
     @Operation(node = AddNode.class)
     public Word add(Signed val) {
         return add((Word) val);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.word/src/com/oracle/graal/word/nodes/LoadIndexedPointerNode.java	Thu Nov 13 11:12:25 2014 +0100
@@ -0,0 +1,46 @@
+/*
+ * 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.word.nodes;
+
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.compiler.common.type.*;
+import com.oracle.graal.nodeinfo.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.java.*;
+
+@NodeInfo
+public class LoadIndexedPointerNode extends LoadIndexedNode {
+
+    public static LoadIndexedPointerNode create(Stamp stamp, ValueNode array, ValueNode index) {
+        return new LoadIndexedPointerNode(stamp, array, index);
+    }
+
+    protected LoadIndexedPointerNode(Stamp stamp, ValueNode array, ValueNode index) {
+        super(stamp, array, index, Kind.Illegal);
+    }
+
+    @Override
+    public boolean inferStamp() {
+        return false;
+    }
+}
--- a/graal/com.oracle.graal.word/src/com/oracle/graal/word/nodes/WordCastNode.java	Wed Nov 12 16:59:39 2014 +0100
+++ b/graal/com.oracle.graal.word/src/com/oracle/graal/word/nodes/WordCastNode.java	Thu Nov 13 11:12:25 2014 +0100
@@ -40,13 +40,13 @@
 
     @Input ValueNode input;
 
-    public static WordCastNode wordToObject(ValueNode input, Kind wordKind) {
+    public static WordCastNode wordToPointer(ValueNode input, Kind wordKind, PointerType type) {
         assert input.getKind() == wordKind;
-        return WordCastNode.create(StampFactory.object(), input);
+        return WordCastNode.create(StampFactory.forPointer(type), input);
     }
 
-    public static WordCastNode objectToWord(ValueNode input, Kind wordKind) {
-        assert input.getKind() == Kind.Object;
+    public static WordCastNode pointerToWord(ValueNode input, Kind wordKind) {
+        assert input.stamp() instanceof ObjectStamp || input.stamp() instanceof PointerStamp;
         return WordCastNode.create(StampFactory.forKind(wordKind), input);
     }
 
@@ -74,18 +74,21 @@
 
     @Override
     public void generate(NodeLIRBuilderTool generator) {
-        assert getKind() != input.getKind();
-        assert generator.getLIRGeneratorTool().target().getSizeInBytes(getKind()) == generator.getLIRGeneratorTool().target().getSizeInBytes(input.getKind());
-
         Value value = generator.operand(input);
         LIRKind kind = generator.getLIRGeneratorTool().getLIRKind(stamp());
-        if (kind.isValue()) {
+        assert generator.getLIRGeneratorTool().target().getSizeInBytes(kind.getPlatformKind()) == generator.getLIRGeneratorTool().target().getSizeInBytes(value.getPlatformKind());
+
+        if (kind.isValue() && !value.getLIRKind().isValue()) {
             // only add reference information, but never drop it
             kind = value.getLIRKind().changeType(kind.getPlatformKind());
         }
 
-        AllocatableValue result = generator.getLIRGeneratorTool().newVariable(kind);
-        generator.getLIRGeneratorTool().emitMove(result, value);
-        generator.setResult(this, result);
+        if (kind.equals(value.getLIRKind())) {
+            generator.setResult(this, value);
+        } else {
+            AllocatableValue result = generator.getLIRGeneratorTool().newVariable(kind);
+            generator.getLIRGeneratorTool().emitMove(result, value);
+            generator.setResult(this, result);
+        }
     }
 }
--- a/graal/com.oracle.graal.word/src/com/oracle/graal/word/phases/WordTypeRewriterPhase.java	Wed Nov 12 16:59:39 2014 +0100
+++ b/graal/com.oracle.graal.word/src/com/oracle/graal/word/phases/WordTypeRewriterPhase.java	Thu Nov 13 11:12:25 2014 +0100
@@ -56,6 +56,8 @@
     protected final SnippetReflectionProvider snippetReflection;
     protected final ResolvedJavaType wordBaseType;
     protected final ResolvedJavaType wordImplType;
+    protected final ResolvedJavaType typePointerType;
+    protected final ResolvedJavaType methodPointerType;
     protected final ResolvedJavaType objectAccessType;
     protected final ResolvedJavaType barrieredAccessType;
     protected final Kind wordKind;
@@ -66,6 +68,8 @@
         this.wordKind = wordKind;
         this.wordBaseType = metaAccess.lookupJavaType(WordBase.class);
         this.wordImplType = metaAccess.lookupJavaType(Word.class);
+        this.typePointerType = metaAccess.lookupJavaType(TypePointer.class);
+        this.methodPointerType = metaAccess.lookupJavaType(MethodPointer.class);
         this.objectAccessType = metaAccess.lookupJavaType(ObjectAccess.class);
         this.barrieredAccessType = metaAccess.lookupJavaType(BarrieredAccess.class);
     }
@@ -101,6 +105,11 @@
             } else {
                 node.setStamp(StampFactory.forKind(wordKind));
             }
+        } else {
+            PointerType pointer = getPointerType(node);
+            if (pointer != null) {
+                node.setStamp(StampFactory.forPointer(pointer));
+            }
         }
     }
 
@@ -163,6 +172,11 @@
             } else {
                 throw GraalInternalError.shouldNotReachHere();
             }
+        } else if (node.stamp() instanceof PointerStamp && node instanceof LoadIndexedNode && node.elementKind() != Kind.Illegal) {
+            /*
+             * Prevent rewriting of the PointerStamp.
+             */
+            graph.replaceFixedWithFixed(node, graph.add(LoadIndexedPointerNode.create(node.stamp(), node.array(), node.index())));
         }
     }
 
@@ -208,7 +222,7 @@
 
             case COMPARISON:
                 assert arguments.size() == 2;
-                replace(invoke, comparisonOp(graph, operation.condition(), arguments.get(0), fromSigned(graph, arguments.get(1))));
+                replace(invoke, comparisonOp(graph, operation.condition(), arguments.get(0), arguments.get(1)));
                 break;
 
             case NOT:
@@ -274,8 +288,9 @@
                 break;
 
             case FROM_OBJECT:
+            case FROM_POINTER:
                 assert arguments.size() == 1;
-                WordCastNode objectToWord = graph.add(WordCastNode.objectToWord(arguments.get(0), wordKind));
+                WordCastNode objectToWord = graph.add(WordCastNode.pointerToWord(arguments.get(0), wordKind));
                 graph.addBeforeFixed(invoke.asNode(), objectToWord);
                 replace(invoke, objectToWord);
                 break;
@@ -286,8 +301,24 @@
                 break;
 
             case TO_OBJECT:
+            case TO_METHOD_POINTER:
+            case TO_TYPE_POINTER:
                 assert arguments.size() == 1;
-                WordCastNode wordToObject = graph.add(WordCastNode.wordToObject(arguments.get(0), wordKind));
+                PointerType type;
+                switch (operation.opcode()) {
+                    case TO_OBJECT:
+                        type = PointerType.Object;
+                        break;
+                    case TO_METHOD_POINTER:
+                        type = PointerType.Method;
+                        break;
+                    case TO_TYPE_POINTER:
+                        type = PointerType.Type;
+                        break;
+                    default:
+                        throw GraalInternalError.shouldNotReachHere();
+                }
+                WordCastNode wordToObject = graph.add(WordCastNode.wordToPointer(arguments.get(0), wordKind, type));
                 graph.addBeforeFixed(invoke.asNode(), wordToObject);
                 replace(invoke, wordToObject);
                 break;
@@ -343,8 +374,6 @@
     }
 
     private ValueNode comparisonOp(StructuredGraph graph, Condition condition, ValueNode left, ValueNode right) {
-        assert left.getKind() == wordKind && right.getKind() == wordKind;
-
         // mirroring gets the condition into canonical form
         boolean mirror = condition.canonicalMirror();
 
@@ -352,12 +381,21 @@
         ValueNode b = mirror ? left : right;
 
         CompareNode comparison;
-        if (condition == Condition.EQ || condition == Condition.NE) {
-            comparison = IntegerEqualsNode.create(a, b);
-        } else if (condition.isUnsigned()) {
-            comparison = IntegerBelowNode.create(a, b);
+        if (left.stamp() instanceof AbstractPointerStamp) {
+            assert right.stamp() instanceof AbstractPointerStamp;
+            assert condition == Condition.EQ || condition == Condition.NE;
+            comparison = PointerEqualsNode.create(a, b);
         } else {
-            comparison = IntegerLessThanNode.create(a, b);
+            a = fromSigned(graph, a);
+            b = fromSigned(graph, b);
+            assert a.getKind() == wordKind && b.getKind() == wordKind;
+            if (condition == Condition.EQ || condition == Condition.NE) {
+                comparison = IntegerEqualsNode.create(a, b);
+            } else if (condition.isUnsigned()) {
+                comparison = IntegerBelowNode.create(a, b);
+            } else {
+                comparison = IntegerLessThanNode.create(a, b);
+            }
         }
 
         ConstantNode trueValue = ConstantNode.forInt(1, graph);
@@ -430,6 +468,21 @@
         return type != null && wordBaseType.isAssignableFrom(type);
     }
 
+    protected PointerType getPointerType(ValueNode node) {
+        return getPointerType(StampTool.typeOrNull(node));
+    }
+
+    protected PointerType getPointerType(ResolvedJavaType type) {
+        if (type != null) {
+            if (typePointerType.isAssignableFrom(type)) {
+                return PointerType.Type;
+            } else if (methodPointerType.isAssignableFrom(type)) {
+                return PointerType.Method;
+            }
+        }
+        return null;
+    }
+
     protected Kind asKind(JavaType type) {
         if (type instanceof ResolvedJavaType && isWord((ResolvedJavaType) type)) {
             return wordKind;