changeset 18327:13273385abb5

Merge.
author Doug Simon <doug.simon@oracle.com>
date Mon, 10 Nov 2014 18:18:42 +0100
parents 840257b6cdc5 c83efc00f6cc
children 58b7133cd0e1
files mx/mx_graal.py
diffstat 25 files changed, 179 insertions(+), 114 deletions(-) [+]
line wrap: on
line diff
--- a/CHANGELOG.md	Mon Nov 10 18:16:21 2014 +0100
+++ b/CHANGELOG.md	Mon Nov 10 18:18:42 2014 +0100
@@ -16,6 +16,7 @@
 * Renamed DirectCallNode#isSplit to DirectCallNode#isCallTargetCloned
 * Added PrimitiveValueProfile.
 * Added -G:TruffleTimeThreshold=5000 option to defer compilation for call targets
+* Added RootNode#getExecutionContext to identify nodes with languages
 * ...
 
 ## Version 0.5
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/CONTRIBUTING.md	Mon Nov 10 18:18:42 2014 +0100
@@ -0,0 +1,2 @@
+Please see http://openjdk.java.net/contribute/ for details of how to contribute
+to OpenJDK projects including GraalVM.
--- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/LocationIdentity.java	Mon Nov 10 18:16:21 2014 +0100
+++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/LocationIdentity.java	Mon Nov 10 18:18:42 2014 +0100
@@ -22,10 +22,16 @@
  */
 package com.oracle.graal.api.meta;
 
+import java.util.*;
+
 /**
  * Marker interface for location identities. Apart from the special values {@link #ANY_LOCATION} and
  * {@link #FINAL_LOCATION}, a different location identity of two memory accesses guarantees that the
  * two accesses do not interfere.
+ *
+ * Clients of {@link LocationIdentity} must use {@link #equals(Object)}, not {@code ==}, when
+ * comparing two {@link LocationIdentity} values for equality. Likewise, they must not use
+ * {@link IdentityHashMap}s with {@link LocationIdentity} values as keys.
  */
 public interface LocationIdentity {
 
@@ -34,17 +40,17 @@
      * analysis of memory accesses. A read from this location cannot be moved or coalesced with
      * other reads because its interaction with other reads is not known.
      */
-    LocationIdentity ANY_LOCATION = NamedLocationIdentity.create("ANY_LOCATION", false);
+    LocationIdentity ANY_LOCATION = NamedLocationIdentity.mutable("ANY_LOCATION");
 
     /**
      * Denotes the location of a value that is guaranteed to be unchanging.
      */
-    LocationIdentity FINAL_LOCATION = NamedLocationIdentity.create("FINAL_LOCATION", true);
+    LocationIdentity FINAL_LOCATION = NamedLocationIdentity.immutable("FINAL_LOCATION");
 
     /**
      * Denotes the location of the length field of a Java array.
      */
-    LocationIdentity ARRAY_LENGTH_LOCATION = NamedLocationIdentity.create("[].length", true);
+    LocationIdentity ARRAY_LENGTH_LOCATION = NamedLocationIdentity.immutable("[].length");
 
     /**
      * Denotes a location is unchanging in all cases. Not that this is different than the Java
--- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/NamedLocationIdentity.java	Mon Nov 10 18:16:21 2014 +0100
+++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/NamedLocationIdentity.java	Mon Nov 10 18:18:42 2014 +0100
@@ -30,22 +30,17 @@
 public final class NamedLocationIdentity implements LocationIdentity {
 
     /**
-     * Canonicalizing map for {@link NamedLocationIdentity} instances. This is in a separate class
-     * to work around class initialization issues.
+     * Map for asserting all {@link NamedLocationIdentity} instances have a unique name.
      */
     static class DB {
         private static final HashMap<String, NamedLocationIdentity> map = new HashMap<>();
 
-        static synchronized NamedLocationIdentity register(NamedLocationIdentity identity) {
+        static boolean checkUnique(NamedLocationIdentity identity) {
             NamedLocationIdentity oldValue = map.put(identity.name, identity);
             if (oldValue != null) {
-                throw new IllegalArgumentException("identity " + identity + " already exists");
+                throw new AssertionError("identity " + identity + " already exists");
             }
-            return identity;
-        }
-
-        static synchronized NamedLocationIdentity lookup(String name) {
-            return map.get(name);
+            return true;
         }
     }
 
@@ -59,28 +54,36 @@
     }
 
     /**
-     * Creates a named unique location identity for read and write operations.
+     * Creates a named unique location identity for read and write operations against mutable
+     * memory.
      *
      * @param name the name of the new location identity
      */
-    public static NamedLocationIdentity create(String name) {
+    public static NamedLocationIdentity mutable(String name) {
         return create(name, false);
     }
 
     /**
+     * Creates a named unique location identity for read operations against immutable memory.
+     * Immutable memory will never have a visible write in the graph, which is more restictive than
+     * Java final.
+     *
+     * @param name the name of the new location identity
+     */
+    public static NamedLocationIdentity immutable(String name) {
+        return create(name, true);
+    }
+
+    /**
      * Creates a named unique location identity for read and write operations.
      *
      * @param name the name of the new location identity
+     * @param immutable true if the location is immutable
      */
-    public static NamedLocationIdentity create(String name, boolean immutable) {
-        return DB.register(new NamedLocationIdentity(name, immutable));
-    }
-
-    /**
-     * Gets the unique {@link NamedLocationIdentity} (if any) for a given name.
-     */
-    public static NamedLocationIdentity lookup(String name) {
-        return DB.lookup(name);
+    private static NamedLocationIdentity create(String name, boolean immutable) {
+        NamedLocationIdentity id = new NamedLocationIdentity(name, immutable);
+        assert DB.checkUnique(id);
+        return id;
     }
 
     @Override
@@ -95,7 +98,9 @@
         }
         if (obj instanceof NamedLocationIdentity) {
             NamedLocationIdentity that = (NamedLocationIdentity) obj;
-            return this.name.equals(that.name);
+            boolean res = this.name.equals(that.name);
+            assert !res || this.immutable == that.immutable;
+            return res;
         }
         return false;
     }
@@ -123,7 +128,7 @@
     private static EnumMap<Kind, LocationIdentity> initArrayLocations() {
         EnumMap<Kind, LocationIdentity> result = new EnumMap<>(Kind.class);
         for (Kind kind : Kind.values()) {
-            result.put(kind, NamedLocationIdentity.create("Array: " + kind.getJavaName()));
+            result.put(kind, NamedLocationIdentity.mutable("Array: " + kind.getJavaName()));
         }
         return result;
     }
--- a/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/replacements/HSAILHotSpotReplacementsUtil.java	Mon Nov 10 18:16:21 2014 +0100
+++ b/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/replacements/HSAILHotSpotReplacementsUtil.java	Mon Nov 10 18:18:42 2014 +0100
@@ -43,18 +43,18 @@
         hsailRegisters = registers;
     }
 
-    public static final LocationIdentity TLAB_INFO_LOCATION = NamedLocationIdentity.create("TlabInfo");
-    public static final LocationIdentity TLABINFO_LASTGOODTOP_LOCATION = NamedLocationIdentity.create("TlabInfoLastGoodTop");
-    public static final LocationIdentity TLABINFO_END_LOCATION = NamedLocationIdentity.create("TlabInfoEnd");
-    public static final LocationIdentity TLABINFO_TOP_LOCATION = NamedLocationIdentity.create("TlabInfoTop");
-    public static final LocationIdentity TLABINFO_START_LOCATION = NamedLocationIdentity.create("TlabInfoStart");
-    public static final LocationIdentity TLABINFO_ALLOCINFO_LOCATION = NamedLocationIdentity.create("TlabInfoAllocInfo");
-    public static final LocationIdentity TLABINFO_ORIGINALTOP_LOCATION = NamedLocationIdentity.create("TlabInfoOriginalTop");
-    public static final LocationIdentity TLABINFO_TLAB_LOCATION = NamedLocationIdentity.create("TlabInfoTlab");
+    public static final LocationIdentity TLAB_INFO_LOCATION = NamedLocationIdentity.mutable("TlabInfo");
+    public static final LocationIdentity TLABINFO_LASTGOODTOP_LOCATION = NamedLocationIdentity.mutable("TlabInfoLastGoodTop");
+    public static final LocationIdentity TLABINFO_END_LOCATION = NamedLocationIdentity.mutable("TlabInfoEnd");
+    public static final LocationIdentity TLABINFO_TOP_LOCATION = NamedLocationIdentity.mutable("TlabInfoTop");
+    public static final LocationIdentity TLABINFO_START_LOCATION = NamedLocationIdentity.mutable("TlabInfoStart");
+    public static final LocationIdentity TLABINFO_ALLOCINFO_LOCATION = NamedLocationIdentity.mutable("TlabInfoAllocInfo");
+    public static final LocationIdentity TLABINFO_ORIGINALTOP_LOCATION = NamedLocationIdentity.mutable("TlabInfoOriginalTop");
+    public static final LocationIdentity TLABINFO_TLAB_LOCATION = NamedLocationIdentity.mutable("TlabInfoTlab");
 
-    public static final LocationIdentity ALLOCINFO_TLABINFOSPOOLNEXT_LOCATION = NamedLocationIdentity.create("AllocInfoTlabInfosPoolNext");
-    public static final LocationIdentity ALLOCINFO_TLABINFOSPOOLEND_LOCATION = NamedLocationIdentity.create("AllocInfoTlabInfosPoolEnd");
-    public static final LocationIdentity ALLOCINFO_TLABALIGNRESERVEBYTES_LOCATION = NamedLocationIdentity.create("AllocInfoTlabAlignreservebytes");
+    public static final LocationIdentity ALLOCINFO_TLABINFOSPOOLNEXT_LOCATION = NamedLocationIdentity.mutable("AllocInfoTlabInfosPoolNext");
+    public static final LocationIdentity ALLOCINFO_TLABINFOSPOOLEND_LOCATION = NamedLocationIdentity.mutable("AllocInfoTlabInfosPoolEnd");
+    public static final LocationIdentity ALLOCINFO_TLABALIGNRESERVEBYTES_LOCATION = NamedLocationIdentity.mutable("AllocInfoTlabAlignreservebytes");
 
     /**
      * Gets the value of the thread register as a Word. There is a level of indirection here. Thread
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConfig.java	Mon Nov 10 18:16:21 2014 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConfig.java	Mon Nov 10 18:18:42 2014 +0100
@@ -32,6 +32,8 @@
 import com.oracle.graal.hotspot.meta.*;
 import com.oracle.graal.hotspotvmconfig.*;
 
+//JaCoCo Exclude
+
 /**
  * Used to access native configuration details.
  *
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/HotSpotReplacementsUtil.java	Mon Nov 10 18:16:21 2014 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/HotSpotReplacementsUtil.java	Mon Nov 10 18:18:42 2014 +0100
@@ -63,7 +63,7 @@
         return config().verifyOops;
     }
 
-    public static final LocationIdentity EXCEPTION_OOP_LOCATION = NamedLocationIdentity.create("ExceptionOop");
+    public static final LocationIdentity EXCEPTION_OOP_LOCATION = NamedLocationIdentity.mutable("ExceptionOop");
 
     /**
      * @see HotSpotVMConfig#threadExceptionOopOffset
@@ -73,49 +73,49 @@
         return config().threadExceptionOopOffset;
     }
 
-    public static final LocationIdentity EXCEPTION_PC_LOCATION = NamedLocationIdentity.create("ExceptionPc");
+    public static final LocationIdentity EXCEPTION_PC_LOCATION = NamedLocationIdentity.mutable("ExceptionPc");
 
     @Fold
     public static int threadExceptionPcOffset() {
         return config().threadExceptionPcOffset;
     }
 
-    public static final LocationIdentity LAST_JAVA_PC_LOCATION = NamedLocationIdentity.create("LastJavaPc");
+    public static final LocationIdentity LAST_JAVA_PC_LOCATION = NamedLocationIdentity.mutable("LastJavaPc");
 
     @Fold
     public static int threadLastJavaPcOffset() {
         return config().threadLastJavaPcOffset();
     }
 
-    public static final LocationIdentity LAST_JAVA_FP_LOCATION = NamedLocationIdentity.create("LastJavaFp");
+    public static final LocationIdentity LAST_JAVA_FP_LOCATION = NamedLocationIdentity.mutable("LastJavaFp");
 
     @Fold
     public static int threadLastJavaFpOffset() {
         return config().threadLastJavaFpOffset();
     }
 
-    public static final LocationIdentity TLAB_TOP_LOCATION = NamedLocationIdentity.create("TlabTop");
+    public static final LocationIdentity TLAB_TOP_LOCATION = NamedLocationIdentity.mutable("TlabTop");
 
     @Fold
     public static int threadTlabTopOffset() {
         return config().threadTlabTopOffset();
     }
 
-    public static final LocationIdentity TLAB_END_LOCATION = NamedLocationIdentity.create("TlabEnd");
+    public static final LocationIdentity TLAB_END_LOCATION = NamedLocationIdentity.mutable("TlabEnd");
 
     @Fold
     private static int threadTlabEndOffset() {
         return config().threadTlabEndOffset();
     }
 
-    public static final LocationIdentity TLAB_START_LOCATION = NamedLocationIdentity.create("TlabStart");
+    public static final LocationIdentity TLAB_START_LOCATION = NamedLocationIdentity.mutable("TlabStart");
 
     @Fold
     private static int threadTlabStartOffset() {
         return config().threadTlabStartOffset();
     }
 
-    public static final LocationIdentity PENDING_EXCEPTION_LOCATION = NamedLocationIdentity.create("PendingException");
+    public static final LocationIdentity PENDING_EXCEPTION_LOCATION = NamedLocationIdentity.mutable("PendingException");
 
     /**
      * @see HotSpotVMConfig#pendingExceptionOffset
@@ -125,7 +125,7 @@
         return config().pendingExceptionOffset;
     }
 
-    public static final LocationIdentity PENDING_DEOPTIMIZATION_LOCATION = NamedLocationIdentity.create("PendingDeoptimization");
+    public static final LocationIdentity PENDING_DEOPTIMIZATION_LOCATION = NamedLocationIdentity.mutable("PendingDeoptimization");
 
     /**
      * @see HotSpotVMConfig#pendingDeoptimizationOffset
@@ -135,7 +135,7 @@
         return config().pendingDeoptimizationOffset;
     }
 
-    public static final LocationIdentity OBJECT_RESULT_LOCATION = NamedLocationIdentity.create("ObjectResult");
+    public static final LocationIdentity OBJECT_RESULT_LOCATION = NamedLocationIdentity.mutable("ObjectResult");
 
     @Fold
     private static int objectResultOffset() {
@@ -232,14 +232,14 @@
         return result;
     }
 
-    public static final LocationIdentity JAVA_THREAD_THREAD_OBJECT_LOCATION = NamedLocationIdentity.create("JavaThread::_threadObj");
+    public static final LocationIdentity JAVA_THREAD_THREAD_OBJECT_LOCATION = NamedLocationIdentity.mutable("JavaThread::_threadObj");
 
     @Fold
     public static int threadObjectOffset() {
         return config().threadObjectOffset;
     }
 
-    public static final LocationIdentity JAVA_THREAD_OSTHREAD_LOCATION = NamedLocationIdentity.create("JavaThread::_osthread");
+    public static final LocationIdentity JAVA_THREAD_OSTHREAD_LOCATION = NamedLocationIdentity.mutable("JavaThread::_osthread");
 
     @Fold
     public static int osThreadOffset() {
@@ -271,7 +271,7 @@
         return config().heapWordSize;
     }
 
-    public static final LocationIdentity PROTOTYPE_MARK_WORD_LOCATION = NamedLocationIdentity.create("PrototypeMarkWord");
+    public static final LocationIdentity PROTOTYPE_MARK_WORD_LOCATION = NamedLocationIdentity.mutable("PrototypeMarkWord");
 
     @Fold
     public static int prototypeMarkWordOffset() {
@@ -283,14 +283,14 @@
         return config().arrayPrototypeMarkWord();
     }
 
-    public static final LocationIdentity KLASS_ACCESS_FLAGS_LOCATION = NamedLocationIdentity.create("Klass::_access_flags", true);
+    public static final LocationIdentity KLASS_ACCESS_FLAGS_LOCATION = NamedLocationIdentity.immutable("Klass::_access_flags");
 
     @Fold
     public static int klassAccessFlagsOffset() {
         return config().klassAccessFlagsOffset;
     }
 
-    public static final LocationIdentity KLASS_LAYOUT_HELPER_LOCATION = NamedLocationIdentity.create("Klass::_layout_helper", true);
+    public static final LocationIdentity KLASS_LAYOUT_HELPER_LOCATION = NamedLocationIdentity.immutable("Klass::_layout_helper");
 
     @Fold
     public static int klassLayoutHelperOffset() {
@@ -319,30 +319,30 @@
         return (layoutHelper < layoutHelperNeutralValue);
     }
 
-    public static final LocationIdentity ARRAY_KLASS_COMPONENT_MIRROR = NamedLocationIdentity.create("ArrayKlass::_component_mirror", true);
+    public static final LocationIdentity ARRAY_KLASS_COMPONENT_MIRROR = NamedLocationIdentity.immutable("ArrayKlass::_component_mirror");
 
     @Fold
     public static int arrayKlassComponentMirrorOffset() {
         return config().arrayKlassComponentMirrorOffset;
     }
 
-    public static final LocationIdentity KLASS_SUPER_KLASS_LOCATION = NamedLocationIdentity.create("Klass::_super", true);
+    public static final LocationIdentity KLASS_SUPER_KLASS_LOCATION = NamedLocationIdentity.immutable("Klass::_super");
 
     @Fold
     public static int klassSuperKlassOffset() {
         return config().klassSuperKlassOffset;
     }
 
-    public static final LocationIdentity MARK_WORD_LOCATION = NamedLocationIdentity.create("MarkWord");
+    public static final LocationIdentity MARK_WORD_LOCATION = NamedLocationIdentity.mutable("MarkWord");
 
     @Fold
     public static int markOffset() {
         return config().markOffset;
     }
 
-    public static final LocationIdentity HUB_WRITE_LOCATION = NamedLocationIdentity.create("Hub:write");
+    public static final LocationIdentity HUB_WRITE_LOCATION = NamedLocationIdentity.mutable("Hub:write");
 
-    public static final LocationIdentity HUB_LOCATION = NamedLocationIdentity.create("Hub", true);
+    public static final LocationIdentity HUB_LOCATION = NamedLocationIdentity.immutable("Hub");
 
     @Fold
     private static int hubOffset() {
@@ -479,28 +479,28 @@
         return config().g1SATBQueueBufferOffset();
     }
 
-    public static final LocationIdentity KLASS_SUPER_CHECK_OFFSET_LOCATION = NamedLocationIdentity.create("Klass::_super_check_offset", true);
+    public static final LocationIdentity KLASS_SUPER_CHECK_OFFSET_LOCATION = NamedLocationIdentity.immutable("Klass::_super_check_offset");
 
     @Fold
     public static int superCheckOffsetOffset() {
         return config().superCheckOffsetOffset;
     }
 
-    public static final LocationIdentity SECONDARY_SUPER_CACHE_LOCATION = NamedLocationIdentity.create("SecondarySuperCache");
+    public static final LocationIdentity SECONDARY_SUPER_CACHE_LOCATION = NamedLocationIdentity.mutable("SecondarySuperCache");
 
     @Fold
     public static int secondarySuperCacheOffset() {
         return config().secondarySuperCacheOffset;
     }
 
-    public static final LocationIdentity SECONDARY_SUPERS_LOCATION = NamedLocationIdentity.create("SecondarySupers");
+    public static final LocationIdentity SECONDARY_SUPERS_LOCATION = NamedLocationIdentity.mutable("SecondarySupers");
 
     @Fold
     public static int secondarySupersOffset() {
         return config().secondarySupersOffset;
     }
 
-    public static final LocationIdentity DISPLACED_MARK_WORD_LOCATION = NamedLocationIdentity.create("DisplacedMarkWord");
+    public static final LocationIdentity DISPLACED_MARK_WORD_LOCATION = NamedLocationIdentity.mutable("DisplacedMarkWord");
 
     @Fold
     public static int lockDisplacedMarkOffset() {
@@ -598,7 +598,7 @@
         return CodeUtil.log2(wordSize());
     }
 
-    public static final LocationIdentity CLASS_STATE_LOCATION = NamedLocationIdentity.create("ClassState");
+    public static final LocationIdentity CLASS_STATE_LOCATION = NamedLocationIdentity.mutable("ClassState");
 
     @Fold
     public static int instanceKlassInitStateOffset() {
@@ -623,7 +623,7 @@
         return hub.readByte(instanceKlassInitStateOffset(), CLASS_STATE_LOCATION);
     }
 
-    public static final LocationIdentity KLASS_MODIFIER_FLAGS_LOCATION = NamedLocationIdentity.create("Klass::_modifier_flags", true);
+    public static final LocationIdentity KLASS_MODIFIER_FLAGS_LOCATION = NamedLocationIdentity.immutable("Klass::_modifier_flags");
 
     @Fold
     public static int klassModifierFlagsOffset() {
@@ -640,28 +640,28 @@
         return config().arrayKlassOffset;
     }
 
-    public static final LocationIdentity KLASS_NODE_CLASS = NamedLocationIdentity.create("KlassNodeClass");
+    public static final LocationIdentity KLASS_NODE_CLASS = NamedLocationIdentity.mutable("KlassNodeClass");
 
     @Fold
     public static int instanceKlassNodeClassOffset() {
         return config().instanceKlassNodeClassOffset;
     }
 
-    public static final LocationIdentity CLASS_MIRROR_LOCATION = NamedLocationIdentity.create("Klass::_java_mirror", true);
+    public static final LocationIdentity CLASS_MIRROR_LOCATION = NamedLocationIdentity.immutable("Klass::_java_mirror");
 
     @Fold
     public static int classMirrorOffset() {
         return config().classMirrorOffset;
     }
 
-    public static final LocationIdentity HEAP_TOP_LOCATION = NamedLocationIdentity.create("HeapTop");
+    public static final LocationIdentity HEAP_TOP_LOCATION = NamedLocationIdentity.mutable("HeapTop");
 
     @Fold
     public static long heapTopAddress() {
         return config().heapTopAddress;
     }
 
-    public static final LocationIdentity HEAP_END_LOCATION = NamedLocationIdentity.create("HeapEnd");
+    public static final LocationIdentity HEAP_END_LOCATION = NamedLocationIdentity.mutable("HeapEnd");
 
     @Fold
     public static long heapEndAddress() {
@@ -683,42 +683,42 @@
         return config().tlabAlignmentReserve;
     }
 
-    public static final LocationIdentity TLAB_SIZE_LOCATION = NamedLocationIdentity.create("TlabSize");
+    public static final LocationIdentity TLAB_SIZE_LOCATION = NamedLocationIdentity.mutable("TlabSize");
 
     @Fold
     public static int threadTlabSizeOffset() {
         return config().threadTlabSizeOffset();
     }
 
-    public static final LocationIdentity TLAB_THREAD_ALLOCATED_BYTES_LOCATION = NamedLocationIdentity.create("TlabThreadAllocatedBytes");
+    public static final LocationIdentity TLAB_THREAD_ALLOCATED_BYTES_LOCATION = NamedLocationIdentity.mutable("TlabThreadAllocatedBytes");
 
     @Fold
     public static int threadAllocatedBytesOffset() {
         return config().threadAllocatedBytesOffset;
     }
 
-    public static final LocationIdentity TLAB_REFILL_WASTE_LIMIT_LOCATION = NamedLocationIdentity.create("RefillWasteLimit");
+    public static final LocationIdentity TLAB_REFILL_WASTE_LIMIT_LOCATION = NamedLocationIdentity.mutable("RefillWasteLimit");
 
     @Fold
     public static int tlabRefillWasteLimitOffset() {
         return config().tlabRefillWasteLimitOffset();
     }
 
-    public static final LocationIdentity TLAB_NOF_REFILLS_LOCATION = NamedLocationIdentity.create("TlabNOfRefills");
+    public static final LocationIdentity TLAB_NOF_REFILLS_LOCATION = NamedLocationIdentity.mutable("TlabNOfRefills");
 
     @Fold
     public static int tlabNumberOfRefillsOffset() {
         return config().tlabNumberOfRefillsOffset();
     }
 
-    public static final LocationIdentity TLAB_FAST_REFILL_WASTE_LOCATION = NamedLocationIdentity.create("TlabFastRefillWaste");
+    public static final LocationIdentity TLAB_FAST_REFILL_WASTE_LOCATION = NamedLocationIdentity.mutable("TlabFastRefillWaste");
 
     @Fold
     public static int tlabFastRefillWasteOffset() {
         return config().tlabFastRefillWasteOffset();
     }
 
-    public static final LocationIdentity TLAB_SLOW_ALLOCATIONS_LOCATION = NamedLocationIdentity.create("TlabSlowAllocations");
+    public static final LocationIdentity TLAB_SLOW_ALLOCATIONS_LOCATION = NamedLocationIdentity.mutable("TlabSlowAllocations");
 
     @Fold
     public static int tlabSlowAllocationsOffset() {
@@ -818,11 +818,11 @@
         }
     }
 
-    public static final LocationIdentity OBJ_ARRAY_KLASS_ELEMENT_KLASS_LOCATION = NamedLocationIdentity.create("ObjArrayKlass::_element_klass", true);
+    public static final LocationIdentity OBJ_ARRAY_KLASS_ELEMENT_KLASS_LOCATION = NamedLocationIdentity.immutable("ObjArrayKlass::_element_klass");
 
-    public static final LocationIdentity PRIMARY_SUPERS_LOCATION = NamedLocationIdentity.create("PrimarySupers", true);
+    public static final LocationIdentity PRIMARY_SUPERS_LOCATION = NamedLocationIdentity.immutable("PrimarySupers");
 
-    public static final LocationIdentity METASPACE_ARRAY_LENGTH_LOCATION = NamedLocationIdentity.create("MetaspaceArrayLength", true);
+    public static final LocationIdentity METASPACE_ARRAY_LENGTH_LOCATION = NamedLocationIdentity.immutable("MetaspaceArrayLength");
 
-    public static final LocationIdentity SECONDARY_SUPERS_ELEMENT_LOCATION = NamedLocationIdentity.create("SecondarySupersElement", true);
+    public static final LocationIdentity SECONDARY_SUPERS_ELEMENT_LOCATION = NamedLocationIdentity.immutable("SecondarySupersElement");
 }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/MonitorSnippets.java	Mon Nov 10 18:16:21 2014 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/MonitorSnippets.java	Mon Nov 10 18:18:42 2014 +0100
@@ -369,7 +369,7 @@
      */
     private static final boolean ENABLE_BREAKPOINT = false;
 
-    private static final LocationIdentity MONITOR_COUNTER_LOCATION = NamedLocationIdentity.create("MonitorCounter");
+    private static final LocationIdentity MONITOR_COUNTER_LOCATION = NamedLocationIdentity.mutable("MonitorCounter");
 
     @NodeIntrinsic(BreakpointNode.class)
     static native void bkpt(Object object, Word mark, Word tmp, Word value);
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/NewObjectSnippets.java	Mon Nov 10 18:16:21 2014 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/NewObjectSnippets.java	Mon Nov 10 18:18:42 2014 +0100
@@ -62,7 +62,7 @@
  */
 public class NewObjectSnippets implements Snippets {
 
-    public static final LocationIdentity INIT_LOCATION = NamedLocationIdentity.create("Initialization");
+    public static final LocationIdentity INIT_LOCATION = NamedLocationIdentity.mutable("Initialization");
 
     static class Options {
 
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/WriteBarrierSnippets.java	Mon Nov 10 18:16:21 2014 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/WriteBarrierSnippets.java	Mon Nov 10 18:18:42 2014 +0100
@@ -63,9 +63,9 @@
                     "Number of effective G1 Post Write Barriers (after passing the NULL test)");
     private static final SnippetCounter g1ExecutedPostWriteBarrierCounter = new SnippetCounter(countersWriteBarriers, "g1ExecutedPostWriteBarrier", "Number of executed G1 Post Write Barriers");
 
-    public static final LocationIdentity GC_CARD_LOCATION = NamedLocationIdentity.create("GC-Card");
-    public static final LocationIdentity GC_LOG_LOCATION = NamedLocationIdentity.create("GC-Log");
-    public static final LocationIdentity GC_INDEX_LOCATION = NamedLocationIdentity.create("GC-Index");
+    public static final LocationIdentity GC_CARD_LOCATION = NamedLocationIdentity.mutable("GC-Card");
+    public static final LocationIdentity GC_LOG_LOCATION = NamedLocationIdentity.mutable("GC-Log");
+    public static final LocationIdentity GC_INDEX_LOCATION = NamedLocationIdentity.mutable("GC-Index");
 
     @Snippet
     public static void serialWriteBarrier(Object object, Object location, @ConstantParameter boolean usePrecise) {
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/UncommonTrapStub.java	Mon Nov 10 18:16:21 2014 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/UncommonTrapStub.java	Mon Nov 10 18:18:42 2014 +0100
@@ -78,7 +78,7 @@
  */
 public class UncommonTrapStub extends SnippetStub {
 
-    public static final LocationIdentity STACK_BANG_LOCATION = NamedLocationIdentity.create("stack bang");
+    public static final LocationIdentity STACK_BANG_LOCATION = NamedLocationIdentity.mutable("stack bang");
 
     private final TargetDescription target;
 
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/MethodCallTargetNode.java	Mon Nov 10 18:16:21 2014 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/MethodCallTargetNode.java	Mon Nov 10 18:18:42 2014 +0100
@@ -149,19 +149,35 @@
                     }
                 }
             }
+            // try to turn a interface call into a virtual call
             ResolvedJavaType declaredReceiverType = targetMethod().getDeclaringClass();
-            if (declaredReceiverType.isInterface()) {
+            /*
+             * We need to check the invoke kind to avoid recursive simplification for virtual
+             * interface methods calls.
+             */
+            if (declaredReceiverType.isInterface() && !invokeKind().equals(InvokeKind.Virtual)) {
                 ResolvedJavaType singleImplementor = declaredReceiverType.getSingleImplementor();
                 if (singleImplementor != null && !singleImplementor.equals(declaredReceiverType)) {
                     ResolvedJavaMethod singleImplementorMethod = singleImplementor.resolveMethod(targetMethod(), invoke().getContextType(), true);
-                    // TODO (je): we can not yet deal with default methods
-                    if (singleImplementorMethod != null && !singleImplementorMethod.isDefault()) {
+                    if (singleImplementorMethod != null) {
+                        assert graph().getGuardsStage().ordinal() < StructuredGraph.GuardsStage.FIXED_DEOPTS.ordinal() : "Graph already fixed!";
+                        /**
+                         * We have an invoke on an interface with a single implementor. We can
+                         * replace this with an invoke virtual.
+                         *
+                         * To do so we need to ensure two properties: 1) the receiver must implement
+                         * the interface (declaredReceiverType). The verifier does not prove this so
+                         * we need a dynamic check. 2) we need to ensure that there is still only
+                         * one implementor of this interface, i.e. that we are calling the right
+                         * method. We could do this with an assumption but as we need an instanceof
+                         * check anyway we can verify both properties by checking of the receiver is
+                         * an instance of the single implementor.
+                         */
                         LogicNode condition = graph().unique(InstanceOfNode.create(singleImplementor, receiver, getProfile()));
-                        assert graph().getGuardsStage().ordinal() < StructuredGraph.GuardsStage.FIXED_DEOPTS.ordinal() : "Graph already fixed!";
                         GuardNode guard = graph().unique(
                                         GuardNode.create(condition, BeginNode.prevBegin(invoke().asNode()), DeoptimizationReason.OptimizedTypeCheckViolated, DeoptimizationAction.InvalidateRecompile,
                                                         false, JavaConstant.NULL_OBJECT));
-                        PiNode piNode = graph().unique(PiNode.create(receiver, StampFactory.declared(singleImplementor), guard));
+                        PiNode piNode = graph().unique(PiNode.create(receiver, StampFactory.declaredNonNull(singleImplementor), guard));
                         arguments().set(0, piNode);
                         setInvokeKind(InvokeKind.Virtual);
                         setTargetMethod(singleImplementorMethod);
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/FloatingReadPhase.java	Mon Nov 10 18:16:21 2014 +0100
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/FloatingReadPhase.java	Mon Nov 10 18:18:42 2014 +0100
@@ -52,16 +52,16 @@
         private final Map<LocationIdentity, MemoryNode> lastMemorySnapshot;
 
         public MemoryMapImpl(MemoryMapImpl memoryMap) {
-            lastMemorySnapshot = newIdentityMap(memoryMap.lastMemorySnapshot);
+            lastMemorySnapshot = new HashMap<>(memoryMap.lastMemorySnapshot);
         }
 
         public MemoryMapImpl(StartNode start) {
-            lastMemorySnapshot = newIdentityMap();
+            lastMemorySnapshot = new HashMap<>();
             lastMemorySnapshot.put(ANY_LOCATION, start);
         }
 
         public MemoryMapImpl() {
-            lastMemorySnapshot = newIdentityMap();
+            lastMemorySnapshot = new HashMap<>();
         }
 
         @Override
--- a/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/ObjectAccessTest.java	Mon Nov 10 18:16:21 2014 +0100
+++ b/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/ObjectAccessTest.java	Mon Nov 10 18:18:42 2014 +0100
@@ -40,7 +40,7 @@
  */
 public class ObjectAccessTest extends GraalCompilerTest implements Snippets {
 
-    private static final LocationIdentity ID = NamedLocationIdentity.create("ObjectAccessTestID");
+    private static final LocationIdentity ID = NamedLocationIdentity.mutable("ObjectAccessTestID");
     private static final Kind[] KINDS = new Kind[]{Kind.Byte, Kind.Char, Kind.Short, Kind.Int, Kind.Long, Kind.Float, Kind.Double, Kind.Object};
     private final ReplacementsImpl installer;
 
--- a/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/PointerTest.java	Mon Nov 10 18:16:21 2014 +0100
+++ b/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/PointerTest.java	Mon Nov 10 18:18:42 2014 +0100
@@ -44,7 +44,7 @@
  */
 public class PointerTest extends GraalCompilerTest implements Snippets {
 
-    private static final LocationIdentity ID = NamedLocationIdentity.create("ID");
+    private static final LocationIdentity ID = NamedLocationIdentity.mutable("ID");
     private static final Kind[] KINDS = new Kind[]{Kind.Byte, Kind.Char, Kind.Short, Kind.Int, Kind.Long, Kind.Float, Kind.Double, Kind.Object};
     private final TargetDescription target;
     private final ReplacementsImpl installer;
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/SnippetCounter.java	Mon Nov 10 18:16:21 2014 +0100
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/SnippetCounter.java	Mon Nov 10 18:18:42 2014 +0100
@@ -132,7 +132,7 @@
      * usage in snippets is always possible. If a method accesses the counter via the field and the
      * snippet, the result might not be correct though.
      */
-    protected static final LocationIdentity SNIPPET_COUNTER_LOCATION = NamedLocationIdentity.create("SnippetCounter");
+    protected static final LocationIdentity SNIPPET_COUNTER_LOCATION = NamedLocationIdentity.mutable("SnippetCounter");
 
     /**
      * Increments the value of this counter. This method can be safely used in a snippet if it is
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedDirectCallNode.java	Mon Nov 10 18:16:21 2014 +0100
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedDirectCallNode.java	Mon Nov 10 18:18:42 2014 +0100
@@ -173,8 +173,4 @@
         return true;
     }
 
-    @Override
-    public String toString() {
-        return String.format("OptimizedDirectCallNode(target=%s, parent=%s)", getCurrentCallTarget().toString(), getParent());
-    }
 }
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/ObjectLocationIdentity.java	Mon Nov 10 18:16:21 2014 +0100
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/ObjectLocationIdentity.java	Mon Nov 10 18:18:42 2014 +0100
@@ -31,21 +31,25 @@
  */
 public final class ObjectLocationIdentity implements LocationIdentity {
 
-    private static HashMap<JavaConstant, LocationIdentity> map = new HashMap<>();
-
     private JavaConstant object;
 
     public static LocationIdentity create(JavaConstant 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;
-            }
+        return new ObjectLocationIdentity(object);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (obj instanceof ObjectLocationIdentity) {
+            ObjectLocationIdentity that = (ObjectLocationIdentity) obj;
+            return Objects.equals(that.object, this.object);
         }
+        return false;
+    }
+
+    @Override
+    public int hashCode() {
+        return object.hashCode();
     }
 
     private ObjectLocationIdentity(JavaConstant object) {
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/typesystem/CustomizedUnsafeLoadMacroNode.java	Mon Nov 10 18:16:21 2014 +0100
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/typesystem/CustomizedUnsafeLoadMacroNode.java	Mon Nov 10 18:18:42 2014 +0100
@@ -35,7 +35,8 @@
 import com.oracle.truffle.api.*;
 
 /**
- * Macro node for method {@link CompilerDirectives#unsafeCast(Object, Class, boolean)}.
+ * Macro node for {@link CompilerDirectives#unsafeGetInt(Object, long, boolean, Object)} and
+ * friends.
  */
 @NodeInfo
 public class CustomizedUnsafeLoadMacroNode extends NeverPartOfCompilationNode implements Canonicalizable {
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/CompilerDirectives.java	Mon Nov 10 18:16:21 2014 +0100
+++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/CompilerDirectives.java	Mon Nov 10 18:18:42 2014 +0100
@@ -114,6 +114,12 @@
      * </code>
      * </pre>
      *
+     * Note that optimizations that a compiler will apply to code that is conditional on
+     * <code>isCompilationConstant</code> may be limited. For this reason
+     * <code>isCompilationConstant</code> is not recommended for use to select between alternate
+     * implementations of functionality depending on whether a value is constant. Instead, it is
+     * intended for use as a diagnostic mechanism, such as illustrated above.
+     *
      * @param value
      * @return {@code true} when given value is seen as compilation constant, {@code false} if not
      *         compilation constant.
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/DefaultDirectCallNode.java	Mon Nov 10 18:16:21 2014 +0100
+++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/DefaultDirectCallNode.java	Mon Nov 10 18:18:42 2014 +0100
@@ -98,11 +98,6 @@
         return false;
     }
 
-    @Override
-    public String toString() {
-        return (getParent() != null ? getParent().toString() : super.toString()) + " call " + getCurrentCallTarget().toString();
-    }
-
     private static DefaultTruffleRuntime defaultTruffleRuntime() {
         return (DefaultTruffleRuntime) Truffle.getRuntime();
     }
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/DirectCallNode.java	Mon Nov 10 18:16:21 2014 +0100
+++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/DirectCallNode.java	Mon Nov 10 18:18:42 2014 +0100
@@ -175,4 +175,10 @@
         }
         return null;
     }
+
+    @Override
+    public String toString() {
+        return String.format("%s(target=%s)", getClass().getSimpleName(), getCurrentCallTarget());
+    }
+
 }
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/RootNode.java	Mon Nov 10 18:16:21 2014 +0100
+++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/RootNode.java	Mon Nov 10 18:18:42 2014 +0100
@@ -107,4 +107,23 @@
         this.callTarget = callTarget;
     }
 
+    /**
+     * Returns the {@link ExecutionContext} associated with this <code>RootNode</code>. This allows
+     * the correct <code>ExecutionContext</code> to be determined for a <code>RootNode</code> (and
+     * so also for a {@link RootCallTarget} and a {@link FrameInstance} obtained from the call
+     * stack) without prior knowledge of the language it has come from.
+     *
+     * Used for instance to determine the language of a <code>RootNode<code>:
+     *
+     * <pre>
+     * <code>
+     * rootNode.getExecutionContext().getLanguageShortName();
+     * </code> </pre>
+     *
+     * Returns <code>null</code> by default.
+     */
+    public ExecutionContext getExecutionContext() {
+        return null;
+    }
+
 }
--- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/SLRootNode.java	Mon Nov 10 18:16:21 2014 +0100
+++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/SLRootNode.java	Mon Nov 10 18:18:42 2014 +0100
@@ -22,6 +22,7 @@
  */
 package com.oracle.truffle.sl.nodes;
 
+import com.oracle.truffle.api.*;
 import com.oracle.truffle.api.CompilerDirectives.*;
 import com.oracle.truffle.api.frame.*;
 import com.oracle.truffle.api.nodes.*;
@@ -86,4 +87,9 @@
     public SLContext getSLContext() {
         return this.context;
     }
+
+    @Override
+    public ExecutionContext getExecutionContext() {
+        return this.context;
+    }
 }
--- a/mx/mx_graal.py	Mon Nov 10 18:16:21 2014 +0100
+++ b/mx/mx_graal.py	Mon Nov 10 18:18:42 2014 +0100
@@ -1959,7 +1959,7 @@
         absoluteMicro = os.path.join(jmhPath, suite)
         (pfx, exe, vm, forkedVmArgs, _) = _parseVmArgs(vmArgs)
         if pfx:
-            mx.warn("JMH ignores prefix: \"" + pfx + "\"")
+            mx.log("JMH ignores prefix: \"" + ' '.join(pfx) + "\"")
         javaArgs = ['-jar', os.path.join(absoluteMicro, "target", "microbenchmarks.jar"),
                     '--jvm', exe,
                     '--jvmArgs', ' '.join(["-" + vm] + forkedVmArgs)]