8182883: Update Graal
authoriveresov
Mon, 26 Jun 2017 16:10:31 -0700
changeset 46566 231c681fa946
parent 46565 8dcbf532ea00
child 46567 30efdd5f0dc9
8182883: Update Graal Reviewed-by: kvn
hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/ByteBufferTest.java
hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/DirectByteBufferTest.java
hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.graph/src/org/graalvm/compiler/graph/NodeClass.java
hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/CheckGraalIntrinsics.java
hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/HotSpotGraalMBeanTest.java
hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/GraalHotSpotVMConfig.java
hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/JVMCIVersionCheck.java
hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotClassInitializationPlugin.java
hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/phases/aot/EliminateRedundantInitializationPhase.java
hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/phases/aot/ReplaceConstantNodesPhase.java
hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/NewObjectSnippets.java
hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.java/src/org/graalvm/compiler/java/BytecodeParser.java
hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.java/src/org/graalvm/compiler/java/BytecodeParserOptions.java
hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes.test/src/org/graalvm/compiler/nodes/test/AddNodeTest.java
hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes.test/src/org/graalvm/compiler/nodes/test/StaticFieldAccessTest.java
hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/StructuredGraph.java
hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/DynamicNewArrayNode.java
hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/DynamicNewInstanceNode.java
hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/inlining/InliningUtil.java
hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.options/src/org/graalvm/options/OptionDescriptors.java
hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.options/src/org/graalvm/options/OptionKey.java
hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.options/src/org/graalvm/options/OptionValues.java
hotspot/test/compiler/aot/scripts/build-bootmodules.sh
--- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/ByteBufferTest.java	Tue Apr 11 23:45:37 2017 +0200
+++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/ByteBufferTest.java	Mon Jun 26 16:10:31 2017 -0700
@@ -40,6 +40,7 @@
         byte byteValue = 0;
         short shortValue = 0;
         int intValue = 0;
+        long longValue = 0;
         float floatValue = 0.0f;
         double doubleValue = 0.0d;
 
@@ -59,6 +60,9 @@
             if (this.intValue != other.intValue) {
                 return false;
             }
+            if (this.longValue != other.longValue) {
+                return false;
+            }
             if (Float.floatToRawIntBits(this.floatValue) != Float.floatToRawIntBits(other.floatValue)) {
                 return false;
             }
@@ -98,6 +102,7 @@
         ret.byteValue += buffer.get();
         ret.shortValue = buffer.getShort();
         ret.intValue = buffer.getInt();
+        ret.longValue = buffer.getLong();
         ret.doubleValue = buffer.getDouble();
         ret.floatValue = buffer.getFloat();
 
@@ -106,30 +111,31 @@
 
     @Test
     public void testReadAligned() {
-        byte[] input = new byte[20];
-        for (int i = 0; i < 20; i++) {
+        byte[] input = new byte[28];
+        for (int i = 0; i < 28; i++) {
             input[i] = (byte) (7 * (i + 42));
         }
         test("alignedReadSnippet", input);
     }
 
-    byte[] alignedWriteSnippet(byte a, byte b, short c, int d, double e, float f) {
-        byte[] ret = new byte[20];
+    byte[] alignedWriteSnippet(byte a, byte b, short c, int d, long e, double f, float g) {
+        byte[] ret = new byte[28];
         ByteBuffer buffer = ByteBuffer.wrap(ret).order(byteOrder);
 
         buffer.put(a);
         buffer.put(b);
         buffer.putShort(c);
         buffer.putInt(d);
-        buffer.putDouble(e);
-        buffer.putFloat(f);
+        buffer.putLong(e);
+        buffer.putDouble(f);
+        buffer.putFloat(g);
 
         return ret;
     }
 
     @Test
     public void testWriteAligned() {
-        test("alignedWriteSnippet", (byte) 5, (byte) -3, (short) 17, 42, 84.72, 1.23f);
+        test("alignedWriteSnippet", (byte) 5, (byte) -3, (short) 17, 42, 0x3FC30A25644B7130L, 84.72, 1.23f);
     }
 
     Ret unalignedReadSnippet(byte[] arg) {
@@ -139,6 +145,7 @@
         ret.byteValue = buffer.get();
         ret.shortValue = buffer.getShort();
         ret.intValue = buffer.getInt();
+        ret.longValue = buffer.getLong();
         ret.doubleValue = buffer.getDouble();
         ret.floatValue = buffer.getFloat();
 
@@ -147,28 +154,29 @@
 
     @Test
     public void testReadUnaligned() {
-        byte[] input = new byte[19];
-        for (int i = 0; i < 19; i++) {
+        byte[] input = new byte[27];
+        for (int i = 0; i < 27; i++) {
             input[i] = (byte) (7 * (i + 42));
         }
         test("unalignedReadSnippet", input);
     }
 
-    byte[] unalignedWriteSnippet(byte a, short b, int c, double d, float e) {
-        byte[] ret = new byte[20];
+    byte[] unalignedWriteSnippet(byte a, short b, int c, long d, double e, float f) {
+        byte[] ret = new byte[27];
         ByteBuffer buffer = ByteBuffer.wrap(ret).order(byteOrder);
 
         buffer.put(a);
         buffer.putShort(b);
         buffer.putInt(c);
-        buffer.putDouble(d);
-        buffer.putFloat(e);
+        buffer.putLong(d);
+        buffer.putDouble(e);
+        buffer.putFloat(f);
 
         return ret;
     }
 
     @Test
     public void testWriteUnaligned() {
-        test("unalignedWriteSnippet", (byte) -3, (short) 17, 42, 84.72, 1.23f);
+        test("unalignedWriteSnippet", (byte) -3, (short) 17, 42, 0x3FC30A25644B7130L, 84.72, 1.23f);
     }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/DirectByteBufferTest.java	Mon Jun 26 16:10:31 2017 -0700
@@ -0,0 +1,202 @@
+/*
+ * Copyright (c) 2017, 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 org.graalvm.compiler.core.test;
+
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.util.ArrayList;
+import java.util.Collection;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameter;
+import org.junit.runners.Parameterized.Parameters;
+
+@RunWith(Parameterized.class)
+public class DirectByteBufferTest extends GraalCompilerTest {
+
+    class Ret {
+
+        byte byteValue = 0;
+        short shortValue = 0;
+        int intValue = 0;
+        long longValue = 0;
+        float floatValue = 0.0f;
+        double doubleValue = 0.0d;
+
+        @Override
+        public boolean equals(Object obj) {
+            if (!(obj instanceof Ret)) {
+                return false;
+            }
+
+            Ret other = (Ret) obj;
+            if (this.byteValue != other.byteValue) {
+                return false;
+            }
+            if (this.shortValue != other.shortValue) {
+                return false;
+            }
+            if (this.intValue != other.intValue) {
+                return false;
+            }
+            if (this.longValue != other.longValue) {
+                return false;
+            }
+            if (Float.floatToRawIntBits(this.floatValue) != Float.floatToRawIntBits(other.floatValue)) {
+                return false;
+            }
+            if (Double.doubleToRawLongBits(this.doubleValue) != Double.doubleToRawLongBits(other.doubleValue)) {
+                return false;
+            }
+
+            return true;
+        }
+
+        @Override
+        public int hashCode() {
+            return 0;
+        }
+
+        @Override
+        public String toString() {
+            return String.format("0x%02x, 0x%04x, 0x%08x, 0x%016x,0x%08x, 0x%016x", byteValue, shortValue, intValue, Float.floatToRawIntBits(floatValue), Double.doubleToRawLongBits(doubleValue));
+        }
+    }
+
+    @Parameters(name = "{0}")
+    public static Collection<Object[]> data() {
+        ArrayList<Object[]> ret = new ArrayList<>();
+        ret.add(new Object[]{ByteOrder.BIG_ENDIAN});
+        ret.add(new Object[]{ByteOrder.LITTLE_ENDIAN});
+        return ret;
+    }
+
+    @Parameter public ByteOrder byteOrder;
+
+    Ret alignedReadSnippet(byte[] arg) {
+        ByteBuffer buffer = makeDirect(arg, byteOrder);
+
+        Ret ret = new Ret();
+        ret.byteValue = buffer.get();
+        ret.byteValue += buffer.get();
+        ret.shortValue = buffer.getShort();
+        ret.intValue = buffer.getInt();
+        ret.longValue = buffer.getLong();
+        ret.doubleValue = buffer.getDouble();
+        ret.floatValue = buffer.getFloat();
+
+        return ret;
+    }
+
+    @Test
+    public void testReadAligned() {
+        byte[] input = new byte[28];
+        for (int i = 0; i < 28; i++) {
+            input[i] = (byte) (7 * (i + 42));
+        }
+        test("alignedReadSnippet", input);
+    }
+
+    byte[] alignedWriteSnippet(byte a, byte b, short c, int d, long e, double f, float g) {
+        byte[] ret = new byte[28];
+        ByteBuffer buffer = makeDirect(28, byteOrder);
+
+        buffer.put(a);
+        buffer.put(b);
+        buffer.putShort(c);
+        buffer.putInt(d);
+        buffer.putLong(e);
+        buffer.putDouble(f);
+        buffer.putFloat(g);
+
+        buffer.position(0);
+        buffer.get(ret);
+
+        return ret;
+    }
+
+    @Test
+    public void testWriteAligned() {
+        test("alignedWriteSnippet", (byte) 5, (byte) -3, (short) 17, 42, 0x3FC30A25644B7130L, 84.72, 1.23f);
+    }
+
+    Ret unalignedReadSnippet(byte[] arg) {
+        ByteBuffer buffer = makeDirect(arg, byteOrder);
+
+        Ret ret = new Ret();
+        ret.byteValue = buffer.get();
+        ret.shortValue = buffer.getShort();
+        ret.intValue = buffer.getInt();
+        ret.longValue = buffer.getLong();
+        ret.doubleValue = buffer.getDouble();
+        ret.floatValue = buffer.getFloat();
+
+        return ret;
+    }
+
+    @Test
+    public void testReadUnaligned() {
+        byte[] input = new byte[27];
+        for (int i = 0; i < 27; i++) {
+            input[i] = (byte) (7 * (i + 42));
+        }
+        test("unalignedReadSnippet", input);
+    }
+
+    byte[] unalignedWriteSnippet(byte a, short b, int c, long d, double e, float f) {
+        byte[] ret = new byte[27];
+        ByteBuffer buffer = makeDirect(27, byteOrder);
+
+        buffer.put(a);
+        buffer.putShort(b);
+        buffer.putInt(c);
+        buffer.putLong(d);
+        buffer.putDouble(e);
+        buffer.putFloat(f);
+
+        buffer.position(0);
+        buffer.get(ret);
+
+        return ret;
+    }
+
+    @Test
+    public void testWriteUnaligned() {
+        test("unalignedWriteSnippet", (byte) -3, (short) 17, 42, 0x3FC30A25644B7130L, 84.72, 1.23f);
+    }
+
+    private static ByteBuffer makeDirect(byte[] bytes, ByteOrder byteOrder) {
+        int length = bytes.length;
+        ByteBuffer buffer = ByteBuffer.allocateDirect(length).order(byteOrder);
+        buffer.put(bytes);
+        buffer.position(0);
+        return buffer;
+    }
+
+    private static ByteBuffer makeDirect(int length, ByteOrder byteOrder) {
+        ByteBuffer buffer = ByteBuffer.allocateDirect(length).order(byteOrder);
+        buffer.position(0);
+        return buffer;
+    }
+}
--- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.graph/src/org/graalvm/compiler/graph/NodeClass.java	Tue Apr 11 23:45:37 2017 +0200
+++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.graph/src/org/graalvm/compiler/graph/NodeClass.java	Mon Jun 26 16:10:31 2017 -0700
@@ -210,7 +210,13 @@
 
         NodeInfo info = getAnnotationTimed(clazz, NodeInfo.class);
         assert info != null : "Missing NodeInfo annotation on " + clazz;
-        this.nameTemplate = info.nameTemplate();
+        if (!info.nameTemplate().isEmpty()) {
+            this.nameTemplate = info.nameTemplate();
+        } else if (!info.shortName().isEmpty()) {
+            this.nameTemplate = info.shortName();
+        } else {
+            this.nameTemplate = "";
+        }
 
         try (DebugCloseable t1 = Init_AllowedUsages.start()) {
             allowedUsageTypes = superNodeClass == null ? EnumSet.noneOf(InputType.class) : superNodeClass.allowedUsageTypes.clone();
@@ -809,8 +815,9 @@
 
     /**
      * The template used to build the {@link Verbosity#Name} version. Variable parts are specified
-     * using &#123;i#inputName&#125; or &#123;p#propertyName&#125;. Returns empty string if no
-     * special name template is specified.
+     * using &#123;i#inputName&#125; or &#123;p#propertyName&#125;. If no
+     * {@link NodeInfo#nameTemplate() template} is specified, it uses {@link NodeInfo#shortName()}.
+     * If none of the two is specified, it returns an empty string.
      */
     public String getNameTemplate() {
         return nameTemplate;
--- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/CheckGraalIntrinsics.java	Tue Apr 11 23:45:37 2017 +0200
+++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/CheckGraalIntrinsics.java	Mon Jun 26 16:10:31 2017 -0700
@@ -244,23 +244,23 @@
                         "java/util/zip/Adler32.updateByteBuffer(IJII)I",
                         "java/util/zip/Adler32.updateBytes(I[BII)I",
                         "jdk/internal/misc/Unsafe.allocateUninitializedArray0(Ljava/lang/Class;I)Ljava/lang/Object;",
+                        "jdk/internal/misc/Unsafe.compareAndExchangeByte(Ljava/lang/Object;JBB)B",
                         "jdk/internal/misc/Unsafe.compareAndExchangeByteAcquire(Ljava/lang/Object;JBB)B",
                         "jdk/internal/misc/Unsafe.compareAndExchangeByteRelease(Ljava/lang/Object;JBB)B",
-                        "jdk/internal/misc/Unsafe.compareAndExchangeByteVolatile(Ljava/lang/Object;JBB)B",
+                        "jdk/internal/misc/Unsafe.compareAndExchangeInt(Ljava/lang/Object;JII)I",
                         "jdk/internal/misc/Unsafe.compareAndExchangeIntAcquire(Ljava/lang/Object;JII)I",
                         "jdk/internal/misc/Unsafe.compareAndExchangeIntRelease(Ljava/lang/Object;JII)I",
-                        "jdk/internal/misc/Unsafe.compareAndExchangeIntVolatile(Ljava/lang/Object;JII)I",
+                        "jdk/internal/misc/Unsafe.compareAndExchangeLong(Ljava/lang/Object;JJJ)J",
                         "jdk/internal/misc/Unsafe.compareAndExchangeLongAcquire(Ljava/lang/Object;JJJ)J",
                         "jdk/internal/misc/Unsafe.compareAndExchangeLongRelease(Ljava/lang/Object;JJJ)J",
-                        "jdk/internal/misc/Unsafe.compareAndExchangeLongVolatile(Ljava/lang/Object;JJJ)J",
+                        "jdk/internal/misc/Unsafe.compareAndExchangeObject(Ljava/lang/Object;JLjava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;",
                         "jdk/internal/misc/Unsafe.compareAndExchangeObjectAcquire(Ljava/lang/Object;JLjava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;",
                         "jdk/internal/misc/Unsafe.compareAndExchangeObjectRelease(Ljava/lang/Object;JLjava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;",
-                        "jdk/internal/misc/Unsafe.compareAndExchangeObjectVolatile(Ljava/lang/Object;JLjava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;",
+                        "jdk/internal/misc/Unsafe.compareAndExchangeShort(Ljava/lang/Object;JSS)S",
                         "jdk/internal/misc/Unsafe.compareAndExchangeShortAcquire(Ljava/lang/Object;JSS)S",
                         "jdk/internal/misc/Unsafe.compareAndExchangeShortRelease(Ljava/lang/Object;JSS)S",
-                        "jdk/internal/misc/Unsafe.compareAndExchangeShortVolatile(Ljava/lang/Object;JSS)S",
-                        "jdk/internal/misc/Unsafe.compareAndSwapByte(Ljava/lang/Object;JBB)Z",
-                        "jdk/internal/misc/Unsafe.compareAndSwapShort(Ljava/lang/Object;JSS)Z",
+                        "jdk/internal/misc/Unsafe.compareAndSetByte(Ljava/lang/Object;JBB)Z",
+                        "jdk/internal/misc/Unsafe.compareAndSetShort(Ljava/lang/Object;JSS)Z",
                         "jdk/internal/misc/Unsafe.copyMemory0(Ljava/lang/Object;JLjava/lang/Object;JJ)V",
                         "jdk/internal/misc/Unsafe.getAndAddByte(Ljava/lang/Object;JB)B",
                         "jdk/internal/misc/Unsafe.getAndAddShort(Ljava/lang/Object;JS)S",
@@ -295,26 +295,26 @@
                         "jdk/internal/misc/Unsafe.putObjectOpaque(Ljava/lang/Object;JLjava/lang/Object;)V",
                         "jdk/internal/misc/Unsafe.putShortOpaque(Ljava/lang/Object;JS)V",
                         "jdk/internal/misc/Unsafe.unpark(Ljava/lang/Object;)V",
-                        "jdk/internal/misc/Unsafe.weakCompareAndSwapByte(Ljava/lang/Object;JBB)Z",
-                        "jdk/internal/misc/Unsafe.weakCompareAndSwapByteAcquire(Ljava/lang/Object;JBB)Z",
-                        "jdk/internal/misc/Unsafe.weakCompareAndSwapByteRelease(Ljava/lang/Object;JBB)Z",
-                        "jdk/internal/misc/Unsafe.weakCompareAndSwapByteVolatile(Ljava/lang/Object;JBB)Z",
-                        "jdk/internal/misc/Unsafe.weakCompareAndSwapInt(Ljava/lang/Object;JII)Z",
-                        "jdk/internal/misc/Unsafe.weakCompareAndSwapIntAcquire(Ljava/lang/Object;JII)Z",
-                        "jdk/internal/misc/Unsafe.weakCompareAndSwapIntRelease(Ljava/lang/Object;JII)Z",
-                        "jdk/internal/misc/Unsafe.weakCompareAndSwapIntVolatile(Ljava/lang/Object;JII)Z",
-                        "jdk/internal/misc/Unsafe.weakCompareAndSwapLong(Ljava/lang/Object;JJJ)Z",
-                        "jdk/internal/misc/Unsafe.weakCompareAndSwapLongAcquire(Ljava/lang/Object;JJJ)Z",
-                        "jdk/internal/misc/Unsafe.weakCompareAndSwapLongRelease(Ljava/lang/Object;JJJ)Z",
-                        "jdk/internal/misc/Unsafe.weakCompareAndSwapLongVolatile(Ljava/lang/Object;JJJ)Z",
-                        "jdk/internal/misc/Unsafe.weakCompareAndSwapObject(Ljava/lang/Object;JLjava/lang/Object;Ljava/lang/Object;)Z",
-                        "jdk/internal/misc/Unsafe.weakCompareAndSwapObjectAcquire(Ljava/lang/Object;JLjava/lang/Object;Ljava/lang/Object;)Z",
-                        "jdk/internal/misc/Unsafe.weakCompareAndSwapObjectRelease(Ljava/lang/Object;JLjava/lang/Object;Ljava/lang/Object;)Z",
-                        "jdk/internal/misc/Unsafe.weakCompareAndSwapObjectVolatile(Ljava/lang/Object;JLjava/lang/Object;Ljava/lang/Object;)Z",
-                        "jdk/internal/misc/Unsafe.weakCompareAndSwapShort(Ljava/lang/Object;JSS)Z",
-                        "jdk/internal/misc/Unsafe.weakCompareAndSwapShortAcquire(Ljava/lang/Object;JSS)Z",
-                        "jdk/internal/misc/Unsafe.weakCompareAndSwapShortRelease(Ljava/lang/Object;JSS)Z",
-                        "jdk/internal/misc/Unsafe.weakCompareAndSwapShortVolatile(Ljava/lang/Object;JSS)Z",
+                        "jdk/internal/misc/Unsafe.weakCompareAndSetByte(Ljava/lang/Object;JBB)Z",
+                        "jdk/internal/misc/Unsafe.weakCompareAndSetByteAcquire(Ljava/lang/Object;JBB)Z",
+                        "jdk/internal/misc/Unsafe.weakCompareAndSetBytePlain(Ljava/lang/Object;JBB)Z",
+                        "jdk/internal/misc/Unsafe.weakCompareAndSetByteRelease(Ljava/lang/Object;JBB)Z",
+                        "jdk/internal/misc/Unsafe.weakCompareAndSetInt(Ljava/lang/Object;JII)Z",
+                        "jdk/internal/misc/Unsafe.weakCompareAndSetIntAcquire(Ljava/lang/Object;JII)Z",
+                        "jdk/internal/misc/Unsafe.weakCompareAndSetIntPlain(Ljava/lang/Object;JII)Z",
+                        "jdk/internal/misc/Unsafe.weakCompareAndSetIntRelease(Ljava/lang/Object;JII)Z",
+                        "jdk/internal/misc/Unsafe.weakCompareAndSetLong(Ljava/lang/Object;JJJ)Z",
+                        "jdk/internal/misc/Unsafe.weakCompareAndSetLongAcquire(Ljava/lang/Object;JJJ)Z",
+                        "jdk/internal/misc/Unsafe.weakCompareAndSetLongPlain(Ljava/lang/Object;JJJ)Z",
+                        "jdk/internal/misc/Unsafe.weakCompareAndSetLongRelease(Ljava/lang/Object;JJJ)Z",
+                        "jdk/internal/misc/Unsafe.weakCompareAndSetObject(Ljava/lang/Object;JLjava/lang/Object;Ljava/lang/Object;)Z",
+                        "jdk/internal/misc/Unsafe.weakCompareAndSetObjectAcquire(Ljava/lang/Object;JLjava/lang/Object;Ljava/lang/Object;)Z",
+                        "jdk/internal/misc/Unsafe.weakCompareAndSetObjectPlain(Ljava/lang/Object;JLjava/lang/Object;Ljava/lang/Object;)Z",
+                        "jdk/internal/misc/Unsafe.weakCompareAndSetObjectRelease(Ljava/lang/Object;JLjava/lang/Object;Ljava/lang/Object;)Z",
+                        "jdk/internal/misc/Unsafe.weakCompareAndSetShort(Ljava/lang/Object;JSS)Z",
+                        "jdk/internal/misc/Unsafe.weakCompareAndSetShortAcquire(Ljava/lang/Object;JSS)Z",
+                        "jdk/internal/misc/Unsafe.weakCompareAndSetShortPlain(Ljava/lang/Object;JSS)Z",
+                        "jdk/internal/misc/Unsafe.weakCompareAndSetShortRelease(Ljava/lang/Object;JSS)Z",
                         "jdk/internal/util/Preconditions.checkIndex(IILjava/util/function/BiFunction;)I",
                         "jdk/jfr/internal/JVM.counterTime()J",
                         "jdk/jfr/internal/JVM.getBufferWriter()Ljava/lang/Object;",
--- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/HotSpotGraalMBeanTest.java	Tue Apr 11 23:45:37 2017 +0200
+++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/HotSpotGraalMBeanTest.java	Mon Jun 26 16:10:31 2017 -0700
@@ -22,10 +22,17 @@
  */
 package org.graalvm.compiler.hotspot.test;
 
-import java.lang.annotation.Annotation;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNotSame;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertTrue;
+
 import java.lang.management.ManagementFactory;
 import java.lang.reflect.Field;
-import java.lang.reflect.Type;
+
+import java.util.Arrays;
 import javax.management.Attribute;
 import javax.management.MBeanAttributeInfo;
 import javax.management.MBeanInfo;
@@ -33,35 +40,27 @@
 import javax.management.MBeanServer;
 import javax.management.ObjectInstance;
 import javax.management.ObjectName;
-import jdk.vm.ci.hotspot.HotSpotResolvedJavaMethod;
-import jdk.vm.ci.hotspot.HotSpotResolvedObjectType;
-import jdk.vm.ci.meta.Assumptions;
-import jdk.vm.ci.meta.Constant;
-import jdk.vm.ci.meta.ConstantPool;
-import jdk.vm.ci.meta.ExceptionHandler;
-import jdk.vm.ci.meta.JavaConstant;
-import jdk.vm.ci.meta.JavaKind;
-import jdk.vm.ci.meta.LineNumberTable;
-import jdk.vm.ci.meta.LocalVariableTable;
-import jdk.vm.ci.meta.ProfilingInfo;
-import jdk.vm.ci.meta.ResolvedJavaField;
-import jdk.vm.ci.meta.ResolvedJavaMethod;
-import jdk.vm.ci.meta.ResolvedJavaType;
-import jdk.vm.ci.meta.Signature;
-import jdk.vm.ci.meta.SpeculationLog;
+
 import org.graalvm.compiler.debug.GraalDebugConfig;
 import org.graalvm.compiler.hotspot.HotSpotGraalMBean;
 import org.graalvm.compiler.options.OptionValues;
+import org.graalvm.compiler.test.GraalTest;
 import org.graalvm.util.EconomicMap;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNotSame;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertSame;
-import static org.junit.Assert.assertTrue;
+import org.junit.Assume;
 import org.junit.Test;
 
+import jdk.vm.ci.meta.MetaAccessProvider;
+import jdk.vm.ci.meta.ResolvedJavaMethod;
+
 public class HotSpotGraalMBeanTest {
+
+    public HotSpotGraalMBeanTest() {
+        // No support for registering Graal MBean yet on JDK9 (GR-4025). We cannot
+        // rely on an exception being thrown when accessing ManagementFactory.platformMBeanServer
+        // via reflection as recent JDK9 changes now allow this and issue a warning instead.
+        Assume.assumeTrue(GraalTest.Java8OrEarlier);
+    }
+
     @Test
     public void registration() throws Exception {
         ObjectName name;
@@ -224,8 +223,9 @@
 
         OptionValues empty = new OptionValues(EconomicMap.create());
         OptionValues unsetDump = realBean.optionsFor(empty, null);
-
-        final OptionValues forMethod = realBean.optionsFor(unsetDump, new MockResolvedJavaMethod());
+        final MetaAccessProvider metaAccess = jdk.vm.ci.runtime.JVMCI.getRuntime().getHostJVMCIBackend().getMetaAccess();
+        ResolvedJavaMethod method = metaAccess.lookupJavaMethod(Arrays.class.getMethod("asList", Object[].class));
+        final OptionValues forMethod = realBean.optionsFor(unsetDump, method);
         assertNotSame(unsetDump, forMethod);
         Object nothing = unsetDump.getMap().get(GraalDebugConfig.Options.Dump);
         assertEquals("Empty string", "", nothing);
@@ -238,468 +238,4 @@
         assertEquals("Empty string", "", noSpecialValue);
     }
 
-    private static class MockResolvedJavaMethod implements HotSpotResolvedJavaMethod {
-        MockResolvedJavaMethod() {
-        }
-
-        @Override
-        public boolean isCallerSensitive() {
-            throw new UnsupportedOperationException();
-        }
-
-        @Override
-        public HotSpotResolvedObjectType getDeclaringClass() {
-            return new MockResolvedObjectType();
-        }
-
-        @Override
-        public boolean isForceInline() {
-            throw new UnsupportedOperationException();
-        }
-
-        @Override
-        public boolean hasReservedStackAccess() {
-            throw new UnsupportedOperationException();
-        }
-
-        @Override
-        public void setNotInlineable() {
-            throw new UnsupportedOperationException();
-        }
-
-        @Override
-        public boolean ignoredBySecurityStackWalk() {
-            throw new UnsupportedOperationException();
-        }
-
-        @Override
-        public ResolvedJavaMethod uniqueConcreteMethod(HotSpotResolvedObjectType receiver) {
-            throw new UnsupportedOperationException();
-        }
-
-        @Override
-        public boolean hasCompiledCode() {
-            throw new UnsupportedOperationException();
-        }
-
-        @Override
-        public boolean hasCompiledCodeAtLevel(int level) {
-            throw new UnsupportedOperationException();
-        }
-
-        @Override
-        public int vtableEntryOffset(ResolvedJavaType resolved) {
-            throw new UnsupportedOperationException();
-        }
-
-        @Override
-        public int intrinsicId() {
-            throw new UnsupportedOperationException();
-        }
-
-        @Override
-        public int allocateCompileId(int entryBCI) {
-            throw new UnsupportedOperationException();
-        }
-
-        @Override
-        public boolean hasCodeAtLevel(int entryBCI, int level) {
-            throw new UnsupportedOperationException();
-        }
-
-        @Override
-        public byte[] getCode() {
-            throw new UnsupportedOperationException();
-        }
-
-        @Override
-        public int getCodeSize() {
-            throw new UnsupportedOperationException();
-        }
-
-        @Override
-        public int getMaxLocals() {
-            throw new UnsupportedOperationException();
-        }
-
-        @Override
-        public int getMaxStackSize() {
-            throw new UnsupportedOperationException();
-        }
-
-        @Override
-        public boolean isSynthetic() {
-            throw new UnsupportedOperationException();
-        }
-
-        @Override
-        public boolean isVarArgs() {
-            throw new UnsupportedOperationException();
-        }
-
-        @Override
-        public boolean isBridge() {
-            throw new UnsupportedOperationException();
-        }
-
-        @Override
-        public boolean isClassInitializer() {
-            throw new UnsupportedOperationException();
-        }
-
-        @Override
-        public boolean isConstructor() {
-            throw new UnsupportedOperationException();
-        }
-
-        @Override
-        public boolean canBeStaticallyBound() {
-            throw new UnsupportedOperationException();
-        }
-
-        @Override
-        public ExceptionHandler[] getExceptionHandlers() {
-            throw new UnsupportedOperationException();
-        }
-
-        @Override
-        public StackTraceElement asStackTraceElement(int bci) {
-            throw new UnsupportedOperationException();
-        }
-
-        @Override
-        public ProfilingInfo getProfilingInfo(boolean includeNormal, boolean includeOSR) {
-            throw new UnsupportedOperationException();
-        }
-
-        @Override
-        public void reprofile() {
-            throw new UnsupportedOperationException();
-        }
-
-        @Override
-        public ConstantPool getConstantPool() {
-            throw new UnsupportedOperationException();
-        }
-
-        @Override
-        public Annotation[][] getParameterAnnotations() {
-            throw new UnsupportedOperationException();
-        }
-
-        @Override
-        public Type[] getGenericParameterTypes() {
-            throw new UnsupportedOperationException();
-        }
-
-        @Override
-        public boolean canBeInlined() {
-            throw new UnsupportedOperationException();
-        }
-
-        @Override
-        public boolean hasNeverInlineDirective() {
-            throw new UnsupportedOperationException();
-        }
-
-        @Override
-        public boolean shouldBeInlined() {
-            throw new UnsupportedOperationException();
-        }
-
-        @Override
-        public LineNumberTable getLineNumberTable() {
-            throw new UnsupportedOperationException();
-        }
-
-        @Override
-        public LocalVariableTable getLocalVariableTable() {
-            throw new UnsupportedOperationException();
-        }
-
-        @Override
-        public Constant getEncoding() {
-            throw new UnsupportedOperationException();
-        }
-
-        @Override
-        public boolean isInVirtualMethodTable(ResolvedJavaType resolved) {
-            throw new UnsupportedOperationException();
-        }
-
-        @Override
-        public SpeculationLog getSpeculationLog() {
-            throw new UnsupportedOperationException();
-        }
-
-        @Override
-        public String getName() {
-            return "asList";
-        }
-
-        @Override
-        public Signature getSignature() {
-            throw new UnsupportedOperationException();
-        }
-
-        @Override
-        public int getModifiers() {
-            throw new UnsupportedOperationException();
-        }
-
-        @Override
-        public <T extends Annotation> T getAnnotation(Class<T> annotationClass) {
-            throw new UnsupportedOperationException();
-        }
-
-        @Override
-        public Annotation[] getAnnotations() {
-            throw new UnsupportedOperationException();
-        }
-
-        @Override
-        public Annotation[] getDeclaredAnnotations() {
-            throw new UnsupportedOperationException();
-        }
-
-        @Override
-        public boolean isIntrinsicCandidate() {
-            return true;
-        }
-
-        private static class MockResolvedObjectType implements HotSpotResolvedObjectType {
-            MockResolvedObjectType() {
-            }
-
-            @Override
-            public long getFingerprint() {
-                return 0L;
-            }
-
-            @Override
-            public HotSpotResolvedObjectType getArrayClass() {
-                throw new UnsupportedOperationException();
-            }
-
-            @Override
-            public ResolvedJavaType getComponentType() {
-                throw new UnsupportedOperationException();
-            }
-
-            @Override
-            public Assumptions.AssumptionResult<ResolvedJavaType> findLeafConcreteSubtype() {
-                throw new UnsupportedOperationException();
-            }
-
-            @Override
-            public HotSpotResolvedObjectType getSuperclass() {
-                throw new UnsupportedOperationException();
-            }
-
-            @Override
-            public HotSpotResolvedObjectType[] getInterfaces() {
-                throw new UnsupportedOperationException();
-            }
-
-            @Override
-            public HotSpotResolvedObjectType getSupertype() {
-                throw new UnsupportedOperationException();
-            }
-
-            @Override
-            public HotSpotResolvedObjectType findLeastCommonAncestor(ResolvedJavaType otherType) {
-                throw new UnsupportedOperationException();
-            }
-
-            @Override
-            public ConstantPool getConstantPool() {
-                throw new UnsupportedOperationException();
-            }
-
-            @Override
-            public int instanceSize() {
-                throw new UnsupportedOperationException();
-            }
-
-            @Override
-            public int getVtableLength() {
-                throw new UnsupportedOperationException();
-            }
-
-            @Override
-            public Assumptions.AssumptionResult<ResolvedJavaMethod> findUniqueConcreteMethod(ResolvedJavaMethod method) {
-                throw new UnsupportedOperationException();
-            }
-
-            @Override
-            public boolean isDefinitelyResolvedWithRespectTo(ResolvedJavaType accessingClass) {
-                throw new UnsupportedOperationException();
-            }
-
-            @Override
-            public Constant klass() {
-                throw new UnsupportedOperationException();
-            }
-
-            @Override
-            public boolean isPrimaryType() {
-                throw new UnsupportedOperationException();
-            }
-
-            @Override
-            public int superCheckOffset() {
-                throw new UnsupportedOperationException();
-            }
-
-            @Override
-            public long prototypeMarkWord() {
-                throw new UnsupportedOperationException();
-            }
-
-            @Override
-            public int layoutHelper() {
-                throw new UnsupportedOperationException();
-            }
-
-            @Override
-            public HotSpotResolvedObjectType getEnclosingType() {
-                throw new UnsupportedOperationException();
-            }
-
-            @Override
-            public ResolvedJavaMethod getClassInitializer() {
-                throw new UnsupportedOperationException();
-            }
-
-            @Override
-            public boolean hasFinalizer() {
-                throw new UnsupportedOperationException();
-            }
-
-            @Override
-            public Assumptions.AssumptionResult<Boolean> hasFinalizableSubclass() {
-                throw new UnsupportedOperationException();
-            }
-
-            @Override
-            public boolean isInterface() {
-                throw new UnsupportedOperationException();
-            }
-
-            @Override
-            public boolean isInstanceClass() {
-                throw new UnsupportedOperationException();
-            }
-
-            @Override
-            public boolean isInitialized() {
-                throw new UnsupportedOperationException();
-            }
-
-            @Override
-            public void initialize() {
-                throw new UnsupportedOperationException();
-            }
-
-            @Override
-            public boolean isLinked() {
-                throw new UnsupportedOperationException();
-            }
-
-            @Override
-            public boolean isAssignableFrom(ResolvedJavaType other) {
-                throw new UnsupportedOperationException();
-            }
-
-            @Override
-            public boolean isInstance(JavaConstant obj) {
-                throw new UnsupportedOperationException();
-            }
-
-            @Override
-            public ResolvedJavaType getSingleImplementor() {
-                throw new UnsupportedOperationException();
-            }
-
-            @Override
-            public ResolvedJavaMethod resolveMethod(ResolvedJavaMethod method, ResolvedJavaType callerType) {
-                throw new UnsupportedOperationException();
-            }
-
-            @Override
-            public ResolvedJavaField[] getInstanceFields(boolean includeSuperclasses) {
-                throw new UnsupportedOperationException();
-            }
-
-            @Override
-            public ResolvedJavaField[] getStaticFields() {
-                throw new UnsupportedOperationException();
-            }
-
-            @Override
-            public ResolvedJavaField findInstanceFieldWithOffset(long offset, JavaKind expectedKind) {
-                throw new UnsupportedOperationException();
-            }
-
-            @Override
-            public String getSourceFileName() {
-                throw new UnsupportedOperationException();
-            }
-
-            @Override
-            public boolean isLocal() {
-                throw new UnsupportedOperationException();
-            }
-
-            @Override
-            public boolean isMember() {
-                throw new UnsupportedOperationException();
-            }
-
-            @Override
-            public ResolvedJavaMethod[] getDeclaredConstructors() {
-                throw new UnsupportedOperationException();
-            }
-
-            @Override
-            public ResolvedJavaMethod[] getDeclaredMethods() {
-                throw new UnsupportedOperationException();
-            }
-
-            @Override
-            public boolean isCloneableWithAllocation() {
-                throw new UnsupportedOperationException();
-            }
-
-            @Override
-            public String getName() {
-                return "Ljava/util/Arrays;";
-            }
-
-            @Override
-            public ResolvedJavaType resolve(ResolvedJavaType accessingClass) {
-                throw new UnsupportedOperationException();
-            }
-
-            @Override
-            public int getModifiers() {
-                throw new UnsupportedOperationException();
-            }
-
-            @Override
-            public <T extends Annotation> T getAnnotation(Class<T> annotationClass) {
-                throw new UnsupportedOperationException();
-            }
-
-            @Override
-            public Annotation[] getAnnotations() {
-                throw new UnsupportedOperationException();
-            }
-
-            @Override
-            public Annotation[] getDeclaredAnnotations() {
-                throw new UnsupportedOperationException();
-            }
-        }
-    }
 }
--- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/GraalHotSpotVMConfig.java	Tue Apr 11 23:45:37 2017 +0200
+++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/GraalHotSpotVMConfig.java	Mon Jun 26 16:10:31 2017 -0700
@@ -212,6 +212,7 @@
     }
 
     public final boolean useG1GC = getFlag("UseG1GC", Boolean.class);
+    public final boolean useCMSGC = getFlag("UseConcMarkSweepGC", Boolean.class);
 
     public final int allocatePrefetchStyle = getFlag("AllocatePrefetchStyle", Integer.class);
     public final int allocatePrefetchInstr = getFlag("AllocatePrefetchInstr", Integer.class);
--- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/JVMCIVersionCheck.java	Tue Apr 11 23:45:37 2017 +0200
+++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/JVMCIVersionCheck.java	Mon Jun 26 16:10:31 2017 -0700
@@ -42,7 +42,7 @@
 
     // MAX_VALUE indicates that no current EA version is compatible with Graal.
     // Note: Keep README.md in sync with the EA version support checked here.
-    private static final int JVMCI9_MIN_EA_BUILD = 168;
+    private static final int JVMCI9_MIN_EA_BUILD = 174;
 
     private static void failVersionCheck(boolean exit, String reason, Object... args) {
         Formatter errorMessage = new Formatter().format(reason, args);
--- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotClassInitializationPlugin.java	Tue Apr 11 23:45:37 2017 +0200
+++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotClassInitializationPlugin.java	Mon Jun 26 16:10:31 2017 -0700
@@ -26,7 +26,9 @@
 import org.graalvm.compiler.core.common.type.Stamp;
 import org.graalvm.compiler.core.common.type.StampFactory;
 import org.graalvm.compiler.hotspot.nodes.aot.InitializeKlassNode;
+import org.graalvm.compiler.hotspot.nodes.aot.ResolveConstantNode;
 import org.graalvm.compiler.nodes.ConstantNode;
+import org.graalvm.compiler.nodes.DeoptimizingFixedWithNextNode;
 import org.graalvm.compiler.nodes.FrameState;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.graphbuilderconf.ClassInitializationPlugin;
@@ -40,18 +42,24 @@
     @Override
     public boolean shouldApply(GraphBuilderContext builder, ResolvedJavaType type) {
         if (!builder.parsingIntrinsic()) {
-            ResolvedJavaMethod method = builder.getGraph().method();
-            ResolvedJavaType methodHolder = method.getDeclaringClass();
-            // We can elide initialization nodes if type >=: methodHolder.
-            // The type is already initialized by either "new" or "invokestatic".
+            if (!type.isArray()) {
+                ResolvedJavaMethod method = builder.getGraph().method();
+                ResolvedJavaType methodHolder = method.getDeclaringClass();
+                // We can elide initialization nodes if type >=: methodHolder.
+                // The type is already initialized by either "new" or "invokestatic".
 
-            // Emit initialization node if type is an interface since:
-            // JLS 12.4: Before a class is initialized, its direct superclass must be initialized,
-            // but interfaces implemented by the class are not initialized.
-            // and a class or interface type T will be initialized immediately
-            // before the first occurrence of accesses listed in JLS 12.4.1.
+                // Emit initialization node if type is an interface since:
+                // JLS 12.4: Before a class is initialized, its direct superclass must be
+                // initialized, but interfaces implemented by the class are not
+                // initialized and a class or interface type T will be initialized
+                // immediately before the first occurrence of accesses listed
+                // in JLS 12.4.1.
 
-            return !type.isAssignableFrom(methodHolder) || type.isInterface();
+                return !type.isAssignableFrom(methodHolder) || type.isInterface();
+            } else if (!type.getComponentType().isPrimitive()) {
+                // Always apply to object array types
+                return true;
+            }
         }
         return false;
     }
@@ -61,8 +69,8 @@
         assert shouldApply(builder, type);
         Stamp hubStamp = builder.getStampProvider().createHubStamp((ObjectStamp) StampFactory.objectNonNull());
         ConstantNode hub = builder.append(ConstantNode.forConstant(hubStamp, ((HotSpotResolvedObjectType) type).klass(), builder.getMetaAccess(), builder.getGraph()));
-        InitializeKlassNode initialize = builder.append(new InitializeKlassNode(hub));
-        initialize.setStateBefore(frameState);
-        return initialize;
+        DeoptimizingFixedWithNextNode result = builder.append(type.isArray() ? new ResolveConstantNode(hub) : new InitializeKlassNode(hub));
+        result.setStateBefore(frameState);
+        return result;
     }
 }
--- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/phases/aot/EliminateRedundantInitializationPhase.java	Tue Apr 11 23:45:37 2017 +0200
+++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/phases/aot/EliminateRedundantInitializationPhase.java	Mon Jun 26 16:10:31 2017 -0700
@@ -30,6 +30,7 @@
 
 import org.graalvm.compiler.graph.Node;
 import org.graalvm.compiler.hotspot.nodes.aot.InitializeKlassNode;
+import org.graalvm.compiler.hotspot.nodes.aot.ResolveConstantNode;
 import org.graalvm.compiler.nodes.AbstractMergeNode;
 import org.graalvm.compiler.nodes.FixedNode;
 import org.graalvm.compiler.nodes.FixedWithNextNode;
@@ -62,28 +63,29 @@
     }
 
     /**
-     * Remove redundant {@link InitializeKlassNode} instances from the graph.
+     * Remove redundant {@link InitializeKlassNode} or {@link ResolveConstantNode} instances from
+     * the graph.
      *
      * @param graph the program graph
      */
     private static void removeRedundantInits(StructuredGraph graph) {
-        // Find and remove redundant instances of {@link InitializeKlassNode} from the graph.
-        List<InitializeKlassNode> redundantInits = findRedundantInits(graph);
-        for (InitializeKlassNode n : redundantInits) {
+        // Find and remove redundant nodes from the graph.
+        List<FixedWithNextNode> redundantNodes = findRedundantInits(graph);
+        for (FixedWithNextNode n : redundantNodes) {
             graph.removeFixed(n);
         }
     }
 
     /**
-     * Find {@link InitializeKlassNode} instances that can be removed because there is an existing
-     * dominating initialization.
+     * Find {@link InitializeKlassNode} and {@link ResolveConstantNode} instances that can be
+     * removed because there is an existing dominating node.
      *
      * @param graph the program graph
      */
-    private static List<InitializeKlassNode> findRedundantInits(StructuredGraph graph) {
+    private static List<FixedWithNextNode> findRedundantInits(StructuredGraph graph) {
         EliminateRedundantInitializationIterator i = new EliminateRedundantInitializationIterator(graph.start(), new InitializedTypes());
         i.apply();
-        return i.getRedundantInits();
+        return i.getRedundantNodes();
     }
 
     /**
@@ -106,7 +108,7 @@
         }
 
         public boolean contains(ResolvedJavaType type) {
-            if (type.isInterface()) {
+            if (type.isInterface() || type.isArray()) {
                 // Check for exact match for interfaces
                 return types.contains(type);
             }
@@ -119,8 +121,8 @@
         }
 
         /**
-         * Merge two given types. Interfaces have to be the same to merge successfully. For other
-         * types the answer is the LCA.
+         * Merge two given types. Interfaces and arrays have to be the same to merge successfully.
+         * For other types the answer is the LCA.
          *
          * @param a initialized type
          * @param b initialized type
@@ -128,8 +130,8 @@
          *         no such type exists.
          */
         private static ResolvedJavaType merge(ResolvedJavaType a, ResolvedJavaType b) {
-            // We want exact match for interfaces
-            if (a.isInterface() || b.isInterface()) {
+            // We want exact match for interfaces or arrays
+            if (a.isInterface() || b.isInterface() || a.isArray() || b.isArray()) {
                 if (a.equals(b)) {
                     return a;
                 } else {
@@ -162,8 +164,9 @@
                     ResolvedJavaType tc = merge(ta, tb);
                     if (tc != null) {
                         c.add(tc);
-                        if (tc.isInterface()) {
-                            // Interface is not going merge with anything else, so bail out early.
+                        if (tc.isInterface() || tc.isArray()) {
+                            // Interfaces and arrays are not going merge with anything else, so bail
+                            // out early.
                             break;
                         }
                     }
@@ -202,31 +205,45 @@
     }
 
     /**
-     * Do data flow analysis of class initializations. Collect redundant initialization nodes.
+     * Do data flow analysis of class initializations and array resolutions. Collect redundant
+     * nodes.
      */
     private static class EliminateRedundantInitializationIterator extends PostOrderNodeIterator<InitializedTypes> {
-        private List<InitializeKlassNode> redundantInits = new ArrayList<>();
+        private List<FixedWithNextNode> redundantNodes = new ArrayList<>();
 
-        public List<InitializeKlassNode> getRedundantInits() {
-            return redundantInits;
+        public List<FixedWithNextNode> getRedundantNodes() {
+            return redundantNodes;
         }
 
         EliminateRedundantInitializationIterator(FixedNode start, InitializedTypes initialState) {
             super(start, initialState);
         }
 
+        private void processType(FixedWithNextNode node, Constant c) {
+            HotSpotMetaspaceConstant klass = (HotSpotMetaspaceConstant) c;
+            ResolvedJavaType t = klass.asResolvedJavaType();
+            if (t != null) {
+                if (state.contains(t)) {
+                    redundantNodes.add(node);
+                } else {
+                    state.add(t);
+                }
+            }
+        }
+
         @Override
         protected void node(FixedNode node) {
             if (node instanceof InitializeKlassNode) {
                 InitializeKlassNode i = (InitializeKlassNode) node;
-                Constant c = i.value().asConstant();
-                assert c != null : "Klass should be a constant at this point";
-                HotSpotMetaspaceConstant klass = (HotSpotMetaspaceConstant) c;
-                ResolvedJavaType t = klass.asResolvedJavaType();
-                if (state.contains(t)) {
-                    redundantInits.add(i);
-                } else {
-                    state.add(t);
+                if (i.value().isConstant()) {
+                    processType(i, i.value().asConstant());
+                }
+            } else if (node instanceof ResolveConstantNode) {
+                ResolveConstantNode r = (ResolveConstantNode) node;
+                if (r.hasNoUsages()) {
+                    if (r.value().isConstant()) {
+                        processType(r, r.value().asConstant());
+                    }
                 }
             }
         }
--- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/phases/aot/ReplaceConstantNodesPhase.java	Tue Apr 11 23:45:37 2017 +0200
+++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/phases/aot/ReplaceConstantNodesPhase.java	Mon Jun 26 16:10:31 2017 -0700
@@ -136,7 +136,7 @@
                 throw new GraalError("Type with bad fingerprint: " + type);
             }
             assert !metaspaceConstant.isCompressed() : "No support for replacing compressed metaspace constants";
-            replaceWithInitialization(graph, node);
+            tryToReplaceWithExisting(graph, node);
             if (anyUsagesNeedReplacement(node)) {
                 replaceWithResolution(graph, node);
             }
@@ -172,45 +172,45 @@
     }
 
     /**
-     * Try to find dominating {@link InitializeKlassNode} that can be reused.
+     * Try to find dominating node doing the resolution that can be reused.
      *
      * @param graph
      * @param node {@link ConstantNode} containing a {@link HotSpotResolvedJavaType} that needs
      *            resolution.
      */
-    private static void replaceWithInitialization(StructuredGraph graph, ConstantNode node) {
+    private static void tryToReplaceWithExisting(StructuredGraph graph, ConstantNode node) {
         ScheduleResult schedule = graph.getLastSchedule();
         NodeMap<Block> nodeToBlock = schedule.getNodeToBlockMap();
         BlockMap<List<Node>> blockToNodes = schedule.getBlockToNodesMap();
 
-        EconomicMap<Block, Node> blockToInit = EconomicMap.create();
-        for (Node n : node.usages().filter(InitializeKlassNode.class)) {
-            blockToInit.put(nodeToBlock.get(n), n);
+        EconomicMap<Block, Node> blockToExisting = EconomicMap.create();
+        for (Node n : node.usages().filter(n -> isReplacementNode(n))) {
+            blockToExisting.put(nodeToBlock.get(n), n);
         }
         for (Node use : node.usages().filter(n -> !isReplacementNode(n)).snapshot()) {
             boolean replaced = false;
             Block b = nodeToBlock.get(use);
-            InitializeKlassNode i = (InitializeKlassNode) blockToInit.get(b);
-            if (i != null) {
-                // There is an initialization in the same block as the use, look if the use is
-                // scheduled after it.
+            Node e = blockToExisting.get(b);
+            if (e != null) {
+                // There is an initialization or resolution in the same block as the use, look if
+                // the use is scheduled after it.
                 for (Node n : blockToNodes.get(b)) {
                     if (n.equals(use)) {
                         // Usage is before initialization, can't use it
                         break;
                     }
-                    if (n.equals(i)) {
-                        use.replaceFirstInput(node, i);
+                    if (n.equals(e)) {
+                        use.replaceFirstInput(node, e);
                         replaced = true;
                         break;
                     }
                 }
             }
             if (!replaced) {
-                // Look for dominating blocks that have initializations
-                for (Block d : blockToInit.getKeys()) {
+                // Look for dominating blocks that have existing nodes
+                for (Block d : blockToExisting.getKeys()) {
                     if (strictlyDominates(d, b)) {
-                        use.replaceFirstInput(node, blockToInit.get(d));
+                        use.replaceFirstInput(node, blockToExisting.get(d));
                         break;
                     }
                 }
--- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/NewObjectSnippets.java	Tue Apr 11 23:45:37 2017 +0200
+++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/NewObjectSnippets.java	Mon Jun 26 16:10:31 2017 -0700
@@ -86,7 +86,6 @@
 import org.graalvm.compiler.hotspot.nodes.aot.LoadConstantIndirectlyFixedNode;
 import org.graalvm.compiler.hotspot.nodes.aot.LoadConstantIndirectlyNode;
 import org.graalvm.compiler.hotspot.nodes.type.KlassPointerStamp;
-import org.graalvm.compiler.hotspot.replacements.aot.ResolveConstantSnippets;
 import org.graalvm.compiler.hotspot.word.KlassPointer;
 import org.graalvm.compiler.nodes.ConstantNode;
 import org.graalvm.compiler.nodes.DeoptimizeNode;
@@ -300,10 +299,8 @@
     public static Object allocateArrayPIC(KlassPointer hub, int length, Word prototypeMarkWord, @ConstantParameter int headerSize, @ConstantParameter int log2ElementSize,
                     @ConstantParameter boolean fillContents, @ConstantParameter Register threadRegister, @ConstantParameter boolean maybeUnroll, @ConstantParameter String typeContext,
                     @ConstantParameter OptionValues options, @ConstantParameter Counters counters) {
-        // We need to resolve array type. While element type is guaranteed to be initialized, we
-        // cannot guarantee initialization of the array class if NewArrayInstance comes from
-        // canonicalization of DynamicNewArrayInstance.
-        KlassPointer picHub = ResolveConstantSnippets.pureInitializeKlass(hub);
+        // Array type would be resolved by dominating resolution.
+        KlassPointer picHub = LoadConstantIndirectlyFixedNode.loadKlass(hub);
         return allocateArrayImpl(picHub, length, prototypeMarkWord, headerSize, log2ElementSize, fillContents, threadRegister, maybeUnroll, typeContext, false, options, counters);
     }
 
@@ -419,6 +416,7 @@
 
     @Snippet
     public static Object newmultiarrayPIC(KlassPointer hub, @ConstantParameter int rank, @VarargsParameter int[] dimensions) {
+        // Array type would be resolved by dominating resolution.
         KlassPointer picHub = LoadConstantIndirectlyFixedNode.loadKlass(hub);
         return newmultiarray(picHub, rank, dimensions);
     }
--- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.java/src/org/graalvm/compiler/java/BytecodeParser.java	Tue Apr 11 23:45:37 2017 +0200
+++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.java/src/org/graalvm/compiler/java/BytecodeParser.java	Mon Jun 26 16:10:31 2017 -0700
@@ -247,7 +247,6 @@
 import static org.graalvm.compiler.core.common.type.StampFactory.objectNonNull;
 import static org.graalvm.compiler.debug.GraalError.guarantee;
 import static org.graalvm.compiler.debug.GraalError.shouldNotReachHere;
-import static org.graalvm.compiler.java.BytecodeParserOptions.DumpWithInfopoints;
 import static org.graalvm.compiler.java.BytecodeParserOptions.InlinePartialIntrinsicExitDuringParsing;
 import static org.graalvm.compiler.java.BytecodeParserOptions.TraceBytecodeParserLevel;
 import static org.graalvm.compiler.java.BytecodeParserOptions.TraceInlineDuringParsing;
@@ -2808,7 +2807,7 @@
     }
 
     private DebugCloseable openNodeContext() {
-        if ((graphBuilderConfig.trackNodeSourcePosition() || (Debug.isDumpEnabledForMethod() && DumpWithInfopoints.getValue(options))) && !parsingIntrinsic()) {
+        if ((graphBuilderConfig.trackNodeSourcePosition() || Debug.isDumpEnabledForMethod()) && !parsingIntrinsic()) {
             return graph.withNodeSourcePosition(createBytecodePosition());
         }
         return null;
@@ -3687,9 +3686,9 @@
         ResolvedJavaType resolvedType = (ResolvedJavaType) type;
 
         ClassInitializationPlugin classInitializationPlugin = this.graphBuilderConfig.getPlugins().getClassInitializationPlugin();
-        if (classInitializationPlugin != null && classInitializationPlugin.shouldApply(this, resolvedType)) {
+        if (classInitializationPlugin != null && classInitializationPlugin.shouldApply(this, resolvedType.getArrayClass())) {
             FrameState stateBefore = frameState.create(bci(), getNonIntrinsicAncestor(), false, null, null);
-            classInitializationPlugin.apply(this, resolvedType, stateBefore);
+            classInitializationPlugin.apply(this, resolvedType.getArrayClass(), stateBefore);
         }
 
         ValueNode length = frameState.pop(JavaKind.Int);
--- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.java/src/org/graalvm/compiler/java/BytecodeParserOptions.java	Tue Apr 11 23:45:37 2017 +0200
+++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.java/src/org/graalvm/compiler/java/BytecodeParserOptions.java	Mon Jun 26 16:10:31 2017 -0700
@@ -63,9 +63,5 @@
 
     @Option(help = "Use intrinsics guarded by a virtual dispatch test at indirect call sites.", type = OptionType.Debug)
     public static final OptionKey<Boolean> UseGuardedIntrinsics = new OptionKey<>(true);
-
-    // Remove once GR-3604 reduces the memory overhead of including node source info dumps
-    @Option(help = "Enable node source positions if dumping is enabled.", type = OptionType.Debug)
-    public static final OptionKey<Boolean> DumpWithInfopoints = new OptionKey<>(false);
     // @formatter:on
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes.test/src/org/graalvm/compiler/nodes/test/AddNodeTest.java	Mon Jun 26 16:10:31 2017 -0700
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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 org.graalvm.compiler.nodes.test;
+
+import org.graalvm.compiler.graph.Node;
+import org.graalvm.compiler.graph.NodeClass;
+import org.graalvm.compiler.nodes.ConstantNode;
+import org.graalvm.compiler.nodes.calc.AddNode;
+import static org.junit.Assert.assertEquals;
+import org.junit.Test;
+
+public class AddNodeTest {
+    @Test
+    public void checkTemplateAndName() {
+        AddNode add = new AddNode(ConstantNode.forInt(30), ConstantNode.forInt(12));
+        NodeClass<? extends Node> addClass = add.getNodeClass();
+        assertEquals("+", addClass.shortName());
+        assertEquals("Using short name as template", "+", addClass.getNameTemplate());
+    }
+}
--- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes.test/src/org/graalvm/compiler/nodes/test/StaticFieldAccessTest.java	Tue Apr 11 23:45:37 2017 +0200
+++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes.test/src/org/graalvm/compiler/nodes/test/StaticFieldAccessTest.java	Mon Jun 26 16:10:31 2017 -0700
@@ -51,6 +51,5 @@
     @Test
     public void test() {
         tester = this;
-        System.out.println(Inner.o);
     }
 }
--- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/StructuredGraph.java	Tue Apr 11 23:45:37 2017 +0200
+++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/StructuredGraph.java	Mon Jun 26 16:10:31 2017 -0700
@@ -244,7 +244,7 @@
      */
     private final Assumptions assumptions;
 
-    private final SpeculationLog speculationLog;
+    private SpeculationLog speculationLog;
 
     private ScheduleResult lastSchedule;
 
--- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/DynamicNewArrayNode.java	Tue Apr 11 23:45:37 2017 +0200
+++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/DynamicNewArrayNode.java	Mon Jun 26 16:10:31 2017 -0700
@@ -23,6 +23,8 @@
 //JaCoCo Exclude
 package org.graalvm.compiler.nodes.java;
 
+import static org.graalvm.compiler.core.common.GraalOptions.GeneratePIC;
+
 import org.graalvm.compiler.core.common.type.Stamp;
 import org.graalvm.compiler.core.common.type.StampFactory;
 import org.graalvm.compiler.core.common.type.TypeReference;
@@ -96,6 +98,11 @@
     @Override
     public Node canonical(CanonicalizerTool tool) {
         if (elementType.isConstant()) {
+            if (GeneratePIC.getValue(tool.getOptions())) {
+                // Can't fold for AOT, because the resulting NewArrayNode will be missing its
+                // ResolveConstantNode for the array class.
+                return this;
+            }
             ResolvedJavaType type = tool.getConstantReflection().asJavaType(elementType.asConstant());
             if (type != null && !throwsIllegalArgumentException(type)) {
                 return createNewArrayNode(type);
--- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/DynamicNewInstanceNode.java	Tue Apr 11 23:45:37 2017 +0200
+++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/DynamicNewInstanceNode.java	Mon Jun 26 16:10:31 2017 -0700
@@ -22,6 +22,8 @@
  */
 package org.graalvm.compiler.nodes.java;
 
+import static org.graalvm.compiler.core.common.GraalOptions.GeneratePIC;
+
 import java.lang.reflect.Modifier;
 
 import org.graalvm.compiler.core.common.type.ObjectStamp;
@@ -67,6 +69,11 @@
     @Override
     public Node canonical(CanonicalizerTool tool) {
         if (clazz.isConstant()) {
+            if (GeneratePIC.getValue(tool.getOptions())) {
+                // Can't fold for AOT, because the resulting NewInstanceNode will be missing its
+                // InitializeKlassNode.
+                return this;
+            }
             ResolvedJavaType type = tool.getConstantReflection().asJavaType(clazz.asConstant());
             if (type != null && type.isInitialized() && !throwsInstantiationException(type, tool.getMetaAccess())) {
                 return createNewInstanceNode(type);
--- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/inlining/InliningUtil.java	Tue Apr 11 23:45:37 2017 +0200
+++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/inlining/InliningUtil.java	Mon Jun 26 16:10:31 2017 -0700
@@ -516,7 +516,7 @@
         if (inlineGraph.hasUnsafeAccess()) {
             graph.markUnsafeAccess();
         }
-        assert inlineGraph.getSpeculationLog() == null : "Only the root graph should have a speculation log";
+        assert inlineGraph.getSpeculationLog() == null || inlineGraph.getSpeculationLog() == graph.getSpeculationLog() : "Only the root graph should have a speculation log";
 
         return returnValue;
     }
--- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.options/src/org/graalvm/options/OptionDescriptors.java	Tue Apr 11 23:45:37 2017 +0200
+++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.options/src/org/graalvm/options/OptionDescriptors.java	Mon Jun 26 16:10:31 2017 -0700
@@ -27,6 +27,9 @@
 import java.util.Arrays;
 import java.util.Collections;
 import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
 import java.util.NoSuchElementException;
 
 /**
@@ -76,6 +79,41 @@
             return new UnionOptionDescriptors(descriptors);
         }
     }
+
+    /**
+     * Create an {@link OptionDescriptors} instance from a list. The option descriptors
+     * implementation is backed by a {@link LinkedHashMap} that preserves ordering.
+     *
+     * @since 1.0
+     */
+    static OptionDescriptors create(List<OptionDescriptor> descriptors) {
+        if (descriptors == null || descriptors.isEmpty()) {
+            return EMPTY;
+        }
+        return new OptionDescriptorsMap(descriptors);
+    }
+}
+
+class OptionDescriptorsMap implements OptionDescriptors {
+
+    final Map<String, OptionDescriptor> descriptors = new LinkedHashMap<>();
+
+    OptionDescriptorsMap(List<OptionDescriptor> descriptorList) {
+        for (OptionDescriptor descriptor : descriptorList) {
+            descriptors.put(descriptor.getName(), descriptor);
+        }
+    }
+
+    @Override
+    public OptionDescriptor get(String optionName) {
+        return descriptors.get(optionName);
+    }
+
+    @Override
+    public Iterator<OptionDescriptor> iterator() {
+        return descriptors.values().iterator();
+    }
+
 }
 
 final class UnionOptionDescriptors implements OptionDescriptors {
--- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.options/src/org/graalvm/options/OptionKey.java	Tue Apr 11 23:45:37 2017 +0200
+++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.options/src/org/graalvm/options/OptionKey.java	Mon Jun 26 16:10:31 2017 -0700
@@ -92,4 +92,14 @@
         return values.get(this);
     }
 
+    /**
+     * Returns <code>true</code> if a value for this key has been set for the given option values or
+     * <code>false</code> if no value has been set.
+     *
+     * @since 1.0
+     */
+    public boolean hasBeenSet(OptionValues values) {
+        return values.hasBeenSet(this);
+    }
+
 }
--- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.options/src/org/graalvm/options/OptionValues.java	Tue Apr 11 23:45:37 2017 +0200
+++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.options/src/org/graalvm/options/OptionValues.java	Mon Jun 26 16:10:31 2017 -0700
@@ -41,15 +41,30 @@
     /**
      * Sets the value of {@code optionKey} to {@code value}.
      *
+     * @throws IllegalArgumentException if the given value is not {@link OptionType#validate(Object)
+     *             validated} by the {@link OptionKey#getType() option type} of the key. Please note
+     *             that the operation does not fail if the option key is not described by any of the
+     *             associated {@link #getDescriptors() descriptors}.
+     *
      * @since 1.0
      */
     <T> void set(OptionKey<T> optionKey, T value);
 
     /**
-     * Returns the value of a given option. Returns <code>null</code> if the option does not exist.
+     * Returns the value of a given option. If no value is set or the key is not described by any
+     * {@link #getDescriptors() descriptors} the {@link OptionType#getDefaultValue() default value}
+     * of the given key is returned.
      *
      * @since 1.0
      */
     <T> T get(OptionKey<T> optionKey);
 
+    /**
+     * Determines if a value for {@code optionKey} has been {@link #set} in this set of option
+     * values.
+     *
+     * @since 1.0
+     */
+    boolean hasBeenSet(OptionKey<?> optionKey);
+
 }
--- a/hotspot/test/compiler/aot/scripts/build-bootmodules.sh	Tue Apr 11 23:45:37 2017 +0200
+++ b/hotspot/test/compiler/aot/scripts/build-bootmodules.sh	Mon Jun 26 16:10:31 2017 -0700
@@ -36,7 +36,7 @@
 
 $JAVA_HOME/bin/javac -d . $DIR/$TEST.java
 
-JAOTC_OPTS="-J-Xmx4g --compile-for-tiered --info"
+JAOTC_OPTS="-J-Xmx4g -J-ea --compile-for-tiered --info"
 JAVA_OPTS="-Xmx4g -XX:+UseAOT -XX:+UnlockDiagnosticVMOptions -XX:+UseAOTStrictLoading"
 
 # Compile with: +UseCompressedOops +UseG1GC