changeset 18175:cf09e921458f

Merge
author Tom Rodriguez <tom.rodriguez@oracle.com>
date Mon, 27 Oct 2014 13:39:12 -0700
parents 933b3de3c5b0 (diff) 26d381457145 (current diff)
children c2270ad35f57
files
diffstat 22 files changed, 1250 insertions(+), 57 deletions(-) [+]
line wrap: on
line diff
--- a/CHANGELOG.md	Fri Oct 24 13:01:16 2014 -0700
+++ b/CHANGELOG.md	Mon Oct 27 13:39:12 2014 -0700
@@ -14,6 +14,7 @@
 * Renamed DirectCallNode#isSplittable to DirectCallNode#isCallTargetCloningAllowed
 * Renamed DirectCallNode#split to DirectCallNode#cloneCallTarget
 * Renamed DirectCallNode#isSplit to DirectCallNode#isCallTargetCloned
+* Added PrimitiveValueProfile.
 * ...
 
 ## Version 0.5
--- a/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/HotSpotResolvedJavaFieldTest.java	Fri Oct 24 13:01:16 2014 -0700
+++ b/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/HotSpotResolvedJavaFieldTest.java	Mon Oct 27 13:39:12 2014 -0700
@@ -47,7 +47,7 @@
     @Test
     public void testModifiersForInternal() {
         for (Class<?> c : classesWithInternalFields) {
-            ResolvedJavaType type = HotSpotResolvedObjectType.fromClass(c);
+            HotSpotResolvedObjectType type = HotSpotResolvedObjectType.fromObjectClass(c);
             for (ResolvedJavaField field : type.getInstanceFields(false)) {
                 if (field.isInternal()) {
                     Assert.assertEquals(0, ~getReflectionFieldModifiers() & field.getModifiers());
@@ -63,7 +63,7 @@
     @Test
     public void testCachingForInternalFields() {
         for (Class<?> c : classesWithInternalFields) {
-            HotSpotResolvedObjectType type = (HotSpotResolvedObjectType) HotSpotResolvedObjectType.fromClass(c);
+            HotSpotResolvedObjectType type = HotSpotResolvedObjectType.fromObjectClass(c);
             for (ResolvedJavaField field : type.getInstanceFields(false)) {
                 if (field.isInternal()) {
                     HotSpotResolvedJavaField expected = (HotSpotResolvedJavaField) field;
--- a/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/HotSpotResolvedObjectTypeTest.java	Fri Oct 24 13:01:16 2014 -0700
+++ b/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/HotSpotResolvedObjectTypeTest.java	Mon Oct 27 13:39:12 2014 -0700
@@ -33,7 +33,7 @@
 
     @Test
     public void testGetSourceFileName() throws Throwable {
-        Assert.assertEquals("Object.java", HotSpotResolvedObjectType.fromClass(Object.class).getSourceFileName());
-        Assert.assertEquals("HotSpotResolvedObjectTypeTest.java", HotSpotResolvedObjectType.fromClass(this.getClass()).getSourceFileName());
+        Assert.assertEquals("Object.java", HotSpotResolvedObjectType.fromObjectClass(Object.class).getSourceFileName());
+        Assert.assertEquals("HotSpotResolvedObjectTypeTest.java", HotSpotResolvedObjectType.fromObjectClass(this.getClass()).getSourceFileName());
     }
 }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompileTheWorld.java	Fri Oct 24 13:01:16 2014 -0700
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompileTheWorld.java	Mon Oct 27 13:39:12 2014 -0700
@@ -25,6 +25,7 @@
 import static com.oracle.graal.compiler.common.GraalOptions.*;
 import static com.oracle.graal.debug.internal.MemUseTrackerImpl.*;
 import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*;
+import static com.oracle.graal.hotspot.meta.HotSpotResolvedObjectType.*;
 import static com.oracle.graal.nodes.StructuredGraph.*;
 
 import java.io.*;
@@ -276,7 +277,7 @@
 
                         // Pre-load all classes in the constant pool.
                         try {
-                            HotSpotResolvedObjectType objectType = (HotSpotResolvedObjectType) HotSpotResolvedObjectType.fromClass(javaClass);
+                            HotSpotResolvedObjectType objectType = fromObjectClass(javaClass);
                             ConstantPool constantPool = objectType.constantPool();
                             for (int cpi = 1; cpi < constantPool.length(); cpi++) {
                                 constantPool.loadReferencedType(cpi, Bytecodes.LDC);
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotConstantPool.java	Fri Oct 24 13:01:16 2014 -0700
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotConstantPool.java	Mon Oct 27 13:39:12 2014 -0700
@@ -131,7 +131,7 @@
      */
     private HotSpotResolvedObjectType getHolder() {
         final long metaspaceKlass = unsafe.getAddress(metaspaceConstantPool + runtime().getConfig().constantPoolHolderOffset);
-        return (HotSpotResolvedObjectType) HotSpotResolvedObjectType.fromMetaspaceKlass(metaspaceKlass);
+        return HotSpotResolvedObjectType.fromMetaspaceKlass(metaspaceKlass);
     }
 
     /**
@@ -462,7 +462,7 @@
             String name = getNameRefAt(index);
             String signature = getSignatureRefAt(index);
             if (opcode == Bytecodes.INVOKEDYNAMIC) {
-                JavaType holder = HotSpotResolvedJavaType.fromClass(MethodHandle.class);
+                HotSpotResolvedObjectType holder = HotSpotResolvedObjectType.fromObjectClass(MethodHandle.class);
                 return new HotSpotMethodUnresolved(name, signature, holder);
             } else {
                 final int klassIndex = getKlassRefIndexAt(index);
@@ -504,7 +504,7 @@
                  */
                 return new HotSpotUnresolvedField(holder, name, type);
             }
-            HotSpotResolvedObjectType resolvedHolder = (HotSpotResolvedObjectType) HotSpotResolvedObjectType.fromMetaspaceKlass(metaspaceKlass);
+            HotSpotResolvedObjectType resolvedHolder = HotSpotResolvedObjectType.fromMetaspaceKlass(metaspaceKlass);
             final int flags = (int) info[0];
             final long offset = info[1];
             return resolvedHolder.createField(name, type, offset, flags);
@@ -554,7 +554,7 @@
             case UnresolvedClass:
             case UnresolvedClassInError:
                 final long metaspaceKlass = runtime().getCompilerToVM().constantPoolKlassAt(metaspaceConstantPool, index);
-                HotSpotResolvedObjectType type = (HotSpotResolvedObjectType) HotSpotResolvedObjectType.fromMetaspaceKlass(metaspaceKlass);
+                HotSpotResolvedObjectType type = HotSpotResolvedObjectType.fromMetaspaceKlass(metaspaceKlass);
                 Class<?> klass = type.mirror();
                 if (!klass.isPrimitive() && !klass.isArray()) {
                     unsafe.ensureClassInitialized(klass);
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMetaAccessProvider.java	Fri Oct 24 13:01:16 2014 -0700
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMetaAccessProvider.java	Mon Oct 27 13:39:12 2014 -0700
@@ -23,6 +23,8 @@
 package com.oracle.graal.hotspot.meta;
 
 import static com.oracle.graal.compiler.common.UnsafeAccess.*;
+import static com.oracle.graal.hotspot.meta.HotSpotResolvedJavaType.*;
+import static com.oracle.graal.hotspot.meta.HotSpotResolvedObjectType.*;
 
 import java.lang.reflect.*;
 
@@ -43,19 +45,19 @@
         this.runtime = runtime;
     }
 
-    public ResolvedJavaType lookupJavaType(Class<?> clazz) {
+    public HotSpotResolvedJavaType lookupJavaType(Class<?> clazz) {
         if (clazz == null) {
             throw new IllegalArgumentException("Class parameter was null");
         }
-        return HotSpotResolvedObjectType.fromClass(clazz);
+        return fromClass(clazz);
     }
 
-    public ResolvedJavaType lookupJavaType(Constant constant) {
+    public HotSpotResolvedObjectType lookupJavaType(Constant constant) {
         if (constant.isNull() || !(constant instanceof HotSpotObjectConstant)) {
             return null;
         }
         Object o = HotSpotObjectConstant.asObject(constant);
-        return HotSpotResolvedObjectType.fromClass(o.getClass());
+        return fromObjectClass(o.getClass());
     }
 
     public Signature parseMethodDescriptor(String signature) {
@@ -113,11 +115,11 @@
         final int modifiers = reflectionField.getModifiers();
         final long offset = Modifier.isStatic(modifiers) ? unsafe.staticFieldOffset(reflectionField) : unsafe.objectFieldOffset(reflectionField);
 
-        ResolvedJavaType holder = HotSpotResolvedObjectType.fromClass(fieldHolder);
-        ResolvedJavaType type = HotSpotResolvedObjectType.fromClass(fieldType);
+        HotSpotResolvedObjectType holder = fromObjectClass(fieldHolder);
+        HotSpotResolvedJavaType type = fromClass(fieldType);
 
         if (offset != -1) {
-            HotSpotResolvedObjectType resolved = (HotSpotResolvedObjectType) holder;
+            HotSpotResolvedObjectType resolved = holder;
             return resolved.createField(name, type, offset, modifiers);
         } else {
             throw GraalInternalError.shouldNotReachHere("unresolved field " + reflectionField);
@@ -293,7 +295,7 @@
     @Override
     public long getMemorySize(Constant constant) {
         if (constant.getKind() == Kind.Object) {
-            HotSpotResolvedObjectType lookupJavaType = (HotSpotResolvedObjectType) this.lookupJavaType(constant);
+            HotSpotResolvedObjectType lookupJavaType = this.lookupJavaType(constant);
 
             if (lookupJavaType == null) {
                 return 0;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMethodData.java	Fri Oct 24 13:01:16 2014 -0700
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMethodData.java	Mon Oct 27 13:39:12 2014 -0700
@@ -492,7 +492,7 @@
             outer: for (int i = 0; i < typeProfileWidth; i++) {
                 long receiverKlass = data.readWord(position, getTypeOffset(i));
                 if (receiverKlass != 0) {
-                    ResolvedJavaType klass = HotSpotResolvedObjectType.fromMetaspaceKlass(receiverKlass);
+                    HotSpotResolvedObjectType klass = HotSpotResolvedObjectType.fromMetaspaceKlass(receiverKlass);
                     long count = data.readUnsignedInt(position, getTypeCountOffset(i));
                     /*
                      * Because of races in the profile collection machinery it's possible for a
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMethodHandleAccessProvider.java	Fri Oct 24 13:01:16 2014 -0700
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMethodHandleAccessProvider.java	Mon Oct 27 13:39:12 2014 -0700
@@ -23,6 +23,8 @@
 package com.oracle.graal.hotspot.meta;
 
 import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*;
+import static com.oracle.graal.hotspot.meta.HotSpotResolvedJavaType.*;
+import static com.oracle.graal.hotspot.meta.HotSpotResolvedObjectType.*;
 
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.api.replacements.*;
@@ -51,7 +53,7 @@
          */
         private static ResolvedJavaField findFieldInClass(String className, String fieldName) throws ClassNotFoundException {
             Class<?> clazz = Class.forName(className);
-            ResolvedJavaType type = HotSpotResolvedObjectType.fromClass(clazz);
+            ResolvedJavaType type = fromClass(clazz);
             ResolvedJavaField[] fields = type.getInstanceFields(false);
             for (ResolvedJavaField field : fields) {
                 if (field.getName().equals(fieldName)) {
@@ -63,7 +65,7 @@
 
         private static ResolvedJavaMethod findMethodInClass(String className, String methodName) throws ClassNotFoundException {
             Class<?> clazz = Class.forName(className);
-            ResolvedJavaType type = HotSpotResolvedObjectType.fromClass(clazz);
+            HotSpotResolvedObjectType type = fromObjectClass(clazz);
             ResolvedJavaMethod result = null;
             for (ResolvedJavaMethod method : type.getDeclaredMethods()) {
                 if (method.getName().equals(methodName)) {
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaField.java	Fri Oct 24 13:01:16 2014 -0700
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaField.java	Mon Oct 27 13:39:12 2014 -0700
@@ -255,7 +255,7 @@
         if (isStatic()) {
             return false;
         }
-        return getDeclaringClass().isAssignableFrom(HotSpotResolvedObjectType.fromClass(object.getClass()));
+        return getDeclaringClass().isAssignableFrom(HotSpotResolvedObjectType.fromObjectClass(object.getClass()));
     }
 
     @Override
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaMethod.java	Fri Oct 24 13:01:16 2014 -0700
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaMethod.java	Mon Oct 27 13:39:12 2014 -0700
@@ -70,7 +70,7 @@
         final long metaspaceConstMethod = unsafe.getAddress(metaspaceMethod + config.methodConstMethodOffset);
         final long metaspaceConstantPool = unsafe.getAddress(metaspaceConstMethod + config.constMethodConstantsOffset);
         final long metaspaceKlass = unsafe.getAddress(metaspaceConstantPool + config.constantPoolHolderOffset);
-        return (HotSpotResolvedObjectType) HotSpotResolvedObjectType.fromMetaspaceKlass(metaspaceKlass);
+        return HotSpotResolvedObjectType.fromMetaspaceKlass(metaspaceKlass);
     }
 
     /**
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaType.java	Fri Oct 24 13:01:16 2014 -0700
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaType.java	Mon Oct 27 13:39:12 2014 -0700
@@ -32,11 +32,11 @@
 
     /**
      * Gets the Graal mirror for a {@link Class} object.
-     * 
+     *
      * @return the {@link HotSpotResolvedJavaType} corresponding to {@code javaClass}
      */
-    public static ResolvedJavaType fromClass(Class<?> javaClass) {
-        return runtime().fromClass(javaClass);
+    public static HotSpotResolvedJavaType fromClass(Class<?> javaClass) {
+        return (HotSpotResolvedJavaType) runtime().fromClass(javaClass);
     }
 
     public HotSpotResolvedJavaType(String name) {
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedObjectType.java	Fri Oct 24 13:01:16 2014 -0700
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedObjectType.java	Mon Oct 27 13:39:12 2014 -0700
@@ -50,17 +50,26 @@
     private HashMap<Long, HotSpotResolvedJavaField> fieldCache;
     private HashMap<Long, HotSpotResolvedJavaMethod> methodCache;
     private HotSpotResolvedJavaField[] instanceFields;
-    private ResolvedJavaType[] interfaces;
+    private HotSpotResolvedObjectType[] interfaces;
     private ConstantPool constantPool;
-    private ResolvedJavaType arrayOfType;
+    private HotSpotResolvedObjectType arrayOfType;
+
+    /**
+     * Gets the Graal mirror for a {@link Class} object.
+     *
+     * @return the {@link HotSpotResolvedJavaType} corresponding to {@code javaClass}
+     */
+    public static HotSpotResolvedObjectType fromObjectClass(Class<?> javaClass) {
+        return (HotSpotResolvedObjectType) runtime().fromClass(javaClass);
+    }
 
     /**
      * Gets the Graal mirror from a HotSpot metaspace Klass native object.
      *
      * @param metaspaceKlass a metaspace Klass object boxed in a {@link Constant}
-     * @return the {@link ResolvedJavaType} corresponding to {@code klassConstant}
+     * @return the {@link HotSpotResolvedObjectType} corresponding to {@code klassConstant}
      */
-    public static ResolvedJavaType fromMetaspaceKlass(Constant metaspaceKlass) {
+    public static HotSpotResolvedObjectType fromMetaspaceKlass(Constant metaspaceKlass) {
         assert metaspaceKlass.getKind() == Kind.Long;
         return fromMetaspaceKlass(metaspaceKlass.asLong());
     }
@@ -71,11 +80,11 @@
      * @param metaspaceKlass a metaspace Klass object
      * @return the {@link ResolvedJavaType} corresponding to {@code metaspaceKlass}
      */
-    public static ResolvedJavaType fromMetaspaceKlass(long metaspaceKlass) {
+    public static HotSpotResolvedObjectType fromMetaspaceKlass(long metaspaceKlass) {
         assert metaspaceKlass != 0;
         Class<?> javaClass = runtime().getCompilerToVM().getJavaMirror(metaspaceKlass);
         assert javaClass != null;
-        return fromClass(javaClass);
+        return fromObjectClass(javaClass);
     }
 
     /**
@@ -83,8 +92,8 @@
      *
      * <p>
      * <b>NOTE</b>: Creating an instance of this class does not install the mirror for the
-     * {@link Class} type. Use {@link #fromClass(Class)}, {@link #fromMetaspaceKlass(Constant)} or
-     * {@link #fromMetaspaceKlass(long)} instead.
+     * {@link Class} type. Use {@link #fromObjectClass(Class)},
+     * {@link #fromMetaspaceKlass(Constant)} or {@link #fromMetaspaceKlass(long)} instead.
      * </p>
      *
      * @param javaClass the Class to create the mirror for
@@ -125,7 +134,7 @@
     @Override
     public ResolvedJavaType getArrayClass() {
         if (arrayOfType == null) {
-            arrayOfType = fromClass(Array.newInstance(mirror(), 0).getClass());
+            arrayOfType = fromObjectClass(Array.newInstance(mirror(), 0).getClass());
         }
         return arrayOfType;
     }
@@ -149,7 +158,7 @@
                 return null;
             }
 
-            HotSpotResolvedObjectType type = (HotSpotResolvedObjectType) fromMetaspaceKlass(implementorMetaspaceKlass);
+            HotSpotResolvedObjectType type = fromMetaspaceKlass(implementorMetaspaceKlass);
 
             /*
              * If the implementor field contains itself that indicates that the interface has more
@@ -167,7 +176,7 @@
                 if (subklass == 0 || unsafeReadWord(subklass + config.nextSiblingOffset) != 0) {
                     return null;
                 }
-                type = (HotSpotResolvedObjectType) fromMetaspaceKlass(subklass);
+                type = fromMetaspaceKlass(subklass);
             }
             if (type.isAbstract() || type.isInterface() || !type.isLeafClass()) {
                 return null;
@@ -199,16 +208,16 @@
     @Override
     public HotSpotResolvedObjectType getSuperclass() {
         Class<?> javaSuperclass = mirror().getSuperclass();
-        return javaSuperclass == null ? null : (HotSpotResolvedObjectType) fromClass(javaSuperclass);
+        return javaSuperclass == null ? null : (HotSpotResolvedObjectType) fromObjectClass(javaSuperclass);
     }
 
     @Override
-    public ResolvedJavaType[] getInterfaces() {
+    public HotSpotResolvedObjectType[] getInterfaces() {
         if (interfaces == null) {
             Class<?>[] javaInterfaces = mirror().getInterfaces();
-            ResolvedJavaType[] result = new ResolvedJavaType[javaInterfaces.length];
+            HotSpotResolvedObjectType[] result = new HotSpotResolvedObjectType[javaInterfaces.length];
             for (int i = 0; i < javaInterfaces.length; i++) {
-                result[i] = fromClass(javaInterfaces[i]);
+                result[i] = fromObjectClass(javaInterfaces[i]);
             }
             interfaces = result;
         }
@@ -219,12 +228,12 @@
         if (isArray()) {
             ResolvedJavaType componentType = getComponentType();
             if (mirror() == Object[].class || componentType.isPrimitive()) {
-                return (HotSpotResolvedObjectType) fromClass(Object.class);
+                return fromObjectClass(Object.class);
             }
             return (HotSpotResolvedObjectType) ((HotSpotResolvedObjectType) componentType).getSupertype().getArrayClass();
         }
         if (isInterface()) {
-            return (HotSpotResolvedObjectType) fromClass(Object.class);
+            return fromObjectClass(Object.class);
         }
         return getSuperclass();
     }
@@ -809,9 +818,9 @@
     }
 
     @Override
-    public ResolvedJavaType getEnclosingType() {
+    public HotSpotResolvedObjectType getEnclosingType() {
         final Class<?> encl = mirror().getEnclosingClass();
-        return encl == null ? null : fromClass(encl);
+        return encl == null ? null : fromObjectClass(encl);
     }
 
     @Override
@@ -854,7 +863,7 @@
         return "HotSpotType<" + getName() + ", resolved>";
     }
 
-    private static final ResolvedJavaType trustedInterfaceType = fromClass(TrustedInterface.class);
+    private static final HotSpotResolvedObjectType trustedInterfaceType = fromObjectClass(TrustedInterface.class);
 
     @Override
     public boolean isTrustedInterfaceType() {
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedPrimitiveType.java	Fri Oct 24 13:01:16 2014 -0700
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedPrimitiveType.java	Mon Oct 27 13:39:12 2014 -0700
@@ -71,12 +71,12 @@
     }
 
     @Override
-    public ResolvedJavaType getArrayClass() {
+    public HotSpotResolvedObjectType getArrayClass() {
         if (kind == Kind.Void) {
             return null;
         }
         Class<?> javaArrayMirror = Array.newInstance(mirror(), 0).getClass();
-        return HotSpotResolvedObjectType.fromClass(javaArrayMirror);
+        return HotSpotResolvedObjectType.fromObjectClass(javaArrayMirror);
     }
 
     public ResolvedJavaType getElementalType() {
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassCastNode.java	Fri Oct 24 13:01:16 2014 -0700
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassCastNode.java	Mon Oct 27 13:39:12 2014 -0700
@@ -67,7 +67,7 @@
         if (forJavaClass.isConstant()) {
             Class<?> c = (Class<?>) HotSpotObjectConstant.asObject(forJavaClass.asConstant());
             if (c != null && !c.isPrimitive()) {
-                HotSpotResolvedObjectType type = (HotSpotResolvedObjectType) HotSpotResolvedObjectType.fromClass(c);
+                HotSpotResolvedObjectType type = HotSpotResolvedObjectType.fromObjectClass(c);
                 return CheckCastNode.create(type, forObject, null, false);
             }
         }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassIsInstanceNode.java	Fri Oct 24 13:01:16 2014 -0700
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassIsInstanceNode.java	Mon Oct 27 13:39:12 2014 -0700
@@ -70,7 +70,7 @@
                     Object o = HotSpotObjectConstant.asObject(object.asConstant());
                     return ConstantNode.forBoolean(o != null && c.isInstance(o));
                 }
-                HotSpotResolvedObjectType type = (HotSpotResolvedObjectType) HotSpotResolvedObjectType.fromClass(c);
+                HotSpotResolvedObjectType type = HotSpotResolvedObjectType.fromObjectClass(c);
                 InstanceOfNode instanceOf = InstanceOfNode.create(type, object, null);
                 return ConditionalNode.create(instanceOf, ConstantNode.forBoolean(true), ConstantNode.forBoolean(false));
             }
--- a/graal/com.oracle.graal.truffle.hotspot/src/com/oracle/graal/truffle/hotspot/HotSpotTruffleRuntime.java	Fri Oct 24 13:01:16 2014 -0700
+++ b/graal/com.oracle.graal.truffle.hotspot/src/com/oracle/graal/truffle/hotspot/HotSpotTruffleRuntime.java	Mon Oct 27 13:39:12 2014 -0700
@@ -219,7 +219,7 @@
             try {
                 future.get();
             } catch (ExecutionException e) {
-                if (TruffleCompilationExceptionsAreThrown.getValue() && !(e.getCause() instanceof BailoutException)) {
+                if (TruffleCompilationExceptionsAreThrown.getValue() && !(e.getCause() instanceof BailoutException) && !((BailoutException) e.getCause()).isPermanent()) {
                     throw new RuntimeException(e.getCause());
                 } else {
                     // silently ignored
--- a/graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/builtins/SLTestTruffleBoundary01Builtin.java	Fri Oct 24 13:01:16 2014 -0700
+++ b/graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/builtins/SLTestTruffleBoundary01Builtin.java	Mon Oct 27 13:39:12 2014 -0700
@@ -31,7 +31,7 @@
 import com.oracle.truffle.sl.runtime.*;
 
 /**
- * Just used in TestSlowPath01.sl. Verifies that all intrinsics have no effect inside of a @TruffleBoundary
+ * Just used in TestTruffleBoundary01.sl. Verifies that all intrinsics have no effect inside of a @TruffleBoundary
  * annotated method.
  */
 @NodeInfo(shortName = "testTruffleBoundary01")
@@ -41,7 +41,7 @@
 
     @Specialization
     @TruffleBoundary
-    public Object testSlowPath() {
+    public Object testTruffleBoundary() {
         CompilerAsserts.neverPartOfCompilation();
         CompilerAsserts.neverPartOfCompilation("Should never throw an exception when compiling.");
         CompilerAsserts.compilationConstant(nonConstantValue);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/utilities/PrimitiveValueProfileTest.java	Mon Oct 27 13:39:12 2014 -0700
@@ -0,0 +1,945 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.api.test.utilities;
+
+import static org.hamcrest.CoreMatchers.*;
+import static org.junit.Assert.*;
+
+import org.junit.*;
+import org.junit.experimental.theories.*;
+import org.junit.runner.*;
+
+import com.oracle.truffle.api.utilities.*;
+
+@RunWith(Theories.class)
+public class PrimitiveValueProfileTest {
+
+    @DataPoint public static final String O1 = new String();
+    @DataPoint public static final String O2 = O1;
+    @DataPoint public static final Object O3 = new Object();
+    @DataPoint public static final Object O4 = null;
+
+    @DataPoint public static final byte B1 = Byte.MIN_VALUE;
+    @DataPoint public static final byte B2 = 0;
+    @DataPoint public static final byte B3 = 14;
+    @DataPoint public static final byte B4 = Byte.MAX_VALUE;
+
+    @DataPoint public static final short S1 = Short.MIN_VALUE;
+    @DataPoint public static final short S2 = 0;
+    @DataPoint public static final short S3 = 14;
+    @DataPoint public static final short S4 = Short.MAX_VALUE;
+
+    @DataPoint public static final int I1 = Integer.MIN_VALUE;
+    @DataPoint public static final int I2 = 0;
+    @DataPoint public static final int I3 = 14;
+    @DataPoint public static final int I4 = Integer.MAX_VALUE;
+
+    @DataPoint public static final long L1 = Long.MIN_VALUE;
+    @DataPoint public static final long L2 = 0;
+    @DataPoint public static final long L3 = 14;
+    @DataPoint public static final long L4 = Long.MAX_VALUE;
+
+    @DataPoint public static final float F1 = Float.MIN_VALUE;
+    @DataPoint public static final float F2 = -0.0f;
+    @DataPoint public static final float F3 = +0.0f;
+    @DataPoint public static final float F4 = 14.5f;
+    @DataPoint public static final float F5 = Float.MAX_VALUE;
+
+    @DataPoint public static final double D1 = Double.MIN_VALUE;
+    @DataPoint public static final double D2 = -0.0;
+    @DataPoint public static final double D3 = +0.0;
+    @DataPoint public static final double D4 = 14.5;
+    @DataPoint public static final double D5 = Double.MAX_VALUE;
+
+    @DataPoint public static final boolean T1 = false;
+    @DataPoint public static final boolean T2 = true;
+
+    @DataPoint public static final char C1 = Character.MIN_VALUE;
+    @DataPoint public static final char C2 = 0;
+    @DataPoint public static final char C3 = 14;
+    @DataPoint public static final char C4 = Character.MAX_VALUE;
+
+    private static final float FLOAT_DELTA = 0.00001f;
+    private static final double DOUBLE_DELTA = 0.00001;
+
+    private PrimitiveValueProfile profile;
+
+    @Before
+    public void create() {
+        profile = ValueProfile.createPrimitiveProfile();
+    }
+
+    @Test
+    public void testInitial() {
+        assertThat(profile.isGeneric(), is(false));
+        assertThat(profile.isUninitialized(), is(true));
+        profile.toString(); // test that it is not crashing
+    }
+
+    @Theory
+    public void testProfileOneObject(Object value) {
+        Object result = profile.profile(value);
+
+        assertThat(result, is(value));
+        assertEquals(profile.getCachedValue(), value);
+        assertThat(profile.isUninitialized(), is(false));
+        profile.toString(); // test that it is not crashing
+    }
+
+    @Theory
+    public void testProfileTwoObject(Object value0, Object value1) {
+        Object result0 = profile.profile(value0);
+        Object result1 = profile.profile(value1);
+
+        assertThat(result0, is(value0));
+        assertThat(result1, is(value1));
+
+        if (value0 == value1) {
+            assertThat(profile.getCachedValue(), is(value0));
+            assertThat(profile.isGeneric(), is(false));
+        } else {
+            assertThat(profile.isGeneric(), is(true));
+        }
+        assertThat(profile.isUninitialized(), is(false));
+        profile.toString(); // test that it is not crashing
+    }
+
+    @Theory
+    public void testProfileThreeObject(Object value0, Object value1, Object value2) {
+        Object result0 = profile.profile(value0);
+        Object result1 = profile.profile(value1);
+        Object result2 = profile.profile(value2);
+
+        assertThat(result0, is(value0));
+        assertThat(result1, is(value1));
+        assertThat(result2, is(value2));
+
+        if (value0 == value1 && value1 == value2) {
+            assertThat(profile.getCachedValue(), is(value0));
+            assertThat(profile.isGeneric(), is(false));
+        } else {
+            assertThat(profile.isGeneric(), is(true));
+        }
+        assertThat(profile.isUninitialized(), is(false));
+        profile.toString(); // test that it is not crashing
+    }
+
+    @Theory
+    public void testProfileOneByte(byte value) {
+        byte result = profile.profile(value);
+
+        assertThat(result, is(value));
+        assertEquals(profile.getCachedValue(), value);
+        assertThat(profile.isUninitialized(), is(false));
+        profile.toString(); // test that it is not crashing
+    }
+
+    @Theory
+    public void testProfileTwoByte(byte value0, byte value1) {
+        byte result0 = profile.profile(value0);
+        byte result1 = profile.profile(value1);
+
+        assertEquals(result0, value0);
+        assertEquals(result1, value1);
+
+        if (value0 == value1) {
+            assertTrue(profile.getCachedValue() instanceof Byte);
+            assertEquals((byte) profile.getCachedValue(), value0);
+            assertThat(profile.isGeneric(), is(false));
+        } else {
+            assertThat(profile.isGeneric(), is(true));
+        }
+        assertThat(profile.isUninitialized(), is(false));
+        profile.toString(); // test that it is not crashing
+    }
+
+    @Theory
+    public void testProfileThreeByte(byte value0, byte value1, byte value2) {
+        byte result0 = profile.profile(value0);
+        byte result1 = profile.profile(value1);
+        byte result2 = profile.profile(value2);
+
+        assertEquals(result0, value0);
+        assertEquals(result1, value1);
+        assertEquals(result2, value2);
+
+        if (value0 == value1 && value1 == value2) {
+            assertTrue(profile.getCachedValue() instanceof Byte);
+            assertEquals((byte) profile.getCachedValue(), value0);
+            assertThat(profile.isGeneric(), is(false));
+        } else {
+            assertThat(profile.isGeneric(), is(true));
+        }
+        assertThat(profile.isUninitialized(), is(false));
+        profile.toString(); // test that it is not crashing
+    }
+
+    @Theory
+    public void testProfileOneShort(short value) {
+        short result = profile.profile(value);
+
+        assertThat(result, is(value));
+        assertEquals(profile.getCachedValue(), value);
+        assertThat(profile.isUninitialized(), is(false));
+        profile.toString(); // test that it is not crashing
+    }
+
+    @Theory
+    public void testProfileTwoShort(short value0, short value1) {
+        short result0 = profile.profile(value0);
+        short result1 = profile.profile(value1);
+
+        assertEquals(result0, value0);
+        assertEquals(result1, value1);
+
+        if (value0 == value1) {
+            assertTrue(profile.getCachedValue() instanceof Short);
+            assertEquals((short) profile.getCachedValue(), value0);
+            assertThat(profile.isGeneric(), is(false));
+        } else {
+            assertThat(profile.isGeneric(), is(true));
+        }
+        assertThat(profile.isUninitialized(), is(false));
+        profile.toString(); // test that it is not crashing
+    }
+
+    @Theory
+    public void testProfileThreeShort(short value0, short value1, short value2) {
+        short result0 = profile.profile(value0);
+        short result1 = profile.profile(value1);
+        short result2 = profile.profile(value2);
+
+        assertEquals(result0, value0);
+        assertEquals(result1, value1);
+        assertEquals(result2, value2);
+
+        if (value0 == value1 && value1 == value2) {
+            assertTrue(profile.getCachedValue() instanceof Short);
+            assertEquals((short) profile.getCachedValue(), value0);
+            assertThat(profile.isGeneric(), is(false));
+        } else {
+            assertThat(profile.isGeneric(), is(true));
+        }
+        assertThat(profile.isUninitialized(), is(false));
+        profile.toString(); // test that it is not crashing
+    }
+
+    @Theory
+    public void testProfileOneInteger(int value) {
+        int result = profile.profile(value);
+
+        assertThat(result, is(value));
+        assertEquals(profile.getCachedValue(), value);
+        assertThat(profile.isUninitialized(), is(false));
+        profile.toString(); // test that it is not crashing
+    }
+
+    @Theory
+    public void testProfileTwoInteger(int value0, int value1) {
+        int result0 = profile.profile(value0);
+        int result1 = profile.profile(value1);
+
+        assertEquals(result0, value0);
+        assertEquals(result1, value1);
+
+        if (value0 == value1) {
+            assertTrue(profile.getCachedValue() instanceof Integer);
+            assertEquals((int) profile.getCachedValue(), value0);
+            assertThat(profile.isGeneric(), is(false));
+        } else {
+            assertThat(profile.isGeneric(), is(true));
+        }
+        assertThat(profile.isUninitialized(), is(false));
+        profile.toString(); // test that it is not crashing
+    }
+
+    @Theory
+    public void testProfileThreeInteger(int value0, int value1, int value2) {
+        int result0 = profile.profile(value0);
+        int result1 = profile.profile(value1);
+        int result2 = profile.profile(value2);
+
+        assertEquals(result0, value0);
+        assertEquals(result1, value1);
+        assertEquals(result2, value2);
+
+        if (value0 == value1 && value1 == value2) {
+            assertTrue(profile.getCachedValue() instanceof Integer);
+            assertEquals((int) profile.getCachedValue(), value0);
+            assertThat(profile.isGeneric(), is(false));
+        } else {
+            assertThat(profile.isGeneric(), is(true));
+        }
+        assertThat(profile.isUninitialized(), is(false));
+        profile.toString(); // test that it is not crashing
+    }
+
+    @Theory
+    public void testProfileOneLong(long value) {
+        long result = profile.profile(value);
+
+        assertThat(result, is(value));
+        assertEquals(profile.getCachedValue(), value);
+        assertThat(profile.isUninitialized(), is(false));
+        profile.toString(); // test that it is not crashing
+    }
+
+    @Theory
+    public void testProfileTwoLong(long value0, long value1) {
+        long result0 = profile.profile(value0);
+        long result1 = profile.profile(value1);
+
+        assertEquals(result0, value0);
+        assertEquals(result1, value1);
+
+        if (value0 == value1) {
+            assertTrue(profile.getCachedValue() instanceof Long);
+            assertEquals((long) profile.getCachedValue(), value0);
+            assertThat(profile.isGeneric(), is(false));
+        } else {
+            assertThat(profile.isGeneric(), is(true));
+        }
+        assertThat(profile.isUninitialized(), is(false));
+        profile.toString(); // test that it is not crashing
+    }
+
+    @Theory
+    public void testProfileThreeLong(long value0, long value1, long value2) {
+        long result0 = profile.profile(value0);
+        long result1 = profile.profile(value1);
+        long result2 = profile.profile(value2);
+
+        assertEquals(result0, value0);
+        assertEquals(result1, value1);
+        assertEquals(result2, value2);
+
+        if (value0 == value1 && value1 == value2) {
+            assertTrue(profile.getCachedValue() instanceof Long);
+            assertEquals((long) profile.getCachedValue(), value0);
+            assertThat(profile.isGeneric(), is(false));
+        } else {
+            assertThat(profile.isGeneric(), is(true));
+        }
+        assertThat(profile.isUninitialized(), is(false));
+        profile.toString(); // test that it is not crashing
+    }
+
+    @Theory
+    public void testProfileOneFloat(float value) {
+        float result = profile.profile(value);
+
+        assertThat(result, is(value));
+        assertEquals(profile.getCachedValue(), value);
+        assertThat(profile.isUninitialized(), is(false));
+        profile.toString(); // test that it is not crashing
+    }
+
+    @Theory
+    public void testProfileTwoFloat(float value0, float value1) {
+        float result0 = profile.profile(value0);
+        float result1 = profile.profile(value1);
+
+        assertEquals(result0, value0, FLOAT_DELTA);
+        assertEquals(result1, value1, FLOAT_DELTA);
+
+        if (PrimitiveValueProfile.exactCompare(value0, value1)) {
+            assertTrue(profile.getCachedValue() instanceof Float);
+            assertEquals((float) profile.getCachedValue(), value0, FLOAT_DELTA);
+            assertThat(profile.isGeneric(), is(false));
+        } else {
+            assertThat(profile.isGeneric(), is(true));
+        }
+        assertThat(profile.isUninitialized(), is(false));
+        profile.toString(); // test that it is not crashing
+    }
+
+    @Theory
+    public void testProfileThreeFloat(float value0, float value1, float value2) {
+        float result0 = profile.profile(value0);
+        float result1 = profile.profile(value1);
+        float result2 = profile.profile(value2);
+
+        assertEquals(result0, value0, FLOAT_DELTA);
+        assertEquals(result1, value1, FLOAT_DELTA);
+        assertEquals(result2, value2, FLOAT_DELTA);
+
+        if (PrimitiveValueProfile.exactCompare(value0, value1) && PrimitiveValueProfile.exactCompare(value1, value2)) {
+            assertTrue(profile.getCachedValue() instanceof Float);
+            assertEquals((float) profile.getCachedValue(), value0, FLOAT_DELTA);
+            assertThat(profile.isGeneric(), is(false));
+        } else {
+            assertThat(profile.isGeneric(), is(true));
+        }
+        assertThat(profile.isUninitialized(), is(false));
+        profile.toString(); // test that it is not crashing
+    }
+
+    @Theory
+    public void testProfileOneDouble(double value) {
+        double result = profile.profile(value);
+
+        assertThat(result, is(value));
+        assertEquals(profile.getCachedValue(), value);
+        assertThat(profile.isUninitialized(), is(false));
+        profile.toString(); // test that it is not crashing
+    }
+
+    @Theory
+    public void testProfileTwoDouble(double value0, double value1) {
+        double result0 = profile.profile(value0);
+        double result1 = profile.profile(value1);
+
+        assertEquals(result0, value0, DOUBLE_DELTA);
+        assertEquals(result1, value1, DOUBLE_DELTA);
+
+        if (PrimitiveValueProfile.exactCompare(value0, value1)) {
+            assertTrue(profile.getCachedValue() instanceof Double);
+            assertEquals((double) profile.getCachedValue(), value0, DOUBLE_DELTA);
+            assertThat(profile.isGeneric(), is(false));
+        } else {
+            assertThat(profile.isGeneric(), is(true));
+        }
+        assertThat(profile.isUninitialized(), is(false));
+        profile.toString(); // test that it is not crashing
+    }
+
+    @Theory
+    public void testProfileThreeDouble(double value0, double value1, double value2) {
+        double result0 = profile.profile(value0);
+        double result1 = profile.profile(value1);
+        double result2 = profile.profile(value2);
+
+        assertEquals(result0, value0, DOUBLE_DELTA);
+        assertEquals(result1, value1, DOUBLE_DELTA);
+        assertEquals(result2, value2, DOUBLE_DELTA);
+
+        if (PrimitiveValueProfile.exactCompare(value0, value1) && PrimitiveValueProfile.exactCompare(value1, value2)) {
+            assertTrue(profile.getCachedValue() instanceof Double);
+            assertEquals((double) profile.getCachedValue(), value0, DOUBLE_DELTA);
+            assertThat(profile.isGeneric(), is(false));
+        } else {
+            assertThat(profile.isGeneric(), is(true));
+        }
+        assertThat(profile.isUninitialized(), is(false));
+        profile.toString(); // test that it is not crashing
+    }
+
+    @Theory
+    public void testProfileOneBoolean(boolean value) {
+        boolean result = profile.profile(value);
+
+        assertThat(result, is(value));
+        assertEquals(profile.getCachedValue(), value);
+        assertThat(profile.isUninitialized(), is(false));
+        profile.toString(); // test that it is not crashing
+    }
+
+    @Theory
+    public void testProfileTwoBoolean(boolean value0, boolean value1) {
+        boolean result0 = profile.profile(value0);
+        boolean result1 = profile.profile(value1);
+
+        assertEquals(result0, value0);
+        assertEquals(result1, value1);
+
+        if (value0 == value1) {
+            assertTrue(profile.getCachedValue() instanceof Boolean);
+            assertEquals((boolean) profile.getCachedValue(), value0);
+            assertThat(profile.isGeneric(), is(false));
+        } else {
+            assertThat(profile.isGeneric(), is(true));
+        }
+        assertThat(profile.isUninitialized(), is(false));
+        profile.toString(); // test that it is not crashing
+    }
+
+    @Theory
+    public void testProfileThreeBoolean(boolean value0, boolean value1, boolean value2) {
+        boolean result0 = profile.profile(value0);
+        boolean result1 = profile.profile(value1);
+        boolean result2 = profile.profile(value2);
+
+        assertEquals(result0, value0);
+        assertEquals(result1, value1);
+        assertEquals(result2, value2);
+
+        if (value0 == value1 && value1 == value2) {
+            assertTrue(profile.getCachedValue() instanceof Boolean);
+            assertEquals((boolean) profile.getCachedValue(), value0);
+            assertThat(profile.isGeneric(), is(false));
+        } else {
+            assertThat(profile.isGeneric(), is(true));
+        }
+        assertThat(profile.isUninitialized(), is(false));
+        profile.toString(); // test that it is not crashing
+    }
+
+    @Theory
+    public void testProfileOneChar(char value) {
+        char result = profile.profile(value);
+
+        assertThat(result, is(value));
+        assertEquals(profile.getCachedValue(), value);
+        assertThat(profile.isUninitialized(), is(false));
+        profile.toString(); // test that it is not crashing
+    }
+
+    @Theory
+    public void testProfileTwoChar(char value0, char value1) {
+        char result0 = profile.profile(value0);
+        char result1 = profile.profile(value1);
+
+        assertEquals(result0, value0);
+        assertEquals(result1, value1);
+
+        if (value0 == value1) {
+            assertTrue(profile.getCachedValue() instanceof Character);
+            assertEquals((char) profile.getCachedValue(), value0);
+            assertThat(profile.isGeneric(), is(false));
+        } else {
+            assertThat(profile.isGeneric(), is(true));
+        }
+        assertThat(profile.isUninitialized(), is(false));
+        profile.toString(); // test that it is not crashing
+    }
+
+    @Theory
+    public void testProfileThreeChar(char value0, char value1, char value2) {
+        char result0 = profile.profile(value0);
+        char result1 = profile.profile(value1);
+        char result2 = profile.profile(value2);
+
+        assertEquals(result0, value0);
+        assertEquals(result1, value1);
+        assertEquals(result2, value2);
+
+        if (value0 == value1 && value1 == value2) {
+            assertTrue(profile.getCachedValue() instanceof Character);
+            assertEquals((char) profile.getCachedValue(), value0);
+            assertThat(profile.isGeneric(), is(false));
+        } else {
+            assertThat(profile.isGeneric(), is(true));
+        }
+        assertThat(profile.isUninitialized(), is(false));
+        profile.toString(); // test that it is not crashing
+    }
+
+    @Theory
+    public void testWithBoxedBoxedByte(byte value) {
+        Object result0 = profile.profile((Object) value);
+        Object result1 = profile.profile((Object) value);
+
+        assertTrue(result0 instanceof Byte);
+        assertEquals((byte) result0, value);
+        assertTrue(result1 instanceof Byte);
+        assertEquals((byte) result1, value);
+        assertFalse(profile.isUninitialized());
+        assertFalse(profile.isGeneric());
+    }
+
+    @Theory
+    public void testWithUnboxedBoxedByte(byte value) {
+        byte result0 = profile.profile(value);
+        Object result1 = profile.profile((Object) value);
+
+        assertEquals(result0, value);
+        assertTrue(result1 instanceof Byte);
+        assertEquals((byte) result1, value);
+        assertFalse(profile.isUninitialized());
+        assertFalse(profile.isGeneric());
+    }
+
+    @Theory
+    public void testWithBoxedUnboxedByte(byte value) {
+        Object result0 = profile.profile((Object) value);
+        byte result1 = profile.profile(value);
+
+        assertTrue(result0 instanceof Byte);
+        assertEquals((byte) result0, value);
+        assertEquals(result1, value);
+        assertFalse(profile.isUninitialized());
+        assertFalse(profile.isGeneric());
+    }
+
+    @Theory
+    public void testWithBoxedBoxedShort(short value) {
+        Object result0 = profile.profile((Object) value);
+        Object result1 = profile.profile((Object) value);
+
+        assertTrue(result0 instanceof Short);
+        assertEquals((short) result0, value);
+        assertTrue(result1 instanceof Short);
+        assertEquals((short) result1, value);
+        assertFalse(profile.isUninitialized());
+        assertFalse(profile.isGeneric());
+    }
+
+    @Theory
+    public void testWithUnboxedBoxedShort(short value) {
+        short result0 = profile.profile(value);
+        Object result1 = profile.profile((Object) value);
+
+        assertEquals(result0, value);
+        assertTrue(result1 instanceof Short);
+        assertEquals((short) result1, value);
+        assertFalse(profile.isUninitialized());
+        assertFalse(profile.isGeneric());
+    }
+
+    @Theory
+    public void testWithBoxedUnboxedShort(short value) {
+        Object result0 = profile.profile((Object) value);
+        short result1 = profile.profile(value);
+
+        assertTrue(result0 instanceof Short);
+        assertEquals((short) result0, value);
+        assertEquals(result1, value);
+        assertFalse(profile.isUninitialized());
+        assertFalse(profile.isGeneric());
+    }
+
+    @Theory
+    public void testWithBoxedBoxedInt(int value) {
+        Object result0 = profile.profile((Object) value);
+        Object result1 = profile.profile((Object) value);
+
+        assertTrue(result0 instanceof Integer);
+        assertEquals((int) result0, value);
+        assertTrue(result1 instanceof Integer);
+        assertEquals((int) result1, value);
+        assertFalse(profile.isUninitialized());
+        assertFalse(profile.isGeneric());
+    }
+
+    @Theory
+    public void testWithUnboxedBoxedInt(int value) {
+        int result0 = profile.profile(value);
+        Object result1 = profile.profile((Object) value);
+
+        assertEquals(result0, value);
+        assertTrue(result1 instanceof Integer);
+        assertEquals((int) result1, value);
+        assertFalse(profile.isUninitialized());
+        assertFalse(profile.isGeneric());
+    }
+
+    @Theory
+    public void testWithBoxedUnboxedInt(int value) {
+        Object result0 = profile.profile((Object) value);
+        int result1 = profile.profile(value);
+
+        assertTrue(result0 instanceof Integer);
+        assertEquals((int) result0, value);
+        assertEquals(result1, value);
+        assertFalse(profile.isUninitialized());
+        assertFalse(profile.isGeneric());
+    }
+
+    @Theory
+    public void testWithBoxedBoxedLong(long value) {
+        Object result0 = profile.profile((Object) value);
+        Object result1 = profile.profile((Object) value);
+
+        assertTrue(result0 instanceof Long);
+        assertEquals((long) result0, value);
+        assertTrue(result1 instanceof Long);
+        assertEquals((long) result1, value);
+        assertFalse(profile.isUninitialized());
+        assertFalse(profile.isGeneric());
+    }
+
+    @Theory
+    public void testWithUnboxedBoxedLong(long value) {
+        long result0 = profile.profile(value);
+        Object result1 = profile.profile((Object) value);
+
+        assertEquals(result0, value);
+        assertTrue(result1 instanceof Long);
+        assertEquals((long) result1, value);
+        assertFalse(profile.isUninitialized());
+        assertFalse(profile.isGeneric());
+    }
+
+    @Theory
+    public void testWithBoxedUnboxedLong(long value) {
+        Object result0 = profile.profile((Object) value);
+        long result1 = profile.profile(value);
+
+        assertTrue(result0 instanceof Long);
+        assertEquals((long) result0, value);
+        assertEquals(result1, value);
+        assertFalse(profile.isUninitialized());
+        assertFalse(profile.isGeneric());
+    }
+
+    @Theory
+    public void testWithBoxedBoxedFloat(float value) {
+        Object result0 = profile.profile((Object) value);
+        Object result1 = profile.profile((Object) value);
+
+        assertTrue(result0 instanceof Float);
+        assertTrue(PrimitiveValueProfile.exactCompare((float) result0, value));
+        assertTrue(result1 instanceof Float);
+        assertTrue(PrimitiveValueProfile.exactCompare((float) result1, value));
+        assertFalse(profile.isUninitialized());
+        assertFalse(profile.isGeneric());
+    }
+
+    @Theory
+    public void testWithUnboxedBoxedFloat(float value) {
+        float result0 = profile.profile(value);
+        Object result1 = profile.profile((Object) value);
+
+        assertTrue(PrimitiveValueProfile.exactCompare(result0, value));
+        assertTrue(result1 instanceof Float);
+        assertTrue(PrimitiveValueProfile.exactCompare((float) result1, value));
+        assertFalse(profile.isUninitialized());
+        assertFalse(profile.isGeneric());
+    }
+
+    @Theory
+    public void testWithBoxedUnboxedFloat(float value) {
+        Object result0 = profile.profile((Object) value);
+        float result1 = profile.profile(value);
+
+        assertTrue(result0 instanceof Float);
+        assertTrue(PrimitiveValueProfile.exactCompare((float) result0, value));
+        assertTrue(PrimitiveValueProfile.exactCompare(result1, value));
+        assertFalse(profile.isUninitialized());
+        assertFalse(profile.isGeneric());
+    }
+
+    @Theory
+    public void testWithBoxedBoxedDouble(double value) {
+        Object result0 = profile.profile((Object) value);
+        Object result1 = profile.profile((Object) value);
+
+        assertTrue(result0 instanceof Double);
+        assertTrue(PrimitiveValueProfile.exactCompare((double) result0, value));
+        assertTrue(result1 instanceof Double);
+        assertTrue(PrimitiveValueProfile.exactCompare((double) result1, value));
+        assertFalse(profile.isUninitialized());
+        assertFalse(profile.isGeneric());
+    }
+
+    @Theory
+    public void testWithUnboxedBoxedDouble(double value) {
+        double result0 = profile.profile(value);
+        Object result1 = profile.profile((Object) value);
+
+        assertTrue(PrimitiveValueProfile.exactCompare(result0, value));
+        assertTrue(result1 instanceof Double);
+        assertTrue(PrimitiveValueProfile.exactCompare((double) result1, value));
+        assertFalse(profile.isUninitialized());
+        assertFalse(profile.isGeneric());
+    }
+
+    @Theory
+    public void testWithBoxedUnboxedDouble(double value) {
+        Object result0 = profile.profile((Object) value);
+        double result1 = profile.profile(value);
+
+        assertTrue(result0 instanceof Double);
+        assertTrue(PrimitiveValueProfile.exactCompare((double) result0, value));
+        assertTrue(PrimitiveValueProfile.exactCompare(result1, value));
+        assertFalse(profile.isUninitialized());
+        assertFalse(profile.isGeneric());
+    }
+
+    @Theory
+    public void testWithBoxedBoxedBoolean(boolean value) {
+        Object result0 = profile.profile((Object) value);
+        Object result1 = profile.profile((Object) value);
+
+        assertTrue(result0 instanceof Boolean);
+        assertEquals((boolean) result0, value);
+        assertTrue(result1 instanceof Boolean);
+        assertEquals((boolean) result1, value);
+        assertFalse(profile.isUninitialized());
+        assertFalse(profile.isGeneric());
+    }
+
+    @Theory
+    public void testWithUnboxedBoxedBoolean(boolean value) {
+        boolean result0 = profile.profile(value);
+        Object result1 = profile.profile((Object) value);
+
+        assertEquals(result0, value);
+        assertTrue(result1 instanceof Boolean);
+        assertEquals((boolean) result1, value);
+        assertFalse(profile.isUninitialized());
+        assertFalse(profile.isGeneric());
+    }
+
+    @Theory
+    public void testWithBoxedUnboxedBoolean(boolean value) {
+        Object result0 = profile.profile((Object) value);
+        boolean result1 = profile.profile(value);
+
+        assertTrue(result0 instanceof Boolean);
+        assertEquals((boolean) result0, value);
+        assertEquals(result1, value);
+        assertFalse(profile.isUninitialized());
+        assertFalse(profile.isGeneric());
+    }
+
+    @Theory
+    public void testWithBoxedBoxedChar(char value) {
+        Object result0 = profile.profile((Object) value);
+        Object result1 = profile.profile((Object) value);
+
+        assertTrue(result0 instanceof Character);
+        assertEquals((char) result0, value);
+        assertTrue(result1 instanceof Character);
+        assertEquals((char) result1, value);
+        assertFalse(profile.isUninitialized());
+        assertFalse(profile.isGeneric());
+    }
+
+    @Theory
+    public void testWithUnboxedBoxedChar(char value) {
+        char result0 = profile.profile(value);
+        Object result1 = profile.profile((Object) value);
+
+        assertEquals(result0, value);
+        assertTrue(result1 instanceof Character);
+        assertEquals((char) result1, value);
+        assertFalse(profile.isUninitialized());
+        assertFalse(profile.isGeneric());
+    }
+
+    @Theory
+    public void testWithBoxedUnboxedCharacter(char value) {
+        Object result0 = profile.profile((Object) value);
+        char result1 = profile.profile(value);
+
+        assertTrue(result0 instanceof Character);
+        assertEquals((char) result0, value);
+        assertEquals(result1, value);
+        assertFalse(profile.isUninitialized());
+        assertFalse(profile.isGeneric());
+    }
+
+    @Theory
+    public void testWithByteThenObject(byte value0, Object value1) {
+        byte result0 = profile.profile(value0);
+        Object result1 = profile.profile(value1);
+
+        assertEquals(result0, value0);
+        assertSame(result1, value1);
+        assertFalse(profile.isUninitialized());
+        assertTrue(profile.isGeneric());
+    }
+
+    @Theory
+    public void testWithShortThenObject(short value0, Object value1) {
+        short result0 = profile.profile(value0);
+        Object result1 = profile.profile(value1);
+
+        assertEquals(result0, value0);
+        assertSame(result1, value1);
+        assertFalse(profile.isUninitialized());
+        assertTrue(profile.isGeneric());
+    }
+
+    @Theory
+    public void testWithIntThenObject(int value0, Object value1) {
+        int result0 = profile.profile(value0);
+        Object result1 = profile.profile(value1);
+
+        assertEquals(result0, value0);
+        assertSame(result1, value1);
+        assertFalse(profile.isUninitialized());
+        assertTrue(profile.isGeneric());
+    }
+
+    @Theory
+    public void testWithLongThenObject(long value0, Object value1) {
+        long result0 = profile.profile(value0);
+        Object result1 = profile.profile(value1);
+
+        assertEquals(result0, value0);
+        assertSame(result1, value1);
+        assertFalse(profile.isUninitialized());
+        assertTrue(profile.isGeneric());
+    }
+
+    @Theory
+    public void testWithFloatThenObject(float value0, Object value1) {
+        float result0 = profile.profile(value0);
+        Object result1 = profile.profile(value1);
+
+        assertTrue(PrimitiveValueProfile.exactCompare(result0, value0));
+        assertSame(result1, value1);
+        assertFalse(profile.isUninitialized());
+        assertTrue(profile.isGeneric());
+    }
+
+    @Theory
+    public void testWithDoubleThenObject(double value0, Object value1) {
+        double result0 = profile.profile(value0);
+        Object result1 = profile.profile(value1);
+
+        assertTrue(PrimitiveValueProfile.exactCompare(result0, value0));
+        assertSame(result1, value1);
+        assertFalse(profile.isUninitialized());
+        assertTrue(profile.isGeneric());
+    }
+
+    @Theory
+    public void testWithBooleanThenObject(boolean value0, Object value1) {
+        boolean result0 = profile.profile(value0);
+        Object result1 = profile.profile(value1);
+
+        assertEquals(result0, value0);
+        assertSame(result1, value1);
+        assertFalse(profile.isUninitialized());
+        assertTrue(profile.isGeneric());
+    }
+
+    @Theory
+    public void testWithCharThenObject(char value0, Object value1) {
+        char result0 = profile.profile(value0);
+        Object result1 = profile.profile(value1);
+
+        assertEquals(result0, value0);
+        assertSame(result1, value1);
+        assertFalse(profile.isUninitialized());
+        assertTrue(profile.isGeneric());
+    }
+
+    @Test
+    public void testNegativeZeroFloat() {
+        profile.profile(-0.0f);
+        profile.profile(+0.0f);
+        assertThat(profile.isGeneric(), is(true));
+    }
+
+    @Test
+    public void testNegativeZeroDouble() {
+        profile.profile(-0.0);
+        profile.profile(+0.0);
+        assertThat(profile.isGeneric(), is(true));
+    }
+
+}
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/OptimizationFailedException.java	Fri Oct 24 13:01:16 2014 -0700
+++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/OptimizationFailedException.java	Mon Oct 27 13:39:12 2014 -0700
@@ -26,14 +26,14 @@
 
 public class OptimizationFailedException extends RuntimeException {
 
-    private final CallTarget callTarget;
+    private final RootCallTarget callTarget;
 
-    public OptimizationFailedException(Throwable cause, CallTarget callTarget) {
+    public OptimizationFailedException(Throwable cause, RootCallTarget callTarget) {
         super(cause);
         this.callTarget = callTarget;
     }
 
-    public CallTarget getCallTarget() {
+    public RootCallTarget getCallTarget() {
         return callTarget;
     }
 
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/RootNode.java	Fri Oct 24 13:01:16 2014 -0700
+++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/RootNode.java	Mon Oct 27 13:39:12 2014 -0700
@@ -59,7 +59,7 @@
     @Override
     public Node copy() {
         RootNode root = (RootNode) super.copy();
-        root.frameDescriptor = frameDescriptor.shallowCopy();
+        root.frameDescriptor = frameDescriptor;
         return root;
     }
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/utilities/PrimitiveValueProfile.java	Mon Oct 27 13:39:12 2014 -0700
@@ -0,0 +1,224 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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.truffle.api.utilities;
+
+import java.util.*;
+
+import com.oracle.truffle.api.*;
+import com.oracle.truffle.api.CompilerDirectives.CompilationFinal;
+
+/**
+ * Represents a {@link ValueProfile} that speculates on the primitive equality or object identity of
+ * values.
+ * <p>
+ * Note that for {code float} and {@code double} values we compare primitive equality via
+ * {@link Float#floatToRawIntBits} and {@link Double#doubleToRawLongBits}, so that for example
+ * {@code -0.0} is not considered the same as {@code 0.0}, even though primitive equality would
+ * normally say that it was.
+ */
+public class PrimitiveValueProfile extends ValueProfile {
+
+    private static final Object UNINITIALIZED = new Object();
+    private static final Object GENERIC = new Object();
+
+    @CompilationFinal private Object cachedValue = UNINITIALIZED;
+
+    PrimitiveValueProfile() {
+    }
+
+    @SuppressWarnings("unchecked")
+    @Override
+    public Object profile(Object value) {
+        if (cachedValue != GENERIC) {
+            if (cachedValue instanceof Byte && value instanceof Byte && (byte) cachedValue == (byte) value) {
+                return cachedValue;
+            } else if (cachedValue instanceof Short && value instanceof Short && (short) cachedValue == (short) value) {
+                return cachedValue;
+            } else if (cachedValue instanceof Integer && value instanceof Integer && (int) cachedValue == (int) value) {
+                return cachedValue;
+            } else if (cachedValue instanceof Long && value instanceof Long && (long) cachedValue == (long) value) {
+                return cachedValue;
+            } else if (cachedValue instanceof Float && value instanceof Float && exactCompare((float) cachedValue, (float) value)) {
+                return cachedValue;
+            } else if (cachedValue instanceof Double && value instanceof Double && exactCompare((double) cachedValue, (double) value)) {
+                return cachedValue;
+            } else if (cachedValue instanceof Boolean && value instanceof Boolean && (boolean) cachedValue == (boolean) value) {
+                return cachedValue;
+            } else if (cachedValue instanceof Character && value instanceof Character && (char) cachedValue == (char) value) {
+                return cachedValue;
+            } else if (cachedValue == value) {
+                return cachedValue;
+            } else {
+                cacheMiss(value);
+            }
+        }
+        return value;
+    }
+
+    public byte profile(byte value) {
+        if (cachedValue != GENERIC) {
+            if (cachedValue instanceof Byte && (byte) cachedValue == value) {
+                return (byte) cachedValue;
+            } else {
+                cacheMiss(value);
+            }
+        }
+        return value;
+    }
+
+    public short profile(short value) {
+        if (cachedValue != GENERIC) {
+            if (cachedValue instanceof Short && (short) cachedValue == value) {
+                return (short) cachedValue;
+            } else {
+                cacheMiss(value);
+            }
+        }
+        return value;
+    }
+
+    public int profile(int value) {
+        if (cachedValue != GENERIC) {
+            if (cachedValue instanceof Integer && (int) cachedValue == value) {
+                return (int) cachedValue;
+            } else {
+                cacheMiss(value);
+            }
+        }
+        return value;
+    }
+
+    public long profile(long value) {
+        if (cachedValue != GENERIC) {
+            if (cachedValue instanceof Long && (long) cachedValue == value) {
+                return (long) cachedValue;
+            } else {
+                cacheMiss(value);
+            }
+        }
+        return value;
+    }
+
+    public float profile(float value) {
+        if (cachedValue != GENERIC) {
+            if (cachedValue instanceof Float && exactCompare((float) cachedValue, value)) {
+                return (float) cachedValue;
+            } else {
+                cacheMiss(value);
+            }
+        }
+        return value;
+    }
+
+    public double profile(double value) {
+        if (cachedValue != GENERIC) {
+            if (cachedValue instanceof Double && exactCompare((double) cachedValue, value)) {
+                return (double) cachedValue;
+            } else {
+                cacheMiss(value);
+            }
+        }
+        return value;
+    }
+
+    public boolean profile(boolean value) {
+        if (cachedValue != GENERIC) {
+            if (cachedValue instanceof Boolean && (boolean) cachedValue == value) {
+                return (boolean) cachedValue;
+            } else {
+                cacheMiss(value);
+            }
+        }
+        return value;
+    }
+
+    public char profile(char value) {
+        if (cachedValue != GENERIC) {
+            if (cachedValue instanceof Character && (char) cachedValue == value) {
+                return (char) cachedValue;
+            } else {
+                cacheMiss(value);
+            }
+        }
+        return value;
+    }
+
+    public boolean isGeneric() {
+        return getCachedValue() == GENERIC;
+    }
+
+    public boolean isUninitialized() {
+        return getCachedValue() == UNINITIALIZED;
+    }
+
+    public Object getCachedValue() {
+        return cachedValue;
+    }
+
+    @Override
+    public String toString() {
+        return String.format("%s(%s)@%x", getClass().getSimpleName(), formatValue(), hashCode());
+    }
+
+    private void cacheMiss(Object value) {
+        CompilerDirectives.transferToInterpreterAndInvalidate();
+        if (cachedValue == UNINITIALIZED) {
+            cachedValue = value;
+        } else {
+            cachedValue = GENERIC;
+        }
+    }
+
+    public static boolean exactCompare(float a, float b) {
+        /*
+         * -0.0 == 0.0, but you can tell the difference through other means, so we need to
+         * differentiate.
+         */
+        return Float.floatToRawIntBits(a) == Float.floatToRawIntBits(b);
+    }
+
+    public static boolean exactCompare(double a, double b) {
+        /*
+         * -0.0 == 0.0, but you can tell the difference through other means, so we need to
+         * differentiate.
+         */
+        return Double.doubleToRawLongBits(a) == Double.doubleToRawLongBits(b);
+    }
+
+    private String formatValue() {
+        if (cachedValue == null) {
+            return "null";
+        } else if (cachedValue == UNINITIALIZED) {
+            return "uninitialized";
+        } else if (cachedValue == GENERIC) {
+            return "generic";
+        } else if (cachedValue instanceof Byte || cachedValue instanceof Short || cachedValue instanceof Integer || cachedValue instanceof Long || cachedValue instanceof Float ||
+                        cachedValue instanceof Double || cachedValue instanceof Boolean || cachedValue instanceof Character) {
+            return String.format("%s=%s", cachedValue.getClass().getSimpleName(), cachedValue);
+        } else {
+            return String.format("%s@%x", cachedValue.getClass().getSimpleName(), Objects.hash(cachedValue));
+        }
+    }
+}
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/utilities/ValueProfile.java	Fri Oct 24 13:01:16 2014 -0700
+++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/utilities/ValueProfile.java	Mon Oct 27 13:39:12 2014 -0700
@@ -31,13 +31,14 @@
  *
  * <pre>
  * private final ValueProfile classProfile = ValueProfile.createClassProfile();
- *
+ * 
  * return classProfile.profile(value);
  * </pre>
  *
  * All instances of {@code ValueProfile} (and subclasses) must be held in {@code final} fields for
  * compiler optimizations to take effect.
  *
+ * @see #createPrimitiveProfile()
  * @see #createIdentityProfile()
  * @see #createClassProfile()
  */
@@ -46,6 +47,14 @@
     public abstract <T> T profile(T value);
 
     /**
+     * Returns a {@link PrimitiveValueProfile} that speculates on the primitive equality or object
+     * identity of a value.
+     */
+    public static PrimitiveValueProfile createPrimitiveProfile() {
+        return new PrimitiveValueProfile();
+    }
+
+    /**
      * Returns a {@link ValueProfile} that speculates on the exact class of a value.
      */
     public static ValueProfile createClassProfile() {