changeset 15018:db4254246f9a

Remove Constant.forObject and Constant.asObject to improve compiler/VM separation
author Christian Wimmer <christian.wimmer@oracle.com>
date Mon, 07 Apr 2014 16:09:17 -0700
parents ff5660822992
children 3498761a33d8
files graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/CodeCacheProvider.java graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/SpeculationLog.java graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TestConstantReflectionProvider.java graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TestMetaAccessProvider.java graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TestResolvedJavaField.java graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TestResolvedJavaType.java graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TypeUniverse.java graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/Constant.java graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ConstantPool.java graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ConstantReflectionProvider.java graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/MetaUtil.java graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/NullConstant.java graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ObjectLocationIdentity.java graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/PrimitiveConstant.java graal/com.oracle.graal.api.replacements/src/com/oracle/graal/api/replacements/SnippetReflectionProvider.java graal/com.oracle.graal.asm.hsail/src/com/oracle/graal/asm/hsail/HSAILAssembler.java graal/com.oracle.graal.asm.ptx/src/com/oracle/graal/asm/ptx/PTXAssembler.java graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/GraalCompilerTest.java graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/backend/AllocatorTest.java graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/deopt/CompiledMethodTest.java graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/EscapeAnalysisTest.java graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotBackendFactory.java graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerator.java graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLoweringProvider.java graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotMemoryPeephole.java graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotMove.java graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotSafepointOp.java graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotAssembler.java graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotBackend.java graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotBackendFactory.java graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotLIRGenerator.java graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotNodeLIRBuilder.java graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotReplacementsImpl.java graal/com.oracle.graal.hotspot.ptx/src/com/oracle/graal/hotspot/ptx/PTXHotSpotBackendFactory.java graal/com.oracle.graal.hotspot.ptx/src/com/oracle/graal/hotspot/ptx/PTXWrapperBuilder.java graal/com.oracle.graal.hotspot.server/src/com/oracle/graal/hotspot/server/ReplacingStreams.java graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotBackendFactory.java graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/AheadOfTimeCompilationTest.java graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/InstalledCodeExecuteHelperTest.java graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/WriteBarrierAdditionTest.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotGraalRuntime.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotReplacementsImpl.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotCodeCacheProvider.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotConstantPool.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/HotSpotHostForeignCallsProvider.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotLoweringProvider.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMetaAccessProvider.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMetaspaceConstant.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotObjectConstant.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotProviders.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaField.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaMethod.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedObjectType.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedPrimitiveType.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotSnippetReflectionProvider.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotSpeculationLog.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nfi/NativeCallStubGraphBuilder.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassCastNode.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassGetComponentTypeNode.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassGetModifiersNode.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassGetSuperclassNode.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassIsArrayNode.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassIsInstanceNode.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassIsInterfaceNode.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassIsPrimitiveNode.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/phases/AheadOfTimeVerificationPhase.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/AbstractMethodHandleNode.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/CallSiteTargetNode.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/CompositeValueClassSubstitutions.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/HotSpotSubstitutions.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/LoadExceptionObjectSnippets.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/NodeClassSubstitutions.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ReflectionGetCallerClassNode.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/SystemIdentityHashCodeNode.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/UnsafeArrayCopySnippets.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/UnsafeLoadSnippets.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/WriteBarrierSnippets.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/ForeignCallStub.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/SnippetStub.java graal/com.oracle.graal.java.decompiler/src/com/oracle/graal/java/decompiler/lines/DecompilerSyntaxLine.java graal/com.oracle.graal.java/src/com/oracle/graal/java/AbstractBytecodeParser.java graal/com.oracle.graal.java/src/com/oracle/graal/java/BytecodeDisassembler.java graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/JTTTest.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ConstantNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ObjectEqualsNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/BytecodeExceptionNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/DeferredForeignCallNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ReadNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/SnippetLocationNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnboxNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/ArrayLengthNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/CheckCastDynamicNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/DynamicNewArrayNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/DynamicNewInstanceNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/InstanceOfDynamicNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/VirtualizerTool.java graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ConditionalEliminationPhase.java graal/com.oracle.graal.replacements.amd64/src/com/oracle/graal/replacements/amd64/AMD64ConvertSnippets.java graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/ObjectAccessTest.java graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/PointerTest.java graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/WordTest.java graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/BoxingSnippets.java graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/CompositeValueClassSubstitutions.java graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/GraalMethodSubstitutions.java graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/GraphKit.java graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/InstanceOfSnippetsTemplates.java graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/NodeClassSubstitutions.java graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/NodeIntrinsificationPhase.java graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/ReplacementsImpl.java graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/SnippetTemplate.java graal/com.oracle.graal.truffle.hotspot/src/com/oracle/graal/truffle/hotspot/HotSpotOptimizedCallTarget.java graal/com.oracle.graal.truffle.hotspot/src/com/oracle/graal/truffle/hotspot/HotSpotTruffleReplacements.java graal/com.oracle.graal.truffle.hotspot/src/com/oracle/graal/truffle/hotspot/HotSpotTruffleRuntime.java graal/com.oracle.graal.truffle.hotspot/src/com/oracle/graal/truffle/hotspot/substitutions/HotSpotOptimizedCallTargetSubstitutions.java graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/PartialEvaluationTest.java graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/TruffleRuntimeTest.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/CompilationProfile.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/GraalTruffleRuntime.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedCallTarget.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedCallTargetImpl.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/PartialEvaluator.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/PartialEvaluatorCanonicalizer.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCompilerImpl.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleExpansionLogger.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleReplacements.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/AssumptionNode.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/BailoutNode.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/LoadIndexedFinalNode.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/ObjectLocationIdentity.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/frame/NewFrameNode.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/typesystem/CustomizedUnsafeLoadFinalNode.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/typesystem/CustomizedUnsafeLoadMacroNode.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/typesystem/CustomizedUnsafeStoreMacroNode.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/typesystem/UnsafeTypeCastMacroNode.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/substitutions/OptimizedCallTargetImplSubstitutions.java graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PEReadEliminationClosure.java graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PartialEscapeClosure.java graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PartialEscapePhase.java graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/VirtualizerToolImpl.java graal/com.oracle.graal.word/src/com/oracle/graal/word/nodes/SnippetLocationNode.java graal/com.oracle.graal.word/src/com/oracle/graal/word/phases/WordTypeRewriterPhase.java graal/com.oracle.graal.word/src/com/oracle/graal/word/phases/WordTypeVerificationPhase.java src/share/vm/classfile/systemDictionary.hpp src/share/vm/classfile/vmSymbols.hpp src/share/vm/graal/graalCodeInstaller.cpp src/share/vm/graal/graalJavaAccess.hpp src/share/vm/graal/graalVMToCompiler.cpp
diffstat 156 files changed, 2468 insertions(+), 1630 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/CodeCacheProvider.java	Mon Apr 07 23:35:41 2014 +0200
+++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/CodeCacheProvider.java	Mon Apr 07 16:09:17 2014 -0700
@@ -79,9 +79,8 @@
     int getMinimumOutgoingSize();
 
     /**
-     * Determines if a {@link DataPatch} should be created for a given
-     * {@linkplain Constant#getPrimitiveAnnotation() annotated} primitive constant that part of a
-     * {@link CompilationResult}. A data patch is always created for an object constant.
+     * Determines if a {@link DataPatch} should be created for a given primitive constant that is
+     * part of a {@link CompilationResult}. A data patch is always created for an object constant.
      */
     boolean needsDataPatch(Constant constant);
 
--- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/SpeculationLog.java	Mon Apr 07 23:35:41 2014 +0200
+++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/SpeculationLog.java	Mon Apr 07 16:09:17 2014 -0700
@@ -31,7 +31,7 @@
  * Manages a list of unique deoptimization reasons.
  * 
  */
-public final class SpeculationLog {
+public abstract class SpeculationLog {
     private volatile Object lastFailed;
     private volatile Collection<Object> speculations;
     private Set<Object> failedSpeculations;
@@ -54,7 +54,7 @@
         return true;
     }
 
-    public Constant speculate(Object reason) {
+    protected void addSpeculation(Object reason) {
         assert maySpeculate(reason);
         if (speculations == null) {
             synchronized (this) {
@@ -64,6 +64,7 @@
             }
         }
         speculations.add(reason);
-        return Constant.forObject(reason);
     }
+
+    public abstract Constant speculate(Object reason);
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TestConstantReflectionProvider.java	Mon Apr 07 16:09:17 2014 -0700
@@ -0,0 +1,118 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.api.meta.test;
+
+import static org.junit.Assert.*;
+
+import java.lang.reflect.*;
+
+import org.junit.*;
+
+import com.oracle.graal.api.meta.*;
+
+/**
+ * Tests for {@link ConstantReflectionProvider}. It assumes an implementation of the interface that
+ * actually returns non-null results for access operations that are possible, i.e., the tests will
+ * fail for an implementation that spuriously returns null (which is allowed by the specification).
+ */
+public class TestConstantReflectionProvider extends TypeUniverse {
+
+    @Test
+    public void constantEqualsTest() {
+        for (Constant c1 : constants) {
+            for (Constant c2 : constants) {
+                // test symmetry
+                assertEquals(constantReflection.constantEquals(c1, c2), constantReflection.constantEquals(c2, c1));
+                if (c1.getKind() != Kind.Object && c2.getKind() != Kind.Object) {
+                    assertEquals(c1.equals(c2), constantReflection.constantEquals(c2, c1));
+                }
+            }
+        }
+    }
+
+    @Test
+    public void readArrayLengthTest() {
+        for (Constant c : constants) {
+            Integer actual = constantReflection.readArrayLength(c);
+            if (c.getKind() != Kind.Object || c.isNull() || !snippetReflection.asObject(c).getClass().isArray()) {
+                assertNull(actual);
+            } else {
+                assertNotNull(actual);
+                int actualInt = actual;
+                assertEquals(Array.getLength(snippetReflection.asObject(c)), actualInt);
+            }
+        }
+    }
+
+    @Test
+    public void boxTest() {
+        for (Constant c : constants) {
+            Constant boxed = constantReflection.boxPrimitive(c);
+            if (c.getKind().isPrimitive()) {
+                assertTrue(boxed.getKind().isObject());
+                assertFalse(boxed.isNull());
+            }
+        }
+
+        assertEquals(Long.valueOf(42), snippetReflection.asObject(constantReflection.boxPrimitive(Constant.forLong(42))));
+        assertEquals(Integer.valueOf(666), snippetReflection.asObject(constantReflection.boxPrimitive(Constant.forInt(666))));
+        assertEquals(Byte.valueOf((byte) 123), snippetReflection.asObject(constantReflection.boxPrimitive(Constant.forByte((byte) 123))));
+        assertSame(Boolean.TRUE, snippetReflection.asObject(constantReflection.boxPrimitive(Constant.forBoolean(true))));
+
+        assertNull(constantReflection.boxPrimitive(Constant.NULL_OBJECT));
+        assertNull(constantReflection.boxPrimitive(snippetReflection.forObject("abc")));
+    }
+
+    @Test
+    public void unboxTest() {
+        for (Constant c : constants) {
+            Constant unboxed = constantReflection.unboxPrimitive(c);
+            if (unboxed != null) {
+                assertFalse(unboxed.getKind().isObject());
+            }
+        }
+
+        assertEquals(Constant.forLong(42), constantReflection.unboxPrimitive(snippetReflection.forObject(Long.valueOf(42))));
+        assertEquals(Constant.forInt(666), constantReflection.unboxPrimitive(snippetReflection.forObject(Integer.valueOf(666))));
+        assertEquals(Constant.forByte((byte) 123), constantReflection.unboxPrimitive(snippetReflection.forObject(Byte.valueOf((byte) 123))));
+        assertSame(Constant.forBoolean(true), constantReflection.unboxPrimitive(snippetReflection.forObject(Boolean.TRUE)));
+
+        assertNull(constantReflection.unboxPrimitive(Constant.NULL_OBJECT));
+        assertNull(constantReflection.unboxPrimitive(snippetReflection.forObject("abc")));
+    }
+
+    @Test
+    public void testAsJavaType() {
+        for (Constant c : constants) {
+            ResolvedJavaType type = constantReflection.asJavaType(c);
+
+            Object o = snippetReflection.asBoxedValue(c);
+            if (o instanceof Class) {
+                assertEquals(metaAccess.lookupJavaType((Class) o), type);
+            } else {
+                assertNull(type);
+            }
+        }
+
+    }
+}
--- a/graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TestMetaAccessProvider.java	Mon Apr 07 23:35:41 2014 +0200
+++ b/graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TestMetaAccessProvider.java	Mon Apr 07 16:09:17 2014 -0700
@@ -81,7 +81,7 @@
     public void lookupJavaTypeConstantTest() {
         for (Constant c : constants) {
             if (c.getKind() == Kind.Object && !c.isNull()) {
-                Object o = c.asObject();
+                Object o = snippetReflection.asObject(c);
                 ResolvedJavaType type = metaAccess.lookupJavaType(c);
                 assertNotNull(type);
                 assertTrue(type.equals(metaAccess.lookupJavaType(o.getClass())));
@@ -90,31 +90,4 @@
             }
         }
     }
-
-    @Test
-    public void constantEqualsTest() {
-        for (Constant c1 : constants) {
-            for (Constant c2 : constants) {
-                // test symmetry
-                assertEquals(constantReflection.constantEquals(c1, c2), constantReflection.constantEquals(c2, c1));
-                if (c1.getKind() != Kind.Object && c2.getKind() != Kind.Object) {
-                    assertEquals(c1.equals(c2), constantReflection.constantEquals(c2, c1));
-                }
-            }
-        }
-    }
-
-    @Test
-    public void lookupArrayLengthTest() {
-        for (Constant c : constants) {
-            Integer actual = constantReflection.lookupArrayLength(c);
-            if (c.getKind() != Kind.Object || c.isNull() || !c.asObject().getClass().isArray()) {
-                assertNull(actual);
-            } else {
-                assertNotNull(actual);
-                int actualInt = actual;
-                assertEquals(Array.getLength(c.asObject()), actualInt);
-            }
-        }
-    }
 }
--- a/graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TestResolvedJavaField.java	Mon Apr 07 23:35:41 2014 +0200
+++ b/graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TestResolvedJavaField.java	Mon Apr 07 16:09:17 2014 -0700
@@ -78,7 +78,7 @@
             if (isStatic(field.getModifiers())) {
                 try {
                     Object expected = field.get(null);
-                    Object actual = e.getValue().readConstantValue(null).asBoxedValue();
+                    Object actual = snippetReflection.asBoxedValue(e.getValue().readConstantValue(null));
                     assertEquals(expected, actual);
                 } catch (IllegalArgumentException | IllegalAccessException e1) {
                 }
@@ -86,7 +86,7 @@
                 try {
                     Object receiver = field.getDeclaringClass().newInstance();
                     Object expected = field.get(receiver);
-                    Object actual = e.getValue().readConstantValue(Constant.forObject(receiver)).asBoxedValue();
+                    Object actual = snippetReflection.asBoxedValue(e.getValue().readConstantValue(snippetReflection.forObject(receiver)));
                     assertEquals(expected, actual);
                 } catch (InstantiationException | IllegalArgumentException | IllegalAccessException e1) {
                 }
@@ -95,16 +95,16 @@
 
         ResolvedJavaField field = metaAccess.lookupJavaField(getClass().getDeclaredField("stringField"));
         for (Object receiver : new Object[]{this, null, new String()}) {
-            Constant value = field.readConstantValue(Constant.forObject(receiver));
+            Constant value = field.readConstantValue(snippetReflection.forObject(receiver));
             assertNull(value);
         }
 
         ResolvedJavaField constField = metaAccess.lookupJavaField(getClass().getDeclaredField("constantStringField"));
         for (Object receiver : new Object[]{this, null, new String()}) {
-            Constant value = constField.readConstantValue(Constant.forObject(receiver));
+            Constant value = constField.readConstantValue(snippetReflection.forObject(receiver));
             if (value != null) {
                 Object expected = "constantField";
-                assertTrue(value.asObject() == expected);
+                assertTrue(snippetReflection.asObject(value) == expected);
             }
         }
     }
@@ -117,7 +117,7 @@
             if (isStatic(field.getModifiers())) {
                 try {
                     Object expected = field.get(null);
-                    Object actual = e.getValue().readValue(null).asBoxedValue();
+                    Object actual = snippetReflection.asBoxedValue(e.getValue().readValue(null));
                     assertEquals(expected, actual);
                 } catch (IllegalArgumentException | IllegalAccessException e1) {
                 }
@@ -131,7 +131,7 @@
             ResolvedJavaField rf = metaAccess.lookupJavaField(f);
             Object receiver = isStatic(f.getModifiers()) ? null : testString;
             Object expected = f.get(receiver);
-            Object actual = rf.readValue(receiver == null ? null : Constant.forObject(receiver)).asBoxedValue();
+            Object actual = snippetReflection.asBoxedValue(rf.readValue(receiver == null ? null : snippetReflection.forObject(receiver)));
             assertEquals(expected, actual);
         }
     }
--- a/graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TestResolvedJavaType.java	Mon Apr 07 23:35:41 2014 +0200
+++ b/graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TestResolvedJavaType.java	Mon Apr 07 16:09:17 2014 -0700
@@ -123,7 +123,7 @@
     public void isInstanceTest() {
         for (Constant c : constants) {
             if (c.getKind() == Kind.Object && !c.isNull()) {
-                Object o = c.asObject();
+                Object o = snippetReflection.asObject(c);
                 Class<? extends Object> cls = o.getClass();
                 while (cls != null) {
                     ResolvedJavaType type = metaAccess.lookupJavaType(cls);
--- a/graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TypeUniverse.java	Mon Apr 07 23:35:41 2014 +0200
+++ b/graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TypeUniverse.java	Mon Apr 07 16:09:17 2014 -0700
@@ -32,6 +32,7 @@
 import sun.misc.*;
 
 import com.oracle.graal.api.meta.*;
+import com.oracle.graal.api.replacements.*;
 import com.oracle.graal.api.runtime.*;
 import com.oracle.graal.phases.util.*;
 import com.oracle.graal.runtime.*;
@@ -46,6 +47,7 @@
 
     public final MetaAccessProvider metaAccess;
     public final ConstantReflectionProvider constantReflection;
+    public final SnippetReflectionProvider snippetReflection;
     public final Collection<Class<?>> classes = new HashSet<>();
     public final Map<Class<?>, Class<?>> arrayClasses = new HashMap<>();
     public final List<Constant> constants = new ArrayList<>();
@@ -54,6 +56,7 @@
         Providers providers = Graal.getRequiredCapability(RuntimeProvider.class).getHostBackend().getProviders();
         metaAccess = providers.getMetaAccess();
         constantReflection = providers.getConstantReflection();
+        snippetReflection = Graal.getRequiredCapability(SnippetReflectionProvider.class);
         Unsafe theUnsafe = null;
         try {
             theUnsafe = Unsafe.getUnsafe();
@@ -88,17 +91,19 @@
         }
         for (Class c : classes) {
             if (c != void.class && !c.isArray()) {
-                constants.add(Constant.forObject(Array.newInstance(c, 42)));
+                constants.add(snippetReflection.forObject(Array.newInstance(c, 42)));
             }
         }
-        constants.add(Constant.forObject(new ArrayList<>()));
-        constants.add(Constant.forObject(new IdentityHashMap<>()));
-        constants.add(Constant.forObject(new LinkedHashMap<>()));
-        constants.add(Constant.forObject(new TreeMap<>()));
-        constants.add(Constant.forObject(new ArrayDeque<>()));
-        constants.add(Constant.forObject(new LinkedList<>()));
-        constants.add(Constant.forObject("a string"));
-        constants.add(Constant.forObject(42));
+        constants.add(snippetReflection.forObject(new ArrayList<>()));
+        constants.add(snippetReflection.forObject(new IdentityHashMap<>()));
+        constants.add(snippetReflection.forObject(new LinkedHashMap<>()));
+        constants.add(snippetReflection.forObject(new TreeMap<>()));
+        constants.add(snippetReflection.forObject(new ArrayDeque<>()));
+        constants.add(snippetReflection.forObject(new LinkedList<>()));
+        constants.add(snippetReflection.forObject("a string"));
+        constants.add(snippetReflection.forObject(42));
+        constants.add(snippetReflection.forObject(String.class));
+        constants.add(snippetReflection.forObject(String[].class));
     }
 
     public synchronized Class<?> getArrayClass(Class componentType) {
--- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/Constant.java	Mon Apr 07 23:35:41 2014 +0200
+++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/Constant.java	Mon Apr 07 16:09:17 2014 -0700
@@ -22,42 +22,40 @@
  */
 package com.oracle.graal.api.meta;
 
-import static com.oracle.graal.api.meta.MetaUtil.*;
-
 /**
  * Represents a constant (boxed) value, such as an integer, floating point number, or object
  * reference, within the compiler and across the compiler/runtime interface. Exports a set of
  * {@code Constant} instances that represent frequently used constant values, such as
  * {@link #NULL_OBJECT}.
  */
-public final class Constant extends Value {
+public abstract class Constant extends Value {
 
     private static final long serialVersionUID = -6355452536852663986L;
 
     private static final Constant[] INT_CONSTANT_CACHE = new Constant[100];
     static {
         for (int i = 0; i < INT_CONSTANT_CACHE.length; ++i) {
-            INT_CONSTANT_CACHE[i] = new Constant(Kind.Int, null, i);
+            INT_CONSTANT_CACHE[i] = new PrimitiveConstant(Kind.Int, i);
         }
     }
 
-    public static final Constant NULL_OBJECT = new Constant(Kind.Object, null, 0);
-    public static final Constant INT_MINUS_1 = new Constant(Kind.Int, null, -1);
+    public static final Constant NULL_OBJECT = new NullConstant();
+    public static final Constant INT_MINUS_1 = new PrimitiveConstant(Kind.Int, -1);
     public static final Constant INT_0 = forInt(0);
     public static final Constant INT_1 = forInt(1);
     public static final Constant INT_2 = forInt(2);
     public static final Constant INT_3 = forInt(3);
     public static final Constant INT_4 = forInt(4);
     public static final Constant INT_5 = forInt(5);
-    public static final Constant LONG_0 = new Constant(Kind.Long, null, 0L);
-    public static final Constant LONG_1 = new Constant(Kind.Long, null, 1L);
-    public static final Constant FLOAT_0 = new Constant(Kind.Float, null, Float.floatToRawIntBits(0.0F));
-    public static final Constant FLOAT_1 = new Constant(Kind.Float, null, Float.floatToRawIntBits(1.0F));
-    public static final Constant FLOAT_2 = new Constant(Kind.Float, null, Float.floatToRawIntBits(2.0F));
-    public static final Constant DOUBLE_0 = new Constant(Kind.Double, null, Double.doubleToRawLongBits(0.0D));
-    public static final Constant DOUBLE_1 = new Constant(Kind.Double, null, Double.doubleToRawLongBits(1.0D));
-    public static final Constant TRUE = new Constant(Kind.Boolean, null, 1L);
-    public static final Constant FALSE = new Constant(Kind.Boolean, null, 0L);
+    public static final Constant LONG_0 = new PrimitiveConstant(Kind.Long, 0L);
+    public static final Constant LONG_1 = new PrimitiveConstant(Kind.Long, 1L);
+    public static final Constant FLOAT_0 = new PrimitiveConstant(Kind.Float, Float.floatToRawIntBits(0.0F));
+    public static final Constant FLOAT_1 = new PrimitiveConstant(Kind.Float, Float.floatToRawIntBits(1.0F));
+    public static final Constant FLOAT_2 = new PrimitiveConstant(Kind.Float, Float.floatToRawIntBits(2.0F));
+    public static final Constant DOUBLE_0 = new PrimitiveConstant(Kind.Double, Double.doubleToRawLongBits(0.0D));
+    public static final Constant DOUBLE_1 = new PrimitiveConstant(Kind.Double, Double.doubleToRawLongBits(1.0D));
+    public static final Constant TRUE = new PrimitiveConstant(Kind.Boolean, 1L);
+    public static final Constant FALSE = new PrimitiveConstant(Kind.Boolean, 0L);
 
     static {
         assert FLOAT_0 != forFloat(-0.0F) : "Constant for 0.0f must be different from -0.0f";
@@ -65,56 +63,82 @@
         assert NULL_OBJECT.isNull();
     }
 
-    /**
-     * The boxed object value if {@code !kind.isObject()} otherwise the (possibly null)
-     * {@link #getPrimitiveAnnotation() annotation} for a primitive value.
-     */
-    private final Object object;
-
-    /**
-     * The boxed primitive value as a {@code long}. This is ignored iff {@code kind.isObject()}. For
-     * {@code float} and {@code double} values, this value is the result of
-     * {@link Float#floatToRawIntBits(float)} and {@link Double#doubleToRawLongBits(double)}
-     * respectively.
-     */
-    private final long primitive;
-
-    private Constant(Kind kind, Object object, long primitive) {
+    protected Constant(Kind kind) {
         super(kind);
-        this.object = object;
-        this.primitive = primitive;
-    }
-
-    /**
-     * Checks whether this constant is non-null.
-     * 
-     * @return {@code true} if this constant is a primitive, or an object constant that is not null
-     */
-    public boolean isNonNull() {
-        return getKind() != Kind.Object || object != null;
     }
 
     /**
      * Checks whether this constant is null.
-     * 
+     *
      * @return {@code true} if this constant is the null constant
      */
-    public boolean isNull() {
-        return getKind() == Kind.Object && object == null;
+    public abstract boolean isNull();
+
+    /**
+     * Checks whether this constant is non-null.
+     *
+     * @return {@code true} if this constant is a primitive, or an object constant that is not null
+     */
+    public final boolean isNonNull() {
+        return !isNull();
     }
 
     /**
      * Checks whether this constant is the default value for its kind (null, 0, 0.0, false).
-     * 
+     *
      * @return {@code true} if this constant is the default value for its kind
      */
-    public boolean isDefaultForKind() {
-        return object == null && primitive == 0;
-    }
+    public abstract boolean isDefaultForKind();
+
+    /**
+     * Returns the value of this constant as a boxed Java value.
+     *
+     * @return the value of this constant
+     */
+    public abstract Object asBoxedPrimitive();
+
+    /**
+     * Returns the primitive int value this constant represents. The constant must have a
+     * {@link Kind#getStackKind()} of {@link Kind#Int}.
+     *
+     * @return the constant value
+     */
+    public abstract int asInt();
+
+    /**
+     * Returns the primitive boolean value this constant represents. The constant must have kind
+     * {@link Kind#Boolean}.
+     *
+     * @return the constant value
+     */
+    public abstract boolean asBoolean();
 
-    public long getPrimitive() {
-        assert getKind().isPrimitive();
-        return primitive;
+    /**
+     * Returns the primitive long value this constant represents. The constant must have kind
+     * {@link Kind#Long}, a {@link Kind#getStackKind()} of {@link Kind#Int}.
+     *
+     * @return the constant value
+     */
+    public abstract long asLong();
+
+    /**
+     * Returns the primitive float value this constant represents. The constant must have kind
+     * {@link Kind#Float}.
+     *
+     * @return the constant value
+     */
+    public abstract float asFloat();
+
+    /**
+     * Returns the primitive double value this constant represents. The constant must have kind
+     * {@link Kind#Double}.
+     *
+     * @return the constant value
+     */
+    public abstract double asDouble();
+
+    public String toValueString() {
+        return getKind().format(asBoxedPrimitive());
     }
 
     @Override
@@ -122,165 +146,13 @@
         if (getKind() == Kind.Illegal) {
             return "illegal";
         } else {
-            String annotationSuffix = "";
-            Object primitiveAnnotation = getPrimitiveAnnotation();
-            if (getKind() != Kind.Object && primitiveAnnotation != null) {
-                try {
-                    annotationSuffix = "{" + primitiveAnnotation + "}";
-                } catch (Throwable t) {
-                    annotationSuffix = "{" + getSimpleName(primitiveAnnotation.getClass(), true) + "@" + System.identityHashCode(primitiveAnnotation) + "}";
-                }
-            }
-            return getKind().getJavaName() + "[" + getKind().format(asBoxedValue()) + (getKind() != Kind.Object ? "|0x" + Long.toHexString(primitive) : "") + "]" + annotationSuffix;
+            return getKind().getJavaName() + "[" + toValueString() + "]";
         }
     }
 
     /**
-     * Returns the value of this constant as a boxed Java value.
-     * 
-     * @return the value of this constant
-     */
-    public Object asBoxedValue() {
-        switch (getKind()) {
-            case Byte:
-                return (byte) asInt();
-            case Boolean:
-                return asInt() == 0 ? Boolean.FALSE : Boolean.TRUE;
-            case Short:
-                return (short) primitive;
-            case Char:
-                return (char) primitive;
-            case Int:
-                return (int) primitive;
-            case Long:
-                return primitive;
-            case Float:
-                return asFloat();
-            case Double:
-                return asDouble();
-            case Object:
-                return object;
-            case Illegal:
-                return this;
-        }
-        throw new IllegalArgumentException();
-    }
-
-    private boolean valueEqual(Constant other, boolean ignoreKind) {
-        // must have equivalent kinds to be equal
-        if (!ignoreKind && getKind() != other.getKind()) {
-            return false;
-        }
-        if (getKind() == Kind.Object) {
-            return object == other.object;
-        }
-        return primitive == other.primitive && getPrimitiveAnnotation() == other.getPrimitiveAnnotation();
-    }
-
-    /**
-     * Returns the primitive int value this constant represents. The constant must have a
-     * {@link Kind#getStackKind()} of {@link Kind#Int}.
-     * 
-     * @return the constant value
-     */
-    public int asInt() {
-        assert getKind().getStackKind() == Kind.Int;
-        return (int) primitive;
-    }
-
-    /**
-     * Returns the primitive boolean value this constant represents. The constant must have kind
-     * {@link Kind#Boolean}.
-     * 
-     * @return the constant value
-     */
-    public boolean asBoolean() {
-        assert getKind() == Kind.Boolean;
-        return primitive != 0L;
-    }
-
-    /**
-     * Returns the primitive long value this constant represents. The constant must have kind
-     * {@link Kind#Long}, a {@link Kind#getStackKind()} of {@link Kind#Int}.
-     * 
-     * @return the constant value
-     */
-    public long asLong() {
-        assert getKind().isNumericInteger();
-        return primitive;
-    }
-
-    /**
-     * Returns the primitive float value this constant represents. The constant must have kind
-     * {@link Kind#Float}.
-     * 
-     * @return the constant value
-     */
-    public float asFloat() {
-        assert getKind() == Kind.Float;
-        return Float.intBitsToFloat((int) primitive);
-    }
-
-    /**
-     * Returns the primitive double value this constant represents. The constant must have kind
-     * {@link Kind#Double}.
-     * 
-     * @return the constant value
-     */
-    public double asDouble() {
-        assert getKind() == Kind.Double;
-        return Double.longBitsToDouble(primitive);
-    }
-
-    /**
-     * Returns the object reference this constant represents. The constant must have kind
-     * {@link Kind#Object}.
-     * 
-     * @return the constant value
-     */
-    public Object asObject() {
-        assert getKind() == Kind.Object;
-        return object;
-    }
-
-    /**
-     * Gets the annotation (if any) associated with this constant.
-     * 
-     * @return null if this constant is not primitive or has no annotation
-     */
-    public Object getPrimitiveAnnotation() {
-        return getKind() == Kind.Object ? null : object;
-    }
-
-    /**
-     * Computes the hashcode of this constant.
-     * 
-     * @return a suitable hashcode for this constant
-     */
-    @Override
-    public int hashCode() {
-        if (getKind() == Kind.Object) {
-            return System.identityHashCode(object);
-        }
-        return (int) primitive * getKind().ordinal();
-    }
-
-    /**
-     * Checks whether this constant equals another object. This is only true if the other object is
-     * a constant that has the same {@linkplain #getKind() kind}, value and
-     * {@link #getPrimitiveAnnotation() annotation}.
-     * 
-     * @param o the object to compare equality
-     * @return {@code true} if this constant is equivalent to the specified object
-     */
-    @Override
-    public boolean equals(Object o) {
-        return o == this || o instanceof Constant && valueEqual((Constant) o, false);
-    }
-
-    /**
      * Creates a boxed double constant.
-     * 
+     *
      * @param d the double value to box
      * @return a boxed copy of {@code value}
      */
@@ -291,12 +163,12 @@
         if (Double.compare(d, 1.0D) == 0) {
             return DOUBLE_1;
         }
-        return new Constant(Kind.Double, null, Double.doubleToRawLongBits(d));
+        return new PrimitiveConstant(Kind.Double, Double.doubleToRawLongBits(d));
     }
 
     /**
      * Creates a boxed float constant.
-     * 
+     *
      * @param f the float value to box
      * @return a boxed copy of {@code value}
      */
@@ -310,22 +182,22 @@
         if (Float.compare(f, 2.0F) == 0) {
             return FLOAT_2;
         }
-        return new Constant(Kind.Float, null, Float.floatToRawIntBits(f));
+        return new PrimitiveConstant(Kind.Float, Float.floatToRawIntBits(f));
     }
 
     /**
      * Creates a boxed long constant.
-     * 
+     *
      * @param i the long value to box
      * @return a boxed copy of {@code value}
      */
     public static Constant forLong(long i) {
-        return i == 0 ? LONG_0 : i == 1 ? LONG_1 : new Constant(Kind.Long, null, i);
+        return i == 0 ? LONG_0 : i == 1 ? LONG_1 : new PrimitiveConstant(Kind.Long, i);
     }
 
     /**
      * Creates a boxed integer constant.
-     * 
+     *
      * @param i the integer value to box
      * @return a boxed copy of {@code value}
      */
@@ -336,22 +208,22 @@
         if (i >= 0 && i < INT_CONSTANT_CACHE.length) {
             return INT_CONSTANT_CACHE[i];
         }
-        return new Constant(Kind.Int, null, i);
+        return new PrimitiveConstant(Kind.Int, i);
     }
 
     /**
      * Creates a boxed byte constant.
-     * 
+     *
      * @param i the byte value to box
      * @return a boxed copy of {@code value}
      */
     public static Constant forByte(byte i) {
-        return new Constant(Kind.Byte, null, i);
+        return new PrimitiveConstant(Kind.Byte, i);
     }
 
     /**
      * Creates a boxed boolean constant.
-     * 
+     *
      * @param i the boolean value to box
      * @return a boxed copy of {@code value}
      */
@@ -361,52 +233,33 @@
 
     /**
      * Creates a boxed char constant.
-     * 
+     *
      * @param i the char value to box
      * @return a boxed copy of {@code value}
      */
     public static Constant forChar(char i) {
-        return new Constant(Kind.Char, null, i);
+        return new PrimitiveConstant(Kind.Char, i);
     }
 
     /**
      * Creates a boxed short constant.
-     * 
+     *
      * @param i the short value to box
      * @return a boxed copy of {@code value}
      */
     public static Constant forShort(short i) {
-        return new Constant(Kind.Short, null, i);
+        return new PrimitiveConstant(Kind.Short, i);
     }
 
     /**
-     * Creates a boxed object constant.
-     * 
-     * @param o the object value to box
-     * @return a boxed copy of {@code value}
+     * Creates a {@link Constant} from a primitive integer of a certain kind.
      */
-    public static Constant forObject(Object o) {
-        if (o == null) {
-            return NULL_OBJECT;
-        }
-        return new Constant(Kind.Object, o, 0L);
-    }
-
-    /**
-     * Creates an annotated int or long constant. An annotation enables a client to associate some
-     * extra semantic or debugging information with a primitive. An annotated primitive constant is
-     * never {@linkplain #equals(Object) equal} to a non-annotated constant.
-     * 
-     * @param kind the type of this constant
-     * @param i the value of this constant
-     * @param annotation an arbitrary non-null object
-     */
-    public static Constant forIntegerKind(Kind kind, long i, Object annotation) {
+    public static Constant forIntegerKind(Kind kind, long i) {
         switch (kind) {
             case Int:
-                return new Constant(kind, annotation, (int) i);
+                return new PrimitiveConstant(kind, (int) i);
             case Long:
-                return new Constant(kind, annotation, i);
+                return new PrimitiveConstant(kind, i);
             default:
                 throw new IllegalArgumentException("not an integer kind: " + kind);
         }
@@ -418,47 +271,42 @@
     public static Constant forPrimitiveInt(int bits, long i) {
         assert bits <= 64;
         if (bits > 32) {
-            return new Constant(Kind.Long, null, i);
+            return new PrimitiveConstant(Kind.Long, i);
         } else {
-            return new Constant(Kind.Int, null, (int) i);
+            return new PrimitiveConstant(Kind.Int, (int) i);
         }
     }
 
     /**
-     * Creates a boxed constant for the given kind from an Object. The object needs to be of the
-     * Java boxed type corresponding to the kind.
-     * 
-     * @param kind the kind of the constant to create
-     * @param value the Java boxed value: a {@link Byte} instance for {@link Kind#Byte}, etc.
-     * @return the boxed copy of {@code value}
+     * Creates a boxed constant for the given boxed primitive value.
+     *
+     * @param value the Java boxed value
+     * @return the primitive constant holding the {@code value}
      */
-    public static Constant forBoxed(Kind kind, Object value) {
-        switch (kind) {
-            case Boolean:
-                return forBoolean((Boolean) value);
-            case Byte:
-                return forByte((Byte) value);
-            case Char:
-                return forChar((Character) value);
-            case Short:
-                return forShort((Short) value);
-            case Int:
-                return forInt((Integer) value);
-            case Long:
-                return forLong((Long) value);
-            case Float:
-                return forFloat((Float) value);
-            case Double:
-                return forDouble((Double) value);
-            case Object:
-                return forObject(value);
-            default:
-                throw new RuntimeException("cannot create Constant for boxed " + kind + " value");
+    public static Constant forBoxedPrimitive(Object value) {
+        if (value instanceof Boolean) {
+            return forBoolean((Boolean) value);
+        } else if (value instanceof Byte) {
+            return forByte((Byte) value);
+        } else if (value instanceof Character) {
+            return forChar((Character) value);
+        } else if (value instanceof Short) {
+            return forShort((Short) value);
+        } else if (value instanceof Integer) {
+            return forInt((Integer) value);
+        } else if (value instanceof Long) {
+            return forLong((Long) value);
+        } else if (value instanceof Float) {
+            return forFloat((Float) value);
+        } else if (value instanceof Double) {
+            return forDouble((Double) value);
+        } else {
+            return null;
         }
     }
 
     public static Constant forIllegal() {
-        return new Constant(Kind.Illegal, null, 0);
+        return new PrimitiveConstant(Kind.Illegal, 0);
     }
 
     /**
--- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ConstantPool.java	Mon Apr 07 23:35:41 2014 +0200
+++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ConstantPool.java	Mon Apr 07 16:09:17 2014 -0700
@@ -117,5 +117,5 @@
      *            {@code -1}
      * @return the appendix if it exists and is resolved or {@code null}
      */
-    Object lookupAppendix(int cpi, int opcode);
+    Constant lookupAppendix(int cpi, int opcode);
 }
--- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ConstantReflectionProvider.java	Mon Apr 07 23:35:41 2014 +0200
+++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ConstantReflectionProvider.java	Mon Apr 07 16:09:17 2014 -0700
@@ -23,34 +23,68 @@
 package com.oracle.graal.api.meta;
 
 /**
- * Reflection operations on values represented as {@linkplain Constant constants}.
+ * Reflection operations on values represented as {@linkplain Constant constants}. All methods in
+ * this interface require the VM to access the actual object encapsulated in {@link Kind#Object
+ * object} constants. This access is not always possible, depending on kind of VM and the state that
+ * the VM is in. Therefore, all methods can return {@code null} at any time, to indicate that the
+ * result is not available at this point. The caller is responsible to check for {@code null}
+ * results and handle them properly, e.g., not perform an optimization.
  */
 public interface ConstantReflectionProvider {
 
     /**
-     * Compares two constants for equality. The equality relationship is symmetric. If the constants
-     * cannot be compared at this point, the return value is {@code null};
-     * 
-     * @return {@code true} if the two parameters represent the same runtime object, {@code false}
-     *         if they are different, or {@code null} if the parameters cannot be compared.
+     * Compares two constants for equality. The equality relationship is symmetric. Returns
+     * {@link Boolean#TRUE true} if the two constants represent the same run time value,
+     * {@link Boolean#FALSE false} if they are different. Returns {@code null} if the constants
+     * cannot be compared at this point.
      */
     Boolean constantEquals(Constant x, Constant y);
 
     /**
-     * Returns the length of an array that is wrapped in a {@link Constant} object. If {@code array}
-     * is not an array, or the array length is not available at this point, the return value is
-     * {@code null}.
+     * Returns the length of the array constant. Returns {@code null} if the constant is not an
+     * array, or if the array length is not available at this point.
      */
-    Integer lookupArrayLength(Constant array);
+    Integer readArrayLength(Constant array);
 
     /**
-     * Reads a value of this kind using a base address and a displacement.
-     * 
-     * @param base the base address from which the value is read
+     * Reads a value from the given array at the given index. Returns {@code null} if the constant
+     * is not an array, if the index is out of bounds, or if the value is not available at this
+     * point.
+     */
+    Constant readArrayElement(Constant array, int index);
+
+    /**
+     * Reads a value of this kind using a base address and a displacement. No bounds checking or
+     * type checking is performed. Returns {@code null} if the value is not available at this point.
+     *
+     * @param base the base address from which the value is read.
      * @param displacement the displacement within the object in bytes
      * @param compressible whether this is a read of a compressed or an uncompressed pointer
      * @return the read value encapsulated in a {@link Constant} object, or {@code null} if the
      *         value cannot be read.
      */
-    Constant readUnsafeConstant(Kind kind, Object base, long displacement, boolean compressible);
+    Constant readUnsafeConstant(Kind kind, Constant base, long displacement, boolean compressible);
+
+    /**
+     * Converts the given {@link Kind#isPrimitive() primitive} constant to a boxed
+     * {@link Kind#Object object} constant, according to the Java boxing rules. Returns {@code null}
+     * if the source is is not a primitive constant, or the boxed value is not available at this
+     * point.
+     */
+    Constant boxPrimitive(Constant source);
+
+    /**
+     * Converts the given {@link Kind#Object object} constant to a {@link Kind#isPrimitive()
+     * primitive} constant, according to the Java unboxing rules. Returns {@code null} if the source
+     * is is not an object constant that can be unboxed, or the unboxed value is not available at
+     * this point.
+     */
+    Constant unboxPrimitive(Constant source);
+
+    /**
+     * Returns the {@link ResolvedJavaType} for a {@link Class} object (or any other object regarded
+     * as a class by the VM) encapsulated in the given constant. Returns {@code null} if the
+     * constant does not encapsulate a class, or if the type is not available at this point.
+     */
+    ResolvedJavaType asJavaType(Constant constant);
 }
--- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/MetaUtil.java	Mon Apr 07 23:35:41 2014 +0200
+++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/MetaUtil.java	Mon Apr 07 16:09:17 2014 -0700
@@ -55,13 +55,13 @@
      * @param printTopN print total size and instance count of the top n classes is desired
      * @return the number of bytes occupied by this constant
      */
-    public static long getMemorySizeRecursive(MetaAccessProvider access, Constant constant, PrintStream out, int printTopN) {
-        IdentityHashMap<Object, Boolean> marked = new IdentityHashMap<>();
+    public static long getMemorySizeRecursive(MetaAccessProvider access, ConstantReflectionProvider constantReflection, Constant constant, PrintStream out, int printTopN) {
+        Set<Constant> marked = new HashSet<>();
         Stack<Constant> stack = new Stack<>();
         if (constant.getKind() == Kind.Object && constant.isNonNull()) {
-            marked.put(constant.asObject(), Boolean.TRUE);
+            marked.add(constant);
         }
-        final HashMap<Class, ClassInfo> histogram = new HashMap<>();
+        final HashMap<ResolvedJavaType, ClassInfo> histogram = new HashMap<>();
         stack.push(constant);
         long sum = 0;
         while (!stack.isEmpty()) {
@@ -69,7 +69,7 @@
             long memorySize = access.getMemorySize(constant);
             sum += memorySize;
             if (c.getKind() == Kind.Object && c.isNonNull()) {
-                Class<?> clazz = c.asObject().getClass();
+                ResolvedJavaType clazz = access.lookupJavaType(c);
                 if (!histogram.containsKey(clazz)) {
                     histogram.put(clazz, new ClassInfo());
                 }
@@ -79,10 +79,10 @@
                 ResolvedJavaType type = access.lookupJavaType(c);
                 if (type.isArray()) {
                     if (!type.getComponentType().isPrimitive()) {
-                        Object[] array = (Object[]) c.asObject();
-                        for (Object value : array) {
-                            Constant forObject = Constant.forObject(value);
-                            pushConstant(marked, stack, forObject);
+                        int length = constantReflection.readArrayLength(c);
+                        for (int i = 0; i < length; i++) {
+                            Constant value = constantReflection.readArrayElement(c, i);
+                            pushConstant(marked, stack, value);
                         }
                     }
                 } else {
@@ -96,12 +96,12 @@
                 }
             }
         }
-        ArrayList<Class> clazzes = new ArrayList<>();
+        ArrayList<ResolvedJavaType> clazzes = new ArrayList<>();
         clazzes.addAll(histogram.keySet());
-        Collections.sort(clazzes, new Comparator<Class>() {
+        Collections.sort(clazzes, new Comparator<ResolvedJavaType>() {
 
             @Override
-            public int compare(Class o1, Class o2) {
+            public int compare(ResolvedJavaType o1, ResolvedJavaType o2) {
                 long l1 = histogram.get(o1).totalSize;
                 long l2 = histogram.get(o2).totalSize;
                 if (l1 > l2) {
@@ -115,7 +115,7 @@
         });
 
         int z = 0;
-        for (Class c : clazzes) {
+        for (ResolvedJavaType c : clazzes) {
             if (z > printTopN) {
                 break;
             }
@@ -126,10 +126,10 @@
         return sum;
     }
 
-    private static void pushConstant(IdentityHashMap<Object, Boolean> marked, Stack<Constant> stack, Constant value) {
+    private static void pushConstant(Set<Constant> marked, Stack<Constant> stack, Constant value) {
         if (value.isNonNull()) {
-            if (!marked.containsKey(value.asObject())) {
-                marked.put(value.asObject(), Boolean.TRUE);
+            if (!marked.contains(value)) {
+                marked.add(value);
                 stack.push(value);
             }
         }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/NullConstant.java	Mon Apr 07 16:09:17 2014 -0700
@@ -0,0 +1,91 @@
+/*
+ * 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.api.meta;
+
+/**
+ * The implementation type of the {@link Constant#NULL_OBJECT null constant}.
+ */
+final class NullConstant extends Constant {
+
+    private static final long serialVersionUID = 8906209595800783961L;
+
+    protected NullConstant() {
+        super(Kind.Object);
+    }
+
+    @Override
+    public boolean isNull() {
+        return true;
+    }
+
+    @Override
+    public boolean isDefaultForKind() {
+        return true;
+    }
+
+    @Override
+    public Object asBoxedPrimitive() {
+        throw new IllegalArgumentException();
+    }
+
+    @Override
+    public int asInt() {
+        throw new IllegalArgumentException();
+    }
+
+    @Override
+    public boolean asBoolean() {
+        throw new IllegalArgumentException();
+    }
+
+    @Override
+    public long asLong() {
+        throw new IllegalArgumentException();
+    }
+
+    @Override
+    public float asFloat() {
+        throw new IllegalArgumentException();
+    }
+
+    @Override
+    public double asDouble() {
+        throw new IllegalArgumentException();
+    }
+
+    @Override
+    public String toValueString() {
+        return "null";
+    }
+
+    @Override
+    public int hashCode() {
+        return System.identityHashCode(this);
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        assert o == this || !(o instanceof NullConstant) : "null constant is a singleton";
+        return o == this;
+    }
+}
--- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ObjectLocationIdentity.java	Mon Apr 07 23:35:41 2014 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,56 +0,0 @@
-/*
- * Copyright (c) 2013, 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.graal.api.meta;
-
-import java.util.*;
-
-/**
- * A {@link LocationIdentity} wrapping an object.
- */
-public final class ObjectLocationIdentity implements LocationIdentity {
-
-    private static IdentityHashMap<Object, LocationIdentity> map = new IdentityHashMap<>();
-
-    private Object object;
-
-    public static LocationIdentity create(Object object) {
-        synchronized (map) {
-            if (map.containsKey(object)) {
-                return map.get(object);
-            } else {
-                ObjectLocationIdentity locationIdentity = new ObjectLocationIdentity(object);
-                map.put(object, locationIdentity);
-                return locationIdentity;
-            }
-        }
-    }
-
-    private ObjectLocationIdentity(Object object) {
-        this.object = object;
-    }
-
-    @Override
-    public String toString() {
-        return "Identity(" + object + ")";
-    }
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/PrimitiveConstant.java	Mon Apr 07 16:09:17 2014 -0700
@@ -0,0 +1,129 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.api.meta;
+
+/**
+ * Represents a primitive constant value, such as an integer or floating point number, within the
+ * compiler and across the compiler/runtime interface.
+ */
+public class PrimitiveConstant extends Constant {
+
+    private static final long serialVersionUID = 8787949721295655376L;
+
+    /**
+     * The boxed primitive value as a {@code long}. For {@code float} and {@code double} values,
+     * this value is the result of {@link Float#floatToRawIntBits(float)} and
+     * {@link Double#doubleToRawLongBits(double)} respectively.
+     */
+    private final long primitive;
+
+    protected PrimitiveConstant(Kind kind, long primitive) {
+        super(kind);
+        this.primitive = primitive;
+
+        assert kind.isPrimitive() || kind == Kind.Illegal;
+    }
+
+    @Override
+    public boolean isNull() {
+        return false;
+    }
+
+    @Override
+    public boolean isDefaultForKind() {
+        return primitive == 0;
+    }
+
+    @Override
+    public boolean asBoolean() {
+        assert getKind() == Kind.Boolean;
+        return primitive != 0L;
+    }
+
+    @Override
+    public int asInt() {
+        assert getKind().getStackKind() == Kind.Int;
+        return (int) primitive;
+    }
+
+    @Override
+    public long asLong() {
+        assert getKind().isNumericInteger();
+        return primitive;
+    }
+
+    @Override
+    public float asFloat() {
+        assert getKind() == Kind.Float;
+        return Float.intBitsToFloat((int) primitive);
+    }
+
+    @Override
+    public double asDouble() {
+        assert getKind() == Kind.Double;
+        return Double.longBitsToDouble(primitive);
+    }
+
+    @Override
+    public Object asBoxedPrimitive() {
+        switch (getKind()) {
+            case Byte:
+                return Byte.valueOf((byte) primitive);
+            case Boolean:
+                return Boolean.valueOf(asBoolean());
+            case Short:
+                return Short.valueOf((short) primitive);
+            case Char:
+                return Character.valueOf((char) primitive);
+            case Int:
+                return Integer.valueOf(asInt());
+            case Long:
+                return Long.valueOf(asLong());
+            case Float:
+                return Float.valueOf(asFloat());
+            case Double:
+                return Double.valueOf(asDouble());
+            default:
+                throw new IllegalArgumentException();
+        }
+    }
+
+    @Override
+    public int hashCode() {
+        return (int) (primitive ^ (primitive >>> 32)) * (getKind().ordinal() + 31);
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        return o == this || (o instanceof PrimitiveConstant && super.equals(o) && primitive == ((PrimitiveConstant) o).primitive);
+    }
+
+    @Override
+    public String toString() {
+        if (getKind() == Kind.Illegal) {
+            return "illegal";
+        } else {
+            return getKind().getJavaName() + "[" + getKind().format(asBoxedPrimitive()) + "|0x" + Long.toHexString(primitive) + "]";
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.api.replacements/src/com/oracle/graal/api/replacements/SnippetReflectionProvider.java	Mon Apr 07 16:09:17 2014 -0700
@@ -0,0 +1,70 @@
+/*
+ * 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.api.replacements;
+
+import com.oracle.graal.api.meta.*;
+
+/**
+ * Reflection operations on values represented as {@linkplain Constant constants} for the processing
+ * of snippets. Snippets need a direct access to the value of object constants, which is not allowed
+ * in other parts of Graal to enforce compiler-VM separation.
+ * <p>
+ * This interface must not be used in Graal code that is not related to snippet processing.
+ */
+public interface SnippetReflectionProvider {
+
+    /**
+     * Creates a boxed {@link Kind#Object object} constant.
+     *
+     * @param object the object value to box
+     * @return a constant containing {@code object}
+     */
+    Constant forObject(Object object);
+
+    /**
+     * Returns the object reference the given constant represents. The constant must have kind
+     * {@link Kind#Object}.
+     *
+     * @param constant the to access
+     * @return the object value of the constant
+     */
+    Object asObject(Constant constant);
+
+    /**
+     * Creates a boxed constant for the given kind from an Object. The object needs to be of the
+     * Java boxed type corresponding to the kind.
+     *
+     * @param kind the kind of the constant to create
+     * @param value the Java boxed value: a {@link Byte} instance for {@link Kind#Byte}, etc.
+     * @return the boxed copy of {@code value}
+     */
+    Constant forBoxed(Kind kind, Object value);
+
+    /**
+     * Returns the value of this constant as a boxed Java value.
+     *
+     * @param constant the constant to box
+     * @return the value of the constant
+     */
+    Object asBoxedValue(Constant constant);
+}
--- a/graal/com.oracle.graal.asm.hsail/src/com/oracle/graal/asm/hsail/HSAILAssembler.java	Mon Apr 07 23:35:41 2014 +0200
+++ b/graal/com.oracle.graal.asm.hsail/src/com/oracle/graal/asm/hsail/HSAILAssembler.java	Mon Apr 07 16:09:17 2014 -0700
@@ -25,9 +25,6 @@
 import static com.oracle.graal.api.code.MemoryBarriers.*;
 import static com.oracle.graal.api.code.ValueUtil.*;
 
-import java.lang.reflect.*;
-
-import com.amd.okra.*;
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.graph.*;
@@ -36,7 +33,7 @@
 /**
  * This class contains routines to emit HSAIL assembly code.
  */
-public class HSAILAssembler extends AbstractHSAILAssembler {
+public abstract class HSAILAssembler extends AbstractHSAILAssembler {
 
     /**
      * Stack size in bytes (used to keep track of spilling).
@@ -87,35 +84,13 @@
      * references get updated by the GC whenever the GC moves an Object.
      *
      * @param a the destination register
-     * @param obj the Object being moved
+     * @param src the Object Constant being moved
      */
-    public final void mov(Register a, Object obj) {
-        String regName = "$d" + a.encoding();
-        // For a null object simply move 0x0 into the destination register.
-        if (obj == null) {
-            emitString("mov_b64 " + regName + ", 0x0;  // null object");
-        } else {
-            // Get a JNI reference handle to the object.
-            long refHandle = OkraUtil.getRefHandle(obj);
-            // Get the clasname of the object for emitting a comment.
-            Class<?> clazz = obj.getClass();
-            String className = clazz.getName();
-            String comment = "// handle for object of type " + className;
-            // If the object is an array note the array length in the comment.
-            if (className.startsWith("[")) {
-                comment += ", length " + Array.getLength(obj);
-            }
-            // First move the reference handle into a register.
-            emitString("mov_b64 " + regName + ", 0x" + Long.toHexString(refHandle) + ";    " + comment);
-            // Next load the Object addressed by this reference handle into the destination reg.
-            emitString("ld_global_u64 " + regName + ", [" + regName + "];");
-        }
-
-    }
+    public abstract void mov(Register a, Constant src);
 
     public final void emitMov(Kind kind, Value dst, Value src) {
         if (isRegister(dst) && isConstant(src) && kind.getStackKind() == Kind.Object) {
-            mov(asRegister(dst), (asConstant(src)).asObject());
+            mov(asRegister(dst), asConstant(src));
         } else {
             String argtype = getArgTypeFromKind(kind).substring(1);
             emitString("mov_b" + argtype + " " + mapRegOrConstToString(dst) + ", " + mapRegOrConstToString(src) + ";");
@@ -127,7 +102,7 @@
         if (reg instanceof RegisterValue) {
             storeValue = HSAIL.mapRegister(reg);
         } else if (reg instanceof Constant) {
-            storeValue = ((Constant) reg).asBoxedValue().toString();
+            storeValue = ((Constant) reg).toValueString();
         }
         emitString(instr + " " + storeValue + ", " + mapAddress(addr) + ";");
     }
@@ -320,7 +295,7 @@
         String unorderedPrefix = (argType.startsWith("f") && unordered ? "u" : "");
         String prefix = "cmp_" + condition + unorderedPrefix + "_b1_" + (isUnsignedCompare ? getArgTypeForceUnsigned(src1) : argType);
         // Generate a comment for debugging purposes
-        String comment = (isConstant(src1) && (src1.getKind() == Kind.Object) && (asConstant(src1).asObject() == null) ? " // null test " : "");
+        String comment = (isConstant(src1) && (src1.getKind() == Kind.Object) && (asConstant(src1).isNull()) ? " // null test " : "");
         // Emit the instruction.
         emitString(prefix + " $c0, " + mapRegOrConstToString(src0) + ", " + mapRegOrConstToString(src1) + ";" + comment);
     }
@@ -367,8 +342,7 @@
                 case Long:
                     return "0x" + Long.toHexString(consrc.asLong());
                 case Object:
-                    Object obj = consrc.asObject();
-                    if (obj == null) {
+                    if (consrc.isNull()) {
                         return "0";
                     } else {
                         throw GraalInternalError.shouldNotReachHere("unknown type: " + src);
--- a/graal/com.oracle.graal.asm.ptx/src/com/oracle/graal/asm/ptx/PTXAssembler.java	Mon Apr 07 23:35:41 2014 +0200
+++ b/graal/com.oracle.graal.asm.ptx/src/com/oracle/graal/asm/ptx/PTXAssembler.java	Mon Apr 07 16:09:17 2014 -0700
@@ -370,7 +370,7 @@
             assert var instanceof Variable;
             assert val instanceof Constant;
             Constant constant = (Constant) val;
-            return ("[" + ((space == PTXStateSpace.Parameter) ? emitParameter((Variable) var) : emitRegister((Variable) var, false)) + " + " + constant.asBoxedValue() + "]");
+            return ("[" + ((space == PTXStateSpace.Parameter) ? emitParameter((Variable) var) : emitRegister((Variable) var, false)) + " + " + constant.toValueString() + "]");
         }
 
         @Override
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/GraalCompilerTest.java	Mon Apr 07 23:35:41 2014 +0200
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/GraalCompilerTest.java	Mon Apr 07 16:09:17 2014 -0700
@@ -38,6 +38,7 @@
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.code.CallingConvention.Type;
 import com.oracle.graal.api.meta.*;
+import com.oracle.graal.api.replacements.*;
 import com.oracle.graal.api.runtime.*;
 import com.oracle.graal.baseline.*;
 import com.oracle.graal.compiler.target.*;
@@ -240,6 +241,10 @@
         return providers;
     }
 
+    protected SnippetReflectionProvider getSnippetReflection() {
+        return Graal.getRequiredCapability(SnippetReflectionProvider.class);
+    }
+
     protected TargetDescription getTarget() {
         return getProviders().getCodeCache().getTarget();
     }
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/backend/AllocatorTest.java	Mon Apr 07 23:35:41 2014 +0200
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/backend/AllocatorTest.java	Mon Apr 07 16:09:17 2014 -0700
@@ -114,7 +114,7 @@
         SchedulePhase schedule = null;
         try (Scope s = Debug.scope("FrontEnd")) {
             schedule = GraalCompiler.emitFrontEnd(getProviders(), getBackend().getTarget(), graph, assumptions, null, getDefaultGraphBuilderSuite(), OptimisticOptimizations.NONE,
-                            graph.method().getProfilingInfo(), new SpeculationLog(), getSuites());
+                            graph.method().getProfilingInfo(), null, getSuites());
         } catch (Throwable e) {
             throw Debug.handle(e);
         }
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/deopt/CompiledMethodTest.java	Mon Apr 07 23:35:41 2014 +0200
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/deopt/CompiledMethodTest.java	Mon Apr 07 16:09:17 2014 -0700
@@ -59,8 +59,8 @@
         new DeadCodeEliminationPhase().apply(graph);
 
         for (ConstantNode node : ConstantNode.getConstantNodes(graph)) {
-            if (node.getKind() == Kind.Object && " ".equals(node.getValue().asObject())) {
-                node.replace(graph, ConstantNode.forObject("-", getMetaAccess(), graph));
+            if (node.getKind() == Kind.Object && " ".equals(getSnippetReflection().asObject(node.getValue()))) {
+                node.replace(graph, ConstantNode.forConstant(getSnippetReflection().forObject("-"), getMetaAccess(), graph));
             }
         }
 
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/EscapeAnalysisTest.java	Mon Apr 07 23:35:41 2014 +0200
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/EscapeAnalysisTest.java	Mon Apr 07 16:09:17 2014 -0700
@@ -62,7 +62,7 @@
 
     @Test
     public void test3() {
-        testEscapeAnalysis("test3Snippet", Constant.forObject(null), false);
+        testEscapeAnalysis("test3Snippet", Constant.NULL_OBJECT, false);
     }
 
     public static Object test3Snippet() {
@@ -257,7 +257,7 @@
 
     @Test
     public void testCheckCast() {
-        testEscapeAnalysis("testCheckCastSnippet", Constant.forObject(TestClassObject.class), false);
+        testEscapeAnalysis("testCheckCastSnippet", getSnippetReflection().forObject(TestClassObject.class), false);
     }
 
     public Object testCheckCastSnippet() {
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotBackendFactory.java	Mon Apr 07 23:35:41 2014 +0200
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotBackendFactory.java	Mon Apr 07 16:09:17 2014 -0700
@@ -27,6 +27,7 @@
 import com.oracle.graal.amd64.*;
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
+import com.oracle.graal.api.replacements.*;
 import com.oracle.graal.api.runtime.*;
 import com.oracle.graal.hotspot.*;
 import com.oracle.graal.hotspot.meta.*;
@@ -108,10 +109,11 @@
         // to be valid for the entire run of the VM.
         Assumptions assumptions = new Assumptions(false);
         Providers p = new Providers(metaAccess, codeCache, constantReflection, foreignCalls, lowerer, null);
-        Replacements replacements = createReplacements(runtime, assumptions, p);
+        HotSpotSnippetReflectionProvider snippetReflection = createSnippetReflection();
+        Replacements replacements = createReplacements(runtime, assumptions, p, snippetReflection);
         HotSpotDisassemblerProvider disassembler = createDisassembler(runtime);
         HotSpotSuitesProvider suites = createSuites(runtime);
-        HotSpotProviders providers = new HotSpotProviders(metaAccess, codeCache, constantReflection, foreignCalls, lowerer, replacements, disassembler, suites, registers);
+        HotSpotProviders providers = new HotSpotProviders(metaAccess, codeCache, constantReflection, foreignCalls, lowerer, replacements, disassembler, suites, registers, snippetReflection);
 
         return createBackend(runtime, providers);
     }
@@ -128,8 +130,8 @@
         return new HotSpotDisassemblerProvider(runtime);
     }
 
-    protected Replacements createReplacements(HotSpotGraalRuntime runtime, Assumptions assumptions, Providers p) {
-        return new HotSpotReplacementsImpl(p, runtime.getConfig(), assumptions, p.getCodeCache().getTarget());
+    protected Replacements createReplacements(HotSpotGraalRuntime runtime, Assumptions assumptions, Providers p, SnippetReflectionProvider snippetReflection) {
+        return new HotSpotReplacementsImpl(p, snippetReflection, runtime.getConfig(), assumptions, p.getCodeCache().getTarget());
     }
 
     protected AMD64HotSpotForeignCallsProvider createForeignCalls(HotSpotGraalRuntime runtime, HotSpotMetaAccessProvider metaAccess, HotSpotCodeCacheProvider codeCache,
@@ -153,6 +155,10 @@
         return new HotSpotSuitesProvider(runtime);
     }
 
+    protected HotSpotSnippetReflectionProvider createSnippetReflection() {
+        return new HotSpotSnippetReflectionProvider();
+    }
+
     protected AMD64HotSpotLoweringProvider createLowerer(HotSpotGraalRuntime runtime, HotSpotMetaAccessProvider metaAccess, HotSpotForeignCallsProvider foreignCalls, HotSpotRegistersProvider registers) {
         return new AMD64HotSpotLoweringProvider(runtime, metaAccess, foreignCalls, registers);
     }
@@ -183,15 +189,15 @@
         } else {
             /*
              * System V Application Binary Interface, AMD64 Architecture Processor Supplement
-             * 
+             *
              * Draft Version 0.96
-             * 
+             *
              * http://www.uclibc.org/docs/psABI-x86_64.pdf
-             * 
+             *
              * 3.2.1
-             * 
+             *
              * ...
-             * 
+             *
              * This subsection discusses usage of each register. Registers %rbp, %rbx and %r12
              * through %r15 "belong" to the calling function and the called function is required to
              * preserve their values. In other words, a called function must preserve these
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerator.java	Mon Apr 07 23:35:41 2014 +0200
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerator.java	Mon Apr 07 16:09:17 2014 -0700
@@ -344,7 +344,12 @@
      */
     protected static Constant compress(Constant c, CompressEncoding encoding) {
         if (c.getKind() == Kind.Long) {
-            return Constant.forIntegerKind(Kind.Int, (int) (((c.asLong() - encoding.base) >> encoding.shift) & 0xffffffffL), c.getPrimitiveAnnotation());
+            int compressedValue = (int) (((c.asLong() - encoding.base) >> encoding.shift) & 0xffffffffL);
+            if (c instanceof HotSpotMetaspaceConstant) {
+                return HotSpotMetaspaceConstant.forMetaspaceObject(Kind.Int, compressedValue, HotSpotMetaspaceConstant.getMetaspaceObject(c));
+            } else {
+                return Constant.forIntegerKind(Kind.Int, compressedValue);
+            }
         } else {
             throw GraalInternalError.shouldNotReachHere();
         }
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLoweringProvider.java	Mon Apr 07 23:35:41 2014 +0200
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLoweringProvider.java	Mon Apr 07 16:09:17 2014 -0700
@@ -41,7 +41,7 @@
 
     @Override
     public void initialize(HotSpotProviders providers, HotSpotVMConfig config) {
-        convertSnippets = new AMD64ConvertSnippets.Templates(providers, providers.getCodeCache().getTarget());
+        convertSnippets = new AMD64ConvertSnippets.Templates(providers, providers.getSnippetReflection(), providers.getCodeCache().getTarget());
         super.initialize(providers, config);
     }
 
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotMemoryPeephole.java	Mon Apr 07 23:35:41 2014 +0200
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotMemoryPeephole.java	Mon Apr 07 16:09:17 2014 -0700
@@ -31,6 +31,7 @@
 import com.oracle.graal.graph.*;
 import com.oracle.graal.hotspot.*;
 import com.oracle.graal.hotspot.data.*;
+import com.oracle.graal.hotspot.meta.*;
 import com.oracle.graal.lir.*;
 import com.oracle.graal.lir.amd64.*;
 import com.oracle.graal.lir.amd64.AMD64ControlFlow.BranchOp;
@@ -63,9 +64,9 @@
                 masm.cmpl(x.toAddress(), 0);
             } else {
                 if (y.getKind() == Kind.Object) {
-                    crb.recordInlineDataInCode(new OopData(0, constant.asObject(), true));
+                    crb.recordInlineDataInCode(new OopData(0, HotSpotObjectConstant.asObject(constant), true));
                 } else if (y.getKind() == Kind.Long) {
-                    crb.recordInlineDataInCode(new MetaspaceData(0, constant.asLong(), constant.getPrimitiveAnnotation(), true));
+                    crb.recordInlineDataInCode(new MetaspaceData(0, constant.asLong(), HotSpotMetaspaceConstant.getMetaspaceObject(constant), true));
                 } else {
                     throw GraalInternalError.shouldNotReachHere();
                 }
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotMove.java	Mon Apr 07 23:35:41 2014 +0200
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotMove.java	Mon Apr 07 16:09:17 2014 -0700
@@ -34,6 +34,7 @@
 import com.oracle.graal.graph.*;
 import com.oracle.graal.hotspot.HotSpotVMConfig.CompressEncoding;
 import com.oracle.graal.hotspot.data.*;
+import com.oracle.graal.hotspot.meta.*;
 import com.oracle.graal.hotspot.nodes.type.*;
 import com.oracle.graal.lir.*;
 import com.oracle.graal.lir.amd64.*;
@@ -53,8 +54,8 @@
         public void emitMemAccess(CompilationResultBuilder crb, AMD64MacroAssembler masm) {
             if (kind == Kind.Long) {
                 if (NumUtil.isInt(input.asLong())) {
-                    if (input.getPrimitiveAnnotation() != null) {
-                        crb.recordInlineDataInCode(new MetaspaceData(0, input.asLong(), input.getPrimitiveAnnotation(), true));
+                    if (input instanceof HotSpotMetaspaceConstant) {
+                        crb.recordInlineDataInCode(new MetaspaceData(0, input.asLong(), HotSpotMetaspaceConstant.getMetaspaceObject(input), true));
                     }
                     masm.movl(address.toAddress(), (int) input.asLong());
                 } else {
@@ -64,7 +65,7 @@
                 if (input.isNull()) {
                     masm.movl(address.toAddress(), 0);
                 } else if (crb.target.inlineObjects) {
-                    crb.recordInlineDataInCode(new OopData(0, input.asObject(), true));
+                    crb.recordInlineDataInCode(new OopData(0, HotSpotObjectConstant.asObject(input), true));
                     masm.movl(address.toAddress(), 0xDEADDEAD);
                 } else {
                     throw GraalInternalError.shouldNotReachHere("Cannot store 64-bit constants to memory");
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotSafepointOp.java	Mon Apr 07 23:35:41 2014 +0200
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotSafepointOp.java	Mon Apr 07 16:09:17 2014 -0700
@@ -77,7 +77,7 @@
         if (ImmutableCode.getValue()) {
             Kind hostWordKind = HotSpotGraalRuntime.getHostWordKind();
             int alignment = hostWordKind.getBitCount() / Byte.SIZE;
-            Constant pollingPageAddress = Constant.forIntegerKind(hostWordKind, config.safepointPollingAddress, null);
+            Constant pollingPageAddress = Constant.forIntegerKind(hostWordKind, config.safepointPollingAddress);
             // This move will be patched to load the safepoint page from a data segment
             // co-located with the immutable code.
             asm.movq(scratch, (AMD64Address) crb.recordDataReferenceInCode(pollingPageAddress, alignment));
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotAssembler.java	Mon Apr 07 16:09:17 2014 -0700
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.hotspot.hsail;
+
+import java.lang.reflect.*;
+
+import com.amd.okra.*;
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.asm.hsail.*;
+import com.oracle.graal.hotspot.meta.*;
+
+/**
+ * This class contains routines to emit HSAIL assembly code.
+ */
+public class HSAILHotSpotAssembler extends HSAILAssembler {
+
+    public HSAILHotSpotAssembler(TargetDescription target) {
+        super(target);
+    }
+
+    @Override
+    public final void mov(Register a, Constant src) {
+        String regName = "$d" + a.encoding();
+        // For a null object simply move 0x0 into the destination register.
+        if (src.isNull()) {
+            emitString("mov_b64 " + regName + ", 0x0;  // null object");
+        } else {
+            Object obj = HotSpotObjectConstant.asObject(src);
+            // Get a JNI reference handle to the object.
+            long refHandle = OkraUtil.getRefHandle(obj);
+            // Get the clasname of the object for emitting a comment.
+            Class<?> clazz = obj.getClass();
+            String className = clazz.getName();
+            String comment = "// handle for object of type " + className;
+            // If the object is an array note the array length in the comment.
+            if (className.startsWith("[")) {
+                comment += ", length " + Array.getLength(obj);
+            }
+            // First move the reference handle into a register.
+            emitString("mov_b64 " + regName + ", 0x" + Long.toHexString(refHandle) + ";    " + comment);
+            // Next load the Object addressed by this reference handle into the destination reg.
+            emitString("ld_global_u64 " + regName + ", [" + regName + "];");
+        }
+    }
+}
--- a/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotBackend.java	Mon Apr 07 23:35:41 2014 +0200
+++ b/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotBackend.java	Mon Apr 07 16:09:17 2014 -0700
@@ -412,7 +412,7 @@
 
     @Override
     protected Assembler createAssembler(FrameMap frameMap) {
-        return new HSAILAssembler(getTarget());
+        return new HSAILHotSpotAssembler(getTarget());
     }
 
     @Override
--- a/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotBackendFactory.java	Mon Apr 07 23:35:41 2014 +0200
+++ b/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotBackendFactory.java	Mon Apr 07 16:09:17 2014 -0700
@@ -50,10 +50,10 @@
         // to be valid for the entire run of the VM.
         Assumptions assumptions = new Assumptions(false);
         Providers p = new Providers(metaAccess, codeCache, constantReflection, foreignCalls, lowerer, null);
-        Replacements replacements = new HSAILHotSpotReplacementsImpl(p, assumptions, codeCache.getTarget(), host.getReplacements());
+        Replacements replacements = new HSAILHotSpotReplacementsImpl(p, host.getSnippetReflection(), assumptions, codeCache.getTarget(), host.getReplacements());
         HotSpotDisassemblerProvider disassembler = host.getDisassembler();
         SuitesProvider suites = new DefaultSuitesProvider();
-        HotSpotProviders providers = new HotSpotProviders(metaAccess, codeCache, constantReflection, foreignCalls, lowerer, replacements, disassembler, suites, registers);
+        HotSpotProviders providers = new HotSpotProviders(metaAccess, codeCache, constantReflection, foreignCalls, lowerer, replacements, disassembler, suites, registers, host.getSnippetReflection());
 
         return new HSAILHotSpotBackend(runtime, providers);
     }
--- a/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotLIRGenerator.java	Mon Apr 07 23:35:41 2014 +0200
+++ b/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotLIRGenerator.java	Mon Apr 07 16:09:17 2014 -0700
@@ -252,7 +252,12 @@
      */
     protected static Constant compress(Constant c, CompressEncoding encoding) {
         if (c.getKind() == Kind.Long) {
-            return Constant.forIntegerKind(Kind.Int, (int) (((c.asLong() - encoding.base) >> encoding.shift) & 0xffffffffL), c.getPrimitiveAnnotation());
+            int compressedValue = (int) (((c.asLong() - encoding.base) >> encoding.shift) & 0xffffffffL);
+            if (c instanceof HotSpotMetaspaceConstant) {
+                return HotSpotMetaspaceConstant.forMetaspaceObject(Kind.Int, compressedValue, HotSpotMetaspaceConstant.getMetaspaceObject(c));
+            } else {
+                return Constant.forIntegerKind(Kind.Int, compressedValue);
+            }
         } else {
             throw GraalInternalError.shouldNotReachHere();
         }
--- a/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotNodeLIRBuilder.java	Mon Apr 07 23:35:41 2014 +0200
+++ b/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotNodeLIRBuilder.java	Mon Apr 07 16:09:17 2014 -0700
@@ -30,6 +30,7 @@
 import com.oracle.graal.compiler.hsail.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.hotspot.HotSpotVMConfig.CompressEncoding;
+import com.oracle.graal.hotspot.meta.*;
 import com.oracle.graal.hotspot.nodes.*;
 import com.oracle.graal.lir.*;
 import com.oracle.graal.lir.hsail.*;
@@ -102,7 +103,12 @@
      */
     protected static Constant compress(Constant c, CompressEncoding encoding) {
         if (c.getKind() == Kind.Long) {
-            return Constant.forIntegerKind(Kind.Int, (int) (((c.asLong() - encoding.base) >> encoding.shift) & 0xffffffffL), c.getPrimitiveAnnotation());
+            int compressedValue = (int) (((c.asLong() - encoding.base) >> encoding.shift) & 0xffffffffL);
+            if (c instanceof HotSpotMetaspaceConstant) {
+                return HotSpotMetaspaceConstant.forMetaspaceObject(Kind.Int, compressedValue, HotSpotMetaspaceConstant.getMetaspaceObject(c));
+            } else {
+                return Constant.forIntegerKind(Kind.Int, compressedValue);
+            }
         } else {
             throw GraalInternalError.shouldNotReachHere();
         }
--- a/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotReplacementsImpl.java	Mon Apr 07 23:35:41 2014 +0200
+++ b/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotReplacementsImpl.java	Mon Apr 07 16:09:17 2014 -0700
@@ -27,6 +27,7 @@
 
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
+import com.oracle.graal.api.replacements.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.phases.util.*;
@@ -41,8 +42,8 @@
     private final Replacements host;
     private HashSet<ResolvedJavaMethod> ignoredResolvedMethods = new HashSet<>();
 
-    public HSAILHotSpotReplacementsImpl(Providers providers, Assumptions assumptions, TargetDescription target, Replacements host) {
-        super(providers, assumptions, target);
+    public HSAILHotSpotReplacementsImpl(Providers providers, SnippetReflectionProvider snippetReflection, Assumptions assumptions, TargetDescription target, Replacements host) {
+        super(providers, snippetReflection, assumptions, target);
         this.host = host;
     }
 
--- a/graal/com.oracle.graal.hotspot.ptx/src/com/oracle/graal/hotspot/ptx/PTXHotSpotBackendFactory.java	Mon Apr 07 23:35:41 2014 +0200
+++ b/graal/com.oracle.graal.hotspot.ptx/src/com/oracle/graal/hotspot/ptx/PTXHotSpotBackendFactory.java	Mon Apr 07 16:09:17 2014 -0700
@@ -47,7 +47,7 @@
         HotSpotDisassemblerProvider disassembler = host.getDisassembler();
         SuitesProvider suites = new DefaultSuitesProvider();
         HotSpotRegistersProvider registers = new HotSpotRegisters(PTX.tid, Register.None, Register.None);
-        HotSpotProviders providers = new HotSpotProviders(metaAccess, codeCache, constantReflection, foreignCalls, lowerer, replacements, disassembler, suites, registers);
+        HotSpotProviders providers = new HotSpotProviders(metaAccess, codeCache, constantReflection, foreignCalls, lowerer, replacements, disassembler, suites, registers, host.getSnippetReflection());
         return new PTXHotSpotBackend(runtime, providers);
     }
 
--- a/graal/com.oracle.graal.hotspot.ptx/src/com/oracle/graal/hotspot/ptx/PTXWrapperBuilder.java	Mon Apr 07 23:35:41 2014 +0200
+++ b/graal/com.oracle.graal.hotspot.ptx/src/com/oracle/graal/hotspot/ptx/PTXWrapperBuilder.java	Mon Apr 07 16:09:17 2014 -0700
@@ -192,7 +192,7 @@
             }
         }
 
-        InvokeNode kernelStart = createInvoke(getClass(), "getKernelStart", ConstantNode.forObject(kernel, providers.getMetaAccess(), getGraph()));
+        InvokeNode kernelStart = createInvoke(getClass(), "getKernelStart", ConstantNode.forConstant(HotSpotObjectConstant.forObject(kernel), providers.getMetaAccess(), getGraph()));
 
         AllocaNode buf = append(new AllocaNode(bufSize / wordSize, new BitSet()));
         ValueNode objectParametersOffsets;
@@ -290,8 +290,8 @@
             Debug.dump(getGraph(), "Initial kernel launch graph");
         }
 
-        rewriteWordTypes();
-        inlineInvokes();
+        rewriteWordTypes(providers.getSnippetReflection());
+        inlineInvokes(providers.getSnippetReflection());
 
         if (Debug.isDumpEnabled()) {
             Debug.dump(getGraph(), "Kernel launch graph before compilation");
--- a/graal/com.oracle.graal.hotspot.server/src/com/oracle/graal/hotspot/server/ReplacingStreams.java	Mon Apr 07 23:35:41 2014 +0200
+++ b/graal/com.oracle.graal.hotspot.server/src/com/oracle/graal/hotspot/server/ReplacingStreams.java	Mon Apr 07 16:09:17 2014 -0700
@@ -28,6 +28,7 @@
 
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.hotspot.logging.*;
+import com.oracle.graal.hotspot.meta.*;
 
 public class ReplacingStreams {
 
@@ -172,7 +173,7 @@
                 if (constant.getKind() != Kind.Object) {
                     return obj;
                 }
-                Object contents = constant.asObject();
+                Object contents = HotSpotObjectConstant.asObject(constant);
                 if (contents == null) {
                     return obj;
                 }
@@ -182,12 +183,12 @@
                 }
                 placeholder = objectMap.get(contents);
                 if (placeholder != null) {
-                    return Constant.forObject(placeholder);
+                    return HotSpotObjectConstant.forObject(placeholder);
                 }
                 if (contents instanceof Remote) {
-                    return Constant.forObject(createRemoteCallPlaceholder(contents));
+                    return HotSpotObjectConstant.forObject(createRemoteCallPlaceholder(contents));
                 }
-                return Constant.forObject(createDummyPlaceholder(contents));
+                return HotSpotObjectConstant.forObject(createDummyPlaceholder(contents));
             }
             return obj;
         }
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotBackendFactory.java	Mon Apr 07 23:35:41 2014 +0200
+++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotBackendFactory.java	Mon Apr 07 16:09:17 2014 -0700
@@ -60,10 +60,11 @@
         // to be valid for the entire run of the VM.
         Assumptions assumptions = new Assumptions(false);
         Providers p = new Providers(metaAccess, codeCache, constantReflection, foreignCalls, lowerer, null);
-        HotSpotReplacementsImpl replacements = new HotSpotReplacementsImpl(p, runtime.getConfig(), assumptions, target);
+        HotSpotSnippetReflectionProvider snippetReflection = new HotSpotSnippetReflectionProvider();
+        HotSpotReplacementsImpl replacements = new HotSpotReplacementsImpl(p, snippetReflection, runtime.getConfig(), assumptions, target);
         HotSpotDisassemblerProvider disassembler = new HotSpotDisassemblerProvider(runtime);
         HotSpotSuitesProvider suites = new HotSpotSuitesProvider(runtime);
-        HotSpotProviders providers = new HotSpotProviders(metaAccess, codeCache, constantReflection, foreignCalls, lowerer, replacements, disassembler, suites, registers);
+        HotSpotProviders providers = new HotSpotProviders(metaAccess, codeCache, constantReflection, foreignCalls, lowerer, replacements, disassembler, suites, registers, snippetReflection);
 
         return new SPARCHotSpotBackend(runtime, providers);
     }
--- a/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/AheadOfTimeCompilationTest.java	Mon Apr 07 23:35:41 2014 +0200
+++ b/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/AheadOfTimeCompilationTest.java	Mon Apr 07 16:09:17 2014 -0700
@@ -104,7 +104,7 @@
 
         NodeIterable<ConstantNode> filter = getConstantNodes(result);
         assertEquals(1, filter.count());
-        Object mirror = filter.first().asConstant().asObject();
+        Object mirror = HotSpotObjectConstant.asObject(filter.first().asConstant());
         assertEquals(Class.class, mirror.getClass());
         assertEquals(AheadOfTimeCompilationTest.class, mirror);
 
@@ -132,7 +132,7 @@
         StructuredGraph result = compile("getPrimitiveClassObject", false);
         NodeIterable<ConstantNode> filter = getConstantNodes(result);
         assertEquals(1, filter.count());
-        Object mirror = filter.first().asConstant().asObject();
+        Object mirror = HotSpotObjectConstant.asObject(filter.first().asConstant());
         assertEquals(Class.class, mirror.getClass());
         assertEquals(Integer.TYPE, mirror);
 
@@ -160,7 +160,7 @@
 
         NodeIterable<ConstantNode> filter = getConstantNodes(result);
         assertEquals(1, filter.count());
-        Object mirror = filter.first().asConstant().asObject();
+        Object mirror = HotSpotObjectConstant.asObject(filter.first().asConstant());
         assertEquals(String.class, mirror.getClass());
         assertEquals("test string", mirror);
 
@@ -193,7 +193,7 @@
         assertEquals(1, getConstantNodes(result).count());
         ConstantNode constant = getConstantNodes(result).first();
         assertEquals(Kind.Object, constant.getKind());
-        assertEquals(Boolean.TRUE, constant.asConstant().asObject());
+        assertEquals(Boolean.TRUE, HotSpotObjectConstant.asObject(constant.asConstant()));
     }
 
     private StructuredGraph compile(String test, boolean compileAOT) {
--- a/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/InstalledCodeExecuteHelperTest.java	Mon Apr 07 23:35:41 2014 +0200
+++ b/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/InstalledCodeExecuteHelperTest.java	Mon Apr 07 16:09:17 2014 -0700
@@ -89,7 +89,7 @@
             assert parameterTypes.length == args.length;
             for (int i = 0; i < argsToBind.length; i++) {
                 ParameterNode param = graph.getParameter(i);
-                Constant c = Constant.forBoxed(parameterTypes[i].getKind(), argsToBind[i]);
+                Constant c = HotSpotObjectConstant.forBoxedValue(parameterTypes[i].getKind(), argsToBind[i]);
                 ConstantNode replacement = ConstantNode.forConstant(c, getMetaAccess(), graph);
                 param.replaceAtUsages(replacement);
             }
--- a/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/WriteBarrierAdditionTest.java	Mon Apr 07 23:35:41 2014 +0200
+++ b/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/WriteBarrierAdditionTest.java	Mon Apr 07 16:09:17 2014 -0700
@@ -187,7 +187,7 @@
      */
     @Test
     public void test8() throws Exception {
-        test2("testUnsafeLoad", wr, new Long(32), null);
+        test2("testUnsafeLoad", wr, new Long(useCompressedOops() ? 20 : 32), null);
     }
 
     /**
@@ -207,7 +207,7 @@
      */
     @Test
     public void test9() throws Exception {
-        test2("testUnsafeLoad", wr, new Long(16), new Integer(16));
+        test2("testUnsafeLoad", wr, new Long(useCompressedOops() ? 10 : 16), new Integer(useCompressedOops() ? 10 : 16));
     }
 
     static Object[] src = new Object[1];
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotGraalRuntime.java	Mon Apr 07 23:35:41 2014 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotGraalRuntime.java	Mon Apr 07 16:09:17 2014 -0700
@@ -34,6 +34,7 @@
 
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
+import com.oracle.graal.api.replacements.*;
 import com.oracle.graal.api.runtime.*;
 import com.oracle.graal.compiler.target.*;
 import com.oracle.graal.graph.*;
@@ -362,6 +363,8 @@
     public <T> T getCapability(Class<T> clazz) {
         if (clazz == RuntimeProvider.class) {
             return (T) this;
+        } else if (clazz == SnippetReflectionProvider.class) {
+            return (T) getHostProviders().getSnippetReflection();
         }
         return null;
     }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotReplacementsImpl.java	Mon Apr 07 23:35:41 2014 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotReplacementsImpl.java	Mon Apr 07 16:09:17 2014 -0700
@@ -26,6 +26,7 @@
 
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
+import com.oracle.graal.api.replacements.*;
 import com.oracle.graal.hotspot.meta.*;
 import com.oracle.graal.hotspot.replacements.*;
 import com.oracle.graal.nodes.*;
@@ -41,8 +42,8 @@
 
     private final HotSpotVMConfig config;
 
-    public HotSpotReplacementsImpl(Providers providers, HotSpotVMConfig config, Assumptions assumptions, TargetDescription target) {
-        super(providers, assumptions, target);
+    public HotSpotReplacementsImpl(Providers providers, SnippetReflectionProvider snippetReflection, HotSpotVMConfig config, Assumptions assumptions, TargetDescription target) {
+        super(providers, snippetReflection, assumptions, target);
         this.config = config;
     }
 
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotCodeCacheProvider.java	Mon Apr 07 23:35:41 2014 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotCodeCacheProvider.java	Mon Apr 07 16:09:17 2014 -0700
@@ -251,14 +251,14 @@
     }
 
     public boolean needsDataPatch(Constant constant) {
-        return constant.getPrimitiveAnnotation() != null;
+        return constant instanceof HotSpotMetaspaceConstant;
     }
 
     public Data createDataItem(Constant constant, int alignment) {
-        if (constant.getPrimitiveAnnotation() != null) {
-            return new MetaspaceData(alignment, constant.asLong(), constant.getPrimitiveAnnotation(), false);
+        if (constant instanceof HotSpotMetaspaceConstant) {
+            return new MetaspaceData(alignment, constant.asLong(), HotSpotMetaspaceConstant.getMetaspaceObject(constant), false);
         } else if (constant.getKind().isObject()) {
-            return new OopData(alignment, constant.asObject(), false);
+            return new OopData(alignment, HotSpotObjectConstant.asObject(constant), false);
         } else {
             return new PrimitiveData(constant, alignment);
         }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotConstantPool.java	Mon Apr 07 23:35:41 2014 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotConstantPool.java	Mon Apr 07 16:09:17 2014 -0700
@@ -368,13 +368,13 @@
                 return lookupType(cpi, opcode);
             case String:
                 Object string = runtime().getCompilerToVM().resolvePossiblyCachedConstantInPool(metaspaceConstantPool, cpi);
-                return Constant.forObject(string);
+                return HotSpotObjectConstant.forObject(string);
             case MethodHandle:
             case MethodHandleInError:
             case MethodType:
             case MethodTypeInError:
                 Object obj = runtime().getCompilerToVM().resolveConstantInPool(metaspaceConstantPool, cpi);
-                return Constant.forObject(obj);
+                return HotSpotObjectConstant.forObject(obj);
             default:
                 throw GraalInternalError.shouldNotReachHere("unknown constant pool tag " + tag);
         }
@@ -394,10 +394,15 @@
     }
 
     @Override
-    public Object lookupAppendix(int cpi, int opcode) {
+    public Constant lookupAppendix(int cpi, int opcode) {
         assert Bytecodes.isInvoke(opcode);
         final int index = toConstantPoolIndex(cpi, opcode);
-        return runtime().getCompilerToVM().lookupAppendixInPool(metaspaceConstantPool, index);
+        Object result = runtime().getCompilerToVM().lookupAppendixInPool(metaspaceConstantPool, index);
+        if (result == null) {
+            return null;
+        } else {
+            return HotSpotObjectConstant.forObject(result);
+        }
     }
 
     /**
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotConstantReflectionProvider.java	Mon Apr 07 23:35:41 2014 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotConstantReflectionProvider.java	Mon Apr 07 16:09:17 2014 -0700
@@ -48,15 +48,34 @@
     }
 
     @Override
-    public Integer lookupArrayLength(Constant array) {
-        if (array.getKind() != Kind.Object || array.isNull() || !array.asObject().getClass().isArray()) {
+    public Integer readArrayLength(Constant array) {
+        if (array.getKind() != Kind.Object || array.isNull() || !HotSpotObjectConstant.asObject(array).getClass().isArray()) {
             return null;
         }
-        return Array.getLength(array.asObject());
+        return Array.getLength(HotSpotObjectConstant.asObject(array));
     }
 
     @Override
-    public Constant readUnsafeConstant(Kind kind, Object base, long displacement, boolean compressible) {
+    public Constant readUnsafeConstant(Kind kind, Constant baseConstant, long initialDisplacement, boolean compressible) {
+        Object base;
+        long displacement;
+        if (baseConstant.getKind() == Kind.Object) {
+            base = HotSpotObjectConstant.asObject(baseConstant);
+            displacement = initialDisplacement;
+            if (base == null) {
+                return null;
+            }
+        } else if (baseConstant.getKind().isNumericInteger()) {
+            long baseLong = baseConstant.asLong();
+            if (baseLong == 0L) {
+                return null;
+            }
+            displacement = initialDisplacement + baseLong;
+            base = null;
+        } else {
+            throw GraalInternalError.shouldNotReachHere();
+        }
+
         switch (kind) {
             case Boolean:
                 return Constant.forBoolean(base == null ? unsafe.getByte(displacement) != 0 : unsafe.getBoolean(base, displacement));
@@ -89,10 +108,55 @@
                 } else {
                     o = runtime.getCompilerToVM().readUnsafeUncompressedPointer(base, displacement);
                 }
-                return Constant.forObject(o);
+                return HotSpotObjectConstant.forObject(o);
             }
             default:
                 throw GraalInternalError.shouldNotReachHere();
         }
     }
+
+    @Override
+    public Constant readArrayElement(Constant array, int index) {
+        if (array.getKind() != Kind.Object || array.isNull()) {
+            return null;
+        }
+        Object a = HotSpotObjectConstant.asObject(array);
+
+        if (index < 0 || index >= Array.getLength(a)) {
+            return null;
+        }
+
+        if (a instanceof Object[]) {
+            return HotSpotObjectConstant.forObject(((Object[]) a)[index]);
+        } else {
+            return Constant.forBoxedPrimitive(Array.get(a, index));
+        }
+    }
+
+    @Override
+    public Constant boxPrimitive(Constant source) {
+        if (!source.getKind().isPrimitive()) {
+            return null;
+        }
+        return HotSpotObjectConstant.forObject(source.asBoxedPrimitive());
+    }
+
+    @Override
+    public Constant unboxPrimitive(Constant source) {
+        if (!source.getKind().isObject()) {
+            return null;
+        }
+        return Constant.forBoxedPrimitive(HotSpotObjectConstant.asObject(source));
+    }
+
+    @Override
+    public ResolvedJavaType asJavaType(Constant constant) {
+        if (constant.getKind() == Kind.Object) {
+            Object obj = HotSpotObjectConstant.asObject(constant);
+            if (obj instanceof Class) {
+                return runtime.getHostProviders().getMetaAccess().lookupJavaType((Class) obj);
+            }
+        }
+        return null;
+    }
 }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotHostForeignCallsProvider.java	Mon Apr 07 23:35:41 2014 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotHostForeignCallsProvider.java	Mon Apr 07 16:09:17 2014 -0700
@@ -42,7 +42,7 @@
 import static com.oracle.graal.hotspot.stubs.NewInstanceStub.*;
 import static com.oracle.graal.hotspot.stubs.StubUtil.*;
 import static com.oracle.graal.hotspot.stubs.UnwindExceptionToCallerStub.*;
-import static com.oracle.graal.java.GraphBuilderPhase.RuntimeCalls.*;
+import static com.oracle.graal.hotspot.meta.HotSpotLoweringProvider.RuntimeCalls.*;
 import static com.oracle.graal.nodes.java.RegisterFinalizerNode.*;
 import static com.oracle.graal.replacements.Log.*;
 import static com.oracle.graal.replacements.MathSubstitutionsX86.*;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotLoweringProvider.java	Mon Apr 07 23:35:41 2014 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotLoweringProvider.java	Mon Apr 07 16:09:17 2014 -0700
@@ -90,7 +90,7 @@
         newObjectSnippets = new NewObjectSnippets.Templates(providers, target);
         monitorSnippets = new MonitorSnippets.Templates(providers, target, config.useFastLocking);
         writeBarrierSnippets = new WriteBarrierSnippets.Templates(providers, target, config.useCompressedOops ? config.getOopEncoding() : null);
-        boxingSnippets = new BoxingSnippets.Templates(providers, target);
+        boxingSnippets = new BoxingSnippets.Templates(providers, providers.getSnippetReflection(), target);
         exceptionObjectSnippets = new LoadExceptionObjectSnippets.Templates(providers, target);
         unsafeLoadSnippets = new UnsafeLoadSnippets.Templates(providers, target);
         providers.getReplacements().registerSnippetTemplateCache(new UnsafeArrayCopySnippets.Templates(providers, target));
@@ -134,8 +134,8 @@
             lowerOSRStartNode((OSRStartNode) n);
         } else if (n instanceof DynamicCounterNode) {
             lowerDynamicCounterNode((DynamicCounterNode) n);
-        } else if (n instanceof DeferredForeignCallNode) {
-            lowerDeferredForeignCallNode((DeferredForeignCallNode) n);
+        } else if (n instanceof BytecodeExceptionNode) {
+            lowerBytecodeExceptionNode((BytecodeExceptionNode) n);
         } else if (n instanceof CheckCastDynamicNode) {
             checkcastDynamicSnippets.lower((CheckCastDynamicNode) n, tool);
         } else if (n instanceof InstanceOfNode) {
@@ -307,7 +307,7 @@
     private void lowerLoadFieldNode(LoadFieldNode loadField, LoweringTool tool) {
         StructuredGraph graph = loadField.graph();
         HotSpotResolvedJavaField field = (HotSpotResolvedJavaField) loadField.field();
-        ValueNode object = loadField.isStatic() ? ConstantNode.forObject(field.getDeclaringClass().mirror(), metaAccess, graph) : loadField.object();
+        ValueNode object = loadField.isStatic() ? ConstantNode.forConstant(HotSpotObjectConstant.forObject(field.getDeclaringClass().mirror()), metaAccess, graph) : loadField.object();
         assert loadField.getKind() != Kind.Illegal;
         BarrierType barrierType = getFieldLoadBarrierType(field);
 
@@ -351,7 +351,7 @@
     private void lowerStoreFieldNode(StoreFieldNode storeField, LoweringTool tool) {
         StructuredGraph graph = storeField.graph();
         HotSpotResolvedJavaField field = (HotSpotResolvedJavaField) storeField.field();
-        ValueNode object = storeField.isStatic() ? ConstantNode.forObject(field.getDeclaringClass().mirror(), metaAccess, graph) : storeField.object();
+        ValueNode object = storeField.isStatic() ? ConstantNode.forConstant(HotSpotObjectConstant.forObject(field.getDeclaringClass().mirror()), metaAccess, graph) : storeField.object();
         BarrierType barrierType = getFieldStoreBarrierType(storeField);
 
         ValueNode value = implicitStoreConvert(graph, storeField.field().getKind(), storeField.value());
@@ -661,11 +661,51 @@
         }
     }
 
-    private void lowerDeferredForeignCallNode(DeferredForeignCallNode deferred) {
-        StructuredGraph graph = deferred.graph();
+    static final class Exceptions {
+        protected static final ArrayIndexOutOfBoundsException cachedArrayIndexOutOfBoundsException;
+        protected static final NullPointerException cachedNullPointerException;
+
+        static {
+            cachedArrayIndexOutOfBoundsException = new ArrayIndexOutOfBoundsException();
+            cachedArrayIndexOutOfBoundsException.setStackTrace(new StackTraceElement[0]);
+            cachedNullPointerException = new NullPointerException();
+            cachedNullPointerException.setStackTrace(new StackTraceElement[0]);
+        }
+    }
+
+    public static final class RuntimeCalls {
+        public static final ForeignCallDescriptor CREATE_NULL_POINTER_EXCEPTION = new ForeignCallDescriptor("createNullPointerException", NullPointerException.class);
+        public static final ForeignCallDescriptor CREATE_OUT_OF_BOUNDS_EXCEPTION = new ForeignCallDescriptor("createOutOfBoundsException", ArrayIndexOutOfBoundsException.class, int.class);
+    }
+
+    private void lowerBytecodeExceptionNode(BytecodeExceptionNode node) {
+        StructuredGraph graph = node.graph();
         if (graph.getGuardsStage() == StructuredGraph.GuardsStage.FLOATING_GUARDS) {
-            ForeignCallNode foreignCallNode = graph.add(new ForeignCallNode(foreignCalls, deferred.getDescriptor(), deferred.stamp(), deferred.getArguments()));
-            graph.replaceFixedWithFixed(deferred, foreignCallNode);
+            if (OmitHotExceptionStacktrace.getValue()) {
+                Throwable exception;
+                if (node.getExceptionClass() == NullPointerException.class) {
+                    exception = Exceptions.cachedNullPointerException;
+                } else if (node.getExceptionClass() == ArrayIndexOutOfBoundsException.class) {
+                    exception = Exceptions.cachedArrayIndexOutOfBoundsException;
+                } else {
+                    throw GraalInternalError.shouldNotReachHere();
+                }
+                FloatingNode exceptionNode = ConstantNode.forConstant(HotSpotObjectConstant.forObject(exception), metaAccess, graph);
+                graph.replaceFixedWithFloating(node, exceptionNode);
+
+            } else {
+                ForeignCallDescriptor descriptor;
+                if (node.getExceptionClass() == NullPointerException.class) {
+                    descriptor = RuntimeCalls.CREATE_NULL_POINTER_EXCEPTION;
+                } else if (node.getExceptionClass() == ArrayIndexOutOfBoundsException.class) {
+                    descriptor = RuntimeCalls.CREATE_OUT_OF_BOUNDS_EXCEPTION;
+                } else {
+                    throw GraalInternalError.shouldNotReachHere();
+                }
+
+                ForeignCallNode foreignCallNode = graph.add(new ForeignCallNode(foreignCalls, descriptor, node.stamp(), node.getArguments()));
+                graph.replaceFixedWithFixed(node, foreignCallNode);
+            }
         }
     }
 
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMetaAccessProvider.java	Mon Apr 07 23:35:41 2014 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMetaAccessProvider.java	Mon Apr 07 16:09:17 2014 -0700
@@ -54,7 +54,7 @@
         if (constant.getKind() != Kind.Object || constant.isNull()) {
             return null;
         }
-        Object o = constant.asObject();
+        Object o = HotSpotObjectConstant.asObject(constant);
         return HotSpotResolvedObjectType.fromClass(o.getClass());
     }
 
@@ -295,7 +295,7 @@
             } else {
                 if (lookupJavaType.isArray()) {
                     // TODO(tw): Add compressed pointer support.
-                    int length = Array.getLength(constant.asObject());
+                    int length = Array.getLength(HotSpotObjectConstant.asObject(constant));
                     ResolvedJavaType elementType = lookupJavaType.getComponentType();
                     Kind elementKind = elementType.getKind();
                     final int headerSize = HotSpotGraalRuntime.getArrayBaseOffset(elementKind);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMetaspaceConstant.java	Mon Apr 07 16:09:17 2014 -0700
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2014, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.hotspot.meta;
+
+import java.util.*;
+
+import com.oracle.graal.api.meta.*;
+
+public final class HotSpotMetaspaceConstant extends PrimitiveConstant {
+
+    private static final long serialVersionUID = 1003463314013122983L;
+
+    public static Constant forMetaspaceObject(Kind kind, long primitive, Object metaspaceObject) {
+        return new HotSpotMetaspaceConstant(kind, primitive, metaspaceObject);
+    }
+
+    public static Object getMetaspaceObject(Constant constant) {
+        return ((HotSpotMetaspaceConstant) constant).metaspaceObject;
+    }
+
+    private final Object metaspaceObject;
+
+    private HotSpotMetaspaceConstant(Kind kind, long primitive, Object metaspaceObject) {
+        super(kind, primitive);
+        this.metaspaceObject = metaspaceObject;
+    }
+
+    @Override
+    public int hashCode() {
+        return super.hashCode() ^ System.identityHashCode(metaspaceObject);
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        return o == this || (o instanceof HotSpotMetaspaceConstant && super.equals(o) && Objects.equals(metaspaceObject, ((HotSpotMetaspaceConstant) o).metaspaceObject));
+    }
+
+    @Override
+    public String toString() {
+        return super.toString() + "{" + metaspaceObject + "}";
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotObjectConstant.java	Mon Apr 07 16:09:17 2014 -0700
@@ -0,0 +1,140 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.hotspot.meta;
+
+import com.oracle.graal.api.meta.*;
+
+/**
+ * Represents a constant non-{@code null} object reference, within the compiler and across the
+ * compiler/runtime interface.
+ */
+public final class HotSpotObjectConstant extends Constant {
+
+    private static final long serialVersionUID = 3592151693708093496L;
+
+    public static Constant forObject(Object object) {
+        if (object == null) {
+            return Constant.NULL_OBJECT;
+        } else {
+            return new HotSpotObjectConstant(object);
+        }
+    }
+
+    public static Constant forBoxedValue(Kind kind, Object value) {
+        if (kind == Kind.Object) {
+            return HotSpotObjectConstant.forObject(value);
+        } else {
+            return Constant.forBoxedPrimitive(value);
+        }
+    }
+
+    public static Object asObject(Constant constant) {
+        if (constant.isNull()) {
+            return null;
+        } else {
+            return ((HotSpotObjectConstant) constant).object;
+        }
+    }
+
+    public static Object asBoxedValue(Constant constant) {
+        if (constant.isNull()) {
+            return null;
+        } else if (constant.getKind() == Kind.Object) {
+            return ((HotSpotObjectConstant) constant).object;
+        } else {
+            return constant.asBoxedPrimitive();
+        }
+    }
+
+    private final Object object;
+
+    private HotSpotObjectConstant(Object object) {
+        super(Kind.Object);
+        this.object = object;
+        assert object != null;
+    }
+
+    @Override
+    public boolean isNull() {
+        return false;
+    }
+
+    @Override
+    public boolean isDefaultForKind() {
+        return false;
+    }
+
+    @Override
+    public Object asBoxedPrimitive() {
+        throw new IllegalArgumentException();
+    }
+
+    @Override
+    public int asInt() {
+        throw new IllegalArgumentException();
+    }
+
+    @Override
+    public boolean asBoolean() {
+        throw new IllegalArgumentException();
+    }
+
+    @Override
+    public long asLong() {
+        throw new IllegalArgumentException();
+    }
+
+    @Override
+    public float asFloat() {
+        throw new IllegalArgumentException();
+    }
+
+    @Override
+    public double asDouble() {
+        throw new IllegalArgumentException();
+    }
+
+    @Override
+    public int hashCode() {
+        return System.identityHashCode(object);
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        return o == this || (o instanceof HotSpotObjectConstant && super.equals(o) && object == ((HotSpotObjectConstant) o).object);
+    }
+
+    @Override
+    public String toValueString() {
+        if (object instanceof String) {
+            return (String) object;
+        } else {
+            return Kind.Object.format(object);
+        }
+    }
+
+    @Override
+    public String toString() {
+        return getKind().getJavaName() + "[" + Kind.Object.format(object) + "]";
+    }
+}
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotProviders.java	Mon Apr 07 23:35:41 2014 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotProviders.java	Mon Apr 07 16:09:17 2014 -0700
@@ -23,6 +23,7 @@
 package com.oracle.graal.hotspot.meta;
 
 import com.oracle.graal.api.meta.*;
+import com.oracle.graal.api.replacements.*;
 import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.phases.tiers.*;
 import com.oracle.graal.phases.util.*;
@@ -36,13 +37,16 @@
     private final HotSpotDisassemblerProvider disassembler;
     private final SuitesProvider suites;
     private final HotSpotRegistersProvider registers;
+    private final SnippetReflectionProvider snippetReflection;
 
     public HotSpotProviders(HotSpotMetaAccessProvider metaAccess, HotSpotCodeCacheProvider codeCache, ConstantReflectionProvider constantReflection, HotSpotForeignCallsProvider foreignCalls,
-                    LoweringProvider lowerer, Replacements replacements, HotSpotDisassemblerProvider disassembler, SuitesProvider suites, HotSpotRegistersProvider registers) {
+                    LoweringProvider lowerer, Replacements replacements, HotSpotDisassemblerProvider disassembler, SuitesProvider suites, HotSpotRegistersProvider registers,
+                    SnippetReflectionProvider snippetReflection) {
         super(metaAccess, codeCache, constantReflection, foreignCalls, lowerer, replacements);
         this.disassembler = disassembler;
         this.suites = suites;
         this.registers = registers;
+        this.snippetReflection = snippetReflection;
     }
 
     @Override
@@ -72,4 +76,7 @@
         return registers;
     }
 
+    public SnippetReflectionProvider getSnippetReflection() {
+        return snippetReflection;
+    }
 }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaField.java	Mon Apr 07 23:35:41 2014 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaField.java	Mon Apr 07 16:09:17 2014 -0700
@@ -213,7 +213,7 @@
              * have a non-default value.
              */
             assert !isStatic(modifiers);
-            Object object = receiver.asObject();
+            Object object = HotSpotObjectConstant.asObject(receiver);
 
             // Canonicalization may attempt to process an unsafe read before
             // processing a guard (e.g. a null check or a type check) for this read
@@ -234,7 +234,7 @@
                     if (StableOptionValue.class.isAssignableFrom(clazz)) {
                         assert getName().equals("value") : "Unexpected field in " + StableOptionValue.class.getName() + " hierarchy:" + this;
                         StableOptionValue<?> option = (StableOptionValue<?>) object;
-                        return Constant.forObject(option.getValue());
+                        return HotSpotObjectConstant.forObject(option.getValue());
                     }
                 }
             }
@@ -260,14 +260,13 @@
         if (receiver == null) {
             assert isStatic(modifiers);
             if (holder.isInitialized()) {
-                return runtime().getHostProviders().getConstantReflection().readUnsafeConstant(getKind(), holder.mirror(), offset, getKind() == Kind.Object);
+                return runtime().getHostProviders().getConstantReflection().readUnsafeConstant(getKind(), HotSpotObjectConstant.forObject(holder.mirror()), offset, getKind() == Kind.Object);
             }
             return null;
         } else {
             assert !isStatic(modifiers);
-            Object object = receiver.asObject();
-            assert object != null && isInObject(object);
-            return runtime().getHostProviders().getConstantReflection().readUnsafeConstant(getKind(), object, offset, getKind() == Kind.Object);
+            assert receiver.isNonNull() && isInObject(HotSpotObjectConstant.asObject(receiver));
+            return runtime().getHostProviders().getConstantReflection().readUnsafeConstant(getKind(), receiver, offset, getKind() == Kind.Object);
         }
     }
 
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaMethod.java	Mon Apr 07 23:35:41 2014 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaMethod.java	Mon Apr 07 16:09:17 2014 -0700
@@ -59,7 +59,7 @@
 
     /**
      * Gets the holder of a HotSpot metaspace method native object.
-     * 
+     *
      * @param metaspaceMethod a metaspace Method object
      * @return the {@link ResolvedJavaType} corresponding to the holder of the
      *         {@code metaspaceMethod}
@@ -74,7 +74,7 @@
 
     /**
      * Gets the {@link ResolvedJavaMethod} for a HotSpot metaspace method native object.
-     * 
+     *
      * @param metaspaceMethod a metaspace Method object
      * @return the {@link ResolvedJavaMethod} corresponding to {@code metaspaceMethod}
      */
@@ -110,7 +110,7 @@
     /**
      * Returns a pointer to this method's constant method data structure (
      * {@code Method::_constMethod}).
-     * 
+     *
      * @return pointer to this method's ConstMethod
      */
     private long getConstMethod() {
@@ -134,7 +134,7 @@
 
     /**
      * Returns this method's flags ({@code Method::_flags}).
-     * 
+     *
      * @return flags of this method
      */
     private int getFlags() {
@@ -143,7 +143,7 @@
 
     /**
      * Returns this method's constant method flags ({@code ConstMethod::_flags}).
-     * 
+     *
      * @return flags of this method's ConstMethod
      */
     private int getConstMethodFlags() {
@@ -159,7 +159,7 @@
      * Gets the address of the C++ Method object for this method.
      */
     public Constant getMetaspaceMethodConstant() {
-        return Constant.forIntegerKind(getHostWordKind(), metaspaceMethod, this);
+        return HotSpotMetaspaceConstant.forMetaspaceObject(getHostWordKind(), metaspaceMethod, this);
     }
 
     @Override
@@ -248,7 +248,7 @@
 
     /**
      * Returns true if this method has a {@code CallerSensitive} annotation.
-     * 
+     *
      * @return true if CallerSensitive annotation present, false otherwise
      */
     public boolean isCallerSensitive() {
@@ -257,7 +257,7 @@
 
     /**
      * Returns true if this method has a {@code ForceInline} annotation.
-     * 
+     *
      * @return true if ForceInline annotation present, false otherwise
      */
     public boolean isForceInline() {
@@ -266,7 +266,7 @@
 
     /**
      * Returns true if this method has a {@code DontInline} annotation.
-     * 
+     *
      * @return true if DontInline annotation present, false otherwise
      */
     public boolean isDontInline() {
@@ -283,7 +283,7 @@
     /**
      * Returns true if this method is one of the special methods that is ignored by security stack
      * walks.
-     * 
+     *
      * @return true if special method ignored by security stack walks, false otherwise
      */
     public boolean ignoredBySecurityStackWalk() {
@@ -374,7 +374,7 @@
 
     /**
      * Gets the value of {@code Method::_code}.
-     * 
+     *
      * @return the value of {@code Method::_code}
      */
     private long getCompiledCode() {
@@ -384,7 +384,7 @@
 
     /**
      * Returns whether this method has compiled code.
-     * 
+     *
      * @return true if this method has compiled code, false otherwise
      */
     public boolean hasCompiledCode() {
@@ -589,7 +589,7 @@
     /**
      * Returns the offset of this method into the v-table. The method must have a v-table entry as
      * indicated by {@link #isInVirtualMethodTable()}, otherwise an exception is thrown.
-     * 
+     *
      * @return the offset of this method into the v-table
      */
     public int vtableEntryOffset() {
@@ -608,7 +608,7 @@
 
     /**
      * Returns this method's virtual table index.
-     * 
+     *
      * @return virtual table index
      */
     private int getVtableIndex() {
@@ -618,7 +618,7 @@
 
     public SpeculationLog getSpeculationLog() {
         if (speculationLog == null) {
-            speculationLog = new SpeculationLog();
+            speculationLog = new HotSpotSpeculationLog();
         }
         return speculationLog;
     }
@@ -636,13 +636,13 @@
 
         Object[] objArguments = new Object[arguments.length];
         for (int i = 0; i < arguments.length; i++) {
-            objArguments[i] = arguments[i].asBoxedValue();
+            objArguments[i] = HotSpotObjectConstant.asBoxedValue(arguments[i]);
         }
-        Object objReceiver = receiver != null ? receiver.asObject() : null;
+        Object objReceiver = receiver != null ? HotSpotObjectConstant.asObject(receiver) : null;
 
         try {
             Object objResult = javaMethod.invoke(objReceiver, objArguments);
-            return javaMethod.getReturnType() == void.class ? null : Constant.forBoxed(getSignature().getReturnKind(), objResult);
+            return javaMethod.getReturnType() == void.class ? null : HotSpotObjectConstant.forBoxedValue(getSignature().getReturnKind(), objResult);
 
         } catch (IllegalAccessException | InvocationTargetException ex) {
             throw new IllegalArgumentException(ex);
@@ -657,13 +657,13 @@
 
         Object[] objArguments = new Object[arguments.length];
         for (int i = 0; i < arguments.length; i++) {
-            objArguments[i] = arguments[i].asBoxedValue();
+            objArguments[i] = HotSpotObjectConstant.asBoxedValue(arguments[i]);
         }
 
         try {
             Object objResult = javaConstructor.newInstance(objArguments);
             assert objResult != null;
-            return Constant.forObject(objResult);
+            return HotSpotObjectConstant.forObject(objResult);
 
         } catch (IllegalAccessException | InvocationTargetException | InstantiationException ex) {
             throw new IllegalArgumentException(ex);
@@ -672,7 +672,7 @@
 
     /**
      * Allocates a compile id for this method by asking the VM for one.
-     * 
+     *
      * @param entryBCI entry bci
      * @return compile id
      */
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedObjectType.java	Mon Apr 07 23:35:41 2014 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedObjectType.java	Mon Apr 07 16:09:17 2014 -0700
@@ -267,7 +267,7 @@
     public Constant getEncoding(Representation r) {
         switch (r) {
             case JavaClass:
-                return Constant.forObject(mirror());
+                return HotSpotObjectConstant.forObject(mirror());
             case ObjectHub:
                 return klass();
             default:
@@ -330,7 +330,7 @@
     @Override
     public boolean isInstance(Constant obj) {
         if (obj.getKind() == Kind.Object && !obj.isNull()) {
-            return mirror().isInstance(obj.asObject());
+            return mirror().isInstance(HotSpotObjectConstant.asObject(obj));
         }
         return false;
     }
@@ -661,7 +661,7 @@
      * Gets the metaspace Klass boxed in a {@link Constant}.
      */
     public Constant klass() {
-        return Constant.forIntegerKind(runtime().getTarget().wordKind, metaspaceKlass(), this);
+        return HotSpotMetaspaceConstant.forMetaspaceObject(runtime().getTarget().wordKind, metaspaceKlass(), this);
     }
 
     public boolean isPrimaryType() {
@@ -747,7 +747,7 @@
 
     @Override
     public Constant newArray(int length) {
-        return Constant.forObject(Array.newInstance(mirror(), length));
+        return HotSpotObjectConstant.forObject(Array.newInstance(mirror(), length));
     }
 
     /**
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedPrimitiveType.java	Mon Apr 07 23:35:41 2014 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedPrimitiveType.java	Mon Apr 07 16:09:17 2014 -0700
@@ -253,6 +253,6 @@
 
     @Override
     public Constant newArray(int length) {
-        return Constant.forObject(Array.newInstance(mirror(), length));
+        return HotSpotObjectConstant.forObject(Array.newInstance(mirror(), length));
     }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotSnippetReflectionProvider.java	Mon Apr 07 16:09:17 2014 -0700
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2014, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.hotspot.meta;
+
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.api.replacements.*;
+
+public class HotSpotSnippetReflectionProvider implements SnippetReflectionProvider {
+
+    @Override
+    public Constant forObject(Object object) {
+        return HotSpotObjectConstant.forObject(object);
+    }
+
+    @Override
+    public Object asObject(Constant constant) {
+        return HotSpotObjectConstant.asObject(constant);
+    }
+
+    @Override
+    public Constant forBoxed(Kind kind, Object value) {
+        return HotSpotObjectConstant.forBoxedValue(kind, value);
+    }
+
+    @Override
+    public Object asBoxedValue(Constant constant) {
+        return HotSpotObjectConstant.asBoxedValue(constant);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotSpeculationLog.java	Mon Apr 07 16:09:17 2014 -0700
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2014, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.hotspot.meta;
+
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
+
+public class HotSpotSpeculationLog extends SpeculationLog {
+
+    @Override
+    public Constant speculate(Object reason) {
+        addSpeculation(reason);
+        return HotSpotObjectConstant.forObject(reason);
+    }
+}
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nfi/NativeCallStubGraphBuilder.java	Mon Apr 07 23:35:41 2014 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nfi/NativeCallStubGraphBuilder.java	Mon Apr 07 16:09:17 2014 -0700
@@ -91,7 +91,7 @@
 
             ReturnNode returnNode = g.add(new ReturnNode(boxedResult));
             callNode.setNext(returnNode);
-            (new WordTypeRewriterPhase(providers.getMetaAccess(), Kind.Long)).apply(g);
+            (new WordTypeRewriterPhase(providers.getMetaAccess(), providers.getSnippetReflection(), Kind.Long)).apply(g);
             return g;
         } catch (NoSuchMethodException e) {
             throw GraalInternalError.shouldNotReachHere("Call Stub method not found");
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassCastNode.java	Mon Apr 07 23:35:41 2014 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassCastNode.java	Mon Apr 07 16:09:17 2014 -0700
@@ -54,7 +54,7 @@
         ValueNode javaClass = getJavaClass();
         if (javaClass.isConstant()) {
             ValueNode object = getObject();
-            Class c = (Class) javaClass.asConstant().asObject();
+            Class c = (Class) HotSpotObjectConstant.asObject(javaClass.asConstant());
             if (c != null && !c.isPrimitive()) {
                 HotSpotResolvedObjectType type = (HotSpotResolvedObjectType) HotSpotResolvedObjectType.fromClass(c);
                 CheckCastNode checkcast = graph().add(new CheckCastNode(type, object, null, false));
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassGetComponentTypeNode.java	Mon Apr 07 23:35:41 2014 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassGetComponentTypeNode.java	Mon Apr 07 16:09:17 2014 -0700
@@ -24,13 +24,14 @@
 
 import com.oracle.graal.graph.*;
 import com.oracle.graal.graph.spi.*;
+import com.oracle.graal.hotspot.meta.*;
 import com.oracle.graal.hotspot.replacements.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.replacements.nodes.*;
 
 /**
  * {@link MacroNode Macro node} for {@link Class#getComponentType()}.
- * 
+ *
  * @see ClassSubstitutions#getComponentType(Class)
  */
 public class ClassGetComponentTypeNode extends MacroNode implements Canonicalizable {
@@ -47,10 +48,10 @@
     public Node canonical(CanonicalizerTool tool) {
         ValueNode javaClass = getJavaClass();
         if (javaClass.isConstant()) {
-            Class c = (Class) javaClass.asConstant().asObject();
+            Class c = (Class) HotSpotObjectConstant.asObject(javaClass.asConstant());
             if (c != null) {
                 Class componentType = c.getComponentType();
-                return ConstantNode.forObject(componentType, tool.getMetaAccess(), graph());
+                return ConstantNode.forConstant(HotSpotObjectConstant.forObject(componentType), tool.getMetaAccess(), graph());
             }
         }
         return this;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassGetModifiersNode.java	Mon Apr 07 23:35:41 2014 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassGetModifiersNode.java	Mon Apr 07 16:09:17 2014 -0700
@@ -24,6 +24,7 @@
 
 import com.oracle.graal.graph.*;
 import com.oracle.graal.graph.spi.*;
+import com.oracle.graal.hotspot.meta.*;
 import com.oracle.graal.hotspot.replacements.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.replacements.nodes.*;
@@ -47,7 +48,7 @@
     public Node canonical(CanonicalizerTool tool) {
         ValueNode javaClass = getJavaClass();
         if (javaClass.isConstant()) {
-            Class c = (Class) javaClass.asConstant().asObject();
+            Class c = (Class) HotSpotObjectConstant.asObject(javaClass.asConstant());
             if (c != null) {
                 return ConstantNode.forInt(c.getModifiers(), graph());
             }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassGetSuperclassNode.java	Mon Apr 07 23:35:41 2014 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassGetSuperclassNode.java	Mon Apr 07 16:09:17 2014 -0700
@@ -24,13 +24,14 @@
 
 import com.oracle.graal.graph.*;
 import com.oracle.graal.graph.spi.*;
+import com.oracle.graal.hotspot.meta.*;
 import com.oracle.graal.hotspot.replacements.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.replacements.nodes.*;
 
 /**
  * {@link MacroNode Macro node} for {@link Class#getSuperclass()}.
- * 
+ *
  * @see ClassSubstitutions#getSuperclass(Class)
  */
 public class ClassGetSuperclassNode extends MacroNode implements Canonicalizable {
@@ -47,10 +48,10 @@
     public Node canonical(CanonicalizerTool tool) {
         ValueNode javaClass = getJavaClass();
         if (javaClass.isConstant()) {
-            Class c = (Class) javaClass.asConstant().asObject();
+            Class c = (Class) HotSpotObjectConstant.asObject(javaClass.asConstant());
             if (c != null) {
                 Class superclass = c.getSuperclass();
-                return ConstantNode.forObject(superclass, tool.getMetaAccess(), graph());
+                return ConstantNode.forConstant(HotSpotObjectConstant.forObject(superclass), tool.getMetaAccess(), graph());
             }
         }
         return this;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassIsArrayNode.java	Mon Apr 07 23:35:41 2014 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassIsArrayNode.java	Mon Apr 07 16:09:17 2014 -0700
@@ -24,6 +24,7 @@
 
 import com.oracle.graal.graph.*;
 import com.oracle.graal.graph.spi.*;
+import com.oracle.graal.hotspot.meta.*;
 import com.oracle.graal.hotspot.replacements.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.replacements.nodes.*;
@@ -47,7 +48,7 @@
     public Node canonical(CanonicalizerTool tool) {
         ValueNode javaClass = getJavaClass();
         if (javaClass.isConstant()) {
-            Class c = (Class) javaClass.asConstant().asObject();
+            Class c = (Class) HotSpotObjectConstant.asObject(javaClass.asConstant());
             if (c != null) {
                 return ConstantNode.forBoolean(c.isArray(), graph());
             }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassIsInstanceNode.java	Mon Apr 07 23:35:41 2014 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassIsInstanceNode.java	Mon Apr 07 16:09:17 2014 -0700
@@ -55,13 +55,13 @@
         ValueNode javaClass = getJavaClass();
         if (javaClass.isConstant()) {
             ValueNode object = getObject();
-            Class c = (Class) javaClass.asConstant().asObject();
+            Class c = (Class) HotSpotObjectConstant.asObject(javaClass.asConstant());
             if (c != null) {
                 if (c.isPrimitive()) {
                     return ConstantNode.forBoolean(false, graph());
                 }
                 if (object.isConstant()) {
-                    Object o = object.asConstant().asObject();
+                    Object o = HotSpotObjectConstant.asObject(object.asConstant());
                     return ConstantNode.forBoolean(o != null && c.isInstance(o), graph());
                 }
                 HotSpotResolvedObjectType type = (HotSpotResolvedObjectType) HotSpotResolvedObjectType.fromClass(c);
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassIsInterfaceNode.java	Mon Apr 07 23:35:41 2014 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassIsInterfaceNode.java	Mon Apr 07 16:09:17 2014 -0700
@@ -24,6 +24,7 @@
 
 import com.oracle.graal.graph.*;
 import com.oracle.graal.graph.spi.*;
+import com.oracle.graal.hotspot.meta.*;
 import com.oracle.graal.hotspot.replacements.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.replacements.nodes.*;
@@ -47,7 +48,7 @@
     public Node canonical(CanonicalizerTool tool) {
         ValueNode javaClass = getJavaClass();
         if (javaClass.isConstant()) {
-            Class c = (Class) javaClass.asConstant().asObject();
+            Class c = (Class) HotSpotObjectConstant.asObject(javaClass.asConstant());
             if (c != null) {
                 return ConstantNode.forBoolean(c.isInterface(), graph());
             }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassIsPrimitiveNode.java	Mon Apr 07 23:35:41 2014 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassIsPrimitiveNode.java	Mon Apr 07 16:09:17 2014 -0700
@@ -24,6 +24,7 @@
 
 import com.oracle.graal.graph.*;
 import com.oracle.graal.graph.spi.*;
+import com.oracle.graal.hotspot.meta.*;
 import com.oracle.graal.hotspot.replacements.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.replacements.nodes.*;
@@ -47,7 +48,7 @@
     public Node canonical(CanonicalizerTool tool) {
         ValueNode javaClass = getJavaClass();
         if (javaClass.isConstant()) {
-            Class c = (Class) javaClass.asConstant().asObject();
+            Class c = (Class) HotSpotObjectConstant.asObject(javaClass.asConstant());
             if (c != null) {
                 return ConstantNode.forBoolean(c.isPrimitive(), graph());
             }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/phases/AheadOfTimeVerificationPhase.java	Mon Apr 07 23:35:41 2014 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/phases/AheadOfTimeVerificationPhase.java	Mon Apr 07 16:09:17 2014 -0700
@@ -25,6 +25,7 @@
 import static com.oracle.graal.nodes.ConstantNode.*;
 
 import com.oracle.graal.api.meta.*;
+import com.oracle.graal.hotspot.meta.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.phases.*;
 import com.oracle.graal.phases.tiers.*;
@@ -57,7 +58,7 @@
     }
 
     private static boolean isNullReference(ConstantNode node) {
-        return isObject(node) && node.asConstant().asObject() == null;
+        return isObject(node) && node.asConstant().isNull();
     }
 
     @SuppressFBWarnings(value = "ES_COMPARING_STRINGS_WITH_EQ", justification = "reference equality is what we want")
@@ -66,7 +67,7 @@
             return false;
         }
 
-        Object o = node.asConstant().asObject();
+        Object o = HotSpotObjectConstant.asObject(node.asConstant());
         if (!(o instanceof String)) {
             return false;
         }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/phases/LoadJavaMirrorWithKlassPhase.java	Mon Apr 07 23:35:41 2014 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/phases/LoadJavaMirrorWithKlassPhase.java	Mon Apr 07 16:09:17 2014 -0700
@@ -54,9 +54,9 @@
     }
 
     private FloatingReadNode getClassConstantReplacement(StructuredGraph graph, PhaseContext context, Constant constant) {
-        if (constant.getKind() == Kind.Object && constant.asObject() instanceof Class<?>) {
+        if (constant.getKind() == Kind.Object && HotSpotObjectConstant.asObject(constant) instanceof Class<?>) {
             MetaAccessProvider metaAccess = context.getMetaAccess();
-            ResolvedJavaType type = metaAccess.lookupJavaType((Class<?>) constant.asObject());
+            ResolvedJavaType type = metaAccess.lookupJavaType((Class<?>) HotSpotObjectConstant.asObject(constant));
             assert type instanceof HotSpotResolvedObjectType;
 
             Constant klass = ((HotSpotResolvedObjectType) type).klass();
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/AbstractMethodHandleNode.java	Mon Apr 07 23:35:41 2014 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/AbstractMethodHandleNode.java	Mon Apr 07 16:09:17 2014 -0700
@@ -162,7 +162,7 @@
         Constant vmtarget = memberNameVmtargetField.readValue(memberName);
 
         // Create a method from the vmtarget pointer
-        Class<?> c = (Class<?>) clazz.asObject();
+        Class<?> c = (Class<?>) HotSpotObjectConstant.asObject(clazz);
         HotSpotResolvedObjectType holderClass = (HotSpotResolvedObjectType) HotSpotResolvedObjectType.fromClass(c);
         HotSpotResolvedJavaMethod targetMethod = HotSpotResolvedJavaMethod.fromMetaspace(vmtarget.asLong());
 
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/CallSiteTargetNode.java	Mon Apr 07 23:35:41 2014 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/CallSiteTargetNode.java	Mon Apr 07 16:09:17 2014 -0700
@@ -28,6 +28,7 @@
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.graph.spi.*;
+import com.oracle.graal.hotspot.meta.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.replacements.nodes.*;
@@ -44,7 +45,7 @@
 
     private ConstantNode getConstantCallTarget(MetaAccessProvider metaAccess, Assumptions assumptions) {
         if (getCallSite().isConstant() && !getCallSite().isNullConstant()) {
-            CallSite callSite = (CallSite) getCallSite().asConstant().asObject();
+            CallSite callSite = (CallSite) HotSpotObjectConstant.asObject(getCallSite().asConstant());
             MethodHandle target = callSite.getTarget();
             if (!(callSite instanceof ConstantCallSite)) {
                 if (assumptions == null || !assumptions.useOptimisticAssumptions()) {
@@ -52,7 +53,7 @@
                 }
                 assumptions.record(new Assumptions.CallSiteTargetValue(callSite, target));
             }
-            return ConstantNode.forObject(target, metaAccess, graph());
+            return ConstantNode.forConstant(HotSpotObjectConstant.forObject(target), metaAccess, graph());
         }
         return null;
     }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/CheckCastDynamicSnippets.java	Mon Apr 07 23:35:41 2014 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/CheckCastDynamicSnippets.java	Mon Apr 07 16:09:17 2014 -0700
@@ -32,13 +32,13 @@
 
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.debug.*;
+import com.oracle.graal.hotspot.meta.*;
 import com.oracle.graal.hotspot.nodes.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.extended.*;
 import com.oracle.graal.nodes.java.*;
 import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.nodes.type.*;
-import com.oracle.graal.phases.util.*;
 import com.oracle.graal.replacements.*;
 import com.oracle.graal.replacements.SnippetTemplate.AbstractTemplates;
 import com.oracle.graal.replacements.SnippetTemplate.Arguments;
@@ -69,8 +69,8 @@
 
         private final SnippetInfo dynamic = snippet(CheckCastDynamicSnippets.class, "checkcastDynamic");
 
-        public Templates(Providers providers, TargetDescription target) {
-            super(providers, target);
+        public Templates(HotSpotProviders providers, TargetDescription target) {
+            super(providers, providers.getSnippetReflection(), target);
         }
 
         public void lower(CheckCastDynamicNode checkcast, LoweringTool tool) {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/CompositeValueClassSubstitutions.java	Mon Apr 07 16:09:17 2014 -0700
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.hotspot.replacements;
+
+import static com.oracle.graal.phases.GraalOptions.*;
+
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.api.replacements.*;
+import com.oracle.graal.hotspot.meta.*;
+import com.oracle.graal.lir.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.spi.*;
+import com.oracle.graal.replacements.nodes.*;
+
+/**
+ * Substitutions for improving the performance of {@link CompositeValueClass#getClass()}.
+ */
+@ClassSubstitution(CompositeValueClass.class)
+public class CompositeValueClassSubstitutions {
+
+    /**
+     * A macro node for calls to {@link CompositeValueClass#get(Class)}. It can use the compiler's
+     * knowledge about node classes to replace itself with a constant value for a constant
+     * {@link Class} parameter.
+     */
+    public static class CompositeValueClassGetNode extends PureFunctionMacroNode {
+
+        public CompositeValueClassGetNode(Invoke invoke) {
+            super(invoke);
+        }
+
+        @SuppressWarnings("unchecked")
+        @Override
+        protected Constant evaluate(Constant param, MetaAccessProvider metaAccess) {
+            if (param.isNull() || ImmutableCode.getValue()) {
+                return null;
+            }
+            return HotSpotObjectConstant.forObject(CompositeValueClass.get((Class<? extends CompositeValue>) HotSpotObjectConstant.asObject(param)));
+        }
+    }
+
+    @MacroSubstitution(isStatic = true, forced = true, macro = CompositeValueClassGetNode.class)
+    private static native CompositeValueClass get(Class<?> c);
+}
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/HotSpotSubstitutions.java	Mon Apr 07 23:35:41 2014 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/HotSpotSubstitutions.java	Mon Apr 07 16:09:17 2014 -0700
@@ -42,5 +42,7 @@
         replacements.registerSubstitutions(CipherBlockChainingSubstitutions.class);
         replacements.registerSubstitutions(CRC32Substitutions.class);
         replacements.registerSubstitutions(ReflectionSubstitutions.class);
+        replacements.registerSubstitutions(NodeClassSubstitutions.class);
+        replacements.registerSubstitutions(CompositeValueClassSubstitutions.class);
     }
 }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/InstanceOfSnippets.java	Mon Apr 07 23:35:41 2014 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/InstanceOfSnippets.java	Mon Apr 07 16:09:17 2014 -0700
@@ -42,7 +42,6 @@
 import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.nodes.type.*;
 import com.oracle.graal.options.*;
-import com.oracle.graal.phases.util.*;
 import com.oracle.graal.replacements.*;
 import com.oracle.graal.replacements.Snippet.ConstantParameter;
 import com.oracle.graal.replacements.Snippet.VarargsParameter;
@@ -216,8 +215,8 @@
         private final SnippetInfo instanceofSecondary = snippet(InstanceOfSnippets.class, "instanceofSecondary");
         private final SnippetInfo instanceofDynamic = snippet(InstanceOfSnippets.class, "instanceofDynamic");
 
-        public Templates(Providers providers, TargetDescription target) {
-            super(providers, target);
+        public Templates(HotSpotProviders providers, TargetDescription target) {
+            super(providers, providers.getSnippetReflection(), target);
         }
 
         @Override
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/LoadExceptionObjectSnippets.java	Mon Apr 07 23:35:41 2014 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/LoadExceptionObjectSnippets.java	Mon Apr 07 16:09:17 2014 -0700
@@ -66,7 +66,7 @@
         private final SnippetInfo loadException = snippet(LoadExceptionObjectSnippets.class, "loadException");
 
         public Templates(HotSpotProviders providers, TargetDescription target) {
-            super(providers, target);
+            super(providers, providers.getSnippetReflection(), target);
         }
 
         public void lower(LoadExceptionObjectNode loadExceptionObject, HotSpotRegistersProvider registers, LoweringTool tool) {
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/MonitorSnippets.java	Mon Apr 07 23:35:41 2014 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/MonitorSnippets.java	Mon Apr 07 16:09:17 2014 -0700
@@ -48,7 +48,6 @@
 import com.oracle.graal.nodes.type.*;
 import com.oracle.graal.options.*;
 import com.oracle.graal.phases.common.*;
-import com.oracle.graal.phases.util.*;
 import com.oracle.graal.replacements.*;
 import com.oracle.graal.replacements.Snippet.ConstantParameter;
 import com.oracle.graal.replacements.Snippet.Fold;
@@ -417,8 +416,8 @@
 
         private final boolean useFastLocking;
 
-        public Templates(Providers providers, TargetDescription target, boolean useFastLocking) {
-            super(providers, target);
+        public Templates(HotSpotProviders providers, TargetDescription target, boolean useFastLocking) {
+            super(providers, providers.getSnippetReflection(), target);
             this.useFastLocking = useFastLocking;
         }
 
@@ -508,7 +507,7 @@
                     for (ReturnNode ret : rets) {
                         returnType = checkCounter.getMethod().getSignature().getReturnType(checkCounter.getMethod().getDeclaringClass());
                         String msg = "unbalanced monitors in " + MetaUtil.format("%H.%n(%p)", graph.method()) + ", count = %d";
-                        ConstantNode errMsg = ConstantNode.forObject(msg, providers.getMetaAccess(), graph);
+                        ConstantNode errMsg = ConstantNode.forConstant(HotSpotObjectConstant.forObject(msg), providers.getMetaAccess(), graph);
                         callTarget = graph.add(new MethodCallTargetNode(InvokeKind.Static, checkCounter.getMethod(), new ValueNode[]{errMsg}, returnType));
                         invoke = graph.add(new InvokeNode(callTarget, 0));
                         List<ValueNode> stack = Collections.emptyList();
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/NewObjectSnippets.java	Mon Apr 07 23:35:41 2014 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/NewObjectSnippets.java	Mon Apr 07 16:09:17 2014 -0700
@@ -48,7 +48,6 @@
 import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.nodes.type.*;
 import com.oracle.graal.options.*;
-import com.oracle.graal.phases.util.*;
 import com.oracle.graal.replacements.*;
 import com.oracle.graal.replacements.Snippet.ConstantParameter;
 import com.oracle.graal.replacements.Snippet.Fold;
@@ -382,8 +381,8 @@
         private final SnippetInfo allocateInstanceDynamic = snippet(NewObjectSnippets.class, "allocateInstanceDynamic");
         private final SnippetInfo newmultiarray = snippet(NewObjectSnippets.class, "newmultiarray");
 
-        public Templates(Providers providers, TargetDescription target) {
-            super(providers, target);
+        public Templates(HotSpotProviders providers, TargetDescription target) {
+            super(providers, providers.getSnippetReflection(), target);
         }
 
         /**
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/NodeClassSubstitutions.java	Mon Apr 07 16:09:17 2014 -0700
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.hotspot.replacements;
+
+import static com.oracle.graal.phases.GraalOptions.*;
+
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.api.replacements.*;
+import com.oracle.graal.graph.*;
+import com.oracle.graal.hotspot.meta.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.spi.*;
+import com.oracle.graal.replacements.nodes.*;
+
+/**
+ * Substitutions for improving the performance of some critical methods in {@link NodeClass}
+ * methods.
+ */
+@ClassSubstitution(NodeClass.class)
+public class NodeClassSubstitutions {
+
+    /**
+     * A macro node for calls to {@link NodeClass#get(Class)}. It can use the compiler's knowledge
+     * about node classes to replace itself with a constant value for a constant {@link Class}
+     * parameter.
+     */
+    public static class NodeClassGetNode extends PureFunctionMacroNode {
+
+        public NodeClassGetNode(Invoke invoke) {
+            super(invoke);
+        }
+
+        @Override
+        protected Constant evaluate(Constant param, MetaAccessProvider metaAccess) {
+            if (param.isNull() || ImmutableCode.getValue()) {
+                return null;
+            }
+            return HotSpotObjectConstant.forObject(NodeClass.get((Class<?>) HotSpotObjectConstant.asObject(param)));
+        }
+    }
+
+    @MacroSubstitution(isStatic = true, forced = true, macro = NodeClassGetNode.class)
+    private static native NodeClass get(Class<?> c);
+}
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ReflectionGetCallerClassNode.java	Mon Apr 07 23:35:41 2014 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ReflectionGetCallerClassNode.java	Mon Apr 07 16:09:17 2014 -0700
@@ -93,7 +93,7 @@
                     if (!method.ignoredBySecurityStackWalk()) {
                         // We have reached the desired frame; return the holder class.
                         HotSpotResolvedObjectType callerClass = method.getDeclaringClass();
-                        return ConstantNode.forObject(callerClass.mirror(), metaAccess, graph());
+                        return ConstantNode.forConstant(HotSpotObjectConstant.forObject(callerClass.mirror()), metaAccess, graph());
                     }
                     break;
             }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/SystemIdentityHashCodeNode.java	Mon Apr 07 23:35:41 2014 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/SystemIdentityHashCodeNode.java	Mon Apr 07 16:09:17 2014 -0700
@@ -25,6 +25,7 @@
 import static com.oracle.graal.phases.GraalOptions.*;
 
 import com.oracle.graal.api.meta.*;
+import com.oracle.graal.hotspot.meta.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.replacements.nodes.*;
 
@@ -36,6 +37,6 @@
 
     @Override
     protected Constant evaluate(Constant param, MetaAccessProvider metaAccess) {
-        return ImmutableCode.getValue() || param.isNull() ? null : Constant.forInt(System.identityHashCode(param.asObject()));
+        return ImmutableCode.getValue() || param.isNull() ? null : Constant.forInt(System.identityHashCode(HotSpotObjectConstant.asObject(param)));
     }
 }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/UnsafeArrayCopySnippets.java	Mon Apr 07 23:35:41 2014 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/UnsafeArrayCopySnippets.java	Mon Apr 07 16:09:17 2014 -0700
@@ -31,10 +31,10 @@
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.asm.*;
+import com.oracle.graal.hotspot.meta.*;
 import com.oracle.graal.hotspot.phases.*;
 import com.oracle.graal.nodes.extended.*;
 import com.oracle.graal.nodes.spi.*;
-import com.oracle.graal.phases.util.*;
 import com.oracle.graal.replacements.*;
 import com.oracle.graal.replacements.Snippet.Fold;
 import com.oracle.graal.replacements.SnippetTemplate.AbstractTemplates;
@@ -249,8 +249,8 @@
         private final SnippetInfo[] arraycopySnippets;
         private final SnippetInfo genericPrimitiveSnippet;
 
-        public Templates(Providers providers, TargetDescription target) {
-            super(providers, target);
+        public Templates(HotSpotProviders providers, TargetDescription target) {
+            super(providers, providers.getSnippetReflection(), target);
 
             arraycopySnippets = new SnippetInfo[Kind.values().length];
             arraycopySnippets[Kind.Boolean.ordinal()] = snippet(UnsafeArrayCopySnippets.class, "arraycopyBoolean");
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/UnsafeLoadSnippets.java	Mon Apr 07 23:35:41 2014 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/UnsafeLoadSnippets.java	Mon Apr 07 16:09:17 2014 -0700
@@ -26,10 +26,10 @@
 import static com.oracle.graal.replacements.SnippetTemplate.*;
 
 import com.oracle.graal.api.code.*;
+import com.oracle.graal.hotspot.meta.*;
 import com.oracle.graal.nodes.HeapAccess.BarrierType;
 import com.oracle.graal.nodes.extended.*;
 import com.oracle.graal.nodes.spi.*;
-import com.oracle.graal.phases.util.*;
 import com.oracle.graal.replacements.*;
 import com.oracle.graal.replacements.SnippetTemplate.AbstractTemplates;
 import com.oracle.graal.replacements.SnippetTemplate.Arguments;
@@ -52,8 +52,8 @@
 
         private final SnippetInfo unsafeLoad = snippet(UnsafeLoadSnippets.class, "lowerUnsafeLoad");
 
-        public Templates(Providers providers, TargetDescription target) {
-            super(providers, target);
+        public Templates(HotSpotProviders providers, TargetDescription target) {
+            super(providers, providers.getSnippetReflection(), target);
         }
 
         public void lower(UnsafeLoadNode load, LoweringTool tool) {
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/WriteBarrierSnippets.java	Mon Apr 07 23:35:41 2014 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/WriteBarrierSnippets.java	Mon Apr 07 16:09:17 2014 -0700
@@ -40,7 +40,6 @@
 import com.oracle.graal.nodes.extended.*;
 import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.phases.*;
-import com.oracle.graal.phases.util.*;
 import com.oracle.graal.replacements.*;
 import com.oracle.graal.replacements.Snippet.ConstantParameter;
 import com.oracle.graal.replacements.SnippetTemplate.AbstractTemplates;
@@ -334,8 +333,8 @@
 
         private final CompressEncoding oopEncoding;
 
-        public Templates(Providers providers, TargetDescription target, CompressEncoding oopEncoding) {
-            super(providers, target);
+        public Templates(HotSpotProviders providers, TargetDescription target, CompressEncoding oopEncoding) {
+            super(providers, providers.getSnippetReflection(), target);
             this.oopEncoding = oopEncoding;
         }
 
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/ForeignCallStub.java	Mon Apr 07 23:35:41 2014 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/ForeignCallStub.java	Mon Apr 07 16:09:17 2014 -0700
@@ -203,8 +203,8 @@
             Debug.dump(graph, "Initial stub graph");
         }
 
-        kit.rewriteWordTypes();
-        kit.inlineInvokes();
+        kit.rewriteWordTypes(providers.getSnippetReflection());
+        kit.inlineInvokes(providers.getSnippetReflection());
 
         if (Debug.isDumpEnabled()) {
             Debug.dump(graph, "Stub graph before compilation");
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/NewArrayStub.java	Mon Apr 07 23:35:41 2014 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/NewArrayStub.java	Mon Apr 07 16:09:17 2014 -0700
@@ -65,7 +65,7 @@
         // convert the hub (i.e., Klass*) for int[] to be a naked word. This should be safe since
         // the int[] class will never be unloaded.
         Constant intArrayHub = intArrayType.klass();
-        intArrayHub = Constant.forIntegerKind(runtime().getTarget().wordKind, intArrayHub.asLong(), null);
+        intArrayHub = Constant.forIntegerKind(runtime().getTarget().wordKind, intArrayHub.asLong());
 
         Arguments args = new Arguments(stub, GuardsStage.FLOATING_GUARDS, LoweringTool.StandardLoweringStage.HIGH_TIER);
         args.add("hub", null);
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/NewInstanceStub.java	Mon Apr 07 23:35:41 2014 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/NewInstanceStub.java	Mon Apr 07 16:09:17 2014 -0700
@@ -65,7 +65,7 @@
         // convert the hub (i.e., Klass*) for int[] to be a naked word. This should be safe since
         // the int[] class will never be unloaded.
         Constant intArrayHub = intArrayType.klass();
-        intArrayHub = Constant.forIntegerKind(runtime().getTarget().wordKind, intArrayHub.asLong(), null);
+        intArrayHub = Constant.forIntegerKind(runtime().getTarget().wordKind, intArrayHub.asLong());
 
         Arguments args = new Arguments(stub, GuardsStage.FLOATING_GUARDS, LoweringTool.StandardLoweringStage.HIGH_TIER);
         args.add("hub", null);
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/SnippetStub.java	Mon Apr 07 23:35:41 2014 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/SnippetStub.java	Mon Apr 07 16:09:17 2014 -0700
@@ -32,7 +32,6 @@
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.StructuredGraph.GuardsStage;
 import com.oracle.graal.nodes.spi.*;
-import com.oracle.graal.phases.util.*;
 import com.oracle.graal.replacements.*;
 import com.oracle.graal.replacements.SnippetTemplate.AbstractTemplates;
 import com.oracle.graal.replacements.SnippetTemplate.Arguments;
@@ -45,8 +44,8 @@
 
     static class Template extends AbstractTemplates {
 
-        Template(Providers providers, TargetDescription target, Class<? extends Snippets> declaringClass) {
-            super(providers, target);
+        Template(HotSpotProviders providers, TargetDescription target, Class<? extends Snippets> declaringClass) {
+            super(providers, providers.getSnippetReflection(), target);
             this.info = snippet(declaringClass, null);
         }
 
@@ -65,7 +64,7 @@
 
     /**
      * Creates a new snippet stub.
-     * 
+     *
      * @param linkage linkage details for a call to the stub
      */
     public SnippetStub(HotSpotProviders providers, TargetDescription target, HotSpotForeignCallLinkage linkage) {
--- a/graal/com.oracle.graal.java.decompiler/src/com/oracle/graal/java/decompiler/lines/DecompilerSyntaxLine.java	Mon Apr 07 23:35:41 2014 +0200
+++ b/graal/com.oracle.graal.java.decompiler/src/com/oracle/graal/java/decompiler/lines/DecompilerSyntaxLine.java	Mon Apr 07 16:09:17 2014 -0700
@@ -48,7 +48,7 @@
 
     protected static String getStringRepresentation(Node node) {
         if (node instanceof ConstantNode) {
-            return String.valueOf(((ConstantNode) node).asConstant().asBoxedValue());
+            return ((ConstantNode) node).asConstant().toValueString();
         } else if (node instanceof ParameterNode) {
             return "param_" + ((ParameterNode) node).index();
         } else {
--- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/AbstractBytecodeParser.java	Mon Apr 07 23:35:41 2014 +0200
+++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/AbstractBytecodeParser.java	Mon Apr 07 16:09:17 2014 -0700
@@ -712,13 +712,6 @@
 
     protected abstract void emitNullCheck(T receiver);
 
-    protected static final ArrayIndexOutOfBoundsException cachedArrayIndexOutOfBoundsException = new ArrayIndexOutOfBoundsException();
-    protected static final NullPointerException cachedNullPointerException = new NullPointerException();
-    static {
-        cachedArrayIndexOutOfBoundsException.setStackTrace(new StackTraceElement[0]);
-        cachedNullPointerException.setStackTrace(new StackTraceElement[0]);
-    }
-
     protected abstract void emitBoundsCheck(T index, T length);
 
     private static final DebugMetric EXPLICIT_EXCEPTIONS = Debug.metric("ExplicitExceptions");
--- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/BytecodeDisassembler.java	Mon Apr 07 23:35:41 2014 +0200
+++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/BytecodeDisassembler.java	Mon Apr 07 16:09:17 2014 -0700
@@ -117,26 +117,7 @@
                         String desc = null;
                         if (constant instanceof Constant) {
                             Constant c = ((Constant) constant);
-                            switch (c.getKind()) {
-                                case Int :
-                                    desc = String.valueOf(c.asInt());
-                                    break;
-                                case Float:
-                                    desc = String.valueOf(c.asFloat());
-                                    break;
-                                case Object:
-                                    desc = Kind.Object.format(c.asObject());
-                                    break;
-                                case Double :
-                                    desc = String.valueOf(c.asDouble());
-                                    break;
-                                case Long :
-                                    desc = String.valueOf(c.asLong());
-                                    break;
-                                default:
-                                    desc = c.toString();
-                                    break;
-                            }
+                            desc = c.toValueString();
                         } else {
                             desc = constant.toString();
                         }
--- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java	Mon Apr 07 23:35:41 2014 +0200
+++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java	Mon Apr 07 16:09:17 2014 -0700
@@ -25,7 +25,6 @@
 import static com.oracle.graal.api.meta.DeoptimizationAction.*;
 import static com.oracle.graal.api.meta.DeoptimizationReason.*;
 import static com.oracle.graal.bytecode.Bytecodes.*;
-import static com.oracle.graal.java.GraphBuilderPhase.RuntimeCalls.*;
 import static com.oracle.graal.phases.GraalOptions.*;
 import static java.lang.reflect.Modifier.*;
 
@@ -59,12 +58,6 @@
  */
 public class GraphBuilderPhase extends BasePhase<HighTierContext> {
 
-    public static final class RuntimeCalls {
-
-        public static final ForeignCallDescriptor CREATE_NULL_POINTER_EXCEPTION = new ForeignCallDescriptor("createNullPointerException", NullPointerException.class);
-        public static final ForeignCallDescriptor CREATE_OUT_OF_BOUNDS_EXCEPTION = new ForeignCallDescriptor("createOutOfBoundsException", ArrayIndexOutOfBoundsException.class, int.class);
-    }
-
     private final GraphBuilderConfiguration graphBuilderConfig;
 
     public GraphBuilderPhase(GraphBuilderConfiguration graphBuilderConfig) {
@@ -650,16 +643,10 @@
                 append(new IfNode(currentGraph.unique(new IsNullNode(receiver)), trueSucc, falseSucc, 0.01));
                 lastInstr = falseSucc;
 
-                if (OmitHotExceptionStacktrace.getValue()) {
-                    ValueNode exception = ConstantNode.forObject(cachedNullPointerException, metaAccess, currentGraph);
-                    trueSucc.setNext(handleException(exception, bci()));
-                } else {
-                    DeferredForeignCallNode call = currentGraph.add(new DeferredForeignCallNode(CREATE_NULL_POINTER_EXCEPTION));
-                    call.setStamp(StampFactory.exactNonNull(metaAccess.lookupJavaType(CREATE_NULL_POINTER_EXCEPTION.getResultType())));
-                    call.setStateAfter(frameState.create(bci()));
-                    trueSucc.setNext(call);
-                    call.setNext(handleException(call, bci()));
-                }
+                BytecodeExceptionNode exception = currentGraph.add(new BytecodeExceptionNode(metaAccess, NullPointerException.class));
+                exception.setStateAfter(frameState.create(bci()));
+                trueSucc.setNext(exception);
+                exception.setNext(handleException(exception, bci()));
             }
 
             @Override
@@ -669,16 +656,10 @@
                 append(new IfNode(currentGraph.unique(new IntegerBelowThanNode(index, length)), trueSucc, falseSucc, 0.99));
                 lastInstr = trueSucc;
 
-                if (OmitHotExceptionStacktrace.getValue()) {
-                    ValueNode exception = ConstantNode.forObject(cachedArrayIndexOutOfBoundsException, metaAccess, currentGraph);
-                    falseSucc.setNext(handleException(exception, bci()));
-                } else {
-                    DeferredForeignCallNode call = currentGraph.add(new DeferredForeignCallNode(CREATE_OUT_OF_BOUNDS_EXCEPTION, index));
-                    call.setStamp(StampFactory.exactNonNull(metaAccess.lookupJavaType(CREATE_OUT_OF_BOUNDS_EXCEPTION.getResultType())));
-                    call.setStateAfter(frameState.create(bci()));
-                    falseSucc.setNext(call);
-                    call.setNext(handleException(call, bci()));
-                }
+                BytecodeExceptionNode exception = currentGraph.add(new BytecodeExceptionNode(metaAccess, ArrayIndexOutOfBoundsException.class, index));
+                exception.setStateAfter(frameState.create(bci()));
+                falseSucc.setNext(exception);
+                exception.setNext(handleException(exception, bci()));
             }
 
             @Override
@@ -720,9 +701,9 @@
             @Override
             protected void genInvokeDynamic(JavaMethod target) {
                 if (target instanceof ResolvedJavaMethod) {
-                    Object appendix = constantPool.lookupAppendix(stream.readCPI4(), Bytecodes.INVOKEDYNAMIC);
+                    Constant appendix = constantPool.lookupAppendix(stream.readCPI4(), Bytecodes.INVOKEDYNAMIC);
                     if (appendix != null) {
-                        frameState.apush(ConstantNode.forObject(appendix, metaAccess, currentGraph));
+                        frameState.apush(ConstantNode.forConstant(appendix, metaAccess, currentGraph));
                     }
                     ValueNode[] args = frameState.popArguments(target.getSignature().getParameterSlots(false), target.getSignature().getParameterCount(false));
                     appendInvoke(InvokeKind.Static, (ResolvedJavaMethod) target, args);
@@ -742,9 +723,9 @@
                      * +and+invokedynamic
                      */
                     boolean hasReceiver = !isStatic(((ResolvedJavaMethod) target).getModifiers());
-                    Object appendix = constantPool.lookupAppendix(stream.readCPI(), Bytecodes.INVOKEVIRTUAL);
+                    Constant appendix = constantPool.lookupAppendix(stream.readCPI(), Bytecodes.INVOKEVIRTUAL);
                     if (appendix != null) {
-                        frameState.apush(ConstantNode.forObject(appendix, metaAccess, currentGraph));
+                        frameState.apush(ConstantNode.forConstant(appendix, metaAccess, currentGraph));
                     }
                     ValueNode[] args = frameState.popArguments(target.getSignature().getParameterSlots(hasReceiver), target.getSignature().getParameterCount(hasReceiver));
                     if (hasReceiver) {
--- a/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/JTTTest.java	Mon Apr 07 23:35:41 2014 +0200
+++ b/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/JTTTest.java	Mon Apr 07 16:09:17 2014 -0700
@@ -64,7 +64,7 @@
             assert parameterTypes.length == args.length;
             for (int i = 0; i < args.length; i++) {
                 ParameterNode param = graph.getParameter(i);
-                Constant c = Constant.forBoxed(parameterTypes[i].getKind(), args[i]);
+                Constant c = getSnippetReflection().forBoxed(parameterTypes[i].getKind(), args[i]);
                 ConstantNode replacement = ConstantNode.forConstant(c, getMetaAccess(), graph);
                 param.replaceAtUsages(replacement);
             }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ConstantNode.java	Mon Apr 07 23:35:41 2014 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ConstantNode.java	Mon Apr 07 16:09:17 2014 -0700
@@ -262,18 +262,6 @@
         return unique(graph, createPrimitive(Constant.forInt(i)));
     }
 
-    /**
-     * Returns a node for an object constant.
-     *
-     * @param o the object value for which to create the instruction
-     * @return a node representing the object
-     */
-    public static ConstantNode forObject(Object o, MetaAccessProvider metaAccess, StructuredGraph graph) {
-        assert !(o instanceof Constant) : "wrapping a Constant into a Constant";
-        Constant constant = Constant.forObject(o);
-        return unique(graph, new ConstantNode(constant, StampFactory.forConstant(constant, metaAccess)));
-    }
-
     private static ConstantNode unique(StructuredGraph graph, ConstantNode node) {
         return graph.unique(node);
     }
@@ -351,7 +339,7 @@
             case Long:
                 return ConstantNode.forLong(0L, graph);
             case Object:
-                return ConstantNode.forObject(null, null, graph);
+                return ConstantNode.forConstant(Constant.NULL_OBJECT, null, graph);
             default:
                 return null;
         }
@@ -360,14 +348,14 @@
     @Override
     public Map<Object, Object> getDebugProperties(Map<Object, Object> map) {
         Map<Object, Object> properties = super.getDebugProperties(map);
-        properties.put("rawvalue", value.getKind() == Kind.Object ? value.getKind().format(value.asBoxedValue()) : value.asBoxedValue());
+        properties.put("rawvalue", value.toValueString());
         return properties;
     }
 
     @Override
     public String toString(Verbosity verbosity) {
         if (verbosity == Verbosity.Name) {
-            return super.toString(Verbosity.Name) + "(" + value.getKind().format(value.asBoxedValue()) + ")";
+            return super.toString(Verbosity.Name) + "(" + value.toValueString() + ")";
         } else {
             return super.toString(verbosity);
         }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ObjectEqualsNode.java	Mon Apr 07 23:35:41 2014 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ObjectEqualsNode.java	Mon Apr 07 16:09:17 2014 -0700
@@ -75,9 +75,9 @@
     private void virtualizeNonVirtualComparison(State state, ValueNode other, VirtualizerTool tool) {
         if (!state.getVirtualObject().hasIdentity() && state.getVirtualObject().entryKind(0) == Kind.Boolean) {
             if (other.isConstant()) {
-                Object otherValue = other.asConstant().asObject();
-                if (otherValue == Boolean.TRUE || otherValue == Boolean.FALSE) {
-                    int expectedValue = (otherValue == Boolean.TRUE) ? 1 : 0;
+                Constant otherUnboxed = tool.getConstantReflectionProvider().unboxPrimitive(other.asConstant());
+                if (otherUnboxed != null && otherUnboxed.getKind() == Kind.Boolean) {
+                    int expectedValue = otherUnboxed.asBoolean() ? 1 : 0;
                     IntegerEqualsNode equals = new IntegerEqualsNode(state.getEntry(0), ConstantNode.forInt(expectedValue, graph()));
                     tool.addNode(equals);
                     tool.replaceWithValue(equals);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/BytecodeExceptionNode.java	Mon Apr 07 16:09:17 2014 -0700
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.nodes.extended;
+
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.graph.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.spi.*;
+import com.oracle.graal.nodes.type.*;
+
+/**
+ * A node that represents an exception thrown implicitly by a Java bytecode. It can be lowered to
+ * either a {@linkplain ForeignCallDescriptor foreign} call or a pre-allocated exception object.
+ */
+public class BytecodeExceptionNode extends AbstractMemoryCheckpoint implements Lowerable, MemoryCheckpoint.Single {
+
+    private final Class<? extends Throwable> exceptionClass;
+    @Input private final NodeInputList<ValueNode> arguments;
+    @Input private FrameState deoptState;
+
+    public BytecodeExceptionNode(MetaAccessProvider metaAccess, Class<? extends Throwable> exceptionClass, ValueNode... arguments) {
+        super(StampFactory.exactNonNull(metaAccess.lookupJavaType(exceptionClass)));
+        this.exceptionClass = exceptionClass;
+        this.arguments = new NodeInputList<>(this, arguments);
+    }
+
+    public Class<? extends Throwable> getExceptionClass() {
+        return exceptionClass;
+    }
+
+    @Override
+    public String toString(Verbosity verbosity) {
+        if (verbosity == Verbosity.Name) {
+            return super.toString(verbosity) + "#" + exceptionClass.getSimpleName();
+        }
+        return super.toString(verbosity);
+    }
+
+    public LocationIdentity getLocationIdentity() {
+        return LocationIdentity.ANY_LOCATION;
+    }
+
+    public void lower(LoweringTool tool) {
+        tool.getLowerer().lower(this, tool);
+    }
+
+    public NodeInputList<ValueNode> getArguments() {
+        return arguments;
+    }
+}
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/DeferredForeignCallNode.java	Mon Apr 07 23:35:41 2014 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,71 +0,0 @@
-/*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.graal.nodes.extended;
-
-import com.oracle.graal.api.meta.*;
-import com.oracle.graal.graph.*;
-import com.oracle.graal.nodes.*;
-import com.oracle.graal.nodes.spi.*;
-import com.oracle.graal.nodes.type.*;
-
-/**
- * A node that will be lowered to a {@linkplain ForeignCallDescriptor foreign} call.
- */
-@NodeInfo(nameTemplate = "DeferredForeignCall#{p#descriptor/s}")
-public class DeferredForeignCallNode extends AbstractMemoryCheckpoint implements Lowerable, MemoryCheckpoint.Single {
-
-    @Input private final NodeInputList<ValueNode> arguments;
-    @Input(InputType.State) private FrameState deoptState;
-
-    private final ForeignCallDescriptor descriptor;
-
-    public DeferredForeignCallNode(ForeignCallDescriptor descriptor, ValueNode... arguments) {
-        super(StampFactory.forKind(Kind.fromJavaClass(descriptor.getResultType())));
-        this.arguments = new NodeInputList<>(this, arguments);
-        this.descriptor = descriptor;
-    }
-
-    public ForeignCallDescriptor getDescriptor() {
-        return descriptor;
-    }
-
-    @Override
-    public String toString(Verbosity verbosity) {
-        if (verbosity == Verbosity.Name) {
-            return super.toString(verbosity) + "#" + descriptor;
-        }
-        return super.toString(verbosity);
-    }
-
-    public LocationIdentity getLocationIdentity() {
-        return LocationIdentity.ANY_LOCATION;
-    }
-
-    public void lower(LoweringTool tool) {
-        tool.getLowerer().lower(this, tool);
-    }
-
-    public NodeInputList<ValueNode> getArguments() {
-        return arguments;
-    }
-}
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ReadNode.java	Mon Apr 07 23:35:41 2014 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ReadNode.java	Mon Apr 07 16:09:17 2014 -0700
@@ -95,21 +95,11 @@
                                 location instanceof ConstantLocationNode) {
                     long displacement = ((ConstantLocationNode) location).getDisplacement();
                     Kind kind = location.getValueKind();
-                    if (object.getKind() == Kind.Object) {
-                        Object base = object.asConstant().asObject();
-                        if (base != null) {
-                            Constant constant = tool.getConstantReflection().readUnsafeConstant(kind, base, displacement, compressible);
-                            if (constant != null) {
-                                return ConstantNode.forConstant(constant, metaAccess, read.graph());
-                            }
-                        }
-                    } else if (object.getKind().isNumericInteger()) {
-                        long base = object.asConstant().asLong();
-                        if (base != 0L) {
-                            Constant constant = tool.getConstantReflection().readUnsafeConstant(kind, null, base + displacement, compressible);
-                            if (constant != null) {
-                                return ConstantNode.forConstant(constant, metaAccess, read.graph());
-                            }
+                    Constant base = object.asConstant();
+                    if (base != null) {
+                        Constant constant = tool.getConstantReflection().readUnsafeConstant(kind, base, displacement, compressible);
+                        if (constant != null) {
+                            return ConstantNode.forConstant(constant, metaAccess, read.graph());
                         }
                     }
                 }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/SnippetLocationNode.java	Mon Apr 07 23:35:41 2014 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,112 +0,0 @@
-/*
- * Copyright (c) 2013, 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.graal.nodes.extended;
-
-import static com.oracle.graal.api.meta.LocationIdentity.*;
-
-import com.oracle.graal.api.meta.*;
-import com.oracle.graal.graph.*;
-import com.oracle.graal.graph.spi.*;
-import com.oracle.graal.nodes.*;
-import com.oracle.graal.nodes.spi.*;
-import com.oracle.graal.nodes.type.*;
-
-/**
- * Location node that can be used inside a snippet without having the elements (including the
- * location identity and kind) as a snippet constant. Can represent locations in the form of [base +
- * index * scale + disp]. When the location is created, all elements (base, index, scale, disp) are
- * nodes. Both scale and disp must eventually canonicalize to {@link ConstantNode constants} so that
- * this node can be canonicalized to a {@link IndexedLocationNode} or {@link ConstantLocationNode}.
- */
-public final class SnippetLocationNode extends LocationNode implements Canonicalizable {
-
-    @Input private ValueNode valueKind;
-    @Input(InputType.Association) private ValueNode locationIdentity;
-    @Input private ValueNode displacement;
-    @Input private ValueNode index;
-    @Input private ValueNode indexScaling;
-
-    public static SnippetLocationNode create(ValueNode identity, ValueNode kind, ValueNode displacement, ValueNode index, ValueNode indexScaling, Graph graph) {
-        return graph.unique(new SnippetLocationNode(identity, kind, displacement, index, indexScaling));
-    }
-
-    private SnippetLocationNode(ValueNode locationIdentity, ValueNode kind, ValueNode displacement) {
-        this(locationIdentity, kind, displacement, null, null);
-    }
-
-    private SnippetLocationNode(ValueNode locationIdentity, ValueNode kind, ValueNode displacement, ValueNode index, ValueNode indexScaling) {
-        super(StampFactory.object());
-        this.valueKind = kind;
-        this.locationIdentity = locationIdentity;
-        this.displacement = displacement;
-        this.index = index;
-        this.indexScaling = indexScaling;
-    }
-
-    @Override
-    public Kind getValueKind() {
-        if (valueKind.isConstant()) {
-            return (Kind) valueKind.asConstant().asObject();
-        }
-        throw new GraalInternalError("Cannot access kind yet because it is not constant: " + valueKind);
-    }
-
-    @Override
-    public LocationIdentity getLocationIdentity() {
-        if (locationIdentity.isConstant()) {
-            return (LocationIdentity) locationIdentity.asConstant().asObject();
-        }
-        // We do not know our actual location identity yet, so be conservative.
-        return ANY_LOCATION;
-    }
-
-    @Override
-    public Node canonical(CanonicalizerTool tool) {
-        if (valueKind.isConstant() && locationIdentity.isConstant() && displacement.isConstant() && (indexScaling == null || indexScaling.isConstant())) {
-            Kind constKind = (Kind) valueKind.asConstant().asObject();
-            LocationIdentity constLocation = (LocationIdentity) locationIdentity.asConstant().asObject();
-            long constDisplacement = displacement.asConstant().asLong();
-            int constIndexScaling = indexScaling == null ? 0 : indexScaling.asConstant().asInt();
-
-            if (index == null || constIndexScaling == 0) {
-                return ConstantLocationNode.create(constLocation, constKind, constDisplacement, graph());
-            } else if (index.isConstant()) {
-                return ConstantLocationNode.create(constLocation, constKind, index.asConstant().asLong() * constIndexScaling + constDisplacement, graph());
-            } else {
-                return IndexedLocationNode.create(constLocation, constKind, constDisplacement, index, graph(), constIndexScaling);
-            }
-        }
-        return this;
-    }
-
-    @Override
-    public Value generateAddress(NodeLIRBuilderTool gen, Value base) {
-        throw new GraalInternalError("locationIdentity must be a constant so that this node can be canonicalized: " + locationIdentity);
-    }
-
-    @NodeIntrinsic
-    public static native Location constantLocation(LocationIdentity identity, Kind kind, long displacement);
-
-    @NodeIntrinsic
-    public static native Location indexedLocation(LocationIdentity identity, Kind kind, long displacement, int index, int indexScaling);
-}
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnboxNode.java	Mon Apr 07 23:35:41 2014 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnboxNode.java	Mon Apr 07 16:09:17 2014 -0700
@@ -70,28 +70,9 @@
     public Node canonical(CanonicalizerTool tool) {
         if (value.isConstant()) {
             Constant constant = value.asConstant();
-            Object o = constant.asObject();
-            if (o != null) {
-                switch (boxingKind) {
-                    case Boolean:
-                        return ConstantNode.forBoolean((Boolean) o, graph());
-                    case Byte:
-                        return ConstantNode.forByte((Byte) o, graph());
-                    case Char:
-                        return ConstantNode.forChar((Character) o, graph());
-                    case Short:
-                        return ConstantNode.forShort((Short) o, graph());
-                    case Int:
-                        return ConstantNode.forInt((Integer) o, graph());
-                    case Long:
-                        return ConstantNode.forLong((Long) o, graph());
-                    case Float:
-                        return ConstantNode.forFloat((Float) o, graph());
-                    case Double:
-                        return ConstantNode.forDouble((Double) o, graph());
-                    default:
-                        ValueNodeUtil.shouldNotReachHere();
-                }
+            Constant unboxed = tool.getConstantReflection().unboxPrimitive(constant);
+            if (unboxed != null && unboxed.getKind() == boxingKind) {
+                return ConstantNode.forConstant(unboxed, tool.getMetaAccess(), graph());
             }
         } else if (value instanceof BoxNode) {
             BoxNode box = (BoxNode) value;
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/ArrayLengthNode.java	Mon Apr 07 23:35:41 2014 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/ArrayLengthNode.java	Mon Apr 07 16:09:17 2014 -0700
@@ -72,7 +72,7 @@
         if (constantReflection != null && array.isConstant() && !array.isNullConstant()) {
             Constant constantValue = array.asConstant();
             if (constantValue != null && constantValue.isNonNull()) {
-                Integer constantLength = constantReflection.lookupArrayLength(constantValue);
+                Integer constantLength = constantReflection.readArrayLength(constantValue);
                 if (constantLength != null) {
                     return ConstantNode.forInt(constantLength, graph);
                 }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/CheckCastDynamicNode.java	Mon Apr 07 23:35:41 2014 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/CheckCastDynamicNode.java	Mon Apr 07 16:09:17 2014 -0700
@@ -76,10 +76,11 @@
         if (ObjectStamp.isObjectAlwaysNull(object())) {
             return object();
         }
-        if (hub.isConstant() && hub.asConstant().getKind() == Kind.Object && hub.asConstant().asObject() instanceof Class) {
-            Class clazz = (Class) hub.asConstant().asObject();
-            ResolvedJavaType t = tool.getMetaAccess().lookupJavaType(clazz);
-            return graph().add(new CheckCastNode(t, object(), null, forStoreCheck));
+        if (hub.isConstant()) {
+            ResolvedJavaType t = tool.getConstantReflection().asJavaType(hub.asConstant());
+            if (t != null) {
+                return graph().add(new CheckCastNode(t, object(), null, forStoreCheck));
+            }
         }
         return this;
     }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/DynamicNewArrayNode.java	Mon Apr 07 23:35:41 2014 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/DynamicNewArrayNode.java	Mon Apr 07 16:09:17 2014 -0700
@@ -55,9 +55,8 @@
     @Override
     public void simplify(SimplifierTool tool) {
         if (isAlive() && elementType.isConstant()) {
-            Class<?> elementClass = (Class<?>) elementType.asConstant().asObject();
-            if (elementClass != null && !(elementClass.equals(void.class))) {
-                ResolvedJavaType javaType = tool.getMetaAccess().lookupJavaType(elementClass);
+            ResolvedJavaType javaType = tool.getConstantReflection().asJavaType(elementType.asConstant());
+            if (javaType != null && !javaType.equals(tool.getMetaAccess().lookupJavaType(void.class))) {
                 NewArrayNode newArray = graph().add(new NewArrayNode(javaType, length(), fillContents()));
                 List<Node> snapshot = inputs().snapshot();
                 graph().replaceFixedWithFixed(this, newArray);
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/DynamicNewInstanceNode.java	Mon Apr 07 23:35:41 2014 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/DynamicNewInstanceNode.java	Mon Apr 07 16:09:17 2014 -0700
@@ -40,13 +40,9 @@
     @Override
     public Node canonical(CanonicalizerTool tool) {
         if (clazz.isConstant()) {
-            Constant clazzConstant = clazz.asConstant();
-            if (clazzConstant.getKind() == Kind.Object && clazzConstant.asObject() instanceof Class) {
-                Class staticClass = (Class) clazzConstant.asObject();
-                ResolvedJavaType type = tool.getMetaAccess().lookupJavaType(staticClass);
-                if (type.isInitialized()) {
-                    return graph().add(new NewInstanceNode(type, fillContents()));
-                }
+            ResolvedJavaType type = tool.getConstantReflection().asJavaType(clazz.asConstant());
+            if (type != null && type.isInitialized()) {
+                return graph().add(new NewInstanceNode(type, fillContents()));
             }
         }
         return this;
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/InstanceOfDynamicNode.java	Mon Apr 07 23:35:41 2014 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/InstanceOfDynamicNode.java	Mon Apr 07 16:09:17 2014 -0700
@@ -60,12 +60,13 @@
     public Node canonical(CanonicalizerTool tool) {
         assert object() != null : this;
         if (mirror().isConstant()) {
-            Class clazz = (Class) mirror().asConstant().asObject();
-            ResolvedJavaType t = tool.getMetaAccess().lookupJavaType(clazz);
-            if (t.isPrimitive()) {
-                return LogicConstantNode.contradiction(graph());
-            } else {
-                return graph().unique(new InstanceOfNode(t, object(), null));
+            ResolvedJavaType t = tool.getConstantReflection().asJavaType(mirror().asConstant());
+            if (t != null) {
+                if (t.isPrimitive()) {
+                    return LogicConstantNode.contradiction(graph());
+                } else {
+                    return graph().unique(new InstanceOfNode(t, object(), null));
+                }
             }
         }
         return this;
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/VirtualizerTool.java	Mon Apr 07 23:35:41 2014 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/VirtualizerTool.java	Mon Apr 07 16:09:17 2014 -0700
@@ -41,12 +41,17 @@
 public interface VirtualizerTool {
 
     /**
-     * @return the {@link MetaAccessProvider} associated with the current compilation, which might
-     *         be required for creating constants, etc.
+     * @return the {@link MetaAccessProvider} associated with the current compilation.
      */
     MetaAccessProvider getMetaAccessProvider();
 
     /**
+     * @return the {@link ConstantReflectionProvider} associated with the current compilation, which
+     *         can be used to access {@link Constant}s.
+     */
+    ConstantReflectionProvider getConstantReflectionProvider();
+
+    /**
      * @return the {@link Assumptions} associated with the current compilation, which can be used to
      *         make type assumptions during virtualization.
      */
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ConditionalEliminationPhase.java	Mon Apr 07 23:35:41 2014 +0200
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ConditionalEliminationPhase.java	Mon Apr 07 16:09:17 2014 -0700
@@ -710,7 +710,7 @@
                     replacementAnchor = BeginNode.prevBegin(checkCast);
                     PiNode piNode;
                     if (isNull) {
-                        ConstantNode nullObject = ConstantNode.forObject(null, metaAccess, graph);
+                        ConstantNode nullObject = ConstantNode.defaultForKind(Kind.Object, graph);
                         piNode = graph.unique(new PiNode(nullObject, StampFactory.forConstant(nullObject.getValue(), metaAccess), replacementAnchor.asNode()));
                     } else {
                         piNode = graph.unique(new PiNode(object, StampFactory.declared(type, nonNull), replacementAnchor.asNode()));
--- a/graal/com.oracle.graal.replacements.amd64/src/com/oracle/graal/replacements/amd64/AMD64ConvertSnippets.java	Mon Apr 07 23:35:41 2014 +0200
+++ b/graal/com.oracle.graal.replacements.amd64/src/com/oracle/graal/replacements/amd64/AMD64ConvertSnippets.java	Mon Apr 07 16:09:17 2014 -0700
@@ -26,6 +26,7 @@
 import static com.oracle.graal.replacements.SnippetTemplate.*;
 
 import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.replacements.*;
 import com.oracle.graal.debug.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.calc.*;
@@ -49,7 +50,7 @@
      * conversion. If the float value is a NaN, infinity or if the result of the conversion is
      * larger than {@link Integer#MAX_VALUE} then CVTTSS2SI returns {@link Integer#MIN_VALUE} and
      * extra tests are required on the float value to return the correct int value.
-     * 
+     *
      * @param input the float being converted
      * @param result the result produced by the CVTTSS2SI instruction
      */
@@ -74,7 +75,7 @@
      * conversion. If the float value is a NaN or infinity then CVTTSS2SI returns
      * {@link Long#MIN_VALUE} and extra tests are required on the float value to return the correct
      * long value.
-     * 
+     *
      * @param input the float being converted
      * @param result the result produced by the CVTTSS2SI instruction
      */
@@ -99,7 +100,7 @@
      * conversion. If the double value is a NaN, infinity or if the result of the conversion is
      * larger than {@link Integer#MAX_VALUE} then CVTTSD2SI returns {@link Integer#MIN_VALUE} and
      * extra tests are required on the double value to return the correct int value.
-     * 
+     *
      * @param input the double being converted
      * @param result the result produced by the CVTTSS2SI instruction
      */
@@ -124,7 +125,7 @@
      * conversion. If the double value is a NaN, infinity or if the result of the conversion is
      * larger than {@link Long#MAX_VALUE} then CVTTSD2SI returns {@link Long#MIN_VALUE} and extra
      * tests are required on the double value to return the correct long value.
-     * 
+     *
      * @param input the double being converted
      * @param result the result produced by the CVTTSS2SI instruction
      */
@@ -149,8 +150,8 @@
         private final SnippetInfo d2i;
         private final SnippetInfo d2l;
 
-        public Templates(Providers providers, TargetDescription target) {
-            super(providers, target);
+        public Templates(Providers providers, SnippetReflectionProvider snippetReflection, TargetDescription target) {
+            super(providers, snippetReflection, target);
 
             f2i = snippet(AMD64ConvertSnippets.class, "f2i");
             f2l = snippet(AMD64ConvertSnippets.class, "f2l");
--- a/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/ObjectAccessTest.java	Mon Apr 07 23:35:41 2014 +0200
+++ b/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/ObjectAccessTest.java	Mon Apr 07 16:09:17 2014 -0700
@@ -47,7 +47,7 @@
     private final ReplacementsImpl installer;
 
     public ObjectAccessTest() {
-        installer = new ReplacementsImpl(getProviders(), new Assumptions(false), getTarget());
+        installer = new ReplacementsImpl(getProviders(), getSnippetReflection(), new Assumptions(false), getTarget());
     }
 
     private static final ThreadLocal<SnippetInliningPolicy> inliningPolicy = new ThreadLocal<>();
--- a/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/PointerTest.java	Mon Apr 07 23:35:41 2014 +0200
+++ b/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/PointerTest.java	Mon Apr 07 16:09:17 2014 -0700
@@ -53,7 +53,7 @@
 
     public PointerTest() {
         target = getCodeCache().getTarget();
-        installer = new ReplacementsImpl(getProviders(), new Assumptions(false), getTarget());
+        installer = new ReplacementsImpl(getProviders(), getSnippetReflection(), new Assumptions(false), getTarget());
     }
 
     private static final ThreadLocal<SnippetInliningPolicy> inliningPolicy = new ThreadLocal<>();
--- a/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/WordTest.java	Mon Apr 07 23:35:41 2014 +0200
+++ b/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/WordTest.java	Mon Apr 07 16:09:17 2014 -0700
@@ -42,7 +42,7 @@
     private final ReplacementsImpl installer;
 
     public WordTest() {
-        installer = new ReplacementsImpl(getProviders(), new Assumptions(false), getTarget());
+        installer = new ReplacementsImpl(getProviders(), getSnippetReflection(), new Assumptions(false), getTarget());
     }
 
     private static final ThreadLocal<SnippetInliningPolicy> inliningPolicy = new ThreadLocal<>();
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/BoxingSnippets.java	Mon Apr 07 23:35:41 2014 +0200
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/BoxingSnippets.java	Mon Apr 07 16:09:17 2014 -0700
@@ -30,6 +30,7 @@
 
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
+import com.oracle.graal.api.replacements.*;
 import com.oracle.graal.debug.*;
 import com.oracle.graal.graph.Node.NodeIntrinsic;
 import com.oracle.graal.nodes.*;
@@ -173,30 +174,13 @@
         return value.shortValue();
     }
 
-    public static FloatingNode canonicalizeBoxing(BoxNode box, MetaAccessProvider metaAccess) {
+    public static FloatingNode canonicalizeBoxing(BoxNode box, MetaAccessProvider metaAccess, ConstantReflectionProvider constantReflection) {
         ValueNode value = box.getValue();
         if (value.isConstant()) {
             Constant sourceConstant = value.asConstant();
-            switch (box.getBoxingKind()) {
-                case Boolean:
-                    return ConstantNode.forObject(Boolean.valueOf(sourceConstant.asInt() != 0), metaAccess, box.graph());
-                case Byte:
-                    return ConstantNode.forObject(Byte.valueOf((byte) sourceConstant.asInt()), metaAccess, box.graph());
-                case Char:
-                    return ConstantNode.forObject(Character.valueOf((char) sourceConstant.asInt()), metaAccess, box.graph());
-                case Short:
-                    return ConstantNode.forObject(Short.valueOf((short) sourceConstant.asInt()), metaAccess, box.graph());
-                case Int:
-                    return ConstantNode.forObject(Integer.valueOf(sourceConstant.asInt()), metaAccess, box.graph());
-                case Long:
-                    return ConstantNode.forObject(Long.valueOf(sourceConstant.asLong()), metaAccess, box.graph());
-                case Float:
-                    return ConstantNode.forObject(Float.valueOf(sourceConstant.asFloat()), metaAccess, box.graph());
-                case Double:
-                    return ConstantNode.forObject(Double.valueOf(sourceConstant.asDouble()), metaAccess, box.graph());
-                default:
-                    assert false : "Unexpected source kind for boxing";
-                    break;
+            Constant boxedConstant = constantReflection.boxPrimitive(sourceConstant);
+            if (boxedConstant != null && boxedConstant.getKind() == box.getBoxingKind()) {
+                return ConstantNode.forConstant(boxedConstant, metaAccess, box.graph());
             }
         }
         return null;
@@ -207,8 +191,8 @@
         private final EnumMap<Kind, SnippetInfo> boxSnippets = new EnumMap<>(Kind.class);
         private final EnumMap<Kind, SnippetInfo> unboxSnippets = new EnumMap<>(Kind.class);
 
-        public Templates(Providers providers, TargetDescription target) {
-            super(providers, target);
+        public Templates(Providers providers, SnippetReflectionProvider snippetReflection, TargetDescription target) {
+            super(providers, snippetReflection, target);
             for (Kind kind : new Kind[]{Kind.Boolean, Kind.Byte, Kind.Char, Kind.Double, Kind.Float, Kind.Int, Kind.Long, Kind.Short}) {
                 boxSnippets.put(kind, snippet(BoxingSnippets.class, kind.getJavaName() + "ValueOf"));
                 unboxSnippets.put(kind, snippet(BoxingSnippets.class, kind.getJavaName() + "Value"));
@@ -216,7 +200,7 @@
         }
 
         public void lower(BoxNode box, LoweringTool tool) {
-            FloatingNode canonical = canonicalizeBoxing(box, providers.getMetaAccess());
+            FloatingNode canonical = canonicalizeBoxing(box, providers.getMetaAccess(), providers.getConstantReflection());
             // if in AOT mode, we don't want to embed boxed constants.
             if (canonical != null && !ImmutableCode.getValue()) {
                 box.graph().replaceFloating(box, canonical);
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/CompositeValueClassSubstitutions.java	Mon Apr 07 23:35:41 2014 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,63 +0,0 @@
-/*
- * Copyright (c) 2011, 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.replacements;
-
-import static com.oracle.graal.phases.GraalOptions.*;
-
-import com.oracle.graal.api.meta.*;
-import com.oracle.graal.api.replacements.*;
-import com.oracle.graal.lir.*;
-import com.oracle.graal.nodes.*;
-import com.oracle.graal.nodes.spi.*;
-import com.oracle.graal.replacements.nodes.*;
-
-/**
- * Substitutions for improving the performance of {@link CompositeValueClass#getClass()}.
- */
-@ClassSubstitution(CompositeValueClass.class)
-public class CompositeValueClassSubstitutions {
-
-    /**
-     * A macro node for calls to {@link CompositeValueClass#get(Class)}. It can use the compiler's
-     * knowledge about node classes to replace itself with a constant value for a constant
-     * {@link Class} parameter.
-     */
-    public static class CompositeValueClassGetNode extends PureFunctionMacroNode {
-
-        public CompositeValueClassGetNode(Invoke invoke) {
-            super(invoke);
-        }
-
-        @SuppressWarnings("unchecked")
-        @Override
-        protected Constant evaluate(Constant param, MetaAccessProvider metaAccess) {
-            if (param.isNull() || ImmutableCode.getValue()) {
-                return null;
-            }
-            return Constant.forObject(CompositeValueClass.get((Class<? extends CompositeValue>) param.asObject()));
-        }
-    }
-
-    @MacroSubstitution(isStatic = true, forced = true, macro = CompositeValueClassGetNode.class)
-    private static native CompositeValueClass get(Class<?> c);
-}
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/GraalMethodSubstitutions.java	Mon Apr 07 23:35:41 2014 +0200
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/GraalMethodSubstitutions.java	Mon Apr 07 16:09:17 2014 -0700
@@ -50,8 +50,6 @@
             replacements.registerSubstitutions(CharacterSubstitutions.class);
             replacements.registerSubstitutions(ShortSubstitutions.class);
             replacements.registerSubstitutions(UnsignedMathSubstitutions.class);
-            replacements.registerSubstitutions(NodeClassSubstitutions.class);
-            replacements.registerSubstitutions(CompositeValueClassSubstitutions.class);
         }
     }
 }
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/GraphKit.java	Mon Apr 07 23:35:41 2014 +0200
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/GraphKit.java	Mon Apr 07 16:09:17 2014 -0700
@@ -27,6 +27,7 @@
 
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
+import com.oracle.graal.api.replacements.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.java.*;
 import com.oracle.graal.nodes.*;
@@ -179,16 +180,16 @@
     /**
      * Rewrite all word types in the graph.
      */
-    public void rewriteWordTypes() {
-        new WordTypeRewriterPhase(providers.getMetaAccess(), providers.getCodeCache().getTarget().wordKind).apply(graph);
+    public void rewriteWordTypes(SnippetReflectionProvider snippetReflection) {
+        new WordTypeRewriterPhase(providers.getMetaAccess(), snippetReflection, providers.getCodeCache().getTarget().wordKind).apply(graph);
     }
 
     /**
-     * {@linkplain #inline(InvokeNode) Inlines} all invocations currently in the graph.
+     * {@linkplain #inline Inlines} all invocations currently in the graph.
      */
-    public void inlineInvokes() {
+    public void inlineInvokes(SnippetReflectionProvider snippetReflection) {
         for (InvokeNode invoke : graph.getNodes().filter(InvokeNode.class).snapshot()) {
-            inline(invoke);
+            inline(invoke, snippetReflection);
         }
 
         // Clean up all code that is now dead after inlining.
@@ -201,9 +202,9 @@
      * {@linkplain ReplacementsImpl#makeGraph processed} in the same manner as for snippets and
      * method substitutions.
      */
-    public void inline(InvokeNode invoke) {
+    public void inline(InvokeNode invoke, SnippetReflectionProvider snippetReflection) {
         ResolvedJavaMethod method = ((MethodCallTargetNode) invoke.callTarget()).targetMethod();
-        ReplacementsImpl repl = new ReplacementsImpl(providers, new Assumptions(false), providers.getCodeCache().getTarget());
+        ReplacementsImpl repl = new ReplacementsImpl(providers, snippetReflection, new Assumptions(false), providers.getCodeCache().getTarget());
         StructuredGraph calleeGraph = repl.makeGraph(method, null, method, null, FrameStateProcessing.CollapseFrameForSingleSideEffect);
         InliningUtil.inline(invoke, calleeGraph, false);
     }
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/InstanceOfSnippetsTemplates.java	Mon Apr 07 23:35:41 2014 +0200
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/InstanceOfSnippetsTemplates.java	Mon Apr 07 16:09:17 2014 -0700
@@ -27,6 +27,7 @@
 import java.util.*;
 
 import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.replacements.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.calc.*;
@@ -53,8 +54,8 @@
  */
 public abstract class InstanceOfSnippetsTemplates extends AbstractTemplates {
 
-    public InstanceOfSnippetsTemplates(Providers providers, TargetDescription target) {
-        super(providers, target);
+    public InstanceOfSnippetsTemplates(Providers providers, SnippetReflectionProvider snippetReflection, TargetDescription target) {
+        super(providers, snippetReflection, target);
     }
 
     /**
@@ -130,7 +131,7 @@
 
         /**
          * Gets the result of this instantiation as a condition.
-         * 
+         *
          * @param testValue the returned condition is true if the result is equal to this value
          */
         LogicNode asCondition(ValueNode testValue) {
@@ -148,7 +149,7 @@
 
         /**
          * Gets the result of the instantiation as a materialized value.
-         * 
+         *
          * @param t the true value for the materialization
          * @param f the false value for the materialization
          */
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/NodeClassSubstitutions.java	Mon Apr 07 23:35:41 2014 +0200
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/NodeClassSubstitutions.java	Mon Apr 07 16:09:17 2014 -0700
@@ -22,15 +22,11 @@
  */
 package com.oracle.graal.replacements;
 
-import static com.oracle.graal.phases.GraalOptions.*;
-
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.api.replacements.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.extended.*;
-import com.oracle.graal.nodes.spi.*;
-import com.oracle.graal.replacements.nodes.*;
 
 /**
  * Substitutions for improving the performance of some critical methods in {@link NodeClass}
@@ -42,26 +38,6 @@
 @ClassSubstitution(NodeClass.class)
 public class NodeClassSubstitutions {
 
-    /**
-     * A macro node for calls to {@link NodeClass#get(Class)}. It can use the compiler's knowledge
-     * about node classes to replace itself with a constant value for a constant {@link Class}
-     * parameter.
-     */
-    public static class NodeClassGetNode extends PureFunctionMacroNode {
-
-        public NodeClassGetNode(Invoke invoke) {
-            super(invoke);
-        }
-
-        @Override
-        protected Constant evaluate(Constant param, MetaAccessProvider metaAccess) {
-            return param.isNull() || ImmutableCode.getValue() ? null : Constant.forObject(NodeClass.get((Class<?>) param.asObject()));
-        }
-    }
-
-    @MacroSubstitution(isStatic = true, forced = true, macro = NodeClassGetNode.class)
-    private static native NodeClass get(Class<?> c);
-
     @MethodSubstitution
     private static Node getNode(Node node, long offset) {
         return PiNode.piCast(UnsafeLoadNode.load(node, offset, Kind.Object, LocationIdentity.ANY_LOCATION), Node.class);
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/NodeIntrinsificationPhase.java	Mon Apr 07 23:35:41 2014 +0200
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/NodeIntrinsificationPhase.java	Mon Apr 07 16:09:17 2014 -0700
@@ -29,6 +29,7 @@
 
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
+import com.oracle.graal.api.replacements.*;
 import com.oracle.graal.debug.*;
 import com.oracle.graal.debug.internal.*;
 import com.oracle.graal.graph.*;
@@ -52,9 +53,11 @@
 public class NodeIntrinsificationPhase extends Phase {
 
     private final Providers providers;
+    private final SnippetReflectionProvider snippetReflection;
 
-    public NodeIntrinsificationPhase(Providers providers) {
+    public NodeIntrinsificationPhase(Providers providers, SnippetReflectionProvider snippetReflection) {
         this.providers = providers;
+        this.snippetReflection = snippetReflection;
     }
 
     @Override
@@ -167,25 +170,25 @@
                 }
                 ConstantNode constantNode = (ConstantNode) argument;
                 Constant constant = constantNode.asConstant();
-                Object o = constant.asBoxedValue();
-                if (o instanceof Class<?>) {
-                    reflectionCallArguments[i] = Constant.forObject(providers.getMetaAccess().lookupJavaType((Class<?>) o));
+                ResolvedJavaType type = providers.getConstantReflection().asJavaType(constant);
+                if (type != null) {
+                    reflectionCallArguments[i] = snippetReflection.forObject(type);
                     parameterTypes[i] = providers.getMetaAccess().lookupJavaType(ResolvedJavaType.class);
                 } else {
                     if (parameterTypes[i].getKind() == Kind.Boolean) {
-                        reflectionCallArguments[i] = Constant.forObject(Boolean.valueOf(constant.asInt() != 0));
+                        reflectionCallArguments[i] = snippetReflection.forObject(Boolean.valueOf(constant.asInt() != 0));
                     } else if (parameterTypes[i].getKind() == Kind.Byte) {
-                        reflectionCallArguments[i] = Constant.forObject(Byte.valueOf((byte) constant.asInt()));
+                        reflectionCallArguments[i] = snippetReflection.forObject(Byte.valueOf((byte) constant.asInt()));
                     } else if (parameterTypes[i].getKind() == Kind.Short) {
-                        reflectionCallArguments[i] = Constant.forObject(Short.valueOf((short) constant.asInt()));
+                        reflectionCallArguments[i] = snippetReflection.forObject(Short.valueOf((short) constant.asInt()));
                     } else if (parameterTypes[i].getKind() == Kind.Char) {
-                        reflectionCallArguments[i] = Constant.forObject(Character.valueOf((char) constant.asInt()));
+                        reflectionCallArguments[i] = snippetReflection.forObject(Character.valueOf((char) constant.asInt()));
                     } else {
                         reflectionCallArguments[i] = constant;
                     }
                 }
             } else {
-                reflectionCallArguments[i] = Constant.forObject(argument);
+                reflectionCallArguments[i] = snippetReflection.forObject(argument);
                 parameterTypes[i] = providers.getMetaAccess().lookupJavaType(ValueNode.class);
             }
         }
@@ -226,7 +229,7 @@
         }
 
         try {
-            ValueNode intrinsicNode = (ValueNode) constructor.newInstance(arguments).asObject();
+            ValueNode intrinsicNode = (ValueNode) snippetReflection.asObject(constructor.newInstance(arguments));
 
             if (setStampFromReturnType) {
                 intrinsicNode.setStamp(invokeStamp);
@@ -267,11 +270,13 @@
             if (getParameterAnnotation(InjectedNodeParameter.class, i, c) != null) {
                 injected = injected == null ? new Constant[1] : Arrays.copyOf(injected, injected.length + 1);
                 if (signature[i].equals(metaAccess.lookupJavaType(MetaAccessProvider.class))) {
-                    injected[injected.length - 1] = Constant.forObject(metaAccess);
+                    injected[injected.length - 1] = snippetReflection.forObject(metaAccess);
                 } else if (signature[i].equals(metaAccess.lookupJavaType(StructuredGraph.class))) {
-                    injected[injected.length - 1] = Constant.forObject(graph);
+                    injected[injected.length - 1] = snippetReflection.forObject(graph);
                 } else if (signature[i].equals(metaAccess.lookupJavaType(ForeignCallsProvider.class))) {
-                    injected[injected.length - 1] = Constant.forObject(providers.getForeignCalls());
+                    injected[injected.length - 1] = snippetReflection.forObject(providers.getForeignCalls());
+                } else if (signature[i].equals(metaAccess.lookupJavaType(SnippetReflectionProvider.class))) {
+                    injected[injected.length - 1] = snippetReflection.forObject(snippetReflection);
                 } else {
                     throw new GraalInternalError("Cannot handle injected argument of type %s in %s", toJavaName(signature[i]), format("%H.%n(%p)", c));
                 }
@@ -311,9 +316,9 @@
             arguments = Arrays.copyOf(nodeConstructorArguments, fixedArgs + 1);
             arguments[fixedArgs] = componentType.newArray(nodeConstructorArguments.length - fixedArgs);
 
-            Object varargs = arguments[fixedArgs].asObject();
+            Object varargs = snippetReflection.asObject(arguments[fixedArgs]);
             for (int i = fixedArgs; i < nodeConstructorArguments.length; i++) {
-                Array.set(varargs, i - fixedArgs, nodeConstructorArguments[i].asBoxedValue());
+                Array.set(varargs, i - fixedArgs, snippetReflection.asBoxedValue(nodeConstructorArguments[i]));
             }
         } else {
             return null;
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/ReplacementsImpl.java	Mon Apr 07 23:35:41 2014 +0200
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/ReplacementsImpl.java	Mon Apr 07 16:09:17 2014 -0700
@@ -56,6 +56,7 @@
 public class ReplacementsImpl implements Replacements {
 
     protected final Providers providers;
+    protected final SnippetReflectionProvider snippetReflection;
     protected final TargetDescription target;
     protected final Assumptions assumptions;
 
@@ -71,8 +72,9 @@
     private final Set<ResolvedJavaMethod> forcedSubstitutions;
     private final Map<Class<? extends SnippetTemplateCache>, SnippetTemplateCache> snippetTemplateCache;
 
-    public ReplacementsImpl(Providers providers, Assumptions assumptions, TargetDescription target) {
+    public ReplacementsImpl(Providers providers, SnippetReflectionProvider snippetReflection, Assumptions assumptions, TargetDescription target) {
         this.providers = providers.copyWith(this);
+        this.snippetReflection = snippetReflection;
         this.target = target;
         this.assumptions = assumptions;
         this.graphs = new ConcurrentHashMap<>();
@@ -121,7 +123,7 @@
 
         // Do deferred intrinsification of node intrinsics
 
-        new NodeIntrinsificationPhase(providers).apply(specializedSnippet);
+        new NodeIntrinsificationPhase(providers, snippetReflection).apply(specializedSnippet);
         new CanonicalizerPhase(true).apply(specializedSnippet, new PhaseContext(providers, assumptions));
         NodeIntrinsificationVerificationPhase.verify(specializedSnippet);
     }
@@ -364,7 +366,7 @@
          * Does final processing of a snippet graph.
          */
         protected void finalizeGraph(StructuredGraph graph) {
-            new NodeIntrinsificationPhase(providers).apply(graph);
+            new NodeIntrinsificationPhase(providers, snippetReflection).apply(graph);
             if (!SnippetTemplate.hasConstantParameter(method)) {
                 NodeIntrinsificationVerificationPhase.verify(graph);
             }
@@ -412,8 +414,8 @@
             try (Scope s = Debug.scope("buildInitialGraph", graph)) {
                 MetaAccessProvider metaAccess = providers.getMetaAccess();
                 createGraphBuilder(metaAccess, GraphBuilderConfiguration.getSnippetDefault(), OptimisticOptimizations.NONE).apply(graph);
-                new WordTypeVerificationPhase(metaAccess, target.wordKind).apply(graph);
-                new WordTypeRewriterPhase(metaAccess, target.wordKind).apply(graph);
+                new WordTypeVerificationPhase(metaAccess, snippetReflection, target.wordKind).apply(graph);
+                new WordTypeRewriterPhase(metaAccess, snippetReflection, target.wordKind).apply(graph);
 
                 if (OptCanonicalizer.getValue()) {
                     new CanonicalizerPhase(true).apply(graph, new PhaseContext(providers, assumptions));
@@ -449,7 +451,7 @@
          * Called after all inlining for a given graph is complete.
          */
         protected void afterInlining(StructuredGraph graph) {
-            new NodeIntrinsificationPhase(providers).apply(graph);
+            new NodeIntrinsificationPhase(providers, snippetReflection).apply(graph);
             new DeadCodeEliminationPhase().apply(graph);
             if (OptCanonicalizer.getValue()) {
                 new CanonicalizerPhase(true).apply(graph, new PhaseContext(providers, assumptions));
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/SnippetTemplate.java	Mon Apr 07 23:35:41 2014 +0200
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/SnippetTemplate.java	Mon Apr 07 16:09:17 2014 -0700
@@ -399,11 +399,13 @@
     public abstract static class AbstractTemplates implements SnippetTemplateCache {
 
         protected final Providers providers;
+        protected final SnippetReflectionProvider snippetReflection;
         protected final TargetDescription target;
         private final ConcurrentHashMap<CacheKey, SnippetTemplate> templates;
 
-        protected AbstractTemplates(Providers providers, TargetDescription target) {
+        protected AbstractTemplates(Providers providers, SnippetReflectionProvider snippetReflection, TargetDescription target) {
             this.providers = providers;
+            this.snippetReflection = snippetReflection;
             this.target = target;
             if (UseSnippetTemplateCache) {
                 this.templates = new ConcurrentHashMap<>();
@@ -443,7 +445,7 @@
             if (template == null) {
                 SnippetTemplates.increment();
                 try (TimerCloseable a = SnippetTemplateCreationTime.start(); Scope s = Debug.scope("SnippetSpecialization", args.info.method)) {
-                    template = new SnippetTemplate(providers, args);
+                    template = new SnippetTemplate(providers, snippetReflection, args);
                     if (UseSnippetTemplateCache) {
                         templates.put(args.cacheKey, template);
                     }
@@ -470,10 +472,14 @@
         return false;
     }
 
+    private final SnippetReflectionProvider snippetReflection;
+
     /**
      * Creates a snippet template.
      */
-    protected SnippetTemplate(final Providers providers, Arguments args) {
+    protected SnippetTemplate(final Providers providers, SnippetReflectionProvider snippetReflection, Arguments args) {
+        this.snippetReflection = snippetReflection;
+
         StructuredGraph snippetGraph = providers.getReplacements().getSnippet(args.info.method);
         instantiationTimer = Debug.timer("SnippetTemplateInstantiationTime[%#s]", args);
         instantiationCounter = Debug.metric("SnippetTemplateInstantiationCount[%#s]", args);
@@ -502,7 +508,7 @@
                 if (arg instanceof Constant) {
                     constantArg = (Constant) arg;
                 } else {
-                    constantArg = Constant.forBoxed(kind, arg);
+                    constantArg = snippetReflection.forBoxed(kind, arg);
                 }
                 nodeReplacements.put(snippetGraph.getParameter(i), ConstantNode.forConstant(constantArg, metaAccess, snippetCopy));
             } else if (args.info.isVarargsParameter(i)) {
@@ -702,9 +708,7 @@
             assert arg instanceof Constant : method + ": word constant parameters must be passed boxed in a Constant value: " + arg;
             return true;
         }
-        if (kind == Kind.Object) {
-            assert arg == null || type.isInstance(Constant.forObject(arg)) : method + ": wrong value type for " + name + ": expected " + type.getName() + ", got " + arg.getClass().getName();
-        } else {
+        if (kind != Kind.Object) {
             assert arg != null && kind.toBoxedJavaClass() == arg.getClass() : method + ": wrong value kind for " + name + ": expected " + kind + ", got " +
                             (arg == null ? "null" : arg.getClass().getSimpleName());
         }
@@ -843,20 +847,10 @@
      */
     protected Constant forBoxed(Object argument, Kind localKind) {
         assert localKind == localKind.getStackKind();
-        if (localKind == Kind.Int && !(argument instanceof Integer)) {
-            if (argument instanceof Boolean) {
-                return Constant.forBoxed(Kind.Boolean, argument);
-            }
-            if (argument instanceof Byte) {
-                return Constant.forBoxed(Kind.Byte, argument);
-            }
-            if (argument instanceof Short) {
-                return Constant.forBoxed(Kind.Short, argument);
-            }
-            assert argument instanceof Character;
-            return Constant.forBoxed(Kind.Char, argument);
+        if (localKind == Kind.Int) {
+            return Constant.forBoxedPrimitive(argument);
         }
-        return Constant.forBoxed(localKind, argument);
+        return snippetReflection.forBoxed(localKind, argument);
     }
 
     /**
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.truffle.hotspot/src/com/oracle/graal/truffle/hotspot/HotSpotOptimizedCallTarget.java	Mon Apr 07 16:09:17 2014 -0700
@@ -0,0 +1,189 @@
+/*
+ * Copyright (c) 2013, 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.truffle.hotspot;
+
+import static com.oracle.graal.truffle.TruffleCompilerOptions.*;
+
+import java.util.concurrent.*;
+
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.hotspot.meta.*;
+import com.oracle.graal.truffle.*;
+import com.oracle.truffle.api.*;
+import com.oracle.truffle.api.nodes.*;
+
+/**
+ * Call target for running truffle on a standard VM (and not in SubstrateVM).
+ */
+public final class HotSpotOptimizedCallTarget extends OptimizedCallTarget {
+
+    protected final TruffleCompiler compiler;
+    private Future<InstalledCode> installedCodeTask;
+    private SpeculationLog speculationLog = new HotSpotSpeculationLog();
+
+    HotSpotOptimizedCallTarget(RootNode rootNode, TruffleCompiler compiler, int invokeCounter, int compilationThreshold, boolean compilationEnabled) {
+        super(rootNode, invokeCounter, compilationThreshold, compilationEnabled, TruffleUseTimeForCompilationDecision.getValue() ? new TimedCompilationPolicy() : new DefaultCompilationPolicy());
+        this.compiler = compiler;
+    }
+
+    @Override
+    public SpeculationLog getSpeculationLog() {
+        return speculationLog;
+    }
+
+    public boolean isOptimized() {
+        return installedCode != null || installedCodeTask != null;
+    }
+
+    @CompilerDirectives.SlowPath
+    @Override
+    public Object call(Object[] args) {
+        return CompilerDirectives.inInterpreter() ? callHelper(args) : executeHelper(args);
+    }
+
+    private Object callHelper(Object[] args) {
+        if (installedCode != null && installedCode.isValid()) {
+            reinstallCallMethodShortcut();
+        }
+        if (TruffleCallTargetProfiling.getValue()) {
+            callCount++;
+        }
+        if (CompilerDirectives.injectBranchProbability(CompilerDirectives.FASTPATH_PROBABILITY, installedCode != null)) {
+            try {
+                return installedCode.executeVarargs(new Object[]{this, args});
+            } catch (InvalidInstalledCodeException ex) {
+                return compiledCodeInvalidated(args);
+            }
+        } else {
+            return interpreterCall(args);
+        }
+    }
+
+    private static void reinstallCallMethodShortcut() {
+        if (TraceTruffleCompilation.getValue()) {
+            OUT.println("[truffle] reinstall OptimizedCallTarget.call code with frame prolog shortcut.");
+        }
+        HotSpotTruffleRuntime.installOptimizedCallTargetCallMethod();
+    }
+
+    private Object compiledCodeInvalidated(Object[] args) {
+        invalidate(null, null, "Compiled code invalidated");
+        return call(args);
+    }
+
+    @Override
+    protected void invalidate(Node oldNode, Node newNode, CharSequence reason) {
+        InstalledCode m = this.installedCode;
+        if (m != null) {
+            CompilerAsserts.neverPartOfCompilation();
+            installedCode = null;
+            inliningResult = null;
+            compilationProfile.reportInvalidated();
+            logOptimizedInvalidated(this, oldNode, newNode, reason);
+        }
+        cancelInstalledTask(oldNode, newNode, reason);
+    }
+
+    @Override
+    protected void cancelInstalledTask(Node oldNode, Node newNode, CharSequence reason) {
+        Future<InstalledCode> task = this.installedCodeTask;
+        if (task != null) {
+            task.cancel(true);
+            this.installedCodeTask = null;
+            logOptimizingUnqueued(this, oldNode, newNode, reason);
+            compilationProfile.reportInvalidated();
+        }
+    }
+
+    private Object interpreterCall(Object[] args) {
+        CompilerAsserts.neverPartOfCompilation();
+        compilationProfile.reportInterpreterCall();
+
+        if (compilationEnabled && compilationPolicy.shouldCompile(compilationProfile)) {
+            InstalledCode code = compile();
+            if (code != null && code.isValid()) {
+                this.installedCode = code;
+                try {
+                    return code.executeVarargs(new Object[]{this, args});
+                } catch (InvalidInstalledCodeException ex) {
+                    return compiledCodeInvalidated(args);
+                }
+            }
+        }
+        return executeHelper(args);
+    }
+
+    private boolean isCompiling() {
+        Future<InstalledCode> codeTask = this.installedCodeTask;
+        if (codeTask != null) {
+            if (codeTask.isCancelled()) {
+                installedCodeTask = null;
+                return false;
+            }
+            return true;
+        }
+        return false;
+    }
+
+    @Override
+    public InstalledCode compile() {
+        if (isCompiling()) {
+            if (installedCodeTask.isDone()) {
+                return receiveInstalledCode();
+            }
+            return null;
+        } else {
+            performInlining();
+            cancelInlinedCallOptimization();
+            logOptimizingQueued(this);
+            this.installedCodeTask = compiler.compile(this);
+            if (!TruffleBackgroundCompilation.getValue()) {
+                return receiveInstalledCode();
+            }
+            return null;
+        }
+    }
+
+    private InstalledCode receiveInstalledCode() {
+        try {
+            return installedCodeTask.get();
+        } catch (InterruptedException | ExecutionException e) {
+            compilationEnabled = false;
+            logOptimizingFailed(this, e.getMessage());
+            if (e.getCause() instanceof BailoutException) {
+                // Bailout => move on.
+            } else {
+                if (TraceTruffleCompilationExceptions.getValue()) {
+                    e.printStackTrace(OUT);
+                }
+                if (TruffleCompilationExceptionsAreFatal.getValue()) {
+                    System.exit(-1);
+                }
+            }
+            return null;
+        } finally {
+            onCompilationDone();
+        }
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.truffle.hotspot/src/com/oracle/graal/truffle/hotspot/HotSpotTruffleReplacements.java	Mon Apr 07 16:09:17 2014 -0700
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2013, 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.truffle.hotspot;
+
+import com.oracle.graal.api.replacements.*;
+import com.oracle.graal.api.runtime.*;
+import com.oracle.graal.nodes.spi.*;
+import com.oracle.graal.phases.util.*;
+import com.oracle.graal.runtime.*;
+import com.oracle.graal.truffle.*;
+import com.oracle.graal.truffle.hotspot.substitutions.*;
+
+public final class HotSpotTruffleReplacements extends TruffleReplacements {
+
+    private HotSpotTruffleReplacements(Providers providers, SnippetReflectionProvider snippetReflection) {
+        super(providers, snippetReflection);
+    }
+
+    public static Replacements makeInstance() {
+        Providers providers = Graal.getRequiredCapability(RuntimeProvider.class).getHostBackend().getProviders();
+        SnippetReflectionProvider snippetReflection = Graal.getRequiredCapability(SnippetReflectionProvider.class);
+        return new HotSpotTruffleReplacements(providers, snippetReflection);
+    }
+
+    @Override
+    protected void registerTruffleSubstitutions() {
+        super.registerTruffleSubstitutions();
+        registerSubstitutions(HotSpotOptimizedCallTargetSubstitutions.class);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.truffle.hotspot/src/com/oracle/graal/truffle/hotspot/HotSpotTruffleRuntime.java	Mon Apr 07 16:09:17 2014 -0700
@@ -0,0 +1,215 @@
+/*
+ * Copyright (c) 2013, 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.truffle.hotspot;
+
+import static com.oracle.graal.api.code.CodeUtil.*;
+import static com.oracle.graal.compiler.GraalCompiler.*;
+import static com.oracle.graal.truffle.TruffleCompilerOptions.*;
+
+import java.lang.reflect.*;
+import java.util.*;
+
+import com.oracle.graal.api.code.*;
+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.target.*;
+import com.oracle.graal.debug.*;
+import com.oracle.graal.debug.Debug.Scope;
+import com.oracle.graal.graph.*;
+import com.oracle.graal.java.*;
+import com.oracle.graal.lir.asm.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.spi.*;
+import com.oracle.graal.phases.*;
+import com.oracle.graal.phases.common.*;
+import com.oracle.graal.phases.tiers.*;
+import com.oracle.graal.phases.util.*;
+import com.oracle.graal.runtime.*;
+import com.oracle.graal.truffle.*;
+import com.oracle.truffle.api.*;
+import com.oracle.truffle.api.frame.*;
+import com.oracle.truffle.api.impl.*;
+import com.oracle.truffle.api.nodes.*;
+
+/**
+ * Implementation of the Truffle runtime when running on top of Graal.
+ */
+public final class HotSpotTruffleRuntime implements GraalTruffleRuntime {
+
+    public static HotSpotTruffleRuntime makeInstance() {
+        return new HotSpotTruffleRuntime();
+    }
+
+    private TruffleCompiler truffleCompiler;
+    private Replacements truffleReplacements;
+    private ArrayList<String> includes;
+    private ArrayList<String> excludes;
+
+    private HotSpotTruffleRuntime() {
+        installOptimizedCallTargetCallMethod();
+    }
+
+    public String getName() {
+        return "Graal Truffle Runtime";
+    }
+
+    public RootCallTarget createCallTarget(RootNode rootNode) {
+        if (truffleCompiler == null) {
+            truffleCompiler = new TruffleCompilerImpl();
+        }
+        return new HotSpotOptimizedCallTarget(rootNode, truffleCompiler, TruffleMinInvokeThreshold.getValue(), TruffleCompilationThreshold.getValue(), acceptForCompilation(rootNode));
+    }
+
+    public CallNode createCallNode(CallTarget target) {
+        if (target instanceof OptimizedCallTarget) {
+            return OptimizedCallNode.create((OptimizedCallTarget) target);
+        } else {
+            return new DefaultCallNode(target);
+        }
+    }
+
+    @Override
+    public VirtualFrame createVirtualFrame(Object[] arguments, FrameDescriptor frameDescriptor) {
+        return OptimizedCallTarget.createFrame(frameDescriptor, arguments);
+    }
+
+    @Override
+    public MaterializedFrame createMaterializedFrame(Object[] arguments) {
+        return createMaterializedFrame(arguments, new FrameDescriptor());
+    }
+
+    @Override
+    public MaterializedFrame createMaterializedFrame(Object[] arguments, FrameDescriptor frameDescriptor) {
+        return new FrameWithoutBoxing(frameDescriptor, arguments);
+    }
+
+    @Override
+    public Assumption createAssumption() {
+        return createAssumption(null);
+    }
+
+    @Override
+    public Assumption createAssumption(String name) {
+        return new OptimizedAssumption(name);
+    }
+
+    public Replacements getReplacements() {
+        if (truffleReplacements == null) {
+            truffleReplacements = HotSpotTruffleReplacements.makeInstance();
+        }
+        return truffleReplacements;
+    }
+
+    private boolean acceptForCompilation(RootNode rootNode) {
+        if (TruffleCompileOnly.getValue() != null) {
+            if (includes == null) {
+                parseCompileOnly();
+            }
+
+            String name = rootNode.toString();
+            boolean included = includes.isEmpty();
+            for (int i = 0; !included && i < includes.size(); i++) {
+                if (name.contains(includes.get(i))) {
+                    included = true;
+                }
+            }
+            if (!included) {
+                return false;
+            }
+            for (String exclude : excludes) {
+                if (name.contains(exclude)) {
+                    return false;
+                }
+            }
+        }
+        return true;
+    }
+
+    private void parseCompileOnly() {
+        includes = new ArrayList<>();
+        excludes = new ArrayList<>();
+
+        String[] items = TruffleCompileOnly.getValue().split(",");
+        for (String item : items) {
+            if (item.startsWith("~")) {
+                excludes.add(item.substring(1));
+            } else {
+                includes.add(item);
+            }
+        }
+    }
+
+    public static void installOptimizedCallTargetCallMethod() {
+        Providers providers = getGraalProviders();
+        MetaAccessProvider metaAccess = providers.getMetaAccess();
+        CodeCacheProvider codeCache = providers.getCodeCache();
+        ResolvedJavaMethod resolvedCallMethod = metaAccess.lookupJavaMethod(getCallMethod());
+        CompilationResult compResult = compileMethod(resolvedCallMethod);
+        try (Scope s = Debug.scope("CodeInstall", codeCache, resolvedCallMethod)) {
+            codeCache.setDefaultMethod(resolvedCallMethod, compResult);
+        }
+    }
+
+    private static Method getCallMethod() {
+        Method method;
+        try {
+            method = HotSpotOptimizedCallTarget.class.getDeclaredMethod("call", new Class[]{Object[].class});
+        } catch (NoSuchMethodException | SecurityException e) {
+            throw GraalInternalError.shouldNotReachHere();
+        }
+        return method;
+    }
+
+    private static CompilationResultBuilderFactory getOptimizedCallTargetInstrumentationFactory(String arch, ResolvedJavaMethod method) {
+        for (OptimizedCallTargetInstrumentationFactory factory : ServiceLoader.loadInstalled(OptimizedCallTargetInstrumentationFactory.class)) {
+            if (factory.getArchitecture().equals(arch)) {
+                factory.setInstrumentedMethod(method);
+                return factory;
+            }
+        }
+        // No specialization of OptimizedCallTarget on this platform.
+        return CompilationResultBuilderFactory.Default;
+    }
+
+    private static CompilationResult compileMethod(ResolvedJavaMethod javaMethod) {
+        Providers providers = getGraalProviders();
+        MetaAccessProvider metaAccess = providers.getMetaAccess();
+        SuitesProvider suitesProvider = Graal.getRequiredCapability(RuntimeProvider.class).getHostBackend().getSuites();
+        Suites suites = suitesProvider.createSuites();
+        suites.getHighTier().findPhase(InliningPhase.class).remove();
+        StructuredGraph graph = new StructuredGraph(javaMethod);
+        new GraphBuilderPhase.Instance(metaAccess, GraphBuilderConfiguration.getEagerDefault(), OptimisticOptimizations.ALL).apply(graph);
+        PhaseSuite<HighTierContext> graphBuilderSuite = suitesProvider.getDefaultGraphBuilderSuite();
+        CallingConvention cc = getCallingConvention(providers.getCodeCache(), Type.JavaCallee, graph.method(), false);
+        Backend backend = Graal.getRequiredCapability(RuntimeProvider.class).getHostBackend();
+        CompilationResultBuilderFactory factory = getOptimizedCallTargetInstrumentationFactory(backend.getTarget().arch.getName(), javaMethod);
+        return compileGraph(graph, null, cc, javaMethod, providers, backend, providers.getCodeCache().getTarget(), null, graphBuilderSuite, OptimisticOptimizations.ALL, getProfilingInfo(graph), null,
+                        suites, new CompilationResult(), factory);
+    }
+
+    private static Providers getGraalProviders() {
+        RuntimeProvider runtimeProvider = Graal.getRequiredCapability(RuntimeProvider.class);
+        return runtimeProvider.getHostBackend().getProviders();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.truffle.hotspot/src/com/oracle/graal/truffle/hotspot/substitutions/HotSpotOptimizedCallTargetSubstitutions.java	Mon Apr 07 16:09:17 2014 -0700
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2013, 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.truffle.hotspot.substitutions;
+
+import com.oracle.graal.api.replacements.*;
+import com.oracle.graal.nodes.spi.*;
+import com.oracle.graal.truffle.*;
+import com.oracle.graal.truffle.hotspot.*;
+import com.oracle.graal.truffle.nodes.asserts.*;
+
+@ClassSubstitution(HotSpotOptimizedCallTarget.class)
+public class HotSpotOptimizedCallTargetSubstitutions {
+
+    @MacroSubstitution(macro = NeverInlineMacroNode.class, isStatic = false)
+    public static native Object callHelper(OptimizedCallTarget target, Object[] args);
+
+    @MacroSubstitution(macro = NeverInlineMacroNode.class, isStatic = false)
+    public static native Object interpreterCall(OptimizedCallTarget target, Object[] args);
+
+    @MacroSubstitution(macro = NeverInlineMacroNode.class, isStatic = false)
+    public static native Object compiledCodeInvalidated(OptimizedCallTarget target, Object[] args);
+}
--- a/graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/PartialEvaluationTest.java	Mon Apr 07 23:35:41 2014 +0200
+++ b/graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/PartialEvaluationTest.java	Mon Apr 07 16:09:17 2014 -0700
@@ -51,7 +51,7 @@
 
     public PartialEvaluationTest() {
         // Make sure Truffle runtime is initialized.
-        Assert.assertTrue(Truffle.getRuntime() instanceof GraalTruffleRuntime);
+        Assert.assertTrue(Truffle.getRuntime() != null);
         this.truffleCompiler = new TruffleCompilerImpl();
 
         DebugEnvironment.initialize(System.out);
@@ -85,7 +85,7 @@
     }
 
     protected StructuredGraph partialEval(RootNode root, Object[] arguments, final Assumptions assumptions, final boolean canonicalizeReads) {
-        final OptimizedCallTargetImpl compilable = (OptimizedCallTargetImpl) Truffle.getRuntime().createCallTarget(root);
+        final OptimizedCallTarget compilable = (OptimizedCallTarget) Truffle.getRuntime().createCallTarget(root);
 
         // Executed AST so that all classes are loaded and initialized.
         compilable.call(arguments);
--- a/graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/TruffleRuntimeTest.java	Mon Apr 07 23:35:41 2014 +0200
+++ b/graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/TruffleRuntimeTest.java	Mon Apr 07 16:09:17 2014 -0700
@@ -28,8 +28,8 @@
 
 import com.oracle.graal.api.runtime.*;
 import com.oracle.graal.runtime.*;
-import com.oracle.graal.truffle.*;
 import com.oracle.truffle.api.*;
+import com.oracle.truffle.api.impl.*;
 
 public class TruffleRuntimeTest {
 
@@ -46,6 +46,6 @@
     @Test
     public void testRuntimeIsGraalRuntime() {
         TruffleRuntime runtime = Truffle.getRuntime();
-        assertEquals(GraalTruffleRuntime.class, runtime.getClass());
+        assertTrue(runtime.getClass() != DefaultTruffleRuntime.class);
     }
 }
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/CompilationProfile.java	Mon Apr 07 23:35:41 2014 +0200
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/CompilationProfile.java	Mon Apr 07 16:09:17 2014 -0700
@@ -126,7 +126,7 @@
         this.previousTimestamp = timestamp;
     }
 
-    void reportInvalidated() {
+    public void reportInvalidated() {
         invalidationCount++;
         int reprofile = TruffleInvalidationReprofileCount.getValue();
         ensureProfiling(reprofile, reprofile);
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/GraalTruffleRuntime.java	Mon Apr 07 23:35:41 2014 +0200
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/GraalTruffleRuntime.java	Mon Apr 07 16:09:17 2014 -0700
@@ -22,193 +22,10 @@
  */
 package com.oracle.graal.truffle;
 
-import static com.oracle.graal.api.code.CodeUtil.*;
-import static com.oracle.graal.compiler.GraalCompiler.*;
-import static com.oracle.graal.truffle.TruffleCompilerOptions.*;
-
-import java.lang.reflect.*;
-import java.util.*;
-
-import com.oracle.graal.api.code.*;
-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.target.*;
-import com.oracle.graal.debug.*;
-import com.oracle.graal.debug.Debug.Scope;
-import com.oracle.graal.graph.*;
-import com.oracle.graal.java.*;
-import com.oracle.graal.lir.asm.*;
-import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.spi.*;
-import com.oracle.graal.phases.*;
-import com.oracle.graal.phases.common.*;
-import com.oracle.graal.phases.tiers.*;
-import com.oracle.graal.phases.util.*;
-import com.oracle.graal.runtime.*;
 import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.frame.*;
-import com.oracle.truffle.api.impl.*;
-import com.oracle.truffle.api.nodes.*;
-
-/**
- * Implementation of the Truffle runtime when running on top of Graal.
- */
-public final class GraalTruffleRuntime implements TruffleRuntime {
-
-    public static GraalTruffleRuntime makeInstance() {
-        return new GraalTruffleRuntime();
-    }
-
-    private TruffleCompiler truffleCompiler;
-    private Replacements truffleReplacements;
-    private ArrayList<String> includes;
-    private ArrayList<String> excludes;
-
-    private GraalTruffleRuntime() {
-        installOptimizedCallTargetCallMethod();
-    }
-
-    public String getName() {
-        return "Graal Truffle Runtime";
-    }
-
-    public RootCallTarget createCallTarget(RootNode rootNode) {
-        if (truffleCompiler == null) {
-            truffleCompiler = new TruffleCompilerImpl();
-        }
-        return new OptimizedCallTargetImpl(rootNode, truffleCompiler, TruffleMinInvokeThreshold.getValue(), TruffleCompilationThreshold.getValue(), acceptForCompilation(rootNode));
-    }
-
-    public CallNode createCallNode(CallTarget target) {
-        if (target instanceof OptimizedCallTarget) {
-            return OptimizedCallNode.create((OptimizedCallTarget) target);
-        } else {
-            return new DefaultCallNode(target);
-        }
-    }
-
-    @Override
-    public VirtualFrame createVirtualFrame(Object[] arguments, FrameDescriptor frameDescriptor) {
-        return OptimizedCallTargetImpl.createFrame(frameDescriptor, arguments);
-    }
-
-    @Override
-    public MaterializedFrame createMaterializedFrame(Object[] arguments) {
-        return createMaterializedFrame(arguments, new FrameDescriptor());
-    }
-
-    @Override
-    public MaterializedFrame createMaterializedFrame(Object[] arguments, FrameDescriptor frameDescriptor) {
-        return new FrameWithoutBoxing(frameDescriptor, arguments);
-    }
-
-    @Override
-    public Assumption createAssumption() {
-        return createAssumption(null);
-    }
-
-    @Override
-    public Assumption createAssumption(String name) {
-        return new OptimizedAssumption(name);
-    }
 
-    public Replacements getReplacements() {
-        if (truffleReplacements == null) {
-            truffleReplacements = TruffleReplacements.makeInstance();
-        }
-        return truffleReplacements;
-    }
-
-    private boolean acceptForCompilation(RootNode rootNode) {
-        if (TruffleCompileOnly.getValue() != null) {
-            if (includes == null) {
-                parseCompileOnly();
-            }
-
-            String name = rootNode.toString();
-            boolean included = includes.isEmpty();
-            for (int i = 0; !included && i < includes.size(); i++) {
-                if (name.contains(includes.get(i))) {
-                    included = true;
-                }
-            }
-            if (!included) {
-                return false;
-            }
-            for (String exclude : excludes) {
-                if (name.contains(exclude)) {
-                    return false;
-                }
-            }
-        }
-        return true;
-    }
-
-    private void parseCompileOnly() {
-        includes = new ArrayList<>();
-        excludes = new ArrayList<>();
-
-        String[] items = TruffleCompileOnly.getValue().split(",");
-        for (String item : items) {
-            if (item.startsWith("~")) {
-                excludes.add(item.substring(1));
-            } else {
-                includes.add(item);
-            }
-        }
-    }
+public interface GraalTruffleRuntime extends TruffleRuntime {
 
-    public static void installOptimizedCallTargetCallMethod() {
-        Providers providers = getGraalProviders();
-        MetaAccessProvider metaAccess = providers.getMetaAccess();
-        CodeCacheProvider codeCache = providers.getCodeCache();
-        ResolvedJavaMethod resolvedCallMethod = metaAccess.lookupJavaMethod(getCallMethod());
-        CompilationResult compResult = compileMethod(resolvedCallMethod);
-        try (Scope s = Debug.scope("CodeInstall", codeCache, resolvedCallMethod)) {
-            codeCache.setDefaultMethod(resolvedCallMethod, compResult);
-        }
-    }
-
-    private static Method getCallMethod() {
-        Method method;
-        try {
-            method = OptimizedCallTargetImpl.class.getDeclaredMethod("call", new Class[]{Object[].class});
-        } catch (NoSuchMethodException | SecurityException e) {
-            throw GraalInternalError.shouldNotReachHere();
-        }
-        return method;
-    }
-
-    private static CompilationResultBuilderFactory getOptimizedCallTargetInstrumentationFactory(String arch, ResolvedJavaMethod method) {
-        for (OptimizedCallTargetInstrumentationFactory factory : ServiceLoader.loadInstalled(OptimizedCallTargetInstrumentationFactory.class)) {
-            if (factory.getArchitecture().equals(arch)) {
-                factory.setInstrumentedMethod(method);
-                return factory;
-            }
-        }
-        // No specialization of OptimizedCallTarget on this platform.
-        return CompilationResultBuilderFactory.Default;
-    }
-
-    private static CompilationResult compileMethod(ResolvedJavaMethod javaMethod) {
-        Providers providers = getGraalProviders();
-        MetaAccessProvider metaAccess = providers.getMetaAccess();
-        SuitesProvider suitesProvider = Graal.getRequiredCapability(RuntimeProvider.class).getHostBackend().getSuites();
-        Suites suites = suitesProvider.createSuites();
-        suites.getHighTier().findPhase(InliningPhase.class).remove();
-        StructuredGraph graph = new StructuredGraph(javaMethod);
-        new GraphBuilderPhase.Instance(metaAccess, GraphBuilderConfiguration.getEagerDefault(), OptimisticOptimizations.ALL).apply(graph);
-        PhaseSuite<HighTierContext> graphBuilderSuite = suitesProvider.getDefaultGraphBuilderSuite();
-        CallingConvention cc = getCallingConvention(providers.getCodeCache(), Type.JavaCallee, graph.method(), false);
-        Backend backend = Graal.getRequiredCapability(RuntimeProvider.class).getHostBackend();
-        CompilationResultBuilderFactory factory = getOptimizedCallTargetInstrumentationFactory(backend.getTarget().arch.getName(), javaMethod);
-        return compileGraph(graph, null, cc, javaMethod, providers, backend, providers.getCodeCache().getTarget(), null, graphBuilderSuite, OptimisticOptimizations.ALL, getProfilingInfo(graph), null,
-                        suites, new CompilationResult(), factory);
-    }
-
-    private static Providers getGraalProviders() {
-        RuntimeProvider runtimeProvider = Graal.getRequiredCapability(RuntimeProvider.class);
-        return runtimeProvider.getHostBackend().getProviders();
-    }
+    Replacements getReplacements();
 }
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedCallTarget.java	Mon Apr 07 23:35:41 2014 +0200
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedCallTarget.java	Mon Apr 07 16:09:17 2014 -0700
@@ -49,7 +49,6 @@
     protected TruffleInliningResult inliningResult;
     protected final CompilationProfile compilationProfile;
     protected final CompilationPolicy compilationPolicy;
-    private final SpeculationLog speculationLog = new SpeculationLog();
     private OptimizedCallTarget splitSource;
 
     private final AtomicInteger callSitesKnown = new AtomicInteger(0);
@@ -181,9 +180,7 @@
         invalidate(oldNode, newNode, reason);
     }
 
-    public SpeculationLog getSpeculationLog() {
-        return speculationLog;
-    }
+    public abstract SpeculationLog getSpeculationLog();
 
     public Map<String, Object> getDebugProperties() {
         Map<String, Object> properties = new LinkedHashMap<>();
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedCallTargetImpl.java	Mon Apr 07 23:35:41 2014 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,181 +0,0 @@
-/*
- * Copyright (c) 2013, 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.truffle;
-
-import static com.oracle.graal.truffle.TruffleCompilerOptions.*;
-
-import java.util.concurrent.*;
-
-import com.oracle.graal.api.code.*;
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.nodes.*;
-
-/**
- * Call target for running truffle on a standard VM (and not in SubstrateVM).
- */
-public final class OptimizedCallTargetImpl extends OptimizedCallTarget {
-
-    protected final TruffleCompiler compiler;
-    private Future<InstalledCode> installedCodeTask;
-
-    OptimizedCallTargetImpl(RootNode rootNode, TruffleCompiler compiler, int invokeCounter, int compilationThreshold, boolean compilationEnabled) {
-        super(rootNode, invokeCounter, compilationThreshold, compilationEnabled, TruffleUseTimeForCompilationDecision.getValue() ? new TimedCompilationPolicy() : new DefaultCompilationPolicy());
-        this.compiler = compiler;
-    }
-
-    public boolean isOptimized() {
-        return installedCode != null || installedCodeTask != null;
-    }
-
-    @CompilerDirectives.SlowPath
-    @Override
-    public Object call(Object[] args) {
-        return CompilerDirectives.inInterpreter() ? callHelper(args) : executeHelper(args);
-    }
-
-    private Object callHelper(Object[] args) {
-        if (installedCode != null && installedCode.isValid()) {
-            reinstallCallMethodShortcut();
-        }
-        if (TruffleCallTargetProfiling.getValue()) {
-            callCount++;
-        }
-        if (CompilerDirectives.injectBranchProbability(CompilerDirectives.FASTPATH_PROBABILITY, installedCode != null)) {
-            try {
-                return installedCode.executeVarargs(new Object[]{this, args});
-            } catch (InvalidInstalledCodeException ex) {
-                return compiledCodeInvalidated(args);
-            }
-        } else {
-            return interpreterCall(args);
-        }
-    }
-
-    private static void reinstallCallMethodShortcut() {
-        if (TraceTruffleCompilation.getValue()) {
-            OUT.println("[truffle] reinstall OptimizedCallTarget.call code with frame prolog shortcut.");
-        }
-        GraalTruffleRuntime.installOptimizedCallTargetCallMethod();
-    }
-
-    private Object compiledCodeInvalidated(Object[] args) {
-        invalidate(null, null, "Compiled code invalidated");
-        return call(args);
-    }
-
-    @Override
-    protected void invalidate(Node oldNode, Node newNode, CharSequence reason) {
-        InstalledCode m = this.installedCode;
-        if (m != null) {
-            CompilerAsserts.neverPartOfCompilation();
-            installedCode = null;
-            inliningResult = null;
-            compilationProfile.reportInvalidated();
-            logOptimizedInvalidated(this, oldNode, newNode, reason);
-        }
-        cancelInstalledTask(oldNode, newNode, reason);
-    }
-
-    @Override
-    protected void cancelInstalledTask(Node oldNode, Node newNode, CharSequence reason) {
-        Future<InstalledCode> task = this.installedCodeTask;
-        if (task != null) {
-            task.cancel(true);
-            this.installedCodeTask = null;
-            logOptimizingUnqueued(this, oldNode, newNode, reason);
-            compilationProfile.reportInvalidated();
-        }
-    }
-
-    private Object interpreterCall(Object[] args) {
-        CompilerAsserts.neverPartOfCompilation();
-        compilationProfile.reportInterpreterCall();
-
-        if (compilationEnabled && compilationPolicy.shouldCompile(compilationProfile)) {
-            InstalledCode code = compile();
-            if (code != null && code.isValid()) {
-                this.installedCode = code;
-                try {
-                    return code.executeVarargs(new Object[]{this, args});
-                } catch (InvalidInstalledCodeException ex) {
-                    return compiledCodeInvalidated(args);
-                }
-            }
-        }
-        return executeHelper(args);
-    }
-
-    private boolean isCompiling() {
-        Future<InstalledCode> codeTask = this.installedCodeTask;
-        if (codeTask != null) {
-            if (codeTask.isCancelled()) {
-                installedCodeTask = null;
-                return false;
-            }
-            return true;
-        }
-        return false;
-    }
-
-    @Override
-    public InstalledCode compile() {
-        if (isCompiling()) {
-            if (installedCodeTask.isDone()) {
-                return receiveInstalledCode();
-            }
-            return null;
-        } else {
-            performInlining();
-            cancelInlinedCallOptimization();
-            logOptimizingQueued(this);
-            this.installedCodeTask = compiler.compile(this);
-            if (!TruffleBackgroundCompilation.getValue()) {
-                return receiveInstalledCode();
-            }
-            return null;
-        }
-    }
-
-    private InstalledCode receiveInstalledCode() {
-        try {
-            return installedCodeTask.get();
-        } catch (InterruptedException | ExecutionException e) {
-            compilationEnabled = false;
-            logOptimizingFailed(this, e.getMessage());
-            if (e.getCause() instanceof BailoutException) {
-                // Bailout => move on.
-            } else {
-                if (TraceTruffleCompilationExceptions.getValue()) {
-                    e.printStackTrace(OUT);
-                }
-                if (TruffleCompilationExceptionsAreFatal.getValue()) {
-                    System.exit(-1);
-                }
-            }
-            return null;
-        } finally {
-            onCompilationDone();
-        }
-    }
-
-}
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/PartialEvaluator.java	Mon Apr 07 23:35:41 2014 +0200
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/PartialEvaluator.java	Mon Apr 07 16:09:17 2014 -0700
@@ -30,6 +30,8 @@
 
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
+import com.oracle.graal.api.replacements.*;
+import com.oracle.graal.api.runtime.*;
 import com.oracle.graal.debug.*;
 import com.oracle.graal.debug.Debug.Scope;
 import com.oracle.graal.debug.internal.*;
@@ -95,7 +97,14 @@
 
             // Replace thisNode with constant.
             ParameterNode thisNode = graph.getParameter(0);
-            thisNode.replaceAndDelete(ConstantNode.forObject(callTarget, providers.getMetaAccess(), graph));
+
+            /*
+             * Converting the call target to a Constant using the SnippetReflectionProvider is a
+             * workaround, we should think about a better solution. Since object constants are
+             * VM-specific, only the hosting VM knows how to do the conversion.
+             */
+            SnippetReflectionProvider snippetReflection = Graal.getRequiredCapability(SnippetReflectionProvider.class);
+            thisNode.replaceAndDelete(ConstantNode.forConstant(snippetReflection.forObject(callTarget), providers.getMetaAccess(), graph));
 
             // Canonicalize / constant propagate.
             PhaseContext baseContext = new PhaseContext(providers, assumptions);
@@ -123,7 +132,7 @@
             if (TraceTruffleCompilationHistogram.getValue() && constantReceivers != null) {
                 DebugHistogram histogram = Debug.createHistogram("Expanded Truffle Nodes");
                 for (Constant c : constantReceivers) {
-                    histogram.add(c.asObject().getClass().getSimpleName());
+                    histogram.add(providers.getMetaAccess().lookupJavaType(c).getName());
                 }
                 new DebugHistogramAsciiPrinter(TTY.out().out()).print(histogram);
             }
@@ -170,7 +179,7 @@
         PhaseContext phaseContext = new PhaseContext(providers, assumptions);
         TruffleExpansionLogger expansionLogger = null;
         if (TraceTruffleExpansion.getValue()) {
-            expansionLogger = new TruffleExpansionLogger(graph);
+            expansionLogger = new TruffleExpansionLogger(providers, graph);
         }
         boolean inliningEnabled = target.getInliningResult() != null && target.getInliningResult().size() > 0;
         Map<Node, TruffleCallPath> methodTargetToStack = new HashMap<>();
@@ -278,7 +287,13 @@
             return null;
         }
 
-        Object receiverValue = receiverNode.asConstant().asObject();
+        /*
+         * Accessing the constant using the SnippetReflectionProvider is a workaround, we should
+         * think about a better solution. Since object constants are VM-specific, only the hosting
+         * VM knows how to do the conversion.
+         */
+        SnippetReflectionProvider snippetReflection = Graal.getRequiredCapability(SnippetReflectionProvider.class);
+        Object receiverValue = snippetReflection.asObject(receiverNode.asConstant());
         if (receiverValue instanceof OptimizedCallNode) {
             OptimizedCallNode callNode = (OptimizedCallNode) receiverValue;
             TruffleCallPath callPath = methodCallToCallPath.get(methodCallTargetNode);
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/PartialEvaluatorCanonicalizer.java	Mon Apr 07 23:35:41 2014 +0200
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/PartialEvaluatorCanonicalizer.java	Mon Apr 07 16:09:17 2014 -0700
@@ -24,8 +24,6 @@
 
 import java.lang.reflect.*;
 
-import sun.misc.*;
-
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.graph.Node;
 import com.oracle.graal.nodes.*;
@@ -44,8 +42,6 @@
         this.constantReflection = constantReflection;
     }
 
-    private static final Unsafe unsafe = Unsafe.getUnsafe();
-
     @Override
     public Node canonicalize(Node node) {
         if (node instanceof LoadFieldNode) {
@@ -60,14 +56,11 @@
             }
         } else if (node instanceof LoadIndexedNode) {
             LoadIndexedNode loadIndexedNode = (LoadIndexedNode) node;
-            if (loadIndexedNode.array().isConstant() && !loadIndexedNode.array().isNullConstant() && loadIndexedNode.index().isConstant()) {
-                Object array = loadIndexedNode.array().asConstant().asObject();
-                long index = loadIndexedNode.index().asConstant().asLong();
-                if (index >= 0 && index < Array.getLength(array)) {
-                    int arrayBaseOffset = unsafe.arrayBaseOffset(array.getClass());
-                    int arrayIndexScale = unsafe.arrayIndexScale(array.getClass());
-                    Constant constant = constantReflection.readUnsafeConstant(loadIndexedNode.elementKind(), array, arrayBaseOffset + index * arrayIndexScale,
-                                    loadIndexedNode.elementKind() == Kind.Object);
+            if (loadIndexedNode.array().isConstant() && loadIndexedNode.index().isConstant()) {
+                int index = loadIndexedNode.index().asConstant().asInt();
+
+                Constant constant = constantReflection.readArrayElement(loadIndexedNode.array().asConstant(), index);
+                if (constant != null) {
                     return ConstantNode.forConstant(constant, metaAccess, loadIndexedNode.graph());
                 }
             }
@@ -75,9 +68,10 @@
         return node;
     }
 
-    private static boolean verifyFieldValue(ResolvedJavaField field, Constant constant) {
-        assert field.getAnnotation(Child.class) == null || constant.isNull() || constant.asObject() instanceof com.oracle.truffle.api.nodes.Node : "@Child field value must be a Node: " + field +
-                        ", but was: " + constant.asObject();
+    private boolean verifyFieldValue(ResolvedJavaField field, Constant constant) {
+        assert field.getAnnotation(Child.class) == null || constant.isNull() ||
+                        metaAccess.lookupJavaType(com.oracle.truffle.api.nodes.Node.class).isAssignableFrom(metaAccess.lookupJavaType(constant)) : "@Child field value must be a Node: " + field +
+                        ", but was: " + constant;
         return true;
     }
 }
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCompilerImpl.java	Mon Apr 07 23:35:41 2014 +0200
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCompilerImpl.java	Mon Apr 07 16:09:17 2014 -0700
@@ -120,7 +120,7 @@
             @Override
             public InstalledCode call() throws Exception {
                 try (Scope s = Debug.scope("Truffle", new TruffleDebugJavaMethod(compilable))) {
-                    return compileMethodImpl((OptimizedCallTargetImpl) compilable);
+                    return compileMethodImpl(compilable);
                 } catch (Throwable e) {
                     throw Debug.handle(e);
                 }
@@ -132,11 +132,11 @@
     public static final DebugTimer CompilationTime = Debug.timer("CompilationTime");
     public static final DebugTimer CodeInstallationTime = Debug.timer("CodeInstallation");
 
-    private InstalledCode compileMethodImpl(final OptimizedCallTargetImpl compilable) {
+    private InstalledCode compileMethodImpl(final OptimizedCallTarget compilable) {
         final StructuredGraph graph;
 
         if (TraceTruffleCompilation.getValue()) {
-            OptimizedCallTargetImpl.logOptimizingStart(compilable);
+            OptimizedCallTarget.logOptimizingStart(compilable);
         }
 
         long timeCompilationStarted = System.nanoTime();
@@ -179,7 +179,7 @@
             properties.put("CodeSize", code != null ? code.length : 0);
             properties.put("Source", formatSourceSection(compilable.getRootNode().getSourceSection()));
 
-            OptimizedCallTargetImpl.logOptimizingDone(compilable, properties);
+            OptimizedCallTarget.logOptimizingDone(compilable, properties);
         }
         return compiledMethod;
     }
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleExpansionLogger.java	Mon Apr 07 23:35:41 2014 +0200
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleExpansionLogger.java	Mon Apr 07 16:09:17 2014 -0700
@@ -31,13 +31,16 @@
 import com.oracle.graal.graph.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.java.*;
+import com.oracle.graal.phases.util.*;
 
 public class TruffleExpansionLogger {
 
+    private final Providers providers;
     private final ExpansionTree root;
     private final Map<MethodCallTargetNode, ExpansionTree> callToParentTree = new HashMap<>();
 
-    public TruffleExpansionLogger(StructuredGraph graph) {
+    public TruffleExpansionLogger(Providers providers, StructuredGraph graph) {
+        this.providers = providers;
         root = new ExpansionTree(null, null, graph.method(), -1);
         registerParentInCalls(root, graph);
     }
@@ -47,16 +50,16 @@
 
         int sourceMethodBci = callTarget.invoke().bci();
         ResolvedJavaMethod targetMethod = callTarget.targetMethod();
-        Object targetReceiver = null;
+        ResolvedJavaType targetReceiverType = null;
         if (!Modifier.isStatic(sourceMethod.getModifiers()) && callTarget.receiver().isConstant()) {
-            targetReceiver = callTarget.receiver().asConstant().asObject();
+            targetReceiverType = providers.getMetaAccess().lookupJavaType(callTarget.arguments().first().asConstant());
         }
 
-        if (targetReceiver != null) {
+        if (targetReceiverType != null) {
             ExpansionTree parent = callToParentTree.get(callTarget);
             assert parent != null;
             callToParentTree.remove(callTarget);
-            ExpansionTree tree = new ExpansionTree(parent, targetReceiver, targetMethod, sourceMethodBci);
+            ExpansionTree tree = new ExpansionTree(parent, targetReceiverType, targetMethod, sourceMethodBci);
             registerParentInCalls(tree, inliningGraph);
         }
     }
@@ -94,14 +97,14 @@
     private static final class ExpansionTree implements Comparable<ExpansionTree> {
 
         private final ExpansionTree parent;
-        private final Object targetReceiver;
+        private final ResolvedJavaType targetReceiverType;
         private final ResolvedJavaMethod targetMethod;
         private final int parentBci;
         private final List<ExpansionTree> children = new ArrayList<>();
 
-        public ExpansionTree(ExpansionTree parent, Object receiver, ResolvedJavaMethod targetMethod, int parentBci) {
+        public ExpansionTree(ExpansionTree parent, ResolvedJavaType targetReceiverType, ResolvedJavaMethod targetMethod, int parentBci) {
             this.parent = parent;
-            this.targetReceiver = receiver;
+            this.targetReceiverType = targetReceiverType;
             this.targetMethod = targetMethod;
             this.parentBci = parentBci;
             if (parent != null) {
@@ -141,9 +144,9 @@
             }
 
             String constantType = "";
-            if (targetReceiver != null) {
-                if (!targetReceiver.getClass().getSimpleName().equals(className)) {
-                    constantType = "<" + targetReceiver.getClass().getSimpleName() + ">";
+            if (targetReceiverType != null) {
+                if (!targetReceiverType.getName().equals(className)) {
+                    constantType = "<" + targetReceiverType.getName() + ">";
                 }
             }
 
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleReplacements.java	Mon Apr 07 23:35:41 2014 +0200
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleReplacements.java	Mon Apr 07 16:09:17 2014 -0700
@@ -26,39 +26,33 @@
 
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.api.replacements.*;
-import com.oracle.graal.api.runtime.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.phases.util.*;
 import com.oracle.graal.replacements.*;
-import com.oracle.graal.runtime.*;
 import com.oracle.graal.truffle.substitutions.*;
 
 /**
  * Custom {@link Replacements} for Truffle compilation.
  */
-public final class TruffleReplacements extends ReplacementsImpl {
+public abstract class TruffleReplacements extends ReplacementsImpl {
 
     private final Replacements graalReplacements;
 
-    private TruffleReplacements(Providers providers) {
-        super(providers, providers.getReplacements().getAssumptions(), providers.getCodeCache().getTarget());
+    protected TruffleReplacements(Providers providers, SnippetReflectionProvider snippetReflection) {
+        super(providers, snippetReflection, providers.getReplacements().getAssumptions(), providers.getCodeCache().getTarget());
         this.graalReplacements = providers.getReplacements();
+
+        registerTruffleSubstitutions();
     }
 
-    public static Replacements makeInstance() {
-        Providers graalProviders = Graal.getRequiredCapability(RuntimeProvider.class).getHostBackend().getProviders();
-        Replacements truffleReplacements = new TruffleReplacements(graalProviders);
-
-        truffleReplacements.registerSubstitutions(CompilerAssertsSubstitutions.class);
-        truffleReplacements.registerSubstitutions(CompilerDirectivesSubstitutions.class);
-        truffleReplacements.registerSubstitutions(ExactMathSubstitutions.class);
-        truffleReplacements.registerSubstitutions(OptimizedAssumptionSubstitutions.class);
-        truffleReplacements.registerSubstitutions(OptimizedCallTargetSubstitutions.class);
-        truffleReplacements.registerSubstitutions(OptimizedCallTargetImplSubstitutions.class);
-
-        return truffleReplacements;
+    protected void registerTruffleSubstitutions() {
+        registerSubstitutions(CompilerAssertsSubstitutions.class);
+        registerSubstitutions(CompilerDirectivesSubstitutions.class);
+        registerSubstitutions(ExactMathSubstitutions.class);
+        registerSubstitutions(OptimizedAssumptionSubstitutions.class);
+        registerSubstitutions(OptimizedCallTargetSubstitutions.class);
     }
 
     @Override
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/AssumptionNode.java	Mon Apr 07 23:35:41 2014 +0200
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/AssumptionNode.java	Mon Apr 07 16:09:17 2014 -0700
@@ -23,6 +23,8 @@
 package com.oracle.graal.truffle.nodes;
 
 import com.oracle.graal.api.meta.*;
+import com.oracle.graal.api.replacements.*;
+import com.oracle.graal.api.runtime.*;
 import com.oracle.graal.graph.spi.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.replacements.nodes.*;
@@ -39,13 +41,21 @@
         return arguments.first();
     }
 
+    private static SnippetReflectionProvider getSnippetReflection() {
+        /*
+         * This class requires access to the objects encapsulated in Constants, and therefore breaks
+         * the compiler-VM separation of object constants.
+         */
+        return Graal.getRequiredCapability(SnippetReflectionProvider.class);
+    }
+
     @Override
     public void simplify(SimplifierTool tool) {
         ValueNode assumption = getAssumption();
         if (tool.assumptions() != null && assumption.isConstant()) {
             Constant c = assumption.asConstant();
             assert c.getKind() == Kind.Object;
-            Object object = c.asObject();
+            Object object = getSnippetReflection().asObject(c);
             OptimizedAssumption assumptionObject = (OptimizedAssumption) object;
             StructuredGraph graph = graph();
             if (assumptionObject.isValid()) {
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/BailoutNode.java	Mon Apr 07 23:35:41 2014 +0200
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/BailoutNode.java	Mon Apr 07 16:09:17 2014 -0700
@@ -40,7 +40,7 @@
         ValueNode arg = arguments.get(0);
         String message = "";
         if (arg.isConstant()) {
-            message = (String) arg.asConstant().asObject();
+            message = arg.asConstant().toValueString();
         }
         throw new BailoutException(message);
     }
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/LoadIndexedFinalNode.java	Mon Apr 07 23:35:41 2014 +0200
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/LoadIndexedFinalNode.java	Mon Apr 07 16:09:17 2014 -0700
@@ -22,10 +22,6 @@
  */
 package com.oracle.graal.truffle.nodes;
 
-import java.lang.reflect.*;
-
-import sun.misc.*;
-
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.graph.spi.*;
@@ -52,13 +48,9 @@
 
     @Override
     public Node canonical(CanonicalizerTool tool) {
-        if (array().isConstant() && !array().isNullConstant() && index().isConstant()) {
-            Object array = array().asConstant().asObject();
-            long index = index().asConstant().asLong();
-            if (index >= 0 && index < Array.getLength(array)) {
-                int arrayBaseOffset = Unsafe.getUnsafe().arrayBaseOffset(array.getClass());
-                int arrayIndexScale = Unsafe.getUnsafe().arrayIndexScale(array.getClass());
-                Constant constant = tool.getConstantReflection().readUnsafeConstant(elementKind(), array().asConstant(), arrayBaseOffset + index * arrayIndexScale, elementKind() == Kind.Object);
+        if (array().isConstant() && index().isConstant()) {
+            Constant constant = tool.getConstantReflection().readArrayElement(array().asConstant(), index().asConstant().asInt());
+            if (constant != null) {
                 return ConstantNode.forConstant(constant, tool.getMetaAccess(), graph());
             }
         }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/ObjectLocationIdentity.java	Mon Apr 07 16:09:17 2014 -0700
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2013, 2013, 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.truffle.nodes;
+
+import java.util.*;
+
+import com.oracle.graal.api.meta.*;
+
+/**
+ * A {@link LocationIdentity} wrapping an object.
+ */
+public final class ObjectLocationIdentity implements LocationIdentity {
+
+    private static HashMap<Constant, LocationIdentity> map = new HashMap<>();
+
+    private Constant object;
+
+    public static LocationIdentity create(Constant object) {
+        assert object.getKind() == Kind.Object && object.isNonNull();
+        synchronized (map) {
+            if (map.containsKey(object)) {
+                return map.get(object);
+            } else {
+                ObjectLocationIdentity locationIdentity = new ObjectLocationIdentity(object);
+                map.put(object, locationIdentity);
+                return locationIdentity;
+            }
+        }
+    }
+
+    private ObjectLocationIdentity(Constant object) {
+        this.object = object;
+    }
+
+    @Override
+    public String toString() {
+        return "Identity(" + object + ")";
+    }
+}
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/frame/NewFrameNode.java	Mon Apr 07 23:35:41 2014 +0200
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/frame/NewFrameNode.java	Mon Apr 07 16:09:17 2014 -0700
@@ -25,6 +25,8 @@
 import java.util.*;
 
 import com.oracle.graal.api.meta.*;
+import com.oracle.graal.api.replacements.*;
+import com.oracle.graal.api.runtime.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.graph.spi.*;
 import com.oracle.graal.nodes.*;
@@ -64,9 +66,17 @@
         return arguments;
     }
 
+    private static SnippetReflectionProvider getSnippetReflection() {
+        /*
+         * This class requires access to the objects encapsulated in Constants, and therefore breaks
+         * the compiler-VM separation of object constants.
+         */
+        return Graal.getRequiredCapability(SnippetReflectionProvider.class);
+    }
+
     private FrameDescriptor getConstantFrameDescriptor() {
         assert descriptor.isConstant() && !descriptor.isNullConstant();
-        return (FrameDescriptor) descriptor.asConstant().asObject();
+        return (FrameDescriptor) getSnippetReflection().asObject(descriptor.asConstant());
     }
 
     private int getFrameSize() {
@@ -151,7 +161,7 @@
 
         if (frameSize > 0) {
             FrameDescriptor frameDescriptor = getConstantFrameDescriptor();
-            ConstantNode objectDefault = ConstantNode.forObject(frameDescriptor.getTypeConversion().getDefaultValue(), tool.getMetaAccessProvider(), graph());
+            ConstantNode objectDefault = ConstantNode.forConstant(getSnippetReflection().forObject(frameDescriptor.getTypeConversion().getDefaultValue()), tool.getMetaAccessProvider(), graph());
             ConstantNode tagDefault = ConstantNode.forByte((byte) 0, graph());
             for (int i = 0; i < frameSize; i++) {
                 objectArrayEntryState[i] = objectDefault;
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/typesystem/CustomizedUnsafeLoadFinalNode.java	Mon Apr 07 23:35:41 2014 +0200
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/typesystem/CustomizedUnsafeLoadFinalNode.java	Mon Apr 07 16:09:17 2014 -0700
@@ -30,6 +30,7 @@
 import com.oracle.graal.nodes.extended.*;
 import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.nodes.type.*;
+import com.oracle.graal.truffle.nodes.*;
 import com.oracle.truffle.api.*;
 
 /**
@@ -56,7 +57,7 @@
     @Override
     public Node canonical(CanonicalizerTool tool) {
         if (object.isConstant() && !object.isNullConstant() && offset.isConstant()) {
-            Constant constant = tool.getConstantReflection().readUnsafeConstant(accessKind, object.asConstant().asObject(), offset.asConstant().asLong(), accessKind == Kind.Object);
+            Constant constant = tool.getConstantReflection().readUnsafeConstant(accessKind, object.asConstant(), offset.asConstant().asLong(), accessKind == Kind.Object);
             return ConstantNode.forConstant(constant, tool.getMetaAccess(), graph());
         }
         return this;
@@ -86,12 +87,11 @@
     @Override
     public void lower(LoweringTool tool) {
         CompareNode compare = CompareNode.createCompareNode(graph(), Condition.EQ, condition, ConstantNode.forBoolean(true, graph()));
-        Object locationIdentityObject = location.asConstant().asObject();
         LocationIdentity locationIdentity;
-        if (locationIdentityObject == null) {
+        if (location.asConstant().isNull()) {
             locationIdentity = LocationIdentity.ANY_LOCATION;
         } else {
-            locationIdentity = ObjectLocationIdentity.create(locationIdentityObject);
+            locationIdentity = ObjectLocationIdentity.create(location.asConstant());
         }
         UnsafeLoadNode result = graph().add(new UnsafeLoadNode(object, offset, accessKind, locationIdentity, compare));
         graph().replaceFixedWithFixed(this, result);
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/typesystem/CustomizedUnsafeLoadMacroNode.java	Mon Apr 07 23:35:41 2014 +0200
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/typesystem/CustomizedUnsafeLoadMacroNode.java	Mon Apr 07 16:09:17 2014 -0700
@@ -28,6 +28,7 @@
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.calc.*;
 import com.oracle.graal.nodes.extended.*;
+import com.oracle.graal.truffle.nodes.*;
 import com.oracle.graal.truffle.nodes.asserts.*;
 import com.oracle.truffle.api.*;
 
@@ -54,12 +55,11 @@
             ValueNode objectArgument = arguments.get(OBJECT_ARGUMENT_INDEX);
             ValueNode offsetArgument = arguments.get(OFFSET_ARGUMENT_INDEX);
             ValueNode conditionArgument = arguments.get(CONDITION_ARGUMENT_INDEX);
-            Object locationIdentityObject = locationArgument.asConstant().asObject();
             LocationIdentity locationIdentity;
-            if (locationIdentityObject == null) {
+            if (locationArgument.asConstant().isNull()) {
                 locationIdentity = LocationIdentity.ANY_LOCATION;
             } else {
-                locationIdentity = ObjectLocationIdentity.create(locationIdentityObject);
+                locationIdentity = ObjectLocationIdentity.create(locationArgument.asConstant());
             }
             CompareNode compare = CompareNode.createCompareNode(graph(), Condition.EQ, conditionArgument, ConstantNode.forBoolean(true, graph()));
             Kind returnKind = this.getTargetMethod().getSignature().getReturnKind();
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/typesystem/CustomizedUnsafeStoreMacroNode.java	Mon Apr 07 23:35:41 2014 +0200
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/typesystem/CustomizedUnsafeStoreMacroNode.java	Mon Apr 07 16:09:17 2014 -0700
@@ -27,6 +27,7 @@
 import com.oracle.graal.graph.spi.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.extended.*;
+import com.oracle.graal.truffle.nodes.*;
 import com.oracle.graal.truffle.nodes.asserts.*;
 import com.oracle.truffle.api.*;
 
@@ -53,12 +54,11 @@
             ValueNode objectArgument = arguments.get(OBJECT_ARGUMENT_INDEX);
             ValueNode offsetArgument = arguments.get(OFFSET_ARGUMENT_INDEX);
             ValueNode valueArgument = arguments.get(VALUE_ARGUMENT_INDEX);
-            Object locationIdentityObject = locationArgument.asConstant().asObject();
             LocationIdentity locationIdentity;
-            if (locationIdentityObject == null) {
+            if (locationArgument.asConstant().isNull()) {
                 locationIdentity = LocationIdentity.ANY_LOCATION;
             } else {
-                locationIdentity = ObjectLocationIdentity.create(locationIdentityObject);
+                locationIdentity = ObjectLocationIdentity.create(locationArgument.asConstant());
             }
 
             UnsafeStoreNode unsafeStoreNode = graph().add(
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/typesystem/UnsafeTypeCastMacroNode.java	Mon Apr 07 23:35:41 2014 +0200
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/typesystem/UnsafeTypeCastMacroNode.java	Mon Apr 07 16:09:17 2014 -0700
@@ -55,11 +55,10 @@
         if (classArgument.isConstant() && nonNullArgument.isConstant()) {
             ValueNode objectArgument = arguments.get(OBJECT_ARGUMENT_INDEX);
             ValueNode conditionArgument = arguments.get(CONDITION_ARGUMENT_INDEX);
-            Class c = (Class) classArgument.asConstant().asObject();
-            if (c == null) {
+            ResolvedJavaType lookupJavaType = tool.getConstantReflection().asJavaType(classArgument.asConstant());
+            if (lookupJavaType == null) {
                 return objectArgument;
             }
-            ResolvedJavaType lookupJavaType = tool.getMetaAccess().lookupJavaType(c);
             Stamp stamp = StampFactory.declared(lookupJavaType, nonNullArgument.asConstant().asInt() != 0);
             ConditionAnchorNode valueAnchorNode = graph().add(new ConditionAnchorNode(CompareNode.createCompareNode(graph(), Condition.EQ, conditionArgument, ConstantNode.forBoolean(true, graph()))));
             UnsafeCastNode piCast = graph().unique(new UnsafeCastNode(objectArgument, stamp, valueAnchorNode));
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/substitutions/OptimizedCallTargetImplSubstitutions.java	Mon Apr 07 23:35:41 2014 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,41 +0,0 @@
-/*
- * Copyright (c) 2013, 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.truffle.substitutions;
-
-import com.oracle.graal.api.replacements.*;
-import com.oracle.graal.nodes.spi.*;
-import com.oracle.graal.truffle.*;
-import com.oracle.graal.truffle.nodes.asserts.*;
-
-@ClassSubstitution(OptimizedCallTargetImpl.class)
-public class OptimizedCallTargetImplSubstitutions {
-
-    @MacroSubstitution(macro = NeverInlineMacroNode.class, isStatic = false)
-    public static native Object callHelper(OptimizedCallTarget target, Object[] args);
-
-    @MacroSubstitution(macro = NeverInlineMacroNode.class, isStatic = false)
-    public static native Object interpreterCall(OptimizedCallTarget target, Object[] args);
-
-    @MacroSubstitution(macro = NeverInlineMacroNode.class, isStatic = false)
-    public static native Object compiledCodeInvalidated(OptimizedCallTarget target, Object[] args);
-}
--- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PEReadEliminationClosure.java	Mon Apr 07 23:35:41 2014 +0200
+++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PEReadEliminationClosure.java	Mon Apr 07 16:09:17 2014 -0700
@@ -39,8 +39,8 @@
 
 public class PEReadEliminationClosure extends PartialEscapeClosure<PEReadEliminationBlockState> {
 
-    public PEReadEliminationClosure(SchedulePhase schedule, MetaAccessProvider metaAccess, Assumptions assumptions) {
-        super(schedule, metaAccess, assumptions);
+    public PEReadEliminationClosure(SchedulePhase schedule, MetaAccessProvider metaAccess, ConstantReflectionProvider constantReflection, Assumptions assumptions) {
+        super(schedule, metaAccess, constantReflection, assumptions);
     }
 
     @Override
--- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PartialEscapeClosure.java	Mon Apr 07 23:35:41 2014 +0200
+++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PartialEscapeClosure.java	Mon Apr 07 16:09:17 2014 -0700
@@ -63,8 +63,8 @@
      */
     public static final class Final extends PartialEscapeClosure<PartialEscapeBlockState.Final> {
 
-        public Final(SchedulePhase schedule, MetaAccessProvider metaAccess, Assumptions assumptions) {
-            super(schedule, metaAccess, assumptions);
+        public Final(SchedulePhase schedule, MetaAccessProvider metaAccess, ConstantReflectionProvider constantReflection, Assumptions assumptions) {
+            super(schedule, metaAccess, constantReflection, assumptions);
         }
 
         @Override
@@ -78,10 +78,10 @@
         }
     }
 
-    public PartialEscapeClosure(SchedulePhase schedule, MetaAccessProvider metaAccess, Assumptions assumptions) {
+    public PartialEscapeClosure(SchedulePhase schedule, MetaAccessProvider metaAccess, ConstantReflectionProvider constantReflection, Assumptions assumptions) {
         super(schedule);
         this.usages = schedule.getCFG().graph.createNodeBitMap();
-        this.tool = new VirtualizerToolImpl(metaAccess, assumptions, this);
+        this.tool = new VirtualizerToolImpl(metaAccess, constantReflection, assumptions, this);
     }
 
     public Map<Invoke, Double> getHints() {
--- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PartialEscapePhase.java	Mon Apr 07 23:35:41 2014 +0200
+++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PartialEscapePhase.java	Mon Apr 07 16:09:17 2014 -0700
@@ -72,9 +72,9 @@
     @Override
     protected Closure<?> createEffectsClosure(PhaseContext context, SchedulePhase schedule) {
         if (readElimination) {
-            return new PEReadEliminationClosure(schedule, context.getMetaAccess(), context.getAssumptions());
+            return new PEReadEliminationClosure(schedule, context.getMetaAccess(), context.getConstantReflection(), context.getAssumptions());
         } else {
-            return new PartialEscapeClosure.Final(schedule, context.getMetaAccess(), context.getAssumptions());
+            return new PartialEscapeClosure.Final(schedule, context.getMetaAccess(), context.getConstantReflection(), context.getAssumptions());
         }
     }
 
--- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/VirtualizerToolImpl.java	Mon Apr 07 23:35:41 2014 +0200
+++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/VirtualizerToolImpl.java	Mon Apr 07 16:09:17 2014 -0700
@@ -40,11 +40,13 @@
 class VirtualizerToolImpl implements VirtualizerTool {
 
     private final MetaAccessProvider metaAccess;
+    private final ConstantReflectionProvider constantReflection;
     private final Assumptions assumptions;
     private final PartialEscapeClosure<?> closure;
 
-    VirtualizerToolImpl(MetaAccessProvider metaAccess, Assumptions assumptions, PartialEscapeClosure<?> closure) {
+    VirtualizerToolImpl(MetaAccessProvider metaAccess, ConstantReflectionProvider constantReflection, Assumptions assumptions, PartialEscapeClosure<?> closure) {
         this.metaAccess = metaAccess;
+        this.constantReflection = constantReflection;
         this.assumptions = assumptions;
         this.closure = closure;
     }
@@ -60,6 +62,10 @@
         return metaAccess;
     }
 
+    public ConstantReflectionProvider getConstantReflectionProvider() {
+        return constantReflection;
+    }
+
     @Override
     public Assumptions getAssumptions() {
         return assumptions;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.word/src/com/oracle/graal/word/nodes/SnippetLocationNode.java	Mon Apr 07 16:09:17 2014 -0700
@@ -0,0 +1,119 @@
+/*
+ * Copyright (c) 2013, 2013, 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 static com.oracle.graal.api.meta.LocationIdentity.*;
+
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.api.replacements.*;
+import com.oracle.graal.graph.*;
+import com.oracle.graal.graph.spi.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.extended.*;
+import com.oracle.graal.nodes.spi.*;
+import com.oracle.graal.nodes.type.*;
+
+/**
+ * Location node that can be used inside a snippet without having the elements (including the
+ * location identity and kind) as a snippet constant. Can represent locations in the form of [base +
+ * index * scale + disp]. When the location is created, all elements (base, index, scale, disp) are
+ * nodes. Both scale and disp must eventually canonicalize to {@link ConstantNode constants} so that
+ * this node can be canonicalized to a {@link IndexedLocationNode} or {@link ConstantLocationNode}.
+ */
+public final class SnippetLocationNode extends LocationNode implements Canonicalizable {
+
+    private final SnippetReflectionProvider snippetReflection;
+
+    @Input private ValueNode valueKind;
+    @Input(InputType.Association) private ValueNode locationIdentity;
+    @Input private ValueNode displacement;
+    @Input private ValueNode index;
+    @Input private ValueNode indexScaling;
+
+    public static SnippetLocationNode create(SnippetReflectionProvider snippetReflection, ValueNode identity, ValueNode kind, ValueNode displacement, ValueNode index, ValueNode indexScaling,
+                    Graph graph) {
+        return graph.unique(new SnippetLocationNode(snippetReflection, identity, kind, displacement, index, indexScaling));
+    }
+
+    private SnippetLocationNode(@InjectedNodeParameter SnippetReflectionProvider snippetReflection, ValueNode locationIdentity, ValueNode kind, ValueNode displacement) {
+        this(snippetReflection, locationIdentity, kind, displacement, null, null);
+    }
+
+    private SnippetLocationNode(@InjectedNodeParameter SnippetReflectionProvider snippetReflection, ValueNode locationIdentity, ValueNode kind, ValueNode displacement, ValueNode index,
+                    ValueNode indexScaling) {
+        super(StampFactory.object());
+        this.snippetReflection = snippetReflection;
+        this.valueKind = kind;
+        this.locationIdentity = locationIdentity;
+        this.displacement = displacement;
+        this.index = index;
+        this.indexScaling = indexScaling;
+    }
+
+    @Override
+    public Kind getValueKind() {
+        if (valueKind.isConstant()) {
+            return (Kind) snippetReflection.asObject(valueKind.asConstant());
+        }
+        throw new GraalInternalError("Cannot access kind yet because it is not constant: " + valueKind);
+    }
+
+    @Override
+    public LocationIdentity getLocationIdentity() {
+        if (locationIdentity.isConstant()) {
+            return (LocationIdentity) snippetReflection.asObject(locationIdentity.asConstant());
+        }
+        // We do not know our actual location identity yet, so be conservative.
+        return ANY_LOCATION;
+    }
+
+    @Override
+    public Node canonical(CanonicalizerTool tool) {
+        if (valueKind.isConstant() && locationIdentity.isConstant() && displacement.isConstant() && (indexScaling == null || indexScaling.isConstant())) {
+            Kind constKind = (Kind) snippetReflection.asObject(valueKind.asConstant());
+            LocationIdentity constLocation = (LocationIdentity) snippetReflection.asObject(locationIdentity.asConstant());
+            long constDisplacement = displacement.asConstant().asLong();
+            int constIndexScaling = indexScaling == null ? 0 : indexScaling.asConstant().asInt();
+
+            if (index == null || constIndexScaling == 0) {
+                return ConstantLocationNode.create(constLocation, constKind, constDisplacement, graph());
+            } else if (index.isConstant()) {
+                return ConstantLocationNode.create(constLocation, constKind, index.asConstant().asLong() * constIndexScaling + constDisplacement, graph());
+            } else {
+                return IndexedLocationNode.create(constLocation, constKind, constDisplacement, index, graph(), constIndexScaling);
+            }
+        }
+        return this;
+    }
+
+    @Override
+    public Value generateAddress(NodeLIRBuilderTool gen, Value base) {
+        throw new GraalInternalError("locationIdentity must be a constant so that this node can be canonicalized: " + locationIdentity);
+    }
+
+    @NodeIntrinsic
+    public static native Location constantLocation(LocationIdentity identity, Kind kind, long displacement);
+
+    @NodeIntrinsic
+    public static native Location indexedLocation(LocationIdentity identity, Kind kind, long displacement, int index, int indexScaling);
+}
--- a/graal/com.oracle.graal.word/src/com/oracle/graal/word/phases/WordTypeRewriterPhase.java	Mon Apr 07 23:35:41 2014 +0200
+++ b/graal/com.oracle.graal.word/src/com/oracle/graal/word/phases/WordTypeRewriterPhase.java	Mon Apr 07 16:09:17 2014 -0700
@@ -27,6 +27,7 @@
 import java.lang.reflect.*;
 
 import com.oracle.graal.api.meta.*;
+import com.oracle.graal.api.replacements.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.HeapAccess.BarrierType;
@@ -49,13 +50,15 @@
 public class WordTypeRewriterPhase extends Phase {
 
     protected final MetaAccessProvider metaAccess;
+    protected final SnippetReflectionProvider snippetReflection;
     protected final ResolvedJavaType wordBaseType;
     protected final ResolvedJavaType wordImplType;
     protected final ResolvedJavaType objectAccessType;
     protected final Kind wordKind;
 
-    public WordTypeRewriterPhase(MetaAccessProvider metaAccess, Kind wordKind) {
+    public WordTypeRewriterPhase(MetaAccessProvider metaAccess, SnippetReflectionProvider snippetReflection, Kind wordKind) {
         this.metaAccess = metaAccess;
+        this.snippetReflection = snippetReflection;
         this.wordKind = wordKind;
         this.wordBaseType = metaAccess.lookupJavaType(WordBase.class);
         this.wordImplType = metaAccess.lookupJavaType(Word.class);
@@ -86,7 +89,7 @@
             if (node.isConstant()) {
                 ConstantNode oldConstant = (ConstantNode) node;
                 assert oldConstant.getValue().getKind() == Kind.Object;
-                WordBase value = (WordBase) oldConstant.getValue().asObject();
+                WordBase value = (WordBase) snippetReflection.asObject(oldConstant.getValue());
                 ConstantNode newConstant = ConstantNode.forIntegerKind(wordKind, value.rawValue(), node.graph());
                 graph.replaceFloating(oldConstant, newConstant);
 
@@ -221,7 +224,7 @@
                 assert arguments.size() == 3;
                 Kind readKind = asKind(callTargetNode.returnType());
                 LocationNode location = makeLocation(graph, arguments.get(1), readKind, ANY_LOCATION);
-                BarrierType barrierType = (BarrierType) arguments.get(2).asConstant().asObject();
+                BarrierType barrierType = (BarrierType) snippetReflection.asObject(arguments.get(2).asConstant());
                 replace(invoke, readOp(graph, arguments.get(0), invoke, location, barrierType, true));
                 break;
             }
@@ -359,10 +362,10 @@
 
     private LocationNode makeLocation(StructuredGraph graph, ValueNode offset, Kind readKind, ValueNode locationIdentity) {
         if (locationIdentity.isConstant()) {
-            return makeLocation(graph, offset, readKind, (LocationIdentity) locationIdentity.asConstant().asObject());
+            return makeLocation(graph, offset, readKind, (LocationIdentity) snippetReflection.asObject(locationIdentity.asConstant()));
         }
-        return SnippetLocationNode.create(locationIdentity, ConstantNode.forObject(readKind, metaAccess, graph), ConstantNode.forLong(0, graph), fromSigned(graph, offset),
-                        ConstantNode.forInt(1, graph), graph);
+        return SnippetLocationNode.create(snippetReflection, locationIdentity, ConstantNode.forConstant(snippetReflection.forObject(readKind), metaAccess, graph), ConstantNode.forLong(0, graph),
+                        fromSigned(graph, offset), ConstantNode.forInt(1, graph), graph);
     }
 
     protected LocationNode makeLocation(StructuredGraph graph, ValueNode offset, Kind readKind, LocationIdentity locationIdentity) {
--- a/graal/com.oracle.graal.word/src/com/oracle/graal/word/phases/WordTypeVerificationPhase.java	Mon Apr 07 23:35:41 2014 +0200
+++ b/graal/com.oracle.graal.word/src/com/oracle/graal/word/phases/WordTypeVerificationPhase.java	Mon Apr 07 16:09:17 2014 -0700
@@ -25,6 +25,7 @@
 import java.lang.reflect.*;
 
 import com.oracle.graal.api.meta.*;
+import com.oracle.graal.api.replacements.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.graph.Node.NodeIntrinsic;
 import com.oracle.graal.nodes.*;
@@ -44,8 +45,8 @@
 
     private final WordTypeRewriterPhase wordAccess;
 
-    public WordTypeVerificationPhase(MetaAccessProvider metaAccess, Kind wordKind) {
-        this.wordAccess = new WordTypeRewriterPhase(metaAccess, wordKind);
+    public WordTypeVerificationPhase(MetaAccessProvider metaAccess, SnippetReflectionProvider snippetReflection, Kind wordKind) {
+        this.wordAccess = new WordTypeRewriterPhase(metaAccess, snippetReflection, wordKind);
     }
 
     @Override
--- a/src/share/vm/classfile/systemDictionary.hpp	Mon Apr 07 23:35:41 2014 +0200
+++ b/src/share/vm/classfile/systemDictionary.hpp	Mon Apr 07 16:09:17 2014 -0700
@@ -204,6 +204,8 @@
   do_klass(HotSpotResolvedJavaMethod_klass,       com_oracle_graal_hotspot_meta_HotSpotResolvedJavaMethod,      Opt) \
   do_klass(HotSpotResolvedObjectType_klass,       com_oracle_graal_hotspot_meta_HotSpotResolvedObjectType,      Opt) \
   do_klass(HotSpotMonitorValue_klass,             com_oracle_graal_hotspot_meta_HotSpotMonitorValue,            Opt) \
+  do_klass(HotSpotObjectConstant_klass,           com_oracle_graal_hotspot_meta_HotSpotObjectConstant,          Opt) \
+  do_klass(HotSpotMetaspaceConstant_klass,        com_oracle_graal_hotspot_meta_HotSpotMetaspaceConstant,       Opt) \
   /* graal.api.code */                                                                                               \
   do_klass(Assumptions_klass,                     com_oracle_graal_api_code_Assumptions,                        Opt) \
   do_klass(Assumptions_ConcreteMethod_klass,      com_oracle_graal_api_code_Assumptions_ConcreteMethod,         Opt) \
@@ -231,6 +233,8 @@
   do_klass(SpeculationLog_klass,                  com_oracle_graal_api_code_SpeculationLog,                     Opt) \
   /* graal.api.meta */                                                                                               \
   do_klass(Constant_klass,                        com_oracle_graal_api_meta_Constant,                           Opt) \
+  do_klass(PrimitiveConstant_klass,               com_oracle_graal_api_meta_PrimitiveConstant,                  Opt) \
+  do_klass(NullConstant_klass,                    com_oracle_graal_api_meta_NullConstant,                       Opt) \
   do_klass(ExceptionHandler_klass,                com_oracle_graal_api_meta_ExceptionHandler,                   Opt) \
   do_klass(Kind_klass,                            com_oracle_graal_api_meta_Kind,                               Opt) \
   do_klass(JavaMethod_klass,                      com_oracle_graal_api_meta_JavaMethod,                         Opt) \
--- a/src/share/vm/classfile/vmSymbols.hpp	Mon Apr 07 23:35:41 2014 +0200
+++ b/src/share/vm/classfile/vmSymbols.hpp	Mon Apr 07 16:09:17 2014 -0700
@@ -315,8 +315,12 @@
   template(com_oracle_graal_hotspot_meta_HotSpotResolvedJavaMethod,  "com/oracle/graal/hotspot/meta/HotSpotResolvedJavaMethod")       \
   template(com_oracle_graal_hotspot_meta_HotSpotResolvedObjectType,  "com/oracle/graal/hotspot/meta/HotSpotResolvedObjectType")       \
   template(com_oracle_graal_hotspot_meta_HotSpotMonitorValue,        "com/oracle/graal/hotspot/meta/HotSpotMonitorValue")             \
+  template(com_oracle_graal_hotspot_meta_HotSpotObjectConstant,      "com/oracle/graal/hotspot/meta/HotSpotObjectConstant")           \
+  template(com_oracle_graal_hotspot_meta_HotSpotMetaspaceConstant,   "com/oracle/graal/hotspot/meta/HotSpotMetaspaceConstant")        \
   /* graal.api.meta */                                                                                                                \
   template(com_oracle_graal_api_meta_Constant,                       "com/oracle/graal/api/meta/Constant")                            \
+  template(com_oracle_graal_api_meta_PrimitiveConstant,              "com/oracle/graal/api/meta/PrimitiveConstant")                   \
+  template(com_oracle_graal_api_meta_NullConstant,                   "com/oracle/graal/api/meta/NullConstant")                   \
   template(com_oracle_graal_api_meta_ConstantPool,                   "com/oracle/graal/api/meta/ConstantPool")                        \
   template(com_oracle_graal_api_meta_ExceptionHandler,               "com/oracle/graal/api/meta/ExceptionHandler")                    \
   template(com_oracle_graal_api_meta_JavaMethod,                     "com/oracle/graal/api/meta/JavaMethod")                          \
@@ -352,7 +356,7 @@
   /* graal.gpu */                                                                                                                     \
   template(com_oracle_graal_gpu_ExternalCompilationResult,           "com/oracle/graal/gpu/ExternalCompilationResult")                \
   /* graal.truffle */                                                                                                                 \
-  template(com_oracle_graal_truffle_GraalTruffleRuntime,             "com/oracle/graal/truffle/GraalTruffleRuntime")                  \
+  template(com_oracle_graal_truffle_hotspot_HotSpotTruffleRuntime,   "com/oracle/graal/truffle/hotspot/HotSpotTruffleRuntime")        \
   template(startCompiler_name,                    "startCompiler")                                                                    \
   template(bootstrap_name,                        "bootstrap")                                                                        \
   template(compileTheWorld_name,                  "compileTheWorld")                                                                  \
@@ -367,7 +371,7 @@
   template(runtime_name,                          "runtime")                                                                          \
   template(runtime_signature,                     "()Lcom/oracle/graal/hotspot/HotSpotGraalRuntime;")                                 \
   template(makeInstance_name,                     "makeInstance")                                                                     \
-  template(makeInstance_signature,                "()Lcom/oracle/graal/truffle/GraalTruffleRuntime;")                                 \
+  template(makeInstance_signature,                "()Lcom/oracle/graal/truffle/hotspot/HotSpotTruffleRuntime;")                       \
   template(initialize_name,                       "initialize")                                                                       \
   template(forObject_name,                        "forObject")                                                                        \
   template(callbackInternal_name,                 "callbackInternal")                                                                 \
--- a/src/share/vm/graal/graalCodeInstaller.cpp	Mon Apr 07 23:35:41 2014 +0200
+++ b/src/share/vm/graal/graalCodeInstaller.cpp	Mon Apr 07 16:09:17 2014 -0700
@@ -180,14 +180,14 @@
 
 // Records any Metadata values embedded in a Constant (e.g., the value returned by HotSpotResolvedObjectType.klass()).
 static void record_metadata_in_constant(oop constant, OopRecorder* oop_recorder) {
-  char kind = Kind::typeChar(Constant::kind(constant));
-  char wordKind = 'j';
-  if (kind == wordKind) {
-    oop obj = Constant::object(constant);
-    jlong prim = Constant::primitive(constant);
-    if (obj != NULL) {
-      record_metadata_reference(obj, prim, false, oop_recorder);
-    }
+  if (constant->is_a(HotSpotMetaspaceConstant::klass())) {
+    oop obj = HotSpotMetaspaceConstant::metaspaceObject(constant);
+    jlong prim = HotSpotMetaspaceConstant::primitive(constant);
+    assert(Kind::typeChar(Constant::kind(constant)) == 'j', "must have word kind");
+    assert(obj != NULL, "must have an object");
+    assert(prim != 0, "must have a primitive value");
+
+    record_metadata_reference(obj, prim, false, oop_recorder);
   }
 }
 
@@ -263,17 +263,19 @@
     return value;
   } else if (value->is_a(Constant::klass())){
     record_metadata_in_constant(value, oop_recorder);
-    jlong prim = Constant::primitive(value);
     if (type == T_INT || type == T_FLOAT || type == T_SHORT || type == T_CHAR || type == T_BOOLEAN || type == T_BYTE) {
+      jlong prim = PrimitiveConstant::primitive(value);
       return new ConstantIntValue(*(jint*)&prim);
     } else if (type == T_LONG || type == T_DOUBLE) {
+      jlong prim = PrimitiveConstant::primitive(value);
       second = new ConstantIntValue(0);
       return new ConstantLongValue(prim);
     } else if (type == T_OBJECT) {
-      oop obj = Constant::object(value);
-      if (obj == NULL) {
+      if (value->is_a(NullConstant::klass())) {
         return new ConstantOopWriteValue(NULL);
       } else {
+        oop obj = HotSpotObjectConstant::object(value);
+        assert(obj != NULL, "null value must be in NullConstant");
         return new ConstantOopWriteValue(JNIHandles::make_local(obj));
       }
     } else if (type == T_ADDRESS) {
--- a/src/share/vm/graal/graalJavaAccess.hpp	Mon Apr 07 23:35:41 2014 +0200
+++ b/src/share/vm/graal/graalJavaAccess.hpp	Mon Apr 07 16:09:17 2014 -0700
@@ -201,8 +201,18 @@
   end_class                                                                                                                                                    \
   start_class(Constant)                                                                                                                                        \
     oop_field(Constant, kind, "Lcom/oracle/graal/api/meta/Kind;")                                                                                              \
-    oop_field(Constant, object, "Ljava/lang/Object;")                                                                                                          \
-    long_field(Constant, primitive)                                                                                                                            \
+  end_class                                                                                                                                                    \
+  start_class(PrimitiveConstant)                                                                                                                                        \
+    long_field(PrimitiveConstant, primitive)                                                                                                                            \
+  end_class                                                                                                                                                    \
+  start_class(NullConstant)                                                                                                                                        \
+  end_class                                                                                                                                                    \
+  start_class(HotSpotObjectConstant)                                                                                                                                        \
+    oop_field(HotSpotObjectConstant, object, "Ljava/lang/Object;")                                                                                                          \
+  end_class                                                                                                                                                    \
+  start_class(HotSpotMetaspaceConstant)                                                                                                                                        \
+    long_field(HotSpotMetaspaceConstant, primitive)                                                                                                                            \
+    oop_field(HotSpotMetaspaceConstant, metaspaceObject, "Ljava/lang/Object;")                                                                                                          \
   end_class                                                                                                                                                    \
   start_class(Kind)                                                                                                                                            \
     char_field(Kind, typeChar)                                                                                                                                 \
--- a/src/share/vm/graal/graalVMToCompiler.cpp	Mon Apr 07 23:35:41 2014 +0200
+++ b/src/share/vm/graal/graalVMToCompiler.cpp	Mon Apr 07 16:09:17 2014 -0700
@@ -49,12 +49,12 @@
 }
 
 Handle VMToCompiler::truffleRuntime() {
-  Symbol* name = vmSymbols::com_oracle_graal_truffle_GraalTruffleRuntime();
+  Symbol* name = vmSymbols::com_oracle_graal_truffle_hotspot_HotSpotTruffleRuntime();
   KlassHandle klass = loadClass(name);
 
   JavaValue result(T_OBJECT);
   JavaCalls::call_static(&result, klass, vmSymbols::makeInstance_name(), vmSymbols::makeInstance_signature(), Thread::current());
-  check_pending_exception("Couldn't initialize GraalTruffleRuntime");
+  check_pending_exception("Couldn't initialize HotSpotTruffleRuntime");
   return Handle((oop) result.get_jobject());
 }