diff --git a/hotspot/test/runtime/appcds/AppCDSOptions.java b/hotspot/test/runtime/appcds/AppCDSOptions.java
new file mode 100644
index 00000000..f5ebb5d5
--- /dev/null
+++ b/hotspot/test/runtime/appcds/AppCDSOptions.java
@@ -0,0 +1,46 @@
+/*
+ * 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.
+ *
+ */
+
+// This class represents options used for
+// during creation of the archive and/or running JVM with archive
+
+import com.oracle.java.testlibrary.cds.CDSOptions;
+
+public class AppCDSOptions extends CDSOptions {
+    public String appJar;
+
+    // Application classes to be archived
+    public String[] appClasses;
+
+    public AppCDSOptions setAppJar(String appJar) {
+        this.appJar = appJar;
+        return this;
+    }
+
+    public AppCDSOptions setAppClasses(String[] appClasses) {
+        this.appClasses = appClasses;
+        return this;
+    }
+
+}
diff --git a/hotspot/test/runtime/appcds/AppendClasspath.java b/hotspot/test/runtime/appcds/AppendClasspath.java
new file mode 100644
index 00000000..7ebe7f62
--- /dev/null
+++ b/hotspot/test/runtime/appcds/AppendClasspath.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2014, 2018, 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.
+ *
+ */
+
+/*
+ * @test
+ * @summary At run time, it is OK to append new elements to the classpath that was used at dump time.
+ * @library /testlibrary
+ * @compile test-classes/Hello.java
+ * @compile test-classes/HelloMore.java
+ * @run main AppendClasspath
+ */
+
+import java.io.File;
+import com.oracle.java.testlibrary.OutputAnalyzer;
+
+public class AppendClasspath {
+
+    public static void main(String[] args) throws Exception {
+        String appJar = JarBuilder.getOrCreateHelloJar();
+        System.out.println("appJar = ");
+        System.out.println(appJar);
+        String appJar2 = JarBuilder.build("AppendClasspath_HelloMore", "HelloMore");
+        System.out.println("appJar2 = ");
+        System.out.println(appJar2);
+        // Dump an archive with a specified JAR file in -classpath
+        TestCommon.testDump(appJar, TestCommon.list("Hello"));
+
+        // PASS: 1) runtime with classpath containing the one used in dump time
+        TestCommon.run(
+                "-cp", appJar + File.pathSeparator + appJar2,
+                "HelloMore")
+                .assertNormalExit();
+
+        // PASS: 2) runtime with classpath different from the one used in dump time
+        TestCommon.run(
+                "-cp", appJar2 + File.pathSeparator + appJar,
+                "HelloMore");
+
+        // PASS: 3) runtime with classpath part of the one used in dump time
+        TestCommon.testDump(appJar + File.pathSeparator + appJar2,
+                TestCommon.list("Hello"));
+        TestCommon.run(
+                "-cp", appJar2,
+                "Hello");
+
+        // PASS: 4) runtime with same set of jar files in the classpath but
+        // with different order
+        TestCommon.run(
+                "-cp", appJar2 + File.pathSeparator + appJar,
+                "HelloMore");
+    }
+}
+
diff --git a/hotspot/test/runtime/appcds/CaseSensitiveClassPath.java b/hotspot/test/runtime/appcds/CaseSensitiveClassPath.java
new file mode 100644
index 00000000..689d2a17
--- /dev/null
+++ b/hotspot/test/runtime/appcds/CaseSensitiveClassPath.java
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2016, 2018, 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.
+ *
+ */
+
+
+/*
+ * @test
+ * @summary Test case sensitive aspect of comparing class paths
+ *     between dump time and archive use time
+ * @library /testlibrary
+ * @compile test-classes/Hello.java
+ * @run main CaseSensitiveClassPath
+ */
+
+import java.nio.file.FileAlreadyExistsException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.nio.file.StandardCopyOption;
+import com.oracle.java.testlibrary.Platform;
+import com.oracle.java.testlibrary.OutputAnalyzer;
+
+
+// Excluded from running on MAC: a more comprehensive case sensitivity detection
+// and fix mechanism is needed, which is planned to be implemented in the future.
+public class CaseSensitiveClassPath {
+    public static void main(String[] args) throws Exception {
+        String appJar = JarBuilder.getOrCreateHelloJar();
+        String appJarUpper = appJar.replace("hello", "Hello");
+
+        OutputAnalyzer out = TestCommon.dump(appJar, TestCommon.list("Hello"));
+        TestCommon.checkDump(out);
+
+        Path jarPath = Paths.get(appJar);
+        Path jarPathUpper = null;
+
+        boolean fileExists = false;
+        try {
+            jarPathUpper = Files.createFile(Paths.get(appJarUpper));
+        } catch (FileAlreadyExistsException faee) {
+            fileExists = true;
+        }
+
+        if (!fileExists) {
+            try {
+                Files.copy(jarPath, jarPathUpper, StandardCopyOption.REPLACE_EXISTING);
+            } catch (Exception e) {
+                throw new java.lang.RuntimeException(
+                        "Failed copying file from " + appJar + " to " + appJarUpper + ".", e);
+            }
+        } else {
+            jarPathUpper = Paths.get(appJarUpper);
+        }
+        boolean isSameFile = Files.isSameFile(jarPath, jarPathUpper);
+
+        TestCommon.run("-cp", appJarUpper, "Hello", "-Xlog:class+path=info",
+                "-Xlog:cds")
+                .ifNoMappingFailure(output -> {
+                    output.shouldContain("Hello World");
+                });
+    }
+}
+
diff --git a/hotspot/test/runtime/appcds/CommandLineFlagCombo.java b/hotspot/test/runtime/appcds/CommandLineFlagCombo.java
new file mode 100644
index 00000000..7f7ca7bf
--- /dev/null
+++ b/hotspot/test/runtime/appcds/CommandLineFlagCombo.java
@@ -0,0 +1,117 @@
+/*
+ * Copyright (c) 2014, 2018, 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.
+ *
+ */
+
+/*
+ * @test CommandLineFlagCombo
+ * @requires (vm.gc=="null")
+ * @summary Test command line flag combinations that
+ *          could likely affect the behaviour of AppCDS
+ * @library /testlibrary /testlibrary/whitebox
+ * @build sun.hotspot.WhiteBox
+ * @run driver ClassFileInstaller sun.hotspot.WhiteBox sun.hotspot.WhiteBox$WhiteBoxPermission
+ * @compile test-classes/Hello.java
+ * @run main/othervm/timeout=240 -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xbootclasspath/a:. CommandLineFlagCombo
+ */
+
+import com.oracle.java.testlibrary.BuildHelper;
+import com.oracle.java.testlibrary.Platform;
+import com.oracle.java.testlibrary.OutputAnalyzer;
+
+import sun.hotspot.code.Compiler;
+
+public class CommandLineFlagCombo {
+
+    // shared base address test table
+    private static final String[] testTable = {
+            "-XX:+UseG1GC", "-XX:+UseSerialGC", "-XX:+UseParallelGC", "-XX:+UseConcMarkSweepGC",
+            "-XX:+FlightRecorder",
+            "-XX:+UseLargePages", // may only take effect on machines with large-pages
+            "-XX:+UseCompressedClassPointers",
+            "-XX:+UseCompressedOops",
+            "-XX:ObjectAlignmentInBytes=16",
+            "-XX:ObjectAlignmentInBytes=32",
+            "-XX:ObjectAlignmentInBytes=64"
+    };
+
+    public static void main(String[] args) throws Exception {
+        String appJar = JarBuilder.getOrCreateHelloJar();
+        String classList[] = {"Hello"};
+
+        for (String testEntry : testTable) {
+            System.out.println("CommandLineFlagCombo = " + testEntry);
+
+            if (skipTestCase(testEntry))
+                continue;
+
+            OutputAnalyzer dumpOutput = TestCommon.dump(appJar, classList, testEntry);
+            TestCommon.checkDump(dumpOutput, "Loading classes to share");
+
+            OutputAnalyzer execOutput = TestCommon.exec(appJar, testEntry, "Hello");
+            TestCommon.checkExec(execOutput, "Hello World");
+        }
+
+        for (int i=0; i<2; i++) {
+            String g1Flag, serialFlag;
+
+            // Interned strings are supported only with G1GC. However, we should not crash if:
+            // 0: archive has shared strings, but run time doesn't support shared strings
+            // 1: archive has no shared strings, but run time supports shared strings
+
+            String dump_g1Flag     = "-XX:" + (i == 0 ? "+" : "-") + "UseG1GC";
+            String run_g1Flag      = "-XX:" + (i != 0 ? "+" : "-") + "UseG1GC";
+            String dump_serialFlag = "-XX:" + (i != 0 ? "+" : "-") + "UseSerialGC";
+            String run_serialFlag  = "-XX:" + (i == 0 ? "+" : "-") + "UseSerialGC";
+
+            OutputAnalyzer dumpOutput = TestCommon.dump(
+                    appJar, classList, dump_g1Flag, dump_serialFlag);
+
+            TestCommon.checkDump(dumpOutput, "Loading classes to share");
+
+            OutputAnalyzer execOutput = TestCommon.exec(appJar, run_g1Flag, run_serialFlag, "Hello");
+            TestCommon.checkExec(execOutput, "Hello World");
+        }
+    }
+
+    private static boolean skipTestCase(String testEntry) throws Exception {
+        if (Platform.is32bit())
+        {
+            if (testEntry.equals("-XX:+UseCompressedOops") ||
+                    testEntry.equals("-XX:+UseCompressedClassPointers") ||
+                    testEntry.contains("ObjectAlignmentInBytes") )
+            {
+                System.out.println("Test case not applicable on 32-bit platforms");
+                return true;
+            }
+        }
+
+        if (Compiler.isGraalEnabled() && testEntry.equals("-XX:+UseConcMarkSweepGC"))
+        {
+            System.out.println("Graal does not support CMS");
+            return true;
+        }
+
+        return false;
+    }
+}
+
diff --git a/hotspot/test/runtime/appcds/CommandLineFlagComboNegative.java b/hotspot/test/runtime/appcds/CommandLineFlagComboNegative.java
new file mode 100644
index 00000000..4fb965ab
--- /dev/null
+++ b/hotspot/test/runtime/appcds/CommandLineFlagComboNegative.java
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 2014, 2018, 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.
+ *
+ */
+
+/*
+ * @test CommandLineFlagComboNegative
+ * @summary Test command line flag combinations that differ between
+ *          the dump and execute steps, in such way that they cause errors
+ *          E.g. use compressed oops for creating and archive, but then
+ *               execute w/o compressed oops
+ * @library /testlibrary
+ * @compile test-classes/Hello.java
+ * @run main CommandLineFlagComboNegative
+ */
+
+import java.util.ArrayList;
+import com.oracle.java.testlibrary.Platform;
+import com.oracle.java.testlibrary.OutputAnalyzer;
+
+public class CommandLineFlagComboNegative {
+
+    private class TestVector {
+        public String testOptionForDumpStep;
+        public String testOptionForExecuteStep;
+        public String expectedErrorMsg;
+        public int expectedErrorCode;
+
+        public TestVector(String testOptionForDumpStep, String testOptionForExecuteStep,
+                          String expectedErrorMsg, int expectedErrorCode) {
+            this.testOptionForDumpStep=testOptionForDumpStep;
+            this.testOptionForExecuteStep=testOptionForExecuteStep;
+            this.expectedErrorMsg=expectedErrorMsg;
+            this.expectedErrorCode=expectedErrorCode;
+        }
+    }
+
+    private ArrayList<TestVector> testTable = new ArrayList<TestVector>();
+
+    private void initTestTable() {
+        // These options are not applicable on 32-bit platforms
+        if (Platform.is64bit()) {
+            testTable.add( new TestVector("-XX:ObjectAlignmentInBytes=8", "-XX:ObjectAlignmentInBytes=16",
+                    "An error has occurred while processing the shared archive file", 1) );
+            testTable.add( new TestVector("-XX:ObjectAlignmentInBytes=64", "-XX:ObjectAlignmentInBytes=32",
+                    "An error has occurred while processing the shared archive file", 1) );
+            testTable.add( new TestVector("-XX:+UseCompressedOops", "-XX:-UseCompressedOops",
+                    "Class data sharing is inconsistent with other specified options", 1) );
+            testTable.add( new TestVector("-XX:+UseCompressedClassPointers", "-XX:-UseCompressedClassPointers",
+                    "Class data sharing is inconsistent with other specified options", 1) );
+        }
+    }
+
+    private void runTests() throws Exception
+    {
+        for (TestVector testEntry : testTable) {
+            System.out.println("CommandLineFlagComboNegative: dump = " + testEntry.testOptionForDumpStep);
+            System.out.println("CommandLineFlagComboNegative: execute = " + testEntry.testOptionForExecuteStep);
+
+            String appJar = JarBuilder.getOrCreateHelloJar();
+            OutputAnalyzer dumpOutput = TestCommon.dump(
+                    appJar, new String[] {"Hello"}, testEntry.testOptionForDumpStep);
+
+            TestCommon.checkDump(dumpOutput, "Loading classes to share");
+
+            TestCommon.run(
+                    "-cp", appJar,
+                    testEntry.testOptionForExecuteStep,
+                    "Hello")
+                    .assertAbnormalExit(output -> {
+                        output.shouldContain(testEntry.expectedErrorMsg)
+                                .shouldHaveExitValue(testEntry.expectedErrorCode);
+                    });
+        }
+    }
+
+    public static void main(String[] args) throws Exception {
+        CommandLineFlagComboNegative thisClass = new CommandLineFlagComboNegative();
+        thisClass.initTestTable();
+        thisClass.runTests();
+    }
+}
+
diff --git a/hotspot/test/runtime/appcds/DirClasspathTest.java b/hotspot/test/runtime/appcds/DirClasspathTest.java
new file mode 100644
index 00000000..e2c4e698
--- /dev/null
+++ b/hotspot/test/runtime/appcds/DirClasspathTest.java
@@ -0,0 +1,116 @@
+/*
+ * Copyright (c) 2017, 2018, 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.
+ *
+ */
+
+/*
+ * @test
+ * @summary Handling of directories in -cp is based on the classlist
+ * @library /testlibrary
+ * @compile test-classes/Hello.java
+ * @run main DirClasspathTest
+ */
+
+import com.oracle.java.testlibrary.Platform;
+import com.oracle.java.testlibrary.OutputAnalyzer;
+import java.io.File;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.Arrays;
+
+public class DirClasspathTest {
+    private static final int MAX_PATH = 260;
+
+    public static void main(String[] args) throws Exception {
+        File dir = new File(System.getProperty("user.dir"));
+        File emptydir = new File(dir, "emptydir");
+        emptydir.mkdir();
+
+        /////////////////////////////////////////////////////////////////
+        // The classlist only contains boot class in following test cases
+        /////////////////////////////////////////////////////////////////
+        String bootClassList[] = {"java/lang/Object"};
+
+        // Empty dir in -cp: should be OK
+        OutputAnalyzer output;
+        output = TestCommon.dump(emptydir.getPath(), bootClassList);
+        TestCommon.checkDump(output);
+
+        // Long path to empty dir in -cp: should be OK
+        Path classDir = Paths.get(System.getProperty("test.classes"));
+        Path destDir = classDir;
+        int subDirLen = MAX_PATH - classDir.toString().length() - 2;
+        if (subDirLen > 0) {
+            char[] chars = new char[subDirLen];
+            Arrays.fill(chars, 'x');
+            String subPath = new String(chars);
+            destDir = Paths.get(System.getProperty("test.classes"), subPath);
+        }
+        File longDir = destDir.toFile();
+        longDir.mkdir();
+        File subDir = new File(longDir, "subdir");
+        subDir.mkdir();
+        output = TestCommon.dump(subDir.getPath(), bootClassList);
+        TestCommon.checkDump(output);
+
+        // Non-empty dir in -cp: should be OK
+        // <dir> is not empty because it has at least one subdirectory, i.e., <emptydir>
+        output = TestCommon.dump(dir.getPath(), bootClassList);
+        TestCommon.checkDump(output);
+
+        // Long path to non-empty dir in -cp: should be OK
+        // <dir> is not empty because it has at least one subdirectory, i.e., <emptydir>
+        output = TestCommon.dump(longDir.getPath(), bootClassList);
+        TestCommon.checkDump(output);
+
+        /////////////////////////////////////////////////////////////////
+        // The classlist contains non-boot class in following test cases
+        /////////////////////////////////////////////////////////////////
+        String appClassList[] = {"java/lang/Object", "com/sun/tools/javac/Main"};
+
+        // Non-empty dir in -cp: should be OK (as long as no classes were loaded from there)
+        output = TestCommon.dump(dir.getPath(), appClassList);
+        TestCommon.checkDump(output);
+
+        // Long path to non-empty dir in -cp: should be OK (as long as no classes were loaded from there)
+        output = TestCommon.dump(longDir.getPath(), appClassList);
+        TestCommon.checkDump(output);
+
+        /////////////////////////////////////////////////////////////////
+        // Loading an app class from a directory
+        /////////////////////////////////////////////////////////////////
+        String appClassList2[] = {"Hello", "java/lang/Object", "com/sun/tools/javac/Main"};
+        // Non-empty dir in -cp: should report error if a class is loaded from it
+        output = TestCommon.dump(classDir.toString(), appClassList2);
+        output.shouldNotHaveExitValue(1);
+        output.shouldContain("Cannot find com/sun/tools/javac/Main");
+        // Long path to non-empty dir in -cp: should report error if a class is loaded from it
+        File srcClass = new File(classDir.toFile(), "Hello.class");
+        File destClass = new File(longDir, "Hello.class");
+        Files.copy(srcClass.toPath(), destClass.toPath());
+        output = TestCommon.dump(longDir.getPath(), appClassList2);
+        output.shouldNotHaveExitValue(1);
+        output.shouldContain("Cannot find Hello");
+    }
+}
+
diff --git a/hotspot/test/runtime/appcds/HelloTest.java b/hotspot/test/runtime/appcds/HelloTest.java
new file mode 100644
index 00000000..c49179a1
--- /dev/null
+++ b/hotspot/test/runtime/appcds/HelloTest.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2015, 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.
+ *
+ */
+
+/*
+ * @test
+ * @summary Hello World test for AppCDS
+ * @library /testlibrary
+ * @compile test-classes/Hello.java
+ * @run main HelloTest
+ */
+
+public class HelloTest {
+  public static void main(String[] args) throws Exception {
+      TestCommon.test(JarBuilder.getOrCreateHelloJar(),
+          TestCommon.list("Hello"), "Hello");
+  }
+}
diff --git a/hotspot/test/runtime/appcds/IgnoreEmptyClassPaths.java b/hotspot/test/runtime/appcds/IgnoreEmptyClassPaths.java
new file mode 100644
index 00000000..36618b17
--- /dev/null
+++ b/hotspot/test/runtime/appcds/IgnoreEmptyClassPaths.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2014, 2018, 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.
+ *
+ */
+
+/*
+ * @test
+ * @summary Test the -XX:+IgnoreEmptyClassPaths flag
+ * @library /testlibrary
+ * @compile test-classes/Hello.java
+ * @compile test-classes/HelloMore.java
+ * @run main IgnoreEmptyClassPaths
+ */
+
+import java.io.File;
+import com.oracle.java.testlibrary.OutputAnalyzer;
+
+public class IgnoreEmptyClassPaths {
+
+    public static void main(String[] args) throws Exception {
+        String jar1 = JarBuilder.getOrCreateHelloJar();
+        String jar2 = JarBuilder.build("IgnoreEmptyClassPaths_more", "HelloMore");
+
+        String sep = File.pathSeparator;
+        String cp_dump = jar1 + sep + jar2 + sep;
+        String cp_exec = sep + jar1 + sep + sep + jar2 + sep;
+
+        TestCommon.testDump(cp_dump, TestCommon.list("Hello", "HelloMore"),
+                "-XX:+TraceClassPaths", "-XX:+IgnoreEmptyClassPaths");
+
+        TestCommon.run(
+                "-verbose:class",
+                "-cp", cp_exec,
+                "-XX:+IgnoreEmptyClassPaths", // should affect classpath even if placed after the "-cp" argument
+                "-XX:+TraceClassPaths",
+                "HelloMore")
+                .assertNormalExit();
+    }
+}
diff --git a/hotspot/test/runtime/appcds/JarBuilder.java b/hotspot/test/runtime/appcds/JarBuilder.java
new file mode 100644
index 00000000..e06ab2bc
--- /dev/null
+++ b/hotspot/test/runtime/appcds/JarBuilder.java
@@ -0,0 +1,270 @@
+/*
+ * Copyright (c) 2015, 2018, 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.
+ *
+ */
+
+/*
+ * @summary Simple jar builder
+ *   Input: jarName className1 className2 ...
+ *     do not specify extensions, just the names
+ *     E.g. prot_domain ProtDomainA ProtDomainB
+ *   Output: A jar containing compiled classes, placed in a test classes folder
+ * @library /open/test/lib
+ */
+
+import java.io.File;
+import java.nio.file.Path;
+import java.util.ArrayList;
+
+import com.oracle.java.testlibrary.JDKToolFinder;
+import com.oracle.java.testlibrary.OutputAnalyzer;
+import com.oracle.java.testlibrary.ProcessTools;
+import com.oracle.java.testlibrary.compiler.CompilerUtils;
+import sun.tools.jar.Main;
+
+public class JarBuilder {
+    // to turn DEBUG on via command line: -DJarBuilder.DEBUG=[true, TRUE]
+    private static final boolean DEBUG = Boolean.parseBoolean(System.getProperty("JarBuilder.DEBUG", "false"));
+    private static final String classDir = System.getProperty("test.classes");
+
+    public static String getJarFilePath(String jarName) {
+        return classDir + File.separator + jarName + ".jar";
+    }
+
+    // jar all files under dir, with manifest file man, with an optional versionArgs
+    // for generating a multi-release jar.
+    // The jar command is as follows:
+    // jar cmf \
+    //  <path to output jar> <path to the manifest file>\
+    //   -C <path to the base classes> .\
+    //    --release 9 -C <path to the versioned classes> .
+    // the last line begins with "--release" corresponds to the optional versionArgs.
+    public static void build(String jarName, File dir, String man, String...versionArgs)
+        throws Exception {
+        ArrayList<String> args = new ArrayList<String>();
+        if (man != null) {
+            args.add("cfm");
+        } else {
+            args.add("cf");
+        }
+        args.add(classDir + File.separator + jarName + ".jar");
+        if (man != null) {
+            args.add(man);
+        }
+        args.add("-C");
+        args.add(dir.getAbsolutePath());
+        args.add(".");
+        for (String verArg : versionArgs) {
+            args.add(verArg);
+        }
+        createJar(args);
+    }
+
+    public static String build(String jarName, String...classNames)
+        throws Exception {
+
+        return createSimpleJar(classDir, getJarFilePath(jarName), classNames);
+    }
+
+    public static String build(boolean classesInWorkDir, String jarName, String...classNames)
+        throws Exception {
+        if (classesInWorkDir) {
+            return createSimpleJar(".", getJarFilePath(jarName), classNames);
+        } else {
+            return build(jarName, classNames);
+        }
+    }
+
+
+    public static String buildWithManifest(String jarName, String manifest,
+                                           String jarClassesDir, String...classNames) throws Exception {
+        String jarPath = getJarFilePath(jarName);
+        ArrayList<String> args = new ArrayList<String>();
+        args.add("cvfm");
+        args.add(jarPath);
+        args.add(System.getProperty("test.src") + File.separator + "test-classes"
+            + File.separator + manifest);
+        addClassArgs(args, jarClassesDir, classNames);
+        createJar(args);
+
+        return jarPath;
+    }
+
+
+    // Execute: jar uvf $jarFile -C $dir .
+    static void update(String jarFile, String dir) throws Exception {
+        String jarExe = JDKToolFinder.getJDKTool("jar");
+
+        ArrayList<String> args = new ArrayList<>();
+        args.add(jarExe);
+        args.add("uvf");
+        args.add(jarFile);
+        args.add("-C");
+        args.add(dir);
+        args.add(".");
+
+        executeProcess(args.toArray(new String[1]));
+    }
+
+
+    private static String createSimpleJar(String jarclassDir, String jarName,
+                                          String[] classNames) throws Exception {
+
+        ArrayList<String> args = new ArrayList<String>();
+        args.add("cf");
+        args.add(jarName);
+        addClassArgs(args, jarclassDir, classNames);
+        createJar(args);
+
+        return jarName;
+    }
+
+    private static void addClassArgs(ArrayList<String> args, String jarclassDir,
+                                     String[] classNames) {
+
+        for (String name : classNames) {
+            args.add("-C");
+            args.add(jarclassDir);
+            args.add(name + ".class");
+        }
+    }
+
+    public static void createModularJar(String jarPath,
+                                        String classesDir,
+                                        String mainClass) throws Exception {
+        ArrayList<String> argList = new ArrayList<String>();
+        argList.add("--create");
+        argList.add("--file=" + jarPath);
+        if (mainClass != null) {
+            argList.add("--main-class=" + mainClass);
+        }
+        argList.add("-C");
+        argList.add(classesDir);
+        argList.add(".");
+        createJar(argList);
+    }
+
+    private static void createJar(ArrayList<String> args) {
+        if (DEBUG) printIterable("createJar args: ", args);
+
+        Main jarTool = new Main(System.out, System.err, "jar");
+        if (!jarTool.run(args.toArray(new String[1]))) {
+            throw new RuntimeException("jar operation failed");
+        }
+    }
+
+    // Many AppCDS tests use the same simple "Hello.jar" which contains
+    // simple Hello.class and does not specify additional attributes.
+    // For this common use case, use this method to get the jar path.
+    // The method will check if the jar already exists
+    // (created by another test or test run), and will create the jar
+    // if it does not exist
+    public static String getOrCreateHelloJar() throws Exception {
+        String jarPath = getJarFilePath("hello");
+
+        File jarFile = new File(jarPath);
+        if (jarFile.exists()) {
+            return jarPath;
+        } else {
+            return build("hello", "Hello");
+        }
+    }
+
+    public static void compile(String dstPath, String source, String... extraArgs) throws Exception {
+        ArrayList<String> args = new ArrayList<String>();
+        args.add(JDKToolFinder.getCompileJDKTool("javac"));
+        args.add("-d");
+        args.add(dstPath);
+        if (extraArgs != null) {
+            for (String s : extraArgs) {
+                args.add(s);
+            }
+        }
+        args.add(source);
+
+        if (DEBUG) printIterable("compile args: ", args);
+
+        ProcessBuilder pb = new ProcessBuilder(args);
+        OutputAnalyzer output = new OutputAnalyzer(pb.start());
+        output.shouldHaveExitValue(0);
+    }
+
+    public static void compileModule(Path src,
+                                     Path dest,
+                                     String modulePathArg // arg to --module-path
+                                     ) throws Exception {
+        boolean compiled = false;
+        if (modulePathArg == null) {
+            compiled = CompilerUtils.compile(src, dest);
+        } else {
+            compiled = CompilerUtils.compile(src, dest,
+                                           "--module-path", modulePathArg);
+        }
+        if (!compiled) {
+            throw new RuntimeException("module did not compile");
+        }
+    }
+
+
+    public static void signJar() throws Exception {
+        String keyTool = JDKToolFinder.getJDKTool("keytool");
+        String jarSigner = JDKToolFinder.getJDKTool("jarsigner");
+        String classDir = System.getProperty("test.classes");
+        String FS = File.separator;
+
+        executeProcess(keyTool,
+            "-genkey", "-keystore", "./keystore", "-alias", "mykey",
+            "-storepass", "abc123", "-keypass", "abc123",
+            "-dname", "CN=jvmtest")
+            .shouldHaveExitValue(0);
+
+        executeProcess(jarSigner,
+           "-keystore", "./keystore", "-storepass", "abc123", "-keypass",
+           "abc123", "-signedjar", classDir + FS + "signed_hello.jar",
+           classDir + FS + "hello.jar", "mykey")
+           .shouldHaveExitValue(0);
+    }
+
+    private static OutputAnalyzer executeProcess(String... cmds)
+        throws Exception {
+
+        JarBuilder.printArray("executeProcess: ", cmds);
+        return ProcessTools.executeProcess(new ProcessBuilder(cmds));
+    }
+
+    // diagnostic
+    public static void printIterable(String msg, Iterable<String> l) {
+        StringBuilder sum = new StringBuilder();
+        for (String s : l) {
+            sum.append(s).append(' ');
+        }
+        System.out.println(msg + sum.toString());
+    }
+
+    public static void printArray(String msg, String[] l) {
+        StringBuilder sum = new StringBuilder();
+        for (String s : l) {
+            sum.append(s).append(' ');
+        }
+        System.out.println(msg + sum.toString());
+    }
+}
diff --git a/hotspot/test/runtime/appcds/MismatchedUseAppCDS.java b/hotspot/test/runtime/appcds/MismatchedUseAppCDS.java
new file mode 100644
index 00000000..7173d6c9
--- /dev/null
+++ b/hotspot/test/runtime/appcds/MismatchedUseAppCDS.java
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2015, 2018, 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.
+ *
+ */
+
+/*
+ * @test
+ * @summary Try different combination of mismatched UseAppCDS between dump time and run time.
+ * @library /testlibrary /testlibrary/whitebox
+ * @compile test-classes/CheckIfShared.java
+ * @build sun.hotspot.WhiteBox
+ * @run driver ClassFileInstaller sun.hotspot.WhiteBox
+ * @run main MismatchedUseAppCDS
+ */
+
+import com.oracle.java.testlibrary.OutputAnalyzer;
+
+public class MismatchedUseAppCDS {
+    public static void main(String[] args) throws Exception {
+        String wbJar = JarBuilder.build(true, "WhiteBox", "sun/hotspot/WhiteBox");
+        String use_whitebox_jar = "-Xbootclasspath/a:" + wbJar;
+
+        String appJar = JarBuilder.build("MismatchedUseAppCDS", "CheckIfShared");
+
+        OutputAnalyzer output;
+
+        // (1): dump with -XX:+UseAppCDS, but run with -XX:-UseAppCDS
+        TestCommon.testDump(appJar, TestCommon.list("CheckIfShared"),
+                // command-line arguments ...
+                "-XX:+UseAppCDS",
+                use_whitebox_jar);
+
+        output = TestCommon.exec(appJar,
+                // command-line arguments ...
+                use_whitebox_jar,
+                "-XX:+UnlockDiagnosticVMOptions",
+                "-XX:+WhiteBoxAPI",
+                "CheckIfShared", "false");
+        TestCommon.checkExec(output);
+
+        // (2): dump with -XX:-UseAppCDS, but run with -XX:+UseAppCDS
+        TestCommon.testDump(appJar, TestCommon.list("CheckIfShared"),
+                // command-line arguments ...
+                "-XX:+UseAppCDS",
+                use_whitebox_jar);
+
+        output = TestCommon.exec(appJar,
+                // command-line arguments ...
+                use_whitebox_jar,
+                "-XX:+UseAppCDS",
+                "-XX:+UnlockDiagnosticVMOptions",
+                "-XX:+WhiteBoxAPI",
+                "CheckIfShared", "true");
+        TestCommon.checkExec(output);
+    }
+}
+
diff --git a/hotspot/test/runtime/appcds/MissingSuperTest.java b/hotspot/test/runtime/appcds/MissingSuperTest.java
new file mode 100644
index 00000000..33a860b4
--- /dev/null
+++ b/hotspot/test/runtime/appcds/MissingSuperTest.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2014, 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.
+ *
+ */
+
+/*
+ * @test
+ * @summary When super class is missing during dumping, no crash should happen.
+ * @library /testlibrary
+ * @compile test-classes/MissingSuper.java
+ * @run main MissingSuperTest
+ */
+
+public class MissingSuperTest {
+
+  public static void main(String[] args) throws Exception {
+    // The classes "MissingSuperSup" and "MissingSuperIntf" are intentionally not
+    // included into the jar to provoke the test condition
+    JarBuilder.build("missing_super", "MissingSuper",
+        "MissingSuperSub", "MissingSuperImpl");
+
+    String appJar = TestCommon.getTestJar("missing_super.jar");
+    TestCommon.test(appJar, TestCommon.list("MissingSuper",
+        "MissingSuperSub",
+        "MissingSuperImpl"),
+        "MissingSuper");
+  }
+}
diff --git a/hotspot/test/runtime/appcds/PackageSealing.java b/hotspot/test/runtime/appcds/PackageSealing.java
new file mode 100644
index 00000000..6c915085
--- /dev/null
+++ b/hotspot/test/runtime/appcds/PackageSealing.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2014, 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.
+ *
+ */
+
+/*
+ * @test
+ * @summary AppCDS handling of package.
+ * @library /testlibrary
+ * @compile test-classes/C1.java
+ * @compile test-classes/C2.java
+ * @compile test-classes/PackageSealingTest.java
+ * @run main PackageSealing
+ */
+
+import com.oracle.java.testlibrary.OutputAnalyzer;
+
+public class PackageSealing {
+    public static void main(String args[]) throws Exception {
+        String[] classList = {"sealed/pkg/C1", "pkg/C2", "PackageSealingTest"};
+        String appJar = ClassFileInstaller.writeJar("pkg_seal.jar",
+                ClassFileInstaller.Manifest.fromSourceFile("test-classes/package_seal.mf"),
+                "PackageSealingTest", "sealed/pkg/C1", "pkg/C2");
+
+        // test shared package from -cp path
+        TestCommon.testDump(appJar, TestCommon.list(classList));
+        OutputAnalyzer output;
+        output = TestCommon.exec(appJar, "PackageSealingTest");
+        TestCommon.checkExec(output);
+
+        // test shared package from -Xbootclasspath/a
+        TestCommon.dump(appJar, TestCommon.list(classList),
+                "-Xbootclasspath/a:" + appJar);
+        output = TestCommon.exec(appJar, "-Xbootclasspath/a:" + appJar, "PackageSealingTest");
+        TestCommon.checkExec(output);
+    }
+}
diff --git a/hotspot/test/runtime/appcds/ParallelLoad2.java b/hotspot/test/runtime/appcds/ParallelLoad2.java
new file mode 100644
index 00000000..5709be6a
--- /dev/null
+++ b/hotspot/test/runtime/appcds/ParallelLoad2.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2014, 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.
+ *
+ */
+
+/*
+ * @test
+ * @summary Load app classes from CDS archive in parallel threads. Similar to ParallelLoad.java, but each class in its own JAR
+ * @library /testlibrary
+ * @compile test-classes/ParallelLoad.java
+ * @compile test-classes/ParallelClasses.java
+ * @run main ParallelLoad2
+ */
+
+import java.io.File;
+
+public class ParallelLoad2 {
+    public static int MAX_CLASSES = 40;
+    public static void main(String[] args) throws Exception {
+        JarBuilder.build("parallel_load2", "ParallelLoad", "ParallelLoadThread", "ParallelLoadWatchdog");
+        for (int i=0; i<MAX_CLASSES; i++) {
+            JarBuilder.build("parallel_load2_" + i, "ParallelClass" + i);
+        }
+
+        String cp = TestCommon.getTestJar("parallel_load2.jar");
+        for (int i=0; i<MAX_CLASSES; i++) {
+            cp += File.pathSeparator + TestCommon.getTestJar("parallel_load2_" + i + ".jar");
+        }
+
+        String[] class_list = new String[MAX_CLASSES + 2];
+        for (int i=0; i<MAX_CLASSES; i++) {
+            class_list[i] = "ParallelClass" + i;
+        }
+        class_list[class_list.length - 1] = "ParallelLoad";
+        class_list[class_list.length - 2] = "ParallelLoadThread";
+
+        TestCommon.test(cp, class_list,
+                "ParallelLoad");
+    }
+}
+
diff --git a/hotspot/test/runtime/appcds/ParallelLoadTest.java b/hotspot/test/runtime/appcds/ParallelLoadTest.java
new file mode 100644
index 00000000..92d17a47
--- /dev/null
+++ b/hotspot/test/runtime/appcds/ParallelLoadTest.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2014, 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.
+ *
+ */
+
+/*
+ * @test
+ * @summary Load app classes from CDS archive in parallel threads
+ * @library /testlibrary
+ * @compile test-classes/ParallelLoad.java
+ * @compile test-classes/ParallelClasses.java
+ * @run main ParallelLoadTest
+ */
+
+public class ParallelLoadTest {
+    public static final int MAX_CLASSES = 40;
+
+    public static void main(String[] args) throws Exception {
+        JarBuilder.build("parallel_load", getClassList(true));
+        String appJar = TestCommon.getTestJar("parallel_load.jar");
+        TestCommon.test(appJar, getClassList(false), "ParallelLoad");
+    }
+
+    private static String[] getClassList(boolean includeWatchdog) {
+        int extra = includeWatchdog ? 3 : 2;
+        String[] classList = new String[MAX_CLASSES + extra];
+
+        int i;
+        for (i=0; i<MAX_CLASSES; i++) {
+            classList[i] = "ParallelClass" + i;
+        }
+
+        classList[i++] = "ParallelLoad";
+        classList[i++] = "ParallelLoadThread";
+        if (includeWatchdog)
+            classList[i++] = "ParallelLoadWatchdog";
+
+        return classList;
+    }
+}
+
diff --git a/hotspot/test/runtime/appcds/SharedBaseAddress.java b/hotspot/test/runtime/appcds/SharedBaseAddress.java
new file mode 100644
index 00000000..b03b0876
--- /dev/null
+++ b/hotspot/test/runtime/appcds/SharedBaseAddress.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2014, 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.
+ *
+ */
+
+/*
+ * @test SharedBaseAddress
+ * @summary Test variety of values for SharedBaseAddress, in AppCDS mode,
+ *          making sure VM handles normal values as well as edge values
+ *          w/o a crash.
+ * @library /testlibrary
+ * @compile test-classes/Hello.java
+ * @run main/timeout=240 SharedBaseAddress
+ */
+
+import com.oracle.java.testlibrary.OutputAnalyzer;
+
+public class SharedBaseAddress {
+
+    // shared base address test table
+    private static final String[] testTable = {
+            "1g", "8g", "64g","512g", "4t",
+            "32t", "128t", "0",
+            "1", "64k", "64M"
+    };
+
+    public static void main(String[] args) throws Exception {
+        String appJar = JarBuilder.getOrCreateHelloJar();
+
+        for (String testEntry : testTable) {
+            System.out.println("sharedBaseAddress = " + testEntry);
+
+            OutputAnalyzer dumpOutput = TestCommon.dump(
+                    appJar, new String[] {"Hello"}, "-XX:SharedBaseAddress=" + testEntry);
+            TestCommon.checkDump(dumpOutput, "Loading classes to share");
+
+            OutputAnalyzer execOutput = TestCommon.exec(appJar, "Hello");
+            TestCommon.checkExec(execOutput, "Hello World");
+        }
+    }
+}
+
diff --git a/hotspot/test/runtime/appcds/TestCommon.java b/hotspot/test/runtime/appcds/TestCommon.java
new file mode 100644
index 00000000..4ed416fe
--- /dev/null
+++ b/hotspot/test/runtime/appcds/TestCommon.java
@@ -0,0 +1,363 @@
+/*
+ * Copyright (c) 2014, 2018, 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.
+ *
+ */
+
+import com.oracle.java.testlibrary.OutputAnalyzer;
+import com.oracle.java.testlibrary.ProcessTools;
+import com.oracle.java.testlibrary.cds.CDSTestUtils;
+import java.io.File;
+import java.text.SimpleDateFormat;
+import java.util.Arrays;
+import java.util.ArrayList;
+import java.util.Date;
+
+/**
+ * This is a test utility class for common AppCDS test functionality.
+ *
+ * Various methods use (String ...) for passing VM options. Note that the order
+ * of the VM options are important in certain cases. Many methods take arguments like
+ *
+ *    (String prefix[], String suffix[], String... opts)
+ *
+ * Note that the order of the VM options is:
+ *
+ *    prefix + opts + suffix
+ */
+public class TestCommon extends CDSTestUtils {
+    private static final String JSA_FILE_PREFIX = System.getProperty("user.dir") +
+        File.separator + "appcds-";
+
+    private static final SimpleDateFormat timeStampFormat =
+        new SimpleDateFormat("HH'h'mm'm'ss's'SSS");
+
+    private static final String timeoutFactor =
+        System.getProperty("test.timeout.factor", "1.0");
+
+    private static String currentArchiveName;
+
+    // Call this method to start new archive with new unique name
+    public static void startNewArchiveName() {
+        deletePriorArchives();
+        currentArchiveName = JSA_FILE_PREFIX +
+            timeStampFormat.format(new Date()) + ".jsa";
+    }
+
+    // Call this method to get current archive name
+    public static String getCurrentArchiveName() {
+        return currentArchiveName;
+    }
+
+    public static void setCurrentArchiveName(String archiveName) {
+        currentArchiveName = archiveName;
+    }
+
+    // Attempt to clean old archives to preserve space
+    // Archives are large artifacts (20Mb or more), and much larger than
+    // most other artifacts created in jtreg testing.
+    // Therefore it is a good idea to clean the old archives when they are not needed.
+    // In most cases the deletion attempt will succeed; on rare occasion the
+    // delete operation will fail since the system or VM process still holds a handle
+    // to the file; in such cases the File.delete() operation will silently fail, w/o
+    // throwing an exception, thus allowing testing to continue.
+    public static void deletePriorArchives() {
+        File dir = new File(System.getProperty("user.dir"));
+        String files[] = dir.list();
+        for (String name : files) {
+            if (name.startsWith("appcds-") && name.endsWith(".jsa")) {
+                if (!(new File(dir, name)).delete())
+                    System.out.println("deletePriorArchives(): delete failed for file " + name);
+            }
+        }
+    }
+
+
+    // Create AppCDS archive using most common args - convenience method
+    // Legacy name preserved for compatibility
+    public static OutputAnalyzer dump(String appJar, String appClasses[],
+                                      String... suffix) throws Exception {
+        return createArchive(appJar, appClasses, suffix);
+    }
+
+
+    // Create AppCDS archive using most common args - convenience method
+    public static OutputAnalyzer createArchive(String appJar, String appClasses[],
+                                               String... suffix) throws Exception {
+        AppCDSOptions opts = (new AppCDSOptions()).setAppJar(appJar)
+            .setAppClasses(appClasses);
+        opts.addSuffix(suffix);
+        return createArchive(opts);
+    }
+
+    public static String[] makeCommandLineForAppCDS(String... args) throws Exception {
+        return args;
+    }
+
+    // Create AppCDS archive using appcds options
+    public static OutputAnalyzer createArchive(AppCDSOptions opts)
+        throws Exception {
+
+        ArrayList<String> cmd = new ArrayList<String>();
+        File classList = makeClassList(opts.appClasses);
+        startNewArchiveName();
+
+        for (String p : opts.prefix) cmd.add(p);
+
+        if (opts.appJar != null) {
+            cmd.add("-cp");
+            cmd.add(opts.appJar);
+        } else {
+            cmd.add("-cp");
+            cmd.add("\"\"");
+        }
+
+        cmd.add("-Xshare:dump");
+//        cmd.add("-Xlog:cds,cds+hashtables"); comment out because it will be run by jdk1.8
+        cmd.add("-XX:ExtraSharedClassListFile=" + classList.getPath());
+
+        if (opts.archiveName == null)
+            opts.archiveName = getCurrentArchiveName();
+
+        cmd.add("-XX:SharedArchiveFile=" + opts.archiveName);
+
+        for (String s : opts.suffix) cmd.add(s);
+
+        String[] cmdLine = cmd.toArray(new String[cmd.size()]);
+        ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(true, makeCommandLineForAppCDS(cmdLine));
+        return executeAndLog(pb, "dump");
+    }
+
+
+    // Execute JVM using AppCDS archive with specified AppCDSOptions
+    public static OutputAnalyzer runWithArchive(AppCDSOptions opts)
+        throws Exception {
+
+        ArrayList<String> cmd = new ArrayList<String>();
+
+        for (String p : opts.prefix) cmd.add(p);
+
+        cmd.add("-Xshare:" + opts.xShareMode);
+        cmd.add("-showversion");
+        cmd.add("-XX:SharedArchiveFile=" + getCurrentArchiveName());
+        cmd.add("-Dtest.timeout.factor=" + timeoutFactor);
+
+        if (opts.appJar != null) {
+            cmd.add("-cp");
+            cmd.add(opts.appJar);
+        }
+
+        for (String s : opts.suffix) cmd.add(s);
+
+        String[] cmdLine = cmd.toArray(new String[cmd.size()]);
+        ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(true, makeCommandLineForAppCDS(cmdLine));
+        return executeAndLog(pb, "exec");
+    }
+
+
+    public static OutputAnalyzer execCommon(String... suffix) throws Exception {
+        AppCDSOptions opts = (new AppCDSOptions());
+        opts.addSuffix(suffix);
+        return runWithArchive(opts);
+    }
+
+    // This is the new API for running a Java process with CDS enabled.
+    // See comments in the CDSTestUtils.Result class for how to use this method.
+    public static Result run(String... suffix) throws Exception {
+        AppCDSOptions opts = (new AppCDSOptions());
+        opts.addSuffix(suffix);
+        return new Result(opts, runWithArchive(opts));
+    }
+
+    public static OutputAnalyzer exec(String appJar, String... suffix) throws Exception {
+        AppCDSOptions opts = (new AppCDSOptions()).setAppJar(appJar);
+        opts.addSuffix(suffix);
+        return runWithArchive(opts);
+    }
+
+    public static Result runWithModules(String prefix[], String upgrademodulepath, String modulepath,
+                                            String mid, String... testClassArgs) throws Exception {
+        AppCDSOptions opts = makeModuleOptions(prefix, upgrademodulepath, modulepath,
+                                               mid, testClassArgs);
+        return new Result(opts, runWithArchive(opts));
+    }
+
+    public static OutputAnalyzer execAuto(String... suffix) throws Exception {
+        AppCDSOptions opts = (new AppCDSOptions());
+        opts.addSuffix(suffix).setXShareMode("auto");
+        return runWithArchive(opts);
+    }
+
+    public static OutputAnalyzer execOff(String... suffix) throws Exception {
+        AppCDSOptions opts = (new AppCDSOptions());
+        opts.addSuffix(suffix).setXShareMode("off");
+        return runWithArchive(opts);
+    }
+
+
+    private static AppCDSOptions makeModuleOptions(String prefix[], String upgrademodulepath, String modulepath,
+                                            String mid, String testClassArgs[]) {
+        AppCDSOptions opts = (new AppCDSOptions());
+
+        opts.addPrefix(prefix);
+        if (upgrademodulepath == null) {
+            opts.addSuffix("-p", modulepath, "-m", mid);
+        } else {
+            opts.addSuffix("--upgrade-module-path", upgrademodulepath,
+                           "-p", modulepath, "-m", mid);
+        }
+        opts.addSuffix(testClassArgs);
+        return opts;
+    }
+
+    public static OutputAnalyzer execModule(String prefix[], String upgrademodulepath, String modulepath,
+                                            String mid, String... testClassArgs)
+        throws Exception {
+        AppCDSOptions opts = makeModuleOptions(prefix, upgrademodulepath, modulepath,
+                                               mid, testClassArgs);
+        return runWithArchive(opts);
+    }
+
+
+    // A common operation: dump, then check results
+    public static OutputAnalyzer testDump(String appJar, String appClasses[],
+                                          String... suffix) throws Exception {
+        OutputAnalyzer output = dump(appJar, appClasses, suffix);
+        output.shouldContain("Loading classes to share");
+        output.shouldHaveExitValue(0);
+        return output;
+    }
+
+
+    /**
+     * Simple test -- dump and execute appJar with the given appClasses in classlist.
+     */
+    public static OutputAnalyzer test(String appJar, String appClasses[], String... args)
+        throws Exception {
+        testDump(appJar, appClasses);
+
+        OutputAnalyzer output = exec(appJar, args);
+        return checkExec(output);
+    }
+
+
+    public static OutputAnalyzer checkExecReturn(OutputAnalyzer output, int ret,
+                           boolean checkContain, String... matches) throws Exception {
+        try {
+            for (String s : matches) {
+                if (checkContain) {
+                    output.shouldContain(s);
+                } else {
+                    output.shouldNotContain(s);
+                }
+            }
+            output.shouldHaveExitValue(ret);
+        } catch (Exception e) {
+            checkCommonExecExceptions(output, e);
+        }
+
+        return output;
+    }
+
+
+    // Convenience concatenation utils
+    public static String[] list(String ...args) {
+        return args;
+    }
+
+
+    public static String[] list(String arg, int count) {
+        ArrayList<String> stringList = new ArrayList<String>();
+        for (int i = 0; i < count; i++) {
+            stringList.add(arg);
+        }
+
+        String outputArray[] = stringList.toArray(new String[stringList.size()]);
+        return outputArray;
+    }
+
+
+    public static String[] concat(String... args) {
+        return list(args);
+    }
+
+
+    public static String[] concat(String prefix[], String... extra) {
+        ArrayList<String> list = new ArrayList<String>();
+        for (String s : prefix) {
+            list.add(s);
+        }
+        for (String s : extra) {
+            list.add(s);
+        }
+
+        return list.toArray(new String[list.size()]);
+    }
+
+
+    // ===================== Concatenate paths
+    public static String concatPaths(String... paths) {
+        String prefix = "";
+        String s = "";
+        for (String p : paths) {
+            s += prefix;
+            s += p;
+            prefix = File.pathSeparator;
+        }
+        return s;
+    }
+
+
+    public static String getTestJar(String jar) {
+        File jarFile = CDSTestUtils.getTestArtifact(jar, true);
+        if (!jarFile.isFile()) {
+            throw new RuntimeException("Not a regular file: " + jarFile.getPath());
+        }
+        return jarFile.getPath();
+    }
+
+
+    public static String getTestDir(String d) {
+        File dirFile = CDSTestUtils.getTestArtifact(d, true);
+        if (!dirFile.isDirectory()) {
+            throw new RuntimeException("Not a directory: " + dirFile.getPath());
+        }
+        return dirFile.getPath();
+    }
+
+    public static boolean checkOutputStrings(String outputString1,
+                                             String outputString2,
+                                             String split_regex) {
+        String[] sa1 = outputString1.split(split_regex);
+        String[] sa2 = outputString2.split(split_regex);
+        Arrays.sort(sa1);
+        Arrays.sort(sa2);
+
+        int i = 0;
+        for (String s : sa1) {
+            if (!s.equals(sa2[i])) {
+                throw new RuntimeException(s + " is different from " + sa2[i]);
+            }
+            i ++;
+        }
+        return true;
+    }
+}
diff --git a/hotspot/test/runtime/appcds/TraceLongClasspath.java b/hotspot/test/runtime/appcds/TraceLongClasspath.java
new file mode 100644
index 00000000..e25fcd37
--- /dev/null
+++ b/hotspot/test/runtime/appcds/TraceLongClasspath.java
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2014, 2018, 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.
+ *
+ */
+
+/*
+ * @test
+ * @summary ensure -XX:+TraceClassPaths showing entire expecting app classpath
+ * @library /testlibrary
+ * @compile test-classes/Hello.java
+ * @run main TraceLongClasspath
+ */
+
+import java.io.File;
+import com.oracle.java.testlibrary.OutputAnalyzer;
+
+public class TraceLongClasspath {
+
+    final static String ps = File.pathSeparator;
+
+    public static void main(String[] args) throws Exception {
+        String appJar = JarBuilder.getOrCreateHelloJar();
+
+        String longClassPath =
+                "/scratch/xxxx/yyyy/ZZZZZZ/aaaaaaaaaa/xx/abc/abc/modules/user-patch.jar" + ps +
+                        "/scratch/xxxx/yyyy/ZZZZZZ/aaaaaaaaaa/xx/abc/abc/modules/abc-startup.jar" + ps +
+                        "/scratch/xxxx/yyyy/ZZZZZZ/aaaaaaaaaa/xx/foobar_common/modules/features/com.foobar.db.jdbc7-dms.jar" + ps +
+                        "/scratch/xxxx/yyyy/ZZZZZZ/aaaaaaaaaa/jdk/lib/tools.jar" + ps +
+                        "/scratch/xxxx/yyyy/ZZZZZZ/aaaaaaaaaa/xx/aaserver/server/lib/someapps.jar" + ps +
+                        "/scratch/xxxx/yyyy/ZZZZZZ/aaaaaaaaaa/xx/aaserver/../foobar_common/modules/net.xy.batcontrib_1.1.0.0_1-0b3/lib/bat-contrib.jar" + ps +
+                        "/scratch/xxxx/yyyy/ZZZZZZ/aaaaaaaaaa/xx/aaserver/modules/features/foobar.aas.common.kkkkkkkkkkk.jar" + ps +
+                        "/scratch/xxxx/yyyy/ZZZZZZ/aaaaaaaaaa/xx/abc/abc/modules/foobar.abc.common.adapters_11.1.1/foobar.abc.common.adapters.jar" + ps +
+                        "/scratch/xxxx/yyyy/ZZZZZZ/aaaaaaaaaa/xx/abc/abc/modules/foobar.plane.adapter_12.1.3/foobar.plane.adapter.jar" + ps +
+                        "/scratch/xxxx/yyyy/ZZZZZZ/aaaaaaaaaa/xx/abc/lib/ccccccccar-common.jar" + ps +
+                        "/scratch/xxxx/yyyy/ZZZZZZ/aaaaaaaaaa/xx/foobar_common/communications/modules/config.jar" + ps +
+                        "/scratch/xxxx/yyyy/ZZZZZZ/aaaaaaaaaa/xx/foobar_common/communications/modules/userprefs-config.jar" + ps +
+                        "/scratch/xxxx/yyyy/XXXXXX/aaaaaaaa/xxxxxxx/xxxxxxxx.us.foobar.com/CommonDomain/config/abc-infra" + ps +
+                        "/scratch/xxxx/yyyy/ZZZZZZ/aaaaaaaaaa/xx/abc/abc/modules/qqqqqq-all-1.6.5.jar" + ps +
+                        "/scratch/xxxx/yyyy/ZZZZZZ/aaaaaaaaaa/xx/abc/abc/modules/foobar.abc.thread_11.1.1/foobar.abc.thread.jar" + ps +
+                        "/scratch/xxxx/yyyy/ZZZZZZ/aaaaaaaaaa/xx/abc/abc/modules/foobar.abc.thread_11.1.1/thread-rrrrrrr-ext-aas.jar" + ps +
+                        "/scratch/xxxx/yyyy/ZZZZZZ/aaaaaaaaaa/xx/abc/abc/modules/foobar.abc.adapter_11.1.1/foobar.abc.adapter.jar" + ps +
+                        "/scratch/xxxx/yyyy/ZZZZZZ/aaaaaaaaaa/xx/abc/abc/modules/foobar.abc.ccc_11.1.1/foobar.abc.ccc.jar" + ps +
+                        "/scratch/xxxx/yyyy/ZZZZZZ/aaaaaaaaaa/xx/bbb/lib/commons-configuration.jar" + ps +
+                        "/scratch/xxxx/yyyy/ZZZZZZ/aaaaaaaaaa/xx/bbb/lib/commons-lang.jar" + ps +
+                        "/scratch/xxxx/yyyy/ZZZZZZ/aaaaaaaaaa/xx/bbb/lib/commons-logging.jar" + ps +
+                        "/scratch/xxxx/yyyy/ZZZZZZ/aaaaaaaaaa/xx/foobar_common/modules/foobar.wccore/foobar-ppppppp-api.jar" + ps +
+                        "/scratch/xxxx/yyyy/ZZZZZZ/aaaaaaaaaa/xx/foobar_common/modules/foobar.ooo_12.1.3/ooo-manifest.jar" + ps +
+                        "/scratch/xxxx/yyyy/ZZZZZZ/aaaaaaaaaa/xx/foobar_common/modules/internal/features/rrr_aaxyxx_foobar.rrr.aas.classpath.jar" + ps +
+                        "/scratch/xxxx/yyyy/ZZZZZZ/aaaaaaaaaa/xx/abc/abc/modules/foobar.abc.thread_11.1.1/rrrrrrrr-api.jar" + ps +
+                        "/scratch/xxxx/yyyy/ZZZZZZ/aaaaaaaaaa/xx/abc/abc/modules/commons-xxx-1.1.jar" + ps +
+                        "/scratch/xxxx/yyyy/ZZZZZZ/aaaaaaaaaa/xx/abc/abc/modules/foobar.abc.mgmt_11.1.1/abc-infra-mgmt.jar" + ps +
+                        "/scratch/xxxx/yyyy/ZZZZZZ/aaaaaaaaaa/xx/foobar_common/eee/archives/eee-eee.jar" + ps +
+                        "/scratch/xxxx/yyyy/ZZZZZZ/aaaaaaaaaa/xx/aaserver/common/march/lib/marchnet.jar" + ps +
+                        "/scratch/xxxx/yyyy/ZZZZZZ/aaaaaaaaaa/xx/aaserver/common/march/lib/marchclient.jar" + ps +
+                        "/scratch/xxxx/yyyy/ZZZZZZ/aaaaaaaaaa/xx/aaserver/common/march/lib/march.jar" + ps +
+                        "/scratch/xxxx/yyyy/ZZZZZZ/aaaaaaaaaa/xx/wwcontent/cde/iii/jlib/iiiloader.jar" + ps +
+                        "/scratch/xxxx/yyyy/ZZZZZZ/aaaaaaaaaa/xx/wwcontent/cde/iii/components/xxxxxxyyzzzzz/classes-xxxxxxyyzzzzz.jar" + ps +
+                        "/scratch/xxxx/yyyy/ZZZZZZ/aaaaaaaaaa/xx/wwcontent/cde/iii/components/mmmmmmm/lib/abc_core.jar" + ps +
+                        "/scratch/xxxx/yyyy/ZZZZZZ/aaaaaaaaaa/xx/wwcontent/cde/iii/components/mmmmmmm/lib/abc_codec.jar" + ps +
+                        "/scratch/xxxx/yyyy/ZZZZZZ/aaaaaaaaaa/xx/wwcontent/cde/iii/components/mmmmmmm/lib/abc_imageio.jar" + ps +
+                        "/scratch/xxxx/yyyy/ZZZZZZ/aaaaaaaaaa/jdk/lib/tools.jar" + ps +
+                        "/scratch/xxxx/yyyy/ZZZZZZ/aaaaaaaaaa/xx/foobar_common/modules/foobar.ooo_12.1.3/ooo-manifest.jar";
+
+        String myCP = longClassPath + ps + appJar;
+        // Dump an archive with a specified JAR file in -classpath
+        TestCommon.testDump(myCP, TestCommon.list("Hello"));
+
+        TestCommon.run(
+                "-XX:+TraceClassPaths",
+                "-cp", appJar,
+                "Hello");
+    }
+}
+
diff --git a/hotspot/test/runtime/appcds/WideIloadTest.java b/hotspot/test/runtime/appcds/WideIloadTest.java
new file mode 100644
index 00000000..9c045882
--- /dev/null
+++ b/hotspot/test/runtime/appcds/WideIloadTest.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2016, 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.
+ *
+ */
+
+/**
+ * @test
+ * @summary Test 'iload_w' bytecode in shared class
+ * @library /testlibrary
+ * @compile test-classes/Iloadw.jasm
+ * @compile test-classes/IloadwMain.java
+ * @run main WideIloadTest
+ */
+
+import com.oracle.java.testlibrary.OutputAnalyzer;
+
+public class WideIloadTest {
+    public static void main(String args[]) throws Exception {
+        JarBuilder.build("iload_w", "Iloadw", "IloadwMain");
+        String appJar = TestCommon.getTestJar("iload_w.jar");
+        OutputAnalyzer dumpOutput = TestCommon.dump(appJar, TestCommon.list(
+                "Iloadw", "IloadwMain"));
+        TestCommon.checkDump(dumpOutput);
+        OutputAnalyzer execOutput = TestCommon.exec(appJar, "IloadwMain");
+        TestCommon.checkExec(execOutput, "Passed");
+    }
+}
diff --git a/hotspot/test/runtime/appcds/XShareAutoWithChangedJar.java b/hotspot/test/runtime/appcds/XShareAutoWithChangedJar.java
new file mode 100644
index 00000000..f59f2f89
--- /dev/null
+++ b/hotspot/test/runtime/appcds/XShareAutoWithChangedJar.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2015, 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.
+ *
+ */
+
+/*
+ * @test
+ * @summary Test -Xshare:auto for AppCDS
+ * @library /testlibrary
+ * @compile test-classes/Hello.java
+ * @run main XShareAutoWithChangedJar
+ */
+
+import com.oracle.java.testlibrary.OutputAnalyzer;
+
+public class XShareAutoWithChangedJar {
+    public static void main(String[] args) throws Exception {
+        String appJar = JarBuilder.build("XShareAutoWithChangedJar", "Hello");
+
+        // 1. dump
+        OutputAnalyzer output = TestCommon.dump(appJar, TestCommon.list("Hello"));
+        TestCommon.checkDump(output);
+
+        // 2. change the jar
+        JarBuilder.build("XShareAutoWithChangedJar", "Hello");
+
+        // 3. exec
+        output = TestCommon.execAuto("-cp", appJar, "Hello");
+        output.shouldContain("Hello World");
+    }
+}
+
diff --git a/hotspot/test/runtime/appcds/test-classes/C1.java b/hotspot/test/runtime/appcds/test-classes/C1.java
new file mode 100644
index 00000000..86201cd4
--- /dev/null
+++ b/hotspot/test/runtime/appcds/test-classes/C1.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2014, 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 sealed.pkg;
+
+public class C1 {
+}
diff --git a/hotspot/test/runtime/appcds/test-classes/C2.java b/hotspot/test/runtime/appcds/test-classes/C2.java
new file mode 100644
index 00000000..ad0026fb
--- /dev/null
+++ b/hotspot/test/runtime/appcds/test-classes/C2.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2014, 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 pkg;
+
+public class C2 {
+}
diff --git a/hotspot/test/runtime/appcds/test-classes/CheckIfShared.java b/hotspot/test/runtime/appcds/test-classes/CheckIfShared.java
new file mode 100644
index 00000000..59b91f48
--- /dev/null
+++ b/hotspot/test/runtime/appcds/test-classes/CheckIfShared.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2015, 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.
+ *
+ */
+
+import sun.hotspot.WhiteBox;
+
+public class CheckIfShared {
+    public static void main(String args[]) throws Exception {
+        WhiteBox wb = WhiteBox.getWhiteBox();
+        if ("true".equals(args[0])) {
+            if (!wb.isSharedClass(CheckIfShared.class)) {
+                throw new RuntimeException("wb.isSharedClass(CheckIfShared.class) should be true");
+            }
+        } else {
+            if (wb.isSharedClass(CheckIfShared.class)) {
+                throw new RuntimeException("wb.isSharedClass(CheckIfShared.class) should be false");
+            }
+        }
+    }
+}
+
diff --git a/hotspot/test/runtime/appcds/test-classes/Hello.java b/hotspot/test/runtime/appcds/test-classes/Hello.java
new file mode 100644
index 00000000..dc134771
--- /dev/null
+++ b/hotspot/test/runtime/appcds/test-classes/Hello.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2014, 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.
+ *
+ */
+
+public class Hello {
+  public static void main(String args[]) {
+    System.out.println("Hello World");
+  }
+}
diff --git a/hotspot/test/runtime/appcds/test-classes/HelloMore.java b/hotspot/test/runtime/appcds/test-classes/HelloMore.java
new file mode 100644
index 00000000..0d8f335e
--- /dev/null
+++ b/hotspot/test/runtime/appcds/test-classes/HelloMore.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2014, 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.
+ *
+ */
+
+public class HelloMore {
+    public static void main(String args[]) {
+        Hello.main(args);
+        System.out.println("Hello World ... More");
+    }
+}
diff --git a/hotspot/test/runtime/appcds/test-classes/Iloadw.jasm b/hotspot/test/runtime/appcds/test-classes/Iloadw.jasm
new file mode 100644
index 00000000..5c1fffbf
--- /dev/null
+++ b/hotspot/test/runtime/appcds/test-classes/Iloadw.jasm
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2014, 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.
+ *
+ */
+
+public class Iloadw
+    version 51: 0
+{
+    public static Method run:"()I"
+        stack 1 locals 400
+    {
+        iconst_0;
+        istore_w 300;
+        iinc_w 300,1;
+        iload_w 300;
+        ireturn;
+    }
+}
diff --git a/hotspot/test/runtime/appcds/test-classes/IloadwMain.java b/hotspot/test/runtime/appcds/test-classes/IloadwMain.java
new file mode 100644
index 00000000..7257cce6
--- /dev/null
+++ b/hotspot/test/runtime/appcds/test-classes/IloadwMain.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2016, 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.
+ *
+ */
+
+public class IloadwMain {
+    public static void main(String args[]) {
+        int result = Iloadw.run();
+        if (result != 1) {
+            throw new RuntimeException(
+                    "Failed. Result is " + result + ", expect 1.");
+        } else {
+            System.out.println("Passed.");
+        }
+    }
+}
diff --git a/hotspot/test/runtime/appcds/test-classes/MissingSuper.java b/hotspot/test/runtime/appcds/test-classes/MissingSuper.java
new file mode 100644
index 00000000..ef47a7cb
--- /dev/null
+++ b/hotspot/test/runtime/appcds/test-classes/MissingSuper.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2014, 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.
+ *
+ */
+
+public class MissingSuper {
+    public static void main(String args[]) {
+        try {
+            new MissingSuperSub();
+        } catch (NoClassDefFoundError e) {
+            System.out.println("Expected NoClassDefFoundError:");
+            e.printStackTrace(System.out);
+        }
+
+        try {
+            new MissingSuperImpl();
+        } catch (NoClassDefFoundError e) {
+            System.out.println("Expected NoClassDefFoundError:");
+            e.printStackTrace(System.out);
+        }
+    }
+}
+
+class MissingSuperSup {} // This class will be deleted from missing_super.jar before dumping
+
+class MissingSuperSub extends MissingSuperSup {}
+
+interface MissingSuperIntf {} // This interface will be deleted from missing_super.jar before dumping
+
+class MissingSuperImpl implements MissingSuperIntf {}
diff --git a/hotspot/test/runtime/appcds/test-classes/PackageSealingTest.java b/hotspot/test/runtime/appcds/test-classes/PackageSealingTest.java
new file mode 100644
index 00000000..a1e8ea0a
--- /dev/null
+++ b/hotspot/test/runtime/appcds/test-classes/PackageSealingTest.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2014, 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.
+ *
+ */
+
+import java.lang.Package;
+
+public class PackageSealingTest {
+    public static void main(String args[]) {
+        try {
+            Class c1 = PackageSealingTest.class.forName("sealed.pkg.C1");
+            Class c2 = PackageSealingTest.class.forName("pkg.C2");
+            Package p1 = c1.getPackage();
+            System.out.println("Package 1: " + p1.toString());
+            Package p2 = c2.getPackage();
+            System.out.println("Package 2: " + p2.toString());
+
+            if (!p1.isSealed()) {
+                System.out.println("Failed: sealed.pkg is not sealed.");
+                System.exit(0);
+            }
+
+            if (p2.isSealed()) {
+                System.out.println("Failed: pkg is sealed.");
+                System.exit(0);
+            }
+
+            System.out.println("OK");
+        } catch (Exception e) {
+            System.out.println(e.getMessage());
+        }
+    }
+}
diff --git a/hotspot/test/runtime/appcds/test-classes/ParallelClasses.java b/hotspot/test/runtime/appcds/test-classes/ParallelClasses.java
new file mode 100644
index 00000000..a4d0520f
--- /dev/null
+++ b/hotspot/test/runtime/appcds/test-classes/ParallelClasses.java
@@ -0,0 +1,64 @@
+/*
+ * 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.
+ *
+ */
+
+class ParallelClass0 {}
+class ParallelClass1 {}
+class ParallelClass2 {}
+class ParallelClass3 {}
+class ParallelClass4 {}
+class ParallelClass5 {}
+class ParallelClass6 {}
+class ParallelClass7 {}
+class ParallelClass8 {}
+class ParallelClass9 {}
+class ParallelClass10 {}
+class ParallelClass11 {}
+class ParallelClass12 {}
+class ParallelClass13 {}
+class ParallelClass14 {}
+class ParallelClass15 {}
+class ParallelClass16 {}
+class ParallelClass17 {}
+class ParallelClass18 {}
+class ParallelClass19 {}
+class ParallelClass20 {}
+class ParallelClass21 {}
+class ParallelClass22 {}
+class ParallelClass23 {}
+class ParallelClass24 {}
+class ParallelClass25 {}
+class ParallelClass26 {}
+class ParallelClass27 {}
+class ParallelClass28 {}
+class ParallelClass29 {}
+class ParallelClass30 {}
+class ParallelClass31 {}
+class ParallelClass32 {}
+class ParallelClass33 {}
+class ParallelClass34 {}
+class ParallelClass35 {}
+class ParallelClass36 {}
+class ParallelClass37 {}
+class ParallelClass38 {}
+class ParallelClass39 {}
diff --git a/hotspot/test/runtime/appcds/test-classes/ParallelLoad.java b/hotspot/test/runtime/appcds/test-classes/ParallelLoad.java
new file mode 100644
index 00000000..9a6fe550
--- /dev/null
+++ b/hotspot/test/runtime/appcds/test-classes/ParallelLoad.java
@@ -0,0 +1,220 @@
+/*
+ * Copyright (c) 2016, 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.
+ *
+ */
+
+import java.io.*;
+import java.net.*;
+import java.lang.reflect.Field;
+
+
+// This test helper is parameterized by:
+// - class transformation mode: property "appcds.parallel.transform.mode"
+// - class loader test types
+//
+// In the case of transformMode == "cflh", the transformation is performed
+// by AppCDS/jvmti/TransformerAgent.java. The classes to be transformed, such as
+// ParallelClassTr0, are defined in ./jvmti/parallelLoad/ParallelClasses.java
+
+public class ParallelLoad {
+    public static int MAX_CLASSES = 40;
+    public static int NUM_THREADS = 4;
+
+    public final static int SYSTEM_LOADER = 0;
+    public final static int SINGLE_CUSTOM_LOADER = 1;
+    public final static int MULTI_CUSTOM_LOADER = 2;
+
+    public static final int FINGERPRINT_MODE = 1;
+    public static final int API_MODE         = 2;
+
+    public static int loaderType = SYSTEM_LOADER;
+    public static ClassLoader classLoaders[];
+    public static int mode = FINGERPRINT_MODE;
+
+    public static float timeoutFactor =
+            Float.parseFloat(System.getProperty("test.timeout.factor", "1.0"));
+
+    public static void main(String args[]) throws Throwable {
+        run(args, null);
+    }
+    public static void run(String args[], ClassLoader loaders[]) throws Throwable {
+        String customJar = null;
+        System.out.println("ParallelLoad: timeoutFactor = " + timeoutFactor);
+
+        if (args.length >= 1) {
+            if ("SINGLE_CUSTOM_LOADER".equals(args[0])) {
+                loaderType = SINGLE_CUSTOM_LOADER;
+                customJar = args[2];
+            } else if ("MULTI_CUSTOM_LOADER".equals(args[0])) {
+                loaderType = MULTI_CUSTOM_LOADER;
+                customJar = args[2];
+            } else if ("SYSTEM_LOADER".equals(args[0])) {
+                loaderType = SYSTEM_LOADER;
+            } else {
+                throw new RuntimeException("Unexpected loaderType" + args[0]);
+            }
+        }
+
+        if (customJar != null) {
+            if ("FINGERPRINT_MODE".equals(args[1])) {
+                mode = FINGERPRINT_MODE;
+                classLoaders = new ClassLoader[NUM_THREADS];
+                for (int i=0; i<NUM_THREADS; i++) {
+                    URL url = new File(customJar).toURI().toURL();
+                    URL[] urls = new URL[] {url};
+                    classLoaders[i] = new URLClassLoader(urls);
+                }
+            } else {
+                // Loaders must be supplied by caller of the run() method
+                mode = API_MODE;
+                classLoaders = loaders;
+            }
+        }
+
+        System.out.println("Start Parallel Load ...");
+
+        Thread thread[] = new Thread[NUM_THREADS];
+        for (int i=0; i<NUM_THREADS; i++) {
+            Thread t = new ParallelLoadThread(i);
+            t.start();
+            thread[i] = t;
+        }
+
+        Thread watchdog = new ParallelLoadWatchdog();
+        watchdog.setDaemon(true);
+        watchdog.start();
+
+        for (int i=0; i<NUM_THREADS; i++) {
+            thread[i].join();
+        }
+        System.out.println("Parallel Load ... done");
+        System.exit(0);
+    }
+}
+
+
+class ParallelLoadWatchdog extends Thread {
+    public void run() {
+        try {
+            long timeout = (long) (20 * 1000 * ParallelLoad.timeoutFactor);
+            Thread.sleep(timeout);
+            System.out.println("ParallelLoadWatchdog: Timeout reached: timeout(ms) = " + timeout);
+            System.exit(1);
+        } catch (Throwable t) {
+            t.printStackTrace();
+            System.exit(1);
+        }
+    }
+};
+
+
+class ParallelLoadThread extends Thread {
+    static int num_ready[] = new int[ParallelLoad.MAX_CLASSES];
+    static Object lock = new Object();
+    static String transformMode =
+            System.getProperty("appcds.parallel.transform.mode", "none");
+
+    int thread_id;
+    ParallelLoadThread(int thread_id) {
+        this.thread_id = thread_id;
+    }
+
+    public void run() {
+        try {
+            run0();
+        } catch (Throwable t) {
+            t.printStackTrace();
+            System.exit(1);
+        }
+    }
+
+    private static void log(String msg, Object... args) {
+        String msg0 = "ParallelLoadThread: " + String.format(msg, args);
+        System.out.println(msg0);
+    }
+
+    private void run0() throws Throwable {
+        for (int i=0; i<ParallelLoad.MAX_CLASSES; i++) {
+            synchronized(lock) {
+                num_ready[i] ++;
+                while (num_ready[i] < ParallelLoad.NUM_THREADS) {
+                    lock.wait();
+                }
+                lock.notifyAll();
+            }
+            log("this = %s %d", this, i);
+            String className = "ParallelClass" + i;
+            if (transformMode.equals("cflh"))
+                className = "ParallelClassTr" + i;
+
+            Class clazz = null;
+
+            switch (ParallelLoad.loaderType) {
+                case ParallelLoad.SYSTEM_LOADER:
+                    clazz = Class.forName(className);
+                    break;
+                case ParallelLoad.SINGLE_CUSTOM_LOADER:
+                    clazz = ParallelLoad.classLoaders[0].loadClass(className);
+                    break;
+                case ParallelLoad.MULTI_CUSTOM_LOADER:
+                    clazz = ParallelLoad.classLoaders[thread_id].loadClass(className);
+                    break;
+            }
+
+            log("clazz = %s", clazz);
+            testTransformation(clazz);
+        }
+    }
+
+    private void testTransformation(Class c) throws Exception {
+        if (transformMode.equals("none"))
+            return;
+
+        // currently only cflh transform mode is supported
+        if (!transformMode.equals("cflh")) {
+            String msg = "wrong transform mode: " + transformMode;
+            throw new IllegalArgumentException(msg);
+        }
+
+        Field[] fields = c.getFields();
+        boolean fieldFound = false;
+        for (Field f : fields) {
+            if (f.getName().equals("testString")) {
+                checkTransformationString(c, (String) f.get(null));
+                fieldFound = true;
+            }
+        }
+
+        if (!fieldFound)
+            throw new RuntimeException ("Expected field 'testString' not found");
+    }
+
+    private void checkTransformationString(Class c, String actual) throws Exception {
+        String expected = "class-transform-check: this-has-been--transformed";
+        if (!actual.equals(expected)) {
+            String msg1 = "Transformation failed for class" + c.getName();
+            String msg2 = String.format("Expected: %s, actual: %s", expected, actual);
+            throw new RuntimeException(msg1 + "\n" + msg2);
+        }
+    }
+}
+
diff --git a/hotspot/test/runtime/appcds/test-classes/package_seal.mf b/hotspot/test/runtime/appcds/test-classes/package_seal.mf
new file mode 100644
index 00000000..e34c7ab5
--- /dev/null
+++ b/hotspot/test/runtime/appcds/test-classes/package_seal.mf
@@ -0,0 +1,5 @@
+Manifest-Version: 1.0
+Created-By: 1.9.0-internal (Oracle Corporation)
+
+Name: sealed/pkg/
+Sealed: true
diff --git a/hotspot/test/testlibrary/com/oracle/java/testlibrary/OutputAnalyzer.java b/hotspot/test/testlibrary/com/oracle/java/testlibrary/OutputAnalyzer.java
index 67806cab..2132325f 100644
--- a/hotspot/test/testlibrary/com/oracle/java/testlibrary/OutputAnalyzer.java
+++ b/hotspot/test/testlibrary/com/oracle/java/testlibrary/OutputAnalyzer.java
@@ -164,6 +164,21 @@ public final class OutputAnalyzer {
     return this;
   }
 
+  /**
+   * Verify the exit value of the process
+   * backport from jdk11u
+   * @param notExpectedExitValue Unexpected exit value from process
+   * @throws RuntimeException If the exit value from the process did match the expected value
+   */
+  public OutputAnalyzer shouldNotHaveExitValue(int notExpectedExitValue) {
+    if (getExitValue() == notExpectedExitValue) {
+        reportDiagnosticSummary();
+        throw new RuntimeException("Unexpected to get exit value of ["
+                + notExpectedExitValue + "]\n");
+    }
+    return this;
+  }
+
   /**
    * Verify that the stdout and stderr contents of output buffer does not contain the string
    *
diff --git a/hotspot/test/testlibrary/com/oracle/java/testlibrary/Utils.java b/hotspot/test/testlibrary/com/oracle/java/testlibrary/Utils.java
index 902e3b13..be48a7e6 100644
--- a/hotspot/test/testlibrary/com/oracle/java/testlibrary/Utils.java
+++ b/hotspot/test/testlibrary/com/oracle/java/testlibrary/Utils.java
@@ -370,4 +370,57 @@ public final class Utils {
         }
         return new String(hexView);
     }
+
+    // This method is intended to be called from a jtreg test.
+    // It will identify the name of the test by means of stack walking.
+    // It can handle both jtreg tests and a testng tests wrapped inside jtreg tests.
+    // For jtreg tests the name of the test will be searched by stack-walking
+    // until the method main() is found; the class containing that method is the
+    // main test class and will be returned as the name of the test.
+    // Special handling is used for testng tests.
+    // backport from jdk11u
+    public static String getTestName() {
+        String result = null;
+        // If we are using testng, then we should be able to load the "Test" annotation.
+        Class testClassAnnotation;
+
+        try {
+            testClassAnnotation = Class.forName("org.testng.annotations.Test");
+        } catch (ClassNotFoundException e) {
+            testClassAnnotation = null;
+        }
+
+        StackTraceElement[] elms = (new Throwable()).getStackTrace();
+        for (StackTraceElement n: elms) {
+            String className = n.getClassName();
+
+            // If this is a "main" method, then use its class name, but only
+            // if we are not using testng.
+            if (testClassAnnotation == null && "main".equals(n.getMethodName())) {
+                result = className;
+                break;
+            }
+
+            // If this is a testng test, the test will have no "main" method. We can
+            // detect a testng test class by looking for the org.testng.annotations.Test
+            // annotation. If present, then use the name of this class.
+            if (testClassAnnotation != null) {
+                try {
+                    Class c = Class.forName(className);
+                    if (c.isAnnotationPresent(testClassAnnotation)) {
+                        result = className;
+                        break;
+                    }
+                } catch (ClassNotFoundException e) {
+                    throw new RuntimeException("Unexpected exception: " + e, e);
+                }
+            }
+        }
+
+        if (result == null) {
+            throw new RuntimeException("Couldn't find main test class in stack trace");
+        }
+
+        return result;
+    }
 }
diff --git a/hotspot/test/testlibrary/com/oracle/java/testlibrary/cds/CDSOptions.java b/hotspot/test/testlibrary/com/oracle/java/testlibrary/cds/CDSOptions.java
new file mode 100644
index 00000000..09050d6c
--- /dev/null
+++ b/hotspot/test/testlibrary/com/oracle/java/testlibrary/cds/CDSOptions.java
@@ -0,0 +1,71 @@
+/*
+ * 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 com.oracle.java.testlibrary.cds;
+
+import java.util.ArrayList;
+
+// This class represents options used
+// during creation of CDS archive and/or running JVM with a CDS archive
+public class CDSOptions {
+    public String xShareMode = "on";
+    public String archiveName;
+    public ArrayList<String> prefix = new ArrayList<String>();
+    public ArrayList<String> suffix = new ArrayList<String>();
+
+    // Indicate whether to append "-version" when using CDS Archive.
+    // Most of tests will use '-version'
+    public boolean useVersion = true;
+
+
+    public CDSOptions() {
+    }
+
+
+    public CDSOptions addPrefix(String... prefix) {
+        for (String s : prefix) this.prefix.add(s);
+        return this;
+    }
+
+
+    public CDSOptions addSuffix(String... suffix) {
+        for (String s : suffix) this.suffix.add(s);
+        return this;
+    }
+
+    public CDSOptions setXShareMode(String mode) {
+        this.xShareMode = mode;
+        return this;
+    }
+
+
+    public CDSOptions setArchiveName(String name) {
+        this.archiveName = name;
+        return this;
+    }
+
+
+    public CDSOptions setUseVersion(boolean use) {
+        this.useVersion = use;
+        return this;
+    }
+}
diff --git a/hotspot/test/testlibrary/com/oracle/java/testlibrary/cds/CDSTestUtils.java b/hotspot/test/testlibrary/com/oracle/java/testlibrary/cds/CDSTestUtils.java
new file mode 100644
index 00000000..f1ff7e48
--- /dev/null
+++ b/hotspot/test/testlibrary/com/oracle/java/testlibrary/cds/CDSTestUtils.java
@@ -0,0 +1,590 @@
+/*
+ * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.java.testlibrary.cds;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.PrintStream;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Date;
+
+import com.oracle.java.testlibrary.OutputAnalyzer;
+import com.oracle.java.testlibrary.ProcessTools;
+import com.oracle.java.testlibrary.Utils;
+
+
+// This class contains common test utilities for testing CDS
+public class CDSTestUtils {
+    public static final String MSG_RANGE_NOT_WITHIN_HEAP =
+        "UseSharedSpaces: Unable to allocate region, range is not within java heap.";
+    public static final String MSG_RANGE_ALREADT_IN_USE =
+        "Unable to allocate region, java heap range is already in use.";
+    public static final String MSG_COMPRESSION_MUST_BE_USED =
+        "Unable to use shared archive: UseCompressedOops and UseCompressedClassPointers must be on for UseSharedSpaces.";
+
+    public interface Checker {
+        public void check(OutputAnalyzer output) throws Exception;
+    }
+
+    /*
+     * INTRODUCTION
+     *
+     * When testing various CDS functionalities, we need to launch JVM processes
+     * using a "launch method" (such as TestCommon.run), and analyze the results of these
+     * processes.
+     *
+     * While typical jtreg tests would use OutputAnalyzer in such cases, due to the
+     * complexity of CDS failure modes, we have added the CDSTestUtils.Result class
+     * to make the analysis more convenient and less error prone.
+     *
+     * A Java process can end in one of the following 4 states:
+     *
+     *    1: Unexpected error - such as JVM crashing. In this case, the "launch method"
+     *                          will throw a RuntimeException.
+     *    2: Mapping Failure  - this happens when the OS (intermittently) fails to map the
+     *                          CDS archive, normally caused by Address Space Layout Randomization.
+     *                          We usually treat this as "pass".
+     *    3: Normal Exit      - the JVM process has finished without crashing, and the exit code is 0.
+     *    4: Abnormal Exit    - the JVM process has finished without crashing, and the exit code is not 0.
+     *
+     * In most test cases, we need to check the JVM process's output in cases 3 and 4. However, we need
+     * to make sure that our test code is not confused by case 2.
+     *
+     * For example, a JVM process is expected to print the string "Hi" and exit with 0. With the old
+     * CDSTestUtils.runWithArchive API, the test may be written as this:
+     *
+     *     OutputAnalyzer out = CDSTestUtils.runWithArchive(args);
+     *     out.shouldContain("Hi");
+     *
+     * However, if the JVM process fails with mapping failure, the string "Hi" will not be in the output,
+     * and your test case will fail intermittently.
+     *
+     * Instead, the test case should be written as
+     *
+     *      CCDSTestUtils.run(args).assertNormalExit("Hi");
+     *
+     * EXAMPLES/HOWTO
+     *
+     * 1. For simple substring matching:
+     *
+     *      CCDSTestUtils.run(args).assertNormalExit("Hi");
+     *      CCDSTestUtils.run(args).assertNormalExit("a", "b", "x");
+     *      CCDSTestUtils.run(args).assertAbnormalExit("failure 1", "failure2");
+     *
+     * 2. For more complex output matching: using Lambda expressions
+     *
+     *      CCDSTestUtils.run(args)
+     *         .assertNormalExit(output -> output.shouldNotContain("this should not be printed");
+     *      CCDSTestUtils.run(args)
+     *         .assertAbnormalExit(output -> {
+     *             output.shouldNotContain("this should not be printed");
+     *             output.shouldHaveExitValue(123);
+     *           });
+     *
+     * 3. Chaining several checks:
+     *
+     *      CCDSTestUtils.run(args)
+     *         .assertNormalExit(output -> output.shouldNotContain("this should not be printed")
+     *         .assertNormalExit("should have this", "should have that");
+     *
+     * 4. [Rare use case] if a test sometimes exit normally, and sometimes abnormally:
+     *
+     *      CCDSTestUtils.run(args)
+     *         .ifNormalExit("ths string is printed when exiting with 0")
+     *         .ifAbNormalExit("ths string is printed when exiting with 1");
+     *
+     *    NOTE: you usually don't want to write your test case like this -- it should always
+     *    exit with the same exit code. (But I kept this API because some existing test cases
+     *    behave this way -- need to revisit).
+     */
+    public static class Result {
+        private final OutputAnalyzer output;
+        private final CDSOptions options;
+        private final boolean hasMappingFailure;
+        private final boolean hasAbnormalExit;
+        private final boolean hasNormalExit;
+        private final String CDS_DISABLED = "warning: CDS is disabled when the";
+
+        public Result(CDSOptions opts, OutputAnalyzer out) throws Exception {
+            options = opts;
+            output = out;
+            hasMappingFailure = CDSTestUtils.checkCommonExecExceptions(output);
+            hasAbnormalExit   = (!hasMappingFailure) && (output.getExitValue() != 0);
+            hasNormalExit     = (!hasMappingFailure) && (output.getExitValue() == 0);
+
+            if (hasNormalExit) {
+                if ("on".equals(options.xShareMode) &&
+                    output.getStderr().contains("java version") &&
+                    !output.getStderr().contains(CDS_DISABLED)) {
+                    // "-showversion" is always passed in the command-line by the execXXX methods.
+                    // During normal exit, we require that the VM to show that sharing was enabled.
+                    output.shouldContain("sharing");
+                }
+            }
+        }
+
+        public Result assertNormalExit(Checker checker) throws Exception {
+            if (!hasMappingFailure) {
+                checker.check(output);
+                output.shouldHaveExitValue(0);
+            }
+            return this;
+        }
+
+        public Result assertAbnormalExit(Checker checker) throws Exception {
+            if (!hasMappingFailure) {
+                checker.check(output);
+                output.shouldNotHaveExitValue(0);
+            }
+            return this;
+        }
+
+        // When {--limit-modules, --patch-module, and/or --upgrade-module-path}
+        // are specified, CDS is silently disabled for both -Xshare:auto and -Xshare:on.
+        public Result assertSilentlyDisabledCDS(Checker checker) throws Exception {
+            if (hasMappingFailure) {
+                throw new RuntimeException("Unexpected mapping failure");
+            }
+            // this comes from a JVM warning message.
+            output.shouldContain(CDS_DISABLED);
+
+            checker.check(output);
+            return this;
+        }
+
+        public Result assertSilentlyDisabledCDS(int exitCode, String... matches) throws Exception {
+            return assertSilentlyDisabledCDS((out) -> {
+                out.shouldHaveExitValue(exitCode);
+                checkMatches(out, matches);
+                   });
+        }
+
+        public Result ifNormalExit(Checker checker) throws Exception {
+            if (hasNormalExit) {
+                checker.check(output);
+            }
+            return this;
+        }
+
+        public Result ifAbnormalExit(Checker checker) throws Exception {
+            if (hasAbnormalExit) {
+                checker.check(output);
+            }
+            return this;
+        }
+
+        public Result ifNoMappingFailure(Checker checker) throws Exception {
+            if (!hasMappingFailure) {
+                checker.check(output);
+            }
+            return this;
+        }
+
+
+        public Result assertNormalExit(String... matches) throws Exception {
+            if (!hasMappingFailure) {
+                checkMatches(output, matches);
+                output.shouldHaveExitValue(0);
+            }
+            return this;
+        }
+
+        public Result assertAbnormalExit(String... matches) throws Exception {
+            if (!hasMappingFailure) {
+                checkMatches(output, matches);
+                output.shouldNotHaveExitValue(0);
+            }
+
+            return this;
+        }
+    }
+
+    // Specify this property to copy sdandard output of the child test process to
+    // the parent/main stdout of the test.
+    // By default such output is logged into a file, and is copied into the main stdout.
+    public static final boolean CopyChildStdoutToMainStdout =
+        Boolean.valueOf(System.getProperty("test.cds.copy.child.stdout", "true"));
+
+    // This property is passed to child test processes
+    public static final String TestTimeoutFactor = System.getProperty("test.timeout.factor", "1.0");
+
+    public static final String UnableToMapMsg =
+        "Unable to map shared archive: test did not complete; assumed PASS";
+
+    // Create bootstrap CDS archive,
+    // use extra JVM command line args as a prefix.
+    // For CDS tests specifying prefix makes more sense than specifying suffix, since
+    // normally there are no classes or arguments to classes, just "-version"
+    // To specify suffix explicitly use CDSOptions.addSuffix()
+    public static OutputAnalyzer createArchive(String... cliPrefix)
+        throws Exception {
+        return createArchive((new CDSOptions()).addPrefix(cliPrefix));
+    }
+
+    // Create bootstrap CDS archive
+    public static OutputAnalyzer createArchive(CDSOptions opts)
+        throws Exception {
+
+        startNewArchiveName();
+
+        ArrayList<String> cmd = new ArrayList<String>();
+
+        for (String p : opts.prefix) cmd.add(p);
+
+        cmd.add("-Xshare:dump");
+        cmd.add("-Xlog:cds,cds+hashtables");
+        if (opts.archiveName == null)
+            opts.archiveName = getDefaultArchiveName();
+        cmd.add("-XX:SharedArchiveFile=./" + opts.archiveName);
+
+        for (String s : opts.suffix) cmd.add(s);
+
+        String[] cmdLine = cmd.toArray(new String[cmd.size()]);
+        ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(true, cmdLine);
+        return executeAndLog(pb, "dump");
+    }
+
+
+    // check result of 'dump-the-archive' operation, that is "-Xshare:dump"
+    public static OutputAnalyzer checkDump(OutputAnalyzer output, String... extraMatches)
+        throws Exception {
+
+        output.shouldContain("Loading classes to share");
+        output.shouldHaveExitValue(0);
+
+        for (String match : extraMatches) {
+            output.shouldContain(match);
+        }
+
+        return output;
+    }
+
+
+    // A commonly used convenience methods to create an archive and check the results
+    // Creates an archive and checks for errors
+    public static OutputAnalyzer createArchiveAndCheck(CDSOptions opts)
+        throws Exception {
+        return checkDump(createArchive(opts));
+    }
+
+
+    public static OutputAnalyzer createArchiveAndCheck(String... cliPrefix)
+        throws Exception {
+        return checkDump(createArchive(cliPrefix));
+    }
+
+
+    // This method should be used to check the output of child VM for common exceptions.
+    // Most of CDS tests deal with child VM processes for creating and using the archive.
+    // However exceptions that occur in the child process do not automatically propagate
+    // to the parent process. This mechanism aims to improve the propagation
+    // of exceptions and common errors.
+    // Exception e argument - an exception to be re-thrown if none of the common
+    // exceptions match. Pass null if you wish not to re-throw any exception.
+    public static boolean checkCommonExecExceptions(OutputAnalyzer output, Exception e)
+        throws Exception {
+        if (output.getStdout().contains("https://bugreport.java.com/bugreport/crash.jsp")) {
+            throw new RuntimeException("Hotspot crashed");
+        }
+        if (output.getStdout().contains("TEST FAILED")) {
+            throw new RuntimeException("Test Failed");
+        }
+        if (output.getOutput().contains("Unable to unmap shared space")) {
+            throw new RuntimeException("Unable to unmap shared space");
+        }
+
+        // Special case -- sometimes Xshare:on fails because it failed to map
+        // at given address. This behavior is platform-specific, machine config-specific
+        // and can be random (see ASLR).
+        if (isUnableToMap(output)) {
+            System.out.println(UnableToMapMsg);
+            return true;
+        }
+
+        if (e != null) {
+            throw e;
+        }
+        return false;
+    }
+
+    public static boolean checkCommonExecExceptions(OutputAnalyzer output) throws Exception {
+        return checkCommonExecExceptions(output, null);
+    }
+
+
+    // Check the output for indication that mapping of the archive failed.
+    // Performance note: this check seems to be rather costly - searching the entire
+    // output stream of a child process for multiple strings. However, it is necessary
+    // to detect this condition, a failure to map an archive, since this is not a real
+    // failure of the test or VM operation, and results in a test being "skipped".
+    // Suggestions to improve:
+    // 1. VM can designate a special exit code for such condition.
+    // 2. VM can print a single distinct string indicating failure to map an archive,
+    //    instead of utilizing multiple messages.
+    // These are suggestions to improve testibility of the VM. However, implementing them
+    // could also improve usability in the field.
+    public static boolean isUnableToMap(OutputAnalyzer output) {
+        String outStr = output.getOutput();
+        if ((output.getExitValue() == 1) && (
+            outStr.contains("Unable to reserve shared space at required address") ||
+            outStr.contains("Unable to map ReadOnly shared space at required address") ||
+            outStr.contains("Unable to map ReadWrite shared space at required address") ||
+            outStr.contains("Unable to map MiscData shared space at required address") ||
+            outStr.contains("Unable to map MiscCode shared space at required address") ||
+            outStr.contains("Unable to map OptionalData shared space at required address") ||
+            outStr.contains("Could not allocate metaspace at a compatible address") ||
+            outStr.contains("UseSharedSpaces: Unable to allocate region, range is not within java heap") ))
+        {
+            return true;
+        }
+
+        return false;
+    }
+
+    public static Result run(String... cliPrefix) throws Exception {
+        CDSOptions opts = new CDSOptions();
+        opts.setArchiveName(getDefaultArchiveName());
+        opts.addPrefix(cliPrefix);
+        return new Result(opts, runWithArchive(opts));
+    }
+
+    public static Result run(CDSOptions opts) throws Exception {
+        return new Result(opts, runWithArchive(opts));
+    }
+
+    // Execute JVM with CDS archive, specify command line args suffix
+    public static OutputAnalyzer runWithArchive(String... cliPrefix)
+        throws Exception {
+
+        return runWithArchive( (new CDSOptions())
+                               .setArchiveName(getDefaultArchiveName())
+                               .addPrefix(cliPrefix) );
+    }
+
+
+    // Execute JVM with CDS archive, specify CDSOptions
+    public static OutputAnalyzer runWithArchive(CDSOptions opts)
+        throws Exception {
+
+        ArrayList<String> cmd = new ArrayList<String>();
+
+        for (String p : opts.prefix) cmd.add(p);
+
+        cmd.add("-Xshare:" + opts.xShareMode);
+        cmd.add("-Dtest.timeout.factor=" + TestTimeoutFactor);
+
+        if (opts.archiveName == null)
+            opts.archiveName = getDefaultArchiveName();
+        cmd.add("-XX:SharedArchiveFile=" + opts.archiveName);
+
+        if (opts.useVersion)
+            cmd.add("-version");
+
+        for (String s : opts.suffix) cmd.add(s);
+
+        String[] cmdLine = cmd.toArray(new String[cmd.size()]);
+        ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(true, cmdLine);
+        return executeAndLog(pb, "exec");
+    }
+
+
+    // A commonly used convenience methods to create an archive and check the results
+    // Creates an archive and checks for errors
+    public static OutputAnalyzer runWithArchiveAndCheck(CDSOptions opts) throws Exception {
+        return checkExec(runWithArchive(opts));
+    }
+
+
+    public static OutputAnalyzer runWithArchiveAndCheck(String... cliPrefix) throws Exception {
+        return checkExec(runWithArchive(cliPrefix));
+    }
+
+
+    public static OutputAnalyzer checkExec(OutputAnalyzer output,
+                                     String... extraMatches) throws Exception {
+        CDSOptions opts = new CDSOptions();
+        return checkExec(output, opts, extraMatches);
+    }
+
+
+    // check result of 'exec' operation, that is when JVM is run using the archive
+    public static OutputAnalyzer checkExec(OutputAnalyzer output, CDSOptions opts,
+                                     String... extraMatches) throws Exception {
+        try {
+            if ("on".equals(opts.xShareMode)) {
+                output.shouldContain("sharing");
+            }
+            output.shouldHaveExitValue(0);
+        } catch (RuntimeException e) {
+            checkCommonExecExceptions(output, e);
+            return output;
+        }
+
+        checkMatches(output, extraMatches);
+        return output;
+    }
+
+
+    public static OutputAnalyzer checkExecExpectError(OutputAnalyzer output,
+                                             int expectedExitValue,
+                                             String... extraMatches) throws Exception {
+        if (isUnableToMap(output)) {
+            System.out.println(UnableToMapMsg);
+            return output;
+        }
+
+        output.shouldHaveExitValue(expectedExitValue);
+        checkMatches(output, extraMatches);
+        return output;
+    }
+
+    public static OutputAnalyzer checkMatches(OutputAnalyzer output,
+                                              String... matches) throws Exception {
+        for (String match : matches) {
+            output.shouldContain(match);
+        }
+        return output;
+    }
+
+
+    // get the file object for the test artifact
+    public static File getTestArtifact(String name, boolean checkExistence) {
+        File dir = new File(System.getProperty("test.classes", "."));
+        File file = new File(dir, name);
+
+        if (checkExistence && !file.exists()) {
+            throw new RuntimeException("Cannot find " + file.getPath());
+        }
+
+        return file;
+    }
+
+
+    // create file containing the specified class list
+    public static File makeClassList(String classes[])
+        throws Exception {
+        return makeClassList(getTestName() + "-", classes);
+    }
+
+    // create file containing the specified class list
+    public static File makeClassList(String testCaseName, String classes[])
+        throws Exception {
+
+        File classList = getTestArtifact(testCaseName + "test.classlist", false);
+        FileOutputStream fos = new FileOutputStream(classList);
+        PrintStream ps = new PrintStream(fos);
+
+        addToClassList(ps, classes);
+
+        ps.close();
+        fos.close();
+
+        return classList;
+    }
+
+
+    public static void addToClassList(PrintStream ps, String classes[])
+        throws IOException
+    {
+        if (classes != null) {
+            for (String s : classes) {
+                ps.println(s);
+            }
+        }
+    }
+
+
+    // Optimization for getting a test name.
+    // Test name does not change during execution of the test,
+    // but getTestName() uses stack walking hence it is expensive.
+    // Therefore cache it and reuse it.
+    private static String testName;
+    public static String getTestName() {
+        if (testName == null) {
+            testName = Utils.getTestName();
+        }
+        return testName;
+    }
+
+    private static final SimpleDateFormat timeStampFormat =
+        new SimpleDateFormat("HH'h'mm'm'ss's'SSS");
+
+    private static String defaultArchiveName;
+
+    // Call this method to start new archive with new unique name
+    public static void startNewArchiveName() {
+        defaultArchiveName = getTestName() +
+            timeStampFormat.format(new Date()) + ".jsa";
+    }
+
+    public static String getDefaultArchiveName() {
+        return defaultArchiveName;
+    }
+
+
+    // ===================== FILE ACCESS convenience methods
+    public static File getOutputFile(String name) {
+        File dir = new File(System.getProperty("test.classes", "."));
+        return new File(dir, getTestName() + "-" + name);
+    }
+
+
+    public static File getOutputSourceFile(String name) {
+        File dir = new File(System.getProperty("test.classes", "."));
+        return new File(dir, name);
+    }
+
+
+    public static File getSourceFile(String name) {
+        File dir = new File(System.getProperty("test.src", "."));
+        return new File(dir, name);
+    }
+
+
+    // ============================= Logging
+    public static OutputAnalyzer executeAndLog(ProcessBuilder pb, String logName) throws Exception {
+        long started = System.currentTimeMillis();
+        OutputAnalyzer output = new OutputAnalyzer(pb.start());
+
+        writeFile(getOutputFile(logName + ".stdout"), output.getStdout());
+        writeFile(getOutputFile(logName + ".stderr"), output.getStderr());
+        System.out.println("[ELAPSED: " + (System.currentTimeMillis() - started) + " ms]");
+        System.out.println("[STDERR]\n" + output.getStderr());
+
+        if (CopyChildStdoutToMainStdout)
+            System.out.println("[STDOUT]\n" + output.getStdout());
+
+        return output;
+    }
+
+
+    private static void writeFile(File file, String content) throws Exception {
+        FileOutputStream fos = new FileOutputStream(file);
+        PrintStream ps = new PrintStream(fos);
+        ps.print(content);
+        ps.close();
+        fos.close();
+    }
+}
diff --git a/hotspot/test/testlibrary/com/oracle/java/testlibrary/compiler/CompilerUtils.java b/hotspot/test/testlibrary/com/oracle/java/testlibrary/compiler/CompilerUtils.java
new file mode 100644
index 00000000..a02a1742
--- /dev/null
+++ b/hotspot/test/testlibrary/com/oracle/java/testlibrary/compiler/CompilerUtils.java
@@ -0,0 +1,118 @@
+/*
+ * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.oracle.java.testlibrary.compiler;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.stream.Collectors;
+
+import javax.tools.JavaCompiler;
+import javax.tools.StandardJavaFileManager;
+import javax.tools.StandardLocation;
+import javax.tools.ToolProvider;
+
+/**
+ * This class consists exclusively of static utility methods for invoking the
+ * java compiler.
+ */
+public final class CompilerUtils {
+    private CompilerUtils() {
+    }
+
+    /**
+     * Compile all the java sources in {@code <source>/**} to
+     * {@code <destination>/**}. The destination directory will be created if
+     * it doesn't exist.
+     * <p>
+     * Equivalent to calling {@code compile(source, destination, true, options);}.
+     * <p>
+     * All warnings/errors emitted by the compiler are output to System.out/err.
+     *
+     * @param source      Path to the source directory
+     * @param destination Path to the destination directory
+     * @param options     Any options to pass to the compiler
+     * @return true if the compilation is successful
+     * @throws IOException                   if there is an I/O error scanning the source tree or
+     *                                       creating the destination directory
+     * @throws UnsupportedOperationException if there is no system java compiler
+     */
+    public static boolean compile(Path source, Path destination, String... options)
+            throws IOException {
+        return compile(source, destination, true, options);
+    }
+
+    /**
+     * Compile all the java sources in {@code <source>} and optionally its
+     * subdirectories, to
+     * {@code <destination>}. The destination directory will be created if
+     * it doesn't exist.
+     * <p>
+     * All warnings/errors emitted by the compiler are output to System.out/err.
+     *
+     * @param source      Path to the source directory
+     * @param destination Path to the destination directory
+     * @param recurse     If {@code true} recurse into any {@code source} subdirectories
+     *                    to compile all java source files; else only compile those directly in
+     *                    {@code source}.
+     * @param options     Any options to pass to the compiler
+     * @return true if the compilation is successful
+     * @throws IOException                   if there is an I/O error scanning the source tree or
+     *                                       creating the destination directory
+     * @throws UnsupportedOperationException if there is no system java compiler
+     */
+
+    public static boolean compile(Path source, Path destination, boolean recurse, String... options)
+            throws IOException {
+        JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
+        if (compiler == null) {
+            // no compiler available
+            throw new UnsupportedOperationException("Unable to get system java compiler. "
+                    + "Perhaps, jdk.compiler module is not available.");
+        }
+        StandardJavaFileManager jfm = compiler.getStandardFileManager(null, null, null);
+
+        List<File> sources
+                = Files.find(source, (recurse ? Integer.MAX_VALUE : 1),
+                (file, attrs) -> (file.toString().endsWith(".java")))
+                .map(e -> e.toFile()) // use jdk1.8
+                .collect(Collectors.toList());
+
+        Files.createDirectories(destination);
+//        jfm.setLocation(StandardLocation.CLASS_PATH, Collections.emptyList()); comment out , use jdk1.8, backport from jdk11u
+        jfm.setLocation(StandardLocation.CLASS_OUTPUT,
+                Collections.singletonList(destination.toFile()));
+
+        List<String> opts = Arrays.asList(options);
+        JavaCompiler.CompilationTask task
+                = compiler.getTask(null, jfm, null, opts, null,
+                jfm.getJavaFileObjectsFromFiles(sources)); // use jdk1.8
+
+        return task.call();
+    }
+}
diff --git a/hotspot/test/testlibrary/whitebox/sun/hotspot/WhiteBox.java b/hotspot/test/testlibrary/whitebox/sun/hotspot/WhiteBox.java
index 909e09f9..f06b1cbb 100644
--- a/hotspot/test/testlibrary/whitebox/sun/hotspot/WhiteBox.java
+++ b/hotspot/test/testlibrary/whitebox/sun/hotspot/WhiteBox.java
@@ -28,9 +28,11 @@ import java.lang.management.MemoryUsage;
 import java.lang.reflect.Executable;
 import java.util.Arrays;
 import java.util.List;
+import java.util.function.BiFunction;
 import java.util.function.Function;
 import java.util.stream.Stream;
 import java.security.BasicPermission;
+import java.util.Objects;
 import java.net.URL;
 
 import sun.hotspot.parser.DiagnosticCommand;
@@ -137,6 +139,31 @@ public class WhiteBox {
   }
   public native boolean isMethodCompilable(Executable method, int compLevel, boolean isOsr);
   public native boolean isMethodQueuedForCompilation(Executable method);
+
+  // Determine if the compiler corresponding to the compilation level 'compLevel'
+  // and to the compilation context 'compilation_context' provides an intrinsic
+  // for the method 'method'. An intrinsic is available for method 'method' if:
+  //  - the intrinsic is enabled (by using the appropriate command-line flag) and
+  //  - the platform on which the VM is running provides the instructions necessary
+  //    for the compiler to generate the intrinsic code.
+  //
+  // The compilation context is related to using the DisableIntrinsic flag on a
+  // per-method level, see hotspot/src/share/vm/compiler/abstractCompiler.hpp
+  // for more details.
+  public boolean isIntrinsicAvailable(Executable method,
+                                      Executable compilationContext,
+                                      int compLevel) {
+      Objects.requireNonNull(method);
+      return isIntrinsicAvailable0(method, compilationContext, compLevel);
+  }
+  // If usage of the DisableIntrinsic flag is not expected (or the usage can be ignored),
+  // use the below method that does not require the compilation context as argument.
+  public boolean isIntrinsicAvailable(Executable method, int compLevel) {
+      return isIntrinsicAvailable(method, null, compLevel);
+  }
+  private native boolean isIntrinsicAvailable0(Executable method,
+                                               Executable compilationContext,
+                                               int compLevel);
   public        int     deoptimizeMethod(Executable method) {
     return deoptimizeMethod(method, false /*not osr*/);
   }
@@ -253,5 +280,4 @@ public class WhiteBox {
   // Container testing
   public native boolean isContainerized();
   public native void printOsInfo();
-
 }
diff --git a/hotspot/test/testlibrary/whitebox/sun/hotspot/code/Compiler.java b/hotspot/test/testlibrary/whitebox/sun/hotspot/code/Compiler.java
new file mode 100644
index 00000000..bb06f1af
--- /dev/null
+++ b/hotspot/test/testlibrary/whitebox/sun/hotspot/code/Compiler.java
@@ -0,0 +1,154 @@
+/*
+ * Copyright (c) 2018, 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 sun.hotspot.code;
+
+import java.lang.reflect.Executable;
+import sun.hotspot.WhiteBox;
+
+/**
+ * API to obtain information about enabled JIT compilers
+ * retrieved from the VM with the WhiteBox API.
+ */
+public class Compiler {
+
+    private static final WhiteBox WB = WhiteBox.getWhiteBox();
+
+    /**
+     * Check if Graal is used as JIT compiler.
+     *
+     * Graal is enabled if following conditions are true:
+     * - we are not in Interpreter mode
+     * - UseJVMCICompiler flag is true
+     * - jvmci.Compiler variable is equal to 'graal'
+     * - TieredCompilation is not used or TieredStopAtLevel is greater than 3
+     * No need to check client mode because it set UseJVMCICompiler to false.
+     *
+     * @return true if Graal is used as JIT compiler.
+     */
+    public static boolean isGraalEnabled() {
+        Boolean useCompiler = WB.getBooleanVMFlag("UseCompiler");
+        if (useCompiler == null || !useCompiler) {
+            return false;
+        }
+        Boolean useJvmciComp = WB.getBooleanVMFlag("UseJVMCICompiler");
+        if (useJvmciComp == null || !useJvmciComp) {
+            return false;
+        }
+        // This check might be redundant but let's keep it for now.
+        String jvmciCompiler = System.getProperty("jvmci.Compiler");
+        if (jvmciCompiler == null || !jvmciCompiler.equals("graal")) {
+            return false;
+        }
+
+        Boolean tieredCompilation = WB.getBooleanVMFlag("TieredCompilation");
+        Long compLevel = WB.getIntxVMFlag("TieredStopAtLevel");
+        // if TieredCompilation is enabled and compilation level is <= 3 then no Graal is used
+        if (tieredCompilation != null && tieredCompilation &&
+                compLevel != null && compLevel <= 3) {
+            return false;
+        }
+        return true;
+    }
+
+    /**
+     * Check if C2 is used as JIT compiler.
+     *
+     * C2 is enabled if following conditions are true:
+     * - we are not in Interpreter mode
+     * - we are in Server compilation mode
+     * - TieredCompilation is not used or TieredStopAtLevel is greater than 3
+     * - Graal is not used
+     *
+     * @return true if C2 is used as JIT compiler.
+     */
+    public static boolean isC2Enabled() {
+        Boolean useCompiler = WB.getBooleanVMFlag("UseCompiler");
+        if (useCompiler == null || !useCompiler) {
+            return false;
+        }
+        Boolean serverMode = WB.getBooleanVMFlag("ProfileInterpreter");
+        if (serverMode == null || !serverMode) {
+            return false;
+        }
+
+        Boolean tieredCompilation = WB.getBooleanVMFlag("TieredCompilation");
+        Long compLevel = WB.getIntxVMFlag("TieredStopAtLevel");
+        // if TieredCompilation is enabled and compilation level is <= 3 then no Graal is used
+        if (tieredCompilation != null && tieredCompilation &&
+                compLevel != null && compLevel <= 3) {
+            return false;
+        }
+
+        if (isGraalEnabled()) {
+            return false;
+        }
+
+        return true;
+    }
+
+    /*
+     * Check if C1 is used as JIT compiler.
+     *
+     * C1 is enabled if following conditions are true:
+     * - we are not in Interpreter mode
+     * - we are not in Server compilation mode
+     * - TieredCompilation is used in Server mode
+     *
+     * @return true if C1 is used as JIT compiler.
+     */
+    public static boolean isC1Enabled() {
+        Boolean useCompiler = WB.getBooleanVMFlag("UseCompiler");
+        if (useCompiler == null || !useCompiler) {
+            return false;
+        }
+        Boolean serverMode = WB.getBooleanVMFlag("ProfileInterpreter");
+        if (serverMode == null || !serverMode) {
+            return true; // Client mode
+        }
+
+        Boolean tieredCompilation = WB.getBooleanVMFlag("TieredCompilation");
+        // C1 is not used in server mode if TieredCompilation is off.
+        if (tieredCompilation != null && !tieredCompilation) {
+            return false;
+        }
+        return true;
+    }
+
+    /*
+     * Determine if the compiler corresponding to the compilation level 'compLevel'
+     * provides an intrinsic for 'class'.'method'.
+     */
+    public static boolean isIntrinsicAvailable(int compLevel, String klass, String method, Class<?>... parameterTypes) {
+        Executable intrinsicMethod;
+        try {
+            intrinsicMethod = Class.forName(klass).getDeclaredMethod(method, parameterTypes);
+        } catch (NoSuchMethodException e) {
+            throw new RuntimeException("Test bug, '" + method + "' method unavailable. " + e);
+        } catch (ClassNotFoundException e) {
+            throw new RuntimeException("Test bug, '" + klass + "' class unavailable. " + e);
+        }
+        return WB.isIntrinsicAvailable(intrinsicMethod, compLevel);
+    }
+}
+
