Merge niosocketimpl-branch
authoralanb
Thu, 23 May 2019 11:07:37 +0100
branchniosocketimpl-branch
changeset 57367 276d3e540268
parent 57358 f0a1d9760c5e (current diff)
parent 55004 4645b6d57f54 (diff)
child 57368 82b83342bb31
Merge
src/hotspot/share/c1/c1_globals.cpp
src/hotspot/share/opto/c2_globals.cpp
test/jdk/sun/management/windows/revokeall.c
test/jdk/sun/management/windows/revokeall.exe
--- a/.hgtags	Fri May 17 13:21:44 2019 +0100
+++ b/.hgtags	Thu May 23 11:07:37 2019 +0100
@@ -559,3 +559,4 @@
 a43d6467317d8f1e160f67aadec37919c9d64443 jdk-13+19
 6ccc7cd7931e34129f6b7e04988fc9a63958dde0 jdk-13+20
 f2f11d7f7f4e7128f8aba6ffa576cfa76fbf7d1a jdk-13+21
+181986c5476468bc2dd4532af49599003ee8af37 jdk-13+22
--- a/doc/building.html	Fri May 17 13:21:44 2019 +0100
+++ b/doc/building.html	Thu May 23 11:07:37 2019 +0100
@@ -297,6 +297,10 @@
 </tr>
 </tbody>
 </table>
+<p>All compilers are expected to be able to compile to the C99 language standard,
+as some C99 features are used in the source code. Microsoft Visual Studio
+doesn't fully support C99 so in practice shared code is limited to using C99
+features that it does support.</p>
 <h3 id="gcc">gcc</h3>
 <p>The minimum accepted version of gcc is 4.8. Older versions will generate a warning by <code>configure</code> and are unlikely to work.</p>
 <p>The JDK is currently known to be able to compile with at least version 7.4 of gcc.</p>
--- a/doc/building.md	Fri May 17 13:21:44 2019 +0100
+++ b/doc/building.md	Thu May 23 11:07:37 2019 +0100
@@ -328,6 +328,11 @@
  Solaris            Oracle Solaris Studio 12.6 (with compiler version 5.15)
  Windows            Microsoft Visual Studio 2017 update 15.9.6
 
+All compilers are expected to be able to compile to the C99 language standard,
+as some C99 features are used in the source code. Microsoft Visual Studio
+doesn't fully support C99 so in practice shared code is limited to using C99
+features that it does support.
+
 ### gcc
 
 The minimum accepted version of gcc is 4.8. Older versions will generate a warning
--- a/make/Docs.gmk	Fri May 17 13:21:44 2019 +0100
+++ b/make/Docs.gmk	Thu May 23 11:07:37 2019 +0100
@@ -85,13 +85,14 @@
     -tag param \
     -tag return \
     -tag throws \
+    -taglet build.tools.taglet.JSpec\$$JLS \
+    -taglet build.tools.taglet.JSpec\$$JVMS \
     -taglet build.tools.taglet.ModuleGraph \
+    -taglet build.tools.taglet.ToolGuide \
     -tag since \
     -tag serialData \
     -tag factory \
     -tag see \
-    -tag 'jvms:a:See <cite>The Java&trade; Virtual Machine Specification</cite>:' \
-    -tag 'jls:a:See <cite>The Java&trade; Language Specification</cite>:' \
     -taglet build.tools.taglet.ExtLink \
     -taglet build.tools.taglet.Incubating \
     -tagletpath $(BUILDTOOLS_OUTPUTDIR)/jdk_tools_classes \
@@ -275,7 +276,8 @@
   $1_INDIRECT_EXPORTS := $$(call FindTransitiveIndirectDepsForModules, $$($1_MODULES))
   $1_ALL_MODULES := $$(sort $$($1_MODULES) $$($1_INDIRECT_EXPORTS))
 
-  $1_JAVA_ARGS := -Dextlink.spec.version=$$(VERSION_SPECIFICATION)
+  $1_JAVA_ARGS := -Dextlink.spec.version=$$(VERSION_SPECIFICATION) \
+	-Djspec.version=$$(VERSION_SPECIFICATION)
 
   ifeq ($$(ENABLE_FULL_DOCS), true)
     # Tell the ModuleGraph taglet to generate html links to soon-to-be-created
--- a/make/autoconf/flags-cflags.m4	Fri May 17 13:21:44 2019 +0100
+++ b/make/autoconf/flags-cflags.m4	Thu May 23 11:07:37 2019 +0100
@@ -300,6 +300,20 @@
     C_O_FLAG_DEBUG="-O0"
     C_O_FLAG_DEBUG_JVM="-O0"
     C_O_FLAG_NONE="-O0"
+    # -D_FORTIFY_SOURCE=2 hardening option needs optimization (at least -O1) enabled
+    # set for lower O-levels -U_FORTIFY_SOURCE to overwrite previous settings
+    if test "x$OPENJDK_TARGET_OS" = xlinux -a "x$DEBUG_LEVEL" = "xfastdebug"; then
+      ENABLE_FORTIFY_CFLAGS="-D_FORTIFY_SOURCE=2"
+      DISABLE_FORTIFY_CFLAGS="-U_FORTIFY_SOURCE"
+      C_O_FLAG_HIGHEST_JVM="${C_O_FLAG_HIGHEST_JVM} ${ENABLE_FORTIFY_CFLAGS}"
+      C_O_FLAG_HIGHEST="${C_O_FLAG_HIGHEST} ${ENABLE_FORTIFY_CFLAGS}"
+      C_O_FLAG_HI="${C_O_FLAG_HI} ${ENABLE_FORTIFY_CFLAGS}"
+      C_O_FLAG_NORM="${C_O_FLAG_NORM} ${ENABLE_FORTIFY_CFLAGS}"
+      C_O_FLAG_SIZE="${C_O_FLAG_SIZE} ${DISABLE_FORTIFY_CFLAGS}"
+      C_O_FLAG_DEBUG="${C_O_FLAG_DEBUG} ${DISABLE_FORTIFY_CFLAGS}"
+      C_O_FLAG_DEBUG_JVM="${C_O_FLAG_DEBUG_JVM} ${DISABLE_FORTIFY_CFLAGS}"
+      C_O_FLAG_NONE="${C_O_FLAG_NONE} ${DISABLE_FORTIFY_CFLAGS}"
+    fi
   elif test "x$TOOLCHAIN_TYPE" = xclang; then
     if test "x$OPENJDK_TARGET_OS" = xmacosx; then
       # On MacOSX we optimize for size, something
@@ -550,7 +564,7 @@
     TOOLCHAIN_CFLAGS="-errshort=tags"
 
     TOOLCHAIN_CFLAGS_JDK="-mt $TOOLCHAIN_FLAGS"
-    TOOLCHAIN_CFLAGS_JDK_CONLY="-xCC -Xa -W0,-noglobal $TOOLCHAIN_CFLAGS" # C only
+    TOOLCHAIN_CFLAGS_JDK_CONLY="-W0,-noglobal $TOOLCHAIN_CFLAGS" # C only
     TOOLCHAIN_CFLAGS_JDK_CXXONLY="-features=no%except -norunpath -xnolib" # CXX only
     TOOLCHAIN_CFLAGS_JVM="-template=no%extdef -features=no%split_init \
         -library=stlport4 -mt -features=no%except $TOOLCHAIN_FLAGS"
@@ -571,6 +585,30 @@
     TOOLCHAIN_CFLAGS_JDK="-nologo -MD -Zc:wchar_t-"
   fi
 
+  # CFLAGS C language level for JDK sources (hotspot only uses C++)
+  # Ideally we would have a common level across all toolchains so that all sources
+  # are sure to conform to the same standard. Unfortunately neither our sources nor
+  # our toolchains are in a condition to support that. But what we loosely aim for is
+  # C99 level.
+  if test "x$TOOLCHAIN_TYPE" = xgcc || test "x$TOOLCHAIN_TYPE" = xclang || test "x$TOOLCHAIN_TYPE" = xxlc; then
+    # This raises the language level for older 4.8 gcc, while lowering it for later
+    # versions. clang and xlclang support the same flag.
+    LANGSTD_CFLAGS="-std=c99"
+  elif test "x$TOOLCHAIN_TYPE" = xsolstudio; then
+    # We can't turn on -std=c99 without breaking compilation of the splashscreen/png
+    # utilities. But we can enable c99 as below (previously achieved by using -Xa).
+    # It is the no_lib that makes the difference.
+    LANGSTD_CFLAGS="-xc99=all,no_lib"
+  elif test "x$TOOLCHAIN_TYPE" = xmicrosoft; then
+    # MSVC doesn't support C99/C11 explicitly, unless you compile as C++:
+    # LANGSTD_CFLAGS="/TP"
+    # but that requires numerous changes to the sources files. So we are limited
+    # to C89/C90 plus whatever extensions Visual Studio has decided to implement.
+    # This is the lowest bar for shared code.
+    LANGSTD_CFLAGS=""
+  fi
+  TOOLCHAIN_CFLAGS_JDK_CONLY="$LANGSTD_CFLAGS $TOOLCHAIN_CFLAGS_JDK_CONLY"
+
   # CFLAGS WARNINGS STUFF
   # Set JVM_CFLAGS warning handling
   if test "x$TOOLCHAIN_TYPE" = xgcc; then
--- a/make/hotspot/lib/JvmFeatures.gmk	Fri May 17 13:21:44 2019 +0100
+++ b/make/hotspot/lib/JvmFeatures.gmk	Thu May 23 11:07:37 2019 +0100
@@ -111,6 +111,7 @@
   JVM_EXCLUDE_FILES += \
       classListParser.cpp \
       classLoaderExt.cpp \
+      dynamicArchive.cpp \
       filemap.cpp \
       heapShared.cpp \
       metaspaceShared.cpp \
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/make/jdk/src/classes/build/tools/taglet/JSpec.java	Thu May 23 11:07:37 2019 +0100
@@ -0,0 +1,192 @@
+/*
+ * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package build.tools.taglet;
+
+import java.util.EnumSet;
+import java.util.List;
+import java.util.Set;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import javax.lang.model.element.Element;
+
+import com.sun.source.doctree.DocTree;
+import com.sun.source.doctree.LiteralTree;
+import com.sun.source.doctree.UnknownBlockTagTree;
+import com.sun.source.util.SimpleDocTreeVisitor;
+import jdk.javadoc.doclet.Taglet;
+
+import static com.sun.source.doctree.DocTree.Kind.*;
+
+/**
+ * A base class for block tags to insert a link to an external copy of JLS or JVMS.
+ * The tags can be used as follows:
+ *
+ * <pre>
+ * &commat;jls section-number description
+ * </pre>
+ *
+ * For example:
+ *
+ * <pre>
+ * &commat;jls 3.4 Line Terminators
+ * </pre>
+ *
+ * will produce the following HTML for a docs build configured for Java SE 12.
+ *
+ * <pre>{@code
+ * <dt>See <i>Java Language Specification</i>:
+ * <dd><a href="https://docs.oracle.com/javase/specs/jls/se12/html/jls-3.html#jls-3.4">3.4 Line terminators</a>
+ * }</pre>
+ *
+ * The version of the spec must be set in the jspec.version system property.
+ */
+public class JSpec implements Taglet  {
+    static final String SPEC_VERSION;
+
+    static {
+        SPEC_VERSION = System.getProperty("jspec.version");
+        if (SPEC_VERSION == null) {
+            throw new RuntimeException("jspec.version property not set");
+        }
+    }
+
+    public static class JLS extends JSpec {
+        public JLS() {
+            super("jls",
+                "Java Language Specification",
+                "https://docs.oracle.com/javase/specs/jls/se" + SPEC_VERSION + "/html",
+                "jls");
+        }
+    }
+
+    public static class JVMS extends JSpec {
+        public JVMS() {
+            super("jvms",
+                "Java Virtual Machine Specification",
+                "https://docs.oracle.com/javase/specs/jvms/se" + SPEC_VERSION + "/html",
+                "jvms");
+        }
+    }
+
+    private String tagName;
+    private String specTitle;
+    private String baseURL;
+    private String idPrefix;
+
+    protected JSpec(String tagName, String specTitle, String baseURL, String idPrefix) {
+        this.tagName = tagName;
+        this.specTitle = specTitle;
+        this.baseURL = baseURL;
+        this.idPrefix = idPrefix;
+    }
+
+
+    static final Pattern TAG_PATTERN = Pattern.compile("(?s)(.+ )?(?<chapter>[1-9][0-9]*)(?<section>[0-9.]*)( .*)?$");
+
+
+    /**
+     * Returns the set of locations in which the tag may be used.
+     */
+    @Override
+    public Set<Location> getAllowedLocations() {
+        return EnumSet.allOf(jdk.javadoc.doclet.Taglet.Location.class);
+    }
+
+    @Override
+    public boolean isInlineTag() {
+        return false;
+    }
+
+    @Override
+    public String getName() {
+        return tagName;
+    }
+
+    @Override
+    public String toString(List<? extends DocTree> tags, Element elem) {
+
+        if (tags.isEmpty())
+            return "";
+
+        StringBuilder sb = new StringBuilder();
+        sb.append("<dt>See <i>" + specTitle + "</i>:</dt>\n")
+            .append("<dd>\n");
+
+        for (DocTree tag : tags) {
+
+            if (tag.getKind() != UNKNOWN_BLOCK_TAG) {
+                continue;
+            }
+
+            UnknownBlockTagTree blockTag = (UnknownBlockTagTree)tag;
+            String tagText = blockTag.getContent().toString().trim();
+            Matcher m = TAG_PATTERN.matcher(tagText);
+            if (m.find()) {
+                String chapter = m.group("chapter");
+                String section = m.group("section");
+
+                String url = String.format("%1$s/%2$s-%3$s.html#jls-%3$s%4$s",
+                        baseURL, idPrefix, chapter, section);
+
+
+                sb.append("<a href=\"")
+                        .append(url)
+                        .append("\">")
+                        .append(expand(blockTag))
+                        .append("</a><br>");
+            }
+
+        }
+
+        sb.append("</dd>");
+
+        return sb.toString();
+    }
+
+    private String expand(UnknownBlockTagTree tree) {
+        StringBuilder sb = new StringBuilder();
+        return (new SimpleDocTreeVisitor<StringBuilder, StringBuilder>() {
+            public StringBuilder defaultAction(DocTree tree, StringBuilder sb) {
+                return sb.append(tree.toString());
+            }
+
+            public StringBuilder visitLiteral(LiteralTree tree, StringBuilder sb) {
+                if (tree.getKind() == CODE) {
+                    sb.append("<code>");
+                }
+                sb.append(escape(tree.getBody().toString()));
+                if (tree.getKind() == CODE) {
+                    sb.append("</code>");
+                }
+                return sb;
+            }
+
+            private String escape(String s) {
+                return s.replace("&", "&amp;").replace("<", "&lt;").replace(">", "&gt");
+            }
+        }).visit(tree.getContent(), new StringBuilder()).toString();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/make/jdk/src/classes/build/tools/taglet/ToolGuide.java	Thu May 23 11:07:37 2019 +0100
@@ -0,0 +1,159 @@
+/*
+ * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package build.tools.taglet;
+
+import java.util.EnumSet;
+import java.util.List;
+import java.util.Set;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import javax.lang.model.element.Element;
+import javax.lang.model.element.ModuleElement;
+import javax.lang.model.element.PackageElement;
+
+import com.sun.source.doctree.DocTree;
+import com.sun.source.doctree.UnknownBlockTagTree;
+import jdk.javadoc.doclet.Taglet;
+
+import static com.sun.source.doctree.DocTree.Kind.*;
+import static jdk.javadoc.doclet.Taglet.Location.*;
+
+/**
+ * A block tag to insert a link to tool guide in a nearby directory.
+ * The tag can be used as follows:
+ * <ul>
+ * <li>&commat;toolGuide tool-name label
+ * </ul>
+ *
+ * If the label is omitted, it defaults to the tool name.
+ *
+ * For example
+ * <p>
+ * &commat;toolGuide javac
+ * <p>
+ * will produce the following html, depending on the file containing
+ * the tag.
+ * <p>
+ * {@code
+ * <dt>Tool Guides:
+ * <dd><a href="../../specs/man/javac.html">javac</a>
+ * }
+ */
+public class ToolGuide implements Taglet {
+
+    static final String TAG_NAME = "toolGuide";
+
+    static final String BASE_URL = "../specs/man";
+
+    static final Pattern TAG_PATTERN = Pattern.compile("(?s)(?<name>[A-Za-z0-9]+)\\s*(?<label>.*)$");
+
+    /**
+     * Returns the set of locations in which the tag may be used.
+     */
+    @Override
+    public Set<Location> getAllowedLocations() {
+        return EnumSet.of(MODULE, PACKAGE);
+    }
+
+    @Override
+    public boolean isInlineTag() {
+        return false;
+    }
+
+    @Override
+    public String getName() {
+        return TAG_NAME;
+    }
+
+    @Override
+    public String toString(List<? extends DocTree> tags, Element elem) {
+
+        if (tags.isEmpty())
+            return "";
+
+        StringBuilder sb = new StringBuilder();
+        sb.append("<dt class=\"simpleTagLabel\">Tool Guides:</dt>\n")
+                .append("<dd>");
+
+        boolean needComma = false;
+        for (DocTree tag : tags) {
+
+            if (tag.getKind() != UNKNOWN_BLOCK_TAG) {
+                continue;
+            }
+
+            UnknownBlockTagTree blockTag = (UnknownBlockTagTree)tag;
+            String tagText = blockTag.getContent().toString().trim();
+            Matcher m = TAG_PATTERN.matcher(tagText);
+            if (m.matches()) {
+                String name = m.group("name");
+                String label = m.group("label");
+                if (label.isEmpty()) {
+                    label = name;
+                }
+
+                String url = String.format("%s/%s/%s.html",
+                        docRoot(elem), BASE_URL, name);
+
+                if (needComma) {
+                    sb.append(",\n");
+                } else {
+                    needComma = true;
+                }
+
+                sb.append("<a href=\"")
+                        .append(url)
+                        .append("\">")
+                        .append(label)
+                        .append("</a>");
+            }
+        }
+
+        sb.append("</dd>\n");
+
+        return sb.toString();
+    }
+
+    private String docRoot(Element elem) {
+        switch (elem.getKind()) {
+            case MODULE:
+                return "..";
+
+            case PACKAGE:
+                PackageElement pe = (PackageElement)elem;
+                String pkgPart = pe.getQualifiedName()
+                        .toString()
+                        .replace('.', '/')
+                        .replaceAll("[^/]+", "..");
+                return pe.getEnclosingElement() != null
+                        ? "../" + pkgPart
+                        : pkgPart;
+
+            default:
+                throw new IllegalArgumentException(elem.getKind().toString());
+        }
+    }
+}
--- a/make/lib/Awt2dLibraries.gmk	Fri May 17 13:21:44 2019 +0100
+++ b/make/lib/Awt2dLibraries.gmk	Thu May 23 11:07:37 2019 +0100
@@ -378,7 +378,6 @@
     OPTIMIZATION := HIGHEST, \
     CFLAGS := $(CFLAGS_JDKLIB) \
         $(LCMS_CFLAGS), \
-    CFLAGS_solaris := -xc99=no_lib, \
     CFLAGS_windows := -DCMS_IS_WINDOWS_, \
     EXTRA_HEADER_DIRS := \
         common/awt/debug \
--- a/make/test/JtregNativeJdk.gmk	Fri May 17 13:21:44 2019 +0100
+++ b/make/test/JtregNativeJdk.gmk	Thu May 23 11:07:37 2019 +0100
@@ -62,9 +62,11 @@
   WIN_LIB_JLI := $(SUPPORT_OUTPUTDIR)/native/java.base/libjli/jli.lib
   BUILD_JDK_JTREG_EXECUTABLES_LIBS_exeJliLaunchTest := $(WIN_LIB_JLI)
   BUILD_JDK_JTREG_EXECUTABLES_LIBS_exeCallerAccessTest := jvm.lib
+  BUILD_JDK_JTREG_EXECUTABLES_LIBS_exerevokeall := advapi32.lib
 else
   BUILD_JDK_JTREG_LIBRARIES_LIBS_libstringPlatformChars := -ljava
   BUILD_JDK_JTREG_LIBRARIES_LIBS_libDirectIO := -ljava
+  BUILD_JDK_JTREG_EXCLUDE += exerevokeall.c
   ifeq ($(call isTargetOs, linux), true)
     BUILD_JDK_JTREG_LIBRARIES_LIBS_libInheritedChannel := -ljava
   else ifeq ($(call isTargetOs, solaris), true)
--- a/src/hotspot/cpu/aarch64/assembler_aarch64.hpp	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/cpu/aarch64/assembler_aarch64.hpp	Thu May 23 11:07:37 2019 +0100
@@ -629,6 +629,14 @@
 
   enum { instruction_size = 4 };
 
+  //---<  calculate length of instruction  >---
+  // We just use the values set above.
+  // instruction must start at passed address
+  static unsigned int instr_len(unsigned char *instr) { return instruction_size; }
+
+  //---<  longest instructions  >---
+  static unsigned int instr_maxlen() { return instruction_size; }
+
   Address adjust(Register base, int offset, bool preIncrement) {
     if (preIncrement)
       return Address(Pre(base, offset));
--- a/src/hotspot/cpu/aarch64/c2_globals_aarch64.hpp	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/cpu/aarch64/c2_globals_aarch64.hpp	Thu May 23 11:07:37 2019 +0100
@@ -76,7 +76,7 @@
 define_pd_global(intx, NonProfiledCodeHeapSize,      21*M);
 define_pd_global(intx, ProfiledCodeHeapSize,         22*M);
 define_pd_global(intx, NonNMethodCodeHeapSize,       5*M );
-define_pd_global(uintx, CodeCacheMinBlockLength,     4);
+define_pd_global(uintx, CodeCacheMinBlockLength,     6);
 define_pd_global(uintx, CodeCacheMinimumUseSpace,    400*K);
 
 // Heap related flags
--- a/src/hotspot/cpu/aarch64/disassembler_aarch64.hpp	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/cpu/aarch64/disassembler_aarch64.hpp	Thu May 23 11:07:37 2019 +0100
@@ -34,4 +34,24 @@
     return "";
   }
 
+  // Returns address of n-th instruction preceding addr,
+  // NULL if no preceding instruction can be found.
+  // On ARM(aarch64), we assume a constant instruction length.
+  // It might be beneficial to check "is_readable" as we do on ppc and s390.
+  static address find_prev_instr(address addr, int n_instr) {
+    return addr - Assembler::instruction_size*n_instr;
+  }
+
+  // special-case instruction decoding.
+  // There may be cases where the binutils disassembler doesn't do
+  // the perfect job. In those cases, decode_instruction0 may kick in
+  // and do it right.
+  // If nothing had to be done, just return "here", otherwise return "here + instr_len(here)"
+  static address decode_instruction0(address here, outputStream* st, address virtual_begin = NULL) {
+    return here;
+  }
+
+  // platform-specific instruction annotations (like value of loaded constants)
+  static void annotate(address pc, outputStream* st) { };
+
 #endif // CPU_AARCH64_DISASSEMBLER_AARCH64_HPP
--- a/src/hotspot/cpu/aarch64/gc/shared/barrierSetAssembler_aarch64.hpp	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/cpu/aarch64/gc/shared/barrierSetAssembler_aarch64.hpp	Thu May 23 11:07:37 2019 +0100
@@ -37,7 +37,7 @@
 
 public:
   virtual void arraycopy_prologue(MacroAssembler* masm, DecoratorSet decorators, bool is_oop,
-                                  Register addr, Register count, RegSet saved_regs) {}
+                                  Register src, Register dst, Register count, RegSet saved_regs) {}
   virtual void arraycopy_epilogue(MacroAssembler* masm, DecoratorSet decorators, bool is_oop,
                                   Register start, Register end, Register tmp, RegSet saved_regs) {}
   virtual void load_at(MacroAssembler* masm, DecoratorSet decorators, BasicType type,
--- a/src/hotspot/cpu/aarch64/gc/shared/modRefBarrierSetAssembler_aarch64.cpp	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/cpu/aarch64/gc/shared/modRefBarrierSetAssembler_aarch64.cpp	Thu May 23 11:07:37 2019 +0100
@@ -29,10 +29,10 @@
 #define __ masm->
 
 void ModRefBarrierSetAssembler::arraycopy_prologue(MacroAssembler* masm, DecoratorSet decorators, bool is_oop,
-                                                   Register addr, Register count, RegSet saved_regs) {
+                                                   Register src, Register dst, Register count, RegSet saved_regs) {
 
   if (is_oop) {
-    gen_write_ref_array_pre_barrier(masm, decorators, addr, count, saved_regs);
+    gen_write_ref_array_pre_barrier(masm, decorators, dst, count, saved_regs);
   }
 }
 
--- a/src/hotspot/cpu/aarch64/gc/shared/modRefBarrierSetAssembler_aarch64.hpp	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/cpu/aarch64/gc/shared/modRefBarrierSetAssembler_aarch64.hpp	Thu May 23 11:07:37 2019 +0100
@@ -44,7 +44,7 @@
 
 public:
   virtual void arraycopy_prologue(MacroAssembler* masm, DecoratorSet decorators, bool is_oop,
-                                  Register addr, Register count, RegSet saved_regs);
+                                  Register src, Register dst, Register count, RegSet saved_regs);
   virtual void arraycopy_epilogue(MacroAssembler* masm, DecoratorSet decorators, bool is_oop,
                                   Register start, Register count, Register tmp, RegSet saved_regs);
   virtual void store_at(MacroAssembler* masm, DecoratorSet decorators, BasicType type,
--- a/src/hotspot/cpu/aarch64/gc/shenandoah/shenandoahBarrierSetAssembler_aarch64.cpp	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/cpu/aarch64/gc/shenandoah/shenandoahBarrierSetAssembler_aarch64.cpp	Thu May 23 11:07:37 2019 +0100
@@ -44,7 +44,7 @@
 address ShenandoahBarrierSetAssembler::_shenandoah_lrb = NULL;
 
 void ShenandoahBarrierSetAssembler::arraycopy_prologue(MacroAssembler* masm, DecoratorSet decorators, bool is_oop,
-                                                       Register addr, Register count, RegSet saved_regs) {
+                                                       Register src, Register dst, Register count, RegSet saved_regs) {
   if (is_oop) {
     bool dest_uninitialized = (decorators & IS_DEST_UNINITIALIZED) != 0;
     if (ShenandoahSATBBarrier && !dest_uninitialized && !ShenandoahHeap::heap()->heuristics()->can_do_traversal_gc()) {
@@ -61,17 +61,17 @@
 
       __ push(saved_regs, sp);
       if (count == c_rarg0) {
-        if (addr == c_rarg1) {
+        if (dst == c_rarg1) {
           // exactly backwards!!
           __ mov(rscratch1, c_rarg0);
           __ mov(c_rarg0, c_rarg1);
           __ mov(c_rarg1, rscratch1);
         } else {
           __ mov(c_rarg1, count);
-          __ mov(c_rarg0, addr);
+          __ mov(c_rarg0, dst);
         }
       } else {
-        __ mov(c_rarg0, addr);
+        __ mov(c_rarg0, dst);
         __ mov(c_rarg1, count);
       }
       if (UseCompressedOops) {
--- a/src/hotspot/cpu/aarch64/gc/shenandoah/shenandoahBarrierSetAssembler_aarch64.hpp	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/cpu/aarch64/gc/shenandoah/shenandoahBarrierSetAssembler_aarch64.hpp	Thu May 23 11:07:37 2019 +0100
@@ -73,7 +73,7 @@
 #endif
 
   virtual void arraycopy_prologue(MacroAssembler* masm, DecoratorSet decorators, bool is_oop,
-                                  Register addr, Register count, RegSet saved_regs);
+                                  Register src, Register dst, Register count, RegSet saved_regs);
   virtual void arraycopy_epilogue(MacroAssembler* masm, DecoratorSet decorators, bool is_oop,
                                   Register start, Register count, Register tmp, RegSet saved_regs);
   virtual void load_at(MacroAssembler* masm, DecoratorSet decorators, BasicType type,
--- a/src/hotspot/cpu/aarch64/stubGenerator_aarch64.cpp	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/cpu/aarch64/stubGenerator_aarch64.cpp	Thu May 23 11:07:37 2019 +0100
@@ -1364,7 +1364,7 @@
     }
 
     BarrierSetAssembler *bs = BarrierSet::barrier_set()->barrier_set_assembler();
-    bs->arraycopy_prologue(_masm, decorators, is_oop, d, count, saved_reg);
+    bs->arraycopy_prologue(_masm, decorators, is_oop, s, d, count, saved_reg);
 
     if (is_oop) {
       // save regs before copy_memory
@@ -1436,7 +1436,7 @@
     }
 
     BarrierSetAssembler *bs = BarrierSet::barrier_set()->barrier_set_assembler();
-    bs->arraycopy_prologue(_masm, decorators, is_oop, d, count, saved_regs);
+    bs->arraycopy_prologue(_masm, decorators, is_oop, s, d, count, saved_regs);
 
     if (is_oop) {
       // save regs before copy_memory
@@ -1796,7 +1796,7 @@
     }
 
     BarrierSetAssembler *bs = BarrierSet::barrier_set()->barrier_set_assembler();
-    bs->arraycopy_prologue(_masm, decorators, is_oop, to, count, wb_pre_saved_regs);
+    bs->arraycopy_prologue(_masm, decorators, is_oop, from, to, count, wb_pre_saved_regs);
 
     // save the original count
     __ mov(count_save, count);
@@ -4035,14 +4035,14 @@
         : "compare_long_string_different_encoding UL");
     address entry = __ pc();
     Label SMALL_LOOP, TAIL, TAIL_LOAD_16, LOAD_LAST, DIFF1, DIFF2,
-        DONE, CALCULATE_DIFFERENCE, LARGE_LOOP_PREFETCH, SMALL_LOOP_ENTER,
+        DONE, CALCULATE_DIFFERENCE, LARGE_LOOP_PREFETCH, NO_PREFETCH,
         LARGE_LOOP_PREFETCH_REPEAT1, LARGE_LOOP_PREFETCH_REPEAT2;
     Register result = r0, str1 = r1, cnt1 = r2, str2 = r3, cnt2 = r4,
         tmp1 = r10, tmp2 = r11, tmp3 = r12, tmp4 = r14;
     FloatRegister vtmpZ = v0, vtmp = v1, vtmp3 = v2;
     RegSet spilled_regs = RegSet::of(tmp3, tmp4);
 
-    int prefetchLoopExitCondition = MAX(32, SoftwarePrefetchHintDistance/2);
+    int prefetchLoopExitCondition = MAX(64, SoftwarePrefetchHintDistance/2);
 
     __ eor(vtmpZ, __ T16B, vtmpZ, vtmpZ);
     // cnt2 == amount of characters left to compare
@@ -4069,7 +4069,7 @@
 
     if (SoftwarePrefetchHintDistance >= 0) {
       __ subs(rscratch2, cnt2, prefetchLoopExitCondition);
-      __ br(__ LT, SMALL_LOOP);
+      __ br(__ LT, NO_PREFETCH);
       __ bind(LARGE_LOOP_PREFETCH);
         __ prfm(Address(tmp2, SoftwarePrefetchHintDistance));
         __ mov(tmp4, 2);
@@ -4089,51 +4089,20 @@
           __ br(__ GE, LARGE_LOOP_PREFETCH);
     }
     __ cbz(cnt2, LOAD_LAST); // no characters left except last load
+    __ bind(NO_PREFETCH);
     __ subs(cnt2, cnt2, 16);
     __ br(__ LT, TAIL);
-    __ b(SMALL_LOOP_ENTER);
     __ bind(SMALL_LOOP); // smaller loop
       __ subs(cnt2, cnt2, 16);
-    __ bind(SMALL_LOOP_ENTER);
       compare_string_16_x_LU(tmpL, tmpU, DIFF1, DIFF2);
       __ br(__ GE, SMALL_LOOP);
-      __ cbz(cnt2, LOAD_LAST);
-    __ bind(TAIL); // 1..15 characters left
-      __ subs(zr, cnt2, -8);
-      __ br(__ GT, TAIL_LOAD_16);
-      __ ldrd(vtmp, Address(tmp2));
-      __ zip1(vtmp3, __ T8B, vtmp, vtmpZ);
-
-      __ ldr(tmpU, Address(__ post(cnt1, 8)));
-      __ fmovd(tmpL, vtmp3);
-      __ eor(rscratch2, tmp3, tmpL);
-      __ cbnz(rscratch2, DIFF2);
-      __ umov(tmpL, vtmp3, __ D, 1);
-      __ eor(rscratch2, tmpU, tmpL);
-      __ cbnz(rscratch2, DIFF1);
-      __ b(LOAD_LAST);
-    __ bind(TAIL_LOAD_16);
-      __ ldrq(vtmp, Address(tmp2));
-      __ ldr(tmpU, Address(__ post(cnt1, 8)));
-      __ zip1(vtmp3, __ T16B, vtmp, vtmpZ);
-      __ zip2(vtmp, __ T16B, vtmp, vtmpZ);
-      __ fmovd(tmpL, vtmp3);
-      __ eor(rscratch2, tmp3, tmpL);
-      __ cbnz(rscratch2, DIFF2);
-
-      __ ldr(tmp3, Address(__ post(cnt1, 8)));
-      __ umov(tmpL, vtmp3, __ D, 1);
-      __ eor(rscratch2, tmpU, tmpL);
-      __ cbnz(rscratch2, DIFF1);
-
-      __ ldr(tmpU, Address(__ post(cnt1, 8)));
-      __ fmovd(tmpL, vtmp);
-      __ eor(rscratch2, tmp3, tmpL);
-      __ cbnz(rscratch2, DIFF2);
-
-      __ umov(tmpL, vtmp, __ D, 1);
-      __ eor(rscratch2, tmpU, tmpL);
-      __ cbnz(rscratch2, DIFF1);
+      __ cmn(cnt2, (u1)16);
+      __ br(__ EQ, LOAD_LAST);
+    __ bind(TAIL); // 1..15 characters left until last load (last 4 characters)
+      __ add(cnt1, cnt1, cnt2, __ LSL, 1); // Address of 8 bytes before last 4 characters in UTF-16 string
+      __ add(tmp2, tmp2, cnt2); // Address of 16 bytes before last 4 characters in Latin1 string
+      __ ldr(tmp3, Address(cnt1, -8));
+      compare_string_16_x_LU(tmpL, tmpU, DIFF1, DIFF2); // last 16 characters before last load
       __ b(LOAD_LAST);
     __ bind(DIFF2);
       __ mov(tmpU, tmp3);
@@ -4141,10 +4110,12 @@
       __ pop(spilled_regs, sp);
       __ b(CALCULATE_DIFFERENCE);
     __ bind(LOAD_LAST);
+      // Last 4 UTF-16 characters are already pre-loaded into tmp3 by compare_string_16_x_LU.
+      // No need to load it again
+      __ mov(tmpU, tmp3);
       __ pop(spilled_regs, sp);
 
       __ ldrs(vtmp, Address(strL));
-      __ ldr(tmpU, Address(strU));
       __ zip1(vtmp, __ T8B, vtmp, vtmpZ);
       __ fmovd(tmpL, vtmp);
 
@@ -4206,10 +4177,10 @@
         compare_string_16_bytes_same(DIFF, DIFF2);
         __ br(__ GT, LARGE_LOOP_PREFETCH);
         __ cbz(cnt2, LAST_CHECK_AND_LENGTH_DIFF); // no more chars left?
-        // less than 16 bytes left?
-        __ subs(cnt2, cnt2, isLL ? 16 : 8);
-        __ br(__ LT, TAIL);
     }
+    // less than 16 bytes left?
+    __ subs(cnt2, cnt2, isLL ? 16 : 8);
+    __ br(__ LT, TAIL);
     __ bind(SMALL_LOOP);
       compare_string_16_bytes_same(DIFF, DIFF2);
       __ subs(cnt2, cnt2, isLL ? 16 : 8);
@@ -4338,6 +4309,7 @@
     __ ldr(ch1, Address(str1));
     // Read whole register from str2. It is safe, because length >=8 here
     __ ldr(ch2, Address(str2));
+    __ sub(cnt2, cnt2, cnt1);
     __ andr(first, ch1, str1_isL ? 0xFF : 0xFFFF);
     if (str1_isL != str2_isL) {
       __ eor(v0, __ T16B, v0, v0);
--- a/src/hotspot/cpu/arm/assembler_arm_32.hpp	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/cpu/arm/assembler_arm_32.hpp	Thu May 23 11:07:37 2019 +0100
@@ -199,6 +199,14 @@
   static const int LogInstructionSize = 2;
   static const int InstructionSize    = 1 << LogInstructionSize;
 
+  //---<  calculate length of instruction  >---
+  // We just use the values set above.
+  // instruction must start at passed address
+  static unsigned int instr_len(unsigned char *instr) { return InstructionSize; }
+
+  //---<  longest instructions  >---
+  static unsigned int instr_maxlen() { return InstructionSize; }
+
   static inline AsmCondition inverse(AsmCondition cond) {
     assert ((cond != al) && (cond != nv), "AL and NV conditions cannot be inversed");
     return (AsmCondition)((int)cond ^ 1);
--- a/src/hotspot/cpu/arm/c2_globals_arm.hpp	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/cpu/arm/c2_globals_arm.hpp	Thu May 23 11:07:37 2019 +0100
@@ -97,7 +97,7 @@
 // Ergonomics related flags
 define_pd_global(uint64_t, MaxRAM,                   4ULL*G);
 #endif
-define_pd_global(uintx, CodeCacheMinBlockLength,     4);
+define_pd_global(uintx, CodeCacheMinBlockLength,     6);
 define_pd_global(size_t, CodeCacheMinimumUseSpace,   400*K);
 
 define_pd_global(bool,  TrapBasedRangeChecks,        false); // Not needed
--- a/src/hotspot/cpu/arm/disassembler_arm.hpp	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/cpu/arm/disassembler_arm.hpp	Thu May 23 11:07:37 2019 +0100
@@ -33,4 +33,24 @@
     return "";
   }
 
+  // Returns address of n-th instruction preceding addr,
+  // NULL if no preceding instruction can be found.
+  // On ARM, we assume a constant instruction length.
+  // It might be beneficial to check "is_readable" as we do on ppc and s390.
+  static address find_prev_instr(address addr, int n_instr) {
+    return addr - Assembler::InstructionSize*n_instr;
+  }
+
+  // special-case instruction decoding.
+  // There may be cases where the binutils disassembler doesn't do
+  // the perfect job. In those cases, decode_instruction0 may kick in
+  // and do it right.
+  // If nothing had to be done, just return "here", otherwise return "here + instr_len(here)"
+  static address decode_instruction0(address here, outputStream* st, address virtual_begin = NULL) {
+    return here;
+  }
+
+  // platform-specific instruction annotations (like value of loaded constants)
+  static void annotate(address pc, outputStream* st) { };
+
 #endif // CPU_ARM_DISASSEMBLER_ARM_HPP
--- a/src/hotspot/cpu/ppc/assembler_ppc.hpp	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/cpu/ppc/assembler_ppc.hpp	Thu May 23 11:07:37 2019 +0100
@@ -929,11 +929,13 @@
 
   enum Predict { pt = 1, pn = 0 }; // pt = predict taken
 
-  // Instruction must start at passed address.
-  static int instr_len(unsigned char *instr) { return BytesPerInstWord; }
+  //---<  calculate length of instruction  >---
+  // With PPC64 being a RISC architecture, this always is BytesPerInstWord
+  // instruction must start at passed address
+  static unsigned int instr_len(unsigned char *instr) { return BytesPerInstWord; }
 
-  // longest instructions
-  static int instr_maxlen() { return BytesPerInstWord; }
+  //---<  longest instructions  >---
+  static unsigned int instr_maxlen() { return BytesPerInstWord; }
 
   // Test if x is within signed immediate range for nbits.
   static bool is_simm(int x, unsigned int nbits) {
--- a/src/hotspot/cpu/ppc/c2_globals_ppc.hpp	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/cpu/ppc/c2_globals_ppc.hpp	Thu May 23 11:07:37 2019 +0100
@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2012, 2018 SAP SE. All rights reserved.
+ * Copyright (c) 2012, 2019 SAP SE. 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
@@ -90,7 +90,7 @@
 
 // Ergonomics related flags
 define_pd_global(uint64_t, MaxRAM,                       128ULL*G);
-define_pd_global(uintx,    CodeCacheMinBlockLength,      4);
+define_pd_global(uintx,    CodeCacheMinBlockLength,      6);
 define_pd_global(uintx,    CodeCacheMinimumUseSpace,     400*K);
 
 define_pd_global(bool,     TrapBasedRangeChecks,          true);
--- a/src/hotspot/cpu/ppc/c2_init_ppc.cpp	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/cpu/ppc/c2_init_ppc.cpp	Thu May 23 11:07:37 2019 +0100
@@ -36,18 +36,18 @@
   // Power7 and later.
   if (PowerArchitecturePPC64 > 6) {
     if (FLAG_IS_DEFAULT(UsePopCountInstruction)) {
-      FLAG_SET_ERGO(bool, UsePopCountInstruction, true);
+      FLAG_SET_ERGO(UsePopCountInstruction, true);
     }
   }
 
   if (PowerArchitecturePPC64 == 6) {
     if (FLAG_IS_DEFAULT(InsertEndGroupPPC64)) {
-      FLAG_SET_ERGO(bool, InsertEndGroupPPC64, true);
+      FLAG_SET_ERGO(InsertEndGroupPPC64, true);
     }
   }
 
   if (!VM_Version::has_isel() && FLAG_IS_DEFAULT(ConditionalMoveLimit)) {
-    FLAG_SET_ERGO(intx, ConditionalMoveLimit, 0);
+    FLAG_SET_ERGO(ConditionalMoveLimit, 0);
   }
 
   if (OptimizeFill) {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/cpu/ppc/disassembler_ppc.cpp	Thu May 23 11:07:37 2019 +0100
@@ -0,0 +1,201 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2019 SAP SE. 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.
+ *
+ */
+
+#include "asm/macroAssembler.inline.hpp"
+#include "code/codeCache.hpp"
+#include "compiler/disassembler.hpp"
+#include "depChecker_ppc.hpp"
+#include "gc/cms/concurrentMarkSweepGeneration.inline.hpp"
+#include "gc/cms/parOopClosures.inline.hpp"
+#include "gc/shared/collectedHeap.hpp"
+#include "gc/shared/cardTableBarrierSet.hpp"
+#include "gc/shared/genOopClosures.inline.hpp"
+#include "oops/oop.inline.hpp"
+#include "runtime/handles.inline.hpp"
+#include "runtime/stubCodeGenerator.hpp"
+#include "runtime/stubRoutines.hpp"
+
+// Macro to print instruction bits.
+// numbering of instruction bits on ppc64 is (highest) 0 1 ... 30 31 (lowest).
+#define print_instruction_bits(st, instruction, start_bit, end_bit) \
+  { assert((start_bit) <= (end_bit), "sanity check"); \
+    for (int i=(31-(start_bit));i>=(31-(end_bit));i--) { \
+      (st)->print("%d", ((instruction) >> i) & 0x1); \
+    } \
+  }
+
+// Macro to decode "bo" instruction bits.
+#define print_decoded_bo_bits(env, instruction, end_bit) \
+  { int bo_bits = (instruction >> (31 - (end_bit))) & 0x1f; \
+    if ( ((bo_bits & 0x1c) == 0x4) || ((bo_bits & 0x1c) == 0xc) ) { \
+      switch (bo_bits & 0x3) { \
+        case (0 << 1) | (0 << 0): env->print("[no_hint]"); break; \
+        case (0 << 1) | (1 << 0): env->print("[reserved]"); break; \
+        case (1 << 1) | (0 << 0): env->print("[not_taken]"); break; \
+        case (1 << 1) | (1 << 0): env->print("[taken]"); break; \
+        default: break; \
+      } \
+    } else if ( ((bo_bits & 0x14) == 0x10) ) { \
+      switch (bo_bits & 0x9) { \
+        case (0 << 3) | (0 << 0): env->print("[no_hint]"); break; \
+        case (0 << 3) | (1 << 0): env->print("[reserved]"); break; \
+        case (1 << 3) | (0 << 0): env->print("[not_taken]"); break; \
+        case (1 << 3) | (1 << 0): env->print("[taken]"); break; \
+        default: break; \
+      } \
+    } \
+  }
+
+// Macro to decode "bh" instruction bits.
+#define print_decoded_bh_bits(env, instruction, end_bit, is_bclr) \
+  { int bh_bits = (instruction >> (31 - (end_bit))) & 0x3; \
+    if (is_bclr) { \
+      switch (bh_bits) { \
+        case (0 << 1) | (0 << 0): env->print("[subroutine_return]"); break; \
+        case (0 << 1) | (1 << 0): env->print("[not_return_but_same]"); break; \
+        case (1 << 1) | (0 << 0): env->print("[reserved]"); break; \
+        case (1 << 1) | (1 << 0): env->print("[not_predictable]"); break; \
+        default: break; \
+      } \
+    } else { \
+      switch (bh_bits) { \
+        case (0 << 1) | (0 << 0): env->print("[not_return_but_same]"); break; \
+        case (0 << 1) | (1 << 0): env->print("[reserved]"); break; \
+        case (1 << 1) | (0 << 0): env->print("[reserved]"); break; \
+        case (1 << 1) | (1 << 0): env->print("[not_predictable]"); break; \
+        default: break; \
+      } \
+    } \
+  }
+
+address Disassembler::find_prev_instr(address here, int n_instr) {
+  if (!os::is_readable_pointer(here)) return NULL;    // obviously a bad location to decode
+
+  // Find most distant possible starting point.
+  // Narrow down because we don't want to SEGV while printing.
+  address start = here - n_instr*Assembler::instr_maxlen(); // starting point can't be further away.
+  while ((start < here) && !os::is_readable_range(start, here)) {
+    start = align_down(start, os::min_page_size()) + os::min_page_size();
+  }
+  if (start >= here) {
+    // Strange. Can only happen with here on page boundary.
+    return NULL;
+  }
+  return start;
+}
+
+address Disassembler::decode_instruction0(address here, outputStream * st, address virtual_begin ) {
+  if (is_abstract()) {
+    // The disassembler library was not loaded (yet),
+    // use AbstractDisassembler's decode method.
+    return decode_instruction_abstract(here, st, Assembler::instr_len(here), Assembler::instr_maxlen());
+  }
+
+  // Currently, "special decoding" doesn't work when decoding error files.
+  // When decoding an instruction from a hs_err file, the given
+  // instruction address 'start' points to the instruction's virtual address
+  // which is not equal to the address where the instruction is located.
+  // Therefore, we will either crash or decode garbage.
+  if (is_decode_error_file()) {
+    return here;
+  }
+
+  //---<  Decode some well-known "instructions"  >---
+
+  address  next;
+  uint32_t instruction = *(uint32_t*)here;
+
+  // Align at next tab position.
+  const uint tabspacing  = 8;
+  const uint pos         = st->position();
+  const uint aligned_pos = ((pos+tabspacing-1)/tabspacing)*tabspacing;
+  st->fill_to(aligned_pos);
+
+  if (instruction == 0x0) {
+    st->print("illtrap .data 0x0");
+    next = here + Assembler::instr_len(here);
+  } else if (instruction == 0xbadbabe) {
+    st->print(".data 0xbadbabe");
+    next = here + Assembler::instr_len(here);
+  } else if (Assembler::is_endgroup(instruction)) {
+    st->print("endgroup");
+    next = here + Assembler::instr_len(here);
+  } else {
+    next = here;
+  }
+  return next;
+}
+
+// print annotations (instruction control bits)
+void Disassembler::annotate(address here, outputStream* st) {
+  // Currently, annotation doesn't work when decoding error files.
+  // When decoding an instruction from a hs_err file, the given
+  // instruction address 'start' points to the instruction's virtual address
+  // which is not equal to the address where the instruction is located.
+  // Therefore, we will either crash or decode garbage.
+  if (is_decode_error_file()) {
+    return;
+  }
+
+  uint32_t   instruction = *(uint32_t*)here;
+
+  // Align at next tab position.
+  const uint tabspacing  = 8;
+  const uint pos         = st->position();
+  const uint aligned_pos = ((pos+tabspacing-1)/tabspacing)*tabspacing;
+
+  if (MacroAssembler::is_bcxx(instruction)) {
+    st->print(",bo=0b");
+    print_instruction_bits(st, instruction, 6, 10);
+    print_decoded_bo_bits(st, instruction, 10);
+  } else if (MacroAssembler::is_bctr(instruction) ||
+             MacroAssembler::is_bctrl(instruction) ||
+             MacroAssembler::is_bclr(instruction)) {
+    st->fill_to(aligned_pos);
+    st->print("bo=0b");
+    print_instruction_bits(st, instruction, 6, 10);
+    print_decoded_bo_bits(st, instruction, 10);
+    st->print(",bh=0b");
+    print_instruction_bits(st, instruction, 19, 20);
+    print_decoded_bh_bits(st, instruction, 20,
+                          !(MacroAssembler::is_bctr(instruction) ||
+                            MacroAssembler::is_bctrl(instruction)));
+  } else if (MacroAssembler::is_trap_should_not_reach_here(instruction)) {
+    st->fill_to(aligned_pos + tabspacing);
+    st->print(";trap: should not reach here");
+  } else if (MacroAssembler::is_trap_null_check(instruction)) {
+    st->fill_to(aligned_pos + tabspacing);
+    st->print(";trap: null check");
+  } else if (MacroAssembler::is_trap_range_check(instruction)) {
+    st->fill_to(aligned_pos + tabspacing);
+    st->print(";trap: range check");
+  } else if (MacroAssembler::is_trap_ic_miss_check(instruction)) {
+    st->fill_to(aligned_pos + tabspacing);
+    st->print(";trap: ic miss check");
+  } else if (MacroAssembler::is_trap_zombie_not_entrant(instruction)) {
+    st->fill_to(aligned_pos + tabspacing);
+    st->print(";trap: zombie");
+  }
+}
--- a/src/hotspot/cpu/ppc/disassembler_ppc.hpp	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/cpu/ppc/disassembler_ppc.hpp	Thu May 23 11:07:37 2019 +0100
@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2002, 2019, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2012, 2013 SAP SE. All rights reserved.
+ * Copyright (c) 2012, 2019 SAP SE. 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
@@ -34,4 +34,23 @@
     return "ppc64";
   }
 
+  // Find preceding instruction.
+  //
+  // Starting at the passed location, the n-th preceding (towards lower addresses)
+  // location is searched, the contents of which - if interpreted as
+  // instructions - has the passed location as n-th successor.
+  //  - If no such location exists, NULL is returned. The caller should then
+  //    terminate its search and react properly.
+  static address find_prev_instr(address here, int n_instr);
+
+  // special-case instruction decoding.
+  // There may be cases where the binutils disassembler doesn't do
+  // the perfect job. In those cases, decode_instruction0 may kick in
+  // and do it right.
+  // If nothing had to be done, just return "here", otherwise return "here + instr_len(here)"
+  static address decode_instruction0(address here, outputStream* st, address virtual_begin = NULL);
+
+  // platform-specific instruction annotations (like value of loaded constants)
+  static void annotate(address pc, outputStream* st);
+
 #endif // CPU_PPC_DISASSEMBLER_PPC_HPP
--- a/src/hotspot/cpu/ppc/vm_version_ppc.cpp	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/cpu/ppc/vm_version_ppc.cpp	Thu May 23 11:07:37 2019 +0100
@@ -67,17 +67,17 @@
   // If PowerArchitecturePPC64 hasn't been specified explicitly determine from features.
   if (FLAG_IS_DEFAULT(PowerArchitecturePPC64)) {
     if (VM_Version::has_darn()) {
-      FLAG_SET_ERGO(uintx, PowerArchitecturePPC64, 9);
+      FLAG_SET_ERGO(PowerArchitecturePPC64, 9);
     } else if (VM_Version::has_lqarx()) {
-      FLAG_SET_ERGO(uintx, PowerArchitecturePPC64, 8);
+      FLAG_SET_ERGO(PowerArchitecturePPC64, 8);
     } else if (VM_Version::has_popcntw()) {
-      FLAG_SET_ERGO(uintx, PowerArchitecturePPC64, 7);
+      FLAG_SET_ERGO(PowerArchitecturePPC64, 7);
     } else if (VM_Version::has_cmpb()) {
-      FLAG_SET_ERGO(uintx, PowerArchitecturePPC64, 6);
+      FLAG_SET_ERGO(PowerArchitecturePPC64, 6);
     } else if (VM_Version::has_popcntb()) {
-      FLAG_SET_ERGO(uintx, PowerArchitecturePPC64, 5);
+      FLAG_SET_ERGO(PowerArchitecturePPC64, 5);
     } else {
-      FLAG_SET_ERGO(uintx, PowerArchitecturePPC64, 0);
+      FLAG_SET_ERGO(PowerArchitecturePPC64, 0);
     }
   }
 
@@ -103,15 +103,15 @@
     MSG(TrapBasedICMissChecks);
     MSG(TrapBasedNotEntrantChecks);
     MSG(TrapBasedNullChecks);
-    FLAG_SET_ERGO(bool, TrapBasedNotEntrantChecks, false);
-    FLAG_SET_ERGO(bool, TrapBasedNullChecks,       false);
-    FLAG_SET_ERGO(bool, TrapBasedICMissChecks,     false);
+    FLAG_SET_ERGO(TrapBasedNotEntrantChecks, false);
+    FLAG_SET_ERGO(TrapBasedNullChecks,       false);
+    FLAG_SET_ERGO(TrapBasedICMissChecks,     false);
   }
 
 #ifdef COMPILER2
   if (!UseSIGTRAP) {
     MSG(TrapBasedRangeChecks);
-    FLAG_SET_ERGO(bool, TrapBasedRangeChecks, false);
+    FLAG_SET_ERGO(TrapBasedRangeChecks, false);
   }
 
   // On Power6 test for section size.
@@ -123,7 +123,7 @@
 
   if (PowerArchitecturePPC64 >= 8) {
     if (FLAG_IS_DEFAULT(SuperwordUseVSX)) {
-      FLAG_SET_ERGO(bool, SuperwordUseVSX, true);
+      FLAG_SET_ERGO(SuperwordUseVSX, true);
     }
   } else {
     if (SuperwordUseVSX) {
@@ -135,10 +135,10 @@
 
   if (PowerArchitecturePPC64 >= 9) {
     if (FLAG_IS_DEFAULT(UseCountTrailingZerosInstructionsPPC64)) {
-      FLAG_SET_ERGO(bool, UseCountTrailingZerosInstructionsPPC64, true);
+      FLAG_SET_ERGO(UseCountTrailingZerosInstructionsPPC64, true);
     }
     if (FLAG_IS_DEFAULT(UseCharacterCompareIntrinsics)) {
-      FLAG_SET_ERGO(bool, UseCharacterCompareIntrinsics, true);
+      FLAG_SET_ERGO(UseCharacterCompareIntrinsics, true);
     }
   } else {
     if (UseCountTrailingZerosInstructionsPPC64) {
@@ -708,6 +708,8 @@
   uint32_t *code_end = (uint32_t *)a->pc();
   a->flush();
 
+  cb.insts()->set_end((u_char*)code_end);
+
   double loop1_seconds,loop2_seconds, rel_diff;
   uint64_t start1, stop1;
 
@@ -725,10 +727,11 @@
 
   rel_diff = (loop2_seconds - loop1_seconds) / loop1_seconds *100;
 
-  if (PrintAssembly) {
+  if (PrintAssembly || PrintStubCode) {
     ttyLocker ttyl;
     tty->print_cr("Decoding section size detection stub at " INTPTR_FORMAT " before execution:", p2i(code));
-    Disassembler::decode((u_char*)code, (u_char*)code_end, tty);
+    // Use existing decode function. This enables the [MachCode] format which is needed to DecodeErrorFile.
+    Disassembler::decode(&cb, (u_char*)code, (u_char*)code_end, tty);
     tty->print_cr("Time loop1 :%f", loop1_seconds);
     tty->print_cr("Time loop2 :%f", loop2_seconds);
     tty->print_cr("(time2 - time1) / time1 = %f %%", rel_diff);
--- a/src/hotspot/cpu/s390/assembler_s390.hpp	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/cpu/s390/assembler_s390.hpp	Thu May 23 11:07:37 2019 +0100
@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2016, 2017 SAP SE. All rights reserved.
+ * Copyright (c) 2016, 2019 SAP SE. 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
@@ -1531,16 +1531,16 @@
   //-----------------------------------------------
 
   // Calculate length of instruction.
-  static int instr_len(unsigned char *instr);
+  static unsigned int instr_len(unsigned char *instr);
 
   // Longest instructions are 6 bytes on z/Architecture.
-  static int instr_maxlen() { return 6; }
+  static unsigned int instr_maxlen() { return 6; }
 
   // Average instruction is 4 bytes on z/Architecture (just a guess).
-  static int instr_avglen() { return 4; }
+  static unsigned int instr_avglen() { return 4; }
 
   // Shortest instructions are 2 bytes on z/Architecture.
-  static int instr_minlen() { return 2; }
+  static unsigned int instr_minlen() { return 2; }
 
   // Move instruction at pc right-justified into passed long int.
   // Return instr len in bytes as function result.
--- a/src/hotspot/cpu/s390/assembler_s390.inline.hpp	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/cpu/s390/assembler_s390.inline.hpp	Thu May 23 11:07:37 2019 +0100
@@ -1344,7 +1344,7 @@
 
 // Instruction must start at passed address.
 // Extra check for illtraps with ID.
-inline int Assembler::instr_len(unsigned char *instr) {
+inline unsigned int Assembler::instr_len(unsigned char *instr) {
   switch ((*instr) >> 6) {
     case 0: return 2;
     case 1: // fallthru
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/cpu/s390/disassembler_s390.cpp	Thu May 23 11:07:37 2019 +0100
@@ -0,0 +1,261 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2019 SAP SE. 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.
+ *
+ */
+
+#include "asm/assembler.inline.hpp"
+#include "asm/macroAssembler.hpp"
+#include "code/codeCache.hpp"
+#include "compiler/disassembler.hpp"
+#include "depChecker_s390.hpp"
+#include "gc/cms/concurrentMarkSweepGeneration.inline.hpp"
+#include "gc/cms/parOopClosures.inline.hpp"
+#include "gc/shared/collectedHeap.hpp"
+#include "gc/shared/cardTableBarrierSet.hpp"
+#include "gc/shared/genOopClosures.inline.hpp"
+#include "oops/oop.inline.hpp"
+#include "runtime/handles.inline.hpp"
+#include "runtime/stubCodeGenerator.hpp"
+#include "runtime/stubRoutines.hpp"
+#include "utilities/align.hpp"
+
+// List of all major opcodes, as of
+// Principles of Operation, Eleventh Edition, March 2015
+bool Disassembler::valid_opcodes[] =
+{ true,  true,  false, false, true,  true,  true,  true,  // 0x00..07
+  false, false, true,  true,  true,  true,  true,  true,  // 0x08..0f
+  true,  true,  true,  true,  true,  true,  true,  true,  // 0x10..17
+  true,  true,  true,  true,  true,  true,  true,  true,  // 0x18..1f
+  true,  true,  true,  true,  true,  true,  true,  true,  // 0x20..27
+  true,  true,  true,  true,  true,  true,  true,  true,  // 0x28..2f
+  true,  true,  true,  true,  true,  true,  true,  true,  // 0x30..37
+  true,  true,  true,  true,  true,  true,  true,  true,  // 0x38..3f
+  true,  true,  true,  true,  true,  true,  true,  true,  // 0x40..47
+  true,  true,  true,  true,  true,  true,  true,  true,  // 0x48..4f
+  true,  true,  false, false, true,  true,  true,  true,  // 0x50..57
+  true,  true,  true,  true,  true,  true,  true,  true,  // 0x58..5f
+  true,  false, false, false, false, false, false, true,  // 0x60..67
+  true,  true,  true,  true,  true,  true,  true,  true,  // 0x68..6f
+  true,  true,  false, false, false, false, false, false, // 0x70..77
+  true,  true,  true,  true,  true,  true,  true,  true,  // 0x78..7f
+  true,  false, true,  true,  true,  true,  true,  true,  // 0x80..87
+  true,  true,  true,  true,  true,  true,  true,  true,  // 0x88..8f
+  true,  true,  true,  true,  true,  true,  true,  true,  // 0x90..97
+  true,  true,  true,  true,  false, false, false, false, // 0x98..9f
+  false, false, false, false, false, true,  false, true,  // 0xa0..a7
+  true,  true,  false, false, true,  true,  true,  true,  // 0xa8..af
+  false, true,  true,  true,  false, false, true,  true,  // 0xb0..b7
+  false, true,  true,  true,  false, true,  true,  true,  // 0xb8..bf
+  true,  false, true,  false, true,  false, true,  false, // 0xc0..c7
+  true,  false, false, false, true,  false, false, false, // 0xc8..cf
+  true,  true,  true,  true,  true,  true,  true,  true,  // 0xd0..d7
+  false, true,  true,  true,  true,  true,  true,  true,  // 0xd8..df
+  false, true,  true,  true,  false, true,  false, true,  // 0xe0..e7
+  true,  true,  true,  true,  true,  true,  true,  true,  // 0xe8..ef
+  true,  true,  true,  true,  false, false, false, false, // 0xf0..f7
+  true,  true,  true,  true,  true,  true,  false, false, // 0xf8..ff
+};
+// Check for valid opcodes.
+//
+// The major opcode (one byte) at the passed location is inspected.
+// If the opcode found is assigned, the function returns true, false otherwise.
+// The true indication is not reliable. It may well be that the major opcode is
+// assigned, but there exists a minor opcode field in the instruction which
+// which has unassigned values.
+bool Disassembler::is_valid_opcode_at(address here) {
+  return valid_opcodes[*here];
+}
+
+// This method does plain instruction decoding, no frills.
+// It may be called before the binutils disassembler kicks in
+// to handle special cases the binutils disassembler does not.
+// Instruction address, comments, and the like have to be output by caller.
+address Disassembler::decode_instruction0(address here, outputStream * st, address virtual_begin) {
+  if (is_abstract()) {
+    // The disassembler library was not loaded (yet),
+    // use AbstractDisassembler's decode-method.
+    return decode_instruction_abstract(here, st, Assembler::instr_len(here), Assembler::instr_maxlen());
+  }
+
+  // Currently, "special decoding" doesn't work when decoding error files.
+  // When decoding an instruction from a hs_err file, the given
+  // instruction address 'start' points to the instruction's virtual address
+  // which is not equal to the address where the instruction is located.
+  // Therefore, we will either crash or decode garbage.
+  if (is_decode_error_file()) {
+    return here;
+  }
+
+  //---<  Decode some well-known "instructions"  >---
+
+  address  next;
+  uint16_t instruction_2bytes = *(uint16_t*)here;
+
+  if (Assembler::is_z_nop((long)instruction_2bytes)) {
+#if 1
+    st->print("nop     ");  // fill up to operand column, leads to better code comment alignment
+    next = here + 2;
+#else
+    // Compact disassembler output. Does not work the easy way.
+    // Currently unusable, search does not terminate, risk of crash.
+    // TODO: rework required.
+    // Terminate search loop when reaching CodeEntryAlignment-aligned offset
+    // or, at the latest, when reaching the next page boundary.
+    int n_nops = 0;
+    while(is_same_page(here, here+2*n_nops) && Assembler::is_z_nop((long)instruction_2bytes)) {
+      n_nops++;
+      instruction_2bytes   = *(uint16_t*)(here+2*n_nops);
+    }
+    if (n_nops <= 4) { // do not group few subsequent nops
+      st->print("nop     ");  // fill up to operand column, leads to better code comment alignment
+      next = here + 2;
+    } else {
+      st->print("nop     count=%d", n_nops);
+      next = here + 2*n_nops;
+    }
+#endif
+  } else if (Assembler::is_z_sync((long)instruction_2bytes)) {
+    // Specific names. Make use of lightweight sync.
+    st->print("sync   ");
+    if (Assembler::is_z_sync_full((long)instruction_2bytes) ) st->print("heavyweight");
+    if (Assembler::is_z_sync_light((long)instruction_2bytes)) st->print("lightweight");
+    next = here + 2;
+  } else if (instruction_2bytes == 0x0000) {
+#if 1
+    st->print("illtrap .nodata");
+    next = here + 2;
+#else
+    // Compact disassembler output. Does not work the easy way.
+    // Currently unusable, search does not terminate, risk of crash.
+    // TODO: rework required.
+    // Terminate search loop when reaching CodeEntryAlignment-aligned offset
+    // or, at the latest, when reaching the next page boundary.
+    int n_traps = 0;
+    while(is_same_page(here, here+2*n_nops) && (instruction_2bytes == 0x0000)) {
+      n_traps++;
+      instruction_2bytes   = *(uint16_t*)(here+2*n_traps);
+    }
+    if (n_traps <= 4) { // do not group few subsequent illtraps
+      st->print("illtrap .nodata");
+      next = here + 2;
+    } else {
+      st->print("illtrap .nodata count=%d", n_traps);
+      next = here + 2*n_traps;
+    }
+#endif
+  } else if ((instruction_2bytes & 0xff00) == 0x0000) {
+    st->print("illtrap .data 0x%2.2x", instruction_2bytes & 0x00ff);
+    next = here + 2;
+  } else {
+     next = here;
+  }
+  return next;
+}
+
+// Count the instructions contained in the range [begin..end).
+// The range must exactly contain the instructions, i.e.
+//  - the first instruction starts @begin
+//  - the last instruction ends @(end-1)
+// The caller has to make sure that the given range is readable.
+// This function performs no safety checks!
+// Return value:
+//  - The number of instructions, if there was exact containment.
+//  - If there is no exact containment, a negative value is returned.
+//    Its absolute value is the number of instructions from begin to end,
+//    where the last instruction counted runs over the range end.
+//  - 0 (zero) is returned if there was a parameter error
+//    (inverted range, bad starting point).
+int Disassembler::count_instr(address begin, address end) {
+  if (end < begin+2) return 0; // no instructions in range
+  if (!Disassembler::is_valid_opcode_at(begin)) return 0; // bad starting point
+
+  address p = begin;
+  int     n = 0;
+  while(p < end) {
+    p += Assembler::instr_len(p);
+    n++;
+  }
+  return (p == end) ? n : -n;
+}
+
+// Find preceding instruction.
+//
+// Starting at the passed location, the n-th preceding (towards lower addresses)
+// instruction is searched. With variable length instructions, there may be
+// more than one solution, or no solution at all (if the passed location
+// does not point to the start of an instruction or if the storage area
+// does not contain instructions at all).
+// instructions - has the passed location as n-th successor.
+//  - If multiple such locations exist between (here-n*instr_maxlen()) and here,
+//    the most distant location is selected.
+//  - If no such location exists, NULL is returned. The caller should then
+//    terminate its search and react properly.
+// Must be placed here in disassembler_s390.cpp. It does not compile
+// in the header. There the class 'Assembler' is not available.
+address Disassembler::find_prev_instr(address here, int n_instr) {
+  if (!os::is_readable_pointer(here)) return NULL;    // obviously a bad location to decode
+
+  // Find most distant possible starting point.
+  // Narrow down because we don't want to SEGV while printing.
+  address start = here - n_instr*Assembler::instr_maxlen(); // starting point can't be further away.
+  while ((start < here) && !os::is_readable_range(start, here)) {
+    start = align_down(start, os::min_page_size()) + os::min_page_size();
+  }
+  if (start >= here) {
+    // Strange. Can only happen with here on page boundary.
+    return NULL;
+  }
+
+  //---<  Find a starting point  >---
+  int i_count = 0;
+  while ((start < here) && ((i_count = count_instr(start, here)) <= 0)) start += 2;
+  if (i_count == 0) return NULL; // There is something seriously wrong
+
+  //---<  Narrow down distance (estimate was too large)  >---
+  while(i_count-- > n_instr) {
+    start   += Assembler::instr_len(start);
+  }
+  assert(n_instr >= count_instr(start, here), "just checking");
+  return start;
+}
+
+
+// Print annotations (value of loaded constant)
+void Disassembler::annotate(address here, outputStream* st) {
+  // Currently, annotation doesn't work when decoding error files.
+  // When decoding an instruction from a hs_err file, the given
+  // instruction address 'start' points to the instruction's virtual address
+  // which is not equal to the address where the instruction is located.
+  // Therefore, we will either crash or decode garbage.
+  if (is_decode_error_file()) {
+    return;
+  }
+
+  if (MacroAssembler::is_load_const(here)) {
+    long      value = MacroAssembler::get_const(here);
+    const int tsize = 8;
+
+    st->fill_to(60);
+    st->print(";const %p | %ld | %23.15e", (void *)value, value, (double)value);
+  }
+}
--- a/src/hotspot/cpu/s390/disassembler_s390.hpp	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/cpu/s390/disassembler_s390.hpp	Thu May 23 11:07:37 2019 +0100
@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2016 SAP SE. All rights reserved.
+ * Copyright (c) 2016, 2019 SAP SE. 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
@@ -27,11 +27,36 @@
 #define CPU_S390_DISASSEMBLER_S390_HPP
 
   static int pd_instruction_alignment() {
-    return 1;
+    return 2;
   }
 
   static const char* pd_cpu_opts() {
-    return "zarch";
+    return "s390";
   }
 
+  static bool valid_opcodes[256];
+  static bool is_valid_opcode_at(address here);
+
+  // Find preceding instruction.
+  //
+  // Starting at the passed location, the n-th preceding (towards lower addresses)
+  // location is searched, the contents of which - if interpreted as
+  // instructions - has the passed location as n-th successor.
+  //  - If multiple such locations exist between (here-n*instr_maxlen()) and here,
+  //    the most distant location is selected.
+  //  - If no such location exists, NULL is returned. The caller should then
+  //    terminate its search and react properly.
+  static address find_prev_instr(address here, int n_instr);
+  static int     count_instr(address begin, address end);
+
+  // special-case instruction decoding.
+  // There may be cases where the binutils disassembler doesn't do
+  // the perfect job. In those cases, decode_instruction0 may kick in
+  // and do it right.
+  // If nothing had to be done, just return "here", otherwise return "here + instr_len(here)"
+  static address decode_instruction0(address here, outputStream* st, address virtual_begin = NULL);
+
+  // platform-specific instruction annotations (like value of loaded constants)
+  static void annotate(address pc, outputStream* st);
+
 #endif // CPU_S390_DISASSEMBLER_S390_HPP
--- a/src/hotspot/cpu/s390/s390.ad	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/cpu/s390/s390.ad	Thu May 23 11:07:37 2019 +0100
@@ -1,6 +1,6 @@
 //
-// Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
-// Copyright (c) 2017, SAP SE. All rights reserved.
+// Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved.
+// Copyright (c) 2017, 2019 SAP SE. 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
@@ -1388,7 +1388,6 @@
     __ z_br(R1_ic_miss_stub_addr);
     __ bind(valid);
   }
-
 }
 
 uint MachUEPNode::size(PhaseRegAlloc *ra_) const {
@@ -4318,7 +4317,7 @@
   match(Set dst src);
   ins_cost(DEFAULT_COST);
   size(6);
-  format %{ "LGFI     $dst,$src\t # (int)" %}
+  format %{ "LGFI    $dst,$src\t # (int)" %}
   ins_encode %{ __ z_lgfi($dst$$Register, $src$$constant); %}  // Sign-extend to 64 bit, it's at no cost.
   ins_pipe(pipe_class_dummy);
 %}
@@ -4327,7 +4326,7 @@
   match(Set dst src);
   ins_cost(DEFAULT_COST_LOW);
   size(4);
-  format %{ "LGHI     $dst,$src\t # (int)" %}
+  format %{ "LGHI    $dst,$src\t # (int)" %}
   ins_encode %{ __ z_lghi($dst$$Register, $src$$constant); %}  // Sign-extend to 64 bit, it's at no cost.
   ins_pipe(pipe_class_dummy);
 %}
@@ -4723,7 +4722,7 @@
   match(Set dst (LoadN mem));
   ins_cost(MEMORY_REF_COST);
   size(Z_DISP3_SIZE);
-  format %{ "LoadN  $dst,$mem\t# (cOop)" %}
+  format %{ "LoadN   $dst,$mem\t # (cOop)" %}
   opcode(LLGF_ZOPC, LLGF_ZOPC);
   ins_encode(z_form_rt_mem_opt(dst, mem));
   ins_pipe(pipe_class_dummy);
@@ -4734,7 +4733,7 @@
   match(Set dst (LoadNKlass mem));
   ins_cost(MEMORY_REF_COST);
   size(Z_DISP3_SIZE);
-  format %{ "LoadNKlass $dst,$mem\t# (klass cOop)" %}
+  format %{ "LoadNKlass $dst,$mem\t # (klass cOop)" %}
   opcode(LLGF_ZOPC, LLGF_ZOPC);
   ins_encode(z_form_rt_mem_opt(dst, mem));
   ins_pipe(pipe_class_dummy);
@@ -4787,7 +4786,7 @@
   predicate(false && (CompressedOops::base()==NULL)&&(CompressedOops::shift()==0));
   ins_cost(MEMORY_REF_COST);
   size(Z_DISP3_SIZE);
-  format %{ "DecodeLoadN  $dst,$mem\t# (cOop Load+Decode)" %}
+  format %{ "DecodeLoadN  $dst,$mem\t # (cOop Load+Decode)" %}
   opcode(LLGF_ZOPC, LLGF_ZOPC);
   ins_encode(z_form_rt_mem_opt(dst, mem));
   ins_pipe(pipe_class_dummy);
@@ -4798,7 +4797,7 @@
   predicate(false && (CompressedKlassPointers::base()==NULL)&&(CompressedKlassPointers::shift()==0));
   ins_cost(MEMORY_REF_COST);
   size(Z_DISP3_SIZE);
-  format %{ "DecodeLoadNKlass  $dst,$mem\t# (load/decode NKlass)" %}
+  format %{ "DecodeLoadNKlass  $dst,$mem\t # (load/decode NKlass)" %}
   opcode(LLGF_ZOPC, LLGF_ZOPC);
   ins_encode(z_form_rt_mem_opt(dst, mem));
   ins_pipe(pipe_class_dummy);
@@ -4826,7 +4825,7 @@
   predicate(CompressedOops::base() == NULL || !ExpandLoadingBaseDecode);
   ins_cost(MEMORY_REF_COST+3 * DEFAULT_COST + BRANCH_COST);
   // TODO: s390 port size(VARIABLE_SIZE);
-  format %{ "decodeN  $dst,$src\t# (decode cOop)" %}
+  format %{ "decodeN  $dst,$src\t # (decode cOop)" %}
   ins_encode %{  __ oop_decoder($dst$$Register, $src$$Register, true); %}
   ins_pipe(pipe_class_dummy);
 %}
@@ -4850,7 +4849,7 @@
             (CompressedOops::base()== NULL || !ExpandLoadingBaseDecode_NN));
   ins_cost(MEMORY_REF_COST+2 * DEFAULT_COST);
   // TODO: s390 port size(VARIABLE_SIZE);
-  format %{ "decodeN  $dst,$src\t# (decode cOop NN)" %}
+  format %{ "decodeN  $dst,$src\t # (decode cOop NN)" %}
   ins_encode %{ __ oop_decoder($dst$$Register, $src$$Register, false); %}
   ins_pipe(pipe_class_dummy);
 %}
@@ -4873,7 +4872,7 @@
     effect(KILL cr);
     predicate(false);
     // TODO: s390 port size(VARIABLE_SIZE);
-    format %{ "decodeN  $dst = ($src == 0) ? NULL : ($src << 3) + $base + pow2_offset\t# (decode cOop)" %}
+    format %{ "decodeN  $dst = ($src == 0) ? NULL : ($src << 3) + $base + pow2_offset\t # (decode cOop)" %}
     ins_encode %{
       __ oop_decoder($dst$$Register, $src$$Register, true, $base$$Register,
                      (jlong)MacroAssembler::get_oop_base_pow2_offset((uint64_t)(intptr_t)CompressedOops::base()));
@@ -4887,7 +4886,7 @@
     effect(KILL cr);
     predicate(false);
     // TODO: s390 port size(VARIABLE_SIZE);
-    format %{ "decodeN  $dst = ($src << 3) + $base + pow2_offset\t# (decode cOop)" %}
+    format %{ "decodeN  $dst = ($src << 3) + $base + pow2_offset\t # (decode cOop)" %}
     ins_encode %{
       __ oop_decoder($dst$$Register, $src$$Register, false, $base$$Register,
                      (jlong)MacroAssembler::get_oop_base_pow2_offset((uint64_t)(intptr_t)CompressedOops::base()));
@@ -4937,7 +4936,7 @@
              !ExpandLoadingBaseEncode));
   ins_cost(MEMORY_REF_COST+3 * DEFAULT_COST);
   // TODO: s390 port size(VARIABLE_SIZE);
-  format %{ "encodeP  $dst,$src\t# (encode cOop)" %}
+  format %{ "encodeP  $dst,$src\t # (encode cOop)" %}
   ins_encode %{ __ oop_encoder($dst$$Register, $src$$Register, true, Z_R1_scratch, -1, all_outs_are_Stores(this)); %}
   ins_pipe(pipe_class_dummy);
 %}
@@ -4960,7 +4959,7 @@
              !ExpandLoadingBaseEncode_NN));
   ins_cost(MEMORY_REF_COST+3 * DEFAULT_COST);
   // TODO: s390 port size(VARIABLE_SIZE);
-  format %{ "encodeP  $dst,$src\t# (encode cOop)" %}
+  format %{ "encodeP  $dst,$src\t # (encode cOop)" %}
   ins_encode %{ __ oop_encoder($dst$$Register, $src$$Register, false, Z_R1_scratch, -1, all_outs_are_Stores(this)); %}
   ins_pipe(pipe_class_dummy);
 %}
@@ -4972,7 +4971,7 @@
     predicate(false);
     ins_cost(MEMORY_REF_COST+2 * DEFAULT_COST);
     // TODO: s390 port size(VARIABLE_SIZE);
-    format %{ "encodeP  $dst = ($src>>3) +$base + pow2_offset\t# (encode cOop)" %}
+    format %{ "encodeP  $dst = ($src>>3) +$base + pow2_offset\t # (encode cOop)" %}
     ins_encode %{
       jlong offset = -(jlong)MacroAssembler::get_oop_base_pow2_offset
         (((uint64_t)(intptr_t)CompressedOops::base()) >> CompressedOops::shift());
@@ -4988,7 +4987,7 @@
     predicate(false);
     ins_cost(MEMORY_REF_COST+2 * DEFAULT_COST);
     // TODO: s390 port size(VARIABLE_SIZE);
-    format %{ "encodeP  $dst = ($src>>3) +$base + $pow2_offset\t# (encode cOop)" %}
+    format %{ "encodeP  $dst = ($src>>3) +$base + $pow2_offset\t # (encode cOop)" %}
     ins_encode %{ __ oop_encoder($dst$$Register, $src$$Register, false, $base$$Register, $pow2_offset$$constant); %}
     ins_pipe(pipe_class_dummy);
   %}
@@ -5041,7 +5040,7 @@
   match(Set mem (StoreN mem src));
   ins_cost(MEMORY_REF_COST);
   size(Z_DISP_SIZE);
-  format %{ "ST      $src,$mem\t# (cOop)" %}
+  format %{ "ST      $src,$mem\t # (cOop)" %}
   opcode(STY_ZOPC, ST_ZOPC);
   ins_encode(z_form_rt_mem_opt(src, mem));
   ins_pipe(pipe_class_dummy);
@@ -5052,7 +5051,7 @@
   match(Set mem (StoreNKlass mem src));
   ins_cost(MEMORY_REF_COST);
   size(Z_DISP_SIZE);
-  format %{ "ST      $src,$mem\t# (cKlass)" %}
+  format %{ "ST      $src,$mem\t # (cKlass)" %}
   opcode(STY_ZOPC, ST_ZOPC);
   ins_encode(z_form_rt_mem_opt(src, mem));
   ins_pipe(pipe_class_dummy);
@@ -5064,7 +5063,7 @@
   match(Set cr (CmpN src1 src2));
   ins_cost(DEFAULT_COST);
   size(2);
-  format %{ "CLR     $src1,$src2\t# (cOop)" %}
+  format %{ "CLR     $src1,$src2\t # (cOop)" %}
   opcode(CLR_ZOPC);
   ins_encode(z_rrform(src1, src2));
   ins_pipe(pipe_class_dummy);
@@ -5074,7 +5073,7 @@
   match(Set cr (CmpN src1 src2));
   ins_cost(DEFAULT_COST);
   size(6);
-  format %{ "CLFI    $src1,$src2\t# (cOop) compare immediate narrow" %}
+  format %{ "CLFI    $src1,$src2\t # (cOop) compare immediate narrow" %}
   ins_encode %{
     AddressLiteral cOop = __ constant_oop_address((jobject)$src2$$constant);
     __ relocate(cOop.rspec(), 1);
@@ -5087,7 +5086,7 @@
   match(Set cr (CmpN src1 src2));
   ins_cost(DEFAULT_COST);
   size(6);
-  format %{ "CLFI    $src1,$src2\t# (NKlass) compare immediate narrow" %}
+  format %{ "CLFI    $src1,$src2\t # (NKlass) compare immediate narrow" %}
   ins_encode %{
     AddressLiteral NKlass = __ constant_metadata_address((Metadata*)$src2$$constant);
     __ relocate(NKlass.rspec(), 1);
@@ -5100,7 +5099,7 @@
   match(Set cr (CmpN src1 src2));
   ins_cost(DEFAULT_COST);
   size(2);
-  format %{ "LTR     $src1,$src2\t# (cOop) LTR because comparing against zero" %}
+  format %{ "LTR     $src1,$src2\t # (cOop) LTR because comparing against zero" %}
   opcode(LTR_ZOPC);
   ins_encode(z_rrform(src1, src1));
   ins_pipe(pipe_class_dummy);
@@ -6795,7 +6794,7 @@
   effect(KILL cr); // R1 is killed, too.
   ins_cost(3 * DEFAULT_COST);
   size(14);
-  format %{ "SLL     $dst,$src,[$nbits] & 31\t# use RISC-like SLLG also for int" %}
+  format %{ "SLL     $dst,$src,[$nbits] & 31\t # use RISC-like SLLG also for int" %}
   ins_encode %{
     __ z_lgr(Z_R1_scratch, $nbits$$Register);
     __ z_nill(Z_R1_scratch, BitsPerJavaInteger-1);
@@ -6809,7 +6808,7 @@
 instruct sllI_reg_imm(iRegI dst, iRegI src, immI nbits) %{
   match(Set dst (LShiftI src nbits));
   size(6);
-  format %{ "SLL     $dst,$src,$nbits\t# use RISC-like SLLG also for int" %}
+  format %{ "SLL     $dst,$src,$nbits\t # use RISC-like SLLG also for int" %}
   ins_encode %{
     int Nbit = $nbits$$constant;
     assert((Nbit & (BitsPerJavaInteger - 1)) == Nbit, "Check shift mask in ideal graph");
@@ -7125,7 +7124,7 @@
 instruct overflowNegI_rReg(flagsReg cr, immI_0 zero, iRegI op2) %{
   match(Set cr (OverflowSubI zero op2));
   effect(DEF cr, USE op2);
-  format %{ "NEG    $op2\t# overflow check int" %}
+  format %{ "NEG    $op2\t # overflow check int" %}
   ins_encode %{
     __ clear_reg(Z_R0_scratch, false, false);
     __ z_sr(Z_R0_scratch, $op2$$Register);
@@ -7136,7 +7135,7 @@
 instruct overflowNegL_rReg(flagsReg cr, immL_0 zero, iRegL op2) %{
   match(Set cr (OverflowSubL zero op2));
   effect(DEF cr, USE op2);
-  format %{ "NEGG    $op2\t# overflow check long" %}
+  format %{ "NEGG    $op2\t # overflow check long" %}
   ins_encode %{
     __ clear_reg(Z_R0_scratch, true, false);
     __ z_sgr(Z_R0_scratch, $op2$$Register);
@@ -9191,7 +9190,7 @@
   effect(USE lbl);
   ins_cost(BRANCH_COST);
   size(4);
-  format %{ "branch_con_short,$cmp   $cr, $lbl" %}
+  format %{ "branch_con_short,$cmp   $lbl" %}
   ins_encode(z_enc_branch_con_short(cmp, lbl));
   ins_pipe(pipe_class_dummy);
   // If set to 1 this indicates that the current instruction is a
@@ -9213,7 +9212,7 @@
   // Make more expensive to prefer compare_and_branch over separate instructions.
   ins_cost(2 * BRANCH_COST);
   size(6);
-  format %{ "branch_con_far,$cmp   $cr, $lbl" %}
+  format %{ "branch_con_far,$cmp   $lbl" %}
   ins_encode(z_enc_branch_con_far(cmp, lbl));
   ins_pipe(pipe_class_dummy);
   // This is not a short variant of a branch, but the long variant..
@@ -9782,7 +9781,7 @@
   match(TailCall jump_target method_oop);
   ins_cost(CALL_COST);
   size(2);
-  format %{ "Jmp     $jump_target\t# $method_oop holds method oop" %}
+  format %{ "Jmp     $jump_target\t # $method_oop holds method oop" %}
   ins_encode %{ __ z_br($jump_target$$Register); %}
   ins_pipe(pipe_class_dummy);
 %}
@@ -10790,7 +10789,7 @@
   predicate(UseByteReverseInstruction);  // See Matcher::match_rule_supported
   ins_cost(DEFAULT_COST);
   size(4);
-  format %{ "LRVR    $dst,$src\t# byte reverse int" %}
+  format %{ "LRVR    $dst,$src\t # byte reverse int" %}
   opcode(LRVR_ZOPC);
   ins_encode(z_rreform(dst, src));
   ins_pipe(pipe_class_dummy);
@@ -10801,7 +10800,7 @@
   predicate(UseByteReverseInstruction);  // See Matcher::match_rule_supported
   ins_cost(DEFAULT_COST);
   // TODO: s390 port size(FIXED_SIZE);
-  format %{ "LRVGR   $dst,$src\t# byte reverse long" %}
+  format %{ "LRVGR   $dst,$src\t # byte reverse long" %}
   opcode(LRVGR_ZOPC);
   ins_encode(z_rreform(dst, src));
   ins_pipe(pipe_class_dummy);
@@ -10821,8 +10820,8 @@
   effect(KILL tmp, KILL cr);
   ins_cost(3 * DEFAULT_COST);
   size(14);
-  format %{ "SLLG    $dst,$src,32\t# no need to always count 32 zeroes first\n\t"
-            "IILH    $dst,0x8000 \t# insert \"stop bit\" to force result 32 for zero src.\n\t"
+  format %{ "SLLG    $dst,$src,32\t # no need to always count 32 zeroes first\n\t"
+            "IILH    $dst,0x8000 \t # insert \"stop bit\" to force result 32 for zero src.\n\t"
             "FLOGR   $dst,$dst"
          %}
   ins_encode %{
@@ -10859,7 +10858,7 @@
   effect(KILL tmp, KILL cr);
   ins_cost(DEFAULT_COST);
   size(4);
-  format %{ "FLOGR   $dst,$src \t# count leading zeros (long)\n\t" %}
+  format %{ "FLOGR   $dst,$src \t # count leading zeros (long)\n\t" %}
   ins_encode %{ __ z_flogr($dst$$Register, $src$$Register); %}
   ins_pipe(pipe_class_dummy);
 %}
@@ -10884,14 +10883,14 @@
   effect(TEMP_DEF dst, TEMP tmp, KILL cr);
   ins_cost(8 * DEFAULT_COST);
   // TODO: s390 port size(FIXED_SIZE);  // Emitted code depends on PreferLAoverADD being on/off.
-  format %{ "LLGFR   $dst,$src  \t# clear upper 32 bits (we are dealing with int)\n\t"
-            "LCGFR   $tmp,$src  \t# load 2's complement (32->64 bit)\n\t"
-            "AGHI    $dst,-1    \t# tmp1 = src-1\n\t"
-            "AGHI    $tmp,-1    \t# tmp2 = -src-1 = ~src\n\t"
-            "NGR     $dst,$tmp  \t# tmp3 = tmp1&tmp2\n\t"
-            "FLOGR   $dst,$dst  \t# count trailing zeros (int)\n\t"
-            "AHI     $dst,-64   \t# tmp4 = 64-(trailing zeroes)-64\n\t"
-            "LCR     $dst,$dst  \t# res = -tmp4"
+  format %{ "LLGFR   $dst,$src  \t # clear upper 32 bits (we are dealing with int)\n\t"
+            "LCGFR   $tmp,$src  \t # load 2's complement (32->64 bit)\n\t"
+            "AGHI    $dst,-1    \t # tmp1 = src-1\n\t"
+            "AGHI    $tmp,-1    \t # tmp2 = -src-1 = ~src\n\t"
+            "NGR     $dst,$tmp  \t # tmp3 = tmp1&tmp2\n\t"
+            "FLOGR   $dst,$dst  \t # count trailing zeros (int)\n\t"
+            "AHI     $dst,-64   \t # tmp4 = 64-(trailing zeroes)-64\n\t"
+            "LCR     $dst,$dst  \t # res = -tmp4"
          %}
   ins_encode %{
     Register Rdst = $dst$$Register;
@@ -10937,12 +10936,12 @@
   effect(TEMP_DEF dst, KILL tmp, KILL cr);
   ins_cost(8 * DEFAULT_COST);
   // TODO: s390 port size(FIXED_SIZE);  // Emitted code depends on PreferLAoverADD being on/off.
-  format %{ "LCGR    $dst,$src  \t# preserve src\n\t"
-            "NGR     $dst,$src  \t#"
-            "AGHI    $dst,-1    \t# tmp1 = src-1\n\t"
-            "FLOGR   $dst,$dst  \t# count trailing zeros (long), kill $tmp\n\t"
-            "AHI     $dst,-64   \t# tmp4 = 64-(trailing zeroes)-64\n\t"
-            "LCR     $dst,$dst  \t#"
+  format %{ "LCGR    $dst,$src  \t # preserve src\n\t"
+            "NGR     $dst,$src  \t #\n\t"
+            "AGHI    $dst,-1    \t # tmp1 = src-1\n\t"
+            "FLOGR   $dst,$dst  \t # count trailing zeros (long), kill $tmp\n\t"
+            "AHI     $dst,-64   \t # tmp4 = 64-(trailing zeroes)-64\n\t"
+            "LCR     $dst,$dst  \t #"
          %}
   ins_encode %{
     Register Rdst = $dst$$Register;
@@ -10969,7 +10968,7 @@
   predicate(UsePopCountInstruction && VM_Version::has_PopCount());
   ins_cost(DEFAULT_COST);
   size(24);
-  format %{ "POPCNT  $dst,$src\t# pop count int" %}
+  format %{ "POPCNT  $dst,$src\t # pop count int" %}
   ins_encode %{
     Register Rdst = $dst$$Register;
     Register Rsrc = $src$$Register;
@@ -10996,7 +10995,7 @@
   predicate(UsePopCountInstruction && VM_Version::has_PopCount());
   ins_cost(DEFAULT_COST);
   // TODO: s390 port size(FIXED_SIZE);
-  format %{ "POPCNT  $dst,$src\t# pop count long" %}
+  format %{ "POPCNT  $dst,$src\t # pop count long" %}
   ins_encode %{
     Register Rdst = $dst$$Register;
     Register Rsrc = $src$$Register;
--- a/src/hotspot/cpu/s390/vm_version_s390.cpp	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/cpu/s390/vm_version_s390.cpp	Thu May 23 11:07:37 2019 +0100
@@ -804,6 +804,8 @@
   address code_end = a->pc();
   a->flush();
 
+  cbuf.insts()->set_end(code_end);
+
   // Print the detection code.
   bool printVerbose = Verbose || PrintAssembly || PrintStubCode;
   if (printVerbose) {
@@ -812,8 +814,8 @@
     tty->print_cr("Stub length is %ld bytes, codebuffer reserves %d bytes, %ld bytes spare.",
                   code_end-code, cbuf_size, cbuf_size-(code_end-code));
 
-    // Use existing decode function. This enables the [Code] format which is needed to DecodeErrorFile.
-    Disassembler::decode((u_char*)code, (u_char*)code_end, tty);
+    // Use existing decode function. This enables the [MachCode] format which is needed to DecodeErrorFile.
+    Disassembler::decode(&cbuf, code, code_end, tty);
   }
 
   // Prepare for detection code execution and clear work buffer.
--- a/src/hotspot/cpu/sparc/assembler_sparc.hpp	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/cpu/sparc/assembler_sparc.hpp	Thu May 23 11:07:37 2019 +0100
@@ -335,6 +335,14 @@
     Lookaside  = 1 << 4
   };
 
+  //---<  calculate length of instruction  >---
+  // With SPARC being a RISC architecture, this always is BytesPerInstWord
+  // instruction must start at passed address
+  static unsigned int instr_len(unsigned char *instr) { return BytesPerInstWord; }
+
+  //---<  longest instructions  >---
+  static unsigned int instr_maxlen() { return BytesPerInstWord; }
+
   static bool is_in_wdisp_range(address a, address b, int nbits) {
     intptr_t d = intptr_t(b) - intptr_t(a);
     return is_simm(d, nbits + 2);
--- a/src/hotspot/cpu/sparc/c2_globals_sparc.hpp	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/cpu/sparc/c2_globals_sparc.hpp	Thu May 23 11:07:37 2019 +0100
@@ -80,7 +80,7 @@
 
 // Ergonomics related flags
 define_pd_global(uint64_t,MaxRAM,                    128ULL*G);
-define_pd_global(uintx, CodeCacheMinBlockLength,     4);
+define_pd_global(uintx, CodeCacheMinBlockLength,     6);
 define_pd_global(uintx, CodeCacheMinimumUseSpace,    400*K);
 
 define_pd_global(bool,  TrapBasedRangeChecks,        false); // Not needed on sparc.
--- a/src/hotspot/cpu/sparc/disassembler_sparc.hpp	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/cpu/sparc/disassembler_sparc.hpp	Thu May 23 11:07:37 2019 +0100
@@ -33,4 +33,24 @@
     return "v9only";
   }
 
+  // Returns address of n-th instruction preceding addr,
+  // NULL if no preceding instruction can be found.
+  // With SPARC being a RISC architecture, this always is BytesPerInstWord
+  // It might be beneficial to check "is_readable" as we do on ppc and s390.
+  static address find_prev_instr(address addr, int n_instr) {
+    return addr - BytesPerInstWord*n_instr;
+  }
+
+  // special-case instruction decoding.
+  // There may be cases where the binutils disassembler doesn't do
+  // the perfect job. In those cases, decode_instruction0 may kick in
+  // and do it right.
+  // If nothing had to be done, just return "here", otherwise return "here + instr_len(here)"
+  static address decode_instruction0(address here, outputStream* st, address virtual_begin = NULL) {
+    return here;
+  }
+
+  // platform-specific instruction annotations (like value of loaded constants)
+  static void annotate(address pc, outputStream* st) { };
+
 #endif // CPU_SPARC_DISASSEMBLER_SPARC_HPP
--- a/src/hotspot/cpu/sparc/sparc.ad	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/cpu/sparc/sparc.ad	Thu May 23 11:07:37 2019 +0100
@@ -1,5 +1,5 @@
 //
-// Copyright (c) 1998, 2017, Oracle and/or its affiliates. All rights reserved.
+// Copyright (c) 1998, 2019, 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
@@ -1295,7 +1295,8 @@
 #ifndef PRODUCT
 ATTRIBUTE_PRINTF(2, 3)
 static void print_helper(outputStream* st, const char* format, ...) {
-  if (st->position() > 0) {
+  const int tab_size = 8;
+  if (st->position() > tab_size) {
     st->cr();
     st->sp();
   }
--- a/src/hotspot/cpu/sparc/vm_version_sparc.cpp	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/cpu/sparc/vm_version_sparc.cpp	Thu May 23 11:07:37 2019 +0100
@@ -139,12 +139,12 @@
     if (FLAG_IS_DEFAULT(AllocatePrefetchLines)) {
       const int ap_lns = AllocatePrefetchLines;
       const int ap_inc = cache_line_size < 64 ? ap_lns : (ap_lns + 1) / 2;
-      FLAG_SET_ERGO(intx, AllocatePrefetchLines, ap_lns + ap_inc);
+      FLAG_SET_ERGO(AllocatePrefetchLines, ap_lns + ap_inc);
     }
     if (FLAG_IS_DEFAULT(AllocateInstancePrefetchLines)) {
       const int ip_lns = AllocateInstancePrefetchLines;
       const int ip_inc = cache_line_size < 64 ? ip_lns : (ip_lns + 1) / 2;
-      FLAG_SET_ERGO(intx, AllocateInstancePrefetchLines, ip_lns + ip_inc);
+      FLAG_SET_ERGO(AllocateInstancePrefetchLines, ip_lns + ip_inc);
     }
   }
 #endif /* COMPILER2 */
--- a/src/hotspot/cpu/x86/assembler_x86.hpp	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/cpu/x86/assembler_x86.hpp	Thu May 23 11:07:37 2019 +0100
@@ -630,6 +630,17 @@
     _true = 7
   };
 
+  //---<  calculate length of instruction  >---
+  // As instruction size can't be found out easily on x86/x64,
+  // we just use '4' for len and maxlen.
+  // instruction must start at passed address
+  static unsigned int instr_len(unsigned char *instr) { return 4; }
+
+  //---<  longest instructions  >---
+  // Max instruction length is not specified in architecture documentation.
+  // We could use a "safe enough" estimate (15), but just default to
+  // instruction length guess from above.
+  static unsigned int instr_maxlen() { return 4; }
 
   // NOTE: The general philopsophy of the declarations here is that 64bit versions
   // of instructions are freely declared without the need for wrapping them an ifdef.
--- a/src/hotspot/cpu/x86/c2_globals_x86.hpp	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/cpu/x86/c2_globals_x86.hpp	Thu May 23 11:07:37 2019 +0100
@@ -88,7 +88,7 @@
 define_pd_global(uintx, NonProfiledCodeHeapSize,     21*M);
 define_pd_global(uintx, ProfiledCodeHeapSize,        22*M);
 define_pd_global(uintx, NonNMethodCodeHeapSize,      5*M );
-define_pd_global(uintx, CodeCacheMinBlockLength,     4);
+define_pd_global(uintx, CodeCacheMinBlockLength,     6);
 define_pd_global(uintx, CodeCacheMinimumUseSpace,    400*K);
 
 define_pd_global(bool,  TrapBasedRangeChecks,        false); // Not needed on x86.
--- a/src/hotspot/cpu/x86/disassembler_x86.hpp	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/cpu/x86/disassembler_x86.hpp	Thu May 23 11:07:37 2019 +0100
@@ -33,4 +33,25 @@
     return "";
   }
 
+  // Returns address of n-th instruction preceding addr,
+  // NULL if no preceding instruction can be found.
+  // On CISC architectures, it is difficult to impossible to step
+  // backwards in the instruction stream. Therefore just return NULL.
+  // It might be beneficial to check "is_readable" as we do on ppc and s390.
+  static address find_prev_instr(address addr, int n_instr) {
+    return NULL;
+  }
+
+  // special-case instruction decoding.
+  // There may be cases where the binutils disassembler doesn't do
+  // the perfect job. In those cases, decode_instruction0 may kick in
+  // and do it right.
+  // If nothing had to be done, just return "here", otherwise return "here + instr_len(here)"
+  static address decode_instruction0(address here, outputStream* st, address virtual_begin = NULL) {
+    return here;
+  }
+
+  // platform-specific instruction annotations (like value of loaded constants)
+  static void annotate(address pc, outputStream* st) { };
+
 #endif // CPU_X86_DISASSEMBLER_X86_HPP
--- a/src/hotspot/cpu/x86/rdtsc_x86.cpp	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/cpu/x86/rdtsc_x86.cpp	Thu May 23 11:07:37 2019 +0100
@@ -145,7 +145,7 @@
 static bool ergonomics() {
   const bool invtsc_support = Rdtsc::is_supported();
   if (FLAG_IS_DEFAULT(UseFastUnorderedTimeStamps) && invtsc_support) {
-    FLAG_SET_ERGO(bool, UseFastUnorderedTimeStamps, true);
+    FLAG_SET_ERGO(UseFastUnorderedTimeStamps, true);
   }
 
   bool ft_enabled = UseFastUnorderedTimeStamps && invtsc_support;
--- a/src/hotspot/cpu/x86/x86_64.ad	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/cpu/x86/x86_64.ad	Thu May 23 11:07:37 2019 +0100
@@ -918,19 +918,19 @@
     st->print("\t");
   }
 
-  st->print_cr("popq   rbp");
+  st->print_cr("popq    rbp");
   if (do_polling() && C->is_method_compilation()) {
     st->print("\t");
     if (SafepointMechanism::uses_thread_local_poll()) {
-      st->print_cr("movq   rscratch1, poll_offset[r15_thread] #polling_page_address\n\t"
-                   "testl  rax, [rscratch1]\t"
+      st->print_cr("movq    rscratch1, poll_offset[r15_thread] #polling_page_address\n\t"
+                   "testl   rax, [rscratch1]\t"
                    "# Safepoint: poll for GC");
     } else if (Assembler::is_polling_page_far()) {
-      st->print_cr("movq   rscratch1, #polling_page_address\n\t"
-                   "testl  rax, [rscratch1]\t"
+      st->print_cr("movq    rscratch1, #polling_page_address\n\t"
+                   "testl   rax, [rscratch1]\t"
                    "# Safepoint: poll for GC");
     } else {
-      st->print_cr("testl  rax, [rip + #offset_to_poll_page]\t"
+      st->print_cr("testl   rax, [rip + #offset_to_poll_page]\t"
                    "# Safepoint: poll for GC");
     }
   }
@@ -10303,10 +10303,10 @@
   match(Set p (AddI (AndI (CmpLTMask p q) y) (SubI p q)));
   effect(KILL cr);
   ins_cost(300);
-  format %{ "subl   $p,$q\t# cadd_cmpLTMask\n\t"
-            "jge    done\n\t"
-            "addl   $p,$y\n"
-            "done:  " %}
+  format %{ "subl    $p,$q\t# cadd_cmpLTMask\n\t"
+            "jge     done\n\t"
+            "addl    $p,$y\n"
+            "done:   " %}
   ins_encode %{
     Register Rp = $p$$Register;
     Register Rq = $q$$Register;
@@ -10328,10 +10328,10 @@
 
   ins_cost(300);
 
-  format %{ "cmpl     $p, $q\t# and_cmpLTMask\n\t"
-            "jlt      done\n\t"
-            "xorl     $y, $y\n"
-            "done:  " %}
+  format %{ "cmpl    $p, $q\t# and_cmpLTMask\n\t"
+            "jlt     done\n\t"
+            "xorl    $y, $y\n"
+            "done:   " %}
   ins_encode %{
     Register Rp = $p$$Register;
     Register Rq = $q$$Register;
@@ -11888,7 +11888,7 @@
 %{
   match(Set cr (CmpU src zero));
 
-  format %{ "testl  $src, $src\t# unsigned" %}
+  format %{ "testl   $src, $src\t# unsigned" %}
   opcode(0x85);
   ins_encode(REX_reg_reg(src, src), OpcP, reg_reg(src, src));
   ins_pipe(ialu_cr_reg_imm);
@@ -12431,7 +12431,7 @@
   effect(USE labl);
 
   ins_cost(300);
-  format %{ "j$cop,u  $labl" %}
+  format %{ "j$cop,u   $labl" %}
   size(6);
   ins_encode %{
     Label* L = $labl$$label;
@@ -12445,7 +12445,7 @@
   effect(USE labl);
 
   ins_cost(200);
-  format %{ "j$cop,u  $labl" %}
+  format %{ "j$cop,u   $labl" %}
   size(6);
   ins_encode %{
     Label* L = $labl$$label;
@@ -12461,10 +12461,10 @@
   ins_cost(200);
   format %{ $$template
     if ($cop$$cmpcode == Assembler::notEqual) {
-      $$emit$$"jp,u   $labl\n\t"
+      $$emit$$"jp,u    $labl\n\t"
       $$emit$$"j$cop,u   $labl"
     } else {
-      $$emit$$"jp,u   done\n\t"
+      $$emit$$"jp,u    done\n\t"
       $$emit$$"j$cop,u   $labl\n\t"
       $$emit$$"done:"
     }
@@ -12666,10 +12666,10 @@
   ins_cost(300);
   format %{ $$template
     if ($cop$$cmpcode == Assembler::notEqual) {
-      $$emit$$"jp,u,s   $labl\n\t"
-      $$emit$$"j$cop,u,s   $labl"
+      $$emit$$"jp,u,s  $labl\n\t"
+      $$emit$$"j$cop,u,s  $labl"
     } else {
-      $$emit$$"jp,u,s   done\n\t"
+      $$emit$$"jp,u,s  done\n\t"
       $$emit$$"j$cop,u,s  $labl\n\t"
       $$emit$$"done:"
     }
@@ -12745,7 +12745,7 @@
   match(SafePoint);
   effect(KILL cr);
 
-  format %{ "testl  rax, [rip + #offset_to_poll_page]\t"
+  format %{ "testl   rax, [rip + #offset_to_poll_page]\t"
             "# Safepoint: poll for GC" %}
   ins_cost(125);
   ins_encode %{
@@ -12761,7 +12761,7 @@
   match(SafePoint poll);
   effect(KILL cr, USE poll);
 
-  format %{ "testl  rax, [$poll]\t"
+  format %{ "testl   rax, [$poll]\t"
             "# Safepoint: poll for GC" %}
   ins_cost(125);
   ins_encode %{
@@ -12777,7 +12777,7 @@
   match(SafePoint poll);
   effect(KILL cr, USE poll);
 
-  format %{ "testl  rax, [$poll]\t"
+  format %{ "testl   rax, [$poll]\t"
             "# Safepoint: poll for GC" %}
   ins_cost(125);
   size(4); /* setting an explicit size will cause debug builds to assert if size is incorrect */
--- a/src/hotspot/cpu/zero/assembler_zero.hpp	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/cpu/zero/assembler_zero.hpp	Thu May 23 11:07:37 2019 +0100
@@ -37,6 +37,12 @@
 
  public:
   void pd_patch_instruction(address branch, address target, const char* file, int line);
+
+  //---<  calculate length of instruction  >---
+  static unsigned int instr_len(unsigned char *instr) { return 1; }
+
+  //---<  longest instructions  >---
+  static unsigned int instr_maxlen() { return 1; }
 };
 
 class MacroAssembler : public Assembler {
--- a/src/hotspot/cpu/zero/disassembler_zero.hpp	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/cpu/zero/disassembler_zero.hpp	Thu May 23 11:07:37 2019 +0100
@@ -34,4 +34,24 @@
     return "";
   }
 
+  // Returns address of n-th instruction preceding addr,
+  // NULL if no preceding instruction can be found.
+  // On ZERO, we assume a constant instruction length of 1 byte.
+  // It might be beneficial to check "is_readable" as we do on ppc and s390.
+  static address find_prev_instr(address addr, int n_instr) {
+    return addr - 1*n_instr;
+  }
+
+  // special-case instruction decoding.
+  // There may be cases where the binutils disassembler doesn't do
+  // the perfect job. In those cases, decode_instruction0 may kick in
+  // and do it right.
+  // If nothing had to be done, just return "here", otherwise return "here + instr_len(here)"
+  static address decode_instruction0(address here, outputStream* st, address virtual_begin = NULL) {
+    return here;
+  }
+
+  // platform-specific instruction annotations (like value of loaded constants)
+  static void annotate(address pc, outputStream* st) { };
+
 #endif // CPU_ZERO_DISASSEMBLER_ZERO_HPP
--- a/src/hotspot/os/aix/os_aix.cpp	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/os/aix/os_aix.cpp	Thu May 23 11:07:37 2019 +0100
@@ -3447,7 +3447,7 @@
       // fall back to 4K paged mode and use mmap for everything.
       trcVerbose("4K page mode");
       Aix::_page_size = 4*K;
-      FLAG_SET_ERGO(bool, Use64KPages, false);
+      FLAG_SET_ERGO(Use64KPages, false);
     }
   } else {
     // datapsize = 64k. Data segment, thread stacks are 64k paged.
@@ -3457,11 +3457,11 @@
     assert0(g_multipage_support.can_use_64K_pages);
     Aix::_page_size = 64*K;
     trcVerbose("64K page mode");
-    FLAG_SET_ERGO(bool, Use64KPages, true);
+    FLAG_SET_ERGO(Use64KPages, true);
   }
 
   // For now UseLargePages is just ignored.
-  FLAG_SET_ERGO(bool, UseLargePages, false);
+  FLAG_SET_ERGO(UseLargePages, false);
   _page_sizes[0] = 0;
 
   // debug trace
--- a/src/hotspot/os/windows/os_windows.cpp	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/os/windows/os_windows.cpp	Thu May 23 11:07:37 2019 +0100
@@ -4072,7 +4072,7 @@
   init_page_sizes((size_t) win32::vm_page_size());
 
   // This may be overridden later when argument processing is done.
-  FLAG_SET_ERGO(bool, UseLargePagesIndividualAllocation, false);
+  FLAG_SET_ERGO(UseLargePagesIndividualAllocation, false);
 
   // Initialize main_process and main_thread
   main_process = GetCurrentProcess();  // Remember main_process is a pseudo handle
--- a/src/hotspot/os_cpu/linux_ppc/thread_linux_ppc.cpp	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/os_cpu/linux_ppc/thread_linux_ppc.cpp	Thu May 23 11:07:37 2019 +0100
@@ -1,6 +1,6 @@
 /*
- * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2012, 2014 SAP SE. All rights reserved.
+ * Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2019 SAP SE. 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
@@ -92,9 +92,8 @@
   return false;
 }
 
-// Forte Analyzer AsyncGetCallTrace profiling support is not implemented on Linux/PPC.
+// Forte Analyzer AsyncGetCallTrace profiling support.
 bool JavaThread::pd_get_top_frame_for_signal_handler(frame* fr_addr, void* ucontext, bool isInJava) {
-  assert(this->is_Java_thread(), "must be JavaThread");
   return pd_get_top_frame_for_profiling(fr_addr, ucontext, isInJava);
 }
 
--- a/src/hotspot/os_cpu/linux_s390/thread_linux_s390.cpp	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/os_cpu/linux_s390/thread_linux_s390.cpp	Thu May 23 11:07:37 2019 +0100
@@ -90,10 +90,9 @@
   return false;
 }
 
-// Forte Analyzer AsyncGetCallTrace profiling support is not implemented on Linux/S390x.
+// Forte Analyzer AsyncGetCallTrace profiling support.
 bool JavaThread::pd_get_top_frame_for_signal_handler(frame* fr_addr, void* ucontext, bool isInJava) {
-  Unimplemented();
-  return false;
+  return pd_get_top_frame_for_profiling(fr_addr, ucontext, isInJava);
 }
 
 void JavaThread::cache_global_variables() { }
--- a/src/hotspot/share/Xusage.txt	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/share/Xusage.txt	Thu May 23 11:07:37 2019 +0100
@@ -13,6 +13,7 @@
     -Xmx<size>        set maximum Java heap size
     -Xss<size>        set java thread stack size
     -Xfuture          enable strictest checks, anticipating future default
+                      (deprecated)
     -Xrs              reduce use of OS signals by Java/VM (see documentation)
     -Xcheck:jni       perform additional checks for JNI functions
     -Xshare:off	      do not attempt to use shared class data
--- a/src/hotspot/share/aot/aotLoader.hpp	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/share/aot/aotLoader.hpp	Thu May 23 11:07:37 2019 +0100
@@ -54,7 +54,7 @@
   static void add_heap(AOTCodeHeap *heap);
   static void add_library(AOTLib *lib);
 #endif
-  static void initialize() NOT_AOT({ FLAG_SET_ERGO(bool, UseAOT, false); });
+  static void initialize() NOT_AOT({ FLAG_SET_ERGO(UseAOT, false); });
 
   static void universe_init() NOT_AOT_RETURN;
   static void set_narrow_oop_shift() NOT_AOT_RETURN;
--- a/src/hotspot/share/asm/codeBuffer.cpp	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/share/asm/codeBuffer.cpp	Thu May 23 11:07:37 2019 +0100
@@ -86,7 +86,8 @@
 // External buffer, in a predefined CodeBlob.
 // Important: The code_start must be taken exactly, and not realigned.
 CodeBuffer::CodeBuffer(CodeBlob* blob) {
-  initialize_misc("static buffer");
+  // Provide code buffer with meaningful name
+  initialize_misc(blob->name());
   initialize(blob->content_begin(), blob->content_size());
   verify_section_allocation();
 }
@@ -1035,7 +1036,9 @@
 }
 
 void CodeBuffer::block_comment(intptr_t offset, const char * comment) {
-  _code_strings.add_comment(offset, comment);
+  if (_collect_comments) {
+    _code_strings.add_comment(offset, comment);
+  }
 }
 
 const char* CodeBuffer::code_string(const char* str) {
@@ -1148,15 +1151,23 @@
 
 const char* CodeStrings::_prefix = " ;; ";  // default: can be changed via set_prefix
 
+// Check if any block comments are pending for the given offset.
+bool CodeStrings::has_block_comment(intptr_t offset) const {
+  if (_strings == NULL) return false;
+  CodeString* c = find(offset);
+  return c != NULL;
+}
+
 void CodeStrings::print_block_comment(outputStream* stream, intptr_t offset) const {
-    check_valid();
-    if (_strings != NULL) {
+  check_valid();
+  if (_strings != NULL) {
     CodeString* c = find(offset);
     while (c && c->offset() == offset) {
       stream->bol();
       stream->print("%s", _prefix);
       // Don't interpret as format strings since it could contain %
-      stream->print_raw_cr(c->string());
+      stream->print_raw(c->string());
+      stream->bol(); // advance to next line only if string didn't contain a cr() at the end.
       c = c->next_comment();
     }
   }
@@ -1186,7 +1197,7 @@
 
 void CodeBuffer::decode() {
   ttyLocker ttyl;
-  Disassembler::decode(decode_begin(), insts_end());
+  Disassembler::decode(decode_begin(), insts_end(), tty);
   _decode_begin = insts_end();
 }
 
@@ -1217,4 +1228,10 @@
   }
 }
 
+// Directly disassemble code buffer.
+void CodeBuffer::decode(address start, address end) {
+  ttyLocker ttyl;
+  Disassembler::decode(this, start, end, tty);
+}
+
 #endif // PRODUCT
--- a/src/hotspot/share/asm/codeBuffer.hpp	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/share/asm/codeBuffer.hpp	Thu May 23 11:07:37 2019 +0100
@@ -289,6 +289,7 @@
   const char* add_string(const char * string) PRODUCT_RETURN_(return NULL;);
 
   void add_comment(intptr_t offset, const char * comment) PRODUCT_RETURN;
+  bool has_block_comment(intptr_t offset) const;
   void print_block_comment(outputStream* stream, intptr_t offset) const PRODUCT_RETURN;
   // MOVE strings from other to this; invalidate other.
   void assign(CodeStrings& other)  PRODUCT_RETURN;
@@ -296,6 +297,7 @@
   void copy(CodeStrings& other)  PRODUCT_RETURN;
   // FREE strings; invalidate this.
   void free() PRODUCT_RETURN;
+
   // Guarantee that _strings are used at most once; assign and free invalidate a buffer.
   inline void check_valid() const {
 #ifdef ASSERT
@@ -377,6 +379,7 @@
 
   OopRecorder* _oop_recorder;
   CodeStrings  _code_strings;
+  bool         _collect_comments;      // Indicate if we need to collect block comments at all.
   OopRecorder  _default_oop_recorder;  // override with initialize_oop_recorder
   Arena*       _overflow_arena;
 
@@ -403,6 +406,14 @@
 #if INCLUDE_AOT
     _immutable_PIC   = false;
 #endif
+
+    // Collect block comments, but restrict collection to cases where a disassembly is output.
+    _collect_comments = ( PrintAssembly
+                       || PrintStubCode
+                       || PrintMethodHandleStubs
+                       || PrintInterpreter
+                       || PrintSignatureHandlers
+                        );
   }
 
   void initialize(address code_start, csize_t code_size) {
@@ -604,6 +615,23 @@
     }
   }
 
+  // Directly disassemble code buffer.
+  // Print the comment associated with offset on stream, if there is one.
+  virtual void print_block_comment(outputStream* stream, address block_begin) {
+#ifndef PRODUCT
+    intptr_t offset = (intptr_t)(block_begin - _total_start);  // I assume total_start is not correct for all code sections.
+    _code_strings.print_block_comment(stream, offset);
+#endif
+  }
+  bool has_block_comment(address block_begin) {
+#ifndef PRODUCT
+    intptr_t offset = (intptr_t)(block_begin - _total_start);  // I assume total_start is not correct for all code sections.
+    return _code_strings.has_block_comment(offset);
+#else
+    return false;
+#endif
+  }
+
   // Code generation
   void relocate(address at, RelocationHolder const& rspec, int format = 0) {
     _insts.relocate(at, rspec, format);
@@ -650,7 +678,8 @@
   void    decode();
   void    print();
 #endif
-
+  // Directly disassemble code buffer.
+  void    decode(address start, address end);
 
   // The following header contains architecture-specific implementations
 #include CPU_HEADER(codeBuffer)
--- a/src/hotspot/share/c1/c1_Runtime1.cpp	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/share/c1/c1_Runtime1.cpp	Thu May 23 11:07:37 2019 +0100
@@ -575,7 +575,7 @@
       tempst.print("compiled method <%s>\n"
                    " at PC" INTPTR_FORMAT " for thread " INTPTR_FORMAT,
                    nm->method()->print_value_string(), p2i(pc), p2i(thread));
-      Exceptions::log_exception(exception, tempst);
+      Exceptions::log_exception(exception, tempst.as_string());
     }
     // for AbortVMOnException flag
     Exceptions::debug_check_abort(exception);
--- a/src/hotspot/share/c1/c1_globals.cpp	Fri May 17 13:21:44 2019 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,37 +0,0 @@
-/*
- * Copyright (c) 2000, 2016, 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.
- *
- */
-
-#include "precompiled.hpp"
-#include "c1/c1_globals.hpp"
-
-C1_FLAGS(MATERIALIZE_DEVELOPER_FLAG, \
-         MATERIALIZE_PD_DEVELOPER_FLAG, \
-         MATERIALIZE_PRODUCT_FLAG, \
-         MATERIALIZE_PD_PRODUCT_FLAG, \
-         MATERIALIZE_DIAGNOSTIC_FLAG, \
-         MATERIALIZE_PD_DIAGNOSTIC_FLAG, \
-         MATERIALIZE_NOTPRODUCT_FLAG, \
-         IGNORE_RANGE, \
-         IGNORE_CONSTRAINT, \
-         IGNORE_WRITEABLE)
--- a/src/hotspot/share/c1/c1_globals.hpp	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/share/c1/c1_globals.hpp	Thu May 23 11:07:37 2019 +0100
@@ -25,7 +25,7 @@
 #ifndef SHARE_C1_C1_GLOBALS_HPP
 #define SHARE_C1_C1_GLOBALS_HPP
 
-#include "runtime/globals.hpp"
+#include "runtime/globals_shared.hpp"
 #include "utilities/macros.hpp"
 
 #include CPU_HEADER(c1_globals)
@@ -324,17 +324,5 @@
   develop(bool, PrintCFGToFile, false,                                      \
           "print control flow graph to a separate file during compilation") \
                                                                             \
-// Read default values for c1 globals
-
-C1_FLAGS(DECLARE_DEVELOPER_FLAG, \
-         DECLARE_PD_DEVELOPER_FLAG, \
-         DECLARE_PRODUCT_FLAG, \
-         DECLARE_PD_PRODUCT_FLAG, \
-         DECLARE_DIAGNOSTIC_FLAG, \
-         DECLARE_PD_DIAGNOSTIC_FLAG, \
-         DECLARE_NOTPRODUCT_FLAG, \
-         IGNORE_RANGE, \
-         IGNORE_CONSTRAINT, \
-         IGNORE_WRITEABLE)
 
 #endif // SHARE_C1_C1_GLOBALS_HPP
--- a/src/hotspot/share/classfile/classListParser.cpp	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/share/classfile/classListParser.cpp	Thu May 23 11:07:37 2019 +0100
@@ -295,14 +295,14 @@
   if (!is_id_specified()) {
     error("If source location is specified, id must be also specified");
   }
-  InstanceKlass* k = ClassLoaderExt::load_class(class_name, _source, CHECK_NULL);
-
   if (strncmp(_class_name, "java/", 5) == 0) {
     log_info(cds)("Prohibited package for non-bootstrap classes: %s.class from %s",
           _class_name, _source);
     return NULL;
   }
 
+  InstanceKlass* k = ClassLoaderExt::load_class(class_name, _source, CHECK_NULL);
+
   if (k != NULL) {
     if (k->local_interfaces()->length() != _interfaces->length()) {
       print_specified_interfaces();
@@ -461,4 +461,3 @@
   ShouldNotReachHere();
   return NULL;
 }
-
--- a/src/hotspot/share/classfile/classLoader.cpp	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/share/classfile/classLoader.cpp	Thu May 23 11:07:37 2019 +0100
@@ -36,6 +36,7 @@
 #include "classfile/klassFactory.hpp"
 #include "classfile/symbolTable.hpp"
 #include "classfile/systemDictionary.hpp"
+#include "classfile/systemDictionaryShared.hpp"
 #include "classfile/vmSymbols.hpp"
 #include "compiler/compileBroker.hpp"
 #include "interpreter/bytecodeStream.hpp"
@@ -468,7 +469,7 @@
 
 #if INCLUDE_CDS
 void ClassLoader::exit_with_path_failure(const char* error, const char* message) {
-  assert(DumpSharedSpaces, "only called at dump time");
+  assert(DumpSharedSpaces || DynamicDumpSharedSpaces, "only called at dump time");
   tty->print_cr("Hint: enable -Xlog:class+path=info to diagnose the failure");
   vm_exit_during_initialization(error, message);
 }
@@ -534,7 +535,7 @@
     trace_class_path("bootstrap loader class path=", sys_class_path);
   }
 #if INCLUDE_CDS
-  if (DumpSharedSpaces) {
+  if (DumpSharedSpaces || DynamicDumpSharedSpaces) {
     _shared_paths_misc_info->add_boot_classpath(sys_class_path);
   }
 #endif
@@ -550,16 +551,16 @@
   return _shared_paths_misc_info->buffer();
 }
 
-bool ClassLoader::check_shared_paths_misc_info(void *buf, int size) {
+bool ClassLoader::check_shared_paths_misc_info(void *buf, int size, bool is_static) {
   SharedPathsMiscInfo* checker = new SharedPathsMiscInfo((char*)buf, size);
-  bool result = checker->check();
+  bool result = checker->check(is_static);
   delete checker;
   return result;
 }
 
 void ClassLoader::setup_app_search_path(const char *class_path) {
 
-  assert(DumpSharedSpaces, "Sanity");
+  assert(DumpSharedSpaces || DynamicDumpSharedSpaces, "Sanity");
 
   Thread* THREAD = Thread::current();
   int len = (int)strlen(class_path);
@@ -587,7 +588,7 @@
 void ClassLoader::add_to_module_path_entries(const char* path,
                                              ClassPathEntry* entry) {
   assert(entry != NULL, "ClassPathEntry should not be NULL");
-  assert(DumpSharedSpaces, "dump time only");
+  assert(DumpSharedSpaces || DynamicDumpSharedSpaces, "dump time only");
 
   // The entry does not exist, add to the list
   if (_module_path_entries == NULL) {
@@ -601,7 +602,7 @@
 
 // Add a module path to the _module_path_entries list.
 void ClassLoader::update_module_path_entry_list(const char *path, TRAPS) {
-  assert(DumpSharedSpaces, "dump time only");
+  assert(DumpSharedSpaces || DynamicDumpSharedSpaces, "dump time only");
   struct stat st;
   if (os::stat(path, &st) != 0) {
     tty->print_cr("os::stat error %d (%s). CDS dump aborted (path was \"%s\").",
@@ -709,7 +710,7 @@
   bool set_base_piece = true;
 
 #if INCLUDE_CDS
-  if (DumpSharedSpaces) {
+  if (DumpSharedSpaces || DynamicDumpSharedSpaces) {
     if (!Arguments::has_jimage()) {
       vm_exit_during_initialization("CDS is not supported in exploded JDK build", NULL);
     }
@@ -976,7 +977,7 @@
     return true;
   } else {
 #if INCLUDE_CDS
-    if (DumpSharedSpaces) {
+    if (DumpSharedSpaces || DynamicDumpSharedSpaces) {
       _shared_paths_misc_info->add_nonexist_path(path);
     }
 #endif
@@ -1334,6 +1335,10 @@
     // appear in the _patch_mod_entries. The runtime shared class visibility
     // check will determine if a shared class is visible based on the runtime
     // environemnt, including the runtime --patch-module setting.
+    //
+    // DynamicDumpSharedSpaces requires UseSharedSpaces to be enabled. Since --patch-module
+    // is not supported with UseSharedSpaces, it is not supported with DynamicDumpSharedSpaces.
+    assert(!DynamicDumpSharedSpaces, "sanity");
     if (!DumpSharedSpaces) {
       stream = search_module_entries(_patch_mod_entries, class_name, file_name, CHECK_NULL);
     }
@@ -1423,7 +1428,7 @@
 // Record the shared classpath index and loader type for classes loaded
 // by the builtin loaders at dump time.
 void ClassLoader::record_result(InstanceKlass* ik, const ClassFileStream* stream, TRAPS) {
-  assert(DumpSharedSpaces, "sanity");
+  assert(DumpSharedSpaces || DynamicDumpSharedSpaces, "sanity");
   assert(stream != NULL, "sanity");
 
   if (ik->is_unsafe_anonymous()) {
@@ -1513,6 +1518,8 @@
     // user defined classloader.
     if (classpath_index < 0) {
       assert(ik->shared_classpath_index() < 0, "Sanity");
+      ik->set_shared_classpath_index(UNREGISTERED_INDEX);
+      SystemDictionaryShared::set_shared_class_misc_info(ik, (ClassFileStream*)stream);
       return;
     }
   } else {
@@ -1595,7 +1602,7 @@
   load_jimage_library();
 #if INCLUDE_CDS
   // initialize search path
-  if (DumpSharedSpaces) {
+  if (DumpSharedSpaces || DynamicDumpSharedSpaces) {
     _shared_paths_misc_info = new SharedPathsMiscInfo();
   }
 #endif
@@ -1604,14 +1611,14 @@
 
 #if INCLUDE_CDS
 void ClassLoader::initialize_shared_path() {
-  if (DumpSharedSpaces) {
+  if (DumpSharedSpaces || DynamicDumpSharedSpaces) {
     ClassLoaderExt::setup_search_paths();
     _shared_paths_misc_info->write_jint(0); // see comments in SharedPathsMiscInfo::check()
   }
 }
 
 void ClassLoader::initialize_module_path(TRAPS) {
-  if (DumpSharedSpaces) {
+  if (DumpSharedSpaces || DynamicDumpSharedSpaces) {
     ClassLoaderExt::setup_module_paths(THREAD);
     FileMapInfo::allocate_shared_path_table();
   }
@@ -1677,6 +1684,7 @@
   // entries will be added to the exploded build array.
   if (!has_jrt_entry()) {
     assert(!DumpSharedSpaces, "DumpSharedSpaces not supported with exploded module builds");
+    assert(!DynamicDumpSharedSpaces, "DynamicDumpSharedSpaces not supported with exploded module builds");
     assert(!UseSharedSpaces, "UsedSharedSpaces not supported with exploded module builds");
     // Set up the boot loader's _exploded_entries list.  Note that this gets
     // done before loading any classes, by the same thread that will
--- a/src/hotspot/share/classfile/classLoader.hpp	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/share/classfile/classLoader.hpp	Thu May 23 11:07:37 2019 +0100
@@ -398,7 +398,8 @@
   // Helper function used by CDS code to get the number of module path
   // entries during shared classpath setup time.
   static int num_module_path_entries() {
-    assert(DumpSharedSpaces, "Should only be called at CDS dump time");
+    assert(DumpSharedSpaces || DynamicDumpSharedSpaces,
+           "Should only be called at CDS dump time");
     int num_entries = 0;
     ClassPathEntry* e= ClassLoader::_module_path_entries;
     while (e != NULL) {
@@ -410,7 +411,7 @@
   static void  finalize_shared_paths_misc_info();
   static int   get_shared_paths_misc_info_size();
   static void* get_shared_paths_misc_info();
-  static bool  check_shared_paths_misc_info(void* info, int size);
+  static bool  check_shared_paths_misc_info(void* info, int size, bool is_static);
   static void  exit_with_path_failure(const char* error, const char* message);
   static char* skip_uri_protocol(char* source);
   static void  record_result(InstanceKlass* ik, const ClassFileStream* stream, TRAPS);
--- a/src/hotspot/share/classfile/classLoader.inline.hpp	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/share/classfile/classLoader.inline.hpp	Thu May 23 11:07:37 2019 +0100
@@ -62,7 +62,8 @@
 // entries during shared classpath setup time.
 
 inline int ClassLoader::num_boot_classpath_entries() {
-  assert(DumpSharedSpaces, "Should only be called at CDS dump time");
+  assert(DumpSharedSpaces || DynamicDumpSharedSpaces,
+         "Should only be called at CDS dump time");
   assert(has_jrt_entry(), "must have a java runtime image");
   int num_entries = 1; // count the runtime image
   ClassPathEntry* e = ClassLoader::_first_append_entry;
@@ -84,7 +85,8 @@
 // Helper function used by CDS code to get the number of app classpath
 // entries during shared classpath setup time.
 inline int ClassLoader::num_app_classpath_entries() {
-  assert(DumpSharedSpaces, "Should only be called at CDS dump time");
+  assert(DumpSharedSpaces || DynamicDumpSharedSpaces,
+         "Should only be called at CDS dump time");
   int num_entries = 0;
   ClassPathEntry* e= ClassLoader::_app_classpath_entries;
   while (e != NULL) {
--- a/src/hotspot/share/classfile/classLoaderDataGraph.cpp	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/share/classfile/classLoaderDataGraph.cpp	Thu May 23 11:07:37 2019 +0100
@@ -596,14 +596,13 @@
   DependencyContext::purge_dependency_contexts();
 }
 
-int ClassLoaderDataGraph::resize_if_needed() {
+int ClassLoaderDataGraph::resize_dictionaries() {
   assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint!");
   int resized = 0;
-  if (Dictionary::does_any_dictionary_needs_resizing()) {
-    FOR_ALL_DICTIONARY(cld) {
-      if (cld->dictionary()->resize_if_needed()) {
-        resized++;
-      }
+  assert (Dictionary::does_any_dictionary_needs_resizing(), "some dictionary should need resizing");
+  FOR_ALL_DICTIONARY(cld) {
+    if (cld->dictionary()->resize_if_needed()) {
+      resized++;
     }
   }
   return resized;
--- a/src/hotspot/share/classfile/classLoaderDataGraph.hpp	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/share/classfile/classLoaderDataGraph.hpp	Thu May 23 11:07:37 2019 +0100
@@ -119,16 +119,14 @@
   static GrowableArray<ClassLoaderData*>* new_clds();
 
   static void set_should_purge(bool b) { _should_purge = b; }
-  static void purge_if_needed() {
-    // Only purge the CLDG for CMS if concurrent sweep is complete.
-    if (_should_purge) {
-      purge();
-      // reset for next time.
-      set_should_purge(false);
-    }
+  static bool should_purge_and_reset() {
+    bool res = _should_purge;
+    // reset for next time.
+    set_should_purge(false);
+    return res;
   }
 
-  static int resize_if_needed();
+  static int resize_dictionaries();
 
   static bool has_metaspace_oom()           { return _metaspace_oom; }
   static void set_metaspace_oom(bool value) { _metaspace_oom = value; }
--- a/src/hotspot/share/classfile/classLoaderExt.cpp	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/share/classfile/classLoaderExt.cpp	Thu May 23 11:07:37 2019 +0100
@@ -62,7 +62,8 @@
 }
 
 void ClassLoaderExt::setup_app_search_path() {
-  assert(DumpSharedSpaces, "this function is only used with -Xshare:dump");
+  assert(DumpSharedSpaces || DynamicDumpSharedSpaces,
+         "this function is only used at CDS dump time");
   _app_class_paths_start_index = ClassLoader::num_boot_classpath_entries();
   char* app_class_path = os::strdup(Arguments::get_appclasspath());
 
@@ -92,7 +93,8 @@
   }
 }
 void ClassLoaderExt::setup_module_paths(TRAPS) {
-  assert(DumpSharedSpaces, "this function is only used with -Xshare:dump");
+  assert(DumpSharedSpaces || DynamicDumpSharedSpaces,
+         "this function is only used with CDS dump time");
   _app_module_paths_start_index = ClassLoader::num_boot_classpath_entries() +
                               ClassLoader::num_app_classpath_entries();
   Handle system_class_loader (THREAD, SystemDictionary::java_system_loader());
@@ -227,7 +229,7 @@
 void ClassLoaderExt::record_result(const s2 classpath_index,
                                    InstanceKlass* result,
                                    TRAPS) {
-  assert(DumpSharedSpaces, "Sanity");
+  assert(DumpSharedSpaces || DynamicDumpSharedSpaces, "Sanity");
 
   // We need to remember where the class comes from during dumping.
   oop loader = result->class_loader();
@@ -301,8 +303,6 @@
     tty->print_cr("Preload Error: Failed to load %s", class_name);
     return NULL;
   }
-  result->set_shared_classpath_index(UNREGISTERED_INDEX);
-  SystemDictionaryShared::set_shared_class_misc_info(result, stream);
   return result;
 }
 
--- a/src/hotspot/share/classfile/compactHashtable.cpp	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/share/classfile/compactHashtable.cpp	Thu May 23 11:07:37 2019 +0100
@@ -27,6 +27,7 @@
 #include "classfile/compactHashtable.hpp"
 #include "classfile/javaClasses.hpp"
 #include "logging/logMessage.hpp"
+#include "memory/dynamicArchive.hpp"
 #include "memory/heapShared.inline.hpp"
 #include "memory/metadataFactory.hpp"
 #include "memory/metaspaceShared.hpp"
@@ -39,12 +40,14 @@
 //
 // The compact hash table writer implementations
 //
-CompactHashtableWriter::CompactHashtableWriter(int num_buckets,
+CompactHashtableWriter::CompactHashtableWriter(int num_entries,
                                                CompactHashtableStats* stats) {
-  assert(DumpSharedSpaces, "dump-time only");
-  assert(num_buckets > 0, "no buckets");
-  _num_buckets = num_buckets;
-  _num_entries = 0;
+  assert(DumpSharedSpaces || DynamicDumpSharedSpaces, "dump-time only");
+  assert(num_entries >= 0, "sanity");
+  _num_buckets = calculate_num_buckets(num_entries);
+  assert(_num_buckets > 0, "no buckets");
+
+  _num_entries_written = 0;
   _buckets = NEW_C_HEAP_ARRAY(GrowableArray<Entry>*, _num_buckets, mtSymbol);
   for (int i=0; i<_num_buckets; i++) {
     _buckets[i] = new (ResourceObj::C_HEAP, mtSymbol) GrowableArray<Entry>(0, true, mtSymbol);
@@ -67,11 +70,24 @@
   FREE_C_HEAP_ARRAY(GrowableArray<Entry>*, _buckets);
 }
 
+size_t CompactHashtableWriter::estimate_size(int num_entries) {
+  int num_buckets = calculate_num_buckets(num_entries);
+  size_t bucket_bytes = MetaspaceShared::ro_array_bytesize<u4>(num_buckets + 1);
+
+  // In worst case, we have no VALUE_ONLY_BUCKET_TYPE, so each entry takes 2 slots
+  int entries_space = 2 * num_entries;
+  size_t entry_bytes = MetaspaceShared::ro_array_bytesize<u4>(entries_space);
+
+  return bucket_bytes
+       + entry_bytes
+       + SimpleCompactHashtable::calculate_header_size();
+}
+
 // Add a symbol entry to the temporary hash table
 void CompactHashtableWriter::add(unsigned int hash, u4 value) {
   int index = hash % _num_buckets;
   _buckets[index]->append_if_missing(Entry(hash, value));
-  _num_entries++;
+  _num_entries_written++;
 }
 
 void CompactHashtableWriter::allocate_table() {
@@ -81,7 +97,7 @@
     int bucket_size = bucket->length();
     if (bucket_size == 1) {
       entries_space++;
-    } else {
+    } else if (bucket_size > 1) {
       entries_space += 2 * bucket_size;
     }
   }
@@ -96,7 +112,7 @@
 
   _stats->bucket_count    = _num_buckets;
   _stats->bucket_bytes    = _compact_buckets->size() * BytesPerWord;
-  _stats->hashentry_count = _num_entries;
+  _stats->hashentry_count = _num_entries_written;
   _stats->hashentry_bytes = _compact_entries->size() * BytesPerWord;
 }
 
@@ -144,19 +160,19 @@
   dump_table(&summary);
 
   int table_bytes = _stats->bucket_bytes + _stats->hashentry_bytes;
-  address base_address = address(MetaspaceShared::shared_rs()->base());
-  cht->init(base_address,  _num_entries, _num_buckets,
+  address base_address = address(SharedBaseAddress);
+  cht->init(base_address,  _num_entries_written, _num_buckets,
             _compact_buckets->data(), _compact_entries->data());
 
   LogMessage(cds, hashtables) msg;
   if (msg.is_info()) {
     double avg_cost = 0.0;
-    if (_num_entries > 0) {
-      avg_cost = double(table_bytes)/double(_num_entries);
+    if (_num_entries_written > 0) {
+      avg_cost = double(table_bytes)/double(_num_entries_written);
     }
     msg.info("Shared %s table stats -------- base: " PTR_FORMAT,
                          table_name, (intptr_t)base_address);
-    msg.info("Number of entries       : %9d", _num_entries);
+    msg.info("Number of entries       : %9d", _num_entries_written);
     msg.info("Total bytes used        : %9d", table_bytes);
     msg.info("Average bytes per entry : %9.3f", avg_cost);
     msg.info("Average bucket size     : %9.3f", summary.avg());
@@ -174,7 +190,28 @@
 // The CompactHashtable implementation
 //
 
+void SimpleCompactHashtable::init(address base_address, u4 entry_count, u4 bucket_count, u4* buckets, u4* entries) {
+  _bucket_count = bucket_count;
+  _entry_count = entry_count;
+  _base_address = base_address;
+  if (DynamicDumpSharedSpaces) {
+    _buckets = DynamicArchive::buffer_to_target(buckets);
+    _entries = DynamicArchive::buffer_to_target(entries);
+  } else {
+    _buckets = buckets;
+    _entries = entries;
+  }
+}
+
+size_t SimpleCompactHashtable::calculate_header_size() {
+  // We have 5 fields. Each takes up sizeof(intptr_t). See WriteClosure::do_u4
+  size_t bytes = sizeof(intptr_t) * 5;
+  return bytes;
+}
+
 void SimpleCompactHashtable::serialize_header(SerializeClosure* soc) {
+  // NOTE: if you change this function, you MUST change the number 5 in
+  // calculate_header_size() accordingly.
   soc->do_ptr((void**)&_base_address);
   soc->do_u4(&_entry_count);
   soc->do_u4(&_bucket_count);
--- a/src/hotspot/share/classfile/compactHashtable.hpp	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/share/classfile/compactHashtable.hpp	Thu May 23 11:07:37 2019 +0100
@@ -100,7 +100,7 @@
   }; // class CompactHashtableWriter::Entry
 
 private:
-  int _num_entries;
+  int _num_entries_written;
   int _num_buckets;
   int _num_empty_buckets;
   int _num_value_only_buckets;
@@ -112,7 +112,7 @@
 
 public:
   // This is called at dump-time only
-  CompactHashtableWriter(int num_buckets, CompactHashtableStats* stats);
+  CompactHashtableWriter(int num_entries, CompactHashtableStats* stats);
   ~CompactHashtableWriter();
 
   void add(unsigned int hash, u4 value);
@@ -120,18 +120,16 @@
 private:
   void allocate_table();
   void dump_table(NumberSeq* summary);
+  static int calculate_num_buckets(int num_entries) {
+    int num_buckets = num_entries / SharedSymbolTableBucketSize;
+    // calculation of num_buckets can result in zero buckets, we need at least one
+    return (num_buckets < 1) ? 1 : num_buckets;
+  }
 
 public:
   void dump(SimpleCompactHashtable *cht, const char* table_name);
 
-  static int default_num_buckets(size_t num_entries) {
-    return default_num_buckets((int)num_entries);
-  }
-  static int default_num_buckets(int num_entries) {
-    int num_buckets = num_entries / SharedSymbolTableBucketSize;
-    // calculation of num_buckets can result in zero buckets, we need at least one
-    return (num_buckets < 1) ? 1 : num_buckets;
-  }
+  static size_t estimate_size(int num_entries);
 };
 #endif // INCLUDE_CDS
 
@@ -214,13 +212,7 @@
     _entries = 0;
   }
 
-  void init(address base_address, u4 entry_count, u4 bucket_count, u4* buckets, u4* entries) {
-    _base_address = base_address;
-    _bucket_count = bucket_count;
-    _entry_count = entry_count;
-    _buckets = buckets;
-    _entries = entries;
-  }
+  void init(address base_address, u4 entry_count, u4 bucket_count, u4* buckets, u4* entries);
 
   // Read/Write the table's header from/to the CDS archive
   void serialize_header(SerializeClosure* soc) NOT_CDS_RETURN;
@@ -228,6 +220,8 @@
   inline bool empty() {
     return (_entry_count == 0);
   }
+
+  static size_t calculate_header_size();
 };
 
 template <
--- a/src/hotspot/share/classfile/dictionary.cpp	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/share/classfile/dictionary.cpp	Thu May 23 11:07:37 2019 +0100
@@ -246,7 +246,7 @@
 
 // Used to scan and relocate the classes during CDS archive dump.
 void Dictionary::classes_do(MetaspaceClosure* it) {
-  assert(DumpSharedSpaces, "dump-time only");
+  assert(DumpSharedSpaces || DynamicDumpSharedSpaces, "dump-time only");
   for (int index = 0; index < table_size(); index++) {
     for (DictionaryEntry* probe = bucket(index);
                           probe != NULL;
@@ -312,7 +312,6 @@
   }
 }
 
-
 InstanceKlass* Dictionary::find_class(int index, unsigned int hash,
                                       Symbol* name) {
   assert_locked_or_safepoint(SystemDictionary_lock);
--- a/src/hotspot/share/classfile/klassFactory.cpp	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/share/classfile/klassFactory.cpp	Thu May 23 11:07:37 2019 +0100
@@ -218,7 +218,7 @@
   JFR_ONLY(ON_KLASS_CREATION(result, parser, THREAD);)
 
 #if INCLUDE_CDS
-  if (DumpSharedSpaces) {
+  if (DumpSharedSpaces || DynamicDumpSharedSpaces) {
     ClassLoader::record_result(result, stream, THREAD);
   }
 #endif // INCLUDE_CDS
--- a/src/hotspot/share/classfile/sharedPathsMiscInfo.cpp	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/share/classfile/sharedPathsMiscInfo.cpp	Thu May 23 11:07:37 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2019, 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
@@ -104,7 +104,7 @@
   }
 }
 
-bool SharedPathsMiscInfo::check() {
+bool SharedPathsMiscInfo::check(bool is_static) {
   // The whole buffer must be 0 terminated so that we can use strlen and strcmp
   // without fear.
   _end_ptr -= sizeof(jint);
@@ -116,9 +116,10 @@
   }
 
   jshort cur_index = 0;
-  jshort max_cp_index = FileMapInfo::current_info()->header()->max_used_path_index();
-  jshort module_paths_start_index =
-    FileMapInfo::current_info()->header()->app_module_paths_start_index();
+  FileMapHeader* header = is_static ? FileMapInfo::current_info()->header() :
+                                      FileMapInfo::dynamic_info()->header();
+  jshort max_cp_index = header->max_used_path_index();
+  jshort module_paths_start_index = header->app_module_paths_start_index();
   while (_cur_ptr < _end_ptr) {
     jint type;
     const char* path = _cur_ptr;
@@ -136,7 +137,7 @@
     }
     // skip checking the class path(s) which was not referenced during CDS dump
     if ((cur_index <= max_cp_index) || (cur_index >= module_paths_start_index)) {
-      if (!check(type, path)) {
+      if (!check(type, path, is_static)) {
         if (!PrintSharedArchiveAndExit) {
           return false;
         }
@@ -171,7 +172,7 @@
   return p;
 }
 
-bool SharedPathsMiscInfo::check(jint type, const char* path) {
+bool SharedPathsMiscInfo::check(jint type, const char* path, bool is_static) {
   assert(UseSharedSpaces, "runtime only");
   switch (type) {
   case BOOT_PATH:
@@ -196,7 +197,9 @@
       char* rp = skip_first_path_entry(runtime_boot_path);
       char* dp = skip_first_path_entry(path);
 
-      bool relaxed_check = !FileMapInfo::current_info()->header()->has_platform_or_app_classes();
+      bool relaxed_check = is_static ?
+                             !FileMapInfo::current_info()->header()->has_platform_or_app_classes() :
+                             !FileMapInfo::dynamic_info()->header()->has_platform_or_app_classes();
       if (dp == NULL && rp == NULL) {
         break;   // ok, both runtime and dump time boot paths have modules_images only
       } else if (dp == NULL && rp != NULL && relaxed_check) {
--- a/src/hotspot/share/classfile/sharedPathsMiscInfo.hpp	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/share/classfile/sharedPathsMiscInfo.hpp	Thu May 23 11:07:37 2019 +0100
@@ -67,7 +67,7 @@
 
 protected:
   static bool fail(const char* msg, const char* name = NULL);
-  bool check(jint type, const char* path);
+  bool check(jint type, const char* path, bool is_static);
 
 public:
   enum {
@@ -162,7 +162,7 @@
   }
 
 public:
-  bool check();
+  bool check(bool is_static);
 };
 
 #endif // SHARE_CLASSFILE_SHAREDPATHSMISCINFO_HPP
--- a/src/hotspot/share/classfile/stringTable.cpp	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/share/classfile/stringTable.cpp	Thu May 23 11:07:37 2019 +0100
@@ -372,16 +372,19 @@
 
   bool rehash_warning;
   do {
-    if (_local_table->get(THREAD, lookup, stg, &rehash_warning)) {
-      update_needs_rehash(rehash_warning);
-      return stg.get_res_oop();
-    }
+    // Callers have already looked up the String using the jchar* name, so just go to add.
     WeakHandle<vm_string_table_data> wh = WeakHandle<vm_string_table_data>::create(string_h);
     // The hash table takes ownership of the WeakHandle, even if it's not inserted.
     if (_local_table->insert(THREAD, lookup, wh, &rehash_warning)) {
       update_needs_rehash(rehash_warning);
       return wh.resolve();
     }
+    // In case another thread did a concurrent add, return value already in the table.
+    // This could fail if the String got gc'ed concurrently, so loop back until success.
+    if (_local_table->get(THREAD, lookup, stg, &rehash_warning)) {
+      update_needs_rehash(rehash_warning);
+      return stg.get_res_oop();
+    }
   } while(true);
 }
 
@@ -779,9 +782,7 @@
   assert(HeapShared::is_heap_object_archiving_allowed(), "must be");
 
   _shared_table.reset();
-  int num_buckets = CompactHashtableWriter::default_num_buckets(_items_count);
-  CompactHashtableWriter writer(num_buckets,
-                                &MetaspaceShared::stats()->string);
+  CompactHashtableWriter writer(_items_count, &MetaspaceShared::stats()->string);
 
   // Copy the interned strings into the "string space" within the java heap
   copy_shared_string_table(&writer);
--- a/src/hotspot/share/classfile/symbolTable.cpp	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/share/classfile/symbolTable.cpp	Thu May 23 11:07:37 2019 +0100
@@ -28,6 +28,7 @@
 #include "classfile/javaClasses.hpp"
 #include "classfile/symbolTable.hpp"
 #include "memory/allocation.inline.hpp"
+#include "memory/dynamicArchive.hpp"
 #include "memory/metaspaceClosure.hpp"
 #include "memory/metaspaceShared.hpp"
 #include "memory/resourceArea.hpp"
@@ -69,6 +70,11 @@
   symbol_equals_compact_hashtable_entry
 > _shared_table;
 
+static OffsetCompactHashtable<
+  const char*, Symbol*,
+  symbol_equals_compact_hashtable_entry
+> _dynamic_shared_table;
+
 // --------------------------------------------------------------------------
 
 typedef ConcurrentHashTable<Symbol*,
@@ -109,9 +115,11 @@
   java_lang_String::hash_code((const jbyte*)s, len);
 }
 
+#if INCLUDE_CDS
 static uintx hash_shared_symbol(const char* s, int len) {
   return java_lang_String::hash_code((const jbyte*)s, len);
 }
+#endif
 
 class SymbolTableConfig : public SymbolTableHash::BaseConfig {
 private:
@@ -213,7 +221,7 @@
   assert (len <= Symbol::max_length(), "should be checked by caller");
 
   Symbol* sym;
-  if (DumpSharedSpaces) {
+  if (DumpSharedSpaces || DynamicDumpSharedSpaces) {
     c_heap = false;
   }
   if (c_heap) {
@@ -254,6 +262,7 @@
   // all symbols from shared table
   SharedSymbolIterator iter(cl);
   _shared_table.iterate(&iter);
+  _dynamic_shared_table.iterate(&iter);
 
   // all symbols from the dynamic table
   SymbolsDo sd(cl);
@@ -275,7 +284,7 @@
 };
 
 void SymbolTable::metaspace_pointers_do(MetaspaceClosure* it) {
-  assert(DumpSharedSpaces, "called only during dump time");
+  assert(DumpSharedSpaces || DynamicDumpSharedSpaces, "called only during dump time");
   MetaspacePointersDo mpd(it);
   _local_table->do_safepoint_scan(mpd);
 }
@@ -287,19 +296,24 @@
   return sym;
 }
 
+#if INCLUDE_CDS
 Symbol* SymbolTable::lookup_shared(const char* name,
                                    int len, unsigned int hash) {
+  Symbol* sym = NULL;
   if (!_shared_table.empty()) {
     if (_alt_hash) {
       // hash_code parameter may use alternate hashing algorithm but the shared table
       // always uses the same original hash code.
       hash = hash_shared_symbol(name, len);
     }
-    return _shared_table.lookup(name, hash, len);
-  } else {
-    return NULL;
+    sym = _shared_table.lookup(name, hash, len);
+    if (sym == NULL && DynamicArchive::is_mapped()) {
+      sym = _dynamic_shared_table.lookup(name, hash, len);
+    }
   }
+  return sym;
 }
+#endif
 
 Symbol* SymbolTable::lookup_common(const char* name,
                             int len, unsigned int hash) {
@@ -467,14 +481,17 @@
   Thread* THREAD = Thread::current();
 
   do {
+    // Callers have looked up the symbol once, insert the symbol.
+    sym = allocate_symbol(name, len, heap);
+    if (_local_table->insert(THREAD, lookup, sym, &rehash_warning, &clean_hint)) {
+      break;
+    }
+    // In case another thread did a concurrent add, return value already in the table.
+    // This could fail if the symbol got deleted concurrently, so loop back until success.
     if (_local_table->get(THREAD, lookup, stg, &rehash_warning)) {
       sym = stg.get_res_sym();
       break;
     }
-    sym = allocate_symbol(name, len, heap);
-    if (_local_table->insert(THREAD, lookup, sym, &rehash_warning, &clean_hint)) {
-      break;
-    }
   } while(true);
 
   update_needs_rehash(rehash_warning);
@@ -588,6 +605,9 @@
     unsigned int fixed_hash = hash_shared_symbol((const char*)sym->bytes(), sym->utf8_length());
     assert(fixed_hash == hash_symbol((const char*)sym->bytes(), sym->utf8_length(), false),
            "must not rehash during dumping");
+    if (DynamicDumpSharedSpaces) {
+      sym = DynamicArchive::original_to_target(sym);
+    }
     _writer->add(fixed_hash, MetaspaceShared::object_delta_u4(sym));
     return true;
   }
@@ -598,30 +618,43 @@
   _local_table->do_safepoint_scan(copy);
 }
 
-void SymbolTable::write_to_archive() {
-  _shared_table.reset();
+size_t SymbolTable::estimate_size_for_archive() {
+  return CompactHashtableWriter::estimate_size(int(_items_count));
+}
 
-  int num_buckets = CompactHashtableWriter::default_num_buckets(
-      _items_count);
-  CompactHashtableWriter writer(num_buckets,
+void SymbolTable::write_to_archive(bool is_static_archive) {
+  _shared_table.reset();
+  _dynamic_shared_table.reset();
+
+  CompactHashtableWriter writer(int(_items_count),
                                 &MetaspaceShared::stats()->symbol);
   copy_shared_symbol_table(&writer);
-  writer.dump(&_shared_table, "symbol");
+  if (is_static_archive) {
+    writer.dump(&_shared_table, "symbol");
 
-  // Verify table is correct
-  Symbol* sym = vmSymbols::java_lang_Object();
-  const char* name = (const char*)sym->bytes();
-  int len = sym->utf8_length();
-  unsigned int hash = hash_symbol(name, len, _alt_hash);
-  assert(sym == _shared_table.lookup(name, hash, len), "sanity");
+    // Verify table is correct
+    Symbol* sym = vmSymbols::java_lang_Object();
+    const char* name = (const char*)sym->bytes();
+    int len = sym->utf8_length();
+    unsigned int hash = hash_symbol(name, len, _alt_hash);
+    assert(sym == _shared_table.lookup(name, hash, len), "sanity");
+  } else {
+    writer.dump(&_dynamic_shared_table, "symbol");
+  }
 }
 
-void SymbolTable::serialize_shared_table_header(SerializeClosure* soc) {
-  _shared_table.serialize_header(soc);
-
+void SymbolTable::serialize_shared_table_header(SerializeClosure* soc,
+                                                bool is_static_archive) {
+  OffsetCompactHashtable<const char*, Symbol*, symbol_equals_compact_hashtable_entry> * table;
+  if (is_static_archive) {
+    table = &_shared_table;
+  } else {
+    table = &_dynamic_shared_table;
+  }
+  table->serialize_header(soc);
   if (soc->writing()) {
     // Sanity. Make sure we don't use the shared table at dump time
-    _shared_table.reset();
+    table->reset();
   }
 }
 #endif //INCLUDE_CDS
--- a/src/hotspot/share/classfile/symbolTable.hpp	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/share/classfile/symbolTable.hpp	Thu May 23 11:07:37 2019 +0100
@@ -137,7 +137,7 @@
                           const char** name, int* lengths,
                           int* cp_indices, unsigned int* hashValues);
 
-  static Symbol* lookup_shared(const char* name, int len, unsigned int hash);
+  static Symbol* lookup_shared(const char* name, int len, unsigned int hash) NOT_CDS_RETURN_(NULL);
   static Symbol* lookup_dynamic(const char* name, int len, unsigned int hash);
   static Symbol* lookup_common(const char* name, int len, unsigned int hash);
 
@@ -209,8 +209,10 @@
 private:
   static void copy_shared_symbol_table(CompactHashtableWriter* ch_table);
 public:
-  static void write_to_archive() NOT_CDS_RETURN;
-  static void serialize_shared_table_header(SerializeClosure* soc) NOT_CDS_RETURN;
+  static size_t estimate_size_for_archive() NOT_CDS_RETURN_(0);
+  static void write_to_archive(bool is_static_archive = true) NOT_CDS_RETURN;
+  static void serialize_shared_table_header(SerializeClosure* soc,
+                                            bool is_static_archive = true) NOT_CDS_RETURN;
   static void metaspace_pointers_do(MetaspaceClosure* it);
 
   // Jcmd
--- a/src/hotspot/share/classfile/systemDictionaryShared.cpp	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/share/classfile/systemDictionaryShared.cpp	Thu May 23 11:07:37 2019 +0100
@@ -44,6 +44,7 @@
 #include "memory/oopFactory.hpp"
 #include "memory/resourceArea.hpp"
 #include "memory/universe.hpp"
+#include "memory/dynamicArchive.hpp"
 #include "oops/instanceKlass.hpp"
 #include "oops/klass.inline.hpp"
 #include "oops/objArrayOop.inline.hpp"
@@ -61,9 +62,10 @@
 objArrayOop SystemDictionaryShared::_shared_protection_domains  =  NULL;
 objArrayOop SystemDictionaryShared::_shared_jar_urls            =  NULL;
 objArrayOop SystemDictionaryShared::_shared_jar_manifests       =  NULL;
-DEBUG_ONLY(bool SystemDictionaryShared::_checked_excluded_classes = false;)
+DEBUG_ONLY(bool SystemDictionaryShared::_no_class_loading_should_happen = false;)
 
 class DumpTimeSharedClassInfo: public CHeapObj<mtClass> {
+  bool                         _excluded;
 public:
   struct DTConstraint {
     Symbol* _name;
@@ -76,7 +78,6 @@
   int                          _id;
   int                          _clsfile_size;
   int                          _clsfile_crc32;
-  bool                         _excluded;
   GrowableArray<DTConstraint>* _verifier_constraints;
   GrowableArray<char>*         _verifier_constraint_flags;
 
@@ -115,6 +116,15 @@
       }
     }
   }
+
+  void set_excluded() {
+    _excluded = true;
+  }
+
+  bool is_excluded() {
+    // _klass may become NULL due to DynamicArchiveBuilder::set_to_null
+    return _excluded || _klass == NULL;
+  }
 };
 
 class DumpTimeSharedClassTable: public ResourceHashtable<
@@ -131,8 +141,8 @@
   DumpTimeSharedClassInfo* find_or_allocate_info_for(InstanceKlass* k) {
     DumpTimeSharedClassInfo* p = get(k);
     if (p == NULL) {
-      assert(!SystemDictionaryShared::checked_excluded_classes(),
-             "no new classes can be added after check_excluded_classes");
+      assert(!SystemDictionaryShared::no_class_loading_should_happen(),
+             "no new classes can be loaded while dumping archive");
       put(k, DumpTimeSharedClassInfo());
       p = get(k);
       assert(p != NULL, "sanity");
@@ -146,16 +156,20 @@
   public:
     CountClassByCategory(DumpTimeSharedClassTable* table) : _table(table) {}
     bool do_entry(InstanceKlass* k, DumpTimeSharedClassInfo& info) {
-      if (SystemDictionaryShared::is_builtin(k)) {
-        ++ _table->_builtin_count;
-      } else {
-        ++ _table->_unregistered_count;
+      if (!info.is_excluded()) {
+        if (info.is_builtin()) {
+          ++ _table->_builtin_count;
+        } else {
+          ++ _table->_unregistered_count;
+        }
       }
       return true; // keep on iterating
     }
   };
 
   void update_counts() {
+    _builtin_count = 0;
+    _unregistered_count = 0;
     CountClassByCategory counter(this);
     iterate(&counter);
   }
@@ -250,26 +264,36 @@
     return (char*)(address(this) + verifier_constraint_flags_offset());
   }
 
+  static u4 object_delta_u4(Symbol* sym) {
+    if (DynamicDumpSharedSpaces) {
+      sym = DynamicArchive::original_to_target(sym);
+    }
+    return MetaspaceShared::object_delta_u4(sym);
+  }
+
   void init(DumpTimeSharedClassInfo& info) {
     _klass = info._klass;
-    _num_constraints = info.num_constraints();
     if (!SystemDictionaryShared::is_builtin(_klass)) {
       CrcInfo* c = crc();
       c->_clsfile_size = info._clsfile_size;
       c->_clsfile_crc32 = info._clsfile_crc32;
     }
+    _num_constraints = info.num_constraints();
     if (_num_constraints > 0) {
       RTConstraint* constraints = verifier_constraints();
       char* flags = verifier_constraint_flags();
       int i;
       for (i = 0; i < _num_constraints; i++) {
-        constraints[i]._name      = MetaspaceShared::object_delta_u4(info._verifier_constraints->at(i)._name);
-        constraints[i]._from_name = MetaspaceShared::object_delta_u4(info._verifier_constraints->at(i)._from_name);
+        constraints[i]._name      = object_delta_u4(info._verifier_constraints->at(i)._name);
+        constraints[i]._from_name = object_delta_u4(info._verifier_constraints->at(i)._from_name);
       }
       for (i = 0; i < _num_constraints; i++) {
         flags[i] = info._verifier_constraint_flags->at(i);
       }
     }
+    if (DynamicDumpSharedSpaces) {
+      _klass = DynamicArchive::original_to_target(info._klass);
+    }
   }
 
   bool matches(int clsfile_size, int clsfile_crc32) const {
@@ -307,7 +331,12 @@
     return *info_pointer_addr(klass);
   }
   static void set_for(InstanceKlass* klass, RunTimeSharedClassInfo* record) {
-    *info_pointer_addr(klass) = record;
+    if (DynamicDumpSharedSpaces) {
+      klass = DynamicArchive::original_to_buffer(klass);
+      *info_pointer_addr(klass) = DynamicArchive::buffer_to_target(record);
+    } else {
+      *info_pointer_addr(klass) = record;
+    }
   }
 
   // Used by RunTimeSharedDictionary to implement OffsetCompactHashtable::EQUALS
@@ -323,8 +352,12 @@
   RunTimeSharedClassInfo::EQUALS> {};
 
 static DumpTimeSharedClassTable* _dumptime_table = NULL;
+// SystemDictionaries in the base layer static archive
 static RunTimeSharedDictionary _builtin_dictionary;
 static RunTimeSharedDictionary _unregistered_dictionary;
+// SystemDictionaries in the top layer dynamic archive
+static RunTimeSharedDictionary _dynamic_builtin_dictionary;
+static RunTimeSharedDictionary _dynamic_unregistered_dictionary;
 
 oop SystemDictionaryShared::shared_protection_domain(int index) {
   return _shared_protection_domains->obj_at(index);
@@ -710,6 +743,17 @@
   return false;
 }
 
+bool SystemDictionaryShared::has_platform_or_app_classes() {
+  if (FileMapInfo::current_info()->header()->has_platform_or_app_classes()) {
+    return true;
+  }
+  if (DynamicArchive::is_mapped() &&
+      FileMapInfo::dynamic_info()->header()->has_platform_or_app_classes()) {
+    return true;
+  }
+  return false;
+}
+
 // The following stack shows how this code is reached:
 //
 //   [0] SystemDictionaryShared::find_or_load_shared_class()
@@ -747,7 +791,7 @@
                  Symbol* name, Handle class_loader, TRAPS) {
   InstanceKlass* k = NULL;
   if (UseSharedSpaces) {
-    if (!FileMapInfo::current_info()->header()->has_platform_or_app_classes()) {
+    if (!has_platform_or_app_classes()) {
       return NULL;
     }
 
@@ -864,11 +908,17 @@
 
   const RunTimeSharedClassInfo* record = find_record(&_unregistered_dictionary, class_name);
   if (record == NULL) {
-    return NULL;
+    if (DynamicArchive::is_mapped()) {
+      record = find_record(&_dynamic_unregistered_dictionary, class_name);
+    }
+    if (record == NULL) {
+      return NULL;
+    }
   }
 
   int clsfile_size  = cfs->length();
   int clsfile_crc32 = ClassLoader::crc32(0, (const char*)cfs->buffer(), cfs->length());
+
   if (!record->matches(clsfile_size, clsfile_crc32)) {
     return NULL;
   }
@@ -971,6 +1021,7 @@
 }
 
 DumpTimeSharedClassInfo* SystemDictionaryShared::find_or_allocate_info_for(InstanceKlass* k) {
+  MutexLocker ml(DumpTimeTable_lock, Mutex::_no_safepoint_check_flag);
   if (_dumptime_table == NULL) {
     _dumptime_table = new (ResourceObj::C_HEAP, mtClass)DumpTimeSharedClassTable();
   }
@@ -978,7 +1029,7 @@
 }
 
 void SystemDictionaryShared::set_shared_class_misc_info(InstanceKlass* k, ClassFileStream* cfs) {
-  assert(DumpSharedSpaces, "only when dumping");
+  assert(DumpSharedSpaces || DynamicDumpSharedSpaces, "only when dumping");
   assert(!is_builtin(k), "must be unregistered class");
   DumpTimeSharedClassInfo* info = find_or_allocate_info_for(k);
   info->_clsfile_size  = cfs->length();
@@ -990,6 +1041,28 @@
 }
 
 void SystemDictionaryShared::remove_dumptime_info(InstanceKlass* k) {
+  MutexLocker ml(DumpTimeTable_lock, Mutex::_no_safepoint_check_flag);
+  DumpTimeSharedClassInfo* p = _dumptime_table->get(k);
+  if (p == NULL) {
+    return;
+  }
+  if (p->_verifier_constraints != NULL) {
+    for (int i = 0; i < p->_verifier_constraints->length(); i++) {
+      DumpTimeSharedClassInfo::DTConstraint constraint = p->_verifier_constraints->at(i);
+      if (constraint._name != NULL ) {
+        constraint._name->decrement_refcount();
+      }
+      if (constraint._from_name != NULL ) {
+        constraint._from_name->decrement_refcount();
+      }
+    }
+    FREE_C_HEAP_ARRAY(DTConstraint, p->_verifier_constraints);
+    p->_verifier_constraints = NULL;
+  }
+  if (p->_verifier_constraint_flags != NULL) {
+    FREE_C_HEAP_ARRAY(char, p->_verifier_constraint_flags);
+    p->_verifier_constraint_flags = NULL;
+  }
   _dumptime_table->remove(k);
 }
 
@@ -1010,9 +1083,11 @@
 
 bool SystemDictionaryShared::should_be_excluded(InstanceKlass* k) {
   if (k->class_loader_data()->is_unsafe_anonymous()) {
+    warn_excluded(k, "Unsafe anonymous class");
     return true; // unsafe anonymous classes are not archived, skip
   }
   if (k->is_in_error_state()) {
+    warn_excluded(k, "In error state");
     return true;
   }
   if (k->shared_classpath_index() < 0 && is_builtin(k)) {
@@ -1036,6 +1111,44 @@
     warn_excluded(k, "JFR event class");
     return true;
   }
+  if (k->init_state() < InstanceKlass::linked) {
+    // In static dumping, we will attempt to link all classes. Those that fail to link will
+    // be marked as in error state.
+    assert(DynamicDumpSharedSpaces, "must be");
+
+    // TODO -- rethink how this can be handled.
+    // We should try to link ik, however, we can't do it here because
+    // 1. We are at VM exit
+    // 2. linking a class may cause other classes to be loaded, which means
+    //    a custom ClassLoader.loadClass() may be called, at a point where the
+    //    class loader doesn't expect it.
+    warn_excluded(k, "Not linked");
+    return true;
+  }
+  if (k->major_version() < 50 /*JAVA_6_VERSION*/) {
+    ResourceMark rm;
+    log_warning(cds)("Pre JDK 6 class not supported by CDS: %u.%u %s",
+                     k->major_version(),  k->minor_version(), k->name()->as_C_string());
+    return true;
+  }
+
+  InstanceKlass* super = k->java_super();
+  if (super != NULL && should_be_excluded(super)) {
+    ResourceMark rm;
+    log_warning(cds)("Skipping %s: super class %s is excluded", k->name()->as_C_string(), super->name()->as_C_string());
+    return true;
+  }
+
+  Array<InstanceKlass*>* interfaces = k->local_interfaces();
+  int len = interfaces->length();
+  for (int i = 0; i < len; i++) {
+    InstanceKlass* intf = interfaces->at(i);
+    if (should_be_excluded(intf)) {
+      log_warning(cds)("Skipping %s: interface %s is excluded", k->name()->as_C_string(), intf->name()->as_C_string());
+      return true;
+    }
+  }
+
   return false;
 }
 
@@ -1044,8 +1157,9 @@
   ResourceMark rm;
   const char* name = k->name()->as_C_string();
   DumpTimeSharedClassInfo* info = _dumptime_table->get(k);
+  assert(_no_class_loading_should_happen, "class loading must be disabled");
   guarantee(info != NULL, "Class %s must be entered into _dumptime_table", name);
-  guarantee(!info->_excluded, "Should not attempt to archive excluded class %s", name);
+  guarantee(!info->is_excluded(), "Should not attempt to archive excluded class %s", name);
   if (is_builtin(k)) {
     guarantee(k->loader_type() != 0,
               "Class loader type must be set for BUILTIN class %s", name);
@@ -1059,7 +1173,7 @@
 public:
   bool do_entry(InstanceKlass* k, DumpTimeSharedClassInfo& info) {
     if (SystemDictionaryShared::should_be_excluded(k)) {
-      info._excluded = true;
+      info.set_excluded();
     }
     return true; // keep on iterating
   }
@@ -1068,13 +1182,13 @@
 void SystemDictionaryShared::check_excluded_classes() {
   ExcludeDumpTimeSharedClasses excl;
   _dumptime_table->iterate(&excl);
-  DEBUG_ONLY(_checked_excluded_classes = true;)
+  _dumptime_table->update_counts();
 }
 
 bool SystemDictionaryShared::is_excluded_class(InstanceKlass* k) {
-  assert(_checked_excluded_classes, "sanity");
-  assert(DumpSharedSpaces, "only when dumping");
-  return find_or_allocate_info_for(k)->_excluded;
+  assert(_no_class_loading_should_happen, "sanity");
+  assert(DumpSharedSpaces || DynamicDumpSharedSpaces, "only when dumping");
+  return find_or_allocate_info_for(k)->is_excluded();
 }
 
 class IterateDumpTimeSharedClassTable : StackObj {
@@ -1083,7 +1197,7 @@
   IterateDumpTimeSharedClassTable(MetaspaceClosure* it) : _it(it) {}
 
   bool do_entry(InstanceKlass* k, DumpTimeSharedClassInfo& info) {
-    if (!info._excluded) {
+    if (!info.is_excluded()) {
       info.metaspace_pointers_do(_it);
     }
     return true; // keep on iterating
@@ -1097,18 +1211,27 @@
 
 bool SystemDictionaryShared::add_verification_constraint(InstanceKlass* k, Symbol* name,
          Symbol* from_name, bool from_field_is_protected, bool from_is_array, bool from_is_object) {
-  assert(DumpSharedSpaces, "called at dump time only");
+  assert(DumpSharedSpaces || DynamicDumpSharedSpaces, "called at dump time only");
   DumpTimeSharedClassInfo* info = find_or_allocate_info_for(k);
   info->add_verification_constraint(k, name, from_name, from_field_is_protected,
                                     from_is_array, from_is_object);
-  if (is_builtin(k)) {
-    // For builtin class loaders, we can try to complete the verification check at dump time,
-    // because we can resolve all the constraint classes.
+
+  if (DynamicDumpSharedSpaces) {
+    // For dynamic dumping, we can resolve all the constraint classes for all class loaders during
+    // the initial run prior to creating the archive before vm exit. We will also perform verification
+    // check when running with the archive.
     return false;
   } else {
-    // For non-builtin class loaders, we cannot complete the verification check at dump time,
-    // because at dump time we don't know how to resolve classes for such loaders.
-    return true;
+    if (is_builtin(k)) {
+      // For builtin class loaders, we can try to complete the verification check at dump time,
+      // because we can resolve all the constraint classes. We will also perform verification check
+      // when running with the archive.
+      return false;
+    } else {
+      // For non-builtin class loaders, we cannot complete the verification check at dump time,
+      // because at dump time we don't know how to resolve classes for such loaders.
+      return true;
+    }
   }
 }
 
@@ -1139,9 +1262,9 @@
 
   if (log_is_enabled(Trace, cds, verification)) {
     ResourceMark rm;
-    log_trace(cds, verification)("add_verification_constraint: %s: %s must be subclass of %s",
+    log_trace(cds, verification)("add_verification_constraint: %s: %s must be subclass of %s [0x%x]",
                                  k->external_name(), from_name->as_klass_external_name(),
-                                 name->as_klass_external_name());
+                                 name->as_klass_external_name(), c);
   }
 }
 
@@ -1157,6 +1280,13 @@
       Symbol* from_name = record->get_constraint_from_name(i);
       char c            = record->get_constraint_flag(i);
 
+      if (log_is_enabled(Trace, cds, verification)) {
+        ResourceMark rm(THREAD);
+        log_trace(cds, verification)("check_verification_constraint: %s: %s must be subclass of %s [0x%x]",
+                                     klass->external_name(), from_name->as_klass_external_name(),
+                                     name->as_klass_external_name(), c);
+      }
+
       bool from_field_is_protected = (c & SystemDictionaryShared::FROM_FIELD_IS_PROTECTED) ? true : false;
       bool from_is_array           = (c & SystemDictionaryShared::FROM_IS_ARRAY)           ? true : false;
       bool from_is_object          = (c & SystemDictionaryShared::FROM_IS_OBJECT)          ? true : false;
@@ -1178,22 +1308,72 @@
   }
 }
 
+class EstimateSizeForArchive : StackObj {
+  size_t _shared_class_info_size;
+  int _num_builtin_klasses;
+  int _num_unregistered_klasses;
+
+public:
+  EstimateSizeForArchive() {
+    _shared_class_info_size = 0;
+    _num_builtin_klasses = 0;
+    _num_unregistered_klasses = 0;
+  }
+
+  bool do_entry(InstanceKlass* k, DumpTimeSharedClassInfo& info) {
+    if (!info.is_excluded()) {
+      size_t byte_size = RunTimeSharedClassInfo::byte_size(info._klass, info.num_constraints());
+      _shared_class_info_size += align_up(byte_size, BytesPerWord);
+    }
+    return true; // keep on iterating
+  }
+
+  size_t total() {
+    return _shared_class_info_size;
+  }
+};
+
+size_t SystemDictionaryShared::estimate_size_for_archive() {
+  EstimateSizeForArchive est;
+  _dumptime_table->iterate(&est);
+  return est.total() +
+    CompactHashtableWriter::estimate_size(_dumptime_table->count_of(true)) +
+    CompactHashtableWriter::estimate_size(_dumptime_table->count_of(false));
+}
+
 class CopySharedClassInfoToArchive : StackObj {
   CompactHashtableWriter* _writer;
   bool _is_builtin;
 public:
-  CopySharedClassInfoToArchive(CompactHashtableWriter* writer, bool is_builtin)
+  CopySharedClassInfoToArchive(CompactHashtableWriter* writer,
+                               bool is_builtin,
+                               bool is_static_archive)
     : _writer(writer), _is_builtin(is_builtin) {}
 
   bool do_entry(InstanceKlass* k, DumpTimeSharedClassInfo& info) {
-    if (!info._excluded && info.is_builtin() == _is_builtin) {
+    if (!info.is_excluded() && info.is_builtin() == _is_builtin) {
       size_t byte_size = RunTimeSharedClassInfo::byte_size(info._klass, info.num_constraints());
-      RunTimeSharedClassInfo* record =
-        (RunTimeSharedClassInfo*)MetaspaceShared::read_only_space_alloc(byte_size);
+      RunTimeSharedClassInfo* record;
+      record = (RunTimeSharedClassInfo*)MetaspaceShared::read_only_space_alloc(byte_size);
       record->init(info);
 
-      unsigned int hash = primitive_hash<Symbol*>(info._klass->name());
-      _writer->add(hash, MetaspaceShared::object_delta_u4(record));
+      unsigned int hash;
+      Symbol* name = info._klass->name();
+      if (DynamicDumpSharedSpaces) {
+        name = DynamicArchive::original_to_target(name);
+      }
+      hash = primitive_hash<Symbol*>(name);
+      u4 delta;
+      if (DynamicDumpSharedSpaces) {
+        delta = MetaspaceShared::object_delta_u4(DynamicArchive::buffer_to_target(record));
+      } else {
+        delta = MetaspaceShared::object_delta_u4(record);
+      }
+      _writer->add(hash, delta);
+      if (log_is_enabled(Trace, cds, hashtables)) {
+        ResourceMark rm;
+        log_trace(cds,hashtables)("%s dictionary: %s", (_is_builtin ? "builtin" : "unregistered"), info._klass->external_name());
+      }
 
       // Save this for quick runtime lookup of InstanceKlass* -> RunTimeSharedClassInfo*
       RunTimeSharedClassInfo::set_for(info._klass, record);
@@ -1202,25 +1382,36 @@
   }
 };
 
-void SystemDictionaryShared::write_dictionary(RunTimeSharedDictionary* dictionary, bool is_builtin) {
+void SystemDictionaryShared::write_dictionary(RunTimeSharedDictionary* dictionary,
+                                              bool is_builtin,
+                                              bool is_static_archive) {
   CompactHashtableStats stats;
   dictionary->reset();
-  int num_buckets = CompactHashtableWriter::default_num_buckets(_dumptime_table->count_of(is_builtin));
-  CompactHashtableWriter writer(num_buckets, &stats);
-  CopySharedClassInfoToArchive copy(&writer, is_builtin);
+  CompactHashtableWriter writer(_dumptime_table->count_of(is_builtin), &stats);
+  CopySharedClassInfoToArchive copy(&writer, is_builtin, is_static_archive);
   _dumptime_table->iterate(&copy);
   writer.dump(dictionary, is_builtin ? "builtin dictionary" : "unregistered dictionary");
 }
 
-void SystemDictionaryShared::write_to_archive() {
-  _dumptime_table->update_counts();
-  write_dictionary(&_builtin_dictionary, true);
-  write_dictionary(&_unregistered_dictionary, false);
+void SystemDictionaryShared::write_to_archive(bool is_static_archive) {
+  if (is_static_archive) {
+    write_dictionary(&_builtin_dictionary, true);
+    write_dictionary(&_unregistered_dictionary, false);
+  } else {
+    write_dictionary(&_dynamic_builtin_dictionary, true);
+    write_dictionary(&_dynamic_unregistered_dictionary, false);
+  }
 }
 
-void SystemDictionaryShared::serialize_dictionary_headers(SerializeClosure* soc) {
-  _builtin_dictionary.serialize_header(soc);
-  _unregistered_dictionary.serialize_header(soc);
+void SystemDictionaryShared::serialize_dictionary_headers(SerializeClosure* soc,
+                                                          bool is_static_archive) {
+  if (is_static_archive) {
+    _builtin_dictionary.serialize_header(soc);
+    _unregistered_dictionary.serialize_header(soc);
+  } else {
+    _dynamic_builtin_dictionary.serialize_header(soc);
+    _dynamic_unregistered_dictionary.serialize_header(soc);
+  }
 }
 
 const RunTimeSharedClassInfo*
@@ -1237,9 +1428,16 @@
   const RunTimeSharedClassInfo* record = find_record(&_builtin_dictionary, name);
   if (record) {
     return record->_klass;
-  } else {
-    return NULL;
   }
+
+  if (DynamicArchive::is_mapped()) {
+    record = find_record(&_dynamic_builtin_dictionary, name);
+    if (record) {
+      return record->_klass;
+    }
+  }
+
+  return NULL;
 }
 
 void SystemDictionaryShared::update_shared_entry(InstanceKlass* k, int id) {
@@ -1266,14 +1464,31 @@
     SharedDictionaryPrinter p(st);
     _builtin_dictionary.iterate(&p);
     _unregistered_dictionary.iterate(&p);
+    if (DynamicArchive::is_mapped()) {
+      _dynamic_builtin_dictionary.iterate(&p);
+      _unregistered_dictionary.iterate(&p);
+    }
   }
 }
 
-void SystemDictionaryShared::print() { print_on(tty); }
-
 void SystemDictionaryShared::print_table_statistics(outputStream* st) {
   if (UseSharedSpaces) {
     _builtin_dictionary.print_table_statistics(st, "Builtin Shared Dictionary");
     _unregistered_dictionary.print_table_statistics(st, "Unregistered Shared Dictionary");
+    if (DynamicArchive::is_mapped()) {
+      _dynamic_builtin_dictionary.print_table_statistics(st, "Dynamic Builtin Shared Dictionary");
+      _dynamic_unregistered_dictionary.print_table_statistics(st, "Unregistered Shared Dictionary");
+    }
   }
 }
+
+bool SystemDictionaryShared::empty_dumptime_table() {
+  if (_dumptime_table == NULL) {
+    return true;
+  }
+  _dumptime_table->update_counts();
+  if (_dumptime_table->count_of(true) == 0 && _dumptime_table->count_of(false) == 0){
+    return true;
+  }
+  return false;
+}
--- a/src/hotspot/share/classfile/systemDictionaryShared.hpp	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/share/classfile/systemDictionaryShared.hpp	Thu May 23 11:07:37 2019 +0100
@@ -109,6 +109,7 @@
 class RunTimeSharedDictionary;
 
 class SystemDictionaryShared: public SystemDictionary {
+  friend class ExcludeDumpTimeSharedClasses;
 public:
   enum {
     FROM_FIELD_IS_PROTECTED = 1 << 0,
@@ -211,16 +212,21 @@
                                  const ClassFileStream* cfs,
                                  TRAPS);
   static DumpTimeSharedClassInfo* find_or_allocate_info_for(InstanceKlass* k);
-  static void write_dictionary(RunTimeSharedDictionary* dictionary, bool is_builtin);
+  static void write_dictionary(RunTimeSharedDictionary* dictionary,
+                               bool is_builtin,
+                               bool is_static_archive = true);
   static bool is_jfr_event_class(InstanceKlass *k);
   static void warn_excluded(InstanceKlass* k, const char* reason);
+  static bool should_be_excluded(InstanceKlass* k);
 
-  DEBUG_ONLY(static bool _checked_excluded_classes;)
+  DEBUG_ONLY(static bool _no_class_loading_should_happen;)
 public:
   static InstanceKlass* find_builtin_class(Symbol* class_name);
 
   static const RunTimeSharedClassInfo* find_record(RunTimeSharedDictionary* dict, Symbol* name);
 
+  static bool has_platform_or_app_classes();
+
   // Called by PLATFORM/APP loader only
   static InstanceKlass* find_or_load_shared_class(Symbol* class_name,
                                                Handle class_loader,
@@ -288,18 +294,34 @@
   static bool is_builtin(InstanceKlass* k) {
     return (k->shared_classpath_index() != UNREGISTERED_INDEX);
   }
-  static bool should_be_excluded(InstanceKlass* k);
   static void check_excluded_classes();
   static void validate_before_archiving(InstanceKlass* k);
   static bool is_excluded_class(InstanceKlass* k);
   static void dumptime_classes_do(class MetaspaceClosure* it);
-  static void write_to_archive();
-  static void serialize_dictionary_headers(class SerializeClosure* soc);
-  static void print();
+  static size_t estimate_size_for_archive();
+  static void write_to_archive(bool is_static_archive = true);
+  static void serialize_dictionary_headers(class SerializeClosure* soc,
+                                           bool is_static_archive = true);
+  static void print() { return print_on(tty); }
   static void print_on(outputStream* st) NOT_CDS_RETURN;
   static void print_table_statistics(outputStream* st) NOT_CDS_RETURN;
+  static bool empty_dumptime_table() NOT_CDS_RETURN_(true);
 
-  DEBUG_ONLY(static bool checked_excluded_classes() {return _checked_excluded_classes;})
+  DEBUG_ONLY(static bool no_class_loading_should_happen() {return _no_class_loading_should_happen;})
+
+#ifdef ASSERT
+  class NoClassLoadingMark: public StackObj {
+  public:
+    NoClassLoadingMark() {
+      assert(!_no_class_loading_should_happen, "must not be nested");
+      _no_class_loading_should_happen = true;
+    }
+    ~NoClassLoadingMark() {
+      _no_class_loading_should_happen = false;
+    }
+  };
+#endif
+
 };
 
 #endif // SHARE_CLASSFILE_SYSTEMDICTIONARYSHARED_HPP
--- a/src/hotspot/share/classfile/verificationType.cpp	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/share/classfile/verificationType.cpp	Thu May 23 11:07:37 2019 +0100
@@ -94,12 +94,14 @@
       return true;
     }
 
-    if (DumpSharedSpaces && SystemDictionaryShared::add_verification_constraint(klass,
+    if (DumpSharedSpaces || DynamicDumpSharedSpaces) {
+      if (SystemDictionaryShared::add_verification_constraint(klass,
               name(), from.name(), from_field_is_protected, from.is_array(),
               from.is_object())) {
-      // If add_verification_constraint() returns true, the resolution/check should be
-      // delayed until runtime.
-      return true;
+        // If add_verification_constraint() returns true, the resolution/check should be
+        // delayed until runtime.
+        return true;
+      }
     }
 
     return resolve_and_check_assignability(klass, name(), from.name(),
--- a/src/hotspot/share/code/codeBlob.cpp	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/share/code/codeBlob.cpp	Thu May 23 11:07:37 2019 +0100
@@ -183,8 +183,14 @@
     jio_snprintf(stub_id, sizeof(stub_id), "%s%s", name1, name2);
     if (PrintStubCode) {
       ttyLocker ttyl;
+      tty->print_cr("- - - [BEGIN] - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
       tty->print_cr("Decoding %s " INTPTR_FORMAT, stub_id, (intptr_t) stub);
-      Disassembler::decode(stub->code_begin(), stub->code_end());
+      Disassembler::decode(stub->code_begin(), stub->code_end(), tty);
+      if ((stub->oop_maps() != NULL) && AbstractDisassembler::show_structs()) {
+        tty->print_cr("- - - [OOP MAPS]- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
+        stub->oop_maps()->print();
+      }
+      tty->print_cr("- - - [END] - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
       tty->cr();
     }
     Forte::register_stub(stub_id, stub->code_begin(), stub->code_end());
@@ -263,6 +269,7 @@
 }
 
 void BufferBlob::free(BufferBlob *blob) {
+  assert(blob != NULL, "caller must check for NULL");
   ThreadInVMfromUnknown __tiv;  // get to VM state in case we block on CodeCache_lock
   blob->flush();
   {
--- a/src/hotspot/share/code/codeBlob.hpp	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/share/code/codeBlob.hpp	Thu May 23 11:07:37 2019 +0100
@@ -211,7 +211,7 @@
   const ImmutableOopMap* oop_map_for_return_address(address return_address);
   virtual void preserve_callee_argument_oops(frame fr, const RegisterMap* reg_map, OopClosure* f) = 0;
 
-  // Frame support
+  // Frame support. Sizes are in word units.
   int  frame_size() const                        { return _frame_size; }
   void set_frame_size(int size)                  { _frame_size = size; }
 
@@ -230,6 +230,10 @@
   void dump_for_addr(address addr, outputStream* st, bool verbose) const;
   void print_code();
 
+  bool has_block_comment(address block_begin) const {
+    intptr_t offset = (intptr_t)(block_begin - code_begin());
+    return _strings.has_block_comment(offset);
+  }
   // Print the comment associated with offset on stream, if there is one
   virtual void print_block_comment(outputStream* stream, address block_begin) const {
     intptr_t offset = (intptr_t)(block_begin - code_begin());
--- a/src/hotspot/share/code/codeCache.cpp	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/share/code/codeCache.cpp	Thu May 23 11:07:37 2019 +0100
@@ -283,9 +283,9 @@
 
   // Verify sizes and update flag values
   assert(non_profiled_size + profiled_size + non_nmethod_size == cache_size, "Invalid code heap sizes");
-  FLAG_SET_ERGO(uintx, NonNMethodCodeHeapSize, non_nmethod_size);
-  FLAG_SET_ERGO(uintx, ProfiledCodeHeapSize, profiled_size);
-  FLAG_SET_ERGO(uintx, NonProfiledCodeHeapSize, non_profiled_size);
+  FLAG_SET_ERGO(NonNMethodCodeHeapSize, non_nmethod_size);
+  FLAG_SET_ERGO(ProfiledCodeHeapSize, profiled_size);
+  FLAG_SET_ERGO(NonProfiledCodeHeapSize, non_profiled_size);
 
   // If large page support is enabled, align code heaps according to large
   // page size to make sure that code cache is covered by large pages.
@@ -941,9 +941,9 @@
     initialize_heaps();
   } else {
     // Use a single code heap
-    FLAG_SET_ERGO(uintx, NonNMethodCodeHeapSize, 0);
-    FLAG_SET_ERGO(uintx, ProfiledCodeHeapSize, 0);
-    FLAG_SET_ERGO(uintx, NonProfiledCodeHeapSize, 0);
+    FLAG_SET_ERGO(NonNMethodCodeHeapSize, 0);
+    FLAG_SET_ERGO(ProfiledCodeHeapSize, 0);
+    FLAG_SET_ERGO(NonProfiledCodeHeapSize, 0);
     ReservedCodeSpace rs = reserve_heap_memory(ReservedCodeCacheSize);
     add_heap(rs, "CodeCache", CodeBlobType::All);
   }
--- a/src/hotspot/share/code/codeHeapState.cpp	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/share/code/codeHeapState.cpp	Thu May 23 11:07:37 2019 +0100
@@ -124,7 +124,7 @@
     size_t     _nlockedflush = 0;                             \
     size_t     _nflush_bytes = 0;                             \
     size_t         _capacity = _capa;                         \
-    bufferedStream   _sstobj = bufferedStream(_capa);         \
+    bufferedStream   _sstobj(_capa);                          \
     bufferedStream*  _sstbuf = &_sstobj;                      \
     outputStream*    _outbuf = _outst;                        \
     bufferedStream*   _anyst = &_sstobj; /* any stream. Use this to just print - no buffer flush.  */
--- a/src/hotspot/share/code/exceptionHandlerTable.cpp	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/share/code/exceptionHandlerTable.cpp	Thu May 23 11:07:37 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2019, 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
@@ -185,10 +185,24 @@
 }
 
 void ImplicitExceptionTable::print(address base) const {
-  tty->print("{");
-  for( uint i=0; i<len(); i++ )
-    tty->print("< " INTPTR_FORMAT ", " INTPTR_FORMAT " > ", p2i(base + *adr(i)), p2i(base + *(adr(i)+1)));
-  tty->print_cr("}");
+  const uint n = len();
+  if (n > 0) {
+    const uint items_per_line = 3;
+    uint i;
+    tty->print_cr("ImplicitExceptionTable (size = %d entries, %d bytes):", n, size_in_bytes());
+    tty->print("{");
+    for (i = 0; i < n; i++) {
+      if (i%items_per_line == 0) {
+        tty->cr();
+        tty->fill_to(3);
+      }
+      tty->print("< " INTPTR_FORMAT ", " INTPTR_FORMAT " > ", p2i(base + *adr(i)), p2i(base + *(adr(i)+1)));
+    }
+    tty->bol();
+    tty->print_cr("}");
+  } else {
+    tty->print_cr("ImplicitExceptionTable is empty");
+  }
 }
 
 ImplicitExceptionTable::ImplicitExceptionTable(const nmethod* nm) {
--- a/src/hotspot/share/code/nmethod.cpp	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/share/code/nmethod.cpp	Thu May 23 11:07:37 2019 +0100
@@ -24,6 +24,7 @@
 
 #include "precompiled.hpp"
 #include "jvm.h"
+#include "asm/assembler.inline.hpp"
 #include "code/codeCache.hpp"
 #include "code/compiledIC.hpp"
 #include "code/compiledMethod.inline.hpp"
@@ -456,14 +457,17 @@
   {
     MutexLocker mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
     int native_nmethod_size = CodeBlob::allocation_size(code_buffer, sizeof(nmethod));
+
     CodeOffsets offsets;
     offsets.set_value(CodeOffsets::Verified_Entry, vep_offset);
     offsets.set_value(CodeOffsets::Frame_Complete, frame_complete);
-    nm = new (native_nmethod_size, CompLevel_none) nmethod(method(), compiler_none, native_nmethod_size,
-                                            compile_id, &offsets,
-                                            code_buffer, frame_size,
-                                            basic_lock_owner_sp_offset,
-                                            basic_lock_sp_offset, oop_maps);
+    nm = new (native_nmethod_size, CompLevel_none)
+    nmethod(method(), compiler_none, native_nmethod_size,
+            compile_id, &offsets,
+            code_buffer, frame_size,
+            basic_lock_owner_sp_offset,
+            basic_lock_sp_offset,
+            oop_maps);
     NOT_PRODUCT(if (nm != NULL)  native_nmethod_stats.note_native_nmethod(nm));
   }
 
@@ -593,9 +597,9 @@
   _native_basic_lock_sp_offset(basic_lock_sp_offset)
 {
   {
-    int scopes_data_offset = 0;
-    int deoptimize_offset       = 0;
-    int deoptimize_mh_offset    = 0;
+    int scopes_data_offset   = 0;
+    int deoptimize_offset    = 0;
+    int deoptimize_mh_offset = 0;
 
     debug_only(NoSafepointVerifier nsv;)
     assert_locked_or_safepoint(CodeCache_lock);
@@ -658,18 +662,32 @@
       xtty->stamp();
       xtty->end_head(" address='" INTPTR_FORMAT "'", (intptr_t) this);
     }
-    // print the header part first
-    print();
-    // then print the requested information
+    // Print the header part, then print the requested information.
+    // This is both handled in decode2(), called via print_code() -> decode()
     if (PrintNativeNMethods) {
+      tty->print_cr("-------------------------- Assembly (native nmethod) ---------------------------");
       print_code();
-      if (oop_maps != NULL) {
-        oop_maps->print();
+      tty->print_cr("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ");
+#if defined(SUPPORT_DATA_STRUCTS)
+      if (AbstractDisassembler::show_structs()) {
+        if (oop_maps != NULL) {
+          tty->print("oop maps:"); // oop_maps->print_on(tty) outputs a cr() at the beginning
+          oop_maps->print_on(tty);
+          tty->print_cr("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ");
+        }
+      }
+#endif
+    } else {
+      print(); // print the header part only.
+    }
+#if defined(SUPPORT_DATA_STRUCTS)
+    if (AbstractDisassembler::show_structs()) {
+      if (PrintRelocations) {
+        print_relocations();
+        tty->print_cr("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ");
       }
     }
-    if (PrintRelocations) {
-      print_relocations();
-    }
+#endif
     if (xtty != NULL) {
       xtty->tail("print_native_nmethod");
     }
@@ -746,22 +764,21 @@
       } else {
         _deopt_mh_handler_begin = NULL;
       }
-    } else {
+    } else
 #endif
-    // Exception handler and deopt handler are in the stub section
-    assert(offsets->value(CodeOffsets::Exceptions) != -1, "must be set");
-    assert(offsets->value(CodeOffsets::Deopt     ) != -1, "must be set");
-
-    _exception_offset       = _stub_offset          + offsets->value(CodeOffsets::Exceptions);
-    _deopt_handler_begin    = (address) this + _stub_offset          + offsets->value(CodeOffsets::Deopt);
-    if (offsets->value(CodeOffsets::DeoptMH) != -1) {
-      _deopt_mh_handler_begin  = (address) this + _stub_offset          + offsets->value(CodeOffsets::DeoptMH);
-    } else {
-      _deopt_mh_handler_begin  = NULL;
+    {
+      // Exception handler and deopt handler are in the stub section
+      assert(offsets->value(CodeOffsets::Exceptions) != -1, "must be set");
+      assert(offsets->value(CodeOffsets::Deopt     ) != -1, "must be set");
+
+      _exception_offset       = _stub_offset          + offsets->value(CodeOffsets::Exceptions);
+      _deopt_handler_begin    = (address) this + _stub_offset          + offsets->value(CodeOffsets::Deopt);
+      if (offsets->value(CodeOffsets::DeoptMH) != -1) {
+        _deopt_mh_handler_begin  = (address) this + _stub_offset          + offsets->value(CodeOffsets::DeoptMH);
+      } else {
+        _deopt_mh_handler_begin  = NULL;
+      }
     }
-#if INCLUDE_JVMCI
-    }
-#endif
     if (offsets->value(CodeOffsets::UnwindHandler) != -1) {
       _unwind_handler_offset = code_offset()         + offsets->value(CodeOffsets::UnwindHandler);
     } else {
@@ -787,8 +804,7 @@
     _verified_entry_point    = code_begin()          + offsets->value(CodeOffsets::Verified_Entry);
     _osr_entry_point         = code_begin()          + offsets->value(CodeOffsets::OSR_Entry);
     _exception_cache         = NULL;
-
-    _scopes_data_begin = (address) this + scopes_data_offset;
+    _scopes_data_begin       = (address) this + scopes_data_offset;
 
     _pc_desc_container.reset_to(scopes_pcs_begin());
 
@@ -909,33 +925,72 @@
     xtty->stamp();
     xtty->end_head();
   }
-  // print the header part first
-  print();
-  // then print the requested information
+  // Print the header part, then print the requested information.
+  // This is both handled in decode2().
   if (printmethod) {
-    print_code();
-    print_pcs();
-    if (oop_maps()) {
-      oop_maps()->print();
+    HandleMark hm;
+    ResourceMark m;
+    if (is_compiled_by_c1()) {
+      tty->cr();
+      tty->print_cr("============================= C1-compiled nmethod ==============================");
+    }
+    if (is_compiled_by_jvmci()) {
+      tty->cr();
+      tty->print_cr("=========================== JVMCI-compiled nmethod =============================");
+    }
+    tty->print_cr("----------------------------------- Assembly -----------------------------------");
+    decode2(tty);
+#if defined(SUPPORT_DATA_STRUCTS)
+    if (AbstractDisassembler::show_structs()) {
+      // Print the oops from the underlying CodeBlob as well.
+      tty->print_cr("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ");
+      print_oops(tty);
+      tty->print_cr("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ");
+      print_metadata(tty);
+      tty->print_cr("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ");
+      print_pcs();
+      tty->print_cr("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ");
+      if (oop_maps() != NULL) {
+        tty->print("oop maps:"); // oop_maps()->print_on(tty) outputs a cr() at the beginning
+        oop_maps()->print_on(tty);
+        tty->print_cr("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ");
+      }
+    }
+#endif
+  } else {
+    print(); // print the header part only.
+  }
+
+#if defined(SUPPORT_DATA_STRUCTS)
+  if (AbstractDisassembler::show_structs()) {
+    if (printmethod || PrintDebugInfo || CompilerOracle::has_option_string(_method, "PrintDebugInfo")) {
+      print_scopes();
+      tty->print_cr("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ");
+    }
+    if (printmethod || PrintRelocations || CompilerOracle::has_option_string(_method, "PrintRelocations")) {
+      print_relocations();
+      tty->print_cr("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ");
+    }
+    if (printmethod || PrintDependencies || CompilerOracle::has_option_string(_method, "PrintDependencies")) {
+      print_dependencies();
+      tty->print_cr("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ");
+    }
+    if (printmethod || PrintExceptionHandlers) {
+      print_handler_table();
+      tty->print_cr("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ");
+      print_nul_chk_table();
+      tty->print_cr("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ");
+    }
+
+    if (printmethod) {
+      print_recorded_oops();
+      tty->print_cr("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ");
+      print_recorded_metadata();
+      tty->print_cr("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ");
     }
   }
-  if (printmethod || PrintDebugInfo || CompilerOracle::has_option_string(_method, "PrintDebugInfo")) {
-    print_scopes();
-  }
-  if (printmethod || PrintRelocations || CompilerOracle::has_option_string(_method, "PrintRelocations")) {
-    print_relocations();
-  }
-  if (printmethod || PrintDependencies || CompilerOracle::has_option_string(_method, "PrintDependencies")) {
-    print_dependencies();
-  }
-  if (printmethod || PrintExceptionHandlers) {
-    print_handler_table();
-    print_nul_chk_table();
-  }
-  if (printmethod) {
-    print_recorded_oops();
-    print_recorded_metadata();
-  }
+#endif
+
   if (xtty != NULL) {
     xtty->tail("print_nmethod");
   }
@@ -2062,10 +2117,9 @@
     assert(cb != NULL && cb == this, "");
     ttyLocker ttyl;
     tty->print_cr("implicit exception happened at " INTPTR_FORMAT, p2i(pc));
-    print();
+    // Print all available nmethod info.
+    print_nmethod(true);
     method()->print_codes();
-    print_code();
-    print_pcs();
   }
 #endif
   if (cont_offset == 0) {
@@ -2076,7 +2130,6 @@
 }
 
 
-
 void nmethod_init() {
   // make sure you didn't forget to adjust the filler fields
   assert(sizeof(nmethod) % oopSize == 0, "nmethod size must be multiple of a word");
@@ -2124,12 +2177,14 @@
   bool ok() { return _ok; }
   virtual void do_oop(oop* p) {
     if (oopDesc::is_oop_or_null(*p)) return;
+    // Print diagnostic information before calling print_nmethod().
+    // Assertions therein might prevent call from returning.
+    tty->print_cr("*** non-oop " PTR_FORMAT " found at " PTR_FORMAT " (offset %d)",
+                  p2i(*p), p2i(p), (int)((intptr_t)p - (intptr_t)_nm));
     if (_ok) {
       _nm->print_nmethod(true);
       _ok = false;
     }
-    tty->print_cr("*** non-oop " PTR_FORMAT " found at " PTR_FORMAT " (offset %d)",
-                  p2i(*p), p2i(p), (int)((intptr_t)p - (intptr_t)_nm));
   }
   virtual void do_oop(narrowOop* p) { ShouldNotReachHere(); }
 };
@@ -2238,107 +2293,104 @@
 // Printing operations
 
 void nmethod::print() const {
+  ttyLocker ttyl;   // keep the following output all in one block
+  print(tty);
+}
+
+void nmethod::print(outputStream* st) const {
   ResourceMark rm;
-  ttyLocker ttyl;   // keep the following output all in one block
-
-  tty->print("Compiled method ");
+
+  st->print("Compiled method ");
 
   if (is_compiled_by_c1()) {
-    tty->print("(c1) ");
+    st->print("(c1) ");
   } else if (is_compiled_by_c2()) {
-    tty->print("(c2) ");
+    st->print("(c2) ");
   } else if (is_compiled_by_jvmci()) {
-    tty->print("(JVMCI) ");
+    st->print("(JVMCI) ");
   } else {
-    tty->print("(nm) ");
+    st->print("(n/a) ");
   }
 
   print_on(tty, NULL);
 
   if (WizardMode) {
-    tty->print("((nmethod*) " INTPTR_FORMAT ") ", p2i(this));
-    tty->print(" for method " INTPTR_FORMAT , p2i(method()));
-    tty->print(" { ");
-    tty->print_cr("%s ", state());
-    tty->print_cr("}:");
+    st->print("((nmethod*) " INTPTR_FORMAT ") ", p2i(this));
+    st->print(" for method " INTPTR_FORMAT , p2i(method()));
+    st->print(" { ");
+    st->print_cr("%s ", state());
+    st->print_cr("}:");
   }
-  if (size              () > 0) tty->print_cr(" total in heap  [" INTPTR_FORMAT "," INTPTR_FORMAT "] = %d",
-                                              p2i(this),
-                                              p2i(this) + size(),
-                                              size());
-  if (relocation_size   () > 0) tty->print_cr(" relocation     [" INTPTR_FORMAT "," INTPTR_FORMAT "] = %d",
-                                              p2i(relocation_begin()),
-                                              p2i(relocation_end()),
-                                              relocation_size());
-  if (consts_size       () > 0) tty->print_cr(" constants      [" INTPTR_FORMAT "," INTPTR_FORMAT "] = %d",
-                                              p2i(consts_begin()),
-                                              p2i(consts_end()),
-                                              consts_size());
-  if (insts_size        () > 0) tty->print_cr(" main code      [" INTPTR_FORMAT "," INTPTR_FORMAT "] = %d",
-                                              p2i(insts_begin()),
-                                              p2i(insts_end()),
-                                              insts_size());
-  if (stub_size         () > 0) tty->print_cr(" stub code      [" INTPTR_FORMAT "," INTPTR_FORMAT "] = %d",
-                                              p2i(stub_begin()),
-                                              p2i(stub_end()),
-                                              stub_size());
-  if (oops_size         () > 0) tty->print_cr(" oops           [" INTPTR_FORMAT "," INTPTR_FORMAT "] = %d",
-                                              p2i(oops_begin()),
-                                              p2i(oops_end()),
-                                              oops_size());
-  if (metadata_size      () > 0) tty->print_cr(" metadata       [" INTPTR_FORMAT "," INTPTR_FORMAT "] = %d",
-                                              p2i(metadata_begin()),
-                                              p2i(metadata_end()),
-                                              metadata_size());
-  if (scopes_data_size  () > 0) tty->print_cr(" scopes data    [" INTPTR_FORMAT "," INTPTR_FORMAT "] = %d",
-                                              p2i(scopes_data_begin()),
-                                              p2i(scopes_data_end()),
-                                              scopes_data_size());
-  if (scopes_pcs_size   () > 0) tty->print_cr(" scopes pcs     [" INTPTR_FORMAT "," INTPTR_FORMAT "] = %d",
-                                              p2i(scopes_pcs_begin()),
-                                              p2i(scopes_pcs_end()),
-                                              scopes_pcs_size());
-  if (dependencies_size () > 0) tty->print_cr(" dependencies   [" INTPTR_FORMAT "," INTPTR_FORMAT "] = %d",
-                                              p2i(dependencies_begin()),
-                                              p2i(dependencies_end()),
-                                              dependencies_size());
-  if (handler_table_size() > 0) tty->print_cr(" handler table  [" INTPTR_FORMAT "," INTPTR_FORMAT "] = %d",
-                                              p2i(handler_table_begin()),
-                                              p2i(handler_table_end()),
-                                              handler_table_size());
-  if (nul_chk_table_size() > 0) tty->print_cr(" nul chk table  [" INTPTR_FORMAT "," INTPTR_FORMAT "] = %d",
-                                              p2i(nul_chk_table_begin()),
-                                              p2i(nul_chk_table_end()),
-                                              nul_chk_table_size());
+  if (size              () > 0) st->print_cr(" total in heap  [" INTPTR_FORMAT "," INTPTR_FORMAT "] = %d",
+                                             p2i(this),
+                                             p2i(this) + size(),
+                                             size());
+  if (relocation_size   () > 0) st->print_cr(" relocation     [" INTPTR_FORMAT "," INTPTR_FORMAT "] = %d",
+                                             p2i(relocation_begin()),
+                                             p2i(relocation_end()),
+                                             relocation_size());
+  if (consts_size       () > 0) st->print_cr(" constants      [" INTPTR_FORMAT "," INTPTR_FORMAT "] = %d",
+                                             p2i(consts_begin()),
+                                             p2i(consts_end()),
+                                             consts_size());
+  if (insts_size        () > 0) st->print_cr(" main code      [" INTPTR_FORMAT "," INTPTR_FORMAT "] = %d",
+                                             p2i(insts_begin()),
+                                             p2i(insts_end()),
+                                             insts_size());
+  if (stub_size         () > 0) st->print_cr(" stub code      [" INTPTR_FORMAT "," INTPTR_FORMAT "] = %d",
+                                             p2i(stub_begin()),
+                                             p2i(stub_end()),
+                                             stub_size());
+  if (oops_size         () > 0) st->print_cr(" oops           [" INTPTR_FORMAT "," INTPTR_FORMAT "] = %d",
+                                             p2i(oops_begin()),
+                                             p2i(oops_end()),
+                                             oops_size());
+  if (metadata_size     () > 0) st->print_cr(" metadata       [" INTPTR_FORMAT "," INTPTR_FORMAT "] = %d",
+                                             p2i(metadata_begin()),
+                                             p2i(metadata_end()),
+                                             metadata_size());
+  if (scopes_data_size  () > 0) st->print_cr(" scopes data    [" INTPTR_FORMAT "," INTPTR_FORMAT "] = %d",
+                                             p2i(scopes_data_begin()),
+                                             p2i(scopes_data_end()),
+                                             scopes_data_size());
+  if (scopes_pcs_size   () > 0) st->print_cr(" scopes pcs     [" INTPTR_FORMAT "," INTPTR_FORMAT "] = %d",
+                                             p2i(scopes_pcs_begin()),
+                                             p2i(scopes_pcs_end()),
+                                             scopes_pcs_size());
+  if (dependencies_size () > 0) st->print_cr(" dependencies   [" INTPTR_FORMAT "," INTPTR_FORMAT "] = %d",
+                                             p2i(dependencies_begin()),
+                                             p2i(dependencies_end()),
+                                             dependencies_size());
+  if (handler_table_size() > 0) st->print_cr(" handler table  [" INTPTR_FORMAT "," INTPTR_FORMAT "] = %d",
+                                             p2i(handler_table_begin()),
+                                             p2i(handler_table_end()),
+                                             handler_table_size());
+  if (nul_chk_table_size() > 0) st->print_cr(" nul chk table  [" INTPTR_FORMAT "," INTPTR_FORMAT "] = %d",
+                                             p2i(nul_chk_table_begin()),
+                                             p2i(nul_chk_table_end()),
+                                             nul_chk_table_size());
 #if INCLUDE_JVMCI
-  if (speculations_size () > 0) tty->print_cr(" speculations   [" INTPTR_FORMAT "," INTPTR_FORMAT "] = %d",
-                                              p2i(speculations_begin()),
-                                              p2i(speculations_end()),
-                                              speculations_size());
-  if (jvmci_data_size   () > 0) tty->print_cr(" JVMCI data     [" INTPTR_FORMAT "," INTPTR_FORMAT "] = %d",
-                                              p2i(jvmci_data_begin()),
-                                              p2i(jvmci_data_end()),
-                                              jvmci_data_size());
+  if (speculations_size () > 0) st->print_cr(" speculations   [" INTPTR_FORMAT "," INTPTR_FORMAT "] = %d",
+                                             p2i(speculations_begin()),
+                                             p2i(speculations_end()),
+                                             speculations_size());
+  if (jvmci_data_size   () > 0) st->print_cr(" JVMCI data     [" INTPTR_FORMAT "," INTPTR_FORMAT "] = %d",
+                                             p2i(jvmci_data_begin()),
+                                             p2i(jvmci_data_end()),
+                                             jvmci_data_size());
 #endif
 }
 
-#ifndef PRODUCT
-
-void nmethod::print_scopes() {
-  // Find the first pc desc for all scopes in the code and print it.
-  ResourceMark rm;
-  for (PcDesc* p = scopes_pcs_begin(); p < scopes_pcs_end(); p++) {
-    if (p->scope_decode_offset() == DebugInformationRecorder::serialized_null)
-      continue;
-
-    ScopeDesc* sd = scope_desc_at(p->real_pc(this));
-    while (sd != NULL) {
-      sd->print_on(tty, p);
-      sd = sd->sender();
-    }
-  }
+void nmethod::print_code() {
+  HandleMark hm;
+  ResourceMark m;
+  ttyLocker ttyl;
+  // Call the specialized decode method of this class.
+  decode(tty);
 }
 
+#ifndef PRODUCT  // called InstanceKlass methods are available only then. Declared as PRODUCT_RETURN
+
 void nmethod::print_dependencies() {
   ResourceMark rm;
   ttyLocker ttyl;   // keep the following output all in one block
@@ -2354,57 +2406,379 @@
     deps.log_dependency();  // put it into the xml log also
   }
 }
-
-
+#endif
+
+#if defined(SUPPORT_DATA_STRUCTS)
+
+// Print the oops from the underlying CodeBlob.
+void nmethod::print_oops(outputStream* st) {
+  HandleMark hm;
+  ResourceMark m;
+  st->print("Oops:");
+  if (oops_begin() < oops_end()) {
+    st->cr();
+    for (oop* p = oops_begin(); p < oops_end(); p++) {
+      Disassembler::print_location((unsigned char*)p, (unsigned char*)oops_begin(), (unsigned char*)oops_end(), st, true, false);
+      st->print(PTR_FORMAT " ", *((uintptr_t*)p));
+      if (*p == Universe::non_oop_word()) {
+        st->print_cr("NON_OOP");
+        continue;  // skip non-oops
+      }
+      if (*p == NULL) {
+        st->print_cr("NULL-oop");
+        continue;  // skip non-oops
+      }
+      (*p)->print_value_on(st);
+      st->cr();
+    }
+  } else {
+    st->print_cr(" <list empty>");
+  }
+}
+
+// Print metadata pool.
+void nmethod::print_metadata(outputStream* st) {
+  HandleMark hm;
+  ResourceMark m;
+  st->print("Metadata:");
+  if (metadata_begin() < metadata_end()) {
+    st->cr();
+    for (Metadata** p = metadata_begin(); p < metadata_end(); p++) {
+      Disassembler::print_location((unsigned char*)p, (unsigned char*)metadata_begin(), (unsigned char*)metadata_end(), st, true, false);
+      st->print(PTR_FORMAT " ", *((uintptr_t*)p));
+      if (*p && *p != Universe::non_oop_word()) {
+        (*p)->print_value_on(st);
+      }
+      st->cr();
+    }
+  } else {
+    st->print_cr(" <list empty>");
+  }
+}
+
+#ifndef PRODUCT  // ScopeDesc::print_on() is available only then. Declared as PRODUCT_RETURN
+void nmethod::print_scopes_on(outputStream* st) {
+  // Find the first pc desc for all scopes in the code and print it.
+  ResourceMark rm;
+  st->print("scopes:");
+  if (scopes_pcs_begin() < scopes_pcs_end()) {
+    st->cr();
+    for (PcDesc* p = scopes_pcs_begin(); p < scopes_pcs_end(); p++) {
+      if (p->scope_decode_offset() == DebugInformationRecorder::serialized_null)
+        continue;
+
+      ScopeDesc* sd = scope_desc_at(p->real_pc(this));
+      while (sd != NULL) {
+        sd->print_on(st, p);  // print output ends with a newline
+        sd = sd->sender();
+      }
+    }
+  } else {
+    st->print_cr(" <list empty>");
+  }
+}
+#endif
+
+#ifndef PRODUCT  // RelocIterator does support printing only then.
 void nmethod::print_relocations() {
   ResourceMark m;       // in case methods get printed via the debugger
   tty->print_cr("relocations:");
   RelocIterator iter(this);
   iter.print();
 }
-
-
-void nmethod::print_pcs() {
+#endif
+
+void nmethod::print_pcs_on(outputStream* st) {
   ResourceMark m;       // in case methods get printed via debugger
-  tty->print_cr("pc-bytecode offsets:");
-  for (PcDesc* p = scopes_pcs_begin(); p < scopes_pcs_end(); p++) {
-    p->print(this);
+  st->print("pc-bytecode offsets:");
+  if (scopes_pcs_begin() < scopes_pcs_end()) {
+    st->cr();
+    for (PcDesc* p = scopes_pcs_begin(); p < scopes_pcs_end(); p++) {
+      p->print_on(st, this);  // print output ends with a newline
+    }
+  } else {
+    st->print_cr(" <list empty>");
   }
 }
 
+void nmethod::print_handler_table() {
+  ExceptionHandlerTable(this).print();
+}
+
+void nmethod::print_nul_chk_table() {
+  ImplicitExceptionTable(this).print(code_begin());
+}
+
 void nmethod::print_recorded_oops() {
-  tty->print_cr("Recorded oops:");
-  for (int i = 0; i < oops_count(); i++) {
-    oop o = oop_at(i);
-    tty->print("#%3d: " INTPTR_FORMAT " ", i, p2i(o));
-    if (o == Universe::non_oop_word()) {
-      tty->print("non-oop word");
-    } else {
-      if (o != NULL) {
-        o->print_value();
+  const int n = oops_count();
+  const int log_n = (n<10) ? 1 : (n<100) ? 2 : (n<1000) ? 3 : (n<10000) ? 4 : 6;
+  tty->print("Recorded oops:");
+  if (n > 0) {
+    tty->cr();
+    for (int i = 0; i < n; i++) {
+      oop o = oop_at(i);
+      tty->print("#%*d: " INTPTR_FORMAT " ", log_n, i, p2i(o));
+      if (o == (oop)Universe::non_oop_word()) {
+        tty->print("non-oop word");
+      } else if (o == NULL) {
+        tty->print("NULL-oop");
       } else {
-        tty->print_cr("NULL");
+        o->print_value_on(tty);
       }
+      tty->cr();
     }
-    tty->cr();
+  } else {
+    tty->print_cr(" <list empty>");
   }
 }
 
 void nmethod::print_recorded_metadata() {
-  tty->print_cr("Recorded metadata:");
-  for (int i = 0; i < metadata_count(); i++) {
-    Metadata* m = metadata_at(i);
-    tty->print("#%3d: " INTPTR_FORMAT " ", i, p2i(m));
-    if (m == (Metadata*)Universe::non_oop_word()) {
-      tty->print("non-metadata word");
-    } else {
-      Metadata::print_value_on_maybe_null(tty, m);
+  const int n = metadata_count();
+  const int log_n = (n<10) ? 1 : (n<100) ? 2 : (n<1000) ? 3 : (n<10000) ? 4 : 6;
+  tty->print("Recorded metadata:");
+  if (n > 0) {
+    tty->cr();
+    for (int i = 0; i < n; i++) {
+      Metadata* m = metadata_at(i);
+      tty->print("#%*d: " INTPTR_FORMAT " ", log_n, i, p2i(m));
+      if (m == (Metadata*)Universe::non_oop_word()) {
+        tty->print("non-metadata word");
+      } else if (m == NULL) {
+        tty->print("NULL-oop");
+      } else {
+        Metadata::print_value_on_maybe_null(tty, m);
+      }
+      tty->cr();
     }
-    tty->cr();
+  } else {
+    tty->print_cr(" <list empty>");
   }
 }
-
-#endif // PRODUCT
+#endif
+
+#if defined(SUPPORT_ASSEMBLY) || defined(SUPPORT_ABSTRACT_ASSEMBLY)
+
+void nmethod::print_constant_pool(outputStream* st) {
+  //-----------------------------------
+  //---<  Print the constant pool  >---
+  //-----------------------------------
+  int consts_size = this->consts_size();
+  if ( consts_size > 0 ) {
+    unsigned char* cstart = this->consts_begin();
+    unsigned char* cp     = cstart;
+    unsigned char* cend   = cp + consts_size;
+    unsigned int   bytes_per_line = 4;
+    unsigned int   CP_alignment   = 8;
+    unsigned int   n;
+
+    st->cr();
+
+    //---<  print CP header to make clear what's printed  >---
+    if( ((uintptr_t)cp&(CP_alignment-1)) == 0 ) {
+      n = bytes_per_line;
+      st->print_cr("[Constant Pool]");
+      Disassembler::print_location(cp, cstart, cend, st, true, true);
+      Disassembler::print_hexdata(cp, n, st, true);
+      st->cr();
+    } else {
+      n = (uintptr_t)cp&(bytes_per_line-1);
+      st->print_cr("[Constant Pool (unaligned)]");
+    }
+
+    //---<  print CP contents, bytes_per_line at a time  >---
+    while (cp < cend) {
+      Disassembler::print_location(cp, cstart, cend, st, true, false);
+      Disassembler::print_hexdata(cp, n, st, false);
+      cp += n;
+      n   = bytes_per_line;
+      st->cr();
+    }
+
+    //---<  Show potential alignment gap between constant pool and code  >---
+    cend = code_begin();
+    if( cp < cend ) {
+      n = 4;
+      st->print_cr("[Code entry alignment]");
+      while (cp < cend) {
+        Disassembler::print_location(cp, cstart, cend, st, false, false);
+        cp += n;
+        st->cr();
+      }
+    }
+  } else {
+    st->print_cr("[Constant Pool (empty)]");
+  }
+  st->cr();
+}
+
+#endif
+
+// Disassemble this nmethod.
+// Print additional debug information, if requested. This could be code
+// comments, block comments, profiling counters, etc.
+// The undisassembled format is useful no disassembler library is available.
+// The resulting hex dump (with markers) can be disassembled later, or on
+// another system, when/where a disassembler library is available.
+void nmethod::decode2(outputStream* ost) const {
+
+  // Called from frame::back_trace_with_decode without ResourceMark.
+  ResourceMark rm;
+
+  // Make sure we have a valid stream to print on.
+  outputStream* st = ost ? ost : tty;
+
+#if defined(SUPPORT_ABSTRACT_ASSEMBLY) && ! defined(SUPPORT_ASSEMBLY)
+  const bool use_compressed_format    = true;
+  const bool compressed_with_comments = use_compressed_format && (AbstractDisassembler::show_comment() ||
+                                                                  AbstractDisassembler::show_block_comment());
+#else
+  const bool use_compressed_format    = Disassembler::is_abstract();
+  const bool compressed_with_comments = use_compressed_format && (AbstractDisassembler::show_comment() ||
+                                                                  AbstractDisassembler::show_block_comment());
+#endif
+
+  st->cr();
+  this->print(st);
+  st->cr();
+
+#if defined(SUPPORT_ASSEMBLY)
+  //----------------------------------
+  //---<  Print real disassembly  >---
+  //----------------------------------
+  if (! use_compressed_format) {
+    Disassembler::decode(const_cast<nmethod*>(this), st);
+    return;
+  }
+#endif
+
+#if defined(SUPPORT_ABSTRACT_ASSEMBLY)
+
+  // Compressed undisassembled disassembly format.
+  // The following stati are defined/supported:
+  //   = 0 - currently at bol() position, nothing printed yet on current line.
+  //   = 1 - currently at position after print_location().
+  //   > 1 - in the midst of printing instruction stream bytes.
+  int        compressed_format_idx    = 0;
+  int        code_comment_column      = 0;
+  const int  instr_maxlen             = Assembler::instr_maxlen();
+  const uint tabspacing               = 8;
+  unsigned char* start = this->code_begin();
+  unsigned char* p     = this->code_begin();
+  unsigned char* end   = this->code_end();
+  unsigned char* pss   = p; // start of a code section (used for offsets)
+
+  if ((start == NULL) || (end == NULL)) {
+    st->print_cr("PrintAssembly not possible due to uninitialized section pointers");
+    return;
+  }
+#endif
+
+#if defined(SUPPORT_ABSTRACT_ASSEMBLY)
+  //---<  plain abstract disassembly, no comments or anything, just section headers  >---
+  if (use_compressed_format && ! compressed_with_comments) {
+    const_cast<nmethod*>(this)->print_constant_pool(st);
+
+    //---<  Open the output (Marker for post-mortem disassembler)  >---
+    st->print_cr("[MachCode]");
+    const char* header = NULL;
+    address p0 = p;
+    while (p < end) {
+      address pp = p;
+      while ((p < end) && (header == NULL)) {
+        header = nmethod_section_label(p);
+        pp  = p;
+        p  += Assembler::instr_len(p);
+      }
+      if (pp > p0) {
+        AbstractDisassembler::decode_range_abstract(p0, pp, start, end, st, Assembler::instr_maxlen());
+        p0 = pp;
+        p  = pp;
+        header = NULL;
+      } else if (header != NULL) {
+        st->bol();
+        st->print_cr("%s", header);
+        header = NULL;
+      }
+    }
+    //---<  Close the output (Marker for post-mortem disassembler)  >---
+    st->bol();
+    st->print_cr("[/MachCode]");
+    return;
+  }
+#endif
+
+#if defined(SUPPORT_ABSTRACT_ASSEMBLY)
+  //---<  abstract disassembly with comments and section headers merged in  >---
+  if (compressed_with_comments) {
+    const_cast<nmethod*>(this)->print_constant_pool(st);
+
+    //---<  Open the output (Marker for post-mortem disassembler)  >---
+    st->print_cr("[MachCode]");
+    while ((p < end) && (p != NULL)) {
+      const int instruction_size_in_bytes = Assembler::instr_len(p);
+
+      //---<  Block comments for nmethod. Interrupts instruction stream, if any.  >---
+      // Outputs a bol() before and a cr() after, but only if a comment is printed.
+      // Prints nmethod_section_label as well.
+      if (AbstractDisassembler::show_block_comment()) {
+        print_block_comment(st, p);
+        if (st->position() == 0) {
+          compressed_format_idx = 0;
+        }
+      }
+
+      //---<  New location information after line break  >---
+      if (compressed_format_idx == 0) {
+        code_comment_column   = Disassembler::print_location(p, pss, end, st, false, false);
+        compressed_format_idx = 1;
+      }
+
+      //---<  Code comment for current instruction. Address range [p..(p+len))  >---
+      unsigned char* p_end = p + (ssize_t)instruction_size_in_bytes;
+      S390_ONLY(if (p_end > end) p_end = end;) // avoid getting past the end
+
+      if (AbstractDisassembler::show_comment() && const_cast<nmethod*>(this)->has_code_comment(p, p_end)) {
+        //---<  interrupt instruction byte stream for code comment  >---
+        if (compressed_format_idx > 1) {
+          st->cr();  // interrupt byte stream
+          st->cr();  // add an empty line
+          code_comment_column = Disassembler::print_location(p, pss, end, st, false, false);
+        }
+        const_cast<nmethod*>(this)->print_code_comment_on(st, code_comment_column, p, p_end );
+        st->bol();
+        compressed_format_idx = 0;
+      }
+
+      //---<  New location information after line break  >---
+      if (compressed_format_idx == 0) {
+        code_comment_column   = Disassembler::print_location(p, pss, end, st, false, false);
+        compressed_format_idx = 1;
+      }
+
+      //---<  Nicely align instructions for readability  >---
+      if (compressed_format_idx > 1) {
+        Disassembler::print_delimiter(st);
+      }
+
+      //---<  Now, finally, print the actual instruction bytes  >---
+      unsigned char* p0 = p;
+      p = Disassembler::decode_instruction_abstract(p, st, instruction_size_in_bytes, instr_maxlen);
+      compressed_format_idx += p - p0;
+
+      if (Disassembler::start_newline(compressed_format_idx-1)) {
+        st->cr();
+        compressed_format_idx = 0;
+      }
+    }
+    //---<  Close the output (Marker for post-mortem disassembler)  >---
+    st->bol();
+    st->print_cr("[/MachCode]");
+    return;
+  }
+#endif
+}
+
+#if defined(SUPPORT_ASSEMBLY) || defined(SUPPORT_ABSTRACT_ASSEMBLY)
 
 const char* nmethod::reloc_string_for(u_char* begin, u_char* end) {
   RelocIterator iter(this, begin, end);
@@ -2414,7 +2788,9 @@
     switch (iter.type()) {
         case relocInfo::none:                  return "no_reloc";
         case relocInfo::oop_type: {
-          stringStream st;
+          // Get a non-resizable resource-allocated stringStream.
+          // Our callees make use of (nested) ResourceMarks.
+          stringStream st(NEW_RESOURCE_ARRAY(char, 1024), 1024);
           oop_Relocation* r = iter.oop_reloc();
           oop obj = r->oop_value();
           st.print("oop(");
@@ -2516,17 +2892,28 @@
   return NULL;
 }
 
-void nmethod::print_nmethod_labels(outputStream* stream, address block_begin) const {
-  if (block_begin == entry_point())             stream->print_cr("[Entry Point]");
-  if (block_begin == verified_entry_point())    stream->print_cr("[Verified Entry Point]");
-  if (JVMCI_ONLY(_exception_offset >= 0 &&) block_begin == exception_begin())         stream->print_cr("[Exception Handler]");
-  if (block_begin == stub_begin())              stream->print_cr("[Stub Code]");
-  if (JVMCI_ONLY(_deopt_handler_begin != NULL &&) block_begin == deopt_handler_begin())     stream->print_cr("[Deopt Handler Code]");
-
-  if (has_method_handle_invokes())
-    if (block_begin == deopt_mh_handler_begin())  stream->print_cr("[Deopt MH Handler Code]");
-
-  if (block_begin == consts_begin())            stream->print_cr("[Constants]");
+const char* nmethod::nmethod_section_label(address pos) const {
+  const char* label = NULL;
+  if (pos == code_begin())                                              label = "[Instructions begin]";
+  if (pos == entry_point())                                             label = "[Entry Point]";
+  if (pos == verified_entry_point())                                    label = "[Verified Entry Point]";
+  if (has_method_handle_invokes() && (pos == deopt_mh_handler_begin())) label = "[Deopt MH Handler Code]";
+  if (pos == consts_begin() && pos != insts_begin())                    label = "[Constants]";
+  // Check stub_code before checking exception_handler or deopt_handler.
+  if (pos == this->stub_begin())                                        label = "[Stub Code]";
+  if (JVMCI_ONLY(_exception_offset >= 0 &&) pos == exception_begin())           label = "[Exception Handler]";
+  if (JVMCI_ONLY(_deopt_handler_begin != NULL &&) pos == deopt_handler_begin()) label = "[Deopt Handler Code]";
+  return label;
+}
+
+void nmethod::print_nmethod_labels(outputStream* stream, address block_begin, bool print_section_labels) const {
+  if (print_section_labels) {
+    const char* label = nmethod_section_label(block_begin);
+    if (label != NULL) {
+      stream->bol();
+      stream->print_cr("%s", label);
+    }
+  }
 
   if (block_begin == entry_point()) {
     methodHandle m = method();
@@ -2623,7 +3010,24 @@
   }
 }
 
-void nmethod::print_code_comment_on(outputStream* st, int column, u_char* begin, u_char* end) {
+// Returns whether this nmethod has code comments.
+bool nmethod::has_code_comment(address begin, address end) {
+  // scopes?
+  ScopeDesc* sd  = scope_desc_in(begin, end);
+  if (sd != NULL) return true;
+
+  // relocations?
+  const char* str = reloc_string_for(begin, end);
+  if (str != NULL) return true;
+
+  // implicit exceptions?
+  int cont_offset = ImplicitExceptionTable(this).at(begin - code_begin());
+  if (cont_offset != 0) return true;
+
+  return false;
+}
+
+void nmethod::print_code_comment_on(outputStream* st, int column, address begin, address end) {
   // First, find an oopmap in (begin, end].
   // We use the odd half-closed interval so that oop maps and scope descs
   // which are tied to the byte after a call are printed with the call itself.
@@ -2636,7 +3040,7 @@
       address pc = base + pair->pc_offset();
       if (pc > begin) {
         if (pc <= end) {
-          st->move_to(column);
+          st->move_to(column, 6, 0);
           st->print("; ");
           om->print_on(st);
         }
@@ -2648,7 +3052,7 @@
   // Print any debug info present at this pc.
   ScopeDesc* sd  = scope_desc_in(begin, end);
   if (sd != NULL) {
-    st->move_to(column);
+    st->move_to(column, 6, 0);
     if (sd->bci() == SynchronizationEntryBCI) {
       st->print(";*synchronization entry");
     } else if (sd->bci() == AfterBci) {
@@ -2704,8 +3108,11 @@
 
     // Print all scopes
     for (;sd != NULL; sd = sd->sender()) {
-      st->move_to(column);
+      st->move_to(column, 6, 0);
       st->print("; -");
+      if (sd->should_reexecute()) {
+        st->print(" (reexecute)");
+      }
       if (sd->method() == NULL) {
         st->print("method is NULL");
       } else {
@@ -2722,20 +3129,24 @@
   }
 
   // Print relocation information
+  // Prevent memory leak: allocating without ResourceMark.
+  ResourceMark rm;
   const char* str = reloc_string_for(begin, end);
   if (str != NULL) {
     if (sd != NULL) st->cr();
-    st->move_to(column);
+    st->move_to(column, 6, 0);
     st->print(";   {%s}", str);
   }
   int cont_offset = ImplicitExceptionTable(this).at(begin - code_begin());
   if (cont_offset != 0) {
-    st->move_to(column);
+    st->move_to(column, 6, 0);
     st->print("; implicit exception: dispatches to " INTPTR_FORMAT, p2i(code_begin() + cont_offset));
   }
 
 }
 
+#endif
+
 class DirectNativeCallWrapper: public NativeCallWrapper {
 private:
   NativeCall* _call;
@@ -2842,12 +3253,14 @@
   return CompiledDirectStaticCall::before(return_addr);
 }
 
-#ifndef PRODUCT
-
+#if defined(SUPPORT_DATA_STRUCTS)
 void nmethod::print_value_on(outputStream* st) const {
   st->print("nmethod");
   print_on(st, NULL);
 }
+#endif
+
+#ifndef PRODUCT
 
 void nmethod::print_calls(outputStream* st) {
   RelocIterator iter(this);
@@ -2869,14 +3282,6 @@
   }
 }
 
-void nmethod::print_handler_table() {
-  ExceptionHandlerTable(this).print();
-}
-
-void nmethod::print_nul_chk_table() {
-  ImplicitExceptionTable(this).print(code_begin());
-}
-
 void nmethod::print_statistics() {
   ttyLocker ttyl;
   if (xtty != NULL)  xtty->head("statistics type='nmethod'");
--- a/src/hotspot/share/code/nmethod.hpp	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/share/code/nmethod.hpp	Thu May 23 11:07:37 2019 +0100
@@ -377,6 +377,7 @@
   void  make_unloaded();
 
   bool has_dependencies()                         { return dependencies_size() != 0; }
+  void print_dependencies()                       PRODUCT_RETURN;
   void flush_dependencies(bool delete_immediately);
   bool has_flushed_dependencies()                 { return _has_flushed_dependencies; }
   void set_has_flushed_dependencies()             {
@@ -505,18 +506,40 @@
   void verify_scopes();
   void verify_interrupt_point(address interrupt_point);
 
+  // Disassemble this nmethod with additional debug information, e.g. information about blocks.
+  void decode2(outputStream* st) const;
+  void print_constant_pool(outputStream* st);
+
+  // Avoid hiding of parent's 'decode(outputStream*)' method.
+  void decode(outputStream* st) const { decode2(st); } // just delegate here.
+
   // printing support
   void print()                          const;
+  void print(outputStream* st)          const;
+  void print_code();
+
+#if defined(SUPPORT_DATA_STRUCTS)
+  // print output in opt build for disassembler library
   void print_relocations()                        PRODUCT_RETURN;
-  void print_pcs()                                PRODUCT_RETURN;
-  void print_scopes()                             PRODUCT_RETURN;
-  void print_dependencies()                       PRODUCT_RETURN;
-  void print_value_on(outputStream* st) const     PRODUCT_RETURN;
+  void print_pcs() { print_pcs_on(tty); }
+  void print_pcs_on(outputStream* st);
+  void print_scopes() { print_scopes_on(tty); }
+  void print_scopes_on(outputStream* st)          PRODUCT_RETURN;
+  void print_value_on(outputStream* st) const;
+  void print_handler_table();
+  void print_nul_chk_table();
+  void print_recorded_oops();
+  void print_recorded_metadata();
+
+  void print_oops(outputStream* st);     // oops from the underlying CodeBlob.
+  void print_metadata(outputStream* st); // metadata in metadata pool.
+#else
+  // void print_pcs()                             PRODUCT_RETURN;
+  void print_pcs()                                { return; }
+#endif
+
   void print_calls(outputStream* st)              PRODUCT_RETURN;
-  void print_handler_table()                      PRODUCT_RETURN;
-  void print_nul_chk_table()                      PRODUCT_RETURN;
-  void print_recorded_oops()                      PRODUCT_RETURN;
-  void print_recorded_metadata()                  PRODUCT_RETURN;
+  static void print_statistics()                  PRODUCT_RETURN;
 
   void maybe_print_nmethod(DirectiveSet* directive);
   void print_nmethod(bool print_code);
@@ -532,14 +555,21 @@
 
   // Prints block-level comments, including nmethod specific block labels:
   virtual void print_block_comment(outputStream* stream, address block_begin) const {
+#if defined(SUPPORT_ASSEMBLY) || defined(SUPPORT_ABSTRACT_ASSEMBLY)
     print_nmethod_labels(stream, block_begin);
     CodeBlob::print_block_comment(stream, block_begin);
+#endif
   }
-  void print_nmethod_labels(outputStream* stream, address block_begin) const;
+  bool has_block_comment(address block_begin) {
+    return CodeBlob::has_block_comment(block_begin);
+  }
+  void print_nmethod_labels(outputStream* stream, address block_begin, bool print_section_labels=true) const;
+  const char* nmethod_section_label(address pos) const;
 
+  // returns whether this nmethod has code comments.
+  bool has_code_comment(address begin, address end);
   // Prints a comment for one native instruction (reloc info, pc desc)
   void print_code_comment_on(outputStream* st, int column, address begin, address end);
-  static void print_statistics() PRODUCT_RETURN;
 
   // Compiler task identification.  Note that all OSR methods
   // are numbered in an independent sequence if CICountOSR is true,
--- a/src/hotspot/share/code/pcDesc.cpp	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/share/code/pcDesc.cpp	Thu May 23 11:07:37 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2019, 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
@@ -40,19 +40,24 @@
   return code->code_begin() + pc_offset();
 }
 
-void PcDesc::print(CompiledMethod* code) {
+void PcDesc::print_on(outputStream* st, CompiledMethod* code) {
 #ifndef PRODUCT
   ResourceMark rm;
-  tty->print_cr("PcDesc(pc=" PTR_FORMAT " offset=%x bits=%x):", p2i(real_pc(code)), pc_offset(), _flags);
+  st->print("PcDesc(pc=" PTR_FORMAT " offset=%x bits=%x):", p2i(real_pc(code)), pc_offset(), _flags);
 
   if (scope_decode_offset() == DebugInformationRecorder::serialized_null) {
+    st->cr();
     return;
   }
 
+  int tab = 8;
+  int pos = st->position() + 2; // current column plus two spaces
+  pos = ((pos+tab-1)/tab)*tab;
+
   for (ScopeDesc* sd = code->scope_desc_at(real_pc(code));
        sd != NULL;
        sd = sd->sender()) {
-    sd->print_on(tty);
+    sd->print_on(st);
   }
 #endif
 }
--- a/src/hotspot/share/code/pcDesc.hpp	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/share/code/pcDesc.hpp	Thu May 23 11:07:37 2019 +0100
@@ -92,7 +92,8 @@
   // Returns the real pc
   address real_pc(const CompiledMethod* code) const;
 
-  void print(CompiledMethod* code);
+  void print(CompiledMethod* code) { print_on(tty, code); }
+  void print_on(outputStream* st, CompiledMethod* code);
   bool verify(CompiledMethod* code);
 };
 
--- a/src/hotspot/share/code/vmreg.cpp	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/share/code/vmreg.cpp	Thu May 23 11:07:37 2019 +0100
@@ -39,7 +39,7 @@
 
 void VMRegImpl::print_on(outputStream* st) const {
   if( is_reg() ) {
-    assert( VMRegImpl::regName[value()], "" );
+    assert(VMRegImpl::regName[value()], "VMRegImpl::regName[" INTPTR_FORMAT "] returns NULL", value());
     st->print("%s",VMRegImpl::regName[value()]);
   } else if (is_stack()) {
     int stk = value() - stack0->value();
--- a/src/hotspot/share/code/vtableStubs.cpp	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/share/code/vtableStubs.cpp	Thu May 23 11:07:37 2019 +0100
@@ -80,7 +80,7 @@
 
 
 void VtableStub::print_on(outputStream* st) const {
-  st->print("vtable stub (index = %d, receiver_location = " INTX_FORMAT ", code = [" INTPTR_FORMAT ", " INTPTR_FORMAT "[)",
+  st->print("vtable stub (index = %d, receiver_location = " INTX_FORMAT ", code = [" INTPTR_FORMAT ", " INTPTR_FORMAT "])",
              index(), p2i(receiver_location()), p2i(code_begin()), p2i(code_end()));
 }
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/compiler/abstractDisassembler.cpp	Thu May 23 11:07:37 2019 +0100
@@ -0,0 +1,363 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2019 SAP SE. 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.
+ *
+ */
+
+// AbstractDisassembler is the base class for
+// platform-specific Disassembler classes.
+
+#include "precompiled.hpp"
+#include "asm/assembler.inline.hpp"
+#include "compiler/abstractDisassembler.hpp"
+#include "oops/oop.inline.hpp"
+#include "utilities/debug.hpp"
+#include "utilities/ostream.hpp"
+
+// Default values for what is being printed as line prefix when disassembling a single instruction.
+// Can be overridden by command line parameter PrintAssemblyOptions.
+bool AbstractDisassembler::_show_data_hex      = true;
+bool AbstractDisassembler::_show_data_int      = false;
+bool AbstractDisassembler::_show_data_float    = false;
+bool AbstractDisassembler::_align_instr        = false;
+bool AbstractDisassembler::_show_pc            = true;
+bool AbstractDisassembler::_show_offset        = false;
+bool AbstractDisassembler::_show_structs       = false;
+bool AbstractDisassembler::_show_comment       = false;
+bool AbstractDisassembler::_show_block_comment = false;
+
+// set "true" to see what's in memory bit by bit
+// might prove cumbersome on platforms where instr_len is hard to find out
+bool AbstractDisassembler::_show_bytes         = false;
+
+// Return #bytes printed. Callers may use that for output alignment.
+// Print instruction address, and offset from blob begin.
+// Offset width (2, 4, 6, 8 bytes) is adapted to size of blob.
+// Working assumption: we are at st->bol() upon entry. If not, it's the
+//                     caller's responsibility to guarantee proper alignment.
+int AbstractDisassembler::print_location(address here, address begin, address end, outputStream* st, bool align, bool print_header) {
+  const int     pos_0  = st->position();
+
+  if (show_pc() || show_offset()) {
+    st->print(" ");
+  }
+
+  if (show_pc()) {
+    if (print_header) {
+      st->print(" %*s", 18, "Address");
+    } else {
+      st->print(" " PTR_FORMAT, p2i(here));
+    }
+  }
+
+  if (show_offset()) {
+#ifdef ASSERT
+    if ((uintptr_t)begin > (uintptr_t)here) st->print(">>begin(" PTR_FORMAT ") > here(" PTR_FORMAT ")<<", p2i(begin), p2i(here));
+    if ((uintptr_t)end   < (uintptr_t)here) st->print(">>  end(" PTR_FORMAT ") < here(" PTR_FORMAT ")<<", p2i(end),   p2i(here));
+    assert((uintptr_t)begin <= (uintptr_t)end, "inverted address range");
+#endif
+    const int blob_len = end - begin;
+    const int offset   = here - begin;
+    const int width    = (blob_len < (1<< 8)) ? 2 : (blob_len < (1<<16)) ? 4 : (blob_len < (1<<24)) ? 6 : 8;
+    if (print_header) {
+      st->print(" %*s", width+5, "offset");
+    } else {
+      st->print(" (+0x%*.*x)", width, width, offset);
+    }
+  }
+
+  if ((show_pc() || show_offset()) && !print_header) {
+    st->print(": ");
+  }
+
+  if (align) {
+    const uint tabspacing  = 8;
+    const uint pos         = st->position();
+    const uint aligned_pos = ((pos+tabspacing-1)/tabspacing)*tabspacing /* - 1 */;
+    st->fill_to(aligned_pos);
+  }
+
+  return st->position() - pos_0;
+}
+
+
+// Return #bytes printed. Callers may use that for output alignment.
+// Print instruction in hexadecimal representation, using 2-byte blocks.
+// Used with real disassemblies. Not so useful with abstract disassemblies.
+int AbstractDisassembler::print_instruction(address here, int len, int max_len, outputStream* st, bool align, bool print_header) {
+  if (show_bytes()) {
+    const int block_bytes = 2;
+    const int pos_0       = st->position();
+    address   pos         = here;
+
+    //---<  print instruction bytes in blocks  >---
+    // must print byte by byte: address might be unaligned.
+    for (; pos <= here + len - block_bytes; pos += block_bytes) {
+      for (address byte = pos; byte < pos + block_bytes; byte++) {
+        st->print("%2.2x", *byte);
+      }
+      st->print(" ");
+    }
+
+    //---<  Print the remaining bytes of the instruction  >---
+    if ((len & (block_bytes - 1)) != 0) {
+      for (; pos < here + len; pos++) {
+        st->print("%2.2x", *pos);
+      }
+    }
+
+    //---<  filler for shorter than max_len instructions  >---
+    for (int i = len+1; i < max_len; i++) {
+      st->print("  ");
+    }
+
+    st->print(" "); // separator space.
+    print_delimiter(st);
+    return st->position() - pos_0;
+  }
+
+  if (align) {
+    const uint tabspacing  = 8;
+    const uint pos         = st->position();
+    const uint aligned_pos = ((pos+tabspacing-1)/tabspacing)*tabspacing /* - 1 */;
+    st->fill_to(aligned_pos);
+  }
+
+  return 0;
+}
+
+
+// Return #bytes printed. Callers may use that for output alignment.
+// Print data (e.g. constant pool entries) in hex format.
+// Depending on the alignment, short, int, and long entities are printed.
+// If selected, data is formatted as int/long and float/double values in addition.
+int AbstractDisassembler::print_hexdata(address here, int len, outputStream* st, bool print_header) {
+  const int tsize = 8;
+  const int pos_0 = st->position();
+  int pos   = pos_0;
+  int align = ((pos+tsize-1)/tsize)*tsize;
+  st->fill_to(align);
+
+  //---<  printing hex data  >---
+  if (show_data_hex()) {
+    switch (len) {
+      case 1: if (print_header) {
+                st->print("hex1");
+              } else {
+                st->print("0x%02x", *here);
+              }
+              st->fill_to(align += tsize);
+      case 2: if (print_header) {
+                st->print("  hex2");
+              } else {
+                if (((uintptr_t)(here)&0x01) == 0) {
+                  st->print("0x%04x",   *((jushort*)here));
+                }
+              }
+              st->fill_to(align += tsize);
+      case 4: if (print_header) {
+                st->print("      hex4");
+              } else {
+                if (((uintptr_t)(here)&0x03) == 0) {
+                  st->print("0x%08x",   *((juint*)here));
+                }
+              }
+              st->fill_to(align += 2*tsize);
+      case 8: if (print_header) {
+                st->print("              hex8");
+              } else {
+                if (((uintptr_t)(here)&0x07) == 0) {
+                  st->print(PTR_FORMAT, *((uintptr_t*)here));
+                }
+              }
+              st->fill_to(align += 3*tsize);
+              break;
+      default: ;
+    }
+    pos   = st->position();
+    align = ((pos+tsize-1)/tsize)*tsize;
+    st->fill_to(align);
+  }
+
+  //---<  printing int/long data  >---
+  if (show_data_int()) {
+    switch (len) {
+      case 4: if (print_header) {
+                st->print("         int");
+              } else {
+                if (((uintptr_t)(here)&0x03) == 0) {
+                  st->print("%12.1d",  *((jint*)here));
+                }
+              }
+              st->fill_to(align += 2*tsize);
+      case 8: if (print_header) {
+                st->print("                   long");
+              } else {
+                if (((uintptr_t)(here)&0x07) == 0) {
+                  st->print("%23.1ld", *((jlong*)here));
+                }
+              }
+              st->fill_to(align += 3*tsize);
+              break;
+      default: ;
+    }
+    pos   = st->position();
+    align = ((pos+tsize-1)/tsize)*tsize;
+    st->fill_to(align);
+  }
+
+  //---<  printing float/double data  >---
+  if (show_data_float()) {
+    switch (len) {
+      case 4: if (print_header) {
+                st->print("          float");
+              } else {
+                if (((uintptr_t)(here)&0x03) == 0) {
+                  st->print("%15.7e",  (double)*((float*)here));
+                }
+              }
+              st->fill_to(align += 2*tsize);
+      case 8: if (print_header) {
+                st->print("                 double");
+              } else {
+                if (((uintptr_t)(here)&0x07) == 0) {
+                  st->print("%23.15e",         *((double*)here));
+                }
+              }
+              st->fill_to(align += 3*tsize);
+              break;
+      default: ;
+    }
+  }
+
+  return st->position() - pos_0;
+}
+
+
+// Return #bytes printed. Callers may use that for output alignment.
+// Print an instruction delimiter.
+int AbstractDisassembler::print_delimiter(outputStream* st) {
+  if (align_instr()) { st->print("| "); return 2; }
+  else               return 0;
+}
+
+
+// Decodes the one instruction at address start in a platform-independent format.
+// Returns the start of the next instruction (which is 'start' plus 'instruction_size_in_bytes').
+// The parameter max_instr_size_in_bytes is used for output alignment purposes only.
+address AbstractDisassembler::decode_instruction_abstract(address start,
+                                                          outputStream* st,
+                                                          const int instruction_size_in_bytes,
+                                                          const int max_instr_size_in_bytes) {
+  assert(instruction_size_in_bytes > 0, "no zero-size instructions!");
+  assert(max_instr_size_in_bytes >= instruction_size_in_bytes, "inconsistent call parameters");
+
+  //---<  current instruction is at the start address  >---
+  unsigned char* current = (unsigned char*) start;
+  int            filler_limit = align_instr() ? max_instr_size_in_bytes : ((instruction_size_in_bytes+abstract_instruction_bytes_per_block-1)/abstract_instruction_bytes_per_block)
+                                                                          *abstract_instruction_bytes_per_block;
+
+  //---<  print the instruction's bytes  >---
+  for (int i = 1; i <= instruction_size_in_bytes; i++) {
+    st->print("%02x", *current);
+    ++current;
+    if (abstract_instruction_bytes_per_block <= max_instr_size_in_bytes) {
+      if (i%abstract_instruction_bytes_per_block == 0) st->print(" ");
+    } else {
+      if (i == instruction_size_in_bytes) st->print(" ");
+    }
+  }
+
+  //---<  print some filler spaces to column-align instructions  >---
+  for (int i = instruction_size_in_bytes+1; i <= filler_limit; i++) {
+    st->print("  ");
+    if (abstract_instruction_bytes_per_block <= max_instr_size_in_bytes) {
+      if (i%abstract_instruction_bytes_per_block == 0) st->print(" ");
+    } else {
+      if (i == instruction_size_in_bytes) st->print(" ");
+    }
+  }
+
+  //---<  the address of the next instruction  >---
+  return (address) current;
+}
+
+
+// Decodes all instructions in the given range [start..end)
+// calling decode_instruction_abstract for each instruction.
+// The format is platform dependent only to the extend that
+// it respects the actual instruction length where possible.
+// Does not print any markers or decorators.
+void AbstractDisassembler::decode_range_abstract(address range_start, address range_end,
+                                                 address start, address end,
+                                                 outputStream* st,
+                                                 const int max_instr_size_in_bytes) {
+  assert(st != NULL, "need an output stream (no default)!");
+  int     idx = 0;
+  address pos = range_start;
+
+  while ((pos != NULL) && (pos < range_end)) {
+    int instr_size_in_bytes = Assembler::instr_len(pos);
+
+    if (idx == 0) print_location(pos, start, end, st, false, false);
+    else          print_delimiter(st);
+
+    //---<  print the instruction's bytes  >---
+    // don't access storage beyond end of range
+    if (pos + instr_size_in_bytes <= range_end) {
+      pos = decode_instruction_abstract(pos, st, instr_size_in_bytes, max_instr_size_in_bytes);
+    } else {
+      // If the range to be decoded contains garbage at the end (e.g. 0xcc initializer bytes),
+      // instruction size calculation may run out of sync. Just terminate in that case.
+      pos = range_end;
+    }
+
+    idx += instr_size_in_bytes;
+    if (start_newline(idx)) {
+      st->cr();
+      idx = 0;
+    }
+  }
+}
+
+
+// Decodes all instructions in the given range [start..end).
+// The output is enclosed in [MachCode] and [/MachCode] tags for later recognition.
+// The format is platform dependent only to the extend that
+// it respects the actual instruction length where possible.
+void AbstractDisassembler::decode_abstract(address start, address end, outputStream* ost,
+                                           const int max_instr_size_in_bytes) {
+  int     idx = 0;
+  address pos = start;
+
+  outputStream* st = (ost == NULL) ? tty : ost;
+
+  //---<  Open the output (Marker for post-mortem disassembler)  >---
+  st->bol();
+  st->print_cr("[MachCode]");
+
+  decode_range_abstract(start, end, start, end, st, max_instr_size_in_bytes);
+
+  //---<  Close the output (Marker for post-mortem disassembler)  >---
+  st->bol();
+  st->print_cr("[/MachCode]");
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/compiler/abstractDisassembler.hpp	Thu May 23 11:07:37 2019 +0100
@@ -0,0 +1,118 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2019 SAP SE. 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.
+ *
+ */
+
+#ifndef SHARE_COMPILER_ABSTRACTDISASSEMBLER_HPP
+#define SHARE_COMPILER_ABSTRACTDISASSEMBLER_HPP
+
+// AbstractDisassembler is the base class for
+// platform-specific Disassembler classes.
+
+#include "utilities/globalDefinitions.hpp"
+
+class AbstractDisassembler {
+
+ private:
+  // These are some general settings which control
+  // abstract disassembly output.
+  enum {
+    // that many bytes are dumped in one line.
+    abstract_instruction_bytes_per_line     = 32,
+    // instruction bytes are grouped in blocks of that many bytes.
+    abstract_instruction_bytes_per_block    =  2,
+    // instructions have this default len.
+    abstract_instruction_size_in_bytes      =  1,
+    // instructions have this maximum len.
+    abstract_instruction_maxsize_in_bytes   =  1
+  };
+
+  static bool _align_instr;        // vertical alignment of instructions in abstract disassembly
+  static bool _show_pc;            // print the instruction address
+  static bool _show_offset;        // print the instruction offset (from start of blob)
+  static bool _show_bytes;         // print instruction bytes
+  static bool _show_data_hex;      // print instruction bytes
+  static bool _show_data_int;      // print instruction bytes
+  static bool _show_data_float;    // print instruction bytes
+  static bool _show_structs;       // print compiler data structures (relocations, oop maps, scopes, metadata, ...)
+  static bool _show_comment;       // print instruction comments
+  static bool _show_block_comment; // print block comments
+
+ public:
+  // Platform-independent location and instruction formatting.
+  // All functions return #characters printed.
+  static int  print_location(address here, address begin, address end, outputStream* st, bool align, bool print_header);
+  static int  print_instruction(address here, int len, int max_len,    outputStream* st, bool align, bool print_header);
+  static int  print_hexdata(address here, int len, outputStream* st, bool print_header = false);
+  static int  print_delimiter(outputStream* st);
+  static bool start_newline(int byte_count) { return byte_count >= abstract_instruction_bytes_per_line; }
+
+  static void toggle_align_instr()        { _align_instr        = !_align_instr; }
+  static void toggle_show_pc()            { _show_pc            = !_show_pc; }
+  static void toggle_show_offset()        { _show_offset        = !_show_offset; }
+  static void toggle_show_bytes()         { _show_bytes         = !_show_bytes; }
+  static void toggle_show_data_hex()      { _show_data_hex      = !_show_data_hex; }
+  static void toggle_show_data_int()      { _show_data_int      = !_show_data_int; }
+  static void toggle_show_data_float()    { _show_data_float    = !_show_data_float; }
+  static void toggle_show_structs()       { _show_structs       = !_show_structs; }
+  static void toggle_show_comment()       { _show_comment       = !_show_comment; }
+  static void toggle_show_block_comment() { _show_block_comment = !_show_block_comment; }
+
+  static bool align_instr()        { return _align_instr; }
+  static bool show_pc()            { return _show_pc; }
+  static bool show_offset()        { return _show_offset; }
+  static bool show_bytes()         { return _show_bytes; }
+  static bool show_data_hex()      { return _show_data_hex; }
+  static bool show_data_int()      { return _show_data_int; }
+  static bool show_data_float()    { return _show_data_float; }
+  static bool show_structs()       { return _show_structs; }
+  static bool show_comment()       { return _show_comment; }
+  static bool show_block_comment() { return _show_block_comment; }
+
+  // Decodes the one instruction at address start in a platform-independent
+  // format. Returns the start of the next instruction (which is
+  // 'start' plus 'instruction_size_in_bytes'). The parameter max_instr_size_in_bytes
+  // is used for output alignment purposes only.
+  static address decode_instruction_abstract(address start,
+                                             outputStream* st,
+                                             const int instruction_size_in_bytes,
+                                             const int max_instr_size_in_bytes = abstract_instruction_maxsize_in_bytes);
+
+  // Decodes all instructions in the given range [start..end)
+  // calling decode_instruction_abstract for each instruction.
+  // The format is platform dependent only to the extend that
+  // it respects the actual instruction length where possible.
+  // Does not print any markers or decorators.
+  static void decode_range_abstract(address range_start, address range_end,
+                                    address start, address end,
+                                    outputStream* st,
+                                    const int max_instr_size_in_bytes = abstract_instruction_maxsize_in_bytes);
+
+  // Decodes all instructions in the given range in a platform-independent
+  // format, calling decode_instruction_abstract for each instruction.
+  static void decode_abstract(address start, address end,
+                              outputStream* st,
+                              const int max_instr_size_in_bytes = abstract_instruction_maxsize_in_bytes);
+};
+
+#endif // SHARE_COMPILER_ABSTRACTDISASSEMBLER_HPP
--- a/src/hotspot/share/compiler/compileBroker.cpp	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/share/compiler/compileBroker.cpp	Thu May 23 11:07:37 2019 +0100
@@ -192,7 +192,7 @@
 
   void log_compile(JavaThread* thread, CompileTask* task) {
     StringLogMessage lm;
-    stringStream sstr = lm.stream();
+    stringStream sstr(lm.buffer(), lm.size());
     // msg.time_stamp().update_to(tty->time_stamp().ticks());
     task->print(&sstr, NULL, true, false);
     log(thread, "%s", (const char*)lm);
--- a/src/hotspot/share/compiler/compilerDefinitions.cpp	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/share/compiler/compilerDefinitions.cpp	Thu May 23 11:07:37 2019 +0100
@@ -117,38 +117,38 @@
   Compilation_mode = CompMode_client;
   CompLevel_highest_tier = CompLevel_simple;
   CompLevel_initial_compile = CompLevel_simple;
-  FLAG_SET_ERGO(bool, TieredCompilation, false);
-  FLAG_SET_ERGO(bool, ProfileInterpreter, false);
+  FLAG_SET_ERGO(TieredCompilation, false);
+  FLAG_SET_ERGO(ProfileInterpreter, false);
 #if INCLUDE_JVMCI
-  FLAG_SET_ERGO(bool, EnableJVMCI, false);
-  FLAG_SET_ERGO(bool, UseJVMCICompiler, false);
+  FLAG_SET_ERGO(EnableJVMCI, false);
+  FLAG_SET_ERGO(UseJVMCICompiler, false);
 #endif
 #if INCLUDE_AOT
-  FLAG_SET_ERGO(bool, UseAOT, false);
+  FLAG_SET_ERGO(UseAOT, false);
 #endif
   if (FLAG_IS_DEFAULT(NeverActAsServerClassMachine)) {
-    FLAG_SET_ERGO(bool, NeverActAsServerClassMachine, true);
+    FLAG_SET_ERGO(NeverActAsServerClassMachine, true);
   }
   if (FLAG_IS_DEFAULT(InitialCodeCacheSize)) {
-    FLAG_SET_ERGO(uintx, InitialCodeCacheSize, 160*K);
+    FLAG_SET_ERGO(InitialCodeCacheSize, 160*K);
   }
   if (FLAG_IS_DEFAULT(ReservedCodeCacheSize)) {
-    FLAG_SET_ERGO(uintx, ReservedCodeCacheSize, 32*M);
+    FLAG_SET_ERGO(ReservedCodeCacheSize, 32*M);
   }
   if (FLAG_IS_DEFAULT(NonProfiledCodeHeapSize)) {
-    FLAG_SET_ERGO(uintx, NonProfiledCodeHeapSize, 27*M);
+    FLAG_SET_ERGO(NonProfiledCodeHeapSize, 27*M);
   }
   if (FLAG_IS_DEFAULT(ProfiledCodeHeapSize)) {
-    FLAG_SET_ERGO(uintx, ProfiledCodeHeapSize, 0);
+    FLAG_SET_ERGO(ProfiledCodeHeapSize, 0);
   }
   if (FLAG_IS_DEFAULT(NonNMethodCodeHeapSize)) {
-    FLAG_SET_ERGO(uintx, NonNMethodCodeHeapSize, 5*M);
+    FLAG_SET_ERGO(NonNMethodCodeHeapSize, 5*M);
   }
   if (FLAG_IS_DEFAULT(CodeCacheExpansionSize)) {
-    FLAG_SET_ERGO(uintx, CodeCacheExpansionSize, 32*K);
+    FLAG_SET_ERGO(CodeCacheExpansionSize, 32*K);
   }
   if (FLAG_IS_DEFAULT(MetaspaceSize)) {
-    FLAG_SET_ERGO(size_t, MetaspaceSize, MIN2(12*M, MaxMetaspaceSize));
+    FLAG_SET_ERGO(MetaspaceSize, MIN2(12*M, MaxMetaspaceSize));
   }
   if (FLAG_IS_DEFAULT(MaxRAM)) {
     // Do not use FLAG_SET_ERGO to update MaxRAM, as this will impact
@@ -156,13 +156,13 @@
     FLAG_SET_DEFAULT(MaxRAM, 1ULL*G);
   }
   if (FLAG_IS_DEFAULT(CompileThreshold)) {
-    FLAG_SET_ERGO(intx, CompileThreshold, 1500);
+    FLAG_SET_ERGO(CompileThreshold, 1500);
   }
   if (FLAG_IS_DEFAULT(OnStackReplacePercentage)) {
-    FLAG_SET_ERGO(intx, OnStackReplacePercentage, 933);
+    FLAG_SET_ERGO(OnStackReplacePercentage, 933);
   }
   if (FLAG_IS_DEFAULT(CICompilerCount)) {
-    FLAG_SET_ERGO(intx, CICompilerCount, 1);
+    FLAG_SET_ERGO(CICompilerCount, 1);
   }
 }
 
@@ -177,7 +177,7 @@
 void select_compilation_mode_ergonomically() {
 #if defined(_WINDOWS) && !defined(_LP64)
   if (FLAG_IS_DEFAULT(NeverActAsServerClassMachine)) {
-    FLAG_SET_ERGO(bool, NeverActAsServerClassMachine, true);
+    FLAG_SET_ERGO(NeverActAsServerClassMachine, true);
   }
 #endif
   if (NeverActAsServerClassMachine) {
@@ -198,14 +198,14 @@
   }
   // Increase the code cache size - tiered compiles a lot more.
   if (FLAG_IS_DEFAULT(ReservedCodeCacheSize)) {
-    FLAG_SET_ERGO(uintx, ReservedCodeCacheSize,
+    FLAG_SET_ERGO(ReservedCodeCacheSize,
                   MIN2(CODE_CACHE_DEFAULT_LIMIT, (size_t)ReservedCodeCacheSize * 5));
   }
   // Enable SegmentedCodeCache if TieredCompilation is enabled, ReservedCodeCacheSize >= 240M
   // and the code cache contains at least 8 pages (segmentation disables advantage of huge pages).
   if (FLAG_IS_DEFAULT(SegmentedCodeCache) && ReservedCodeCacheSize >= 240*M &&
       8 * CodeCache::page_size() <= ReservedCodeCacheSize) {
-    FLAG_SET_ERGO(bool, SegmentedCodeCache, true);
+    FLAG_SET_ERGO(SegmentedCodeCache, true);
   }
   if (!UseInterpreter) { // -Xcomp
     Tier3InvokeNotifyFreqLog = 0;
@@ -219,29 +219,29 @@
   // Scale tiered compilation thresholds.
   // CompileThresholdScaling == 0.0 is equivalent to -Xint and leaves compilation thresholds unchanged.
   if (!FLAG_IS_DEFAULT(CompileThresholdScaling) && CompileThresholdScaling > 0.0) {
-    FLAG_SET_ERGO(intx, Tier0InvokeNotifyFreqLog, scaled_freq_log(Tier0InvokeNotifyFreqLog));
-    FLAG_SET_ERGO(intx, Tier0BackedgeNotifyFreqLog, scaled_freq_log(Tier0BackedgeNotifyFreqLog));
+    FLAG_SET_ERGO(Tier0InvokeNotifyFreqLog, scaled_freq_log(Tier0InvokeNotifyFreqLog));
+    FLAG_SET_ERGO(Tier0BackedgeNotifyFreqLog, scaled_freq_log(Tier0BackedgeNotifyFreqLog));
 
-    FLAG_SET_ERGO(intx, Tier3InvocationThreshold, scaled_compile_threshold(Tier3InvocationThreshold));
-    FLAG_SET_ERGO(intx, Tier3MinInvocationThreshold, scaled_compile_threshold(Tier3MinInvocationThreshold));
-    FLAG_SET_ERGO(intx, Tier3CompileThreshold, scaled_compile_threshold(Tier3CompileThreshold));
-    FLAG_SET_ERGO(intx, Tier3BackEdgeThreshold, scaled_compile_threshold(Tier3BackEdgeThreshold));
+    FLAG_SET_ERGO(Tier3InvocationThreshold, scaled_compile_threshold(Tier3InvocationThreshold));
+    FLAG_SET_ERGO(Tier3MinInvocationThreshold, scaled_compile_threshold(Tier3MinInvocationThreshold));
+    FLAG_SET_ERGO(Tier3CompileThreshold, scaled_compile_threshold(Tier3CompileThreshold));
+    FLAG_SET_ERGO(Tier3BackEdgeThreshold, scaled_compile_threshold(Tier3BackEdgeThreshold));
 
     // Tier2{Invocation,MinInvocation,Compile,Backedge}Threshold should be scaled here
     // once these thresholds become supported.
 
-    FLAG_SET_ERGO(intx, Tier2InvokeNotifyFreqLog, scaled_freq_log(Tier2InvokeNotifyFreqLog));
-    FLAG_SET_ERGO(intx, Tier2BackedgeNotifyFreqLog, scaled_freq_log(Tier2BackedgeNotifyFreqLog));
+    FLAG_SET_ERGO(Tier2InvokeNotifyFreqLog, scaled_freq_log(Tier2InvokeNotifyFreqLog));
+    FLAG_SET_ERGO(Tier2BackedgeNotifyFreqLog, scaled_freq_log(Tier2BackedgeNotifyFreqLog));
 
-    FLAG_SET_ERGO(intx, Tier3InvokeNotifyFreqLog, scaled_freq_log(Tier3InvokeNotifyFreqLog));
-    FLAG_SET_ERGO(intx, Tier3BackedgeNotifyFreqLog, scaled_freq_log(Tier3BackedgeNotifyFreqLog));
+    FLAG_SET_ERGO(Tier3InvokeNotifyFreqLog, scaled_freq_log(Tier3InvokeNotifyFreqLog));
+    FLAG_SET_ERGO(Tier3BackedgeNotifyFreqLog, scaled_freq_log(Tier3BackedgeNotifyFreqLog));
 
-    FLAG_SET_ERGO(intx, Tier23InlineeNotifyFreqLog, scaled_freq_log(Tier23InlineeNotifyFreqLog));
+    FLAG_SET_ERGO(Tier23InlineeNotifyFreqLog, scaled_freq_log(Tier23InlineeNotifyFreqLog));
 
-    FLAG_SET_ERGO(intx, Tier4InvocationThreshold, scaled_compile_threshold(Tier4InvocationThreshold));
-    FLAG_SET_ERGO(intx, Tier4MinInvocationThreshold, scaled_compile_threshold(Tier4MinInvocationThreshold));
-    FLAG_SET_ERGO(intx, Tier4CompileThreshold, scaled_compile_threshold(Tier4CompileThreshold));
-    FLAG_SET_ERGO(intx, Tier4BackEdgeThreshold, scaled_compile_threshold(Tier4BackEdgeThreshold));
+    FLAG_SET_ERGO(Tier4InvocationThreshold, scaled_compile_threshold(Tier4InvocationThreshold));
+    FLAG_SET_ERGO(Tier4MinInvocationThreshold, scaled_compile_threshold(Tier4MinInvocationThreshold));
+    FLAG_SET_ERGO(Tier4CompileThreshold, scaled_compile_threshold(Tier4CompileThreshold));
+    FLAG_SET_ERGO(Tier4BackEdgeThreshold, scaled_compile_threshold(Tier4BackEdgeThreshold));
   }
 }
 
@@ -256,7 +256,7 @@
     if (TieredStopAtLevel != CompLevel_full_optimization) {
       // Currently JVMCI compiler can only work at the full optimization level
       warning("forcing TieredStopAtLevel to full optimization because JVMCI is enabled");
-      FLAG_SET_ERGO(intx, TieredStopAtLevel, CompLevel_full_optimization);
+      FLAG_SET_ERGO(TieredStopAtLevel, CompLevel_full_optimization);
     }
     if (FLAG_IS_DEFAULT(TypeProfileLevel)) {
       FLAG_SET_DEFAULT(TypeProfileLevel, 0);
@@ -338,7 +338,7 @@
     if (!FLAG_IS_DEFAULT(BackgroundCompilation)) {
       warning("BackgroundCompilation disabled due to ReplayCompiles option.");
     }
-    FLAG_SET_CMDLINE(bool, BackgroundCompilation, false);
+    FLAG_SET_CMDLINE(BackgroundCompilation, false);
   }
 
 #ifdef COMPILER2
@@ -346,7 +346,7 @@
     if (!FLAG_IS_DEFAULT(PostLoopMultiversioning)) {
       warning("PostLoopMultiversioning disabled because RangeCheckElimination is disabled.");
     }
-    FLAG_SET_CMDLINE(bool, PostLoopMultiversioning, false);
+    FLAG_SET_CMDLINE(PostLoopMultiversioning, false);
   }
   if (UseCountedLoopSafepoints && LoopStripMiningIter == 0) {
     if (!FLAG_IS_DEFAULT(UseCountedLoopSafepoints) || !FLAG_IS_DEFAULT(LoopStripMiningIter)) {
@@ -366,27 +366,27 @@
       if (!FLAG_IS_DEFAULT(UseCompiler)) {
         warning("UseCompiler disabled due to -Xint.");
       }
-      FLAG_SET_CMDLINE(bool, UseCompiler, false);
+      FLAG_SET_CMDLINE(UseCompiler, false);
     }
     if (ProfileInterpreter) {
       if (!FLAG_IS_DEFAULT(ProfileInterpreter)) {
         warning("ProfileInterpreter disabled due to -Xint.");
       }
-      FLAG_SET_CMDLINE(bool, ProfileInterpreter, false);
+      FLAG_SET_CMDLINE(ProfileInterpreter, false);
     }
     if (TieredCompilation) {
       if (!FLAG_IS_DEFAULT(TieredCompilation)) {
         warning("TieredCompilation disabled due to -Xint.");
       }
-      FLAG_SET_CMDLINE(bool, TieredCompilation, false);
+      FLAG_SET_CMDLINE(TieredCompilation, false);
     }
 #if INCLUDE_JVMCI
     if (EnableJVMCI) {
       if (!FLAG_IS_DEFAULT(EnableJVMCI) || !FLAG_IS_DEFAULT(UseJVMCICompiler)) {
         warning("JVMCI Compiler disabled due to -Xint.");
       }
-      FLAG_SET_CMDLINE(bool, EnableJVMCI, false);
-      FLAG_SET_CMDLINE(bool, UseJVMCICompiler, false);
+      FLAG_SET_CMDLINE(EnableJVMCI, false);
+      FLAG_SET_CMDLINE(UseJVMCICompiler, false);
     }
 #endif
   } else {
@@ -434,7 +434,7 @@
     // Scale CompileThreshold
     // CompileThresholdScaling == 0.0 is equivalent to -Xint and leaves CompileThreshold unchanged.
     if (!FLAG_IS_DEFAULT(CompileThresholdScaling) && CompileThresholdScaling > 0.0) {
-      FLAG_SET_ERGO(intx, CompileThreshold, scaled_compile_threshold(CompileThreshold));
+      FLAG_SET_ERGO(CompileThreshold, scaled_compile_threshold(CompileThreshold));
     }
   }
 
@@ -455,7 +455,7 @@
     AlwaysIncrementalInline = false;
   }
   if (PrintIdealGraphLevel > 0) {
-    FLAG_SET_ERGO(bool, PrintIdealGraph, true);
+    FLAG_SET_ERGO(PrintIdealGraph, true);
   }
 #endif
   if (!UseTypeSpeculation && FLAG_IS_DEFAULT(TypeProfileLevel)) {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/compiler/compiler_globals.hpp	Thu May 23 11:07:37 2019 +0100
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 1997, 2019, 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.
+ *
+ */
+
+#ifndef SHARE_COMPILER_COMPILER_GLOBALS_HPP
+#define SHARE_COMPILER_COMPILER_GLOBALS_HPP
+
+#include "runtime/globals_shared.hpp"
+#ifdef COMPILER1
+#include "c1/c1_globals.hpp"
+#endif // COMPILER1
+#ifdef COMPILER2
+#include "opto/c2_globals.hpp"
+#endif // COMPILER2
+#if INCLUDE_JVMCI
+#include "jvmci/jvmci_globals.hpp"
+#endif
+
+#if !defined(COMPILER1) && !defined(COMPILER2) && !INCLUDE_JVMCI
+define_pd_global(bool, BackgroundCompilation,        false);
+define_pd_global(bool, UseTLAB,                      false);
+define_pd_global(bool, CICompileOSR,                 false);
+define_pd_global(bool, UseTypeProfile,               false);
+define_pd_global(bool, UseOnStackReplacement,        false);
+define_pd_global(bool, InlineIntrinsics,             false);
+define_pd_global(bool, PreferInterpreterNativeStubs, true);
+define_pd_global(bool, ProfileInterpreter,           false);
+define_pd_global(bool, ProfileTraps,                 false);
+define_pd_global(bool, TieredCompilation,            false);
+
+define_pd_global(intx, CompileThreshold,             0);
+
+define_pd_global(intx,   OnStackReplacePercentage,   0);
+define_pd_global(bool,   ResizeTLAB,                 false);
+define_pd_global(intx,   FreqInlineSize,             0);
+define_pd_global(size_t, NewSizeThreadIncrease,      4*K);
+define_pd_global(bool,   InlineClassNatives,         true);
+define_pd_global(bool,   InlineUnsafeOps,            true);
+define_pd_global(uintx,  InitialCodeCacheSize,       160*K);
+define_pd_global(uintx,  ReservedCodeCacheSize,      32*M);
+define_pd_global(uintx,  NonProfiledCodeHeapSize,    0);
+define_pd_global(uintx,  ProfiledCodeHeapSize,       0);
+define_pd_global(uintx,  NonNMethodCodeHeapSize,     32*M);
+
+define_pd_global(uintx,  CodeCacheExpansionSize,     32*K);
+define_pd_global(uintx,  CodeCacheMinBlockLength,    1);
+define_pd_global(uintx,  CodeCacheMinimumUseSpace,   200*K);
+define_pd_global(size_t, MetaspaceSize,              ScaleForWordSize(4*M));
+define_pd_global(bool, NeverActAsServerClassMachine, true);
+define_pd_global(uint64_t,MaxRAM,                    1ULL*G);
+#define CI_COMPILER_COUNT 0
+#else
+
+#if COMPILER2_OR_JVMCI
+#define CI_COMPILER_COUNT 2
+#else
+#define CI_COMPILER_COUNT 1
+#endif // COMPILER2_OR_JVMCI
+
+#endif // no compilers
+
+#endif // SHARE_COMPILER_COMPILER_GLOBALS_HPP
--- a/src/hotspot/share/compiler/disassembler.cpp	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/share/compiler/disassembler.cpp	Thu May 23 11:07:37 2019 +0100
@@ -23,6 +23,7 @@
  */
 
 #include "precompiled.hpp"
+#include "asm/assembler.inline.hpp"
 #include "asm/macroAssembler.hpp"
 #include "ci/ciUtilities.hpp"
 #include "classfile/javaClasses.hpp"
@@ -43,6 +44,7 @@
 
 void*       Disassembler::_library               = NULL;
 bool        Disassembler::_tried_to_load_library = false;
+bool        Disassembler::_library_usable        = false;
 
 // This routine is in the shared library:
 Disassembler::decode_func_virtual Disassembler::_decode_instructions_virtual = NULL;
@@ -55,127 +57,46 @@
 #define COMMENT_COLUMN  52 LP64_ONLY(+8) /*could be an option*/
 #define BYTES_COMMENT   ";..."  /* funky byte display comment */
 
-bool Disassembler::load_library() {
-  if (_decode_instructions_virtual != NULL || _decode_instructions != NULL) {
-    // Already succeeded.
-    return true;
-  }
-  if (_tried_to_load_library) {
-    // Do not try twice.
-    // To force retry in debugger: assign _tried_to_load_library=0
-    return false;
-  }
-  // Try to load it.
-  char ebuf[1024];
-  char buf[JVM_MAXPATHLEN];
-  os::jvm_path(buf, sizeof(buf));
-  int jvm_offset = -1;
-  int lib_offset = -1;
-#ifdef STATIC_BUILD
-  char* p = strrchr(buf, '/');
-  *p = '\0';
-  strcat(p, "/lib/");
-  lib_offset = jvm_offset = strlen(buf);
-#else
-  {
-    // Match "jvm[^/]*" in jvm_path.
-    const char* base = buf;
-    const char* p = strrchr(buf, *os::file_separator());
-    if (p != NULL) lib_offset = p - base + 1;
-    p = strstr(p ? p : base, "jvm");
-    if (p != NULL) jvm_offset = p - base;
-  }
-#endif
-  // Find the disassembler shared library.
-  // Search for several paths derived from libjvm, in this order:
-  // 1. <home>/jre/lib/<arch>/<vm>/libhsdis-<arch>.so  (for compatibility)
-  // 2. <home>/jre/lib/<arch>/<vm>/hsdis-<arch>.so
-  // 3. <home>/jre/lib/<arch>/hsdis-<arch>.so
-  // 4. hsdis-<arch>.so  (using LD_LIBRARY_PATH)
-  if (jvm_offset >= 0) {
-    // 1. <home>/jre/lib/<arch>/<vm>/libhsdis-<arch>.so
-    strcpy(&buf[jvm_offset], hsdis_library_name);
-    strcat(&buf[jvm_offset], os::dll_file_extension());
-    _library = os::dll_load(buf, ebuf, sizeof ebuf);
-    if (_library == NULL && lib_offset >= 0) {
-      // 2. <home>/jre/lib/<arch>/<vm>/hsdis-<arch>.so
-      strcpy(&buf[lib_offset], hsdis_library_name);
-      strcat(&buf[lib_offset], os::dll_file_extension());
-      _library = os::dll_load(buf, ebuf, sizeof ebuf);
-    }
-    if (_library == NULL && lib_offset > 0) {
-      // 3. <home>/jre/lib/<arch>/hsdis-<arch>.so
-      buf[lib_offset - 1] = '\0';
-      const char* p = strrchr(buf, *os::file_separator());
-      if (p != NULL) {
-        lib_offset = p - buf + 1;
-        strcpy(&buf[lib_offset], hsdis_library_name);
-        strcat(&buf[lib_offset], os::dll_file_extension());
-        _library = os::dll_load(buf, ebuf, sizeof ebuf);
-      }
-    }
-  }
-  if (_library == NULL) {
-    // 4. hsdis-<arch>.so  (using LD_LIBRARY_PATH)
-    strcpy(&buf[0], hsdis_library_name);
-    strcat(&buf[0], os::dll_file_extension());
-    _library = os::dll_load(buf, ebuf, sizeof ebuf);
-  }
-  if (_library != NULL) {
-    _decode_instructions_virtual = CAST_TO_FN_PTR(Disassembler::decode_func_virtual,
-                                          os::dll_lookup(_library, decode_instructions_virtual_name));
-  }
-  if (_decode_instructions_virtual == NULL && _library != NULL) {
-    // could not spot in new version, try old version
-    _decode_instructions = CAST_TO_FN_PTR(Disassembler::decode_func,
-                                          os::dll_lookup(_library, decode_instructions_name));
-    use_new_version = false;
-  } else {
-    use_new_version = true;
-  }
-  _tried_to_load_library = true;
-  if (_decode_instructions_virtual == NULL && _decode_instructions == NULL) {
-    tty->print_cr("Could not load %s; %s; %s", buf,
-                  ((_library != NULL)
-                   ? "entry point is missing"
-                   : (WizardMode || PrintMiscellaneous)
-                   ? (const char*)ebuf
-                   : "library not loadable"),
-                  "PrintAssembly is disabled");
-    return false;
-  }
-
-  // Success.
-  tty->print_cr("Loaded disassembler from %s", buf);
-  return true;
-}
-
-
 class decode_env {
  private:
-  nmethod*      _nm;
-  CodeBlob*     _code;
+  outputStream* _output;      // where the disassembly is directed to
+  CodeBuffer*   _codeBuffer;  // != NULL only when decoding a CodeBuffer
+  CodeBlob*     _codeBlob;    // != NULL only when decoding a CodeBlob
+  nmethod*      _nm;          // != NULL only when decoding a nmethod
   CodeStrings   _strings;
-  outputStream* _output;
-  address       _start, _end;
-  ptrdiff_t     _offset;
+  address       _start;       // != NULL when decoding a range of unknown type
+  address       _end;         // != NULL when decoding a range of unknown type
 
   char          _option_buf[512];
   char          _print_raw;
-  bool          _print_pc;
-  bool          _print_bytes;
-  address       _cur_insn;
-  int           _bytes_per_line; // arch-specific formatting option
+  address       _cur_insn;        // address of instruction currently being decoded
+  int           _bytes_per_line;  // arch-specific formatting option
+  int           _pre_decode_alignment;
+  int           _post_decode_alignment;
   bool          _print_file_name;
+  bool          _print_help;
+  bool          _helpPrinted;
+  static bool   _optionsParsed;
 
+  enum {
+    tabspacing = 8
+  };
+
+  // Check if the event matches the expected tag
+  // The tag must be a substring of the event, and
+  // the tag must be a token in the event, i.e. separated by delimiters
   static bool match(const char* event, const char* tag) {
-    size_t taglen = strlen(tag);
-    if (strncmp(event, tag, taglen) != 0)
+    size_t eventlen = strlen(event);
+    size_t taglen   = strlen(tag);
+    if (eventlen < taglen)  // size mismatch
+      return false;
+    if (strncmp(event, tag, taglen) != 0)  // string mismatch
       return false;
     char delim = event[taglen];
     return delim == '\0' || delim == ' ' || delim == '/' || delim == '=';
   }
 
+  // Merge new option string with previously recorded options
   void collect_options(const char* p) {
     if (p == NULL || p[0] == '\0')  return;
     size_t opt_so_far = strlen(_option_buf);
@@ -187,14 +108,56 @@
     char* q = fillp;
     while ((q = strpbrk(q, " \t\n")) != NULL)
       *q++ = ',';
-    // Note that multiple PrintAssemblyOptions flags accumulate with \n,
-    // which we want to be changed to a comma...
   }
 
+  void process_options(outputStream* ost);
+
   void print_insn_labels();
-  void print_insn_bytes(address pc0, address pc);
+  void print_insn_prefix();
   void print_address(address value);
 
+  // Properly initializes _start/_end. Overwritten too often if
+  // printing of instructions is called for each instruction.
+  void set_start(address s)   { _start = s; }
+  void set_end  (address e)   { _end = e; }
+  void set_nm   (nmethod* nm) { _nm = nm; }
+  void set_output(outputStream* st) { _output = st; }
+
+#if defined(SUPPORT_ASSEMBLY) || defined(SUPPORT_ABSTRACT_ASSEMBLY)
+  // The disassembler library (sometimes) uses tabs to nicely align the instruction operands.
+  // Depending on the mnemonic length and the column position where the
+  // mnemonic is printed, alignment may turn out to be not so nice.
+  // To improve, we assume 8-character tab spacing and left-align the mnemonic on a tab position.
+  // Instruction comments are aligned 4 tab positions to the right of the mnemonic.
+  void calculate_alignment() {
+    _pre_decode_alignment  = ((output()->position()+tabspacing-1)/tabspacing)*tabspacing;
+    _post_decode_alignment = _pre_decode_alignment + 4*tabspacing;
+  }
+
+  void start_insn(address pc) {
+    _cur_insn = pc;
+    output()->bol();
+    print_insn_labels();
+    print_insn_prefix();
+  }
+
+  void end_insn(address pc) {
+    address pc0 = cur_insn();
+    outputStream* st = output();
+
+    if (AbstractDisassembler::show_comment()) {
+      if ((_nm != NULL) && _nm->has_code_comment(pc0, pc)) {
+        _nm->print_code_comment_on(st, _post_decode_alignment, pc0, pc);
+        // this calls reloc_string_for which calls oop::print_value_on
+      }
+      print_hook_comments(pc0, _nm != NULL);
+    }
+    Disassembler::annotate(pc0, output());
+    // follow each complete insn by a nice newline
+    st->bol();
+  }
+#endif
+
   struct SourceFileInfo {
     struct Link : public CHeapObj<mtCode> {
       const char* file;
@@ -241,40 +204,28 @@
   static GrowableArray<const char*>* _cached_src_lines;
 
  public:
-  decode_env(CodeBlob* code, outputStream* output,
-             CodeStrings c = CodeStrings(), ptrdiff_t offset = 0);
-
-  address decode_instructions(address start, address end);
-
-  void start_insn(address pc) {
-    _cur_insn = pc;
-    output()->bol();
-    print_insn_labels();
-  }
+  decode_env(CodeBuffer* code, outputStream* output);
+  decode_env(CodeBlob*   code, outputStream* output, CodeStrings c = CodeStrings() /* , ptrdiff_t offset */);
+  decode_env(nmethod*    code, outputStream* output, CodeStrings c = CodeStrings());
+  // Constructor for a 'decode_env' to decode an arbitrary
+  // piece of memory, hopefully containing code.
+  decode_env(address start, address end, outputStream* output);
 
-  void end_insn(address pc) {
-    address pc0 = cur_insn();
-    outputStream* st = output();
-    if (_print_bytes && pc > pc0)
-      print_insn_bytes(pc0, pc);
-    if (_nm != NULL) {
-      _nm->print_code_comment_on(st, COMMENT_COLUMN, pc0, pc);
-      // this calls reloc_string_for which calls oop::print_value_on
-    }
-    print_hook_comments(pc0, _nm != NULL);
-    // follow each complete insn by a nice newline
-    st->cr();
-  }
+  // Add 'original_start' argument which is the the original address
+  // the instructions were located at (if this is not equal to 'start').
+  address decode_instructions(address start, address end, address original_start = NULL);
 
   address handle_event(const char* event, address arg);
 
-  outputStream* output() { return _output; }
-  address cur_insn() { return _cur_insn; }
-  const char* options() { return _option_buf; }
-  static void hook(const char* file, int line, address pc);
+  outputStream* output()   { return _output; }
+  address       cur_insn() { return _cur_insn; }
+  const char*   options()  { return _option_buf; }
+  static void   hook(const char* file, int line, address pc);
   void print_hook_comments(address pc, bool newline);
 };
 
+bool decode_env::_optionsParsed = false;
+
 decode_env::SourceFileInfoTable decode_env::_src_table;
 const char* decode_env::_cached_src = NULL;
 GrowableArray<const char*>* decode_env::_cached_src_lines = NULL;
@@ -361,50 +312,185 @@
   }
 }
 
-decode_env::decode_env(CodeBlob* code, outputStream* output, CodeStrings c,
-                       ptrdiff_t offset) : _nm(NULL),
-                                           _start(NULL),
-                                           _end(NULL),
-                                           _option_buf(),
-                                           _print_raw('\0'),
-                                           _cur_insn(NULL) {
+decode_env::decode_env(CodeBuffer* code, outputStream* output) {
+  memset(this, 0, sizeof(*this));
+  _output = output ? output : tty;
+  _codeBlob    = NULL;
+  _codeBuffer  = code;
+  _helpPrinted = false;
+
+  process_options(_output);
+}
+
+decode_env::decode_env(CodeBlob* code, outputStream* output, CodeStrings c) {
+   memset(this, 0, sizeof(*this)); // Beware, this zeroes bits of fields.
+   _output = output ? output : tty;
+  _codeBlob    = code;
+  _codeBuffer  = NULL;
+  _helpPrinted = false;
+  if (_codeBlob != NULL && _codeBlob->is_nmethod()) {
+    _nm = (nmethod*) code;
+  }
+  _strings.copy(c);
+
+  process_options(_output);
+}
+
+decode_env::decode_env(nmethod* code, outputStream* output, CodeStrings c) {
+  memset(this, 0, sizeof(*this)); // Beware, this zeroes bits of fields.
   _output = output ? output : tty;
-  _code = code;
-  if (code != NULL && code->is_nmethod())
-    _nm = (nmethod*) code;
+  _codeBlob    = NULL;
+  _codeBuffer  = NULL;
+  _nm          = code;
+  _start       = _nm->code_begin();
+  _end         = _nm->code_end();
+  _helpPrinted = false;
   _strings.copy(c);
-  _offset = offset;
+
+  process_options(_output);
+}
 
+// Constructor for a 'decode_env' to decode a memory range [start, end)
+// of unknown origin, assuming it contains code.
+decode_env::decode_env(address start, address end, outputStream* output) {
+  assert(start < end, "Range must have a positive size, [" PTR_FORMAT ".." PTR_FORMAT ").", p2i(start), p2i(end));
+  memset(this, 0, sizeof(*this));
+  _output = output ? output : tty;
+  _codeBlob    = NULL;
+  _codeBuffer  = NULL;
+  _start       = start;
+  _end         = end;
+  _helpPrinted = false;
+
+  process_options(_output);
+}
+
+void decode_env::process_options(outputStream* ost) {
   // by default, output pc but not bytes:
-  _print_pc       = true;
-  _print_bytes    = false;
-  _bytes_per_line = Disassembler::pd_instruction_alignment();
-  _print_file_name= true;
+  _print_help      = false;
+  _bytes_per_line  = Disassembler::pd_instruction_alignment();
+  _print_file_name = true;
+
+  if (_optionsParsed) return;  // parse only once
 
   // parse the global option string:
   collect_options(Disassembler::pd_cpu_opts());
   collect_options(PrintAssemblyOptions);
 
-  if (strstr(options(), "hsdis-")) {
-    if (strstr(options(), "hsdis-print-raw"))
-      _print_raw = (strstr(options(), "xml") ? 2 : 1);
-    if (strstr(options(), "hsdis-print-pc"))
-      _print_pc = !_print_pc;
-    if (strstr(options(), "hsdis-print-bytes"))
-      _print_bytes = !_print_bytes;
+  if (strstr(options(), "print-raw")) {
+    _print_raw = (strstr(options(), "xml") ? 2 : 1);
+  }
+
+  if (strstr(options(), "help")) {
+    _print_help = true;
+  }
+  if (strstr(options(), "align-instr")) {
+    AbstractDisassembler::toggle_align_instr();
+  }
+  if (strstr(options(), "show-pc")) {
+    AbstractDisassembler::toggle_show_pc();
+  }
+  if (strstr(options(), "show-offset")) {
+    AbstractDisassembler::toggle_show_offset();
+  }
+  if (strstr(options(), "show-bytes")) {
+    AbstractDisassembler::toggle_show_bytes();
+  }
+  if (strstr(options(), "show-data-hex")) {
+    AbstractDisassembler::toggle_show_data_hex();
+  }
+  if (strstr(options(), "show-data-int")) {
+    AbstractDisassembler::toggle_show_data_int();
+  }
+  if (strstr(options(), "show-data-float")) {
+    AbstractDisassembler::toggle_show_data_float();
   }
-  if (strstr(options(), "help")) {
-    tty->print_cr("PrintAssemblyOptions help:");
-    tty->print_cr("  hsdis-print-raw       test plugin by requesting raw output");
-    tty->print_cr("  hsdis-print-raw-xml   test plugin by requesting raw xml");
-    tty->print_cr("  hsdis-print-pc        turn off PC printing (on by default)");
-    tty->print_cr("  hsdis-print-bytes     turn on instruction byte output");
-    tty->print_cr("combined options: %s", options());
+  if (strstr(options(), "show-structs")) {
+    AbstractDisassembler::toggle_show_structs();
+  }
+  if (strstr(options(), "show-comment")) {
+    AbstractDisassembler::toggle_show_comment();
+  }
+  if (strstr(options(), "show-block-comment")) {
+    AbstractDisassembler::toggle_show_block_comment();
+  }
+  _optionsParsed = true;
+
+  if (_print_help && ! _helpPrinted) {
+    _helpPrinted = true;
+    ost->print_cr("PrintAssemblyOptions help:");
+    ost->print_cr("  print-raw       test plugin by requesting raw output");
+    ost->print_cr("  print-raw-xml   test plugin by requesting raw xml");
+    ost->cr();
+    ost->print_cr("  show-pc            toggle printing current pc,        currently %s", AbstractDisassembler::show_pc()            ? "ON" : "OFF");
+    ost->print_cr("  show-offset        toggle printing current offset,    currently %s", AbstractDisassembler::show_offset()        ? "ON" : "OFF");
+    ost->print_cr("  show-bytes         toggle printing instruction bytes, currently %s", AbstractDisassembler::show_bytes()         ? "ON" : "OFF");
+    ost->print_cr("  show-data-hex      toggle formatting data as hex,     currently %s", AbstractDisassembler::show_data_hex()      ? "ON" : "OFF");
+    ost->print_cr("  show-data-int      toggle formatting data as int,     currently %s", AbstractDisassembler::show_data_int()      ? "ON" : "OFF");
+    ost->print_cr("  show-data-float    toggle formatting data as float,   currently %s", AbstractDisassembler::show_data_float()    ? "ON" : "OFF");
+    ost->print_cr("  show-structs       toggle compiler data structures,   currently %s", AbstractDisassembler::show_structs()       ? "ON" : "OFF");
+    ost->print_cr("  show-comment       toggle instruction comments,       currently %s", AbstractDisassembler::show_comment()       ? "ON" : "OFF");
+    ost->print_cr("  show-block-comment toggle block comments,             currently %s", AbstractDisassembler::show_block_comment() ? "ON" : "OFF");
+    ost->print_cr("  align-instr        toggle instruction alignment,      currently %s", AbstractDisassembler::align_instr()        ? "ON" : "OFF");
+    ost->print_cr("combined options: %s", options());
   }
 }
 
+// Disassembly Event Handler.
+// This method receives events from the disassembler library hsdis
+// via event_to_env for each decoding step (installed by
+// Disassembler::decode_instructions(), replacing the default
+// callback method). This enables dumping additional info
+// and custom line formatting.
+// In a future extension, calling a custom decode method will be
+// supported. We can use such a method to decode instructions the
+// binutils decoder does not handle to our liking (suboptimal
+// formatting, incomplete information, ...).
+// Returns:
+// - NULL for all standard invocations. The function result is not
+//        examined (as of now, 20190409) by the hsdis decoder loop.
+// - next for 'insn0' invocations.
+//        next == arg: the custom decoder didn't do anything.
+//        next >  arg: the custom decoder did decode the instruction.
+//                     next points to the next undecoded instruction
+//                     (continuation point for decoder loop).
+//
+// "Normal" sequence of events:
+//  insns   - start of instruction stream decoding
+//  mach    - display architecture
+//  format  - display bytes-per-line
+//  for each instruction:
+//    insn    - start of instruction decoding
+//    insn0   - custom decoder invocation (if any)
+//    addr    - print address value
+//    /insn   - end of instruction decoding
+//  /insns  - premature end of instruction stream due to no progress
+//
 address decode_env::handle_event(const char* event, address arg) {
-  if (match(event, "insn")) {
+
+#if defined(SUPPORT_ASSEMBLY) || defined(SUPPORT_ABSTRACT_ASSEMBLY)
+
+  //---<  Event: end decoding loop (error, no progress)  >---
+  if (decode_env::match(event, "/insns")) {
+    // Nothing to be done here.
+    return NULL;
+  }
+
+  //---<  Event: start decoding loop  >---
+  if (decode_env::match(event, "insns")) {
+    // Nothing to be done here.
+    return NULL;
+  }
+
+  //---<  Event: finish decoding an instruction  >---
+  if (decode_env::match(event, "/insn")) {
+    output()->fill_to(_post_decode_alignment);
+    end_insn(arg);
+    return NULL;
+  }
+
+  //---<  Event: start decoding an instruction  >---
+  if (decode_env::match(event, "insn")) {
     start_insn(arg);
   } else if (match(event, "/insn")) {
     end_insn(arg);
@@ -413,26 +499,59 @@
       print_address(arg);
       return arg;
     }
-  } else if (match(event, "mach")) {
-    static char buffer[32] = { 0, };
-    if (strcmp(buffer, (const char*)arg) != 0 ||
-        strlen((const char*)arg) > sizeof(buffer) - 1) {
+    calculate_alignment();
+    output()->fill_to(_pre_decode_alignment);
+    return NULL;
+  }
+
+  //---<  Event: call custom decoder (platform specific)  >---
+  if (decode_env::match(event, "insn0")) {
+    return Disassembler::decode_instruction0(arg, output(), arg);
+  }
+
+  //---<  Event: Print address  >---
+  if (decode_env::match(event, "addr")) {
+    print_address(arg);
+    return arg;
+  }
+
+  //---<  Event: mach (inform about machine architecture)  >---
+  // This event is problematic because it messes up the output.
+  // The event is fired after the instruction address has already
+  // been printed. The decoded instruction (event "insn") is
+  // printed afterwards. That doesn't look nice.
+  if (decode_env::match(event, "mach")) {
+    guarantee(arg != NULL, "event_to_env - arg must not be NULL for event 'mach'");
+    static char buffer[64] = { 0, };
+    // Output suppressed because it messes up disassembly.
+    // Only print this when the mach changes.
+    if (false && (strcmp(buffer, (const char*)arg) != 0 ||
+                  strlen((const char*)arg) > sizeof(buffer) - 1)) {
       // Only print this when the mach changes
       strncpy(buffer, (const char*)arg, sizeof(buffer) - 1);
       buffer[sizeof(buffer) - 1] = '\0';
-      output()->print_cr("[Disassembling for mach='%s']", arg);
+      output()->print_cr("[Disassembling for mach='%s']", (const char*)arg);
     }
-  } else if (match(event, "format bytes-per-line")) {
+    return NULL;
+  }
+
+  //---<  Event: format bytes-per-line  >---
+  if (decode_env::match(event, "format bytes-per-line")) {
     _bytes_per_line = (int) (intptr_t) arg;
-  } else {
-    // ignore unrecognized markup
+    return NULL;
   }
+#endif
   return NULL;
 }
 
+static void* event_to_env(void* env_pv, const char* event, void* arg) {
+  decode_env* env = (decode_env*) env_pv;
+  return env->handle_event(event, (address) arg);
+}
+
 // called by the disassembler to print out jump targets and data addresses
 void decode_env::print_address(address adr) {
-  outputStream* st = _output;
+  outputStream* st = output();
 
   if (adr == NULL) {
     st->print("NULL");
@@ -477,9 +596,11 @@
   if (_nm == NULL) {
     // Don't do this for native methods, as the function name will be printed in
     // nmethod::reloc_string_for().
-    ResourceMark rm;
+    // Allocate the buffer on the stack instead of as RESOURCE array.
+    // In case we do DecodeErrorFile, Thread will not be initialized,
+    // causing a "assert(current != __null) failed" failure.
     const int buflen = 1024;
-    char* buf = NEW_RESOURCE_ARRAY(char, buflen);
+    char buf[buflen];
     int offset;
     if (os::dll_address_to_function_name(adr, buf, buflen, &offset)) {
       st->print(PTR_FORMAT " = %s",  p2i(adr), buf);
@@ -495,54 +616,31 @@
 }
 
 void decode_env::print_insn_labels() {
-  address p = cur_insn();
-  outputStream* st = output();
-  CodeBlob* cb = _code;
-  if (cb != NULL) {
-    cb->print_block_comment(st, p);
-  }
-  _strings.print_block_comment(st, (intptr_t)(p - _start + _offset));
-  if (_print_pc) {
-    st->print("  " PTR_FORMAT ": ", p2i(p));
+  if (AbstractDisassembler::show_block_comment()) {
+    address       p  = cur_insn();
+    outputStream* st = output();
+
+    //---<  Block comments for nmethod  >---
+    // Outputs a bol() before and a cr() after, but only if a comment is printed.
+    // Prints nmethod_section_label as well.
+    if (_nm != NULL) {
+      _nm->print_block_comment(st, p);
+    }
+    if (_codeBlob != NULL) {
+      _codeBlob->print_block_comment(st, p);
+    }
+    if (_codeBuffer != NULL) {
+      _codeBuffer->print_block_comment(st, p);
+    }
+    _strings.print_block_comment(st, (intptr_t)(p - _start));
   }
 }
 
-void decode_env::print_insn_bytes(address pc, address pc_limit) {
+void decode_env::print_insn_prefix() {
+  address       p  = cur_insn();
   outputStream* st = output();
-  size_t incr = 1;
-  size_t perline = _bytes_per_line;
-  if ((size_t) Disassembler::pd_instruction_alignment() >= sizeof(int)
-      && !((uintptr_t)pc % sizeof(int))
-      && !((uintptr_t)pc_limit % sizeof(int))) {
-    incr = sizeof(int);
-    if (perline % incr)  perline += incr - (perline % incr);
-  }
-  while (pc < pc_limit) {
-    // tab to the desired column:
-    st->move_to(COMMENT_COLUMN);
-    address pc0 = pc;
-    address pc1 = pc + perline;
-    if (pc1 > pc_limit)  pc1 = pc_limit;
-    for (; pc < pc1; pc += incr) {
-      if (pc == pc0) {
-        st->print(BYTES_COMMENT);
-      } else if ((uint)(pc - pc0) % sizeof(int) == 0) {
-        st->print(" ");         // put out a space on word boundaries
-      }
-      if (incr == sizeof(int)) {
-        st->print("%08x", *(int*)pc);
-      } else {
-        st->print("%02x", (*pc)&0xFF);
-      }
-    }
-    st->cr();
-  }
-}
-
-
-static void* event_to_env(void* env_pv, const char* event, void* arg) {
-  decode_env* env = (decode_env*) env_pv;
-  return env->handle_event(event, (address) arg);
+  AbstractDisassembler::print_location(p, _start, _end, st, false, false);
+  AbstractDisassembler::print_instruction(p, Assembler::instr_len(p), Assembler::instr_maxlen(), st, true, false);
 }
 
 ATTRIBUTE_PRINTF(2, 3)
@@ -575,16 +673,31 @@
   return (int)(cnt1 - cnt0);
 }
 
-address decode_env::decode_instructions(address start, address end) {
-  _start = start; _end = end;
-
-  assert(((((intptr_t)start | (intptr_t)end) % Disassembler::pd_instruction_alignment()) == 0), "misaligned insn addr");
+// The 'original_start' argument holds the the original address where
+// the instructions were located in the originating system. If zero (NULL)
+// is passed in, there is no original address.
+address decode_env::decode_instructions(address start, address end, address original_start /* = 0*/) {
+  // CodeComment in Stubs.
+  // Properly initialize _start/_end. Overwritten too often if
+  // printing of instructions is called for each instruction.
+  assert((_start == NULL) || (start == NULL) || (_start == start), "don't overwrite CTOR values");
+  assert((_end   == NULL) || (end   == NULL) || (_end   == end  ), "don't overwrite CTOR values");
+  if (start != NULL) set_start(start);
+  if (end   != NULL) set_end(end);
+  if (original_start == NULL) {
+    original_start = start;
+  }
 
-  const int show_bytes = false; // for disassembler debugging
+  //---<  Check (and correct) alignment  >---
+  // Don't check alignment of end, it is not aligned.
+  if (((uint64_t)start & ((uint64_t)Disassembler::pd_instruction_alignment() - 1)) != 0) {
+    output()->print_cr("Decode range start:" PTR_FORMAT ": ... (unaligned)", p2i(start));
+    start = (address)((uint64_t)start & ~((uint64_t)Disassembler::pd_instruction_alignment() - 1));
+  }
 
-  //_version = Disassembler::pd_cpu_version();
-
-  if (!Disassembler::can_decode()) {
+  // Trying to decode instructions doesn't make sense if we
+  // couldn't load the disassembler library.
+  if (Disassembler::is_abstract()) {
     return NULL;
   }
 
@@ -625,16 +738,177 @@
                                           options());
 }
 
+// ----------------------------------------------------------------------------
+// Disassembler
+// Used as a static wrapper for decode_env.
+// Each method will create a decode_env before decoding.
+// You can call the decode_env methods directly if you already have one.
 
-void Disassembler::decode(CodeBlob* cb, outputStream* st) {
-  ttyLocker ttyl;
-  if (!load_library())  return;
-  if (cb->is_nmethod()) {
-    decode((nmethod*)cb, st);
+
+bool Disassembler::load_library(outputStream* st) {
+  // Do not try to load multiple times. Failed once -> fails always.
+  // To force retry in debugger: assign _tried_to_load_library=0
+  if (_tried_to_load_library) {
+    return _library_usable;
+  }
+
+#if defined(SUPPORT_ASSEMBLY) || defined(SUPPORT_ABSTRACT_ASSEMBLY)
+  // Print to given stream, if any.
+  // Print to tty if Verbose is on and no stream given.
+  st = ((st == NULL) && Verbose) ? tty : st;
+
+  // Compute fully qualified library name.
+  char ebuf[1024];
+  char buf[JVM_MAXPATHLEN];
+  os::jvm_path(buf, sizeof(buf));
+  int jvm_offset = -1;
+  int lib_offset = -1;
+#ifdef STATIC_BUILD
+  char* p = strrchr(buf, '/');
+  *p = '\0';
+  strcat(p, "/lib/");
+  lib_offset = jvm_offset = strlen(buf);
+#else
+  {
+    // Match "libjvm" instead of "jvm" on *nix platforms. Creates better matches.
+    // Match "[lib]jvm[^/]*" in jvm_path.
+    const char* base = buf;
+    const char* p = strrchr(buf, *os::file_separator());
+#ifdef _WIN32
+    p = strstr(p ? p : base, "jvm");
+#else
+    p = strstr(p ? p : base, "libjvm");
+#endif
+    if (p != NULL) lib_offset = p - base + 1;
+    if (p != NULL) jvm_offset = p - base;
+  }
+#endif
+
+  // Find the disassembler shared library.
+  // Search for several paths derived from libjvm, in this order:
+  // 1. <home>/jre/lib/<arch>/<vm>/libhsdis-<arch>.so  (for compatibility)
+  // 2. <home>/jre/lib/<arch>/<vm>/hsdis-<arch>.so
+  // 3. <home>/jre/lib/<arch>/hsdis-<arch>.so
+  // 4. hsdis-<arch>.so  (using LD_LIBRARY_PATH)
+  if (jvm_offset >= 0) {
+    // 1. <home>/jre/lib/<arch>/<vm>/libhsdis-<arch>.so
+    strcpy(&buf[jvm_offset], hsdis_library_name);
+    strcat(&buf[jvm_offset], os::dll_file_extension());
+    _library = os::dll_load(buf, ebuf, sizeof ebuf);
+    if (_library == NULL && lib_offset >= 0) {
+      // 2. <home>/jre/lib/<arch>/<vm>/hsdis-<arch>.so
+      strcpy(&buf[lib_offset], hsdis_library_name);
+      strcat(&buf[lib_offset], os::dll_file_extension());
+      _library = os::dll_load(buf, ebuf, sizeof ebuf);
+    }
+    if (_library == NULL && lib_offset > 0) {
+      // 3. <home>/jre/lib/<arch>/hsdis-<arch>.so
+      buf[lib_offset - 1] = '\0';
+      const char* p = strrchr(buf, *os::file_separator());
+      if (p != NULL) {
+        lib_offset = p - buf + 1;
+        strcpy(&buf[lib_offset], hsdis_library_name);
+        strcat(&buf[lib_offset], os::dll_file_extension());
+        _library = os::dll_load(buf, ebuf, sizeof ebuf);
+      }
+    }
+  }
+  if (_library == NULL) {
+    // 4. hsdis-<arch>.so  (using LD_LIBRARY_PATH)
+    strcpy(&buf[0], hsdis_library_name);
+    strcat(&buf[0], os::dll_file_extension());
+    _library = os::dll_load(buf, ebuf, sizeof ebuf);
+  }
+
+  // load the decoder function to use (new or old version).
+  if (_library != NULL) {
+    _decode_instructions_virtual = CAST_TO_FN_PTR(Disassembler::decode_func_virtual,
+                                          os::dll_lookup(_library, decode_instructions_virtual_name));
+  }
+  if (_decode_instructions_virtual == NULL && _library != NULL) {
+    // could not spot in new version, try old version
+    _decode_instructions = CAST_TO_FN_PTR(Disassembler::decode_func,
+                                          os::dll_lookup(_library, decode_instructions_name));
+    use_new_version = false;
+  } else {
+    use_new_version = true;
+  }
+  _tried_to_load_library = true;
+  _library_usable        = _decode_instructions_virtual != NULL || _decode_instructions != NULL;
+
+  // Create a dummy environment to initialize PrintAssemblyOptions.
+  // The PrintAssemblyOptions must be known for abstract disassemblies as well.
+  decode_env dummy((unsigned char*)(&buf[0]), (unsigned char*)(&buf[1]), st);
+
+  // Report problems during dll_load or dll_lookup, if any.
+  if (st != NULL) {
+    // Success.
+    if (_library_usable) {
+      st->print_cr("Loaded disassembler from %s", buf);
+    } else {
+      st->print_cr("Could not load %s; %s; %s",
+                   buf,
+                   ((_library != NULL)
+                    ? "entry point is missing"
+                    : ((WizardMode || PrintMiscellaneous)
+                       ? (const char*)ebuf
+                       : "library not loadable")),
+                   "PrintAssembly defaults to abstract disassembly.");
+    }
+  }
+#endif
+  return _library_usable;
+}
+
+
+// Directly disassemble code buffer.
+void Disassembler::decode(CodeBuffer* cb, address start, address end, outputStream* st) {
+#if defined(SUPPORT_ASSEMBLY) || defined(SUPPORT_ABSTRACT_ASSEMBLY)
+  //---<  Test memory before decoding  >---
+  if (!(cb->contains(start) && cb->contains(end))) {
+    //---<  Allow output suppression, but prevent writing to a NULL stream. Could happen with +PrintStubCode.  >---
+    if (st != NULL) {
+      st->print("Memory range [" PTR_FORMAT ".." PTR_FORMAT "] not contained in CodeBuffer", p2i(start), p2i(end));
+    }
     return;
   }
+  if (!os::is_readable_range(start, end)) {
+    //---<  Allow output suppression, but prevent writing to a NULL stream. Could happen with +PrintStubCode.  >---
+    if (st != NULL) {
+      st->print("Memory range [" PTR_FORMAT ".." PTR_FORMAT "] not readable", p2i(start), p2i(end));
+    }
+    return;
+  }
+
   decode_env env(cb, st);
-  env.output()->print_cr("----------------------------------------------------------------------");
+  env.output()->print_cr("--------------------------------------------------------------------------------");
+  env.output()->print("Decoding CodeBuffer (" PTR_FORMAT ")", p2i(cb));
+  if (cb->name() != NULL) {
+    env.output()->print(", name: %s,", cb->name());
+  }
+  env.output()->print_cr(" at  [" PTR_FORMAT ", " PTR_FORMAT "]  " JLONG_FORMAT " bytes", p2i(start), p2i(end), ((jlong)(end - start)));
+
+  if (is_abstract()) {
+    AbstractDisassembler::decode_abstract(start, end, env.output(), Assembler::instr_maxlen());
+  } else {
+    env.decode_instructions(start, end);
+  }
+  env.output()->print_cr("--------------------------------------------------------------------------------");
+#endif
+}
+
+// Directly disassemble code blob.
+void Disassembler::decode(CodeBlob* cb, outputStream* st, CodeStrings c) {
+#if defined(SUPPORT_ASSEMBLY) || defined(SUPPORT_ABSTRACT_ASSEMBLY)
+  if (cb->is_nmethod()) {
+    // If we  have an nmethod at hand,
+    // call the specialized decoder directly.
+    decode((nmethod*)cb, st, c);
+    return;
+  }
+
+  decode_env env(cb, st);
+  env.output()->print_cr("--------------------------------------------------------------------------------");
   if (cb->is_aot()) {
     env.output()->print("A ");
     if (cb->is_compiled()) {
@@ -648,57 +922,78 @@
       env.output()->print_cr("%s", cb->name());
     }
   } else {
-    env.output()->print_cr("%s", cb->name());
+    env.output()->print("Decoding CodeBlob");
+    if (cb->name() != NULL) {
+      env.output()->print(", name: %s,", cb->name());
+    }
   }
-  env.output()->print_cr(" at  [" PTR_FORMAT ", " PTR_FORMAT "]  " JLONG_FORMAT " bytes", p2i(cb->code_begin()), p2i(cb->code_end()), ((jlong)(cb->code_end() - cb->code_begin())) * sizeof(unsigned char*));
-  env.decode_instructions(cb->code_begin(), cb->code_end());
-}
+  env.output()->print_cr(" at  [" PTR_FORMAT ", " PTR_FORMAT "]  " JLONG_FORMAT " bytes", p2i(cb->code_begin()), p2i(cb->code_end()), ((jlong)(cb->code_end() - cb->code_begin())));
 
-void Disassembler::decode(address start, address end, outputStream* st, CodeStrings c,
-                          ptrdiff_t offset) {
-  ttyLocker ttyl;
-  if (!load_library())  return;
-  decode_env env(CodeCache::find_blob_unsafe(start), st, c, offset);
-  env.decode_instructions(start, end);
+  if (is_abstract()) {
+    AbstractDisassembler::decode_abstract(cb->code_begin(), cb->code_end(), env.output(), Assembler::instr_maxlen());
+  } else {
+    env.decode_instructions(cb->code_begin(), cb->code_end());
+  }
+  env.output()->print_cr("--------------------------------------------------------------------------------");
+#endif
 }
 
-void Disassembler::decode(nmethod* nm, outputStream* st) {
+// Decode a nmethod.
+// This includes printing the constant pool and all code segments.
+// The nmethod data structures (oop maps, relocations and the like) are not printed.
+void Disassembler::decode(nmethod* nm, outputStream* st, CodeStrings c) {
+#if defined(SUPPORT_ASSEMBLY) || defined(SUPPORT_ABSTRACT_ASSEMBLY)
   ttyLocker ttyl;
-  if (!load_library())  return;
+
   decode_env env(nm, st);
-  env.output()->print_cr("----------------------------------------------------------------------");
-
-  unsigned char* p   = nm->code_begin();
-  unsigned char* end = nm->code_end();
+  env.output()->print_cr("--------------------------------------------------------------------------------");
+  nm->print_constant_pool(env.output());
+  env.output()->print_cr("--------------------------------------------------------------------------------");
+  env.output()->cr();
+  if (is_abstract()) {
+    AbstractDisassembler::decode_abstract(nm->code_begin(), nm->code_end(), env.output(), Assembler::instr_maxlen());
+  } else {
+    env.decode_instructions(nm->code_begin(), nm->code_end());
+  }
+  env.output()->print_cr("--------------------------------------------------------------------------------");
+#endif
+}
 
-  nm->method()->method_holder()->name()->print_symbol_on(env.output());
-  env.output()->print(".");
-  nm->method()->name()->print_symbol_on(env.output());
-  nm->method()->signature()->print_symbol_on(env.output());
-#if INCLUDE_JVMCI
+// Decode a range, given as [start address, end address)
+void Disassembler::decode(address start, address end, outputStream* st, CodeStrings c /*, ptrdiff_t offset */) {
+#if defined(SUPPORT_ASSEMBLY) || defined(SUPPORT_ABSTRACT_ASSEMBLY)
+  //---<  Test memory before decoding  >---
+  if (!os::is_readable_range(start, end)) {
+    //---<  Allow output suppression, but prevent writing to a NULL stream. Could happen with +PrintStubCode.  >---
+    if (st != NULL) {
+      st->print("Memory range [" PTR_FORMAT ".." PTR_FORMAT "] not readable", p2i(start), p2i(end));
+    }
+    return;
+  }
+
+  if (is_abstract()) {
+    AbstractDisassembler::decode_abstract(start, end, st, Assembler::instr_maxlen());
+    return;
+  }
+
+// Don't do that fancy stuff. If we just have two addresses, live with it
+// and treat the memory contents as "amorphic" piece of code.
+#if 0
+  CodeBlob* cb = CodeCache::find_blob_unsafe(start);
+  if (cb != NULL) {
+    // If we  have an CodeBlob at hand,
+    // call the specialized decoder directly.
+    decode(cb, st, c);
+  } else
+#endif
   {
-    const char* jvmciName = nm->jvmci_name();
-    if (jvmciName != NULL) {
-      env.output()->print(" (%s)", jvmciName);
-    }
+    // This seems to be just a chunk of memory.
+    decode_env env(start, end, st);
+    env.output()->print_cr("--------------------------------------------------------------------------------");
+    env.decode_instructions(start, end);
+    env.output()->print_cr("--------------------------------------------------------------------------------");
   }
 #endif
-  env.output()->print_cr("  [" PTR_FORMAT ", " PTR_FORMAT "]  " JLONG_FORMAT " bytes", p2i(p), p2i(end), ((jlong)(end - p)));
-
-  // Print constant table.
-  if (nm->consts_size() > 0) {
-    nm->print_nmethod_labels(env.output(), nm->consts_begin());
-    int offset = 0;
-    for (address p = nm->consts_begin(); p < nm->consts_end(); p += 4, offset += 4) {
-      if ((offset % 8) == 0) {
-        env.output()->print_cr("  " PTR_FORMAT " (offset: %4d): " PTR32_FORMAT "   " PTR64_FORMAT, p2i(p), offset, *((int32_t*) p), *((int64_t*) p));
-      } else {
-        env.output()->print_cr("  " PTR_FORMAT " (offset: %4d): " PTR32_FORMAT,                    p2i(p), offset, *((int32_t*) p));
-      }
-    }
-  }
-
-  env.decode_instructions(p, end);
 }
 
 // To prevent excessive code expansion in the interpreter generator, we
--- a/src/hotspot/share/compiler/disassembler.hpp	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/share/compiler/disassembler.hpp	Thu May 23 11:07:37 2019 +0100
@@ -25,7 +25,11 @@
 #ifndef SHARE_COMPILER_DISASSEMBLER_HPP
 #define SHARE_COMPILER_DISASSEMBLER_HPP
 
+#include "utilities/globalDefinitions.hpp"
+
+#include "asm/assembler.hpp"
 #include "asm/codeBuffer.hpp"
+#include "compiler/abstractDisassembler.hpp"
 #include "runtime/globals.hpp"
 #include "utilities/macros.hpp"
 
@@ -34,7 +38,8 @@
 // The disassembler prints out assembly code annotated
 // with Java specific information.
 
-class Disassembler {
+// Disassembler inherits from AbstractDisassembler
+class Disassembler : public AbstractDisassembler {
   friend class decode_env;
  private:
   // this is the type of the dll entry point:
@@ -57,26 +62,58 @@
   static void*    _library;
   // bailout
   static bool     _tried_to_load_library;
+  static bool     _library_usable;
   // points to the decode function.
   static decode_func_virtual _decode_instructions_virtual;
   static decode_func _decode_instructions;
-  // tries to load library and return whether it succedded.
-  static bool load_library();
+
+  // tries to load library and return whether it succeeded.
+  // Allow (diagnostic) output redirection.
+  // No output at all if stream is NULL. Can be overridden
+  // with -Verbose flag, in which case output goes to tty.
+  static bool load_library(outputStream* st = NULL);
+
+  // Check if the two addresses are on the same page.
+  static bool is_same_page(address a1, address a2) {
+    return (((uintptr_t)a1 ^ (uintptr_t)a2) & (~0x0fffUL)) == 0L;
+  }
 
   // Machine dependent stuff
 #include CPU_HEADER(disassembler)
 
  public:
-  static bool can_decode() {
-    ttyLocker tl;
-    return (_decode_instructions_virtual != NULL) ||
-           (_decode_instructions != NULL) ||
-           load_library();
+  // We can always decode code blobs.
+  // Either we have a disassembler library available (successfully loaded)
+  // or we will resort to the abstract disassembler. This method informs
+  // about which decoding format is used.
+  // We can also enforce using the abstract disassembler.
+  static bool is_abstract() {
+    if (!_tried_to_load_library /* && !UseAbstractDisassembler */) {
+      load_library();
+    }
+    return ! _library_usable /* || UseAbstractDisassembler */;  // Not available until DecodeErrorFile is supported.
   }
-  static void decode(CodeBlob *cb,               outputStream* st = NULL);
-  static void decode(nmethod* nm,                outputStream* st = NULL);
-  static void decode(address begin, address end, outputStream* st = NULL,
-                     CodeStrings c = CodeStrings(), ptrdiff_t offset = 0);
+
+  // Check out if we are doing a live disassembly or a post-mortem
+  // disassembly where the binary data was loaded from a hs_err file.
+  static bool is_decode_error_file() {
+// Activate once post-mortem disassembly (from hs-err file) is available.
+#if 0
+    return DecodeErrorFile && (strlen(DecodeErrorFile) != 0);
+#else
+    return false;
+#endif
+  }
+
+  // Directly disassemble code buffer.
+  static void decode(CodeBuffer* cb, address start, address end, outputStream* st = NULL);
+  // Directly disassemble code blob.
+  static void decode(CodeBlob *cb,               outputStream* st = NULL, CodeStrings c = CodeStrings());
+  // Directly disassemble nmethod.
+  static void decode(nmethod* nm,                outputStream* st = NULL, CodeStrings c = CodeStrings());
+  // Disassemble an arbitrary memory range.
+  static void decode(address start, address end, outputStream* st = NULL, CodeStrings c = CodeStrings() /* , ptrdiff_t offset */);
+
   static void _hook(const char* file, int line, class MacroAssembler* masm);
 
   // This functions makes it easy to generate comments in the generated
--- a/src/hotspot/share/compiler/oopMap.cpp	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/share/compiler/oopMap.cpp	Thu May 23 11:07:37 2019 +0100
@@ -511,7 +511,7 @@
 
 void ImmutableOopMap::print_on(outputStream* st) const {
   OopMapValue omv;
-  st->print("ImmutableOopMap{");
+  st->print("ImmutableOopMap {");
   for(OopMapStream oms(this); !oms.is_done(); oms.next()) {
     omv = oms.current();
     omv.print_on(st);
@@ -523,44 +523,51 @@
 
 void OopMap::print_on(outputStream* st) const {
   OopMapValue omv;
-  st->print("OopMap{");
+  st->print("OopMap {");
   for(OopMapStream oms((OopMap*)this); !oms.is_done(); oms.next()) {
     omv = oms.current();
     omv.print_on(st);
   }
-  st->print("off=%d}", (int) offset());
+  // Print hex offset in addition.
+  st->print("off=%d/0x%x}", (int) offset(), (int) offset());
 }
 
 void OopMap::print() const { print_on(tty); }
 
 void ImmutableOopMapSet::print_on(outputStream* st) const {
   const ImmutableOopMap* last = NULL;
-  for (int i = 0; i < _count; ++i) {
+  const int len = count();
+
+  st->print_cr("ImmutableOopMapSet contains %d OopMaps", len);
+
+  for (int i = 0; i < len; i++) {
     const ImmutableOopMapPair* pair = pair_at(i);
     const ImmutableOopMap* map = pair->get_from(this);
     if (map != last) {
       st->cr();
       map->print_on(st);
-      st->print("pc offsets: ");
+      st->print(" pc offsets: ");
     }
     last = map;
     st->print("%d ", pair->pc_offset());
   }
+  st->cr();
 }
 
 void ImmutableOopMapSet::print() const { print_on(tty); }
 
 void OopMapSet::print_on(outputStream* st) const {
-  int i, len = om_count();
+  const int len = om_count();
 
-  st->print_cr("OopMapSet contains %d OopMaps\n",len);
+  st->print_cr("OopMapSet contains %d OopMaps", len);
 
-  for( i = 0; i < len; i++) {
+  for( int i = 0; i < len; i++) {
     OopMap* m = at(i);
     st->print_cr("#%d ",i);
     m->print_on(st);
     st->cr();
   }
+  st->cr();
 }
 
 void OopMapSet::print() const { print_on(tty); }
@@ -580,15 +587,17 @@
 
 const ImmutableOopMap* ImmutableOopMapSet::find_map_at_offset(int pc_offset) const {
   ImmutableOopMapPair* pairs = get_pairs();
+  ImmutableOopMapPair* last  = NULL;
 
-  int i;
-  for (i = 0; i < _count; ++i) {
+  for (int i = 0; i < _count; ++i) {
     if (pairs[i].pc_offset() >= pc_offset) {
+      last = &pairs[i];
       break;
     }
   }
-  ImmutableOopMapPair* last = &pairs[i];
 
+  // Heal Coverity issue: potential index out of bounds access.
+  guarantee(last != NULL, "last may not be null");
   assert(last->pc_offset() == pc_offset, "oopmap not found");
   return last->get_from(this);
 }
--- a/src/hotspot/share/gc/cms/cmsArguments.cpp	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/share/gc/cms/cmsArguments.cpp	Thu May 23 11:07:37 2019 +0100
@@ -106,7 +106,7 @@
   }
 
   if (!ClassUnloading) {
-    FLAG_SET_CMDLINE(bool, CMSClassUnloadingEnabled, false);
+    FLAG_SET_CMDLINE(CMSClassUnloadingEnabled, false);
   }
 
   // Set CMS global values
@@ -142,9 +142,9 @@
     // NewSize was set on the command line and it is larger than
     // preferred_max_new_size.
     if (!FLAG_IS_DEFAULT(NewSize)) {   // NewSize explicitly set at command-line
-      FLAG_SET_ERGO(size_t, MaxNewSize, MAX2(NewSize, preferred_max_new_size));
+      FLAG_SET_ERGO(MaxNewSize, MAX2(NewSize, preferred_max_new_size));
     } else {
-      FLAG_SET_ERGO(size_t, MaxNewSize, preferred_max_new_size);
+      FLAG_SET_ERGO(MaxNewSize, preferred_max_new_size);
     }
     log_trace(gc, heap)("CMS ergo set MaxNewSize: " SIZE_FORMAT, MaxNewSize);
 
@@ -159,15 +159,15 @@
       // Unless explicitly requested otherwise, make young gen
       // at least min_new, and at most preferred_max_new_size.
       if (FLAG_IS_DEFAULT(NewSize)) {
-        FLAG_SET_ERGO(size_t, NewSize, MAX2(NewSize, min_new));
-        FLAG_SET_ERGO(size_t, NewSize, MIN2(preferred_max_new_size, NewSize));
+        FLAG_SET_ERGO(NewSize, MAX2(NewSize, min_new));
+        FLAG_SET_ERGO(NewSize, MIN2(preferred_max_new_size, NewSize));
         log_trace(gc, heap)("CMS ergo set NewSize: " SIZE_FORMAT, NewSize);
       }
       // Unless explicitly requested otherwise, size old gen
       // so it's NewRatio x of NewSize.
       if (FLAG_IS_DEFAULT(OldSize)) {
         if (max_heap > NewSize) {
-          FLAG_SET_ERGO(size_t, OldSize, MIN2(NewRatio*NewSize, max_heap - NewSize));
+          FLAG_SET_ERGO(OldSize, MIN2(NewRatio*NewSize, max_heap - NewSize));
           log_trace(gc, heap)("CMS ergo set OldSize: " SIZE_FORMAT, OldSize);
         }
       }
@@ -177,14 +177,14 @@
   // promote all objects surviving "tenuring_default" scavenges.
   if (FLAG_IS_DEFAULT(MaxTenuringThreshold) &&
       FLAG_IS_DEFAULT(SurvivorRatio)) {
-    FLAG_SET_ERGO(uintx, MaxTenuringThreshold, tenuring_default);
+    FLAG_SET_ERGO(MaxTenuringThreshold, tenuring_default);
   }
   // If we decided above (or user explicitly requested)
   // `promote all' (via MaxTenuringThreshold := 0),
   // prefer minuscule survivor spaces so as not to waste
   // space for (non-existent) survivors
   if (FLAG_IS_DEFAULT(SurvivorRatio) && MaxTenuringThreshold == 0) {
-    FLAG_SET_ERGO(uintx, SurvivorRatio, MAX2((uintx)1024, SurvivorRatio));
+    FLAG_SET_ERGO(SurvivorRatio, MAX2((uintx)1024, SurvivorRatio));
   }
 
   // OldPLABSize is interpreted in CMS as not the size of the PLAB in words,
@@ -195,7 +195,7 @@
       // OldPLAB sizing manually turned off: Use a larger default setting,
       // unless it was manually specified. This is because a too-low value
       // will slow down scavenges.
-      FLAG_SET_ERGO(size_t, OldPLABSize, CompactibleFreeListSpaceLAB::_default_static_old_plab_size); // default value before 6631166
+      FLAG_SET_ERGO(OldPLABSize, CompactibleFreeListSpaceLAB::_default_static_old_plab_size); // default value before 6631166
     } else {
       FLAG_SET_DEFAULT(OldPLABSize, CompactibleFreeListSpaceLAB::_default_dynamic_old_plab_size); // old CMSParPromoteBlocksToClaim default
     }
--- a/src/hotspot/share/gc/epsilon/epsilonHeap.hpp	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/share/gc/epsilon/epsilonHeap.hpp	Thu May 23 11:07:37 2019 +0100
@@ -29,7 +29,6 @@
 #include "gc/shared/space.hpp"
 #include "gc/epsilon/epsilonMonitoringSupport.hpp"
 #include "gc/epsilon/epsilonBarrierSet.hpp"
-#include "gc/epsilon/epsilon_globals.hpp"
 #include "services/memoryManager.hpp"
 
 class EpsilonHeap : public CollectedHeap {
--- a/src/hotspot/share/gc/epsilon/epsilon_globals.hpp	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/share/gc/epsilon/epsilon_globals.hpp	Thu May 23 11:07:37 2019 +0100
@@ -25,7 +25,8 @@
 #ifndef SHARE_GC_EPSILON_EPSILON_GLOBALS_HPP
 #define SHARE_GC_EPSILON_EPSILON_GLOBALS_HPP
 
-#include "runtime/globals.hpp"
+#include "runtime/globals_shared.hpp"
+
 //
 // Defines all globals flags used by the Epsilon GC.
 //
--- a/src/hotspot/share/gc/g1/g1Arguments.cpp	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/share/gc/g1/g1Arguments.cpp	Thu May 23 11:07:37 2019 +0100
@@ -110,11 +110,11 @@
   // triggering a full collection. To get as low fragmentation as
   // possible we only use one worker thread.
   if (DumpSharedSpaces) {
-    FLAG_SET_ERGO(uint, ParallelGCThreads, 1);
+    FLAG_SET_ERGO(ParallelGCThreads, 1);
   }
 
   if (FLAG_IS_DEFAULT(G1ConcRefinementThreads)) {
-    FLAG_SET_ERGO(uint, G1ConcRefinementThreads, ParallelGCThreads);
+    FLAG_SET_ERGO(G1ConcRefinementThreads, ParallelGCThreads);
   }
 
   // MarkStackSize will be set (if it hasn't been set by the user)
@@ -162,7 +162,7 @@
 
   // By default do not let the target stack size to be more than 1/4 of the entries
   if (FLAG_IS_DEFAULT(GCDrainStackTargetSize)) {
-    FLAG_SET_ERGO(uintx, GCDrainStackTargetSize, MIN2(GCDrainStackTargetSize, (uintx)TASKQUEUE_SIZE / 4));
+    FLAG_SET_ERGO(GCDrainStackTargetSize, MIN2(GCDrainStackTargetSize, (uintx)TASKQUEUE_SIZE / 4));
   }
 
 #ifdef COMPILER2
--- a/src/hotspot/share/gc/g1/g1CollectedHeap.hpp	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/share/gc/g1/g1CollectedHeap.hpp	Thu May 23 11:07:37 2019 +0100
@@ -1111,7 +1111,7 @@
 
  public:
 
-  inline G1HeapRegionAttr region_attr(const oop obj);
+  inline G1HeapRegionAttr region_attr(const void* obj);
 
   // Return "TRUE" iff the given object address is in the reserved
   // region of g1.
--- a/src/hotspot/share/gc/g1/g1CollectedHeap.inline.hpp	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/share/gc/g1/g1CollectedHeap.inline.hpp	Thu May 23 11:07:37 2019 +0100
@@ -29,6 +29,7 @@
 #include "gc/g1/g1CollectedHeap.hpp"
 #include "gc/g1/g1CollectorState.hpp"
 #include "gc/g1/g1Policy.hpp"
+#include "gc/g1/g1RemSet.hpp"
 #include "gc/g1/heapRegionManager.inline.hpp"
 #include "gc/g1/heapRegionRemSet.hpp"
 #include "gc/g1/heapRegionSet.inline.hpp"
@@ -162,8 +163,8 @@
   return _region_attr.is_in_cset_or_humongous((HeapWord*)obj);
 }
 
-G1HeapRegionAttr G1CollectedHeap::region_attr(const oop obj) {
-  return _region_attr.at((HeapWord*)obj);
+G1HeapRegionAttr G1CollectedHeap::region_attr(const void* addr) {
+  return _region_attr.at((HeapWord*)addr);
 }
 
 void G1CollectedHeap::register_humongous_region_with_region_attr(uint index) {
@@ -176,6 +177,7 @@
 
 void G1CollectedHeap::register_old_region_with_region_attr(HeapRegion* r) {
   _region_attr.set_in_old(r->hrm_index(), r->rem_set()->is_tracked());
+  _rem_set->prepare_for_scan_rem_set(r->hrm_index());
 }
 
 void G1CollectedHeap::register_optional_region_with_region_attr(HeapRegion* r) {
--- a/src/hotspot/share/gc/g1/g1ConcurrentMark.cpp	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/share/gc/g1/g1ConcurrentMark.cpp	Thu May 23 11:07:37 2019 +0100
@@ -425,7 +425,7 @@
     // Calculate the number of concurrent worker threads by scaling
     // the number of parallel GC threads.
     uint marking_thread_num = scale_concurrent_worker_threads(ParallelGCThreads);
-    FLAG_SET_ERGO(uint, ConcGCThreads, marking_thread_num);
+    FLAG_SET_ERGO(ConcGCThreads, marking_thread_num);
   }
 
   assert(ConcGCThreads > 0, "ConcGCThreads have been set.");
@@ -456,7 +456,7 @@
                       mark_stack_size, MarkStackSizeMax);
       return;
     }
-    FLAG_SET_ERGO(size_t, MarkStackSize, mark_stack_size);
+    FLAG_SET_ERGO(MarkStackSize, mark_stack_size);
   } else {
     // Verify MarkStackSize is in range.
     if (FLAG_IS_CMDLINE(MarkStackSize)) {
--- a/src/hotspot/share/gc/g1/g1DirtyCardQueue.cpp	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/share/gc/g1/g1DirtyCardQueue.cpp	Thu May 23 11:07:37 2019 +0100
@@ -66,8 +66,21 @@
   flush();
 }
 
+void G1DirtyCardQueue::handle_completed_buffer() {
+  assert(_buf != NULL, "precondition");
+  BufferNode* node = BufferNode::make_node_from_buffer(_buf, index());
+  G1DirtyCardQueueSet* dcqs = dirty_card_qset();
+  if (dcqs->process_or_enqueue_completed_buffer(node)) {
+    reset();                    // Buffer fully processed, reset index.
+  } else {
+    allocate_buffer();          // Buffer enqueued, get a new one.
+  }
+}
+
 G1DirtyCardQueueSet::G1DirtyCardQueueSet(bool notify_when_complete) :
   PtrQueueSet(notify_when_complete),
+  _max_completed_buffers(MaxCompletedBuffersUnlimited),
+  _completed_buffers_padding(0),
   _free_ids(NULL),
   _processed_buffers_mut(0),
   _processed_buffers_rs_thread(0),
@@ -136,6 +149,24 @@
   } while (0)
 #endif // ASSERT
 
+bool G1DirtyCardQueueSet::process_or_enqueue_completed_buffer(BufferNode* node) {
+  if (Thread::current()->is_Java_thread()) {
+    // If the number of buffers exceeds the limit, make this Java
+    // thread do the processing itself.  We don't lock to access
+    // buffer count or padding; it is fine to be imprecise here.  The
+    // add of padding could overflow, which is treated as unlimited.
+    size_t max_buffers = max_completed_buffers();
+    size_t limit = max_buffers + completed_buffers_padding();
+    if ((completed_buffers_num() > limit) && (limit >= max_buffers)) {
+      if (mut_process_buffer(node)) {
+        return true;
+      }
+    }
+  }
+  enqueue_completed_buffer(node);
+  return false;
+}
+
 bool G1DirtyCardQueueSet::mut_process_buffer(BufferNode* node) {
   guarantee(_free_ids != NULL, "must be");
 
--- a/src/hotspot/share/gc/g1/g1DirtyCardQueue.hpp	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/share/gc/g1/g1DirtyCardQueue.hpp	Thu May 23 11:07:37 2019 +0100
@@ -47,6 +47,9 @@
 
 // A ptrQueue whose elements are "oops", pointers to object heads.
 class G1DirtyCardQueue: public PtrQueue {
+protected:
+  virtual void handle_completed_buffer();
+
 public:
   G1DirtyCardQueue(G1DirtyCardQueueSet* qset);
 
@@ -57,6 +60,8 @@
   // Process queue entries and release resources.
   void flush() { flush_impl(); }
 
+  inline G1DirtyCardQueueSet* dirty_card_qset() const;
+
   // Compiler support.
   static ByteSize byte_offset_of_index() {
     return PtrQueue::byte_offset_of_index<G1DirtyCardQueue>();
@@ -102,6 +107,12 @@
 
   bool mut_process_buffer(BufferNode* node);
 
+  // If the queue contains more buffers than configured here, the
+  // mutator must start doing some of the concurrent refinement work,
+  size_t _max_completed_buffers;
+  size_t _completed_buffers_padding;
+  static const size_t MaxCompletedBuffersUnlimited = ~size_t(0);
+
   G1FreeIdSet* _free_ids;
 
   // The number of completed buffers processed by mutator and rs thread,
@@ -126,6 +137,11 @@
 
   static void handle_zero_index_for_thread(Thread* t);
 
+  // Either process the entire buffer and return true, or enqueue the
+  // buffer and return false.  If the buffer is completely processed,
+  // it can be reused in place.
+  bool process_or_enqueue_completed_buffer(BufferNode* node);
+
   // Apply G1RefineCardConcurrentlyClosure to completed buffers until there are stop_at
   // completed buffers remaining.
   bool refine_completed_buffer_concurrently(uint worker_i, size_t stop_at);
@@ -147,6 +163,20 @@
   // If any threads have partial logs, add them to the global list of logs.
   void concatenate_logs();
 
+  void set_max_completed_buffers(size_t m) {
+    _max_completed_buffers = m;
+  }
+  size_t max_completed_buffers() const {
+    return _max_completed_buffers;
+  }
+
+  void set_completed_buffers_padding(size_t padding) {
+    _completed_buffers_padding = padding;
+  }
+  size_t completed_buffers_padding() const {
+    return _completed_buffers_padding;
+  }
+
   jint processed_buffers_mut() {
     return _processed_buffers_mut;
   }
@@ -156,4 +186,8 @@
 
 };
 
+inline G1DirtyCardQueueSet* G1DirtyCardQueue::dirty_card_qset() const {
+  return static_cast<G1DirtyCardQueueSet*>(qset());
+}
+
 #endif // SHARE_GC_G1_G1DIRTYCARDQUEUE_HPP
--- a/src/hotspot/share/gc/g1/g1EvacFailure.cpp	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/share/gc/g1/g1EvacFailure.cpp	Thu May 23 11:07:37 2019 +0100
@@ -30,7 +30,6 @@
 #include "gc/g1/g1EvacFailure.hpp"
 #include "gc/g1/g1HeapVerifier.hpp"
 #include "gc/g1/g1OopClosures.inline.hpp"
-#include "gc/g1/g1_globals.hpp"
 #include "gc/g1/heapRegion.hpp"
 #include "gc/g1/heapRegionRemSet.hpp"
 #include "gc/shared/preservedMarks.inline.hpp"
--- a/src/hotspot/share/gc/g1/g1EvacStats.cpp	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/share/gc/g1/g1EvacStats.cpp	Thu May 23 11:07:37 2019 +0100
@@ -23,7 +23,6 @@
  */
 
 #include "precompiled.hpp"
-#include "gc/g1/g1_globals.hpp"
 #include "gc/g1/g1EvacStats.hpp"
 #include "gc/shared/gcId.hpp"
 #include "logging/log.hpp"
--- a/src/hotspot/share/gc/g1/g1HotCardCache.hpp	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/share/gc/g1/g1HotCardCache.hpp	Thu May 23 11:07:37 2019 +0100
@@ -26,7 +26,6 @@
 #define SHARE_GC_G1_G1HOTCARDCACHE_HPP
 
 #include "gc/g1/g1CardCounts.hpp"
-#include "gc/g1/g1_globals.hpp"
 #include "memory/allocation.hpp"
 #include "runtime/safepoint.hpp"
 #include "runtime/thread.hpp"
--- a/src/hotspot/share/gc/g1/g1OopClosures.hpp	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/share/gc/g1/g1OopClosures.hpp	Thu May 23 11:07:37 2019 +0100
@@ -73,9 +73,10 @@
 
 // Used during Optional RS scanning to make sure we trim the queues in a timely manner.
 class G1ScanRSForOptionalClosure : public OopClosure {
+  G1CollectedHeap* _g1h;
   G1ScanCardClosure* _scan_cl;
 public:
-  G1ScanRSForOptionalClosure(G1ScanCardClosure* cl) : _scan_cl(cl) { }
+  G1ScanRSForOptionalClosure(G1CollectedHeap* g1h, G1ScanCardClosure* cl) : _g1h(g1h), _scan_cl(cl) { }
 
   template <class T> void do_oop_work(T* p);
   virtual void do_oop(oop* p)          { do_oop_work(p); }
--- a/src/hotspot/share/gc/g1/g1OopClosures.inline.hpp	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/share/gc/g1/g1OopClosures.inline.hpp	Thu May 23 11:07:37 2019 +0100
@@ -169,11 +169,14 @@
 
   check_obj_during_refinement(p, obj);
 
-  // We can not check for references from the collection set: the remembered sets
-  // may contain such entries and we do not filter them before.
+  assert(!_g1h->is_in_cset((HeapWord*)p),
+         "Oop originates from " PTR_FORMAT " (region: %u) which is in the collection set.",
+         p2i(p), _g1h->addr_to_region((HeapWord*)p));
 
   const G1HeapRegionAttr region_attr = _g1h->region_attr(obj);
   if (region_attr.is_in_cset()) {
+    // Since the source is always from outside the collection set, here we implicitly know
+    // that this is a cross-region reference too.
     prefetch_and_push(p, obj);
   } else if (!HeapRegion::is_in_same_region(p, obj)) {
     handle_non_cset_obj_common(region_attr, p, obj);
@@ -183,6 +186,13 @@
 
 template <class T>
 inline void G1ScanRSForOptionalClosure::do_oop_work(T* p) {
+  const G1HeapRegionAttr region_attr = _g1h->region_attr(p);
+  // Entries in the optional collection set may start to originate from the collection
+  // set after one or more increments. In this case, previously optional regions
+  // became actual collection set regions. Filter them out here.
+  if (region_attr.is_in_cset()) {
+    return;
+  }
   _scan_cl->do_oop_work(p);
   _scan_cl->trim_queue_partially();
 }
--- a/src/hotspot/share/gc/g1/g1ParScanThreadState.inline.hpp	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/share/gc/g1/g1ParScanThreadState.inline.hpp	Thu May 23 11:07:37 2019 +0100
@@ -208,6 +208,8 @@
 inline void G1ParScanThreadState::remember_root_into_optional_region(T* p) {
   oop o = RawAccess<IS_NOT_NULL>::oop_load(p);
   uint index = _g1h->heap_region_containing(o)->index_in_opt_cset();
+  assert(index < _num_optional_regions,
+         "Trying to access optional region idx %u beyond " SIZE_FORMAT, index, _num_optional_regions);
   _oops_into_optional_regions[index].push_root(p);
 }
 
@@ -215,11 +217,16 @@
 inline void G1ParScanThreadState::remember_reference_into_optional_region(T* p) {
   oop o = RawAccess<IS_NOT_NULL>::oop_load(p);
   uint index = _g1h->heap_region_containing(o)->index_in_opt_cset();
+  assert(index < _num_optional_regions,
+         "Trying to access optional region idx %u beyond " SIZE_FORMAT, index, _num_optional_regions);
   _oops_into_optional_regions[index].push_oop(p);
   DEBUG_ONLY(verify_ref(p);)
 }
 
 G1OopStarChunkedList* G1ParScanThreadState::oops_into_optional_region(const HeapRegion* hr) {
+  assert(hr->index_in_opt_cset() < _num_optional_regions,
+         "Trying to access optional region idx %u beyond " SIZE_FORMAT " " HR_FORMAT,
+         hr->index_in_opt_cset(), _num_optional_regions, HR_FORMAT_PARAMS(hr));
   return &_oops_into_optional_regions[hr->index_in_opt_cset()];
 }
 
--- a/src/hotspot/share/gc/g1/g1RemSet.cpp	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/share/gc/g1/g1RemSet.cpp	Thu May 23 11:07:37 2019 +0100
@@ -188,7 +188,7 @@
   void reset() {
     for (uint i = 0; i < _max_regions; i++) {
       _iter_states[i] = Unclaimed;
-      _scan_top[i] = NULL;
+      clear_scan_top(i);
     }
 
     G1ResetScanTopClosure cl(_scan_top);
@@ -253,6 +253,10 @@
     return _scan_top[region_idx];
   }
 
+  void clear_scan_top(uint region_idx) {
+    _scan_top[region_idx] = NULL;
+  }
+
   // Clear the card table of "dirty" regions.
   void clear_card_table(WorkGang* workers) {
     if (_cur_dirty_region == 0) {
@@ -304,158 +308,198 @@
   _scan_state->initialize(max_regions);
 }
 
-G1ScanRSForRegionClosure::G1ScanRSForRegionClosure(G1RemSetScanState* scan_state,
-                                                   G1ScanCardClosure* scan_obj_on_card,
-                                                   G1ParScanThreadState* pss,
-                                                   G1GCPhaseTimes::GCParPhases phase,
-                                                   uint worker_i) :
-  _g1h(G1CollectedHeap::heap()),
-  _ct(_g1h->card_table()),
-  _pss(pss),
-  _scan_objs_on_card_cl(scan_obj_on_card),
-  _scan_state(scan_state),
-  _phase(phase),
-  _worker_i(worker_i),
-  _opt_refs_scanned(0),
-  _opt_refs_memory_used(0),
-  _cards_scanned(0),
-  _cards_claimed(0),
-  _cards_skipped(0),
-  _rem_set_root_scan_time(),
-  _rem_set_trim_partially_time(),
-  _strong_code_root_scan_time(),
-  _strong_code_trim_partially_time() {
-}
+class G1ScanRSForRegionClosure : public HeapRegionClosure {
+  G1CollectedHeap* _g1h;
+  G1CardTable *_ct;
 
-void G1ScanRSForRegionClosure::claim_card(size_t card_index, const uint region_idx_for_card){
-  _ct->set_card_claimed(card_index);
-  _scan_state->add_dirty_region(region_idx_for_card);
-}
+  G1ParScanThreadState* _pss;
+  G1ScanCardClosure* _scan_objs_on_card_cl;
+
+  G1RemSetScanState* _scan_state;
+
+  G1GCPhaseTimes::GCParPhases _phase;
+
+  uint   _worker_i;
 
-void G1ScanRSForRegionClosure::scan_card(MemRegion mr, uint region_idx_for_card) {
-  HeapRegion* const card_region = _g1h->region_at(region_idx_for_card);
-  assert(!card_region->is_young(), "Should not scan card in young region %u", region_idx_for_card);
-  card_region->oops_on_card_seq_iterate_careful<true>(mr, _scan_objs_on_card_cl);
-  _scan_objs_on_card_cl->trim_queue_partially();
-  _cards_scanned++;
-}
+  size_t _opt_refs_scanned;
+  size_t _opt_refs_memory_used;
 
-void G1ScanRSForRegionClosure::scan_opt_rem_set_roots(HeapRegion* r) {
-  EventGCPhaseParallel event;
-
-  G1OopStarChunkedList* opt_rem_set_list = _pss->oops_into_optional_region(r);
+  size_t _cards_scanned;
+  size_t _cards_claimed;
+  size_t _cards_skipped;
 
-  G1ScanCardClosure scan_cl(_g1h, _pss);
-  G1ScanRSForOptionalClosure cl(&scan_cl);
-  _opt_refs_scanned += opt_rem_set_list->oops_do(&cl, _pss->closures()->raw_strong_oops());
-  _opt_refs_memory_used += opt_rem_set_list->used_memory();
-
-  event.commit(GCId::current(), _worker_i, G1GCPhaseTimes::phase_name(_phase));
-}
+  Tickspan _rem_set_root_scan_time;
+  Tickspan _rem_set_trim_partially_time;
 
-void G1ScanRSForRegionClosure::scan_rem_set_roots(HeapRegion* r) {
-  EventGCPhaseParallel event;
-  uint const region_idx = r->hrm_index();
+  Tickspan _strong_code_root_scan_time;
+  Tickspan _strong_code_trim_partially_time;
 
-  if (_scan_state->claim_iter(region_idx)) {
-    // If we ever free the collection set concurrently, we should also
-    // clear the card table concurrently therefore we won't need to
-    // add regions of the collection set to the dirty cards region.
-    _scan_state->add_dirty_region(region_idx);
+  void claim_card(size_t card_index, const uint region_idx_for_card) {
+    _ct->set_card_claimed(card_index);
+    _scan_state->add_dirty_region(region_idx_for_card);
   }
 
-  if (r->rem_set()->cardset_is_empty()) {
-    return;
+  void scan_card(MemRegion mr, uint region_idx_for_card) {
+    HeapRegion* const card_region = _g1h->region_at(region_idx_for_card);
+    assert(!card_region->is_young(), "Should not scan card in young region %u", region_idx_for_card);
+    card_region->oops_on_card_seq_iterate_careful<true>(mr, _scan_objs_on_card_cl);
+    _scan_objs_on_card_cl->trim_queue_partially();
+    _cards_scanned++;
+  }
+
+  void scan_opt_rem_set_roots(HeapRegion* r) {
+    EventGCPhaseParallel event;
+
+    G1OopStarChunkedList* opt_rem_set_list = _pss->oops_into_optional_region(r);
+
+    G1ScanCardClosure scan_cl(_g1h, _pss);
+    G1ScanRSForOptionalClosure cl(_g1h, &scan_cl);
+    _opt_refs_scanned += opt_rem_set_list->oops_do(&cl, _pss->closures()->raw_strong_oops());
+    _opt_refs_memory_used += opt_rem_set_list->used_memory();
+
+    event.commit(GCId::current(), _worker_i, G1GCPhaseTimes::phase_name(_phase));
   }
 
-  // We claim cards in blocks so as to reduce the contention.
-  size_t const block_size = G1RSetScanBlockSize;
-
-  HeapRegionRemSetIterator iter(r->rem_set());
-  size_t card_index;
+  void scan_rem_set_roots(HeapRegion* r) {
+    EventGCPhaseParallel event;
+    uint const region_idx = r->hrm_index();
 
-  size_t claimed_card_block = _scan_state->iter_claimed_next(region_idx, block_size);
-  for (size_t current_card = 0; iter.has_next(card_index); current_card++) {
-    if (current_card >= claimed_card_block + block_size) {
-      claimed_card_block = _scan_state->iter_claimed_next(region_idx, block_size);
-    }
-    if (current_card < claimed_card_block) {
-      _cards_skipped++;
-      continue;
-    }
-    _cards_claimed++;
-
-    HeapWord* const card_start = _g1h->bot()->address_for_index_raw(card_index);
-    uint const region_idx_for_card = _g1h->addr_to_region(card_start);
-
-#ifdef ASSERT
-    HeapRegion* hr = _g1h->region_at_or_null(region_idx_for_card);
-    assert(hr == NULL || hr->is_in_reserved(card_start),
-           "Card start " PTR_FORMAT " to scan outside of region %u", p2i(card_start), _g1h->region_at(region_idx_for_card)->hrm_index());
-#endif
-    HeapWord* const top = _scan_state->scan_top(region_idx_for_card);
-    if (card_start >= top) {
-      continue;
+    if (_scan_state->claim_iter(region_idx)) {
+      // If we ever free the collection set concurrently, we should also
+      // clear the card table concurrently therefore we won't need to
+      // add regions of the collection set to the dirty cards region.
+      _scan_state->add_dirty_region(region_idx);
     }
 
-    // If the card is dirty, then G1 will scan it during Update RS.
-    if (_ct->is_card_claimed(card_index) || _ct->is_card_dirty(card_index)) {
-      continue;
+    if (r->rem_set()->cardset_is_empty()) {
+      return;
     }
 
-    // We claim lazily (so races are possible but they're benign), which reduces the
-    // number of duplicate scans (the rsets of the regions in the cset can intersect).
-    // Claim the card after checking bounds above: the remembered set may contain
-    // random cards into current survivor, and we would then have an incorrectly
-    // claimed card in survivor space. Card table clear does not reset the card table
-    // of survivor space regions.
-    claim_card(card_index, region_idx_for_card);
+    // We claim cards in blocks so as to reduce the contention.
+    size_t const block_size = G1RSetScanBlockSize;
+
+    HeapRegionRemSetIterator iter(r->rem_set());
+    size_t card_index;
 
-    MemRegion const mr(card_start, MIN2(card_start + BOTConstants::N_words, top));
+    size_t claimed_card_block = _scan_state->iter_claimed_next(region_idx, block_size);
+    for (size_t current_card = 0; iter.has_next(card_index); current_card++) {
+      if (current_card >= claimed_card_block + block_size) {
+        claimed_card_block = _scan_state->iter_claimed_next(region_idx, block_size);
+      }
+      if (current_card < claimed_card_block) {
+        _cards_skipped++;
+        continue;
+      }
+      _cards_claimed++;
 
-    scan_card(mr, region_idx_for_card);
-  }
-  event.commit(GCId::current(), _worker_i, G1GCPhaseTimes::phase_name(_phase));
-}
+      HeapWord* const card_start = _g1h->bot()->address_for_index_raw(card_index);
+      uint const region_idx_for_card = _g1h->addr_to_region(card_start);
 
-void G1ScanRSForRegionClosure::scan_strong_code_roots(HeapRegion* r) {
-  EventGCPhaseParallel event;
-  // We pass a weak code blobs closure to the remembered set scanning because we want to avoid
-  // treating the nmethods visited to act as roots for concurrent marking.
-  // We only want to make sure that the oops in the nmethods are adjusted with regard to the
-  // objects copied by the current evacuation.
-  r->strong_code_roots_do(_pss->closures()->weak_codeblobs());
-  event.commit(GCId::current(), _worker_i, G1GCPhaseTimes::phase_name(G1GCPhaseTimes::CodeRoots));
-}
+#ifdef ASSERT
+      HeapRegion* hr = _g1h->region_at_or_null(region_idx_for_card);
+      assert(hr == NULL || hr->is_in_reserved(card_start),
+             "Card start " PTR_FORMAT " to scan outside of region %u", p2i(card_start), _g1h->region_at(region_idx_for_card)->hrm_index());
+#endif
+      HeapWord* const top = _scan_state->scan_top(region_idx_for_card);
+      if (card_start >= top) {
+        continue;
+      }
 
-bool G1ScanRSForRegionClosure::do_heap_region(HeapRegion* r) {
-  assert(r->in_collection_set(), "Region %u is not in the collection set.", r->hrm_index());
-  uint const region_idx = r->hrm_index();
+      // If the card is dirty, then G1 will scan it during Update RS.
+      if (_ct->is_card_claimed(card_index) || _ct->is_card_dirty(card_index)) {
+        continue;
+      }
 
-  // The individual references for the optional remembered set are per-worker, so we
-  // always need to scan them.
-  if (r->has_index_in_opt_cset()) {
-    G1EvacPhaseWithTrimTimeTracker timer(_pss, _rem_set_root_scan_time, _rem_set_trim_partially_time);
-    scan_opt_rem_set_roots(r);
+      // We claim lazily (so races are possible but they're benign), which reduces the
+      // number of duplicate scans (the rsets of the regions in the cset can intersect).
+      // Claim the card after checking bounds above: the remembered set may contain
+      // random cards into current survivor, and we would then have an incorrectly
+      // claimed card in survivor space. Card table clear does not reset the card table
+      // of survivor space regions.
+      claim_card(card_index, region_idx_for_card);
+
+      MemRegion const mr(card_start, MIN2(card_start + BOTConstants::N_words, top));
+
+      scan_card(mr, region_idx_for_card);
+    }
+    event.commit(GCId::current(), _worker_i, G1GCPhaseTimes::phase_name(_phase));
   }
 
-  // Do an early out if we know we are complete.
-  if (_scan_state->iter_is_complete(region_idx)) {
+  void scan_strong_code_roots(HeapRegion* r) {
+    EventGCPhaseParallel event;
+    // We pass a weak code blobs closure to the remembered set scanning because we want to avoid
+    // treating the nmethods visited to act as roots for concurrent marking.
+    // We only want to make sure that the oops in the nmethods are adjusted with regard to the
+    // objects copied by the current evacuation.
+    r->strong_code_roots_do(_pss->closures()->weak_codeblobs());
+    event.commit(GCId::current(), _worker_i, G1GCPhaseTimes::phase_name(G1GCPhaseTimes::CodeRoots));
+  }
+
+public:
+  G1ScanRSForRegionClosure(G1RemSetScanState* scan_state,
+                           G1ScanCardClosure* scan_obj_on_card,
+                           G1ParScanThreadState* pss,
+                           G1GCPhaseTimes::GCParPhases phase,
+                           uint worker_i) :
+    _g1h(G1CollectedHeap::heap()),
+    _ct(_g1h->card_table()),
+    _pss(pss),
+    _scan_objs_on_card_cl(scan_obj_on_card),
+    _scan_state(scan_state),
+    _phase(phase),
+    _worker_i(worker_i),
+    _opt_refs_scanned(0),
+    _opt_refs_memory_used(0),
+    _cards_scanned(0),
+    _cards_claimed(0),
+    _cards_skipped(0),
+    _rem_set_root_scan_time(),
+    _rem_set_trim_partially_time(),
+    _strong_code_root_scan_time(),
+    _strong_code_trim_partially_time() { }
+
+  bool do_heap_region(HeapRegion* r) {
+    assert(r->in_collection_set(), "Region %u is not in the collection set.", r->hrm_index());
+    uint const region_idx = r->hrm_index();
+
+    // The individual references for the optional remembered set are per-worker, so we
+    // always need to scan them.
+    if (r->has_index_in_opt_cset()) {
+      G1EvacPhaseWithTrimTimeTracker timer(_pss, _rem_set_root_scan_time, _rem_set_trim_partially_time);
+      scan_opt_rem_set_roots(r);
+    }
+
+    // Do an early out if we know we are complete.
+    if (_scan_state->iter_is_complete(region_idx)) {
+      return false;
+    }
+
+    {
+      G1EvacPhaseWithTrimTimeTracker timer(_pss, _rem_set_root_scan_time, _rem_set_trim_partially_time);
+      scan_rem_set_roots(r);
+    }
+
+    if (_scan_state->set_iter_complete(region_idx)) {
+      G1EvacPhaseWithTrimTimeTracker timer(_pss, _strong_code_root_scan_time, _strong_code_trim_partially_time);
+      // Scan the strong code root list attached to the current region
+      scan_strong_code_roots(r);
+    }
     return false;
   }
 
-  {
-    G1EvacPhaseWithTrimTimeTracker timer(_pss, _rem_set_root_scan_time, _rem_set_trim_partially_time);
-    scan_rem_set_roots(r);
-  }
+  Tickspan rem_set_root_scan_time() const { return _rem_set_root_scan_time; }
+  Tickspan rem_set_trim_partially_time() const { return _rem_set_trim_partially_time; }
+
+  Tickspan strong_code_root_scan_time() const { return _strong_code_root_scan_time;  }
+  Tickspan strong_code_root_trim_partially_time() const { return _strong_code_trim_partially_time; }
 
-  if (_scan_state->set_iter_complete(region_idx)) {
-    G1EvacPhaseWithTrimTimeTracker timer(_pss, _strong_code_root_scan_time, _strong_code_trim_partially_time);
-    // Scan the strong code root list attached to the current region
-    scan_strong_code_roots(r);
-  }
-  return false;
-}
+  size_t cards_scanned() const { return _cards_scanned; }
+  size_t cards_claimed() const { return _cards_claimed; }
+  size_t cards_skipped() const { return _cards_skipped; }
+
+  size_t opt_refs_scanned() const { return _opt_refs_scanned; }
+  size_t opt_refs_memory_used() const { return _opt_refs_memory_used; }
+};
 
 void G1RemSet::scan_rem_set(G1ParScanThreadState* pss,
                             uint worker_i,
@@ -550,6 +594,10 @@
   _scan_state->reset();
 }
 
+void G1RemSet::prepare_for_scan_rem_set(uint region_idx) {
+  _scan_state->clear_scan_top(region_idx);
+}
+
 void G1RemSet::cleanup_after_scan_rem_set() {
   G1GCPhaseTimes* phase_times = _g1h->phase_times();
 
--- a/src/hotspot/share/gc/g1/g1RemSet.hpp	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/share/gc/g1/g1RemSet.hpp	Thu May 23 11:07:37 2019 +0100
@@ -98,10 +98,12 @@
   // into the collection set or update the remembered set.
   void update_rem_set(G1ParScanThreadState* pss, uint worker_i);
 
-  // Prepare for and cleanup after scanning the remembered sets.  Must be called
+  // Prepare for and cleanup after scanning the remembered sets. Must be called
   // once before and after in sequential code.
   void prepare_for_scan_rem_set();
   void cleanup_after_scan_rem_set();
+  // Prepares the given region for remembered set scanning.
+  void prepare_for_scan_rem_set(uint region_idx);
 
   G1RemSetScanState* scan_state() const { return _scan_state; }
 
@@ -128,59 +130,4 @@
   void rebuild_rem_set(G1ConcurrentMark* cm, WorkGang* workers, uint worker_id_offset);
 };
 
-class G1ScanRSForRegionClosure : public HeapRegionClosure {
-  G1CollectedHeap* _g1h;
-  G1CardTable *_ct;
-
-  G1ParScanThreadState* _pss;
-  G1ScanCardClosure* _scan_objs_on_card_cl;
-
-  G1RemSetScanState* _scan_state;
-
-  G1GCPhaseTimes::GCParPhases _phase;
-
-  uint   _worker_i;
-
-  size_t _opt_refs_scanned;
-  size_t _opt_refs_memory_used;
-
-  size_t _cards_scanned;
-  size_t _cards_claimed;
-  size_t _cards_skipped;
-
-  Tickspan _rem_set_root_scan_time;
-  Tickspan _rem_set_trim_partially_time;
-
-  Tickspan _strong_code_root_scan_time;
-  Tickspan _strong_code_trim_partially_time;
-
-  void claim_card(size_t card_index, const uint region_idx_for_card);
-  void scan_card(MemRegion mr, uint region_idx_for_card);
-
-  void scan_opt_rem_set_roots(HeapRegion* r);
-  void scan_rem_set_roots(HeapRegion* r);
-  void scan_strong_code_roots(HeapRegion* r);
-public:
-  G1ScanRSForRegionClosure(G1RemSetScanState* scan_state,
-                           G1ScanCardClosure* scan_obj_on_card,
-                           G1ParScanThreadState* pss,
-                           G1GCPhaseTimes::GCParPhases phase,
-                           uint worker_i);
-
-  bool do_heap_region(HeapRegion* r);
-
-  Tickspan rem_set_root_scan_time() const { return _rem_set_root_scan_time; }
-  Tickspan rem_set_trim_partially_time() const { return _rem_set_trim_partially_time; }
-
-  Tickspan strong_code_root_scan_time() const { return _strong_code_root_scan_time;  }
-  Tickspan strong_code_root_trim_partially_time() const { return _strong_code_trim_partially_time; }
-
-  size_t cards_scanned() const { return _cards_scanned; }
-  size_t cards_claimed() const { return _cards_claimed; }
-  size_t cards_skipped() const { return _cards_skipped; }
-
-  size_t opt_refs_scanned() const { return _opt_refs_scanned; }
-  size_t opt_refs_memory_used() const { return _opt_refs_memory_used; }
-};
-
 #endif // SHARE_GC_G1_G1REMSET_HPP
--- a/src/hotspot/share/gc/g1/g1YoungGenSizer.cpp	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/share/gc/g1/g1YoungGenSizer.cpp	Thu May 23 11:07:37 2019 +0100
@@ -48,7 +48,7 @@
                             "A new max generation size of " SIZE_FORMAT "k will be used.",
                             NewSize/K, MaxNewSize/K, NewSize/K);
     }
-    FLAG_SET_ERGO(size_t, MaxNewSize, NewSize);
+    FLAG_SET_ERGO(MaxNewSize, NewSize);
   }
 
   if (FLAG_IS_CMDLINE(NewSize)) {
@@ -121,7 +121,7 @@
 
   size_t max_young_size = result * HeapRegion::GrainBytes;
   if (max_young_size != MaxNewSize) {
-    FLAG_SET_ERGO(size_t, MaxNewSize, max_young_size);
+    FLAG_SET_ERGO(MaxNewSize, max_young_size);
   }
 }
 
--- a/src/hotspot/share/gc/g1/g1_globals.hpp	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/share/gc/g1/g1_globals.hpp	Thu May 23 11:07:37 2019 +0100
@@ -25,7 +25,8 @@
 #ifndef SHARE_GC_G1_G1_GLOBALS_HPP
 #define SHARE_GC_G1_G1_GLOBALS_HPP
 
-#include <float.h> // for DBL_MAX
+#include "runtime/globals_shared.hpp"
+
 //
 // Defines all globals flags used by the garbage-first compiler.
 //
--- a/src/hotspot/share/gc/g1/heapRegion.cpp	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/share/gc/g1/heapRegion.cpp	Thu May 23 11:07:37 2019 +0100
@@ -106,7 +106,7 @@
   CardsPerRegion = GrainBytes >> G1CardTable::card_shift;
 
   if (G1HeapRegionSize != GrainBytes) {
-    FLAG_SET_ERGO(size_t, G1HeapRegionSize, GrainBytes);
+    FLAG_SET_ERGO(G1HeapRegionSize, GrainBytes);
   }
 }
 
--- a/src/hotspot/share/gc/parallel/parallelArguments.cpp	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/share/gc/parallel/parallelArguments.cpp	Thu May 23 11:07:37 2019 +0100
@@ -113,11 +113,11 @@
   // default gc, which adds 2 to the ratio value. We need to
   // make sure the values are valid before using them.
   if (MinSurvivorRatio < 3) {
-    FLAG_SET_ERGO(uintx, MinSurvivorRatio, 3);
+    FLAG_SET_ERGO(MinSurvivorRatio, 3);
   }
 
   if (InitialSurvivorRatio < 3) {
-    FLAG_SET_ERGO(uintx, InitialSurvivorRatio, 3);
+    FLAG_SET_ERGO(InitialSurvivorRatio, 3);
   }
 }
 
--- a/src/hotspot/share/gc/shared/gcArguments.cpp	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/share/gc/shared/gcArguments.cpp	Thu May 23 11:07:37 2019 +0100
@@ -54,12 +54,12 @@
 
   if (MinHeapFreeRatio == 100) {
     // Keeping the heap 100% free is hard ;-) so limit it to 99%.
-    FLAG_SET_ERGO(uintx, MinHeapFreeRatio, 99);
+    FLAG_SET_ERGO(MinHeapFreeRatio, 99);
   }
 
   if (!ClassUnloading) {
     // If class unloading is disabled, also disable concurrent class unloading.
-    FLAG_SET_CMDLINE(bool, ClassUnloadingWithConcurrentMark, false);
+    FLAG_SET_CMDLINE(ClassUnloadingWithConcurrentMark, false);
   }
 
   if (!FLAG_IS_DEFAULT(AllocateOldGenAt)) {
@@ -172,10 +172,10 @@
 
   // Write back to flags if the values changed
   if (aligned_initial_heap_size != InitialHeapSize) {
-    FLAG_SET_ERGO(size_t, InitialHeapSize, aligned_initial_heap_size);
+    FLAG_SET_ERGO(InitialHeapSize, aligned_initial_heap_size);
   }
   if (aligned_max_heap_size != MaxHeapSize) {
-    FLAG_SET_ERGO(size_t, MaxHeapSize, aligned_max_heap_size);
+    FLAG_SET_ERGO(MaxHeapSize, aligned_max_heap_size);
   }
 
   if (FLAG_IS_CMDLINE(InitialHeapSize) && MinHeapSize != 0 &&
@@ -183,15 +183,15 @@
     vm_exit_during_initialization("Incompatible minimum and initial heap sizes specified");
   }
   if (!FLAG_IS_DEFAULT(InitialHeapSize) && InitialHeapSize > MaxHeapSize) {
-    FLAG_SET_ERGO(size_t, MaxHeapSize, InitialHeapSize);
+    FLAG_SET_ERGO(MaxHeapSize, InitialHeapSize);
   } else if (!FLAG_IS_DEFAULT(MaxHeapSize) && InitialHeapSize > MaxHeapSize) {
-    FLAG_SET_ERGO(size_t, InitialHeapSize, MaxHeapSize);
+    FLAG_SET_ERGO(InitialHeapSize, MaxHeapSize);
     if (InitialHeapSize < MinHeapSize) {
       MinHeapSize = InitialHeapSize;
     }
   }
 
-  FLAG_SET_ERGO(size_t, MinHeapDeltaBytes, align_up(MinHeapDeltaBytes, SpaceAlignment));
+  FLAG_SET_ERGO(MinHeapDeltaBytes, align_up(MinHeapDeltaBytes, SpaceAlignment));
 
   DEBUG_ONLY(assert_flags();)
 }
--- a/src/hotspot/share/gc/shared/gcCause.cpp	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/share/gc/shared/gcCause.cpp	Thu May 23 11:07:37 2019 +0100
@@ -141,6 +141,9 @@
     case _z_proactive:
       return "Proactive";
 
+    case _z_high_usage:
+      return "High Usage";
+
     case _last_gc_cause:
       return "ILLEGAL VALUE - last gc cause - ILLEGAL VALUE";
 
--- a/src/hotspot/share/gc/shared/gcCause.hpp	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/share/gc/shared/gcCause.hpp	Thu May 23 11:07:37 2019 +0100
@@ -91,6 +91,7 @@
     _z_allocation_rate,
     _z_allocation_stall,
     _z_proactive,
+    _z_high_usage,
 
     _last_gc_cause
   };
--- a/src/hotspot/share/gc/shared/gcConfig.cpp	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/share/gc/shared/gcConfig.cpp	Thu May 23 11:07:37 2019 +0100
@@ -109,15 +109,15 @@
 void GCConfig::select_gc_ergonomically() {
   if (os::is_server_class_machine()) {
 #if INCLUDE_G1GC
-    FLAG_SET_ERGO_IF_DEFAULT(bool, UseG1GC, true);
+    FLAG_SET_ERGO_IF_DEFAULT(UseG1GC, true);
 #elif INCLUDE_PARALLELGC
-    FLAG_SET_ERGO_IF_DEFAULT(bool, UseParallelGC, true);
+    FLAG_SET_ERGO_IF_DEFAULT(UseParallelGC, true);
 #elif INCLUDE_SERIALGC
-    FLAG_SET_ERGO_IF_DEFAULT(bool, UseSerialGC, true);
+    FLAG_SET_ERGO_IF_DEFAULT(UseSerialGC, true);
 #endif
   } else {
 #if INCLUDE_SERIALGC
-    FLAG_SET_ERGO_IF_DEFAULT(bool, UseSerialGC, true);
+    FLAG_SET_ERGO_IF_DEFAULT(UseSerialGC, true);
 #endif
   }
 }
--- a/src/hotspot/share/gc/shared/gc_globals.hpp	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/share/gc/shared/gc_globals.hpp	Thu May 23 11:07:37 2019 +0100
@@ -25,6 +25,7 @@
 #ifndef SHARE_GC_SHARED_GC_GLOBALS_HPP
 #define SHARE_GC_SHARED_GC_GLOBALS_HPP
 
+#include "runtime/globals_shared.hpp"
 #include "utilities/macros.hpp"
 #if INCLUDE_CMSGC
 #include "gc/cms/cms_globals.hpp"
--- a/src/hotspot/share/gc/shared/genArguments.cpp	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/share/gc/shared/genArguments.cpp	Thu May 23 11:07:37 2019 +0100
@@ -86,20 +86,20 @@
   size_t smallest_heap_size = align_up(smallest_new_size + old_gen_size_lower_bound(),
                                        HeapAlignment);
   if (MaxHeapSize < smallest_heap_size) {
-    FLAG_SET_ERGO(size_t, MaxHeapSize, smallest_heap_size);
+    FLAG_SET_ERGO(MaxHeapSize, smallest_heap_size);
   }
   // If needed, synchronize MinHeapSize size and InitialHeapSize
   if (MinHeapSize < smallest_heap_size) {
     MinHeapSize = smallest_heap_size;
     if (InitialHeapSize < MinHeapSize) {
-      FLAG_SET_ERGO(size_t, InitialHeapSize, smallest_heap_size);
+      FLAG_SET_ERGO(InitialHeapSize, smallest_heap_size);
     }
   }
 
   // Make sure NewSize allows an old generation to fit even if set on the command line
   if (FLAG_IS_CMDLINE(NewSize) && NewSize >= InitialHeapSize) {
     log_warning(gc, ergo)("NewSize was set larger than initial heap size, will use initial heap size.");
-    FLAG_SET_ERGO(size_t, NewSize, bound_minus_alignment(NewSize, InitialHeapSize, GenAlignment));
+    FLAG_SET_ERGO(NewSize, bound_minus_alignment(NewSize, InitialHeapSize, GenAlignment));
   }
 
   // Now take the actual NewSize into account. We will silently increase NewSize
@@ -107,7 +107,7 @@
   size_t bounded_new_size = bound_minus_alignment(NewSize, MaxHeapSize, GenAlignment);
   bounded_new_size = MAX2(smallest_new_size, align_down(bounded_new_size, GenAlignment));
   if (bounded_new_size != NewSize) {
-    FLAG_SET_ERGO(size_t, NewSize, bounded_new_size);
+    FLAG_SET_ERGO(NewSize, bounded_new_size);
   }
   MinNewSize = smallest_new_size;
 
@@ -120,14 +120,14 @@
                               "heap (" SIZE_FORMAT "k).  A new max generation size of " SIZE_FORMAT "k will be used.",
                               MaxNewSize/K, MaxHeapSize/K, smaller_max_new_size/K);
       }
-      FLAG_SET_ERGO(size_t, MaxNewSize, smaller_max_new_size);
+      FLAG_SET_ERGO(MaxNewSize, smaller_max_new_size);
       if (NewSize > MaxNewSize) {
-        FLAG_SET_ERGO(size_t, NewSize, MaxNewSize);
+        FLAG_SET_ERGO(NewSize, MaxNewSize);
       }
     } else if (MaxNewSize < NewSize) {
-      FLAG_SET_ERGO(size_t, MaxNewSize, NewSize);
+      FLAG_SET_ERGO(MaxNewSize, NewSize);
     } else if (!is_aligned(MaxNewSize, GenAlignment)) {
-      FLAG_SET_ERGO(size_t, MaxNewSize, align_down(MaxNewSize, GenAlignment));
+      FLAG_SET_ERGO(MaxNewSize, align_down(MaxNewSize, GenAlignment));
     }
   }
 
@@ -139,7 +139,7 @@
                             "A new max generation size of " SIZE_FORMAT "k will be used.",
                             NewSize/K, MaxNewSize/K, NewSize/K);
     }
-    FLAG_SET_ERGO(size_t, MaxNewSize, NewSize);
+    FLAG_SET_ERGO(MaxNewSize, NewSize);
   }
 
   if (SurvivorRatio < 1 || NewRatio < 1) {
@@ -147,10 +147,10 @@
   }
 
   if (OldSize < old_gen_size_lower_bound()) {
-    FLAG_SET_ERGO(size_t, OldSize, old_gen_size_lower_bound());
+    FLAG_SET_ERGO(OldSize, old_gen_size_lower_bound());
   }
   if (!is_aligned(OldSize, GenAlignment)) {
-    FLAG_SET_ERGO(size_t, OldSize, align_down(OldSize, GenAlignment));
+    FLAG_SET_ERGO(OldSize, align_down(OldSize, GenAlignment));
   }
 
   if (FLAG_IS_CMDLINE(OldSize) && FLAG_IS_DEFAULT(MaxHeapSize)) {
@@ -161,8 +161,8 @@
     size_t calculated_heapsize = (OldSize / NewRatio) * (NewRatio + 1);
 
     calculated_heapsize = align_up(calculated_heapsize, HeapAlignment);
-    FLAG_SET_ERGO(size_t, MaxHeapSize, calculated_heapsize);
-    FLAG_SET_ERGO(size_t, InitialHeapSize, calculated_heapsize);
+    FLAG_SET_ERGO(MaxHeapSize, calculated_heapsize);
+    FLAG_SET_ERGO(InitialHeapSize, calculated_heapsize);
   }
 
   // Adjust NewSize and OldSize or MaxHeapSize to match each other
@@ -173,15 +173,15 @@
       size_t calculated_size = NewSize + OldSize;
       double shrink_factor = (double) MaxHeapSize / calculated_size;
       size_t smaller_new_size = align_down((size_t)(NewSize * shrink_factor), GenAlignment);
-      FLAG_SET_ERGO(size_t, NewSize, MAX2(young_gen_size_lower_bound(), smaller_new_size));
+      FLAG_SET_ERGO(NewSize, MAX2(young_gen_size_lower_bound(), smaller_new_size));
 
       // OldSize is already aligned because above we aligned MaxHeapSize to
       // HeapAlignment, and we just made sure that NewSize is aligned to
       // GenAlignment. In initialize_flags() we verified that HeapAlignment
       // is a multiple of GenAlignment.
-      FLAG_SET_ERGO(size_t, OldSize, MaxHeapSize - NewSize);
+      FLAG_SET_ERGO(OldSize, MaxHeapSize - NewSize);
     } else {
-      FLAG_SET_ERGO(size_t, MaxHeapSize, align_up(NewSize + OldSize, HeapAlignment));
+      FLAG_SET_ERGO(MaxHeapSize, align_up(NewSize + OldSize, HeapAlignment));
     }
   }
 
@@ -191,7 +191,7 @@
     if (OldSize < InitialHeapSize) {
       size_t new_size = InitialHeapSize - OldSize;
       if (new_size >= MinNewSize && new_size <= MaxNewSize) {
-        FLAG_SET_ERGO(size_t, NewSize, new_size);
+        FLAG_SET_ERGO(NewSize, new_size);
       }
     }
   }
@@ -341,15 +341,15 @@
 
   // Write back to flags if necessary.
   if (NewSize != initial_young_size) {
-    FLAG_SET_ERGO(size_t, NewSize, initial_young_size);
+    FLAG_SET_ERGO(NewSize, initial_young_size);
   }
 
   if (MaxNewSize != max_young_size) {
-    FLAG_SET_ERGO(size_t, MaxNewSize, max_young_size);
+    FLAG_SET_ERGO(MaxNewSize, max_young_size);
   }
 
   if (OldSize != initial_old_size) {
-    FLAG_SET_ERGO(size_t, OldSize, initial_old_size);
+    FLAG_SET_ERGO(OldSize, initial_old_size);
   }
 
   log_trace(gc, heap)("Minimum old " SIZE_FORMAT "  Initial old " SIZE_FORMAT "  Maximum old " SIZE_FORMAT,
--- a/src/hotspot/share/gc/shared/jvmFlagConstraintsGC.cpp	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/share/gc/shared/jvmFlagConstraintsGC.cpp	Thu May 23 11:07:37 2019 +0100
@@ -45,12 +45,6 @@
 #if INCLUDE_PARALLELGC
 #include "gc/parallel/jvmFlagConstraintsParallel.hpp"
 #endif
-#ifdef COMPILER1
-#include "c1/c1_globals.hpp"
-#endif // COMPILER1
-#ifdef COMPILER2
-#include "opto/c2_globals.hpp"
-#endif // COMPILER2
 
 // Some flags that have default values that indicate that the
 // JVM should automatically determine an appropriate value
--- a/src/hotspot/share/gc/shared/ptrQueue.cpp	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/share/gc/shared/ptrQueue.cpp	Thu May 23 11:07:37 2019 +0100
@@ -62,7 +62,6 @@
   }
 }
 
-
 void PtrQueue::enqueue_known_active(void* ptr) {
   while (_index == 0) {
     handle_zero_index();
@@ -75,6 +74,35 @@
   _buf[index()] = ptr;
 }
 
+void PtrQueue::handle_zero_index() {
+  assert(index() == 0, "precondition");
+
+  if (_buf != NULL) {
+    handle_completed_buffer();
+  } else {
+    // Bootstrapping kludge; lazily initialize capacity.  The initial
+    // thread's queues are constructed before the second phase of the
+    // two-phase initialization of the associated qsets.  As a result,
+    // we can't initialize _capacity_in_bytes in the queue constructor.
+    if (_capacity_in_bytes == 0) {
+      _capacity_in_bytes = index_to_byte_index(qset()->buffer_size());
+    }
+    allocate_buffer();
+  }
+}
+
+void PtrQueue::allocate_buffer() {
+  _buf = qset()->allocate_buffer();
+  reset();
+}
+
+void PtrQueue::enqueue_completed_buffer() {
+  assert(_buf != NULL, "precondition");
+  BufferNode* node = BufferNode::make_node_from_buffer(_buf, index());
+  qset()->enqueue_completed_buffer(node);
+  allocate_buffer();
+}
+
 BufferNode* BufferNode::allocate(size_t size) {
   size_t byte_size = size * sizeof(void*);
   void* data = NEW_C_HEAP_ARRAY(char, buffer_offset() + byte_size, mtGC);
@@ -231,8 +259,6 @@
   _process_completed_buffers_threshold(ProcessCompletedBuffersThresholdNever),
   _process_completed_buffers(false),
   _notify_when_complete(notify_when_complete),
-  _max_completed_buffers(MaxCompletedBuffersUnlimited),
-  _completed_buffers_padding(0),
   _all_active(false)
 {}
 
@@ -258,52 +284,6 @@
   _allocator->release(node);
 }
 
-void PtrQueue::handle_zero_index() {
-  assert(index() == 0, "precondition");
-
-  // This thread records the full buffer and allocates a new one (while
-  // holding the lock if there is one).
-  if (_buf != NULL) {
-    if (!should_enqueue_buffer()) {
-      assert(index() > 0, "the buffer can only be re-used if it's not full");
-      return;
-    }
-
-    BufferNode* node = BufferNode::make_node_from_buffer(_buf, index());
-    if (qset()->process_or_enqueue_completed_buffer(node)) {
-      // Recycle the buffer. No allocation.
-      assert(_buf == BufferNode::make_buffer_from_node(node), "invariant");
-      assert(capacity() == qset()->buffer_size(), "invariant");
-      reset();
-      return;
-    }
-  }
-  // Set capacity in case this is the first allocation.
-  set_capacity(qset()->buffer_size());
-  // Allocate a new buffer.
-  _buf = qset()->allocate_buffer();
-  reset();
-}
-
-bool PtrQueueSet::process_or_enqueue_completed_buffer(BufferNode* node) {
-  if (Thread::current()->is_Java_thread()) {
-    // If the number of buffers exceeds the limit, make this Java
-    // thread do the processing itself.  We don't lock to access
-    // buffer count or padding; it is fine to be imprecise here.  The
-    // add of padding could overflow, which is treated as unlimited.
-    size_t limit = _max_completed_buffers + _completed_buffers_padding;
-    if ((_n_completed_buffers > limit) && (limit >= _max_completed_buffers)) {
-      if (mut_process_buffer(node)) {
-        // Successfully processed; return true to allow buffer reuse.
-        return true;
-      }
-    }
-  }
-  // The buffer will be enqueued. The caller will have to get a new one.
-  enqueue_completed_buffer(node);
-  return false;
-}
-
 void PtrQueueSet::enqueue_completed_buffer(BufferNode* cbn) {
   MutexLocker x(_cbl_mon, Mutex::_no_safepoint_check_flag);
   cbn->set_next(NULL);
--- a/src/hotspot/share/gc/shared/ptrQueue.hpp	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/share/gc/shared/ptrQueue.hpp	Thu May 23 11:07:37 2019 +0100
@@ -71,14 +71,6 @@
     return _capacity_in_bytes;
   }
 
-  void set_capacity(size_t entries) {
-    size_t byte_capacity = index_to_byte_index(entries);
-    assert(_capacity_in_bytes == 0 || _capacity_in_bytes == byte_capacity,
-           "changing capacity " SIZE_FORMAT " -> " SIZE_FORMAT,
-           _capacity_in_bytes, byte_capacity);
-    _capacity_in_bytes = byte_capacity;
-  }
-
   static size_t byte_index_to_index(size_t ind) {
     assert(is_aligned(ind, _element_size), "precondition");
     return ind / _element_size;
@@ -106,11 +98,20 @@
     return byte_index_to_index(capacity_in_bytes());
   }
 
-  PtrQueueSet* qset() { return _qset; }
+  PtrQueueSet* qset() const { return _qset; }
 
   // Process queue entries and release resources.
   void flush_impl();
 
+  // Process (some of) the buffer and leave it in place for further use,
+  // or enqueue the buffer and allocate a new one.
+  virtual void handle_completed_buffer() = 0;
+
+  void allocate_buffer();
+
+  // Enqueue the current buffer in the qset and allocate a new buffer.
+  void enqueue_completed_buffer();
+
   // Initialize this queue to contain a null buffer, and be part of the
   // given PtrQueueSet.
   PtrQueue(PtrQueueSet* qset, bool active = false);
@@ -137,14 +138,6 @@
     else enqueue_known_active(ptr);
   }
 
-  // This method is called when we're doing the zero index handling
-  // and gives a chance to the queues to do any pre-enqueueing
-  // processing they might want to do on the buffer. It should return
-  // true if the buffer should be enqueued, or false if enough
-  // entries were cleared from it so that it can be re-used. It should
-  // not return false if the buffer is still full (otherwise we can
-  // get into an infinite loop).
-  virtual bool should_enqueue_buffer() { return true; }
   void handle_zero_index();
 
   void enqueue_known_active(void* ptr);
@@ -306,7 +299,7 @@
   Monitor* _cbl_mon;  // Protects the fields below.
   BufferNode* _completed_buffers_head;
   BufferNode* _completed_buffers_tail;
-  size_t _n_completed_buffers;
+  volatile size_t _n_completed_buffers;
 
   size_t _process_completed_buffers_threshold;
   volatile bool _process_completed_buffers;
@@ -314,24 +307,11 @@
   // If true, notify_all on _cbl_mon when the threshold is reached.
   bool _notify_when_complete;
 
-  // Maximum number of elements allowed on completed queue: after that,
-  // enqueuer does the work itself.
-  size_t _max_completed_buffers;
-  size_t _completed_buffers_padding;
-
   void assert_completed_buffers_list_len_correct_locked() NOT_DEBUG_RETURN;
 
 protected:
   bool _all_active;
 
-  // A mutator thread does the the work of processing a buffer.
-  // Returns "true" iff the work is complete (and the buffer may be
-  // deallocated).
-  virtual bool mut_process_buffer(BufferNode* node) {
-    ShouldNotReachHere();
-    return false;
-  }
-
   // Create an empty ptr queue set.
   PtrQueueSet(bool notify_when_complete = false);
   ~PtrQueueSet();
@@ -365,9 +345,6 @@
   // return a completed buffer from the list.  Otherwise, return NULL.
   BufferNode* get_completed_buffer(size_t stop_at = 0);
 
-  // To be invoked by the mutator.
-  bool process_or_enqueue_completed_buffer(BufferNode* node);
-
   bool process_completed_buffers() { return _process_completed_buffers; }
   void set_process_completed_buffers(bool x) { _process_completed_buffers = x; }
 
@@ -392,21 +369,6 @@
 
   void merge_bufferlists(PtrQueueSet* src);
 
-  void set_max_completed_buffers(size_t m) {
-    _max_completed_buffers = m;
-  }
-  size_t max_completed_buffers() const {
-    return _max_completed_buffers;
-  }
-  static const size_t MaxCompletedBuffersUnlimited = ~size_t(0);
-
-  void set_completed_buffers_padding(size_t padding) {
-    _completed_buffers_padding = padding;
-  }
-  size_t completed_buffers_padding() const {
-    return _completed_buffers_padding;
-  }
-
   // Notify the consumer if the number of buffers crossed the threshold
   void notify_if_necessary();
 };
--- a/src/hotspot/share/gc/shared/satbMarkQueue.cpp	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/share/gc/shared/satbMarkQueue.cpp	Thu May 23 11:07:37 2019 +0100
@@ -56,7 +56,7 @@
 // retains a small enough collection in the buffer, we can continue to
 // use the buffer as-is, instead of enqueueing and replacing it.
 
-bool SATBMarkQueue::should_enqueue_buffer() {
+void SATBMarkQueue::handle_completed_buffer() {
   // This method should only be called if there is a non-NULL buffer
   // that is full.
   assert(index() == 0, "pre-condition");
@@ -64,15 +64,18 @@
 
   filter();
 
-  SATBMarkQueueSet* satb_qset = static_cast<SATBMarkQueueSet*>(qset());
-  size_t threshold = satb_qset->buffer_enqueue_threshold();
+  size_t threshold = satb_qset()->buffer_enqueue_threshold();
   // Ensure we'll enqueue completely full buffers.
   assert(threshold > 0, "enqueue threshold = 0");
   // Ensure we won't enqueue empty buffers.
   assert(threshold <= capacity(),
          "enqueue threshold " SIZE_FORMAT " exceeds capacity " SIZE_FORMAT,
          threshold, capacity());
-  return index() < threshold;
+
+  if (index() < threshold) {
+    // Buffer is sufficiently full; enqueue and allocate a new one.
+    enqueue_completed_buffer();
+  } // Else continue to accumulate in buffer.
 }
 
 void SATBMarkQueue::apply_closure_and_empty(SATBBufferClosure* cl) {
--- a/src/hotspot/share/gc/shared/satbMarkQueue.hpp	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/share/gc/shared/satbMarkQueue.hpp	Thu May 23 11:07:37 2019 +0100
@@ -54,20 +54,21 @@
   template<typename Filter>
   inline void apply_filter(Filter filter_out);
 
+protected:
+  virtual void handle_completed_buffer();
+
 public:
   SATBMarkQueue(SATBMarkQueueSet* qset);
 
   // Process queue entries and free resources.
   void flush();
 
+  inline SATBMarkQueueSet* satb_qset() const;
+
   // Apply cl to the active part of the buffer.
   // Prerequisite: Must be at a safepoint.
   void apply_closure_and_empty(SATBBufferClosure* cl);
 
-  // Overrides PtrQueue::should_enqueue_buffer(). See the method's
-  // definition for more information.
-  virtual bool should_enqueue_buffer();
-
 #ifndef PRODUCT
   // Helpful for debugging
   void print(const char* name);
@@ -140,8 +141,12 @@
   void abandon_partial_marking();
 };
 
+inline SATBMarkQueueSet* SATBMarkQueue::satb_qset() const {
+  return static_cast<SATBMarkQueueSet*>(qset());
+}
+
 inline void SATBMarkQueue::filter() {
-  static_cast<SATBMarkQueueSet*>(qset())->filter(this);
+  satb_qset()->filter(this);
 }
 
 // Removes entries from the buffer that are no longer needed, as
--- a/src/hotspot/share/gc/shenandoah/shenandoahConcurrentMark.cpp	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/share/gc/shenandoah/shenandoahConcurrentMark.cpp	Thu May 23 11:07:37 2019 +0100
@@ -81,10 +81,10 @@
 template<UpdateRefsMode UPDATE_REFS>
 class ShenandoahInitMarkRootsTask : public AbstractGangTask {
 private:
-  ShenandoahRootProcessor* _rp;
+  ShenandoahAllRootScanner* _rp;
   bool _process_refs;
 public:
-  ShenandoahInitMarkRootsTask(ShenandoahRootProcessor* rp, bool process_refs) :
+  ShenandoahInitMarkRootsTask(ShenandoahAllRootScanner* rp, bool process_refs) :
     AbstractGangTask("Shenandoah init mark roots task"),
     _rp(rp),
     _process_refs(process_refs) {
@@ -115,45 +115,21 @@
     //      cache, because there could be the case of embedded class/oop in the generated code,
     //      which we will never visit during mark. Without code cache invalidation, as in (a),
     //      we risk executing that code cache blob, and crashing.
-    //   c. With ShenandoahConcurrentScanCodeRoots, we avoid scanning the entire code cache here,
-    //      and instead do that in concurrent phase under the relevant lock. This saves init mark
-    //      pause time.
-
-    CLDToOopClosure clds_cl(oops, ClassLoaderData::_claim_strong);
-    MarkingCodeBlobClosure blobs_cl(oops, ! CodeBlobToOopClosure::FixRelocations);
-
-    ResourceMark m;
     if (heap->unload_classes()) {
-      _rp->process_strong_roots(oops, &clds_cl, &blobs_cl, NULL, worker_id);
+      _rp->strong_roots_do(worker_id, oops);
     } else {
-      if (ShenandoahConcurrentScanCodeRoots) {
-        CodeBlobClosure* code_blobs = NULL;
-#ifdef ASSERT
-        ShenandoahAssertToSpaceClosure assert_to_space_oops;
-        CodeBlobToOopClosure assert_to_space(&assert_to_space_oops, !CodeBlobToOopClosure::FixRelocations);
-        // If conc code cache evac is disabled, code cache should have only to-space ptrs.
-        // Otherwise, it should have to-space ptrs only if mark does not update refs.
-        if (!heap->has_forwarded_objects()) {
-          code_blobs = &assert_to_space;
-        }
-#endif
-        _rp->process_all_roots(oops, &clds_cl, code_blobs, NULL, worker_id);
-      } else {
-        _rp->process_all_roots(oops, &clds_cl, &blobs_cl, NULL, worker_id);
-      }
+      _rp->roots_do(worker_id, oops);
     }
   }
 };
 
 class ShenandoahUpdateRootsTask : public AbstractGangTask {
 private:
-  ShenandoahRootProcessor* _rp;
-  const bool _update_code_cache;
+  ShenandoahRootUpdater*  _root_updater;
 public:
-  ShenandoahUpdateRootsTask(ShenandoahRootProcessor* rp, bool update_code_cache) :
+  ShenandoahUpdateRootsTask(ShenandoahRootUpdater* root_updater) :
     AbstractGangTask("Shenandoah update roots task"),
-    _rp(rp),
-    _update_code_cache(update_code_cache) {
+    _root_updater(root_updater) {
   }
 
   void work(uint worker_id) {
@@ -162,22 +138,8 @@
 
     ShenandoahHeap* heap = ShenandoahHeap::heap();
     ShenandoahUpdateRefsClosure cl;
-    CLDToOopClosure cldCl(&cl, ClassLoaderData::_claim_strong);
-
-    CodeBlobClosure* code_blobs;
-    CodeBlobToOopClosure update_blobs(&cl, CodeBlobToOopClosure::FixRelocations);
-#ifdef ASSERT
-    ShenandoahAssertToSpaceClosure assert_to_space_oops;
-    CodeBlobToOopClosure assert_to_space(&assert_to_space_oops, !CodeBlobToOopClosure::FixRelocations);
-#endif
-    if (_update_code_cache) {
-      code_blobs = &update_blobs;
-    } else {
-      code_blobs =
-        DEBUG_ONLY(&assert_to_space)
-        NOT_DEBUG(NULL);
-    }
-    _rp->update_all_roots<AlwaysTrueClosure>(&cl, &cldCl, code_blobs, NULL, worker_id);
+    AlwaysTrueClosure always_true;
+    _root_updater->roots_do<AlwaysTrueClosure, ShenandoahUpdateRefsClosure>(worker_id, &always_true, &cl);
   }
 };
 
@@ -265,9 +227,12 @@
       rp = NULL;
     }
 
-    // Degenerated cycle may bypass concurrent cycle, so code roots might not be scanned,
-    // let's check here.
-    _cm->concurrent_scan_code_roots(worker_id, rp);
+    if (heap->is_degenerated_gc_in_progress()) {
+      // Degenerated cycle may bypass concurrent cycle, so code roots might not be scanned,
+      // let's check here.
+      _cm->concurrent_scan_code_roots(worker_id, rp);
+    }
+
     _cm->mark_loop(worker_id, _terminator, rp,
                    false, // not cancellable
                    _dedup_string);
@@ -289,7 +254,7 @@
 
   assert(nworkers <= task_queues()->size(), "Just check");
 
-  ShenandoahRootProcessor root_proc(heap, nworkers, root_phase);
+  ShenandoahAllRootScanner root_proc(nworkers, root_phase);
   TASKQUEUE_STATS_ONLY(task_queues()->reset_taskqueue_stats());
   task_queues()->reserve(nworkers);
 
@@ -333,8 +298,8 @@
 
   uint nworkers = _heap->workers()->active_workers();
 
-  ShenandoahRootProcessor root_proc(_heap, nworkers, root_phase);
-  ShenandoahUpdateRootsTask update_roots(&root_proc, update_code_cache);
+  ShenandoahRootUpdater root_updater(nworkers, root_phase, update_code_cache);
+  ShenandoahUpdateRootsTask update_roots(&root_updater);
   _heap->workers()->run_task(&update_roots);
 
 #if defined(COMPILER2) || INCLUDE_JVMCI
@@ -342,6 +307,34 @@
 #endif
 }
 
+class ShenandoahUpdateThreadRootsTask : public AbstractGangTask {
+private:
+  ShenandoahThreadRoots           _thread_roots;
+  ShenandoahPhaseTimings::Phase   _phase;
+public:
+  ShenandoahUpdateThreadRootsTask(bool is_par, ShenandoahPhaseTimings::Phase phase) :
+    AbstractGangTask("Shenandoah Update Thread Roots"),
+    _thread_roots(is_par),
+    _phase(phase) {
+    ShenandoahHeap::heap()->phase_timings()->record_workers_start(_phase);
+  }
+
+  ~ShenandoahUpdateThreadRootsTask() {
+    ShenandoahHeap::heap()->phase_timings()->record_workers_end(_phase);
+  }
+  void work(uint worker_id) {
+    ShenandoahUpdateRefsClosure cl;
+    _thread_roots.oops_do(&cl, NULL, worker_id);
+  }
+};
+
+void ShenandoahConcurrentMark::update_thread_roots(ShenandoahPhaseTimings::Phase root_phase) {
+  WorkGang* workers = _heap->workers();
+  bool is_par = workers->active_workers() > 1;
+  ShenandoahUpdateThreadRootsTask task(is_par, root_phase);
+  workers->run_task(&task);
+}
+
 void ShenandoahConcurrentMark::initialize(uint workers) {
   _heap = ShenandoahHeap::heap();
 
--- a/src/hotspot/share/gc/shenandoah/shenandoahConcurrentMark.hpp	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/share/gc/shenandoah/shenandoahConcurrentMark.hpp	Thu May 23 11:07:37 2019 +0100
@@ -79,6 +79,7 @@
 
   void mark_roots(ShenandoahPhaseTimings::Phase root_phase);
   void update_roots(ShenandoahPhaseTimings::Phase root_phase);
+  void update_thread_roots(ShenandoahPhaseTimings::Phase root_phase);
 
 // ---------- Weak references
 //
--- a/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp	Thu May 23 11:07:37 2019 +0100
@@ -52,7 +52,7 @@
 #include "gc/shenandoah/shenandoahMonitoringSupport.hpp"
 #include "gc/shenandoah/shenandoahOopClosures.inline.hpp"
 #include "gc/shenandoah/shenandoahPacer.inline.hpp"
-#include "gc/shenandoah/shenandoahRootProcessor.hpp"
+#include "gc/shenandoah/shenandoahRootProcessor.inline.hpp"
 #include "gc/shenandoah/shenandoahStringDedup.hpp"
 #include "gc/shenandoah/shenandoahTaskqueue.hpp"
 #include "gc/shenandoah/shenandoahUtils.hpp"
@@ -67,6 +67,10 @@
 #include "gc/shenandoah/heuristics/shenandoahPassiveHeuristics.hpp"
 #include "gc/shenandoah/heuristics/shenandoahStaticHeuristics.hpp"
 #include "gc/shenandoah/heuristics/shenandoahTraversalHeuristics.hpp"
+#if INCLUDE_JFR
+#include "gc/shenandoah/shenandoahJfrSupport.hpp"
+#endif
+
 #include "memory/metaspace.hpp"
 #include "oops/compressedOops.inline.hpp"
 #include "runtime/globals.hpp"
@@ -596,6 +600,8 @@
   ref_processing_init();
 
   _heuristics->initialize();
+
+  JFR_ONLY(ShenandoahJFRSupport::register_jfr_type_serializers());
 }
 
 size_t ShenandoahHeap::used() const {
@@ -1111,7 +1117,7 @@
     ShenandoahEvacOOMScope oom_evac_scope;
     ShenandoahEvacuateUpdateRootsClosure cl;
     MarkingCodeBlobClosure blobsCl(&cl, CodeBlobToOopClosure::FixRelocations);
-    _rp->process_evacuate_roots(&cl, &blobsCl, worker_id);
+    _rp->roots_do(worker_id, &cl);
   }
 };
 
@@ -1122,7 +1128,7 @@
   assert(ShenandoahSafepoint::is_at_shenandoah_safepoint(), "Only iterate roots while world is stopped");
 
   {
-    ShenandoahRootEvacuator rp(this, workers()->active_workers(), ShenandoahPhaseTimings::init_evac);
+    ShenandoahRootEvacuator rp(workers()->active_workers(), ShenandoahPhaseTimings::init_evac);
     ShenandoahEvacuateUpdateRootsTask roots_task(&rp);
     workers()->run_task(&roots_task);
   }
@@ -1326,11 +1332,9 @@
   Stack<oop,mtGC> oop_stack;
 
   // First, we process all GC roots. This populates the work stack with initial objects.
-  ShenandoahRootProcessor rp(this, 1, ShenandoahPhaseTimings::_num_phases);
+  ShenandoahAllRootScanner rp(1, ShenandoahPhaseTimings::_num_phases);
   ObjectIterateScanRootClosure oops(&_aux_bit_map, &oop_stack);
-  CLDToOopClosure clds(&oops, ClassLoaderData::_claim_none);
-  CodeBlobToOopClosure blobs(&oops, false);
-  rp.process_all_roots(&oops, &clds, &blobs, NULL, 0);
+  rp.roots_do(0, &oops);
 
   // Work through the oop stack to traverse heap.
   while (! oop_stack.is_empty()) {
@@ -1501,10 +1505,14 @@
   if (!cancelled_gc()) {
     concurrent_mark()->finish_mark_from_roots(/* full_gc = */ false);
 
-    // Degen may be caused by failed evacuation of roots
-    if (is_degenerated_gc_in_progress() && has_forwarded_objects()) {
-      concurrent_mark()->update_roots(ShenandoahPhaseTimings::degen_gc_update_roots);
-    }
+    if (has_forwarded_objects()) {
+      // Degen may be caused by failed evacuation of roots
+      if (is_degenerated_gc_in_progress()) {
+        concurrent_mark()->update_roots(ShenandoahPhaseTimings::degen_gc_update_roots);
+      } else {
+        concurrent_mark()->update_thread_roots(ShenandoahPhaseTimings::update_roots);
+      }
+   }
 
     if (ShenandoahVerify) {
       verifier()->verify_roots_no_forwarded();
@@ -2202,9 +2210,11 @@
     verifier()->verify_roots_no_forwarded_except(ShenandoahRootVerifier::ThreadRoots);
   }
 
-  concurrent_mark()->update_roots(is_degenerated_gc_in_progress() ?
-                                  ShenandoahPhaseTimings::degen_gc_update_roots:
-                                  ShenandoahPhaseTimings::final_update_refs_roots);
+  if (is_degenerated_gc_in_progress()) {
+    concurrent_mark()->update_roots(ShenandoahPhaseTimings::degen_gc_update_roots);
+  } else {
+    concurrent_mark()->update_thread_roots(ShenandoahPhaseTimings::final_update_refs_roots);
+  }
 
   ShenandoahGCPhase final_update_refs(ShenandoahPhaseTimings::final_update_refs_recycle);
 
--- a/src/hotspot/share/gc/shenandoah/shenandoahHeap.hpp	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/share/gc/shenandoah/shenandoahHeap.hpp	Thu May 23 11:07:37 2019 +0100
@@ -40,6 +40,7 @@
 class ShenandoahCollectorPolicy;
 class ShenandoahControlThread;
 class ShenandoahGCSession;
+class ShenandoahGCStateResetter;
 class ShenandoahHeuristics;
 class ShenandoahMarkingContext;
 class ShenandoahPhaseTimings;
@@ -111,6 +112,7 @@
   friend class ShenandoahAsserts;
   friend class VMStructs;
   friend class ShenandoahGCSession;
+  friend class ShenandoahGCStateResetter;
 
 // ---------- Locks that guard important data structures in Heap
 //
--- a/src/hotspot/share/gc/shenandoah/shenandoahHeapRegion.cpp	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/share/gc/shenandoah/shenandoahHeapRegion.cpp	Thu May 23 11:07:37 2019 +0100
@@ -30,6 +30,7 @@
 #include "gc/shenandoah/shenandoahMarkingContext.inline.hpp"
 #include "gc/shenandoah/shenandoahTraversalGC.hpp"
 #include "gc/shared/space.inline.hpp"
+#include "jfr/jfrEvents.hpp"
 #include "memory/iterator.inline.hpp"
 #include "memory/resourceArea.hpp"
 #include "memory/universe.hpp"
@@ -93,7 +94,7 @@
     case _empty_uncommitted:
       do_commit();
     case _empty_committed:
-      _state = _regular;
+      set_state(_regular);
     case _regular:
     case _pinned:
       return;
@@ -114,10 +115,10 @@
     case _cset:
     case _humongous_start:
     case _humongous_cont:
-      _state = _regular;
+      set_state(_regular);
       return;
     case _pinned_cset:
-      _state = _pinned;
+      set_state(_pinned);
       return;
     case _regular:
     case _pinned:
@@ -133,7 +134,7 @@
     case _empty_uncommitted:
       do_commit();
     case _empty_committed:
-      _state = _humongous_start;
+      set_state(_humongous_start);
       return;
     default:
       report_illegal_transition("humongous start allocation");
@@ -149,7 +150,7 @@
     case _regular:
     case _humongous_start:
     case _humongous_cont:
-      _state = _humongous_start;
+      set_state(_humongous_start);
       return;
     default:
       report_illegal_transition("humongous start bypass");
@@ -162,7 +163,7 @@
     case _empty_uncommitted:
       do_commit();
     case _empty_committed:
-      _state = _humongous_cont;
+     set_state(_humongous_cont);
       return;
     default:
       report_illegal_transition("humongous continuation allocation");
@@ -178,7 +179,7 @@
     case _regular:
     case _humongous_start:
     case _humongous_cont:
-      _state = _humongous_cont;
+      set_state(_humongous_cont);
       return;
     default:
       report_illegal_transition("humongous continuation bypass");
@@ -190,14 +191,14 @@
   switch (_state) {
     case _regular:
       assert (_critical_pins == 0, "sanity");
-      _state = _pinned;
+      set_state(_pinned);
     case _pinned_cset:
     case _pinned:
       _critical_pins++;
       return;
     case _humongous_start:
       assert (_critical_pins == 0, "sanity");
-      _state = _pinned_humongous_start;
+      set_state(_pinned_humongous_start);
     case _pinned_humongous_start:
       _critical_pins++;
       return;
@@ -219,7 +220,7 @@
       assert (_critical_pins > 0, "sanity");
       _critical_pins--;
       if (_critical_pins == 0) {
-        _state = _regular;
+        set_state(_regular);
       }
       return;
     case _regular:
@@ -231,14 +232,14 @@
       assert (_critical_pins > 0, "sanity");
       _critical_pins--;
       if (_critical_pins == 0) {
-        _state = _cset;
+        set_state(_cset);
       }
       return;
     case _pinned_humongous_start:
       assert (_critical_pins > 0, "sanity");
       _critical_pins--;
       if (_critical_pins == 0) {
-        _state = _humongous_start;
+        set_state(_humongous_start);
       }
       return;
     default:
@@ -250,7 +251,7 @@
   _heap->assert_heaplock_owned_by_current_thread();
   switch (_state) {
     case _regular:
-      _state = _cset;
+      set_state(_cset);
     case _cset:
       return;
     default:
@@ -268,7 +269,7 @@
       // Reclaiming humongous regions
     case _regular:
       // Immediate region reclaim
-      _state = _trash;
+      set_state(_trash);
       return;
     default:
       report_illegal_transition("trashing");
@@ -287,7 +288,7 @@
   _heap->assert_heaplock_owned_by_current_thread();
   switch (_state) {
     case _trash:
-      _state = _empty_committed;
+      set_state(_empty_committed);
       _empty_time = os::elapsedTime();
       return;
     default:
@@ -300,7 +301,7 @@
   switch (_state) {
     case _empty_committed:
       do_uncommit();
-      _state = _empty_uncommitted;
+      set_state(_empty_uncommitted);
       return;
     default:
       report_illegal_transition("uncommiting");
@@ -314,7 +315,7 @@
   switch (_state) {
     case _empty_uncommitted:
       do_commit();
-      _state = _empty_committed;
+      set_state(_empty_committed);
       return;
     default:
       report_illegal_transition("commit bypass");
@@ -679,3 +680,16 @@
   }
   _heap->decrease_committed(ShenandoahHeapRegion::region_size_bytes());
 }
+
+void ShenandoahHeapRegion::set_state(RegionState to) {
+  EventShenandoahHeapRegionStateChange evt;
+  if (evt.should_commit()){
+    evt.set_index((unsigned)region_number());
+    evt.set_start((uintptr_t)bottom());
+    evt.set_used(used());
+    evt.set_from(_state);
+    evt.set_to(to);
+    evt.commit();
+  }
+  _state = to;
+}
--- a/src/hotspot/share/gc/shenandoah/shenandoahHeapRegion.hpp	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/share/gc/shenandoah/shenandoahHeapRegion.hpp	Thu May 23 11:07:37 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2018, Red Hat, Inc. All rights reserved.
+ * Copyright (c) 2013, 2019, Red Hat, Inc. All rights reserved.
  *
  * 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
@@ -32,9 +32,11 @@
 #include "utilities/sizes.hpp"
 
 class VMStructs;
+class ShenandoahHeapRegionStateConstant;
 
 class ShenandoahHeapRegion : public ContiguousSpace {
   friend class VMStructs;
+  friend class ShenandoahHeapRegionStateConstant;
 private:
   /*
     Region state is described by a state machine. Transitions are guarded by
@@ -114,10 +116,11 @@
     _cset,                    // region is in collection set
     _pinned,                  // region is pinned
     _pinned_cset,             // region is pinned and in cset (evac failure path)
-    _trash                    // region contains only trash
+    _trash,                   // region contains only trash
+    _REGION_STATES_NUM        // last
   };
 
-  const char* region_state_to_string(RegionState s) const {
+  static const char* region_state_to_string(RegionState s) {
     switch (s) {
       case _empty_uncommitted:       return "Empty Uncommitted";
       case _empty_committed:         return "Empty Committed";
@@ -157,6 +160,10 @@
   void report_illegal_transition(const char* method);
 
 public:
+  static const int region_states_num() {
+    return _REGION_STATES_NUM;
+  }
+
   // Allowed transitions from the outside code:
   void make_regular_allocation();
   void make_regular_bypass();
@@ -424,6 +431,8 @@
   void oop_iterate_humongous(OopIterateClosure* cl);
 
   inline void internal_increase_live_data(size_t s);
+
+  void set_state(RegionState to);
 };
 
 #endif // SHARE_GC_SHENANDOAH_SHENANDOAHHEAPREGION_HPP
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/shenandoah/shenandoahJfrSupport.cpp	Thu May 23 11:07:37 2019 +0100
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2019, Red Hat, Inc. All rights reserved.
+ *
+ * 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.
+ *
+ */
+
+#include "precompiled.hpp"
+#include "gc/shenandoah/shenandoahHeap.hpp"
+#include "gc/shenandoah/shenandoahHeapRegion.hpp"
+#include "gc/shenandoah/shenandoahJfrSupport.hpp"
+#include "jfr/jfrEvents.hpp"
+#if INCLUDE_JFR
+#include "jfr/metadata/jfrSerializer.hpp"
+#endif
+
+#if INCLUDE_JFR
+
+class ShenandoahHeapRegionStateConstant : public JfrSerializer {
+  friend class ShenandoahHeapRegion;
+public:
+  virtual void serialize(JfrCheckpointWriter& writer) {
+    static const u4 nof_entries = ShenandoahHeapRegion::region_states_num();
+    writer.write_count(nof_entries);
+    for (u4 i = 0; i < nof_entries; ++i) {
+      writer.write_key(i);
+      writer.write(ShenandoahHeapRegion::region_state_to_string((ShenandoahHeapRegion::RegionState)i));
+    }
+  }
+};
+
+void ShenandoahJFRSupport::register_jfr_type_serializers() {
+  JfrSerializer::register_serializer(TYPE_SHENANDOAHHEAPREGIONSTATE,
+                                     false,
+                                     true,
+                                     new ShenandoahHeapRegionStateConstant());
+}
+#endif
+
+class ShenandoahDumpHeapRegionInfoClosure : public ShenandoahHeapRegionClosure {
+public:
+  virtual void heap_region_do(ShenandoahHeapRegion* r) {
+    EventShenandoahHeapRegionInformation evt;
+    evt.set_index((unsigned)r->region_number());
+    evt.set_state((u8)r->state());
+    evt.set_start((uintptr_t)r->bottom());
+    evt.set_used(r->used());
+    evt.commit();
+  }
+};
+
+void VM_ShenandoahSendHeapRegionInfoEvents::doit() {
+  ShenandoahDumpHeapRegionInfoClosure c;
+  ShenandoahHeap::heap()->heap_region_iterate(&c);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/shenandoah/shenandoahJfrSupport.hpp	Thu May 23 11:07:37 2019 +0100
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2019, Red Hat, Inc. All rights reserved.
+ *
+ * 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.
+ *
+ */
+
+#ifndef SHARE_GC_SHENANDOAH_SHENANDOAHJFRSUPPORT_HPP
+#define SHARE_GC_SHENANDOAH_SHENANDOAHJFRSUPPORT_HPP
+
+#include "runtime/vmOperations.hpp"
+
+class VM_ShenandoahSendHeapRegionInfoEvents : public VM_Operation {
+public:
+  virtual void doit();
+  virtual VMOp_Type type() const { return VMOp_HeapIterateOperation; }
+};
+
+class ShenandoahJFRSupport {
+public:
+  static void register_jfr_type_serializers();
+};
+
+#endif // SHARE_VM_GC_SHENANDOAH_SHENANDOAHJFRSUPPORT_HPP
--- a/src/hotspot/share/gc/shenandoah/shenandoahMarkCompact.cpp	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/share/gc/shenandoah/shenandoahMarkCompact.cpp	Thu May 23 11:07:37 2019 +0100
@@ -561,22 +561,16 @@
 
 class ShenandoahAdjustRootPointersTask : public AbstractGangTask {
 private:
-  ShenandoahRootProcessor* _rp;
+  ShenandoahRootAdjuster* _rp;
 
 public:
-  ShenandoahAdjustRootPointersTask(ShenandoahRootProcessor* rp) :
+  ShenandoahAdjustRootPointersTask(ShenandoahRootAdjuster* rp) :
     AbstractGangTask("Shenandoah Adjust Root Pointers Task"),
     _rp(rp) {}
 
   void work(uint worker_id) {
     ShenandoahAdjustPointersClosure cl;
-    CLDToOopClosure adjust_cld_closure(&cl, ClassLoaderData::_claim_strong);
-    MarkingCodeBlobClosure adjust_code_closure(&cl,
-                                             CodeBlobToOopClosure::FixRelocations);
-
-    _rp->update_all_roots<AlwaysTrueClosure>(&cl,
-                                             &adjust_cld_closure,
-                                             &adjust_code_closure, NULL, worker_id);
+    _rp->roots_do(worker_id, &cl);
   }
 };
 
@@ -592,7 +586,7 @@
 #if COMPILER2_OR_JVMCI
     DerivedPointerTable::clear();
 #endif
-    ShenandoahRootProcessor rp(heap, nworkers, ShenandoahPhaseTimings::full_gc_roots);
+    ShenandoahRootAdjuster rp(nworkers, ShenandoahPhaseTimings::full_gc_roots);
     ShenandoahAdjustRootPointersTask task(&rp);
     workers->run_task(&task);
 #if COMPILER2_OR_JVMCI
--- a/src/hotspot/share/gc/shenandoah/shenandoahRootProcessor.cpp	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/share/gc/shenandoah/shenandoahRootProcessor.cpp	Thu May 23 11:07:37 2019 +0100
@@ -28,8 +28,9 @@
 #include "classfile/systemDictionary.hpp"
 #include "code/codeCache.hpp"
 #include "gc/shenandoah/shenandoahClosures.inline.hpp"
-#include "gc/shenandoah/shenandoahRootProcessor.hpp"
+#include "gc/shenandoah/shenandoahRootProcessor.inline.hpp"
 #include "gc/shenandoah/shenandoahHeap.hpp"
+#include "gc/shenandoah/shenandoahHeuristics.hpp"
 #include "gc/shenandoah/shenandoahPhaseTimings.hpp"
 #include "gc/shenandoah/shenandoahStringDedup.hpp"
 #include "gc/shenandoah/shenandoahTimingTracker.hpp"
@@ -43,248 +44,157 @@
 #include "runtime/thread.hpp"
 #include "services/management.hpp"
 
-ShenandoahRootProcessor::ShenandoahRootProcessor(ShenandoahHeap* heap, uint n_workers,
-                                                 ShenandoahPhaseTimings::Phase phase) :
-  _process_strong_tasks(new SubTasksDone(SHENANDOAH_RP_PS_NumElements)),
-  _srs(n_workers),
-  _phase(phase),
-  _coderoots_all_iterator(ShenandoahCodeRoots::iterator()),
-  _weak_processor_timings(n_workers),
-  _weak_processor_task(&_weak_processor_timings, n_workers),
-  _processed_weak_roots(false) {
-  heap->phase_timings()->record_workers_start(_phase);
+ShenandoahSerialRoot::ShenandoahSerialRoot(ShenandoahSerialRoot::OopsDo oops_do, ShenandoahPhaseTimings::GCParPhases phase) :
+  _claimed(false), _oops_do(oops_do), _phase(phase) {
+}
+
+void ShenandoahSerialRoot::oops_do(OopClosure* cl, uint worker_id) {
+  if (!_claimed && Atomic::cmpxchg(true, &_claimed, false) == false) {
+    ShenandoahWorkerTimings* worker_times = ShenandoahHeap::heap()->phase_timings()->worker_times();
+    ShenandoahWorkerTimingsTracker timer(worker_times, _phase, worker_id);
+    _oops_do(cl);
+  }
+}
+
+ShenandoahSerialRoots::ShenandoahSerialRoots() :
+  _universe_root(&Universe::oops_do, ShenandoahPhaseTimings::UniverseRoots),
+  _object_synchronizer_root(&ObjectSynchronizer::oops_do, ShenandoahPhaseTimings::ObjectSynchronizerRoots),
+  _management_root(&Management::oops_do, ShenandoahPhaseTimings::ManagementRoots),
+  _system_dictionary_root(&SystemDictionary::oops_do, ShenandoahPhaseTimings::SystemDictionaryRoots),
+  _jvmti_root(&JvmtiExport::oops_do, ShenandoahPhaseTimings::JVMTIRoots),
+  _jni_handle_root(&JNIHandles::oops_do, ShenandoahPhaseTimings::JNIRoots) {
+}
+
+void ShenandoahSerialRoots::oops_do(OopClosure* cl, uint worker_id) {
+  _universe_root.oops_do(cl, worker_id);
+  _object_synchronizer_root.oops_do(cl, worker_id);
+  _management_root.oops_do(cl, worker_id);
+  _system_dictionary_root.oops_do(cl, worker_id);
+  _jvmti_root.oops_do(cl, worker_id);
+  _jni_handle_root.oops_do(cl, worker_id);
+}
 
+ShenandoahThreadRoots::ShenandoahThreadRoots(bool is_par) : _is_par(is_par) {
+  Threads::change_thread_claim_token();
+}
+
+void ShenandoahThreadRoots::oops_do(OopClosure* oops_cl, CodeBlobClosure* code_cl, uint worker_id) {
+  ShenandoahWorkerTimings* worker_times = ShenandoahHeap::heap()->phase_timings()->worker_times();
+  ShenandoahWorkerTimingsTracker timer(worker_times, ShenandoahPhaseTimings::ThreadRoots, worker_id);
+  ResourceMark rm;
+  Threads::possibly_parallel_oops_do(_is_par, oops_cl, code_cl);
+}
+
+void ShenandoahThreadRoots::threads_do(ThreadClosure* tc, uint worker_id) {
+  ShenandoahWorkerTimings* worker_times = ShenandoahHeap::heap()->phase_timings()->worker_times();
+  ShenandoahWorkerTimingsTracker timer(worker_times, ShenandoahPhaseTimings::ThreadRoots, worker_id);
+  ResourceMark rm;
+  Threads::possibly_parallel_threads_do(_is_par, tc);
+}
+
+ShenandoahThreadRoots::~ShenandoahThreadRoots() {
+  Threads::assert_all_threads_claimed();
+}
+
+ShenandoahWeakRoots::ShenandoahWeakRoots(uint n_workers) :
+  _process_timings(n_workers),
+  _task(&_process_timings, n_workers) {
+}
+
+ShenandoahWeakRoots::~ShenandoahWeakRoots() {
+  ShenandoahWorkerTimings* worker_times = ShenandoahHeap::heap()->phase_timings()->worker_times();
+  ShenandoahTimingConverter::weak_processing_timing_to_shenandoah_timing(&_process_timings,
+                                                                         worker_times);
+}
+
+ShenandoahStringDedupRoots::ShenandoahStringDedupRoots() {
   if (ShenandoahStringDedup::is_enabled()) {
     StringDedup::gc_prologue(false);
   }
 }
 
-ShenandoahRootProcessor::~ShenandoahRootProcessor() {
-  delete _process_strong_tasks;
+ShenandoahStringDedupRoots::~ShenandoahStringDedupRoots() {
   if (ShenandoahStringDedup::is_enabled()) {
     StringDedup::gc_epilogue();
   }
-
-  if (_processed_weak_roots) {
-    assert(_weak_processor_timings.max_threads() == n_workers(), "Must match");
-    ShenandoahWorkerTimings* worker_times = ShenandoahHeap::heap()->phase_timings()->worker_times();
-    ShenandoahTimingConverter::weak_processing_timing_to_shenandoah_timing(&_weak_processor_timings,
-                                                                           worker_times);
-  }
-
-  ShenandoahHeap::heap()->phase_timings()->record_workers_end(_phase);
-}
-
-void ShenandoahRootProcessor::process_strong_roots(OopClosure* oops,
-                                                   CLDClosure* clds,
-                                                   CodeBlobClosure* blobs,
-                                                   ThreadClosure* thread_cl,
-                                                   uint worker_id) {
-
-  process_java_roots(oops, clds, NULL, blobs, thread_cl, worker_id);
-  process_vm_roots(oops, worker_id);
-
-  _process_strong_tasks->all_tasks_completed(n_workers());
 }
 
-void ShenandoahRootProcessor::process_all_roots(OopClosure* oops,
-                                                CLDClosure* clds,
-                                                CodeBlobClosure* blobs,
-                                                ThreadClosure* thread_cl,
-                                                uint worker_id) {
-
-  ShenandoahWorkerTimings* worker_times = ShenandoahHeap::heap()->phase_timings()->worker_times();
-  process_java_roots(oops, clds, clds, blobs, thread_cl, worker_id);
-  process_vm_roots(oops, worker_id);
-
-  if (blobs != NULL) {
-    ShenandoahWorkerTimingsTracker timer(worker_times, ShenandoahPhaseTimings::CodeCacheRoots, worker_id);
-    _coderoots_all_iterator.possibly_parallel_blobs_do(blobs);
-  }
-
-  _process_strong_tasks->all_tasks_completed(n_workers());
-
-}
-
-class ShenandoahParallelOopsDoThreadClosure : public ThreadClosure {
-private:
-  OopClosure* _f;
-  CodeBlobClosure* _cf;
-  ThreadClosure* _thread_cl;
-public:
-  ShenandoahParallelOopsDoThreadClosure(OopClosure* f, CodeBlobClosure* cf, ThreadClosure* thread_cl) :
-    _f(f), _cf(cf), _thread_cl(thread_cl) {}
-
-  void do_thread(Thread* t) {
-    if (_thread_cl != NULL) {
-      _thread_cl->do_thread(t);
-    }
-    t->oops_do(_f, _cf);
-  }
-};
-
-void ShenandoahRootProcessor::process_java_roots(OopClosure* strong_roots,
-                                                 CLDClosure* strong_clds,
-                                                 CLDClosure* weak_clds,
-                                                 CodeBlobClosure* strong_code,
-                                                 ThreadClosure* thread_cl,
-                                                 uint worker_id)
-{
-  ShenandoahWorkerTimings* worker_times = ShenandoahHeap::heap()->phase_timings()->worker_times();
-  // Iterating over the CLDG and the Threads are done early to allow us to
-  // first process the strong CLDs and nmethods and then, after a barrier,
-  // let the thread process the weak CLDs and nmethods.
-  {
-    ShenandoahWorkerTimingsTracker timer(worker_times, ShenandoahPhaseTimings::CLDGRoots, worker_id);
-    _cld_iterator.root_cld_do(strong_clds, weak_clds);
-  }
-
-  {
-    ShenandoahWorkerTimingsTracker timer(worker_times, ShenandoahPhaseTimings::ThreadRoots, worker_id);
-    bool is_par = n_workers() > 1;
-    ResourceMark rm;
-    ShenandoahParallelOopsDoThreadClosure cl(strong_roots, strong_code, thread_cl);
-    Threads::possibly_parallel_threads_do(is_par, &cl);
+void ShenandoahStringDedupRoots::oops_do(BoolObjectClosure* is_alive, OopClosure* keep_alive, uint worker_id) {
+  if (ShenandoahStringDedup::is_enabled()) {
+    ShenandoahStringDedup::parallel_oops_do(is_alive, keep_alive, worker_id);
   }
 }
 
-void ShenandoahRootProcessor::process_vm_roots(OopClosure* strong_roots,
-                                               uint worker_id) {
-  ShenandoahWorkerTimings* worker_times = ShenandoahHeap::heap()->phase_timings()->worker_times();
-  if (_process_strong_tasks->try_claim_task(SHENANDOAH_RP_PS_Universe_oops_do)) {
-    ShenandoahWorkerTimingsTracker timer(worker_times, ShenandoahPhaseTimings::UniverseRoots, worker_id);
-    Universe::oops_do(strong_roots);
-  }
-
-  if (_process_strong_tasks->try_claim_task(SHENANDOAH_RP_PS_JNIHandles_oops_do)) {
-    ShenandoahWorkerTimingsTracker timer(worker_times, ShenandoahPhaseTimings::JNIRoots, worker_id);
-    JNIHandles::oops_do(strong_roots);
-  }
-  if (_process_strong_tasks->try_claim_task(SHENANDOAH_RP_PS_Management_oops_do)) {
-    ShenandoahWorkerTimingsTracker timer(worker_times, ShenandoahPhaseTimings::ManagementRoots, worker_id);
-    Management::oops_do(strong_roots);
-  }
-  if (_process_strong_tasks->try_claim_task(SHENANDOAH_RP_PS_jvmti_oops_do)) {
-    ShenandoahWorkerTimingsTracker timer(worker_times, ShenandoahPhaseTimings::JVMTIRoots, worker_id);
-    JvmtiExport::oops_do(strong_roots);
-  }
-  if (_process_strong_tasks->try_claim_task(SHENANDOAH_RP_PS_SystemDictionary_oops_do)) {
-    ShenandoahWorkerTimingsTracker timer(worker_times, ShenandoahPhaseTimings::SystemDictionaryRoots, worker_id);
-    SystemDictionary::oops_do(strong_roots);
-  }
-
-  {
-    ShenandoahWorkerTimingsTracker timer(worker_times, ShenandoahPhaseTimings::ObjectSynchronizerRoots, worker_id);
-    if (_process_strong_tasks->try_claim_task(SHENANDOAH_RP_PS_ObjectSynchronizer_oops_do)) {
-      ObjectSynchronizer::oops_do(strong_roots);
-    }
-  }
-}
-
-uint ShenandoahRootProcessor::n_workers() const {
-  return _srs.n_threads();
-}
-
-ShenandoahRootEvacuator::ShenandoahRootEvacuator(ShenandoahHeap* heap, uint n_workers, ShenandoahPhaseTimings::Phase phase) :
-  _evacuation_tasks(new SubTasksDone(SHENANDOAH_EVAC_NumElements)),
-  _srs(n_workers),
-  _phase(phase),
-  _coderoots_cset_iterator(ShenandoahCodeRoots::cset_iterator()),
-  _weak_processor_timings(n_workers),
-  _weak_processor_task(&_weak_processor_timings, n_workers) {
-  heap->phase_timings()->record_workers_start(_phase);
-  if (ShenandoahStringDedup::is_enabled()) {
-    StringDedup::gc_prologue(false);
-  }
-}
-
-ShenandoahRootEvacuator::~ShenandoahRootEvacuator() {
-  delete _evacuation_tasks;
-  if (ShenandoahStringDedup::is_enabled()) {
-    StringDedup::gc_epilogue();
-  }
-
-  ShenandoahWorkerTimings* worker_times = ShenandoahHeap::heap()->phase_timings()->worker_times();
-  assert(_weak_processor_timings.max_threads() == n_workers(), "Must match");
-  ShenandoahTimingConverter::weak_processing_timing_to_shenandoah_timing(&_weak_processor_timings,
-                                                                         worker_times);
-
-  ShenandoahHeap::heap()->phase_timings()->record_workers_end(_phase);
-}
-
-void ShenandoahRootEvacuator::process_evacuate_roots(OopClosure* oops,
-                                                     CodeBlobClosure* blobs,
-                                                     uint worker_id) {
-
-  AlwaysTrueClosure always_true;
-  ShenandoahWorkerTimings* worker_times = ShenandoahHeap::heap()->phase_timings()->worker_times();
-  {
-    bool is_par = n_workers() > 1;
-    ResourceMark rm;
-    ShenandoahWorkerTimingsTracker timer(worker_times, ShenandoahPhaseTimings::ThreadRoots, worker_id);
-    Threads::possibly_parallel_oops_do(is_par, oops, NULL);
-  }
-
-  {
-    ShenandoahWorkerTimingsTracker timer(worker_times, ShenandoahPhaseTimings::CLDGRoots, worker_id);
-    CLDToOopClosure clds(oops, ClassLoaderData::_claim_strong);
-    _cld_iterator.root_cld_do(&clds, &clds);
-  }
-
-  if (blobs != NULL) {
-    ShenandoahWorkerTimingsTracker timer(worker_times, ShenandoahPhaseTimings::CodeCacheRoots, worker_id);
-    _coderoots_cset_iterator.possibly_parallel_blobs_do(blobs);
-  }
-
-  if (ShenandoahStringDedup::is_enabled()) {
-    ShenandoahStringDedup::parallel_oops_do(&always_true, oops, worker_id);
-  }
-
-  if (_evacuation_tasks->try_claim_task(SHENANDOAH_EVAC_Universe_oops_do)) {
-    ShenandoahWorkerTimingsTracker timer(worker_times, ShenandoahPhaseTimings::UniverseRoots, worker_id);
-    Universe::oops_do(oops);
-  }
-
-  if (_evacuation_tasks->try_claim_task(SHENANDOAH_EVAC_Management_oops_do)) {
-    ShenandoahWorkerTimingsTracker timer(worker_times, ShenandoahPhaseTimings::ManagementRoots, worker_id);
-    Management::oops_do(oops);
-  }
-
-  if (_evacuation_tasks->try_claim_task(SHENANDOAH_EVAC_jvmti_oops_do)) {
-    ShenandoahWorkerTimingsTracker timer(worker_times, ShenandoahPhaseTimings::JVMTIRoots, worker_id);
-    JvmtiExport::oops_do(oops);
-    ShenandoahForwardedIsAliveClosure is_alive;
-    JvmtiExport::weak_oops_do(&is_alive, oops);
-  }
-
-  if (_evacuation_tasks->try_claim_task(SHENANDOAH_EVAC_JNIHandles_oops_do)) {
-    ShenandoahWorkerTimingsTracker timer(worker_times, ShenandoahPhaseTimings::JNIRoots, worker_id);
-    JNIHandles::oops_do(oops);
-  }
-
-  if (_evacuation_tasks->try_claim_task(SHENANDOAH_EVAC_SystemDictionary_oops_do)) {
-    ShenandoahWorkerTimingsTracker timer(worker_times, ShenandoahPhaseTimings::SystemDictionaryRoots, worker_id);
-    SystemDictionary::oops_do(oops);
-  }
-
-  if (_evacuation_tasks->try_claim_task(SHENANDOAH_EVAC_ObjectSynchronizer_oops_do)) {
-    ShenandoahWorkerTimingsTracker timer(worker_times, ShenandoahPhaseTimings::ObjectSynchronizerRoots, worker_id);
-    ObjectSynchronizer::oops_do(oops);
-  }
-
-  _weak_processor_task.work<AlwaysTrueClosure, OopClosure>(worker_id, &always_true, oops);
-}
-
-uint ShenandoahRootEvacuator::n_workers() const {
-  return _srs.n_threads();
-}
-
-// Implemenation of ParallelCLDRootIterator
-ParallelCLDRootIterator::ParallelCLDRootIterator() {
-  assert(SafepointSynchronize::is_at_safepoint(), "Must at safepoint");
+ShenandoahClassLoaderDataRoots::ShenandoahClassLoaderDataRoots() {
   ClassLoaderDataGraph::clear_claimed_marks();
 }
 
-void ParallelCLDRootIterator::root_cld_do(CLDClosure* strong, CLDClosure* weak) {
-    ClassLoaderDataGraph::roots_cld_do(strong, weak);
+void ShenandoahClassLoaderDataRoots::clds_do(CLDClosure* strong_clds, CLDClosure* weak_clds, uint worker_id) {
+  ShenandoahWorkerTimings* worker_times = ShenandoahHeap::heap()->phase_timings()->worker_times();
+  ShenandoahWorkerTimingsTracker timer(worker_times, ShenandoahPhaseTimings::CLDGRoots, worker_id);
+  ClassLoaderDataGraph::roots_cld_do(strong_clds, weak_clds);
+}
+
+ShenandoahRootProcessor::ShenandoahRootProcessor(ShenandoahPhaseTimings::Phase phase) :
+  _heap(ShenandoahHeap::heap()),
+  _phase(phase) {
+  assert(SafepointSynchronize::is_at_safepoint(), "Must at safepoint");
+  _heap->phase_timings()->record_workers_start(_phase);
+}
+
+ShenandoahRootProcessor::~ShenandoahRootProcessor() {
+  assert(SafepointSynchronize::is_at_safepoint(), "Must at safepoint");
+  _heap->phase_timings()->record_workers_end(_phase);
+}
+
+ShenandoahRootEvacuator::ShenandoahRootEvacuator(uint n_workers, ShenandoahPhaseTimings::Phase phase) :
+  ShenandoahRootProcessor(phase),
+  _thread_roots(n_workers > 1),
+  _weak_roots(n_workers) {
 }
+
+void ShenandoahRootEvacuator::roots_do(uint worker_id, OopClosure* oops) {
+  MarkingCodeBlobClosure blobsCl(oops, CodeBlobToOopClosure::FixRelocations);
+  CLDToOopClosure clds(oops, ClassLoaderData::_claim_strong);
+  CLDToOopClosure* weak_clds = ShenandoahHeap::heap()->unload_classes() ? NULL : &clds;
+
+  AlwaysTrueClosure always_true;
+
+  _serial_roots.oops_do(oops, worker_id);
+
+  _thread_roots.oops_do(oops, NULL, worker_id);
+  _cld_roots.clds_do(&clds, &clds, worker_id);
+  _code_roots.code_blobs_do(&blobsCl, worker_id);
+
+  _weak_roots.oops_do<AlwaysTrueClosure, OopClosure>(&always_true, oops, worker_id);
+  _dedup_roots.oops_do(&always_true, oops, worker_id);
+}
+
+ShenandoahRootUpdater::ShenandoahRootUpdater(uint n_workers, ShenandoahPhaseTimings::Phase phase, bool update_code_cache) :
+  ShenandoahRootProcessor(phase),
+  _thread_roots(n_workers > 1),
+  _weak_roots(n_workers),
+  _update_code_cache(update_code_cache) {
+}
+
+ShenandoahRootAdjuster::ShenandoahRootAdjuster(uint n_workers, ShenandoahPhaseTimings::Phase phase) :
+  ShenandoahRootProcessor(phase),
+  _thread_roots(n_workers > 1),
+  _weak_roots(n_workers) {
+  assert(ShenandoahHeap::heap()->is_full_gc_in_progress(), "Full GC only");
+}
+
+void ShenandoahRootAdjuster::roots_do(uint worker_id, OopClosure* oops) {
+  CodeBlobToOopClosure adjust_code_closure(oops, CodeBlobToOopClosure::FixRelocations);
+  CLDToOopClosure adjust_cld_closure(oops, ClassLoaderData::_claim_strong);
+  AlwaysTrueClosure always_true;
+
+  _serial_roots.oops_do(oops, worker_id);
+
+  _thread_roots.oops_do(oops, NULL, worker_id);
+  _cld_roots.clds_do(&adjust_cld_closure, NULL, worker_id);
+  _code_roots.code_blobs_do(&adjust_code_closure, worker_id);
+
+  _weak_roots.oops_do<AlwaysTrueClosure, OopClosure>(&always_true, oops, worker_id);
+  _dedup_roots.oops_do(&always_true, oops, worker_id);
+}
--- a/src/hotspot/share/gc/shenandoah/shenandoahRootProcessor.hpp	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/share/gc/shenandoah/shenandoahRootProcessor.hpp	Thu May 23 11:07:37 2019 +0100
@@ -36,110 +36,164 @@
 #include "memory/allocation.hpp"
 #include "memory/iterator.hpp"
 
-class ParallelCLDRootIterator {
+class ShenandoahSerialRoot {
+public:
+  typedef void (*OopsDo)(OopClosure*);
+private:
+  volatile bool                             _claimed;
+  const OopsDo                              _oops_do;
+  const ShenandoahPhaseTimings::GCParPhases _phase;
+
 public:
-  ParallelCLDRootIterator();
-  void root_cld_do(CLDClosure* strong, CLDClosure* weak);
+  ShenandoahSerialRoot(OopsDo oops_do, ShenandoahPhaseTimings::GCParPhases);
+  void oops_do(OopClosure* cl, uint worker_id);
+};
+
+class ShenandoahSerialRoots {
+private:
+  ShenandoahSerialRoot  _universe_root;
+  ShenandoahSerialRoot  _object_synchronizer_root;
+  ShenandoahSerialRoot  _management_root;
+  ShenandoahSerialRoot  _system_dictionary_root;
+  ShenandoahSerialRoot  _jvmti_root;
+  ShenandoahSerialRoot  _jni_handle_root;
+public:
+  ShenandoahSerialRoots();
+  void oops_do(OopClosure* cl, uint worker_id);
+};
+
+class ShenandoahThreadRoots {
+private:
+  const bool _is_par;
+public:
+  ShenandoahThreadRoots(bool is_par);
+  ~ShenandoahThreadRoots();
+
+  void oops_do(OopClosure* oops_cl, CodeBlobClosure* code_cl, uint worker_id);
+  void threads_do(ThreadClosure* tc, uint worker_id);
 };
 
-enum Shenandoah_process_roots_tasks {
-  SHENANDOAH_RP_PS_Universe_oops_do,
-  SHENANDOAH_RP_PS_JNIHandles_oops_do,
-  SHENANDOAH_RP_PS_ObjectSynchronizer_oops_do,
-  SHENANDOAH_RP_PS_Management_oops_do,
-  SHENANDOAH_RP_PS_SystemDictionary_oops_do,
-  SHENANDOAH_RP_PS_jvmti_oops_do,
-  // Leave this one last.
-  SHENANDOAH_RP_PS_NumElements
+class ShenandoahWeakRoots {
+private:
+  WeakProcessorPhaseTimes _process_timings;
+  WeakProcessor::Task     _task;
+public:
+  ShenandoahWeakRoots(uint n_workers);
+  ~ShenandoahWeakRoots();
+
+  template <typename IsAlive, typename KeepAlive>
+  void oops_do(IsAlive* is_alive, KeepAlive* keep_alive, uint worker_id);
+};
+
+class ShenandoahStringDedupRoots {
+public:
+  ShenandoahStringDedupRoots();
+  ~ShenandoahStringDedupRoots();
+
+  void oops_do(BoolObjectClosure* is_alive, OopClosure* keep_alive, uint worker_id);
+};
+
+template <typename ITR>
+class ShenandoahCodeCacheRoots {
+private:
+  ITR _coderoots_iterator;
+public:
+  ShenandoahCodeCacheRoots();
+  ~ShenandoahCodeCacheRoots();
+
+  void code_blobs_do(CodeBlobClosure* blob_cl, uint worker_id);
+};
+
+class ShenandoahClassLoaderDataRoots {
+public:
+  ShenandoahClassLoaderDataRoots();
+
+  void clds_do(CLDClosure* strong_clds, CLDClosure* weak_clds, uint worker_id);
 };
 
 class ShenandoahRootProcessor : public StackObj {
-  SubTasksDone* _process_strong_tasks;
-  StrongRootsScope _srs;
-  ShenandoahPhaseTimings::Phase _phase;
-  ParallelCLDRootIterator _cld_iterator;
-  ShenandoahAllCodeRootsIterator _coderoots_all_iterator;
-  CodeBlobClosure* _threads_nmethods_cl;
-  WeakProcessorPhaseTimes _weak_processor_timings;
-  WeakProcessor::Task     _weak_processor_task;
-  bool                    _processed_weak_roots;
-
-  void process_java_roots(OopClosure* scan_non_heap_roots,
-                          CLDClosure* scan_strong_clds,
-                          CLDClosure* scan_weak_clds,
-                          CodeBlobClosure* scan_strong_code,
-                          ThreadClosure* thread_cl,
-                          uint worker_i);
-
-  void process_vm_roots(OopClosure* scan_non_heap_roots,
-                        uint worker_i);
-
-  void weak_processor_timing_to_shenandoah_timing(const WeakProcessorPhases::Phase wpp,
-                                                  const ShenandoahPhaseTimings::GCParPhases spp,
-                                                  ShenandoahWorkerTimings* worker_times) const;
-
+private:
+  ShenandoahHeap* const               _heap;
+  const ShenandoahPhaseTimings::Phase _phase;
 public:
-  ShenandoahRootProcessor(ShenandoahHeap* heap, uint n_workers,
-                          ShenandoahPhaseTimings::Phase phase);
+  ShenandoahRootProcessor(ShenandoahPhaseTimings::Phase phase);
   ~ShenandoahRootProcessor();
 
-  // Apply oops, clds and blobs to all strongly reachable roots in the system.
-  // Optionally, apply class loader closure to weak clds, depending on class unloading
-  // for the particular GC cycles.
-  void process_strong_roots(OopClosure* oops,
-                            CLDClosure* clds,
-                            CodeBlobClosure* blobs,
-                            ThreadClosure* thread_cl,
-                            uint worker_id);
+  ShenandoahHeap* heap() const { return _heap; }
+};
 
-  // Apply oops, clds and blobs to strongly reachable roots in the system
-  void process_all_roots(OopClosure* oops,
-                         CLDClosure* clds,
-                         CodeBlobClosure* blobs,
-                         ThreadClosure* thread_cl,
-                         uint worker_id);
+template <typename ITR>
+class ShenandoahRootScanner : public ShenandoahRootProcessor {
+private:
+  ShenandoahSerialRoots          _serial_roots;
+  ShenandoahClassLoaderDataRoots _cld_roots;
+  ShenandoahThreadRoots          _thread_roots;
+  ShenandoahCodeCacheRoots<ITR>  _code_roots;
+public:
+  ShenandoahRootScanner(uint n_workers, ShenandoahPhaseTimings::Phase phase);
 
-  // Apply oops, clds and blobs to strongly and weakly reachable roots in the system
-  template <typename IsAlive>
-  void update_all_roots(OopClosure* oops,
-                        CLDClosure* clds,
-                        CodeBlobClosure* blobs,
-                        ThreadClosure* thread_cl,
-                        uint worker_id);
+  // Apply oops, clds and blobs to all strongly reachable roots in the system,
+  // during class unloading cycle
+  void strong_roots_do(uint worker_id, OopClosure* cl);
+  void strong_roots_do(uint worker_id, OopClosure* oops, CLDClosure* clds, CodeBlobClosure* code, ThreadClosure* tc = NULL);
 
-  // Number of worker threads used by the root processor.
-  uint n_workers() const;
+  // Apply oops, clds and blobs to all strongly reachable roots and weakly reachable
+  // roots when class unloading is disabled during this cycle
+  void roots_do(uint worker_id, OopClosure* cl);
+  void roots_do(uint worker_id, OopClosure* oops, CLDClosure* clds, CodeBlobClosure* code, ThreadClosure* tc = NULL);
 };
 
-class ShenandoahRootEvacuator : public StackObj {
-  SubTasksDone* _evacuation_tasks;
-  StrongRootsScope _srs;
-  ShenandoahPhaseTimings::Phase _phase;
-  ShenandoahCsetCodeRootsIterator _coderoots_cset_iterator;
-  ParallelCLDRootIterator _cld_iterator;
-  WeakProcessorPhaseTimes _weak_processor_timings;
-  WeakProcessor::Task     _weak_processor_task;
+typedef ShenandoahRootScanner<ShenandoahAllCodeRootsIterator> ShenandoahAllRootScanner;
+typedef ShenandoahRootScanner<ShenandoahCsetCodeRootsIterator> ShenandoahCSetRootScanner;
+
+// Evacuate all roots at a safepoint
+class ShenandoahRootEvacuator : public ShenandoahRootProcessor {
+private:
+  ShenandoahSerialRoots          _serial_roots;
+  ShenandoahClassLoaderDataRoots _cld_roots;
+  ShenandoahThreadRoots          _thread_roots;
+  ShenandoahWeakRoots            _weak_roots;
+  ShenandoahStringDedupRoots     _dedup_roots;
+  ShenandoahCodeCacheRoots<ShenandoahCsetCodeRootsIterator> _code_roots;
+
+public:
+  ShenandoahRootEvacuator(uint n_workers, ShenandoahPhaseTimings::Phase phase);
+
+  void roots_do(uint worker_id, OopClosure* oops);
+};
 
-  enum Shenandoah_evacuate_roots_tasks {
-    SHENANDOAH_EVAC_Universe_oops_do,
-    SHENANDOAH_EVAC_ObjectSynchronizer_oops_do,
-    SHENANDOAH_EVAC_Management_oops_do,
-    SHENANDOAH_EVAC_SystemDictionary_oops_do,
-    SHENANDOAH_EVAC_jvmti_oops_do,
-    SHENANDOAH_EVAC_JNIHandles_oops_do,
-    // Leave this one last.
-    SHENANDOAH_EVAC_NumElements
-  };
+// Update all roots at a safepoint
+class ShenandoahRootUpdater : public ShenandoahRootProcessor {
+private:
+  ShenandoahSerialRoots          _serial_roots;
+  ShenandoahClassLoaderDataRoots _cld_roots;
+  ShenandoahThreadRoots          _thread_roots;
+  ShenandoahWeakRoots            _weak_roots;
+  ShenandoahStringDedupRoots     _dedup_roots;
+  ShenandoahCodeCacheRoots<ShenandoahCsetCodeRootsIterator> _code_roots;
+  const bool                     _update_code_cache;
+
 public:
-  ShenandoahRootEvacuator(ShenandoahHeap* heap, uint n_workers,
-                          ShenandoahPhaseTimings::Phase phase);
-  ~ShenandoahRootEvacuator();
+  ShenandoahRootUpdater(uint n_workers, ShenandoahPhaseTimings::Phase phase, bool update_code_cache);
+
+  template<typename IsAlive, typename KeepAlive>
+  void roots_do(uint worker_id, IsAlive* is_alive, KeepAlive* keep_alive);
+};
 
-  void process_evacuate_roots(OopClosure* oops,
-                              CodeBlobClosure* blobs,
-                              uint worker_id);
+// Adjuster all roots at a safepoint during full gc
+class ShenandoahRootAdjuster : public ShenandoahRootProcessor {
+private:
+  ShenandoahSerialRoots          _serial_roots;
+  ShenandoahClassLoaderDataRoots _cld_roots;
+  ShenandoahThreadRoots          _thread_roots;
+  ShenandoahWeakRoots            _weak_roots;
+  ShenandoahStringDedupRoots     _dedup_roots;
+  ShenandoahCodeCacheRoots<ShenandoahAllCodeRootsIterator> _code_roots;
 
-  // Number of worker threads used by the root processor.
-  uint n_workers() const;
+public:
+  ShenandoahRootAdjuster(uint n_workers, ShenandoahPhaseTimings::Phase phase);
+
+  void roots_do(uint worker_id, OopClosure* oops);
 };
+
 #endif // SHARE_GC_SHENANDOAH_SHENANDOAHROOTPROCESSOR_HPP
--- a/src/hotspot/share/gc/shenandoah/shenandoahRootProcessor.inline.hpp	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/share/gc/shenandoah/shenandoahRootProcessor.inline.hpp	Thu May 23 11:07:37 2019 +0100
@@ -24,23 +24,118 @@
 #ifndef SHARE_GC_SHENANDOAH_SHENANDOAHROOTPROCESSOR_INLINE_HPP
 #define SHARE_GC_SHENANDOAH_SHENANDOAHROOTPROCESSOR_INLINE_HPP
 
+#include "gc/shenandoah/shenandoahHeuristics.hpp"
 #include "gc/shenandoah/shenandoahRootProcessor.hpp"
+#include "gc/shenandoah/shenandoahTimingTracker.hpp"
+#include "memory/resourceArea.hpp"
+
+template <typename IsAlive, typename KeepAlive>
+void ShenandoahWeakRoots::oops_do(IsAlive* is_alive, KeepAlive* keep_alive, uint worker_id) {
+  _task.work<IsAlive, KeepAlive>(worker_id, is_alive, keep_alive);
+}
+
+template <typename ITR>
+ShenandoahCodeCacheRoots<ITR>::ShenandoahCodeCacheRoots() {
+  nmethod::oops_do_marking_prologue();
+}
+
+template <typename ITR>
+void ShenandoahCodeCacheRoots<ITR>::code_blobs_do(CodeBlobClosure* blob_cl, uint worker_id) {
+  ShenandoahWorkerTimings* worker_times = ShenandoahHeap::heap()->phase_timings()->worker_times();
+  ShenandoahWorkerTimingsTracker timer(worker_times, ShenandoahPhaseTimings::CodeCacheRoots, worker_id);
+  _coderoots_iterator.possibly_parallel_blobs_do(blob_cl);
+}
+
+template <typename ITR>
+ShenandoahCodeCacheRoots<ITR>::~ShenandoahCodeCacheRoots() {
+  nmethod::oops_do_marking_epilogue();
+}
+
+class ShenandoahParallelOopsDoThreadClosure : public ThreadClosure {
+private:
+  OopClosure* _f;
+  CodeBlobClosure* _cf;
+  ThreadClosure* _thread_cl;
+public:
+  ShenandoahParallelOopsDoThreadClosure(OopClosure* f, CodeBlobClosure* cf, ThreadClosure* thread_cl) :
+    _f(f), _cf(cf), _thread_cl(thread_cl) {}
 
-template <typename IsAlive>
-void ShenandoahRootProcessor::update_all_roots(OopClosure* oops,
-                                               CLDClosure* clds,
-                                               CodeBlobClosure* blobs,
-                                               ThreadClosure* thread_cl,
-                                               uint worker_id) {
-  process_all_roots(oops, clds, blobs, thread_cl, worker_id);
+  void do_thread(Thread* t) {
+    if (_thread_cl != NULL) {
+      _thread_cl->do_thread(t);
+    }
+    t->oops_do(_f, _cf);
+  }
+};
+
+template <typename ITR>
+ShenandoahRootScanner<ITR>::ShenandoahRootScanner(uint n_workers, ShenandoahPhaseTimings::Phase phase) :
+  ShenandoahRootProcessor(phase),
+  _thread_roots(n_workers > 1) {
+}
+
+template <typename ITR>
+void ShenandoahRootScanner<ITR>::roots_do(uint worker_id, OopClosure* oops) {
+  CLDToOopClosure clds_cl(oops, ClassLoaderData::_claim_strong);
+  MarkingCodeBlobClosure blobs_cl(oops, !CodeBlobToOopClosure::FixRelocations);
+  roots_do(worker_id, oops, &clds_cl, &blobs_cl);
+}
 
-  IsAlive is_alive;
-  _weak_processor_task.work<IsAlive, OopClosure>(worker_id, &is_alive, oops);
-  _processed_weak_roots = true;
+template <typename ITR>
+void ShenandoahRootScanner<ITR>::strong_roots_do(uint worker_id, OopClosure* oops) {
+  CLDToOopClosure clds_cl(oops, ClassLoaderData::_claim_strong);
+  MarkingCodeBlobClosure blobs_cl(oops, !CodeBlobToOopClosure::FixRelocations);
+  strong_roots_do(worker_id, oops, &clds_cl, &blobs_cl);
+}
 
-  if (ShenandoahStringDedup::is_enabled()) {
-    ShenandoahStringDedup::parallel_oops_do(&is_alive, oops, worker_id);
+template <typename ITR>
+void ShenandoahRootScanner<ITR>::roots_do(uint worker_id, OopClosure* oops, CLDClosure* clds, CodeBlobClosure* code, ThreadClosure *tc) {
+  assert(!ShenandoahHeap::heap()->unload_classes() ||
+          ShenandoahHeap::heap()->heuristics()->can_do_traversal_gc(),
+          "No class unloading or traversal GC");
+  ShenandoahParallelOopsDoThreadClosure tc_cl(oops, code, tc);
+  ResourceMark rm;
+
+  _serial_roots.oops_do(oops, worker_id);
+  _cld_roots.clds_do(clds, clds, worker_id);
+  _thread_roots.threads_do(&tc_cl, worker_id);
+
+  // With ShenandoahConcurrentScanCodeRoots, we avoid scanning the entire code cache here,
+  // and instead do that in concurrent phase under the relevant lock. This saves init mark
+  // pause time.
+  if (code != NULL && !ShenandoahConcurrentScanCodeRoots) {
+    _code_roots.code_blobs_do(code, worker_id);
   }
 }
 
+template <typename ITR>
+void ShenandoahRootScanner<ITR>::strong_roots_do(uint worker_id, OopClosure* oops, CLDClosure* clds, CodeBlobClosure* code, ThreadClosure* tc) {
+  assert(ShenandoahHeap::heap()->unload_classes(), "Should be used during class unloading");
+  ShenandoahParallelOopsDoThreadClosure tc_cl(oops, code, tc);
+  ResourceMark rm;
+
+  _serial_roots.oops_do(oops, worker_id);
+  _cld_roots.clds_do(clds, NULL, worker_id);
+  _thread_roots.threads_do(&tc_cl, worker_id);
+}
+
+template <typename IsAlive, typename KeepAlive>
+void ShenandoahRootUpdater::roots_do(uint worker_id, IsAlive* is_alive, KeepAlive* keep_alive) {
+  CodeBlobToOopClosure update_blobs(keep_alive, CodeBlobToOopClosure::FixRelocations);
+  CLDToOopClosure clds(keep_alive, ClassLoaderData::_claim_strong);
+  CLDToOopClosure* weak_clds = ShenandoahHeap::heap()->unload_classes() ? NULL : &clds;
+
+  _serial_roots.oops_do(keep_alive, worker_id);
+
+  _thread_roots.oops_do(keep_alive, NULL, worker_id);
+  _cld_roots.clds_do(&clds, weak_clds, worker_id);
+
+  if(_update_code_cache) {
+    _code_roots.code_blobs_do(&update_blobs, worker_id);
+  }
+
+  _weak_roots.oops_do<IsAlive, KeepAlive>(is_alive, keep_alive, worker_id);
+  _dedup_roots.oops_do(is_alive, keep_alive, worker_id);
+}
+
 #endif // SHARE_GC_SHENANDOAH_SHENANDOAHROOTPROCESSOR_INLINE_HPP
--- a/src/hotspot/share/gc/shenandoah/shenandoahSATBMarkQueueSet.cpp	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/share/gc/shenandoah/shenandoahSATBMarkQueueSet.cpp	Thu May 23 11:07:37 2019 +0100
@@ -70,19 +70,17 @@
   }
 }
 
-bool ShenandoahSATBMarkQueue::should_enqueue_buffer() {
-  bool should_enqueue = SATBMarkQueue::should_enqueue_buffer();
-  size_t cap = capacity();
-  Thread* t = Thread::current();
-  if (ShenandoahThreadLocalData::is_force_satb_flush(t)) {
-    if (!should_enqueue && cap != index()) {
+void ShenandoahSATBMarkQueue::handle_completed_buffer() {
+  SATBMarkQueue::handle_completed_buffer();
+  if (!is_empty()) {
+    Thread* t = Thread::current();
+    if (ShenandoahThreadLocalData::is_force_satb_flush(t)) {
       // Non-empty buffer is compacted, and we decided not to enqueue it.
       // We still want to know about leftover work in that buffer eventually.
       // This avoid dealing with these leftovers during the final-mark, after
       // the buffers are drained completely. See JDK-8205353 for more discussion.
-      should_enqueue = true;
+      ShenandoahThreadLocalData::set_force_satb_flush(t, false);
+      enqueue_completed_buffer();
     }
-    ShenandoahThreadLocalData::set_force_satb_flush(t, false);
   }
-  return should_enqueue;
 }
--- a/src/hotspot/share/gc/shenandoah/shenandoahSATBMarkQueueSet.hpp	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/share/gc/shenandoah/shenandoahSATBMarkQueueSet.hpp	Thu May 23 11:07:37 2019 +0100
@@ -30,9 +30,10 @@
 #include "runtime/thread.hpp"
 
 class ShenandoahSATBMarkQueue: public SATBMarkQueue {
+protected:
+  virtual void handle_completed_buffer();
 public:
   ShenandoahSATBMarkQueue(SATBMarkQueueSet* qset) : SATBMarkQueue(qset) {}
-  virtual bool should_enqueue_buffer();
 };
 
 class ShenandoahSATBMarkQueueSet : public SATBMarkQueueSet {
--- a/src/hotspot/share/gc/shenandoah/shenandoahTraversalGC.cpp	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/share/gc/shenandoah/shenandoahTraversalGC.cpp	Thu May 23 11:07:37 2019 +0100
@@ -161,15 +161,16 @@
 
 class ShenandoahInitTraversalCollectionTask : public AbstractGangTask {
 private:
-  ShenandoahRootProcessor* _rp;
+  ShenandoahCSetRootScanner* _rp;
   ShenandoahHeap* _heap;
   ShenandoahCsetCodeRootsIterator* _cset_coderoots;
+  ShenandoahStringDedupRoots       _dedup_roots;
+
 public:
-  ShenandoahInitTraversalCollectionTask(ShenandoahRootProcessor* rp, ShenandoahCsetCodeRootsIterator* cset_coderoots) :
+  ShenandoahInitTraversalCollectionTask(ShenandoahCSetRootScanner* rp) :
     AbstractGangTask("Shenandoah Init Traversal Collection"),
     _rp(rp),
-    _heap(ShenandoahHeap::heap()),
-    _cset_coderoots(cset_coderoots) {}
+    _heap(ShenandoahHeap::heap()) {}
 
   void work(uint worker_id) {
     ShenandoahParallelWorkerSession worker_session(worker_id);
@@ -191,18 +192,13 @@
       ShenandoahMarkCLDClosure cld_cl(&roots_cl);
       MarkingCodeBlobClosure code_cl(&roots_cl, CodeBlobToOopClosure::FixRelocations);
       if (unload_classes) {
-        _rp->process_strong_roots(&roots_cl, &cld_cl, NULL, NULL, worker_id);
-        // Need to pre-evac code roots here. Otherwise we might see from-space constants.
-        ShenandoahWorkerTimings* worker_times = _heap->phase_timings()->worker_times();
-        ShenandoahWorkerTimingsTracker timer(worker_times, ShenandoahPhaseTimings::CodeCacheRoots, worker_id);
-        _cset_coderoots->possibly_parallel_blobs_do(&code_cl);
+        _rp->roots_do(worker_id, &roots_cl, NULL, &code_cl);
       } else {
-        _rp->process_all_roots(&roots_cl, &cld_cl, &code_cl, NULL, worker_id);
+        _rp->roots_do(worker_id, &roots_cl, &cld_cl, &code_cl);
       }
-      if (ShenandoahStringDedup::is_enabled()) {
-        AlwaysTrueClosure is_alive;
-        ShenandoahStringDedup::parallel_oops_do(&is_alive, &roots_cl, worker_id);
-      }
+
+      AlwaysTrueClosure is_alive;
+      _dedup_roots.oops_do(&is_alive, &roots_cl, worker_id);
     }
   }
 };
@@ -230,11 +226,11 @@
 
 class ShenandoahFinalTraversalCollectionTask : public AbstractGangTask {
 private:
-  ShenandoahRootProcessor* _rp;
+  ShenandoahAllRootScanner* _rp;
   ShenandoahTaskTerminator* _terminator;
   ShenandoahHeap* _heap;
 public:
-  ShenandoahFinalTraversalCollectionTask(ShenandoahRootProcessor* rp, ShenandoahTaskTerminator* terminator) :
+  ShenandoahFinalTraversalCollectionTask(ShenandoahAllRootScanner* rp, ShenandoahTaskTerminator* terminator) :
     AbstractGangTask("Shenandoah Final Traversal Collection"),
     _rp(rp),
     _terminator(terminator),
@@ -273,23 +269,23 @@
     // roots here.
     if (!_heap->is_degenerated_gc_in_progress()) {
       ShenandoahTraversalClosure roots_cl(q, rp);
-      CLDToOopClosure cld_cl(&roots_cl, ClassLoaderData::_claim_strong);
       ShenandoahTraversalSATBThreadsClosure tc(&satb_cl);
       if (unload_classes) {
         ShenandoahRemarkCLDClosure remark_cld_cl(&roots_cl);
-        _rp->process_strong_roots(&roots_cl, &remark_cld_cl, NULL, &tc, worker_id);
+        _rp->strong_roots_do(worker_id, &roots_cl, &remark_cld_cl, NULL, &tc);
       } else {
-        _rp->process_all_roots(&roots_cl, &cld_cl, NULL, &tc, worker_id);
+        CLDToOopClosure cld_cl(&roots_cl, ClassLoaderData::_claim_strong);
+        _rp->roots_do(worker_id, &roots_cl, &cld_cl, NULL, &tc);
       }
     } else {
       ShenandoahTraversalDegenClosure roots_cl(q, rp);
-      CLDToOopClosure cld_cl(&roots_cl, ClassLoaderData::_claim_strong);
       ShenandoahTraversalSATBThreadsClosure tc(&satb_cl);
       if (unload_classes) {
         ShenandoahRemarkCLDClosure remark_cld_cl(&roots_cl);
-        _rp->process_strong_roots(&roots_cl, &remark_cld_cl, NULL, &tc, worker_id);
+        _rp->strong_roots_do(worker_id, &roots_cl, &remark_cld_cl, NULL, &tc);
       } else {
-        _rp->process_all_roots(&roots_cl, &cld_cl, NULL, &tc, worker_id);
+        CLDToOopClosure cld_cl(&roots_cl, ClassLoaderData::_claim_strong);
+        _rp->roots_do(worker_id, &roots_cl, &cld_cl, NULL, &tc);
       }
     }
 
@@ -309,6 +305,9 @@
   _task_queues(new ShenandoahObjToScanQueueSet(heap->max_workers())),
   _traversal_set(ShenandoahHeapRegionSet()) {
 
+  // Traversal does not support concurrent code root scanning
+  FLAG_SET_DEFAULT(ShenandoahConcurrentScanCodeRoots, false);
+
   uint num_queues = heap->max_workers();
   for (uint i = 0; i < num_queues; ++i) {
     ShenandoahObjToScanQueue* task_queue = new ShenandoahObjToScanQueue();
@@ -411,11 +410,8 @@
     {
       uint nworkers = _heap->workers()->active_workers();
       task_queues()->reserve(nworkers);
-      ShenandoahRootProcessor rp(_heap, nworkers, ShenandoahPhaseTimings::init_traversal_gc_work);
-
-      ShenandoahCsetCodeRootsIterator cset_coderoots = ShenandoahCodeRoots::cset_iterator();
-
-      ShenandoahInitTraversalCollectionTask traversal_task(&rp, &cset_coderoots);
+      ShenandoahCSetRootScanner rp(nworkers, ShenandoahPhaseTimings::init_traversal_gc_work);
+      ShenandoahInitTraversalCollectionTask traversal_task(&rp);
       _heap->workers()->run_task(&traversal_task);
     }
 
@@ -584,7 +580,7 @@
     task_queues()->reserve(nworkers);
 
     // Finish traversal
-    ShenandoahRootProcessor rp(_heap, nworkers, ShenandoahPhaseTimings::final_traversal_gc_work);
+    ShenandoahAllRootScanner rp(nworkers, ShenandoahPhaseTimings::final_traversal_gc_work);
     ShenandoahTerminationTracker term(ShenandoahPhaseTimings::final_traversal_gc_termination);
 
     ShenandoahTaskTerminator terminator(nworkers, task_queues());
@@ -693,10 +689,10 @@
 
 class ShenandoahTraversalFixRootsTask : public AbstractGangTask {
 private:
-  ShenandoahRootProcessor* _rp;
+  ShenandoahRootUpdater* _rp;
 
 public:
-  ShenandoahTraversalFixRootsTask(ShenandoahRootProcessor* rp) :
+  ShenandoahTraversalFixRootsTask(ShenandoahRootUpdater* rp) :
     AbstractGangTask("Shenandoah traversal fix roots"),
     _rp(rp) {
     assert(ShenandoahHeap::heap()->has_forwarded_objects(), "Must be");
@@ -705,9 +701,8 @@
   void work(uint worker_id) {
     ShenandoahParallelWorkerSession worker_session(worker_id);
     ShenandoahTraversalFixRootsClosure cl;
-    MarkingCodeBlobClosure blobsCl(&cl, CodeBlobToOopClosure::FixRelocations);
-    CLDToOopClosure cldCl(&cl, ClassLoaderData::_claim_strong);
-    _rp->update_all_roots<ShenandoahForwardedIsAliveClosure>(&cl, &cldCl, &blobsCl, NULL, worker_id);
+    ShenandoahForwardedIsAliveClosure is_alive;
+    _rp->roots_do<ShenandoahForwardedIsAliveClosure, ShenandoahTraversalFixRootsClosure>(worker_id, &is_alive, &cl);
   }
 };
 
@@ -715,7 +710,7 @@
 #if defined(COMPILER2) || INCLUDE_JVMCI
   DerivedPointerTable::clear();
 #endif
-  ShenandoahRootProcessor rp(_heap, _heap->workers()->active_workers(), ShenandoahPhaseTimings::final_traversal_update_roots);
+  ShenandoahRootUpdater rp(_heap->workers()->active_workers(), ShenandoahPhaseTimings::final_traversal_update_roots, true /* update code cache */);
   ShenandoahTraversalFixRootsTask update_roots_task(&rp);
   _heap->workers()->run_task(&update_roots_task);
 #if defined(COMPILER2) || INCLUDE_JVMCI
--- a/src/hotspot/share/gc/shenandoah/shenandoahVerifier.cpp	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/share/gc/shenandoah/shenandoahVerifier.cpp	Thu May 23 11:07:37 2019 +0100
@@ -604,6 +604,23 @@
   }
 };
 
+class ShenandoahGCStateResetter : public StackObj {
+private:
+  ShenandoahHeap* const _heap;
+  char _gc_state;
+
+public:
+  ShenandoahGCStateResetter() : _heap(ShenandoahHeap::heap()) {
+    _gc_state = _heap->gc_state();
+    _heap->_gc_state.clear();
+  }
+
+  ~ShenandoahGCStateResetter() {
+    _heap->_gc_state.set(_gc_state);
+    assert(_heap->gc_state() == _gc_state, "Should be restored");
+  }
+};
+
 void ShenandoahVerifier::verify_at_safepoint(const char *label,
                                              VerifyForwarded forwarded, VerifyMarked marked,
                                              VerifyCollectionSet cset,
@@ -653,6 +670,9 @@
     }
   }
 
+  // Deactivate barriers temporarily: Verifier wants plain heap accesses
+  ShenandoahGCStateResetter resetter;
+
   // Heap size checks
   {
     ShenandoahHeapLocker lock(_heap->lock());
--- a/src/hotspot/share/gc/z/zDirector.cpp	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/share/gc/z/zDirector.cpp	Thu May 23 11:07:37 2019 +0100
@@ -181,6 +181,25 @@
   return time_until_gc <= 0;
 }
 
+bool ZDirector::rule_high_usage() const {
+  // Perform GC if the amount of free memory is 5% or less. This is a preventive
+  // meassure in the case where the application has a very low allocation rate,
+  // such that the allocation rate rule doesn't trigger, but the amount of free
+  // memory is still slowly but surely heading towards zero. In this situation,
+  // we start a GC cycle to avoid a potential allocation stall later.
+
+  // Calculate amount of free memory available to Java threads. Note that
+  // the heap reserve is not available to Java threads and is therefore not
+  // considered part of the free memory.
+  const size_t max_capacity = ZHeap::heap()->current_max_capacity();
+  const size_t max_reserve = ZHeap::heap()->max_reserve();
+  const size_t used = ZHeap::heap()->used();
+  const size_t free_with_reserve = max_capacity - used;
+  const size_t free = free_with_reserve - MIN2(free_with_reserve, max_reserve);
+
+  return percent_of(free, max_capacity) <= 5.0;
+}
+
 GCCause::Cause ZDirector::make_gc_decision() const {
   // Rule 0: Timer
   if (rule_timer()) {
@@ -202,6 +221,11 @@
     return GCCause::_z_proactive;
   }
 
+  // Rule 4: High usage
+  if (rule_high_usage()) {
+    return GCCause::_z_high_usage;
+  }
+
   // No GC
   return GCCause::_no_gc;
 }
--- a/src/hotspot/share/gc/z/zDirector.hpp	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/share/gc/z/zDirector.hpp	Thu May 23 11:07:37 2019 +0100
@@ -43,6 +43,7 @@
   bool rule_warmup() const;
   bool rule_allocation_rate() const;
   bool rule_proactive() const;
+  bool rule_high_usage() const;
   GCCause::Cause make_gc_decision() const;
 
 protected:
--- a/src/hotspot/share/gc/z/zDriver.cpp	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/share/gc/z/zDriver.cpp	Thu May 23 11:07:37 2019 +0100
@@ -234,6 +234,7 @@
   case GCCause::_z_allocation_rate:
   case GCCause::_z_allocation_stall:
   case GCCause::_z_proactive:
+  case GCCause::_z_high_usage:
   case GCCause::_metadata_GC_threshold:
     // Start asynchronous GC
     _gc_cycle_port.send_async(cause);
--- a/src/hotspot/share/include/cds.h	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/share/include/cds.h	Thu May 23 11:07:37 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018, 2019, 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
@@ -35,6 +35,7 @@
 
 #define NUM_CDS_REGIONS 9
 #define CDS_ARCHIVE_MAGIC 0xf00baba2
+#define CDS_DYNAMIC_ARCHIVE_MAGIC 0xf00baba8
 #define CURRENT_CDS_ARCHIVE_VERSION 5
 #define INVALID_CDS_ARCHIVE_VERSION -1
 
--- a/src/hotspot/share/interpreter/bytecodeInterpreter.cpp	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/share/interpreter/bytecodeInterpreter.cpp	Thu May 23 11:07:37 2019 +0100
@@ -2871,7 +2871,7 @@
                      METHOD->print_value_string(),
                      (int)(istate->bcp() - METHOD->code_base()),
                      (int)continuation_bci, p2i(THREAD));
-        Exceptions::log_exception(except_oop, tempst);
+        Exceptions::log_exception(except_oop, tempst.as_string());
       }
       // for AbortVMOnException flag
       Exceptions::debug_check_abort(except_oop);
@@ -2888,7 +2888,7 @@
              METHOD->print_value_string(),
              (int)(istate->bcp() - METHOD->code_base()),
              p2i(THREAD));
-      Exceptions::log_exception(except_oop, tempst);
+      Exceptions::log_exception(except_oop, tempst.as_string());
     }
     // for AbortVMOnException flag
     Exceptions::debug_check_abort(except_oop);
--- a/src/hotspot/share/interpreter/interpreterRuntime.cpp	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/share/interpreter/interpreterRuntime.cpp	Thu May 23 11:07:37 2019 +0100
@@ -543,7 +543,7 @@
       tempst.print("interpreter method <%s>\n"
                    " at bci %d for thread " INTPTR_FORMAT " (%s)",
                    h_method->print_value_string(), current_bci, p2i(thread), thread->name());
-      Exceptions::log_exception(h_exception, tempst);
+      Exceptions::log_exception(h_exception, tempst.as_string());
     }
 // Don't go paging in something which won't be used.
 //     else if (extable->length() == 0) {
--- a/src/hotspot/share/jfr/metadata/metadata.xml	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/share/jfr/metadata/metadata.xml	Thu May 23 11:07:37 2019 +0100
@@ -983,6 +983,27 @@
     <Field type="ulong" name="value" label="Value" />
   </Event>
 
+  <Event name="ShenandoahHeapRegionStateChange" category="Java Virtual Machine, GC, Detailed" label="Shenandoah Heap Region State Change" description="Information about a Shenandoah heap region state change"
+    startTime="false">
+    <Field type="uint" name="index" label="Index" />
+    <Field type="ShenandoahHeapRegionState" name="from" label="From" />
+    <Field type="ShenandoahHeapRegionState" name="to" label="To" />
+    <Field type="ulong" contentType="address" name="start" label="Start" />
+    <Field type="ulong" contentType="bytes" name="used" label="Used" />
+  </Event>
+
+  <Event name="ShenandoahHeapRegionInformation" category="Java Virtual Machine, GC, Detailed" label="Shenandoah Heap Region Information" description="Information about a specific heap region in the Shenandoah GC"
+    period="everyChunk">
+    <Field type="uint" name="index" label="Index" />
+    <Field type="ShenandoahHeapRegionState" name="state" label="State" />
+    <Field type="ulong" contentType="address" name="start" label="Start" />
+    <Field type="ulong" contentType="bytes" name="used" label="Used" />
+  </Event>
+
+  <Type name="ShenandoahHeapRegionState" label="Shenandoah Heap Region State">
+    <Field type="string" name="state" label="State" />
+  </Type>
+
   <Type name="ZStatisticsCounterType" label="Z Statistics Counter">
     <Field type="string" name="counter" label="Counter" />
   </Type>
--- a/src/hotspot/share/jfr/periodic/jfrPeriodic.cpp	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/share/jfr/periodic/jfrPeriodic.cpp	Thu May 23 11:07:37 2019 +0100
@@ -65,7 +65,9 @@
 #include "services/threadService.hpp"
 #include "utilities/exceptions.hpp"
 #include "utilities/globalDefinitions.hpp"
-
+#if INCLUDE_SHENANDOAHGC
+#include "gc/shenandoah/shenandoahJfrSupport.hpp"
+#endif
 /**
  *  JfrPeriodic class
  *  Implementation of declarations in
@@ -626,3 +628,14 @@
   event.set_flushingEnabled(UseCodeCacheFlushing);
   event.commit();
 }
+
+
+TRACE_REQUEST_FUNC(ShenandoahHeapRegionInformation) {
+#if INCLUDE_SHENANDOAHGC
+  if (UseShenandoahGC) {
+    VM_ShenandoahSendHeapRegionInfoEvents op;
+    VMThread::execute(&op);
+  }
+#endif
+}
+
--- a/src/hotspot/share/jfr/recorder/checkpoint/jfrCheckpointManager.cpp	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/share/jfr/recorder/checkpoint/jfrCheckpointManager.cpp	Thu May 23 11:07:37 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2019, 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
@@ -136,6 +136,8 @@
 
 void JfrCheckpointManager::register_full(BufferPtr t, Thread* thread) {
   // nothing here at the moment
+  assert(t != NULL, "invariant");
+  assert(t->acquired_by(thread), "invariant");
   assert(t->retired(), "invariant");
 }
 
--- a/src/hotspot/share/jfr/recorder/jfrRecorder.cpp	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/share/jfr/recorder/jfrRecorder.cpp	Thu May 23 11:07:37 2019 +0100
@@ -57,7 +57,7 @@
 
 static bool enable() {
   assert(!_enabled, "invariant");
-  FLAG_SET_MGMT(bool, FlightRecorder, true);
+  FLAG_SET_MGMT(FlightRecorder, true);
   _enabled = FlightRecorder;
   assert(_enabled, "invariant");
   return _enabled;
@@ -168,7 +168,7 @@
 
 static bool is_cds_dump_requested() {
   // we will not be able to launch recordings if a cds dump is being requested
-  if (DumpSharedSpaces && (JfrOptionSet::startup_recording_options() != NULL)) {
+  if ((DumpSharedSpaces || DynamicDumpSharedSpaces) && (JfrOptionSet::startup_recording_options() != NULL)) {
     warning("JFR will be disabled during CDS dumping");
     teardown_startup_support();
     return true;
--- a/src/hotspot/share/jfr/recorder/storage/jfrBuffer.cpp	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/share/jfr/recorder/storage/jfrBuffer.cpp	Thu May 23 11:07:37 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2019, 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
@@ -136,6 +136,14 @@
   _identity = NULL;
 }
 
+bool JfrBuffer::acquired_by(const void* id) const {
+  return identity() == id;
+}
+
+bool JfrBuffer::acquired_by_self() const {
+  return acquired_by(Thread::current());
+}
+
 #ifdef ASSERT
 static bool validate_to(const JfrBuffer* const to, size_t size) {
   assert(to != NULL, "invariant");
@@ -153,10 +161,6 @@
   assert(t->top() + size <= t->pos(), "invariant");
   return true;
 }
-
-bool JfrBuffer::acquired_by_self() const {
-  return identity() == Thread::current();
-}
 #endif // ASSERT
 
 void JfrBuffer::move(JfrBuffer* const to, size_t size) {
@@ -183,7 +187,6 @@
   set_concurrent_top(start());
 }
 
-// flags
 enum FLAG {
   RETIRED = 1,
   TRANSIENT = 2,
--- a/src/hotspot/share/jfr/recorder/storage/jfrBuffer.hpp	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/share/jfr/recorder/storage/jfrBuffer.hpp	Thu May 23 11:07:37 2019 +0100
@@ -57,7 +57,6 @@
   u4 _size;
 
   const u1* stable_top() const;
-  void clear_flags();
 
  public:
   JfrBuffer();
@@ -150,6 +149,8 @@
 
   void acquire(const void* id);
   bool try_acquire(const void* id);
+  bool acquired_by(const void* id) const;
+  bool acquired_by_self() const;
   void release();
 
   void move(JfrBuffer* const to, size_t size);
@@ -166,8 +167,6 @@
   bool retired() const;
   void set_retired();
   void clear_retired();
-
-  debug_only(bool acquired_by_self() const;)
 };
 
 class JfrAgeNode : public JfrBuffer {
--- a/src/hotspot/share/jfr/recorder/storage/jfrMemorySpace.inline.hpp	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/share/jfr/recorder/storage/jfrMemorySpace.inline.hpp	Thu May 23 11:07:37 2019 +0100
@@ -346,19 +346,19 @@
 template <typename Mspace>
 inline bool ReleaseOp<Mspace>::process(typename Mspace::Type* t) {
   assert(t != NULL, "invariant");
-  if (t->retired() || t->try_acquire(_thread)) {
-    if (t->transient()) {
-      if (_release_full) {
-        mspace_release_full_critical(t, _mspace);
-      } else {
-        mspace_release_free_critical(t, _mspace);
-      }
-      return true;
+  // assumes some means of exclusive access to t
+  if (t->transient()) {
+    if (_release_full) {
+      mspace_release_full_critical(t, _mspace);
+    } else {
+      mspace_release_free_critical(t, _mspace);
     }
-    t->reinitialize();
-    assert(t->empty(), "invariant");
-    t->release(); // publish
+    return true;
   }
+  t->reinitialize();
+  assert(t->empty(), "invariant");
+  assert(!t->retired(), "invariant");
+  t->release(); // publish
   return true;
 }
 
--- a/src/hotspot/share/jfr/recorder/storage/jfrStorage.cpp	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/share/jfr/recorder/storage/jfrStorage.cpp	Thu May 23 11:07:37 2019 +0100
@@ -339,9 +339,9 @@
 void JfrStorage::register_full(BufferPtr buffer, Thread* thread) {
   assert(buffer != NULL, "invariant");
   assert(buffer->retired(), "invariant");
+  assert(buffer->acquired_by(thread), "invariant");
   if (!full_buffer_registration(buffer, _age_mspace, control(), thread)) {
     handle_registration_failure(buffer);
-    buffer->release();
   }
   if (control().should_post_buffer_full_message()) {
     _post_box.post(MSG_FULLBUFFER);
@@ -376,8 +376,8 @@
     }
   }
   assert(buffer->empty(), "invariant");
+  assert(buffer->identity() != NULL, "invariant");
   control().increment_dead();
-  buffer->release();
   buffer->set_retired();
 }
 
@@ -738,13 +738,14 @@
   Scavenger(JfrStorageControl& control, Mspace* mspace) : _control(control), _mspace(mspace), _count(0), _amount(0) {}
   bool process(Type* t) {
     if (t->retired()) {
+      assert(t->identity() != NULL, "invariant");
+      assert(t->empty(), "invariant");
       assert(!t->transient(), "invariant");
       assert(!t->lease(), "invariant");
-      assert(t->empty(), "invariant");
-      assert(t->identity() == NULL, "invariant");
       ++_count;
       _amount += t->total_size();
       t->clear_retired();
+      t->release();
       _control.decrement_dead();
       mspace_release_full_critical(t, _mspace);
     }
--- a/src/hotspot/share/jfr/recorder/storage/jfrStorageUtils.hpp	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/share/jfr/recorder/storage/jfrStorageUtils.hpp	Thu May 23 11:07:37 2019 +0100
@@ -92,7 +92,6 @@
   size_t processed() const { return ConcurrentWriteOp<Operation>::processed(); }
 };
 
-
 template <typename Operation>
 class MutexedWriteOp {
  private:
@@ -104,6 +103,15 @@
   size_t processed() const { return _operation.processed(); }
 };
 
+template <typename Operation>
+class ExclusiveOp : private MutexedWriteOp<Operation> {
+ public:
+  typedef typename Operation::Type Type;
+  ExclusiveOp(Operation& operation) : MutexedWriteOp<Operation>(operation) {}
+  bool process(Type* t);
+  size_t processed() const { return MutexedWriteOp<Operation>::processed(); }
+};
+
 enum jfr_operation_mode {
   mutexed = 1,
   concurrent
--- a/src/hotspot/share/jfr/recorder/storage/jfrStorageUtils.inline.hpp	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/share/jfr/recorder/storage/jfrStorageUtils.inline.hpp	Thu May 23 11:07:37 2019 +0100
@@ -26,6 +26,7 @@
 #define SHARE_JFR_RECORDER_STORAGE_JFRSTORAGEUTILS_INLINE_HPP
 
 #include "jfr/recorder/storage/jfrStorageUtils.hpp"
+#include "runtime/thread.inline.hpp"
 
 template <typename T>
 inline bool UnBufferedWriteToChunk<T>::write(T* t, const u1* data, size_t size) {
@@ -75,6 +76,28 @@
   return result;
 }
 
+template <typename Type>
+static void retired_sensitive_acquire(Type* t) {
+  assert(t != NULL, "invariant");
+  if (t->retired()) {
+    return;
+  }
+  Thread* const thread = Thread::current();
+  while (!t->try_acquire(thread)) {
+    if (t->retired()) {
+      return;
+    }
+  }
+}
+
+template <typename Operation>
+inline bool ExclusiveOp<Operation>::process(typename Operation::Type* t) {
+  retired_sensitive_acquire(t);
+  assert(t->acquired_by_self() || t->retired(), "invariant");
+  // User is required to ensure proper release of the acquisition
+  return MutexedWriteOp<Operation>::process(t);
+}
+
 template <typename Operation>
 inline bool DiscardOp<Operation>::process(typename Operation::Type* t) {
   assert(t != NULL, "invariant");
--- a/src/hotspot/share/jfr/recorder/stringpool/jfrStringPool.cpp	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/share/jfr/recorder/stringpool/jfrStringPool.cpp	Thu May 23 11:07:37 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2019, 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
@@ -140,93 +140,76 @@
   return current_epoch;
 }
 
-class StringPoolWriteOp  {
+template <template <typename> class Operation>
+class StringPoolOp {
  public:
   typedef JfrStringPoolBuffer Type;
  private:
-  UnBufferedWriteToChunk<Type> _writer;
+  Operation<Type> _op;
   Thread* _thread;
   size_t _strings_processed;
  public:
-  StringPoolWriteOp(JfrChunkWriter& writer, Thread* thread) : _writer(writer), _thread(thread), _strings_processed(0) {}
+  StringPoolOp() : _op(), _thread(Thread::current()), _strings_processed(0) {}
+  StringPoolOp(JfrChunkWriter& writer, Thread* thread) : _op(writer), _thread(thread), _strings_processed(0) {}
   bool write(Type* buffer, const u1* data, size_t size) {
-    buffer->acquire(_thread); // blocking
+    assert(buffer->acquired_by(_thread) || buffer->retired(), "invariant");
     const uint64_t nof_strings_used = buffer->string_count();
     assert(nof_strings_used > 0, "invariant");
     buffer->set_string_top(buffer->string_top() + nof_strings_used);
     // "size processed" for string pool buffers is the number of processed string elements
     _strings_processed += nof_strings_used;
-    const bool ret = _writer.write(buffer, data, size);
-    buffer->release();
-    return ret;
+    return _op.write(buffer, data, size);
   }
   size_t processed() { return _strings_processed; }
 };
 
-typedef StringPoolWriteOp WriteOperation;
-typedef ConcurrentWriteOp<WriteOperation> ConcurrentWriteOperation;
+template <typename Type>
+class StringPoolDiscarderStub {
+ public:
+  bool write(Type* buffer, const u1* data, size_t size) {
+    // stub only, discard happens at higher level
+    return true;
+  }
+};
+
+typedef StringPoolOp<UnBufferedWriteToChunk> WriteOperation;
+typedef StringPoolOp<StringPoolDiscarderStub> DiscardOperation;
+typedef ExclusiveOp<WriteOperation> ExclusiveWriteOperation;
+typedef ExclusiveOp<DiscardOperation> ExclusiveDiscardOperation;
+typedef ReleaseOp<JfrStringPoolMspace> StringPoolReleaseOperation;
+typedef CompositeOperation<ExclusiveWriteOperation, StringPoolReleaseOperation> StringPoolWriteOperation;
+typedef CompositeOperation<ExclusiveDiscardOperation, StringPoolReleaseOperation> StringPoolDiscardOperation;
 
 size_t JfrStringPool::write() {
   Thread* const thread = Thread::current();
   WriteOperation wo(_chunkwriter, thread);
-  ConcurrentWriteOperation cwo(wo);
-  assert(_free_list_mspace->is_full_empty(), "invariant");
-  process_free_list(cwo, _free_list_mspace);
-  return wo.processed();
-}
-
-typedef MutexedWriteOp<WriteOperation> MutexedWriteOperation;
-typedef ReleaseOp<JfrStringPoolMspace> StringPoolReleaseOperation;
-typedef CompositeOperation<MutexedWriteOperation, StringPoolReleaseOperation> StringPoolWriteOperation;
-
-size_t JfrStringPool::write_at_safepoint() {
-  assert(SafepointSynchronize::is_at_safepoint(), "invariant");
-  Thread* const thread = Thread::current();
-  WriteOperation wo(_chunkwriter, thread);
-  MutexedWriteOperation mwo(wo);
+  ExclusiveWriteOperation ewo(wo);
   StringPoolReleaseOperation spro(_free_list_mspace, thread, false);
-  StringPoolWriteOperation spwo(&mwo, &spro);
+  StringPoolWriteOperation spwo(&ewo, &spro);
   assert(_free_list_mspace->is_full_empty(), "invariant");
   process_free_list(spwo, _free_list_mspace);
   return wo.processed();
 }
 
-class StringPoolBufferDiscarder {
- private:
-  Thread* _thread;
-  size_t _processed;
- public:
-  typedef JfrStringPoolBuffer Type;
-  StringPoolBufferDiscarder() : _thread(Thread::current()), _processed(0) {}
-  bool process(Type* buffer) {
-    buffer->acquire(_thread); // serialized access
-    const u1* const current_top = buffer->top();
-    const size_t unflushed_size = buffer->pos() - current_top;
-    if (unflushed_size == 0) {
-      assert(buffer->string_count() == 0, "invariant");
-      buffer->release();
-      return true;
-    }
-    buffer->set_top(current_top + unflushed_size);
-    const uint64_t nof_strings_used = buffer->string_count();
-    buffer->set_string_top(buffer->string_top() + nof_strings_used);
-    // "size processed" for string pool buffers is the number of string elements
-    _processed += (size_t)nof_strings_used;
-    buffer->release();
-    return true;
-  }
-  size_t processed() const { return _processed; }
-};
+size_t JfrStringPool::write_at_safepoint() {
+  assert(SafepointSynchronize::is_at_safepoint(), "invariant");
+  return write();
+}
 
 size_t JfrStringPool::clear() {
-  StringPoolBufferDiscarder discard_operation;
+  DiscardOperation discard_operation;
+  ExclusiveDiscardOperation edo(discard_operation);
+  StringPoolReleaseOperation spro(_free_list_mspace, Thread::current(), false);
+  StringPoolDiscardOperation spdo(&edo, &spro);
   assert(_free_list_mspace->is_full_empty(), "invariant");
-  process_free_list(discard_operation, _free_list_mspace);
+  process_free_list(spdo, _free_list_mspace);
   return discard_operation.processed();
 }
 
 void JfrStringPool::register_full(BufferPtr t, Thread* thread) {
   // nothing here at the moment
+  assert(t != NULL, "invariant");
+  assert(t->acquired_by(thread), "invariant");
   assert(t->retired(), "invariant");
 }
 
--- a/src/hotspot/share/jfr/recorder/stringpool/jfrStringPoolBuffer.cpp	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/share/jfr/recorder/stringpool/jfrStringPoolBuffer.cpp	Thu May 23 11:07:37 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2019, 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
@@ -29,11 +29,9 @@
 
 void JfrStringPoolBuffer::reinitialize() {
   assert(acquired_by_self() || retired(), "invariant");
-  concurrent_top();
-  set_pos((start()));
   set_string_pos(0);
   set_string_top(0);
-  set_concurrent_top(start());
+  JfrBuffer::reinitialize();
 }
 
 uint64_t JfrStringPoolBuffer::string_pos() const {
@@ -57,7 +55,7 @@
 }
 
 void JfrStringPoolBuffer::increment(uint64_t value) {
-  assert(acquired_by_self() || retired(), "invariant");
+  assert(acquired_by_self(), "invariant");
   ++_string_count_pos;
 }
 
--- a/src/hotspot/share/jvmci/jvmci.cpp	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/share/jvmci/jvmci.cpp	Thu May 23 11:07:37 2019 +0100
@@ -26,7 +26,6 @@
 #include "gc/shared/collectedHeap.hpp"
 #include "gc/shared/oopStorage.inline.hpp"
 #include "jvmci/jvmci.hpp"
-#include "jvmci/jvmci_globals.hpp"
 #include "jvmci/jvmciJavaClasses.hpp"
 #include "jvmci/jvmciRuntime.hpp"
 #include "jvmci/metadataHandleBlock.hpp"
--- a/src/hotspot/share/jvmci/jvmciRuntime.cpp	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/share/jvmci/jvmciRuntime.cpp	Thu May 23 11:07:37 2019 +0100
@@ -311,7 +311,7 @@
       tempst.print("compiled method <%s>\n"
                    " at PC" INTPTR_FORMAT " for thread " INTPTR_FORMAT,
                    cm->method()->print_value_string(), p2i(pc), p2i(thread));
-      Exceptions::log_exception(exception, tempst);
+      Exceptions::log_exception(exception, tempst.as_string());
     }
     // for AbortVMOnException flag
     NOT_PRODUCT(Exceptions::debug_check_abort(exception));
--- a/src/hotspot/share/jvmci/jvmci_globals.cpp	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/share/jvmci/jvmci_globals.cpp	Thu May 23 11:07:37 2019 +0100
@@ -32,18 +32,6 @@
 
 fileStream* JVMCIGlobals::_jni_config_file = NULL;
 
-JVMCI_FLAGS(MATERIALIZE_DEVELOPER_FLAG, \
-            MATERIALIZE_PD_DEVELOPER_FLAG, \
-            MATERIALIZE_PRODUCT_FLAG, \
-            MATERIALIZE_PD_PRODUCT_FLAG, \
-            MATERIALIZE_DIAGNOSTIC_FLAG, \
-            MATERIALIZE_PD_DIAGNOSTIC_FLAG, \
-            MATERIALIZE_EXPERIMENTAL_FLAG, \
-            MATERIALIZE_NOTPRODUCT_FLAG,
-            IGNORE_RANGE, \
-            IGNORE_CONSTRAINT, \
-            IGNORE_WRITEABLE)
-
 // Return true if jvmci flags are consistent.
 bool JVMCIGlobals::check_jvmci_flags_are_consistent() {
 
--- a/src/hotspot/share/jvmci/jvmci_globals.hpp	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/share/jvmci/jvmci_globals.hpp	Thu May 23 11:07:37 2019 +0100
@@ -25,7 +25,7 @@
 #ifndef SHARE_JVMCI_JVMCI_GLOBALS_HPP
 #define SHARE_JVMCI_JVMCI_GLOBALS_HPP
 
-#include "utilities/ostream.hpp"
+class fileStream;
 
 //
 // Defines all global flags used by the JVMCI compiler. Only flags that need
@@ -129,21 +129,6 @@
   NOT_COMPILER2(diagnostic(bool, UseMontgomerySquareIntrinsic, false,       \
           "Enables intrinsification of BigInteger.montgomerySquare()"))
 
-
-// Read default values for JVMCI globals
-
-JVMCI_FLAGS(DECLARE_DEVELOPER_FLAG, \
-            DECLARE_PD_DEVELOPER_FLAG, \
-            DECLARE_PRODUCT_FLAG, \
-            DECLARE_PD_PRODUCT_FLAG, \
-            DECLARE_DIAGNOSTIC_FLAG, \
-            DECLARE_PD_DIAGNOSTIC_FLAG, \
-            DECLARE_EXPERIMENTAL_FLAG, \
-            DECLARE_NOTPRODUCT_FLAG, \
-            IGNORE_RANGE, \
-            IGNORE_CONSTRAINT, \
-            IGNORE_WRITEABLE)
-
 // The base name for the shared library containing the JVMCI based compiler
 #define JVMCI_SHARED_LIBRARY_NAME "jvmcicompiler"
 
--- a/src/hotspot/share/logging/logTag.hpp	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/share/logging/logTag.hpp	Thu May 23 11:07:37 2019 +0100
@@ -66,6 +66,7 @@
   LOG_TAG(defaultmethods) \
   LOG_TAG(director) \
   LOG_TAG(dump) \
+  LOG_TAG(dynamic) \
   LOG_TAG(ergo) \
   LOG_TAG(event) \
   LOG_TAG(exceptions) \
--- a/src/hotspot/share/memory/allocation.hpp	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/share/memory/allocation.hpp	Thu May 23 11:07:37 2019 +0100
@@ -254,10 +254,9 @@
   // into a single contiguous memory block, so we can use these
   // two pointers to quickly determine if something is in the
   // shared metaspace.
-  //
   // When CDS is not enabled, both pointers are set to NULL.
-  static void* _shared_metaspace_base; // (inclusive) low address
-  static void* _shared_metaspace_top;  // (exclusive) high address
+  static void* _shared_metaspace_base;  // (inclusive) low address
+  static void* _shared_metaspace_top;   // (exclusive) high address
 
  public:
 
@@ -269,7 +268,8 @@
   static bool is_shared(const MetaspaceObj* p) {
     // If no shared metaspace regions are mapped, _shared_metaspace_{base,top} will
     // both be NULL and all values of p will be rejected quickly.
-    return (((void*)p) < _shared_metaspace_top && ((void*)p) >= _shared_metaspace_base);
+    return (((void*)p) < _shared_metaspace_top &&
+            ((void*)p) >= _shared_metaspace_base);
   }
   bool is_shared() const { return MetaspaceObj::is_shared(this); }
 
@@ -279,6 +279,12 @@
     _shared_metaspace_base = base;
     _shared_metaspace_top = top;
   }
+
+  static void expand_shared_metaspace_range(void* top) {
+    assert(top >= _shared_metaspace_top, "must be");
+    _shared_metaspace_top = top;
+  }
+
   static void* shared_metaspace_base() { return _shared_metaspace_base; }
   static void* shared_metaspace_top()  { return _shared_metaspace_top;  }
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/memory/dynamicArchive.cpp	Thu May 23 11:07:37 2019 +0100
@@ -0,0 +1,1147 @@
+/*
+ * Copyright (c) 2019, 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.
+ *
+ */
+
+#include "precompiled.hpp"
+#include "jvm.h"
+#include "classfile/classLoaderData.inline.hpp"
+#include "classfile/symbolTable.hpp"
+#include "classfile/systemDictionary.hpp"
+#include "classfile/systemDictionaryShared.hpp"
+#include "logging/log.hpp"
+#include "memory/metadataFactory.hpp"
+#include "memory/metaspace.hpp"
+#include "memory/metaspaceClosure.hpp"
+#include "memory/metaspaceShared.hpp"
+#include "memory/resourceArea.hpp"
+#include "memory/dynamicArchive.hpp"
+#include "oops/compressedOops.hpp"
+#include "oops/objArrayKlass.hpp"
+#include "prims/jvmtiRedefineClasses.hpp"
+#include "runtime/handles.inline.hpp"
+#include "runtime/os.inline.hpp"
+#include "runtime/sharedRuntime.hpp"
+#include "runtime/vmThread.hpp"
+#include "runtime/vmOperations.hpp"
+#include "utilities/bitMap.inline.hpp"
+
+#ifndef O_BINARY       // if defined (Win32) use binary files.
+#define O_BINARY 0     // otherwise do nothing.
+#endif
+
+class DynamicArchiveBuilder : ResourceObj {
+  CHeapBitMap _ptrmap;
+  static unsigned my_hash(const address& a) {
+    return primitive_hash<address>(a);
+  }
+  static bool my_equals(const address& a0, const address& a1) {
+    return primitive_equals<address>(a0, a1);
+  }
+  typedef ResourceHashtable<
+      address, address,
+      DynamicArchiveBuilder::my_hash,   // solaris compiler doesn't like: primitive_hash<address>
+      DynamicArchiveBuilder::my_equals, // solaris compiler doesn't like: primitive_equals<address>
+      16384, ResourceObj::C_HEAP> RelocationTable;
+  RelocationTable _new_loc_table;
+
+  intx _buffer_to_target_delta;
+
+  DumpRegion* _current_dump_space;
+
+  static size_t reserve_alignment() {
+    return Metaspace::reserve_alignment();
+  }
+
+  static const int _total_dump_regions = 3;
+  int _num_dump_regions_used;
+
+public:
+  void mark_pointer(address* ptr_loc) {
+    if (is_in_buffer_space(ptr_loc)) {
+      size_t idx = pointer_delta(ptr_loc, _alloc_bottom, sizeof(address));
+      _ptrmap.set_bit(idx);
+    }
+  }
+
+  DumpRegion* current_dump_space() const {
+    return _current_dump_space;
+  }
+
+  bool is_in_buffer_space(address p) const {
+    return (_alloc_bottom <= p && p < (address)current_dump_space()->top());
+  }
+
+  template <typename T> bool is_in_target_space(T target_obj) const {
+    address buff_obj = address(target_obj) - _buffer_to_target_delta;
+    return is_in_buffer_space(buff_obj);
+  }
+
+  template <typename T> bool is_in_buffer_space(T obj) const {
+    return is_in_buffer_space(address(obj));
+  }
+
+  template <typename T> T to_target_no_check(T obj) const {
+    return (T)(address(obj) + _buffer_to_target_delta);
+  }
+
+  template <typename T> T to_target(T obj) const {
+    assert(is_in_buffer_space(obj), "must be");
+    return (T)(address(obj) + _buffer_to_target_delta);
+  }
+
+  template <typename T> T get_new_loc(T obj) {
+    address* pp = _new_loc_table.get((address)obj);
+    if (pp == NULL) {
+      // Excluded klasses are not copied
+      return NULL;
+    } else {
+      return (T)*pp;
+    }
+  }
+
+  address get_new_loc(MetaspaceClosure::Ref* ref) {
+    return get_new_loc(ref->obj());
+  }
+
+  template <typename T> bool has_new_loc(T obj) {
+    address* pp = _new_loc_table.get((address)obj);
+    return pp != NULL;
+  }
+
+protected:
+  enum FollowMode {
+    make_a_copy, point_to_it, set_to_null
+  };
+
+public:
+  void copy(MetaspaceClosure::Ref* ref, bool read_only) {
+    int bytes = ref->size() * BytesPerWord;
+    address old_obj = ref->obj();
+    address new_obj = copy_impl(ref, read_only, bytes);
+
+    assert(new_obj != NULL, "must be");
+    assert(new_obj != old_obj, "must be");
+    bool isnew = _new_loc_table.put(old_obj, new_obj);
+    assert(isnew, "must be");
+  }
+
+  // Make a shallow copy of each eligible MetaspaceObj into the buffer.
+  class ShallowCopier: public UniqueMetaspaceClosure {
+    DynamicArchiveBuilder* _builder;
+    bool _read_only;
+  public:
+    ShallowCopier(DynamicArchiveBuilder* shuffler, bool read_only)
+      : _builder(shuffler), _read_only(read_only) {}
+
+    virtual bool do_unique_ref(Ref* orig_obj, bool read_only) {
+      // This method gets called on each *original* object
+      // reachable from _builder->iterate_roots(). Each orig_obj is
+      // called exactly once.
+      FollowMode mode = _builder->follow_ref(orig_obj);
+
+      if (mode == point_to_it) {
+        if (read_only == _read_only) {
+          log_debug(cds, dynamic)("ptr : " PTR_FORMAT " %s", p2i(orig_obj->obj()),
+                                  MetaspaceObj::type_name(orig_obj->msotype()));
+          address p = orig_obj->obj();
+          bool isnew = _builder->_new_loc_table.put(p, p);
+          assert(isnew, "must be");
+        }
+        return false;
+      }
+
+      if (mode == set_to_null) {
+        log_debug(cds, dynamic)("nul : " PTR_FORMAT " %s", p2i(orig_obj->obj()),
+                                MetaspaceObj::type_name(orig_obj->msotype()));
+        return false;
+      }
+
+      if (read_only == _read_only) {
+        // Make a shallow copy of orig_obj in a buffer (maintained
+        // by copy_impl in a subclass of DynamicArchiveBuilder).
+        _builder->copy(orig_obj, read_only);
+      }
+      return true;
+    }
+  };
+
+  // Relocate all embedded pointer fields within a MetaspaceObj's shallow copy
+  class ShallowCopyEmbeddedRefRelocator: public UniqueMetaspaceClosure {
+    DynamicArchiveBuilder* _builder;
+  public:
+    ShallowCopyEmbeddedRefRelocator(DynamicArchiveBuilder* shuffler)
+      : _builder(shuffler) {}
+
+    // This method gets called on each *original* object reachable
+    // from _builder->iterate_roots(). Each orig_obj is
+    // called exactly once.
+    virtual bool do_unique_ref(Ref* orig_ref, bool read_only) {
+      FollowMode mode = _builder->follow_ref(orig_ref);
+
+      if (mode == point_to_it) {
+        // We did not make a copy of this object
+        // and we have nothing to update
+        assert(_builder->get_new_loc(orig_ref) == NULL ||
+               _builder->get_new_loc(orig_ref) == orig_ref->obj(), "must be");
+        return false;
+      }
+
+      if (mode == set_to_null) {
+        // We did not make a copy of this object
+        // and we have nothing to update
+        assert(!_builder->has_new_loc(orig_ref->obj()), "must not be copied or pointed to");
+        return false;
+      }
+
+      // - orig_obj points to the original object.
+      // - new_obj points to the shallow copy (created by ShallowCopier)
+      //   of orig_obj. new_obj is NULL if the orig_obj is excluded
+      address orig_obj = orig_ref->obj();
+      address new_obj  = _builder->get_new_loc(orig_ref);
+
+      assert(new_obj != orig_obj, "must be");
+#ifdef ASSERT
+      if (new_obj == NULL) {
+        if (orig_ref->msotype() == MetaspaceObj::ClassType) {
+          Klass* k = (Klass*)orig_obj;
+          assert(k->is_instance_klass() &&
+                 SystemDictionaryShared::is_excluded_class(InstanceKlass::cast(k)),
+                 "orig_obj must be excluded Class");
+        }
+      }
+#endif
+
+      log_debug(cds, dynamic)("Relocating " PTR_FORMAT " %s", p2i(new_obj),
+                              MetaspaceObj::type_name(orig_ref->msotype()));
+      if (new_obj != NULL) {
+        EmbeddedRefUpdater updater(_builder, orig_obj, new_obj);
+        orig_ref->metaspace_pointers_do(&updater);
+      }
+
+      return true; // keep recursing until every object is visited exactly once.
+    }
+  };
+
+  class EmbeddedRefUpdater: public MetaspaceClosure {
+    DynamicArchiveBuilder* _builder;
+    address _orig_obj;
+    address _new_obj;
+  public:
+    EmbeddedRefUpdater(DynamicArchiveBuilder* shuffler, address orig_obj, address new_obj) :
+      _builder(shuffler), _orig_obj(orig_obj), _new_obj(new_obj) {}
+
+    // This method gets called once for each pointer field F of orig_obj.
+    // We update new_obj->F to point to the new location of orig_obj->F.
+    //
+    // Example: Klass*  0x100 is copied to 0x400
+    //          Symbol* 0x200 is copied to 0x500
+    //
+    // Let orig_obj == 0x100; and
+    //     new_obj  == 0x400; and
+    //     ((Klass*)orig_obj)->_name == 0x200;
+    // Then this function effectively assigns
+    //     ((Klass*)new_obj)->_name = 0x500;
+    virtual bool do_ref(Ref* ref, bool read_only) {
+      address new_pointee = NULL;
+
+      if (ref->not_null()) {
+        address old_pointee = ref->obj();
+
+        FollowMode mode = _builder->follow_ref(ref);
+        if (mode == point_to_it) {
+          new_pointee = old_pointee;
+        } else if (mode == set_to_null) {
+          new_pointee = NULL;
+        } else {
+          new_pointee = _builder->get_new_loc(old_pointee);
+        }
+      }
+
+      const char* kind = MetaspaceObj::type_name(ref->msotype());
+      // offset of this field inside the original object
+      intx offset = (address)ref->addr() - _orig_obj;
+      _builder->update_pointer((address*)(_new_obj + offset), new_pointee, kind, offset);
+
+      // We can't mark the pointer here, because DynamicArchiveBuilder::sort_methods
+      // may re-layout the [iv]tables, which would change the offset(s) in an InstanceKlass
+      // that would contain pointers. Therefore, we must mark the pointers after
+      // sort_methods(), using PointerMarker.
+      return false; // Do not recurse.
+    }
+  };
+
+  class ExternalRefUpdater: public MetaspaceClosure {
+    DynamicArchiveBuilder* _builder;
+
+  public:
+    ExternalRefUpdater(DynamicArchiveBuilder* shuffler) : _builder(shuffler) {}
+
+    virtual bool do_ref(Ref* ref, bool read_only) {
+      // ref is a pointer that lives OUTSIDE of the buffer, but points to an object inside the buffer
+      if (ref->not_null()) {
+        address new_loc = _builder->get_new_loc(ref);
+        const char* kind = MetaspaceObj::type_name(ref->msotype());
+        _builder->update_pointer(ref->addr(), new_loc, kind, 0);
+        _builder->mark_pointer(ref->addr());
+      }
+      return false; // Do not recurse.
+    }
+  };
+
+  class PointerMarker: public UniqueMetaspaceClosure {
+    DynamicArchiveBuilder* _builder;
+
+  public:
+    PointerMarker(DynamicArchiveBuilder* shuffler) : _builder(shuffler) {}
+
+    virtual bool do_unique_ref(Ref* ref, bool read_only) {
+      if (_builder->is_in_buffer_space(ref->obj())) {
+        EmbeddedRefMarker ref_marker(_builder);
+        ref->metaspace_pointers_do(&ref_marker);
+        return true; // keep recursing until every buffered object is visited exactly once.
+      } else {
+        return false;
+      }
+    }
+  };
+
+  class EmbeddedRefMarker: public MetaspaceClosure {
+    DynamicArchiveBuilder* _builder;
+
+  public:
+    EmbeddedRefMarker(DynamicArchiveBuilder* shuffler) : _builder(shuffler) {}
+    virtual bool do_ref(Ref* ref, bool read_only) {
+      if (ref->not_null() && _builder->is_in_buffer_space(ref->obj())) {
+        _builder->mark_pointer(ref->addr());
+      }
+      return false; // Do not recurse.
+    }
+  };
+
+  void update_pointer(address* addr, address value, const char* kind, uintx offset, bool is_mso_pointer=true) {
+    // Propagate the the mask bits to the new value -- see comments above MetaspaceClosure::obj()
+    if (is_mso_pointer) {
+      const uintx FLAG_MASK = 0x03;
+      uintx mask_bits = uintx(*addr) & FLAG_MASK;
+      value = (address)(uintx(value) | mask_bits);
+    }
+
+    if (*addr != value) {
+      log_debug(cds, dynamic)("Update (%18s*) %3d [" PTR_FORMAT "] " PTR_FORMAT " -> " PTR_FORMAT,
+                              kind, int(offset), p2i(addr), p2i(*addr), p2i(value));
+      *addr = value;
+    }
+  }
+
+private:
+  GrowableArray<Symbol*>* _symbols; // symbols to dump
+  GrowableArray<InstanceKlass*>* _klasses; // klasses to dump
+
+  void append(InstanceKlass* k) { _klasses->append(k); }
+  void append(Symbol* s)        { _symbols->append(s); }
+
+  class GatherKlassesAndSymbols : public UniqueMetaspaceClosure {
+    DynamicArchiveBuilder* _builder;
+    bool _read_only;
+
+  public:
+    GatherKlassesAndSymbols(DynamicArchiveBuilder* builder)
+      : _builder(builder) {}
+
+    virtual bool do_unique_ref(Ref* ref, bool read_only) {
+      if (_builder->follow_ref(ref) != make_a_copy) {
+        return false;
+      }
+      if (ref->msotype() == MetaspaceObj::ClassType) {
+        Klass* klass = (Klass*)ref->obj();
+        assert(klass->is_klass(), "must be");
+        if (klass->is_instance_klass()) {
+          InstanceKlass* ik = InstanceKlass::cast(klass);
+          assert(!SystemDictionaryShared::is_excluded_class(ik), "must be");
+          _builder->append(ik);
+          _builder->_estimated_metsapceobj_bytes += BytesPerWord; // See RunTimeSharedClassInfo::get_for()
+        }
+      } else if (ref->msotype() == MetaspaceObj::SymbolType) {
+        _builder->append((Symbol*)ref->obj());
+      }
+
+      int bytes = ref->size() * BytesPerWord;
+      _builder->_estimated_metsapceobj_bytes += bytes;
+
+      return true;
+    }
+  };
+
+  FollowMode follow_ref(MetaspaceClosure::Ref *ref) {
+    address obj = ref->obj();
+    if (MetaspaceShared::is_in_shared_metaspace(obj)) {
+      // Don't dump existing shared metadata again.
+      return point_to_it;
+    } else if (ref->msotype() == MetaspaceObj::MethodDataType) {
+      return set_to_null;
+    } else {
+      if (ref->msotype() == MetaspaceObj::ClassType) {
+        Klass* klass = (Klass*)ref->obj();
+        assert(klass->is_klass(), "must be");
+        if (klass->is_instance_klass()) {
+          InstanceKlass* ik = InstanceKlass::cast(klass);
+          if (SystemDictionaryShared::is_excluded_class(ik)) {
+            ResourceMark rm;
+            log_debug(cds, dynamic)("Skipping class (excluded): %s", klass->external_name());
+            return set_to_null;
+          }
+        } else if (klass->is_array_klass()) {
+          // Don't support archiving of array klasses for now.
+          ResourceMark rm;
+          log_debug(cds, dynamic)("Skipping class (array): %s", klass->external_name());
+          return set_to_null;
+        }
+      }
+
+      return make_a_copy;
+    }
+  }
+
+  address copy_impl(MetaspaceClosure::Ref* ref, bool read_only, int bytes) {
+    if (ref->msotype() == MetaspaceObj::ClassType) {
+      // Save a pointer immediate in front of an InstanceKlass, so
+      // we can do a quick lookup from InstanceKlass* -> RunTimeSharedClassInfo*
+      // without building another hashtable. See RunTimeSharedClassInfo::get_for()
+      // in systemDictionaryShared.cpp.
+      address obj = ref->obj();
+      Klass* klass = (Klass*)obj;
+      if (klass->is_instance_klass()) {
+        SystemDictionaryShared::validate_before_archiving(InstanceKlass::cast(klass));
+        current_dump_space()->allocate(sizeof(address), BytesPerWord);
+      }
+    }
+    address p = (address)current_dump_space()->allocate(bytes);
+    address obj = ref->obj();
+    log_debug(cds, dynamic)("COPY: " PTR_FORMAT " ==> " PTR_FORMAT " %5d %s",
+                            p2i(obj), p2i(p), bytes,
+                            MetaspaceObj::type_name(ref->msotype()));
+    memcpy(p, obj, bytes);
+
+    intptr_t* cloned_vtable = MetaspaceShared::fix_cpp_vtable_for_dynamic_archive(ref->msotype(), p);
+    if (cloned_vtable != NULL) {
+      update_pointer((address*)p, (address)cloned_vtable, "vtb", 0, /*is_mso_pointer*/false);
+    }
+
+    return (address)p;
+  }
+
+  DynamicArchiveHeader *_header;
+  address _alloc_bottom;
+  address _last_verified_top;
+  size_t _other_region_used_bytes;
+
+  // Conservative estimate for number of bytes needed for:
+  size_t _estimated_metsapceobj_bytes;   // all archived MetsapceObj's.
+  size_t _estimated_hashtable_bytes;     // symbol table and dictionaries
+  size_t _estimated_trampoline_bytes;    // method entry trampolines
+
+  size_t estimate_archive_size();
+  size_t estimate_trampoline_size();
+  size_t estimate_class_file_size();
+  address reserve_space_and_init_buffer_to_target_delta();
+  void init_header(address addr);
+  void make_trampolines();
+  void make_klasses_shareable();
+  void sort_methods(InstanceKlass* ik) const;
+  void set_symbols_permanent();
+  void relocate_buffer_to_target();
+  void write_archive(char* read_only_tables_start);
+
+  void init_first_dump_space(address reserved_bottom) {
+    address first_space_base = reserved_bottom;
+    DumpRegion* rw_space = MetaspaceShared::read_write_dump_space();
+    MetaspaceShared::init_shared_dump_space(rw_space, first_space_base);
+    _current_dump_space = rw_space;
+    _last_verified_top = first_space_base;
+    _num_dump_regions_used = 1;
+  }
+
+public:
+  DynamicArchiveBuilder() {
+    _klasses = new (ResourceObj::C_HEAP, mtClass) GrowableArray<InstanceKlass*>(100, true, mtInternal);
+    _symbols = new (ResourceObj::C_HEAP, mtClass) GrowableArray<Symbol*>(1000, true, mtInternal);
+
+    _estimated_metsapceobj_bytes = 0;
+    _estimated_hashtable_bytes = 0;
+    _estimated_trampoline_bytes = 0;
+
+    _num_dump_regions_used = 0;
+  }
+
+  void start_dump_space(DumpRegion* next) {
+    address bottom = _last_verified_top;
+    address top = (address)(current_dump_space()->top());
+    _other_region_used_bytes += size_t(top - bottom);
+
+    MetaspaceShared::pack_dump_space(current_dump_space(), next, MetaspaceShared::shared_rs());
+    _current_dump_space = next;
+    _num_dump_regions_used ++;
+
+    _last_verified_top = (address)(current_dump_space()->top());
+  }
+
+  void verify_estimate_size(size_t estimate, const char* which) {
+    address bottom = _last_verified_top;
+    address top = (address)(current_dump_space()->top());
+    size_t used = size_t(top - bottom) + _other_region_used_bytes;
+    int diff = int(estimate) - int(used);
+
+    log_info(cds)("%s estimate = " SIZE_FORMAT " used = " SIZE_FORMAT "; diff = %d bytes", which, estimate, used, diff);
+    assert(diff >= 0, "Estimate is too small");
+
+    _last_verified_top = top;
+    _other_region_used_bytes = 0;
+  }
+
+  // Do this before and after the archive dump to see if any corruption
+  // is caused by dynamic dumping.
+  void verify_universe(const char* info) {
+    if (VerifyBeforeExit) {
+      log_info(cds)("Verify %s", info);
+      HandleMark hm;
+      // Among other things, this ensures that Eden top is correct.
+      Universe::heap()->prepare_for_verify();
+      Universe::verify(info);
+    }
+  }
+
+  void doit() {
+    verify_universe("Before CDS dynamic dump");
+    DEBUG_ONLY(SystemDictionaryShared::NoClassLoadingMark nclm);
+    SystemDictionaryShared::check_excluded_classes();
+
+    {
+      ResourceMark rm;
+      GatherKlassesAndSymbols gatherer(this);
+
+      SystemDictionaryShared::dumptime_classes_do(&gatherer);
+      SymbolTable::metaspace_pointers_do(&gatherer);
+      FileMapInfo::metaspace_pointers_do(&gatherer);
+
+      gatherer.finish();
+    }
+
+    // rw space starts ...
+    address reserved_bottom = reserve_space_and_init_buffer_to_target_delta();
+    init_header(reserved_bottom);
+
+    verify_estimate_size(sizeof(DynamicArchiveHeader), "header");
+
+    log_info(cds, dynamic)("Copying %d klasses and %d symbols",
+                           _klasses->length(), _symbols->length());
+
+    {
+      assert(current_dump_space() == MetaspaceShared::read_write_dump_space(),
+             "Current dump space is not rw space");
+      // shallow-copy RW objects, if necessary
+      ResourceMark rm;
+      ShallowCopier rw_copier(this, false);
+      iterate_roots(&rw_copier);
+    }
+
+    // ro space starts ...
+    DumpRegion* ro_space = MetaspaceShared::read_only_dump_space();
+    {
+      start_dump_space(ro_space);
+
+      // shallow-copy RO objects, if necessary
+      ResourceMark rm;
+      ShallowCopier ro_copier(this, true);
+      iterate_roots(&ro_copier);
+    }
+
+    size_t bitmap_size = pointer_delta(current_dump_space()->top(),
+                                       _alloc_bottom, sizeof(address));
+    _ptrmap.initialize(bitmap_size);
+
+    {
+      log_info(cds)("Relocating embedded pointers ... ");
+      ResourceMark rm;
+      ShallowCopyEmbeddedRefRelocator emb_reloc(this);
+      iterate_roots(&emb_reloc);
+    }
+
+    {
+      log_info(cds)("Relocating external roots ... ");
+      ResourceMark rm;
+      ExternalRefUpdater ext_reloc(this);
+      iterate_roots(&ext_reloc);
+    }
+
+    verify_estimate_size(_estimated_metsapceobj_bytes, "MetaspaceObjs");
+
+    char* read_only_tables_start;
+    {
+      set_symbols_permanent();
+
+      // Write the symbol table and system dictionaries to the RO space.
+      // Note that these tables still point to the *original* objects
+      // (because they were not processed by ExternalRefUpdater), so
+      // they would need to call DynamicArchive::original_to_target() to
+      // get the correct addresses.
+      assert(current_dump_space() == ro_space, "Must be RO space");
+      SymbolTable::write_to_archive(false);
+      SystemDictionaryShared::write_to_archive(false);
+
+      read_only_tables_start = ro_space->top();
+      WriteClosure wc(ro_space);
+      SymbolTable::serialize_shared_table_header(&wc, false);
+      SystemDictionaryShared::serialize_dictionary_headers(&wc, false);
+    }
+
+    verify_estimate_size(_estimated_hashtable_bytes, "Hashtables");
+
+    // mc space starts ...
+    {
+      start_dump_space(MetaspaceShared::misc_code_dump_space());
+      make_trampolines();
+    }
+
+    verify_estimate_size(_estimated_trampoline_bytes, "Trampolines");
+
+    make_klasses_shareable();
+
+    {
+      log_info(cds)("Final relocation of pointers ... ");
+      ResourceMark rm;
+      PointerMarker marker(this);
+      iterate_roots(&marker);
+      relocate_buffer_to_target();
+    }
+
+    write_archive(read_only_tables_start);
+
+    assert(_num_dump_regions_used == _total_dump_regions, "must be");
+    verify_universe("After CDS dynamic dump");
+  }
+
+  void iterate_roots(MetaspaceClosure* it) {
+    int i;
+    int num_klasses = _klasses->length();
+    for (i = 0; i < num_klasses; i++) {
+      it->push(&_klasses->at(i));
+    }
+
+    int num_symbols = _symbols->length();
+    for (i = 0; i < num_symbols; i++) {
+      it->push(&_symbols->at(i));
+    }
+
+    _header->_shared_path_table.metaspace_pointers_do(it);
+
+    // Do not call these again, as we have already collected all the classes and symbols
+    // that we want to archive. Also, these calls would corrupt the tables when
+    // ExternalRefUpdater is used.
+    //
+    // SystemDictionaryShared::dumptime_classes_do(it);
+    // SymbolTable::metaspace_pointers_do(it);
+
+    it->finish();
+  }
+};
+
+size_t DynamicArchiveBuilder::estimate_archive_size() {
+  // size of the symbol table and two dictionaries, plus the RunTimeSharedClassInfo's
+  _estimated_hashtable_bytes = 0;
+  _estimated_hashtable_bytes += SymbolTable::estimate_size_for_archive();
+  _estimated_hashtable_bytes += SystemDictionaryShared::estimate_size_for_archive();
+
+  _estimated_trampoline_bytes = estimate_trampoline_size();
+
+  size_t total = 0;
+
+  total += _estimated_metsapceobj_bytes;
+  total += _estimated_hashtable_bytes;
+  total += _estimated_trampoline_bytes;
+
+  // allow fragmentation at the end of each dump region
+  total += _total_dump_regions * reserve_alignment();
+
+  return align_up(total, reserve_alignment());
+}
+
+address DynamicArchiveBuilder::reserve_space_and_init_buffer_to_target_delta() {
+  size_t total = estimate_archive_size();
+  bool large_pages = false; // No large pages when dumping the CDS archive.
+  size_t increment = align_up(1*G, reserve_alignment());
+  char* addr = (char*)align_up(CompressedKlassPointers::base() + MetaspaceSize + increment,
+                               reserve_alignment());
+
+  ReservedSpace* rs = MetaspaceShared::reserve_shared_rs(
+                          total, reserve_alignment(), large_pages, addr);
+  while (!rs->is_reserved() && (addr + increment > addr)) {
+    addr += increment;
+    rs = MetaspaceShared::reserve_shared_rs(
+           total, reserve_alignment(), large_pages, addr);
+  }
+  if (!rs->is_reserved()) {
+    log_error(cds, dynamic)("Failed to reserve %d bytes of output buffer.", (int)total);
+    vm_direct_exit(0);
+  }
+
+  address buffer_base = (address)rs->base();
+  log_info(cds, dynamic)("Reserved output buffer space at    : " PTR_FORMAT " [%d bytes]",
+                         p2i(buffer_base), (int)total);
+
+  // At run time, we will mmap the dynamic archive at target_space_bottom.
+  // However, at dump time, we may not be able to write into the target_space,
+  // as it's occupied by dynamically loaded Klasses. So we allocate a buffer
+  // at an arbitrary location chosen by the OS. We will write all the dynamically
+  // archived classes into this buffer. At the final stage of dumping, we relocate
+  // all pointers that are inside the buffer_space to point to their (runtime)
+  // target location inside thetarget_space.
+  address target_space_bottom =
+    (address)align_up(MetaspaceShared::shared_metaspace_top(), reserve_alignment());
+  _buffer_to_target_delta = intx(target_space_bottom) - intx(buffer_base);
+
+  log_info(cds, dynamic)("Target archive space at            : " PTR_FORMAT, p2i(target_space_bottom));
+  log_info(cds, dynamic)("Buffer-space to target-space delta : " PTR_FORMAT, p2i((address)_buffer_to_target_delta));
+
+  return buffer_base;
+}
+
+void DynamicArchiveBuilder::init_header(address reserved_bottom) {
+  _alloc_bottom = reserved_bottom;
+  _last_verified_top = reserved_bottom;
+  _other_region_used_bytes = 0;
+
+  init_first_dump_space(reserved_bottom);
+
+  FileMapInfo* mapinfo = new FileMapInfo(false);
+  _header = (DynamicArchiveHeader*)mapinfo->_header;
+
+  Thread* THREAD = Thread::current();
+  FileMapInfo* base_info = FileMapInfo::current_info();
+  int* crc = _header->_base_archive_crc;
+  *crc++ = base_info->crc(); // base archive header crc
+  for (int i = 0; i < MetaspaceShared::n_regions; i++) {
+    *crc++ = base_info->space_crc(i);
+  }
+  _header->populate(base_info, os::vm_allocation_granularity());
+}
+
+size_t DynamicArchiveBuilder::estimate_trampoline_size() {
+  size_t total = 0;
+  size_t each_method_bytes =
+    align_up(SharedRuntime::trampoline_size(), BytesPerWord) +
+    align_up(sizeof(AdapterHandlerEntry*), BytesPerWord);
+
+  for (int i = 0; i < _klasses->length(); i++) {
+    InstanceKlass* ik = _klasses->at(i);
+    Array<Method*>* methods = ik->methods();
+    total += each_method_bytes * methods->length();
+  }
+  return total;
+}
+
+void DynamicArchiveBuilder::make_trampolines() {
+  for (int i = 0; i < _klasses->length(); i++) {
+    InstanceKlass* ik = _klasses->at(i);
+    Array<Method*>* methods = ik->methods();
+    for (int j = 0; j < methods->length(); j++) {
+      Method* m = methods->at(j);
+      address c2i_entry_trampoline =
+        (address)MetaspaceShared::misc_code_space_alloc(SharedRuntime::trampoline_size());
+      m->set_from_compiled_entry(to_target(c2i_entry_trampoline));
+      AdapterHandlerEntry** adapter_trampoline =
+        (AdapterHandlerEntry**)MetaspaceShared::misc_code_space_alloc(sizeof(AdapterHandlerEntry*));
+      *adapter_trampoline = NULL;
+      m->set_adapter_trampoline(to_target(adapter_trampoline));
+    }
+  }
+}
+
+void DynamicArchiveBuilder::make_klasses_shareable() {
+  int i, count = _klasses->length();
+
+  for (i = 0; i < count; i++) {
+    InstanceKlass* ik = _klasses->at(i);
+    sort_methods(ik);
+  }
+
+  for (i = 0; i < count; i++) {
+    InstanceKlass* ik = _klasses->at(i);
+    ClassLoaderData *cld = ik->class_loader_data();
+    if (cld->is_boot_class_loader_data()) {
+      ik->set_class_loader_type(ClassLoader::BOOT_LOADER);
+    }
+    else if (cld->is_platform_class_loader_data()) {
+      ik->set_class_loader_type(ClassLoader::PLATFORM_LOADER);
+    }
+    else if (cld->is_system_class_loader_data()) {
+      ik->set_class_loader_type(ClassLoader::APP_LOADER);
+    }
+
+    MetaspaceShared::rewrite_nofast_bytecodes_and_calculate_fingerprints(ik);
+    ik->remove_unshareable_info();
+
+    assert(ik->array_klasses() == NULL, "sanity");
+
+    if (log_is_enabled(Debug, cds, dynamic)) {
+      ResourceMark rm;
+      log_debug(cds, dynamic)("klasses[%4i] = " PTR_FORMAT " %s", i, p2i(to_target(ik)), ik->external_name());
+    }
+  }
+}
+
+// The address order of the copied Symbols may be different than when the original
+// klasses were created. Re-sort all the tables. See Method::sort_methods().
+void DynamicArchiveBuilder::sort_methods(InstanceKlass* ik) const {
+  assert(ik != NULL, "DynamicArchiveBuilder currently doesn't support dumping the base archive");
+  if (MetaspaceShared::is_in_shared_metaspace(ik)) {
+    // We have reached a supertype that's already in the base archive
+    return;
+  }
+
+  if (ik->java_mirror() == NULL) {
+    // NULL mirror means this class has already been visited and methods are already sorted
+    return;
+  }
+  ik->remove_java_mirror();
+
+  if (log_is_enabled(Debug, cds, dynamic)) {
+    ResourceMark rm;
+    log_debug(cds, dynamic)("sorting methods for " PTR_FORMAT " %s", p2i(to_target(ik)), ik->external_name());
+  }
+
+  // Make sure all supertypes have been sorted
+  sort_methods(ik->java_super());
+  Array<InstanceKlass*>* interfaces = ik->local_interfaces();
+  int len = interfaces->length();
+  for (int i = 0; i < len; i++) {
+    sort_methods(interfaces->at(i));
+  }
+
+#ifdef ASSERT
+  {
+    for (int m = 0; m < ik->methods()->length(); m++) {
+      Symbol* name = ik->methods()->at(m)->name();
+      assert(MetaspaceShared::is_in_shared_metaspace(name) || is_in_buffer_space(name), "must be");
+    }
+  }
+#endif
+
+  Thread* THREAD = Thread::current();
+  Method::sort_methods(ik->methods());
+  if (ik->default_methods() != NULL) {
+    Method::sort_methods(ik->default_methods(), /*set_idnums=*/false);
+  }
+  ik->vtable().initialize_vtable(true, THREAD); assert(!HAS_PENDING_EXCEPTION, "cannot fail");
+  ik->itable().initialize_itable(true, THREAD); assert(!HAS_PENDING_EXCEPTION, "cannot fail");
+}
+
+void DynamicArchiveBuilder::set_symbols_permanent() {
+  int count = _symbols->length();
+  for (int i=0; i<count; i++) {
+    Symbol* s = _symbols->at(i);
+    s->set_permanent();
+
+    if (log_is_enabled(Trace, cds, dynamic)) {
+      ResourceMark rm;
+      log_trace(cds, dynamic)("symbols[%4i] = " PTR_FORMAT " %s", i, p2i(to_target(s)), s->as_quoted_ascii());
+    }
+  }
+}
+
+class RelocateBufferToTarget: public BitMapClosure {
+  DynamicArchiveBuilder *_builder;
+  address* _buffer_bottom;
+  intx _buffer_to_target_delta;
+ public:
+  RelocateBufferToTarget(DynamicArchiveBuilder* builder, address* bottom, intx delta) :
+    _builder(builder), _buffer_bottom(bottom), _buffer_to_target_delta(delta) {}
+
+  bool do_bit(size_t offset) {
+    address* p = _buffer_bottom + offset;
+    assert(_builder->is_in_buffer_space(p), "pointer must live in buffer space");
+
+    address old_ptr = *p;
+    if (_builder->is_in_buffer_space(old_ptr)) {
+      address new_ptr = old_ptr + _buffer_to_target_delta;
+      log_trace(cds, dynamic)("Final patch: @%6d [" PTR_FORMAT " -> " PTR_FORMAT "] " PTR_FORMAT " => " PTR_FORMAT,
+                              (int)offset, p2i(p), p2i(_builder->to_target(p)),
+                              p2i(old_ptr), p2i(new_ptr));
+      *p = new_ptr;
+    }
+
+    return true; // keep iterating
+  }
+};
+
+
+void DynamicArchiveBuilder::relocate_buffer_to_target() {
+  RelocateBufferToTarget patcher(this, (address*)_alloc_bottom, _buffer_to_target_delta);
+  _ptrmap.iterate(&patcher);
+
+  Array<u8>* table = _header->_shared_path_table.table();
+  table = to_target(table);
+ _header->_shared_path_table.set_table(table);
+}
+
+static void write_archive_info(FileMapInfo* dynamic_info, DynamicArchiveHeader *header) {
+  dynamic_info->write_header();
+  dynamic_info->align_file_position();
+  dynamic_info->write_region(MetaspaceShared::rw,
+                             MetaspaceShared::read_write_dump_space()->base(),
+                             MetaspaceShared::read_write_dump_space()->used(),
+                             /*read_only=*/false,/*allow_exec=*/false);
+  dynamic_info->write_region(MetaspaceShared::ro,
+                             MetaspaceShared::read_only_dump_space()->base(),
+                             MetaspaceShared::read_only_dump_space()->used(),
+                             /*read_only=*/true, /*allow_exec=*/false);
+  dynamic_info->write_region(MetaspaceShared::mc,
+                             MetaspaceShared::misc_code_dump_space()->base(),
+                             MetaspaceShared::misc_code_dump_space()->used(),
+                             /*read_only=*/false,/*allow_exec=*/true);
+}
+
+void DynamicArchiveBuilder::write_archive(char* read_only_tables_start) {
+  int num_klasses = _klasses->length();
+  int num_symbols = _symbols->length();
+
+  _header->_read_only_tables_start = to_target(read_only_tables_start);
+
+  FileMapInfo* dynamic_info = FileMapInfo::dynamic_info();
+  assert(dynamic_info != NULL, "Sanity");
+
+  // Populate the file offsets, region crcs, etc. No data is written out.
+  write_archive_info(dynamic_info, _header);
+
+  // the header will no longer change. Compute its crc.
+  dynamic_info->set_header_crc(dynamic_info->compute_header_crc());
+
+  // Now write the archived data including the file offsets.
+  const char* archive_name = Arguments::GetSharedDynamicArchivePath();
+  dynamic_info->open_for_write(archive_name);
+  write_archive_info(dynamic_info, _header);
+  dynamic_info->close();
+
+
+  address base = to_target(_alloc_bottom);
+  address top  = address(current_dump_space()->top()) + _buffer_to_target_delta;
+  int file_size = int(top - base);
+
+  log_info(cds, dynamic)("Written dynamic archive " PTR_FORMAT " - " PTR_FORMAT " [%d bytes header, %d bytes total]",
+                         p2i(base), p2i(top), (int)_header->_header_size, file_size);
+  log_info(cds, dynamic)("%d klasses; %d symbols", num_klasses, num_symbols);
+}
+
+
+class VM_PopulateDynamicDumpSharedSpace: public VM_Operation {
+  DynamicArchiveBuilder* _builder;
+public:
+  VM_PopulateDynamicDumpSharedSpace(DynamicArchiveBuilder* builder) : _builder(builder) {}
+  VMOp_Type type() const { return VMOp_PopulateDumpSharedSpace; }
+  void doit() {
+    ResourceMark rm;
+    if (SystemDictionaryShared::empty_dumptime_table()) {
+      log_warning(cds, dynamic)("There is no class to be included in the dynamic archive.");
+      return;
+    }
+    if (AllowArchivingWithJavaAgent) {
+      warning("This archive was created with AllowArchivingWithJavaAgent. It should be used "
+              "for testing purposes only and should not be used in a production environment");
+    }
+    FileMapInfo::check_nonempty_dir_in_shared_path_table();
+
+    _builder->doit();
+  }
+};
+
+
+void DynamicArchive::dump() {
+  if (Arguments::GetSharedDynamicArchivePath() == NULL) {
+    log_warning(cds, dynamic)("SharedDynamicArchivePath is not specified");
+    return;
+  }
+
+  DynamicArchiveBuilder builder;
+  _builder = &builder;
+  VM_PopulateDynamicDumpSharedSpace op(&builder);
+  VMThread::execute(&op);
+  _builder = NULL;
+}
+
+address DynamicArchive::original_to_buffer_impl(address orig_obj) {
+  assert(DynamicDumpSharedSpaces, "must be");
+  address buff_obj = _builder->get_new_loc(orig_obj);
+  assert(buff_obj != NULL, "orig_obj must be used by the dynamic archive");
+  assert(buff_obj != orig_obj, "call this only when you know orig_obj must be copied and not just referenced");
+  assert(_builder->is_in_buffer_space(buff_obj), "must be");
+  return buff_obj;
+}
+
+address DynamicArchive::buffer_to_target_impl(address buff_obj) {
+  assert(DynamicDumpSharedSpaces, "must be");
+  assert(_builder->is_in_buffer_space(buff_obj), "must be");
+  return _builder->to_target(buff_obj);
+}
+
+address DynamicArchive::original_to_target_impl(address orig_obj) {
+  assert(DynamicDumpSharedSpaces, "must be");
+  if (MetaspaceShared::is_in_shared_metaspace(orig_obj)) {
+    // This happens when the top archive points to a Symbol* in the base archive.
+    return orig_obj;
+  }
+  address buff_obj = _builder->get_new_loc(orig_obj);
+  assert(buff_obj != NULL, "orig_obj must be used by the dynamic archive");
+  if (buff_obj == orig_obj) {
+    // We are storing a pointer to an original object into the dynamic buffer. E.g.,
+    // a Symbol* that used by both the base and top archives.
+    assert(MetaspaceShared::is_in_shared_metaspace(orig_obj), "must be");
+    return orig_obj;
+  } else {
+    return _builder->to_target(buff_obj);
+  }
+}
+
+uintx DynamicArchive::object_delta_uintx(void* buff_obj) {
+  assert(DynamicDumpSharedSpaces, "must be");
+  address target_obj = _builder->to_target_no_check(address(buff_obj));
+  assert(uintx(target_obj) >= SharedBaseAddress, "must be");
+  return uintx(target_obj) - SharedBaseAddress;
+}
+
+bool DynamicArchive::is_in_target_space(void *obj) {
+  assert(DynamicDumpSharedSpaces, "must be");
+  return _builder->is_in_target_space(obj);
+}
+
+
+static DynamicArchiveHeader *_dynamic_header = NULL;
+DynamicArchiveBuilder* DynamicArchive::_builder = NULL;
+
+void DynamicArchive::map_failed(FileMapInfo* mapinfo) {
+  if (mapinfo->_header != NULL) {
+    os::free(mapinfo->_header);
+  }
+  delete mapinfo;
+}
+
+// Returns the top of the mapped address space
+address DynamicArchive::map() {
+  assert(UseSharedSpaces, "Sanity");
+
+  // Create the dynamic archive map info
+  FileMapInfo* mapinfo;
+  const char* filename = Arguments::GetSharedDynamicArchivePath();
+  struct stat st;
+  address result;
+  if ((filename != NULL) && (os::stat(filename, &st) == 0)) {
+    mapinfo = new FileMapInfo(false);
+    if (!mapinfo->open_for_read(filename)) {
+      result = NULL;
+    }
+    result = map_impl(mapinfo);
+    if (result == NULL) {
+      map_failed(mapinfo);
+      mapinfo->restore_shared_path_table();
+    }
+  } else {
+    if (filename != NULL) {
+      log_warning(cds, dynamic)("specified dynamic archive doesn't exist: %s", filename);
+    }
+    result = NULL;
+  }
+  return result;
+}
+
+address DynamicArchive::map_impl(FileMapInfo* mapinfo) {
+
+
+  // Read header
+  if (!mapinfo->initialize(false)) {
+    return NULL;
+  }
+
+  _dynamic_header = (DynamicArchiveHeader*)mapinfo->header();
+
+  int regions[] = {MetaspaceShared::rw,
+                   MetaspaceShared::ro,
+                   MetaspaceShared::mc};
+
+  size_t len = sizeof(regions)/sizeof(int);
+  char* saved_base[] = {NULL, NULL, NULL};
+  char* top = mapinfo->map_regions(regions, saved_base, len);
+  if (top == NULL) {
+    mapinfo->unmap_regions(regions, saved_base, len);
+    FileMapInfo::fail_continue("Unable to use dynamic archive. Failed map_region for using -Xshare:on.");
+    return NULL;
+  }
+
+  if (!validate(mapinfo)) {
+    return NULL;
+  }
+
+  if (_dynamic_header == NULL) {
+    return NULL;
+  }
+
+  intptr_t* buffer = (intptr_t*)_dynamic_header->_read_only_tables_start;
+  ReadClosure rc(&buffer);
+  SymbolTable::serialize_shared_table_header(&rc, false);
+  SystemDictionaryShared::serialize_dictionary_headers(&rc, false);
+
+  return (address)top;
+}
+
+bool DynamicArchive::validate(FileMapInfo* dynamic_info) {
+  // Check if the recorded base archive matches with the current one
+  FileMapInfo* base_info = FileMapInfo::current_info();
+  DynamicArchiveHeader* dynamic_header = (DynamicArchiveHeader*)dynamic_info->header();
+  int* crc = dynamic_header->_base_archive_crc;
+
+  // Check the header crc
+  if (*crc++ != base_info->crc()) {
+    FileMapInfo::fail_continue("Archive header checksum verification failed.");
+    return false;
+  }
+
+  // Check each space's crc
+  for (int i = 0; i < MetaspaceShared::n_regions; i++) {
+    if (*crc++ != base_info->space_crc(i)) {
+      FileMapInfo::fail_continue("Archive region #%d checksum verification failed.", i);
+      return false;
+    }
+  }
+
+  // Validate the dynamic archived shared path table, and set the global
+  // _shared_path_table to that.
+  if (!dynamic_info->validate_shared_path_table()) {
+    return false;
+  }
+  return true;
+}
+
+bool DynamicArchive::is_mapped() {
+  return (_dynamic_header != NULL);
+}
+
+void DynamicArchive::disable() {
+  _dynamic_header = NULL;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/memory/dynamicArchive.hpp	Thu May 23 11:07:37 2019 +0100
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 2019, 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.
+ *
+ */
+
+#ifndef SHARE_VM_MEMORY_DYNAMICARCHIVE_HPP
+#define SHARE_VM_MEMORY_DYNAMICARCHIVE_HPP
+
+#if INCLUDE_CDS
+
+#include "classfile/compactHashtable.hpp"
+#include "memory/allocation.hpp"
+#include "memory/filemap.hpp"
+#include "memory/memRegion.hpp"
+#include "memory/virtualspace.hpp"
+#include "oops/oop.hpp"
+#include "utilities/exceptions.hpp"
+#include "utilities/macros.hpp"
+#include "utilities/resourceHash.hpp"
+
+// We want to include all archive header information in the dynamic archive.
+// This helps simplify the process if the base layer archive is missing at
+// dynamic archiving time.
+struct DynamicArchiveHeader : public FileMapHeader {
+  // crc for the base archive header and regions
+  int _base_archive_crc[MetaspaceShared::n_regions+1];
+};
+
+class DynamicArchive : AllStatic {
+  static class DynamicArchiveBuilder* _builder;
+  static address original_to_target_impl(address orig_obj);
+  static address original_to_buffer_impl(address orig_obj);
+  static address buffer_to_target_impl(address buff_obj);
+
+public:
+  static void dump();
+
+  // obj is a copy of a MetaspaceObj, stored in the dumping buffer.
+  //
+  // The return value is the runtime targeted location of this object as
+  // mapped from the dynamic archive.
+  template <typename T> static T buffer_to_target(T buff_obj) {
+    return (T)buffer_to_target_impl(address(buff_obj));
+  }
+
+  // obj is an original MetaspaceObj used by the JVM (e.g., a valid Symbol* in the
+  // SymbolTable).
+  //
+  // The return value is the runtime targeted location of this object as
+  // mapped from the dynamic archive.
+  template <typename T> static T original_to_target(T obj) {
+    return (T)original_to_target_impl(address(obj));
+  }
+
+  // obj is an original MetaspaceObj use by the JVM (e.g., a valid Symbol* in the
+  // SymbolTable).
+  //
+  // The return value is the location of this object in the dump time
+  // buffer space
+  template <typename T> static T original_to_buffer(T obj) {
+    return (T)original_to_buffer_impl(address(obj));
+  }
+
+  // Delta of this object from SharedBaseAddress
+  static uintx object_delta_uintx(void* buff_obj);
+
+  // Does obj point to an address inside the runtime target space of the dynamic
+  // archive?
+  static bool is_in_target_space(void *obj);
+
+  static address map();
+  static bool is_mapped();
+  static bool validate(FileMapInfo* dynamic_info);
+  static void disable();
+private:
+  static address map_impl(FileMapInfo* mapinfo);
+  static void map_failed(FileMapInfo* mapinfo);
+};
+#endif // INCLUDE_CDS
+#endif // SHARE_VM_MEMORY_DYNAMICARCHIVE_HPP
--- a/src/hotspot/share/memory/filemap.cpp	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/share/memory/filemap.cpp	Thu May 23 11:07:37 2019 +0100
@@ -34,6 +34,7 @@
 #include "logging/log.hpp"
 #include "logging/logStream.hpp"
 #include "logging/logMessage.hpp"
+#include "memory/dynamicArchive.hpp"
 #include "memory/filemap.hpp"
 #include "memory/heapShared.inline.hpp"
 #include "memory/iterator.inline.hpp"
@@ -42,6 +43,7 @@
 #include "memory/metaspaceShared.hpp"
 #include "memory/oopFactory.hpp"
 #include "memory/universe.hpp"
+#include "oops/compressedOops.hpp"
 #include "oops/compressedOops.inline.hpp"
 #include "oops/objArrayOop.hpp"
 #include "oops/oop.inline.hpp"
@@ -101,7 +103,12 @@
 void FileMapInfo::fail_continue(const char *msg, ...) {
   va_list ap;
   va_start(ap, msg);
-  MetaspaceShared::set_archive_loading_failed();
+  if (_dynamic_archive_info == NULL) {
+    MetaspaceShared::set_archive_loading_failed();
+  } else {
+    // _dynamic_archive_info has been setup after mapping the base archive
+    DynamicArchive::disable();
+  }
   if (PrintSharedArchiveAndExit && _validating_shared_path_table) {
     // If we are doing PrintSharedArchiveAndExit and some of the classpath entries
     // do not validate, we can still continue "limping" to validate the remaining
@@ -120,9 +127,15 @@
         ls.vprint_cr(msg, ap);
       }
     }
-    UseSharedSpaces = false;
-    assert(current_info() != NULL, "singleton must be registered");
-    current_info()->close();
+    if (_dynamic_archive_info == NULL) {
+      UseSharedSpaces = false;
+      assert(current_info() != NULL, "singleton must be registered");
+      current_info()->close();
+    } else {
+      // We are failing when loading the top archive, but the base archive should
+      // continue to work.
+      log_warning(cds, dynamic)("Unable to use shared archive. The top archive failed to load: %s", _dynamic_archive_info->_full_path);
+    }
   }
   va_end(ap);
 }
@@ -159,20 +172,36 @@
   }
 }
 
-FileMapInfo::FileMapInfo() {
-  assert(_current_info == NULL, "must be singleton"); // not thread safe
-  _current_info = this;
+FileMapInfo::FileMapInfo(bool is_static) {
   memset((void*)this, 0, sizeof(FileMapInfo));
+  _is_static = is_static;
+  size_t header_size;
+  if (is_static) {
+    assert(_current_info == NULL, "must be singleton"); // not thread safe
+    _current_info = this;
+    header_size = sizeof(FileMapHeader);
+  } else {
+    assert(_dynamic_archive_info == NULL, "must be singleton"); // not thread safe
+    _dynamic_archive_info = this;
+    header_size = sizeof(DynamicArchiveHeader);
+  }
+  _header = (FileMapHeader*)os::malloc(header_size, mtInternal);
+  memset((void*)_header, 0, header_size);
+  _header->_header_size = header_size;
+  _header->_version = INVALID_CDS_ARCHIVE_VERSION;
+  _header->_has_platform_or_app_classes = true;
   _file_offset = 0;
   _file_open = false;
-  _header = (FileMapHeader*)os::malloc(sizeof(FileMapHeader), mtInternal);
-  _header->_version = INVALID_CDS_ARCHIVE_VERSION;
-  _header->_has_platform_or_app_classes = true;
 }
 
 FileMapInfo::~FileMapInfo() {
-  assert(_current_info == this, "must be singleton"); // not thread safe
-  _current_info = NULL;
+  if (_is_static) {
+    assert(_current_info == this, "must be singleton"); // not thread safe
+    _current_info = NULL;
+  } else {
+    assert(_dynamic_archive_info == this, "must be singleton"); // not thread safe
+    _dynamic_archive_info = NULL;
+  }
 }
 
 void FileMapInfo::populate_header(size_t alignment) {
@@ -180,7 +209,11 @@
 }
 
 void FileMapHeader::populate(FileMapInfo* mapinfo, size_t alignment) {
-  _magic = CDS_ARCHIVE_MAGIC;
+  if (DynamicDumpSharedSpaces) {
+    _magic = CDS_DYNAMIC_ARCHIVE_MAGIC;
+  } else {
+    _magic = CDS_ARCHIVE_MAGIC;
+  }
   _version = CURRENT_CDS_ARCHIVE_VERSION;
   _alignment = alignment;
   _obj_alignment = ObjectAlignmentInBytes;
@@ -191,9 +224,7 @@
   _max_heap_size = MaxHeapSize;
   _narrow_klass_base = CompressedKlassPointers::base();
   _narrow_klass_shift = CompressedKlassPointers::shift();
-  _shared_path_table_size = mapinfo->_shared_path_table_size;
   _shared_path_table = mapinfo->_shared_path_table;
-  _shared_path_entry_size = mapinfo->_shared_path_entry_size;
   if (HeapShared::is_heap_object_archiving_allowed()) {
     _heap_reserved = Universe::heap()->reserved_region();
   }
@@ -208,6 +239,7 @@
   ClassLoaderExt::finalize_shared_paths_misc_info();
   _app_class_paths_start_index = ClassLoaderExt::app_class_paths_start_index();
   _app_module_paths_start_index = ClassLoaderExt::app_module_paths_start_index();
+  _num_module_paths = ClassLoader::num_module_path_entries();
   _max_used_path_index = ClassLoaderExt::max_used_path_index();
 
   _verify_local = BytecodeVerificationLocal;
@@ -215,10 +247,13 @@
   _has_platform_or_app_classes = ClassLoaderExt::has_platform_or_app_classes();
   _shared_base_address = SharedBaseAddress;
   _allow_archiving_with_java_agent = AllowArchivingWithJavaAgent;
+  // the following 2 fields will be set in write_header for dynamic archive header
+  _base_archive_name_size = 0;
+  _base_archive_is_default = false;
 }
 
 void SharedClassPathEntry::init(const char* name, bool is_modules_image, TRAPS) {
-  assert(DumpSharedSpaces, "dump time only");
+  assert(DumpSharedSpaces || DynamicDumpSharedSpaces, "dump time only");
   _timestamp = 0;
   _filesize  = 0;
 
@@ -297,6 +332,7 @@
     // If PrintSharedArchiveAndExit is enabled, don't report failure to the
     // caller. Please see above comments for more details.
     ok = true;
+    MetaspaceShared::set_archive_loading_failed();
   }
   return ok;
 }
@@ -306,8 +342,27 @@
   it->push(&_manifest);
 }
 
+void SharedPathTable::metaspace_pointers_do(MetaspaceClosure* it) {
+  it->push(&_table);
+  for (int i=0; i<_size; i++) {
+    path_at(i)->metaspace_pointers_do(it);
+  }
+}
+
+void SharedPathTable::dumptime_init(ClassLoaderData* loader_data, Thread* THREAD) {
+  size_t entry_size = sizeof(SharedClassPathEntry);
+  int num_boot_classpath_entries = ClassLoader::num_boot_classpath_entries();
+  int num_app_classpath_entries = ClassLoader::num_app_classpath_entries();
+  int num_module_path_entries = ClassLoader::num_module_path_entries();
+  int num_entries = num_boot_classpath_entries + num_app_classpath_entries + num_module_path_entries;
+  size_t bytes = entry_size * num_entries;
+
+  _table = MetadataFactory::new_array<u8>(loader_data, (int)(bytes + 7 / 8), THREAD);
+  _size = num_entries;
+}
+
 void FileMapInfo::allocate_shared_path_table() {
-  assert(DumpSharedSpaces, "Sanity");
+  assert(DumpSharedSpaces || DynamicDumpSharedSpaces, "Sanity");
 
   Thread* THREAD = Thread::current();
   ClassLoaderData* loader_data = ClassLoaderData::the_null_class_loader_data();
@@ -316,16 +371,7 @@
   assert(jrt != NULL,
          "No modular java runtime image present when allocating the CDS classpath entry table");
 
-  size_t entry_size = sizeof(SharedClassPathEntry); // assert ( should be 8 byte aligned??)
-  int num_boot_classpath_entries = ClassLoader::num_boot_classpath_entries();
-  int num_app_classpath_entries = ClassLoader::num_app_classpath_entries();
-  int num_module_path_entries = ClassLoader::num_module_path_entries();
-  int num_entries = num_boot_classpath_entries + num_app_classpath_entries + num_module_path_entries;
-  size_t bytes = entry_size * num_entries;
-
-  _shared_path_table = MetadataFactory::new_array<u8>(loader_data, (int)(bytes + 7 / 8), THREAD);
-  _shared_path_table_size = num_entries;
-  _shared_path_entry_size = entry_size;
+  _shared_path_table.dumptime_init(loader_data, THREAD);
 
   // 1. boot class path
   int i = 0;
@@ -343,7 +389,7 @@
     cpe = ClassLoader::get_next_boot_classpath_entry(cpe);
     i++;
   }
-  assert(i == num_boot_classpath_entries,
+  assert(i == ClassLoader::num_boot_classpath_entries(),
          "number of boot class path entry mismatch");
 
   // 2. app class path
@@ -369,15 +415,15 @@
     mpe = mpe->next();
     i++;
   }
-  assert(i == num_entries, "number of shared path entry mismatch");
+  assert(i == _shared_path_table.size(), "number of shared path entry mismatch");
 }
 
 void FileMapInfo::check_nonempty_dir_in_shared_path_table() {
-  assert(DumpSharedSpaces, "dump time only");
+  assert(DumpSharedSpaces || DynamicDumpSharedSpaces, "dump time only");
 
   bool has_nonempty_dir = false;
 
-  int last = _shared_path_table_size - 1;
+  int last = _shared_path_table.size() - 1;
   if (last > ClassLoaderExt::max_used_path_index()) {
      // no need to check any path beyond max_used_path_index
      last = ClassLoaderExt::max_used_path_index();
@@ -479,9 +525,29 @@
   assert(UseSharedSpaces, "runtime only");
 
   _validating_shared_path_table = true;
+
+  // Load the shared path table info from the archive header
   _shared_path_table = _header->_shared_path_table;
-  _shared_path_entry_size = _header->_shared_path_entry_size;
-  _shared_path_table_size = _header->_shared_path_table_size;
+  if (DynamicDumpSharedSpaces) {
+    // Only support dynamic dumping with the usage of the default CDS archive
+    // or a simple base archive.
+    // If the base layer archive contains additional path component besides
+    // the runtime image and the -cp, dynamic dumping is disabled.
+    //
+    // When dynamic archiving is enabled, the _shared_path_table is overwritten
+    // to include the application path and stored in the top layer archive.
+    assert(shared_path(0)->is_modules_image(), "first shared_path must be the modules image");
+    if (_header->_app_class_paths_start_index > 1) {
+      DynamicDumpSharedSpaces = false;
+      warning(
+        "Dynamic archiving is disabled because base layer archive has appended boot classpath");
+    }
+    if (_header->_num_module_paths > 0) {
+      DynamicDumpSharedSpaces = false;
+      warning(
+        "Dynamic archiving is disabled because base layer archive has module path");
+    }
+  }
 
   int module_paths_start_index = _header->_app_module_paths_start_index;
 
@@ -491,14 +557,18 @@
       if (shared_path(i)->validate()) {
         log_info(class, path)("ok");
       } else {
-        assert(!UseSharedSpaces, "UseSharedSpaces should be disabled");
+        if (_dynamic_archive_info != NULL && _dynamic_archive_info->_is_static) {
+          assert(!UseSharedSpaces, "UseSharedSpaces should be disabled");
+        }
         return false;
       }
     } else if (i >= module_paths_start_index) {
       if (shared_path(i)->validate(false /* not a class path entry */)) {
         log_info(class, path)("ok");
       } else {
-        assert(!UseSharedSpaces, "UseSharedSpaces should be disabled");
+        if (_dynamic_archive_info != NULL && _dynamic_archive_info->_is_static) {
+          assert(!UseSharedSpaces, "UseSharedSpaces should be disabled");
+        }
         return false;
       }
     }
@@ -510,18 +580,151 @@
   if (_classpath_entries_for_jvmti != NULL) {
     os::free(_classpath_entries_for_jvmti);
   }
-  size_t sz = sizeof(ClassPathEntry*) *  _shared_path_table_size;
+  size_t sz = sizeof(ClassPathEntry*) * get_number_of_shared_paths();
   _classpath_entries_for_jvmti = (ClassPathEntry**)os::malloc(sz, mtClass);
-  memset(_classpath_entries_for_jvmti, 0, sz);
+  memset((void*)_classpath_entries_for_jvmti, 0, sz);
 #endif
 
   return true;
 }
 
+bool FileMapInfo::same_files(const char* file1, const char* file2) {
+  if (strcmp(file1, file2) == 0) {
+    return true;
+  }
+
+  bool is_same = false;
+  // if the two paths diff only in case
+  struct stat st1;
+  struct stat st2;
+  int ret1;
+  int ret2;
+  ret1 = os::stat(file1, &st1);
+  ret2 = os::stat(file2, &st2);
+  if (ret1 < 0 || ret2 < 0) {
+    // one of the files is invalid. So they are not the same.
+    is_same = false;
+  } else if (st1.st_dev != st2.st_dev || st1.st_ino != st2.st_ino) {
+    // different files
+    is_same = false;
+#ifndef _WINDOWS
+  } else if (st1.st_dev == st2.st_dev && st1.st_ino == st2.st_ino) {
+    // same files
+    is_same = true;
+#else
+  } else if ((st1.st_size == st2.st_size) && (st1.st_ctime == st2.st_ctime) &&
+             (st1.st_mtime == st2.st_mtime)) {
+    // same files
+    is_same = true;
+#endif
+  }
+  return is_same;
+}
+
+bool FileMapInfo::check_archive(const char* archive_name, bool is_static) {
+  int fd = os::open(archive_name, O_RDONLY | O_BINARY, 0);
+  if (fd < 0) {
+    // do not vm_exit_during_initialization here because Arguments::init_shared_archive_paths()
+    // requires a shared archive name. The open_for_read() function will log a message regarding
+    // failure in opening a shared archive.
+    return false;
+  }
+
+  size_t sz = is_static ? sizeof(FileMapHeader) : sizeof(DynamicArchiveHeader);
+  void* header = os::malloc(sz, mtInternal);
+  memset(header, 0, sz);
+  size_t n = os::read(fd, header, (unsigned int)sz);
+  if (n != sz) {
+    os::free(header);
+    os::close(fd);
+    vm_exit_during_initialization("Unable to read header from shared archive", archive_name);
+    return false;
+  }
+  if (is_static) {
+    FileMapHeader* static_header = (FileMapHeader*)header;
+    if (static_header->_magic != CDS_ARCHIVE_MAGIC) {
+      os::free(header);
+      os::close(fd);
+      vm_exit_during_initialization("Not a base shared archive", archive_name);
+      return false;
+    }
+  } else {
+    DynamicArchiveHeader* dynamic_header = (DynamicArchiveHeader*)header;
+    if (dynamic_header->_magic != CDS_DYNAMIC_ARCHIVE_MAGIC) {
+      os::free(header);
+      os::close(fd);
+      vm_exit_during_initialization("Not a top shared archive", archive_name);
+      return false;
+    }
+  }
+  os::free(header);
+  os::close(fd);
+  return true;
+}
+
+bool FileMapInfo::get_base_archive_name_from_header(const char* archive_name,
+                                                    int* size, char** base_archive_name) {
+  int fd = os::open(archive_name, O_RDONLY | O_BINARY, 0);
+  if (fd < 0) {
+    *size = 0;
+    return false;
+  }
+
+  // read the header as a dynamic archive header
+  size_t sz = sizeof(DynamicArchiveHeader);
+  DynamicArchiveHeader* dynamic_header = (DynamicArchiveHeader*)os::malloc(sz, mtInternal);
+  size_t n = os::read(fd, dynamic_header, (unsigned int)sz);
+  if (n != sz) {
+    fail_continue("Unable to read the file header.");
+    os::free(dynamic_header);
+    os::close(fd);
+    return false;
+  }
+  if (dynamic_header->_magic != CDS_DYNAMIC_ARCHIVE_MAGIC) {
+    // Not a dynamic header, no need to proceed further.
+    *size = 0;
+    os::free(dynamic_header);
+    os::close(fd);
+    return false;
+  }
+  if (dynamic_header->_base_archive_is_default) {
+    *base_archive_name = Arguments::get_default_shared_archive_path();
+  } else {
+    // skip over the _paths_misc_info
+    sz = dynamic_header->_paths_misc_info_size;
+    lseek(fd, (long)sz, SEEK_CUR);
+    // read the base archive name
+    size_t name_size = dynamic_header->_base_archive_name_size;
+    if (name_size == 0) {
+      os::free(dynamic_header);
+      os::close(fd);
+      return false;
+    }
+    *base_archive_name = NEW_C_HEAP_ARRAY(char, name_size, mtInternal);
+    n = os::read(fd, *base_archive_name, (unsigned int)name_size);
+    if (n != name_size) {
+      fail_continue("Unable to read the base archive name from the header.");
+      FREE_C_HEAP_ARRAY(char, *base_archive_name);
+      *base_archive_name = NULL;
+      os::free(dynamic_header);
+      os::close(fd);
+      return false;
+    }
+  }
+
+  os::free(dynamic_header);
+  os::close(fd);
+  return true;
+}
+
+void FileMapInfo::restore_shared_path_table() {
+  _shared_path_table = _current_info->_header->_shared_path_table;
+}
+
 // Read the FileMapInfo information from the file.
 
-bool FileMapInfo::init_from_file(int fd) {
-  size_t sz = sizeof(FileMapHeader);
+bool FileMapInfo::init_from_file(int fd, bool is_static) {
+  size_t sz = is_static ? sizeof(FileMapHeader) : sizeof(DynamicArchiveHeader);
   size_t n = os::read(fd, _header, (unsigned int)sz);
   if (n != sz) {
     fail_continue("Unable to read the file header.");
@@ -531,14 +734,10 @@
     fail_continue("The shared archive file has the wrong version.");
     return false;
   }
-  _file_offset = (long)n;
+  _file_offset = n;
 
   size_t info_size = _header->_paths_misc_info_size;
-  _paths_misc_info = NEW_C_HEAP_ARRAY_RETURN_NULL(char, info_size, mtClass);
-  if (_paths_misc_info == NULL) {
-    fail_continue("Unable to read the file header.");
-    return false;
-  }
+  _paths_misc_info = NEW_C_HEAP_ARRAY(char, info_size, mtClass);
   n = os::read(fd, _paths_misc_info, (unsigned int)info_size);
   if (n != info_size) {
     fail_continue("Unable to read the shared path info header.");
@@ -546,29 +745,45 @@
     _paths_misc_info = NULL;
     return false;
   }
+  _file_offset += n + _header->_base_archive_name_size; // accounts for the size of _base_archive_name
 
-  size_t len = lseek(fd, 0, SEEK_END);
-  CDSFileMapRegion* si = space_at(MetaspaceShared::last_valid_region);
-  // The last space might be empty
-  if (si->_file_offset > len || len - si->_file_offset < si->_used) {
-    fail_continue("The shared archive file has been truncated.");
-    return false;
+  if (is_static) {
+    if (_header->_magic != CDS_ARCHIVE_MAGIC) {
+      fail_continue("Incorrect static archive magic number");
+      return false;
+    }
+    // just checking the last region is sufficient since the archive is written
+    // in sequential order
+    size_t len = lseek(fd, 0, SEEK_END);
+    CDSFileMapRegion* si = space_at(MetaspaceShared::last_valid_region);
+    // The last space might be empty
+    if (si->_file_offset > len || len - si->_file_offset < si->_used) {
+      fail_continue("The shared archive file has been truncated.");
+      return false;
+    }
+
+    SharedBaseAddress = _header->_shared_base_address;
   }
 
-  _file_offset += (long)n;
-  SharedBaseAddress = _header->_shared_base_address;
   return true;
 }
 
 
 // Read the FileMapInfo information from the file.
-bool FileMapInfo::open_for_read() {
-  _full_path = Arguments::GetSharedArchivePath();
+bool FileMapInfo::open_for_read(const char* path) {
+  if (_file_open) {
+    return true;
+  }
+  if (path == NULL) {
+    _full_path = Arguments::GetSharedArchivePath();
+  } else {
+    _full_path = path;
+  }
   int fd = os::open(_full_path, O_RDONLY | O_BINARY, 0);
   if (fd < 0) {
     if (errno == ENOENT) {
       // Not locating the shared archive is ok.
-      fail_continue("Specified shared archive not found.");
+      fail_continue("Specified shared archive not found (%s).", _full_path);
     } else {
       fail_continue("Failed to open shared archive file (%s).",
                     os::strerror(errno));
@@ -581,11 +796,14 @@
   return true;
 }
 
-
 // Write the FileMapInfo information to the file.
 
-void FileMapInfo::open_for_write() {
-  _full_path = Arguments::GetSharedArchivePath();
+void FileMapInfo::open_for_write(const char* path) {
+  if (path == NULL) {
+    _full_path = Arguments::GetSharedArchivePath();
+  } else {
+    _full_path = path;
+  }
   LogMessage(cds) msg;
   if (msg.is_info()) {
     msg.info("Dumping shared data to file: ");
@@ -593,7 +811,7 @@
   }
 
 #ifdef _WINDOWS  // On Windows, need WRITE permission to remove the file.
-  chmod(_full_path, _S_IREAD | _S_IWRITE);
+    chmod(_full_path, _S_IREAD | _S_IWRITE);
 #endif
 
   // Use remove() to delete the existing file because, on Unix, this will
@@ -617,40 +835,59 @@
 
   _header->_paths_misc_info_size = info_size;
 
-  align_file_position();
-  write_bytes(_header, sizeof(FileMapHeader));
+  char* base_archive_name = NULL;
+  if (_header->_magic == CDS_DYNAMIC_ARCHIVE_MAGIC) {
+    base_archive_name = (char*)Arguments::GetSharedArchivePath();
+    _header->_base_archive_name_size = (int)strlen(base_archive_name) + 1;
+    _header->_base_archive_is_default = FLAG_IS_DEFAULT(SharedArchiveFile);
+  }
+
+  assert(is_file_position_aligned(), "must be");
+  write_bytes(_header, _header->_header_size);
   write_bytes(ClassLoader::get_shared_paths_misc_info(), (size_t)info_size);
+  if (base_archive_name != NULL) {
+    write_bytes(base_archive_name, (size_t)_header->_base_archive_name_size);
+  }
   align_file_position();
 }
 
-
 // Dump region to file.
-
+// This is called twice for each region during archiving, once before
+// the archive file is open (_file_open is false) and once after.
 void FileMapInfo::write_region(int region, char* base, size_t size,
                                bool read_only, bool allow_exec) {
+  assert(DumpSharedSpaces || DynamicDumpSharedSpaces, "Dump time only");
+
   CDSFileMapRegion* si = space_at(region);
+  char* target_base = base;
+  if (DynamicDumpSharedSpaces) {
+    target_base = DynamicArchive::buffer_to_target(base);
+  }
 
   if (_file_open) {
     guarantee(si->_file_offset == _file_offset, "file offset mismatch.");
     log_info(cds)("Shared file region %d: " SIZE_FORMAT_HEX_W(08)
                   " bytes, addr " INTPTR_FORMAT " file offset " SIZE_FORMAT_HEX_W(08),
-                  region, size, p2i(base), _file_offset);
+                  region, size, p2i(target_base), _file_offset);
   } else {
     si->_file_offset = _file_offset;
   }
+
   if (HeapShared::is_heap_region(region)) {
-    assert((base - (char*)CompressedOops::base()) % HeapWordSize == 0, "Sanity");
-    if (base != NULL) {
-      si->_addr._offset = (intx)CompressedOops::encode_not_null((oop)base);
+    assert((target_base - (char*)CompressedKlassPointers::base()) % HeapWordSize == 0, "Sanity");
+    if (target_base != NULL) {
+      si->_addr._offset = (intx)CompressedOops::encode_not_null((oop)target_base);
     } else {
       si->_addr._offset = 0;
     }
   } else {
-    si->_addr._base = base;
+    si->_addr._base = target_base;
   }
   si->_used = size;
   si->_read_only = read_only;
   si->_allow_exec = allow_exec;
+
+  // Use the current 'base' when computing the CRC value and writing out data
   si->_crc = ClassLoader::crc32(0, base, (jint)size);
   if (base != NULL) {
     write_bytes_aligned(base, size);
@@ -734,8 +971,7 @@
   if (_file_open) {
     size_t n = os::write(_fd, buffer, (unsigned int)nbytes);
     if (n != nbytes) {
-      // It is dangerous to leave the corrupted shared archive file around,
-      // close and remove the file. See bug 6372906.
+      // If the shared archive is corrupted, close it and remove it.
       close();
       remove(_full_path);
       fail_stop("Unable to write to shared archive file.");
@@ -744,6 +980,10 @@
   _file_offset += nbytes;
 }
 
+bool FileMapInfo::is_file_position_aligned() const {
+  return _file_offset == align_up(_file_offset,
+                                  os::vm_allocation_granularity());
+}
 
 // Align file position to an allocation unit boundary.
 
@@ -843,6 +1083,30 @@
 static const char* shared_region_name[] = { "MiscData", "ReadWrite", "ReadOnly", "MiscCode", "OptionalData",
                                             "String1", "String2", "OpenArchive1", "OpenArchive2" };
 
+char* FileMapInfo::map_regions(int regions[], char* saved_base[], size_t len) {
+  char* prev_top = NULL;
+  char* curr_base;
+  char* curr_top;
+  int i = 0;
+  for (i = 0; i < (int)len; i++) {
+    curr_base = map_region(regions[i], &curr_top);
+    if (curr_base == NULL) {
+      return NULL;
+    }
+    if (i > 0) {
+      // We require that mc->rw->ro->md->od to be laid out consecutively, with no
+      // gaps between them. That way, we can ensure that the OS won't be able to
+      // allocate any new memory spaces inside _shared_metaspace_{base,top}, which
+      // would mess up the simple comparision in MetaspaceShared::is_in_shared_metaspace().
+      assert(curr_base == prev_top, "must be");
+    }
+    log_info(cds)("Mapped region #%d at base %p top %p", regions[i], curr_base, curr_top);
+    saved_base[i] = curr_base;
+    prev_top = curr_top;
+  }
+  return curr_top;
+}
+
 char* FileMapInfo::map_region(int i, char** top_ret) {
   assert(!HeapShared::is_heap_region(i), "sanity");
   CDSFileMapRegion* si = space_at(i);
@@ -869,6 +1133,7 @@
                               si->_allow_exec);
   if (base == NULL || base != requested_addr) {
     fail_continue("Unable to map %s shared space at required address.", shared_region_name[i]);
+    _memory_mapping_failed = true;
     return NULL;
   }
 #ifdef _WINDOWS
@@ -885,6 +1150,18 @@
   return base;
 }
 
+size_t FileMapInfo::read_bytes(void* buffer, size_t count) {
+  assert(_file_open, "Archive file is not open");
+  size_t n = os::read(_fd, buffer, (unsigned int)count);
+  if (n != count) {
+    // Close the file if there's a problem reading it.
+    close();
+    return 0;
+  }
+  _file_offset += count;
+  return count;
+}
+
 address FileMapInfo::decode_start_address(CDSFileMapRegion* spc, bool with_current_oop_encoding_mode) {
   if (with_current_oop_encoding_mode) {
     return (address)CompressedOops::decode_not_null(offset_of_space(spc));
@@ -1126,13 +1403,13 @@
                     p2i(addr), regions[i].byte_size());
       return false;
     }
-  }
 
-  if (!verify_mapped_heap_regions(first, region_num)) {
-    // dealloc the regions from java heap
-    dealloc_archive_heap_regions(regions, region_num, is_open_archive);
-    log_info(cds)("UseSharedSpaces: mapped heap regions are corrupt");
-    return false;
+    if (VerifySharedSpaces && !region_crc_check(addr, regions[i].byte_size(), si->_crc)) {
+      // dealloc the regions from java heap
+      dealloc_archive_heap_regions(regions, region_num, is_open_archive);
+      log_info(cds)("UseSharedSpaces: mapped heap regions are corrupt");
+      return false;
+    }
   }
 
   // the shared heap data is mapped successfully
@@ -1141,18 +1418,6 @@
   return true;
 }
 
-bool FileMapInfo::verify_mapped_heap_regions(int first, int num) {
-  assert(num > 0, "sanity");
-  if (VerifySharedSpaces) {
-    for (int i = first; i < first + num; i++) {
-      if (!verify_region_checksum(i)) {
-        return false;
-      }
-    }
-  }
-  return true;
-}
-
 void FileMapInfo::patch_archived_heap_embedded_pointers() {
   if (!_heap_pointers_need_patching) {
     return;
@@ -1205,6 +1470,15 @@
 }
 #endif // INCLUDE_CDS_JAVA_HEAP
 
+bool FileMapInfo::region_crc_check(char* buf, size_t size, int expected_crc) {
+  int crc = ClassLoader::crc32(0, buf, (jint)size);
+  if (crc != expected_crc) {
+    fail_continue("Checksum verification failed.");
+    return false;
+  }
+  return true;
+}
+
 bool FileMapInfo::verify_region_checksum(int i) {
   assert(VerifySharedSpaces, "sanity");
 
@@ -1213,19 +1487,16 @@
   if (sz == 0) {
     return true; // no data
   }
-  if ((HeapShared::is_closed_archive_heap_region(i) &&
-       !HeapShared::closed_archive_heap_region_mapped()) ||
-      (HeapShared::is_open_archive_heap_region(i) &&
-       !HeapShared::open_archive_heap_region_mapped())) {
-    return true; // archived heap data is not mapped
+
+  return region_crc_check(region_addr(i), sz, space_at(i)->_crc);
+}
+
+void FileMapInfo::unmap_regions(int regions[], char* saved_base[], size_t len) {
+  for (int i = 0; i < (int)len; i++) {
+    if (saved_base[i] != NULL) {
+      unmap_region(regions[i]);
+    }
   }
-  const char* buf = region_addr(i);
-  int crc = ClassLoader::crc32(0, buf, (jint)sz);
-  if (crc != space_at(i)->_crc) {
-    fail_continue("Checksum verification failed.");
-    return false;
-  }
-  return true;
 }
 
 // Unmap a memory region in the address space.
@@ -1253,19 +1524,15 @@
 }
 
 void FileMapInfo::metaspace_pointers_do(MetaspaceClosure* it) {
-  it->push(&_shared_path_table);
-  for (int i=0; i<_shared_path_table_size; i++) {
-    shared_path(i)->metaspace_pointers_do(it);
-  }
+  _shared_path_table.metaspace_pointers_do(it);
 }
 
-
 FileMapInfo* FileMapInfo::_current_info = NULL;
+FileMapInfo* FileMapInfo::_dynamic_archive_info = NULL;
 bool FileMapInfo::_heap_pointers_need_patching = false;
-Array<u8>* FileMapInfo::_shared_path_table = NULL;
-int FileMapInfo::_shared_path_table_size = 0;
-size_t FileMapInfo::_shared_path_entry_size = 0x1234baad;
+SharedPathTable FileMapInfo::_shared_path_table;
 bool FileMapInfo::_validating_shared_path_table = false;
+bool FileMapInfo::_memory_mapping_failed = false;
 
 // Open the shared archive file, read and validate the header
 // information (version, boot classpath, etc.).  If initialization
@@ -1277,7 +1544,7 @@
 // [1] validate_header() - done here. This checks the header, including _paths_misc_info.
 // [2] validate_shared_path_table - this is done later, because the table is in the RW
 //     region of the archive, which is not mapped yet.
-bool FileMapInfo::initialize() {
+bool FileMapInfo::initialize(bool is_static) {
   assert(UseSharedSpaces, "UseSharedSpaces expected.");
 
   if (JvmtiExport::should_post_class_file_load_hook() && JvmtiExport::has_early_class_hook_env()) {
@@ -1293,8 +1560,8 @@
     return false;
   }
 
-  init_from_file(_fd);
-  if (!validate_header()) {
+  init_from_file(_fd, is_static);
+  if (!validate_header(is_static)) {
     return false;
   }
   return true;
@@ -1315,7 +1582,7 @@
   char* start = (char*)this;
   // start computing from the field after _crc
   char* buf = (char*)&_crc + sizeof(_crc);
-  size_t sz = sizeof(FileMapHeader) - (buf - start);
+  size_t sz = _header_size - (buf - start);
   int crc = ClassLoader::crc32(0, buf, (jint)sz);
   return crc;
 }
@@ -1336,7 +1603,7 @@
     FileMapInfo::fail_continue("The shared archive file is the wrong version.");
     return false;
   }
-  if (_magic != CDS_ARCHIVE_MAGIC) {
+  if (_magic != CDS_ARCHIVE_MAGIC && _magic != CDS_DYNAMIC_ARCHIVE_MAGIC) {
     FileMapInfo::fail_continue("The shared archive file has a bad magic number.");
     return false;
   }
@@ -1401,11 +1668,11 @@
   return true;
 }
 
-bool FileMapInfo::validate_header() {
+bool FileMapInfo::validate_header(bool is_static) {
   bool status = _header->validate();
 
   if (status) {
-    if (!ClassLoader::check_shared_paths_misc_info(_paths_misc_info, _header->_paths_misc_info_size)) {
+    if (!ClassLoader::check_shared_paths_misc_info(_paths_misc_info, _header->_paths_misc_info_size, is_static)) {
       if (!PrintSharedArchiveAndExit) {
         fail_continue("shared class paths mismatch (hint: enable -Xlog:class+path=info to diagnose the failure)");
         status = false;
@@ -1435,7 +1702,7 @@
 
 // Unmap mapped regions of shared space.
 void FileMapInfo::stop_sharing_and_unmap(const char* msg) {
-  MetaspaceObj::set_shared_metaspace_range(NULL, NULL);
+  MetaspaceShared::set_shared_metaspace_range(NULL, NULL);
 
   FileMapInfo *map_info = FileMapInfo::current_info();
   if (map_info) {
@@ -1502,7 +1769,7 @@
 ClassFileStream* FileMapInfo::open_stream_for_jvmti(InstanceKlass* ik, Handle class_loader, TRAPS) {
   int path_index = ik->shared_classpath_index();
   assert(path_index >= 0, "should be called for shared built-in classes only");
-  assert(path_index < (int)_shared_path_table_size, "sanity");
+  assert(path_index < (int)get_number_of_shared_paths(), "sanity");
 
   ClassPathEntry* cpe = get_classpath_entry_for_jvmti(path_index, CHECK_NULL);
   assert(cpe != NULL, "must be");
--- a/src/hotspot/share/memory/filemap.hpp	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/share/memory/filemap.hpp	Thu May 23 11:07:37 2019 +0100
@@ -93,7 +93,32 @@
   size_t  _oopmap_size_in_bits;
 };
 
+class SharedPathTable {
+  Array<u8>* _table;
+  int _size;
+public:
+  void dumptime_init(ClassLoaderData* loader_data, Thread* THREAD);
+  void metaspace_pointers_do(MetaspaceClosure* it);
+
+  int size() {
+    return _size;
+  }
+  SharedClassPathEntry* path_at(int index) {
+    if (index < 0) {
+      return NULL;
+    }
+    assert(index < _size, "sanity");
+    char* p = (char*)_table->data();
+    p += sizeof(SharedClassPathEntry) * index;
+    return (SharedClassPathEntry*)p;
+  }
+  Array<u8>* table() {return _table;}
+  void set_table(Array<u8>* table) {_table = table;}
+
+};
+
 struct FileMapHeader : public CDSFileMapHeaderBase {
+  size_t _header_size;
   size_t _alignment;                // how shared archive should be aligned
   int    _obj_alignment;            // value of ObjectAlignmentInBytes
   address _narrow_oop_base;         // compressed oop encoding base
@@ -110,12 +135,16 @@
   size_t  _core_spaces_size;        // number of bytes allocated by the core spaces
                                     // (mc, md, ro, rw and od).
   MemRegion _heap_reserved;         // reserved region for the entire heap at dump time.
+  bool _base_archive_is_default;    // indicates if the base archive is the system default one
 
   // The following fields are all sanity checks for whether this archive
   // will function correctly with this JVM and the bootclasspath it's
   // invoked with.
   char  _jvm_ident[JVM_IDENT_MAX];      // identifier for jvm
 
+  // size of the base archive name including NULL terminator
+  int _base_archive_name_size;
+
   // The _paths_misc_info is a variable-size structure that records "miscellaneous"
   // information during dumping. It is generated and validated by the
   // SharedPathsMiscInfo class. See SharedPathsMiscInfo.hpp for
@@ -140,12 +169,11 @@
   // FIXME -- if JAR files in the tail of the list were specified but not used during dumping,
   // they should be removed from this table, to save space and to avoid spurious
   // loading failures during runtime.
-  int _shared_path_table_size;
-  size_t _shared_path_entry_size;
-  Array<u8>* _shared_path_table;
+  SharedPathTable _shared_path_table;
 
   jshort _app_class_paths_start_index;  // Index of first app classpath entry
   jshort _app_module_paths_start_index; // Index of first module path entry
+  jshort _num_module_paths;             // number of module path entries
   jshort _max_used_path_index;          // max path index referenced during CDS dump
   bool   _verify_local;                 // BytecodeVerificationLocal setting
   bool   _verify_remote;                // BytecodeVerificationRemote setting
@@ -161,13 +189,14 @@
   jshort app_module_paths_start_index() { return _app_module_paths_start_index; }
 
   bool validate();
-  void populate(FileMapInfo* info, size_t alignment);
   int compute_crc();
 
   CDSFileMapRegion* space_at(int i) {
     assert(i >= 0 && i < NUM_CDS_REGIONS, "invalid region");
     return &_space[i];
   }
+public:
+  void populate(FileMapInfo* info, size_t alignment);
 };
 
 class FileMapInfo : public CHeapObj<mtInternal> {
@@ -176,14 +205,14 @@
   friend class VMStructs;
   friend struct FileMapHeader;
 
+  bool    _is_static;
   bool    _file_open;
   int     _fd;
   size_t  _file_offset;
 
 private:
-  static Array<u8>*            _shared_path_table;
-  static int                   _shared_path_table_size;
-  static size_t                _shared_path_entry_size;
+  // TODO: Probably change the following to be non-static
+  static SharedPathTable       _shared_path_table;
   static bool                  _validating_shared_path_table;
 
   // FileMapHeader describes the shared space data in the file to be
@@ -202,24 +231,31 @@
 
   const char* _full_path;
   char* _paths_misc_info;
+  char* _base_archive_name;
 
   static FileMapInfo* _current_info;
+  static FileMapInfo* _dynamic_archive_info;
   static bool _heap_pointers_need_patching;
-
-  bool  init_from_file(int fd);
-  void  align_file_position();
-  bool  validate_header_impl();
+  static bool _memory_mapping_failed;
+  static bool get_base_archive_name_from_header(const char* archive_name,
+                                                int* size, char** base_archive_name);
+  static bool check_archive(const char* archive_name, bool is_static);
+  static bool  same_files(const char* file1, const char* file2);
+  void restore_shared_path_table();
+  bool  init_from_file(int fd, bool is_static);
   static void metaspace_pointers_do(MetaspaceClosure* it);
 
 public:
-  FileMapInfo();
+  FileMapInfo(bool is_static);
   ~FileMapInfo();
 
   int    compute_header_crc()         { return _header->compute_crc(); }
   void   set_header_crc(int crc)      { _header->_crc = crc; }
+  int    space_crc(int i)             { return space_at(i)->_crc; }
   void   populate_header(size_t alignment);
-  bool   validate_header();
+  bool   validate_header(bool is_static);
   void   invalidate();
+  int    crc()                        { return _header->_crc; }
   int    version()                    { return _header->_version; }
   size_t alignment()                  { return _header->_alignment; }
   CompressedOops::Mode narrow_oop_mode() { return _header->_narrow_oop_mode; }
@@ -234,6 +270,9 @@
   char* read_only_tables_start()              { return _header->_read_only_tables_start; }
   void set_read_only_tables_start(char* p)    { _header->_read_only_tables_start = p; }
 
+  bool  is_file_position_aligned() const;
+  void  align_file_position();
+
   address cds_i2i_entry_code_buffers() {
     return _header->_cds_i2i_entry_code_buffers;
   }
@@ -254,12 +293,21 @@
     NOT_CDS(return NULL;)
   }
 
+  static void set_current_info(FileMapInfo* info) {
+    CDS_ONLY(_current_info = info;)
+  }
+
+  static FileMapInfo* dynamic_info() {
+    CDS_ONLY(return _dynamic_archive_info;)
+    NOT_CDS(return NULL;)
+  }
+
   static void assert_mark(bool check);
 
   // File manipulation.
-  bool  initialize() NOT_CDS_RETURN_(false);
-  bool  open_for_read();
-  void  open_for_write();
+  bool  initialize(bool is_static) NOT_CDS_RETURN_(false);
+  bool  open_for_read(const char* path = NULL);
+  void  open_for_write(const char* path = NULL);
   void  write_header();
   void  write_region(int region, char* base, size_t size,
                      bool read_only, bool allow_exec);
@@ -269,6 +317,8 @@
                                     bool print_log);
   void  write_bytes(const void* buffer, size_t count);
   void  write_bytes_aligned(const void* buffer, size_t count);
+  size_t  read_bytes(void* buffer, size_t count);
+  char* map_regions(int regions[], char* saved_base[], size_t len);
   char* map_region(int i, char** top_ret);
   void  map_heap_regions_impl() NOT_CDS_JAVA_HEAP_RETURN;
   void  map_heap_regions() NOT_CDS_JAVA_HEAP_RETURN;
@@ -278,6 +328,7 @@
                                               int first_region_idx) NOT_CDS_JAVA_HEAP_RETURN;
   bool  has_heap_regions()  NOT_CDS_JAVA_HEAP_RETURN_(false);
   MemRegion get_heap_regions_range_with_current_oop_encoding_mode() NOT_CDS_JAVA_HEAP_RETURN_(MemRegion());
+  void  unmap_regions(int regions[], char* saved_base[], size_t len);
   void  unmap_region(int i);
   bool  verify_region_checksum(int i);
   void  close();
@@ -291,7 +342,10 @@
   // Errors.
   static void fail_stop(const char *msg, ...) ATTRIBUTE_PRINTF(1, 2);
   static void fail_continue(const char *msg, ...) ATTRIBUTE_PRINTF(1, 2);
-
+  static bool memory_mapping_failed() {
+    CDS_ONLY(return _memory_mapping_failed;)
+    NOT_CDS(return false;)
+  }
   bool is_in_shared_region(const void* p, int idx) NOT_CDS_RETURN_(false);
 
   // Stop CDS sharing and unmap CDS regions.
@@ -307,13 +361,7 @@
 #endif
 
   static SharedClassPathEntry* shared_path(int index) {
-    if (index < 0) {
-      return NULL;
-    }
-    assert(index < _shared_path_table_size, "sanity");
-    char* p = (char*)_shared_path_table->data();
-    p += _shared_path_entry_size * index;
-    return (SharedClassPathEntry*)p;
+    return _shared_path_table.path_at(index);
   }
 
   static const char* shared_path_name(int index) {
@@ -322,7 +370,7 @@
   }
 
   static int get_number_of_shared_paths() {
-    return _shared_path_table_size;
+    return _shared_path_table.size();
   }
 
   char* region_addr(int idx);
@@ -330,7 +378,7 @@
  private:
   bool  map_heap_data(MemRegion **heap_mem, int first, int max, int* num,
                       bool is_open = false) NOT_CDS_JAVA_HEAP_RETURN_(false);
-  bool  verify_mapped_heap_regions(int first, int num) NOT_CDS_JAVA_HEAP_RETURN_(false);
+  bool  region_crc_check(char* buf, size_t size, int expected_crc) NOT_CDS_RETURN_(false);
   void  dealloc_archive_heap_regions(MemRegion* regions, int num, bool is_open) NOT_CDS_JAVA_HEAP_RETURN;
 
   CDSFileMapRegion* space_at(int i) {
--- a/src/hotspot/share/memory/heap.cpp	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/share/memory/heap.cpp	Thu May 23 11:07:37 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2019, 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
@@ -55,31 +55,67 @@
 }
 
 
+// The segmap is marked free for that part of the heap
+// which has not been allocated yet (beyond _next_segment).
+// "Allocated" space in this context means there exists a
+// HeapBlock or a FreeBlock describing this space.
+// This method takes segment map indices as range boundaries
 void CodeHeap::mark_segmap_as_free(size_t beg, size_t end) {
-  assert(              beg <  _number_of_committed_segments, "interval begin out of bounds");
-  assert(beg <  end && end <= _number_of_committed_segments, "interval end   out of bounds");
-  // setup _segmap pointers for faster indexing
-  address p = (address)_segmap.low() + beg;
-  address q = (address)_segmap.low() + end;
-  // initialize interval
-  while (p < q) *p++ = free_sentinel;
+  assert(             beg <  _number_of_committed_segments, "interval begin out of bounds");
+  assert(beg < end && end <= _number_of_committed_segments, "interval end   out of bounds");
+  // Don't do unpredictable things in PRODUCT build
+  if (beg < end) {
+    // setup _segmap pointers for faster indexing
+    address p = (address)_segmap.low() + beg;
+    address q = (address)_segmap.low() + end;
+    // initialize interval
+    memset(p, free_sentinel, q-p);
+  }
 }
 
-
+// Don't get confused here.
+// All existing blocks, no matter if they are used() or free(),
+// have their segmap marked as used. This allows to find the
+// block header (HeapBlock or FreeBlock) for any pointer
+// within the allocated range (upper limit: _next_segment).
+// This method takes segment map indices as range boundaries
 void CodeHeap::mark_segmap_as_used(size_t beg, size_t end) {
-  assert(              beg <  _number_of_committed_segments, "interval begin out of bounds");
-  assert(beg <  end && end <= _number_of_committed_segments, "interval end   out of bounds");
-  // setup _segmap pointers for faster indexing
-  address p = (address)_segmap.low() + beg;
-  address q = (address)_segmap.low() + end;
-  // initialize interval
-  int i = 0;
-  while (p < q) {
-    *p++ = i++;
-    if (i == free_sentinel) i = 1;
+  assert(             beg <  _number_of_committed_segments, "interval begin out of bounds");
+  assert(beg < end && end <= _number_of_committed_segments, "interval end   out of bounds");
+  // Don't do unpredictable things in PRODUCT build
+  if (beg < end) {
+    // setup _segmap pointers for faster indexing
+    address p = (address)_segmap.low() + beg;
+    address q = (address)_segmap.low() + end;
+    // initialize interval
+    int i = 0;
+    while (p < q) {
+      *p++ = i++;
+      if (i == free_sentinel) i = 1;
+    }
   }
 }
 
+void CodeHeap::invalidate(size_t beg, size_t end, size_t hdr_size) {
+#ifndef PRODUCT
+  // Fill the given range with some bad value.
+  // length is expected to be in segment_size units.
+  // This prevents inadvertent execution of code leftover from previous use.
+  char* p = low_boundary() + segments_to_size(beg) + hdr_size;
+  memset(p, badCodeHeapNewVal, segments_to_size(end-beg)-hdr_size);
+#endif
+}
+
+void CodeHeap::clear(size_t beg, size_t end) {
+  mark_segmap_as_free(beg, end);
+  invalidate(beg, end, 0);
+}
+
+void CodeHeap::clear() {
+  _next_segment = 0;
+  clear(_next_segment, _number_of_committed_segments);
+}
+
 
 static size_t align_to_page_size(size_t size) {
   const size_t alignment = (size_t)os::vm_page_size();
@@ -140,7 +176,7 @@
   assert(_segmap.reserved_size()  >= (size_t) _number_of_reserved_segments , "could not reserve enough space for segment map");
   assert(_segmap.reserved_size()  >= _segmap.committed_size()     , "just checking");
 
-  // initialize remaining instance variables
+  // initialize remaining instance variables, heap memory and segmap
   clear();
   return true;
 }
@@ -167,17 +203,12 @@
       return false;
     }
     assert(_segmap.committed_size() >= (size_t) _number_of_committed_segments, "just checking");
-    // initialize additional segmap entries
-    mark_segmap_as_free(i, _number_of_committed_segments);
+    // initialize additional space (heap memory and segmap)
+    clear(i, _number_of_committed_segments);
   }
   return true;
 }
 
-void CodeHeap::clear() {
-  _next_segment = 0;
-  mark_segmap_as_free(0, _number_of_committed_segments);
-}
-
 
 void* CodeHeap::allocate(size_t instance_size) {
   size_t number_of_segments = size_to_segments(instance_size + header_size());
@@ -189,13 +220,14 @@
   NOT_PRODUCT(verify());
 
   if (block != NULL) {
-    assert(block->length() >= number_of_segments && block->length() < number_of_segments + CodeCacheMinBlockLength, "sanity check");
     assert(!block->free(), "must be marked free");
     guarantee((char*) block >= _memory.low_boundary() && (char*) block < _memory.high(),
               "The newly allocated block " INTPTR_FORMAT " is not within the heap "
               "starting with "  INTPTR_FORMAT " and ending with "  INTPTR_FORMAT,
               p2i(block), p2i(_memory.low_boundary()), p2i(_memory.high()));
-    DEBUG_ONLY(memset((void*)block->allocated_space(), badCodeHeapNewVal, instance_size));
+    // Invalidate the additional space that FreeBlock occupies. The rest of the block should already be invalidated.
+    // This is necessary due to a dubious assert in nmethod.cpp(PcDescCache::reset_to()).
+    DEBUG_ONLY(memset((void*)block->allocated_space(), badCodeHeapNewVal, sizeof(FreeBlock) - sizeof(HeapBlock)));
     _max_allocated_capacity = MAX2(_max_allocated_capacity, allocated_capacity());
     _blob_count++;
     return block->allocated_space();
@@ -213,7 +245,6 @@
               "The newly allocated block " INTPTR_FORMAT " is not within the heap "
               "starting with "  INTPTR_FORMAT " and ending with " INTPTR_FORMAT,
               p2i(b), p2i(_memory.low_boundary()), p2i(_memory.high()));
-    DEBUG_ONLY(memset((void *)b->allocated_space(), badCodeHeapNewVal, instance_size));
     _max_allocated_capacity = MAX2(_max_allocated_capacity, allocated_capacity());
     _blob_count++;
     return b->allocated_space();
@@ -222,19 +253,45 @@
   }
 }
 
+// Split the given block into two at the given segment.
+// This is helpful when a block was allocated too large
+// to trim off the unused space at the end (interpreter).
+// It also helps with splitting a large free block during allocation.
+// Usage state (used or free) must be set by caller since
+// we don't know if the resulting blocks will be used or free.
+// split_at is the segment number (relative to segment_for(b))
+//          where the split happens. The segment with relative
+//          number split_at is the first segment of the split-off block.
+HeapBlock* CodeHeap::split_block(HeapBlock *b, size_t split_at) {
+  if (b == NULL) return NULL;
+  // After the split, both blocks must have a size of at least CodeCacheMinBlockLength
+  assert((split_at >= CodeCacheMinBlockLength) && (split_at + CodeCacheMinBlockLength <= b->length()),
+         "split position(%d) out of range [0..%d]", (int)split_at, (int)b->length());
+  size_t split_segment = segment_for(b) + split_at;
+  size_t b_size        = b->length();
+  size_t newb_size     = b_size - split_at;
+
+  HeapBlock* newb = block_at(split_segment);
+  newb->set_length(newb_size);
+  mark_segmap_as_used(segment_for(newb), segment_for(newb) + newb_size);
+  b->set_length(split_at);
+  return newb;
+}
+
 void CodeHeap::deallocate_tail(void* p, size_t used_size) {
   assert(p == find_start(p), "illegal deallocation");
   // Find start of HeapBlock
   HeapBlock* b = (((HeapBlock *)p) - 1);
   assert(b->allocated_space() == p, "sanity check");
-  size_t used_number_of_segments = size_to_segments(used_size + header_size());
+
   size_t actual_number_of_segments = b->length();
+  size_t used_number_of_segments   = size_to_segments(used_size + header_size());
+  size_t unused_number_of_segments = actual_number_of_segments - used_number_of_segments;
   guarantee(used_number_of_segments <= actual_number_of_segments, "Must be!");
-  guarantee(b == block_at(_next_segment - actual_number_of_segments), "Intermediate allocation!");
-  size_t number_of_segments_to_deallocate = actual_number_of_segments - used_number_of_segments;
-  _next_segment -= number_of_segments_to_deallocate;
-  mark_segmap_as_free(_next_segment, _next_segment + number_of_segments_to_deallocate);
-  b->initialize(used_number_of_segments);
+
+  HeapBlock* f = split_block(b, used_number_of_segments);
+  add_to_freelist(f);
+  NOT_PRODUCT(verify());
 }
 
 void CodeHeap::deallocate(void* p) {
@@ -246,8 +303,6 @@
             "The block to be deallocated " INTPTR_FORMAT " is not within the heap "
             "starting with "  INTPTR_FORMAT " and ending with " INTPTR_FORMAT,
             p2i(b), p2i(_memory.low_boundary()), p2i(_memory.high()));
-  DEBUG_ONLY(memset((void *)b->allocated_space(), badCodeHeapFreeVal,
-             segments_to_size(b->length()) - sizeof(HeapBlock)));
   add_to_freelist(b);
   NOT_PRODUCT(verify());
 }
@@ -410,6 +465,7 @@
     // Update find_start map
     size_t beg = segment_for(a);
     mark_segmap_as_used(beg, beg + a->length());
+    invalidate(beg, beg + a->length(), sizeof(FreeBlock));
     _freelist_length--;
     return true;
   }
@@ -419,19 +475,20 @@
 
 void CodeHeap::add_to_freelist(HeapBlock* a) {
   FreeBlock* b = (FreeBlock*)a;
+  size_t  bseg = segment_for(b);
   _freelist_length++;
 
   assert(b != _freelist, "cannot be removed twice");
 
-
   // Mark as free and update free space count
   _freelist_segments += b->length();
   b->set_free();
+  invalidate(bseg, bseg + b->length(), sizeof(FreeBlock));
 
   // First element in list?
   if (_freelist == NULL) {
+    b->set_link(NULL);
     _freelist = b;
-    b->set_link(NULL);
     return;
   }
 
@@ -463,23 +520,31 @@
  * Search freelist for an entry on the list with the best fit.
  * @return NULL, if no one was found
  */
-FreeBlock* CodeHeap::search_freelist(size_t length) {
-  FreeBlock* found_block = NULL;
-  FreeBlock* found_prev  = NULL;
-  size_t     found_length = 0;
+HeapBlock* CodeHeap::search_freelist(size_t length) {
+  FreeBlock* found_block  = NULL;
+  FreeBlock* found_prev   = NULL;
+  size_t     found_length = _next_segment; // max it out to begin with
 
+  HeapBlock* res  = NULL;
   FreeBlock* prev = NULL;
-  FreeBlock* cur = _freelist;
+  FreeBlock* cur  = _freelist;
+
+  length = length < CodeCacheMinBlockLength ? CodeCacheMinBlockLength : length;
 
-  // Search for first block that fits
+  // Search for best-fitting block
   while(cur != NULL) {
-    if (cur->length() >= length) {
-      // Remember block, its previous element, and its length
-      found_block = cur;
-      found_prev  = prev;
-      found_length = found_block->length();
-
+    size_t cur_length = cur->length();
+    if (cur_length == length) {
+      // We have a perfect fit
+      found_block  = cur;
+      found_prev   = prev;
+      found_length = cur_length;
       break;
+    } else if ((cur_length > length) && (cur_length < found_length)) {
+      // This is a new, closer fit. Remember block, its previous element, and its length
+      found_block  = cur;
+      found_prev   = prev;
+      found_length = cur_length;
     }
     // Next element in list
     prev = cur;
@@ -504,20 +569,18 @@
       // Unmap element
       found_prev->set_link(found_block->link());
     }
+    res = found_block;
   } else {
-    // Truncate block and return a pointer to the following block
-    // Set used bit and length on new block
-    found_block->set_length(found_length - length);
-    found_block = following_block(found_block);
-
-    size_t beg = segment_for(found_block);
-    mark_segmap_as_used(beg, beg + length);
-    found_block->set_length(length);
+    // Truncate the free block and return the truncated part
+    // as new HeapBlock. The remaining free block does not
+    // need to be updated, except for it's length. Truncating
+    // the segment map does not invalidate the leading part.
+    res = split_block(found_block, found_length - length);
   }
 
-  found_block->set_used();
+  res->set_used();
   _freelist_segments -= length;
-  return found_block;
+  return res;
 }
 
 //----------------------------------------------------------------------------
@@ -549,6 +612,28 @@
     // than free blocks found on the full list.
     assert(count == 0, "missing free blocks");
 
+    //---<  all free block memory must have been invalidated  >---
+    for(FreeBlock* b = _freelist; b != NULL; b = b->link()) {
+      for (char* c = (char*)b + sizeof(FreeBlock); c < (char*)b + segments_to_size(b->length()); c++) {
+        assert(*c == (char)badCodeHeapNewVal, "FreeBlock@" PTR_FORMAT "(" PTR_FORMAT ") not invalidated @byte %d", p2i(b), b->length(), (int)(c - (char*)b));
+      }
+    }
+
+    // Verify segment map marking.
+    // All allocated segments, no matter if in a free or used block,
+    // must be marked "in use".
+    address seg_map = (address)_segmap.low();
+    size_t  nseg    = 0;
+    for(HeapBlock* b = first_block(); b != NULL; b = next_block(b)) {
+      size_t seg1 = segment_for(b);
+      size_t segn = seg1 + b->length();
+      for (size_t i = seg1; i < segn; i++) {
+        nseg++;
+        assert(!is_segment_unused(seg_map[i]), "CodeHeap: unused segment. %d [%d..%d], %s block", (int)i, (int)seg1, (int)segn, b->free()? "free":"used");
+      }
+    }
+    assert(nseg == _next_segment, "CodeHeap: segment count mismatch. found %d, expected %d.", (int)nseg, (int)_next_segment);
+
     // Verify that the number of free blocks is not out of hand.
     static int free_block_threshold = 10000;
     if (count > free_block_threshold) {
--- a/src/hotspot/share/memory/heap.hpp	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/share/memory/heap.hpp	Thu May 23 11:07:37 2019 +0100
@@ -51,6 +51,8 @@
  public:
   // Initialization
   void initialize(size_t length)                 { _header._length = length; set_used(); }
+  // Merging/splitting
+  void set_length(size_t length)                 { _header._length = length; }
 
   // Accessors
   void* allocated_space() const                  { return (void*)(this + 1); }
@@ -71,9 +73,6 @@
   // Initialization
   void initialize(size_t length)             { HeapBlock::initialize(length); _link= NULL; }
 
-  // Merging
-  void set_length(size_t l)                  { _header._length = l; }
-
   // Accessors
   FreeBlock* link() const                    { return _link; }
   void set_link(FreeBlock* link)             { _link = link; }
@@ -115,8 +114,12 @@
   bool     is_segment_unused(int val) const      { return val == free_sentinel; }
   HeapBlock* block_at(size_t i) const            { return (HeapBlock*)(_memory.low() + (i << _log2_segment_size)); }
 
-  void  mark_segmap_as_free(size_t beg, size_t end);
-  void  mark_segmap_as_used(size_t beg, size_t end);
+  // These methods take segment map indices as range boundaries
+  void mark_segmap_as_free(size_t beg, size_t end);
+  void mark_segmap_as_used(size_t beg, size_t end);
+  void invalidate(size_t beg, size_t end, size_t header_bytes);
+  void clear(size_t beg, size_t end);
+  void clear();                                 // clears all heap contents
 
   // Freelist management helpers
   FreeBlock* following_block(FreeBlock* b);
@@ -125,7 +128,7 @@
 
   // Toplevel freelist management
   void add_to_freelist(HeapBlock* b);
-  FreeBlock* search_freelist(size_t length);
+  HeapBlock* search_freelist(size_t length);
 
   // Iteration helpers
   void*      next_used(HeapBlock* b) const;
@@ -133,7 +136,6 @@
 
   // to perform additional actions on creation of executable code
   void on_code_mapping(char* base, size_t size);
-  void clear();                                 // clears all heap contents
 
  public:
   CodeHeap(const char* name, const int code_blob_type);
@@ -180,6 +182,7 @@
   size_t segment_size()         const { return _segment_size; }  // for CodeHeapState
   HeapBlock* first_block() const;                                // for CodeHeapState
   HeapBlock* next_block(HeapBlock* b) const;                     // for CodeHeapState
+  HeapBlock* split_block(HeapBlock* b, size_t split_seg);        // split one block into two
 
   FreeBlock* freelist()         const { return _freelist; }      // for CodeHeapState
 
--- a/src/hotspot/share/memory/heapShared.cpp	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/share/memory/heapShared.cpp	Thu May 23 11:07:37 2019 +0100
@@ -418,8 +418,7 @@
 
   _run_time_subgraph_info_table.reset();
 
-  int num_buckets = CompactHashtableWriter::default_num_buckets(d_table->_count);
-  CompactHashtableWriter writer(num_buckets, &stats);
+  CompactHashtableWriter writer(d_table->_count, &stats);
   CopyKlassSubGraphInfoToArchive copy(&writer);
   d_table->iterate(&copy);
 
--- a/src/hotspot/share/memory/heapShared.hpp	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/share/memory/heapShared.hpp	Thu May 23 11:07:37 2019 +0100
@@ -286,16 +286,6 @@
                                idx <= MetaspaceShared::last_open_archive_heap_region));
     NOT_CDS_JAVA_HEAP_RETURN_(false);
   }
-  static bool is_closed_archive_heap_region(int idx) {
-    CDS_JAVA_HEAP_ONLY(return (idx >= MetaspaceShared::first_closed_archive_heap_region &&
-                               idx <= MetaspaceShared::last_closed_archive_heap_region));
-    NOT_CDS_JAVA_HEAP_RETURN_(false);
-  }
-  static bool is_open_archive_heap_region(int idx) {
-    CDS_JAVA_HEAP_ONLY(return (idx >= MetaspaceShared::first_open_archive_heap_region &&
-                               idx <= MetaspaceShared::last_open_archive_heap_region));
-    NOT_CDS_JAVA_HEAP_RETURN_(false);
-  }
 
   static void set_closed_archive_heap_region_mapped() {
     CDS_JAVA_HEAP_ONLY(_closed_archive_heap_region_mapped = true);
--- a/src/hotspot/share/memory/memRegion.cpp	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/share/memory/memRegion.cpp	Thu May 23 11:07:37 2019 +0100
@@ -118,4 +118,3 @@
 void  MemRegion::operator delete [](void* p) {
   FreeHeap(p);
 }
-
--- a/src/hotspot/share/memory/metaspace.cpp	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/share/memory/metaspace.cpp	Thu May 23 11:07:37 2019 +0100
@@ -1152,7 +1152,7 @@
 void Metaspace::ergo_initialize() {
   if (DumpSharedSpaces) {
     // Using large pages when dumping the shared archive is currently not implemented.
-    FLAG_SET_ERGO(bool, UseLargePagesInMetaspace, false);
+    FLAG_SET_ERGO(UseLargePagesInMetaspace, false);
   }
 
   size_t page_size = os::vm_page_size();
@@ -1194,12 +1194,12 @@
       if (min_metaspace_sz >= MaxMetaspaceSize) {
         vm_exit_during_initialization("MaxMetaspaceSize is too small.");
       } else {
-        FLAG_SET_ERGO(size_t, CompressedClassSpaceSize,
+        FLAG_SET_ERGO(CompressedClassSpaceSize,
                       MaxMetaspaceSize - min_metaspace_sz);
       }
     }
   } else if (min_metaspace_sz >= MaxMetaspaceSize) {
-    FLAG_SET_ERGO(size_t, InitialBootClassLoaderMetaspaceSize,
+    FLAG_SET_ERGO(InitialBootClassLoaderMetaspaceSize,
                   min_metaspace_sz);
   }
 
@@ -1220,6 +1220,10 @@
     MetaspaceShared::initialize_runtime_shared_and_meta_spaces();
   }
 
+  if (DynamicDumpSharedSpaces && !UseSharedSpaces) {
+    vm_exit_during_initialization("DynamicDumpSharedSpaces not supported when base CDS archive is not loaded", NULL);
+  }
+
   if (!DumpSharedSpaces && !UseSharedSpaces)
 #endif // INCLUDE_CDS
   {
--- a/src/hotspot/share/memory/metaspaceClosure.cpp	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/share/memory/metaspaceClosure.cpp	Thu May 23 11:07:37 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2019, 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
@@ -34,9 +34,20 @@
   *(address*)mpp() = (address)p;
 }
 
-void MetaspaceClosure::push_impl(MetaspaceClosure::Ref* ref, Writability w) {
-  if (ref->not_null()) {
+void MetaspaceClosure::push_impl(MetaspaceClosure::Ref* ref) {
+  if (_nest_level < MAX_NEST_LEVEL) {
+    do_push(ref);
+    delete ref;
+  } else {
+    ref->set_next(_pending_refs);
+    _pending_refs = ref;
+  }
+}
+
+void MetaspaceClosure::do_push(MetaspaceClosure::Ref* ref) {
+  if (ref->not_null()) { // FIXME: make this configurable, so DynamicArchiveBuilder mark all pointers
     bool read_only;
+    Writability w = ref->writability();
     switch (w) {
     case _writable:
       read_only = false;
@@ -48,12 +59,29 @@
       assert(w == _default, "must be");
       read_only = ref->is_read_only_by_default();
     }
+    _nest_level ++;
     if (do_ref(ref, read_only)) { // true means we want to iterate the embedded pointer in <ref>
       ref->metaspace_pointers_do(this);
     }
+    _nest_level --;
   }
 }
 
+void MetaspaceClosure::finish() {
+  assert(_nest_level == 0, "must be");
+  while (_pending_refs != NULL) {
+    Ref* ref = _pending_refs;
+    _pending_refs = _pending_refs->next();
+    do_push(ref);
+    delete ref;
+  }
+}
+
+MetaspaceClosure::~MetaspaceClosure() {
+  assert(_pending_refs == NULL,
+         "you must explicitly call MetaspaceClosure::finish() to process all refs!");
+}
+
 bool UniqueMetaspaceClosure::do_ref(MetaspaceClosure::Ref* ref, bool read_only) {
   bool* found = _has_been_visited.lookup(ref->obj());
   if (found != NULL) {
@@ -64,7 +92,6 @@
     if (_has_been_visited.maybe_grow(MAX_TABLE_SIZE)) {
       log_info(cds, hashtables)("Expanded _has_been_visited table to %d", _has_been_visited.table_size());
     }
-    do_unique_ref(ref, read_only);
-    return true;  // Saw this for the first time: iterate the embedded pointers.
+    return do_unique_ref(ref, read_only);
   }
 }
--- a/src/hotspot/share/memory/metaspaceClosure.hpp	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/share/memory/metaspaceClosure.hpp	Thu May 23 11:07:37 2019 +0100
@@ -101,9 +101,15 @@
   //         Symbol*     bar() { return (Symbol*)    _obj; }
   //
   // [2] All Array<T> dimensions are statically declared.
-  class Ref {
+  class Ref : public CHeapObj<mtInternal> {
+    Writability _writability;
+    Ref* _next;
+    // Noncopyable.
+    Ref(const Ref&);
+    Ref& operator=(const Ref&);
   protected:
     virtual void** mpp() const = 0;
+    Ref(Writability w) : _writability(w), _next(NULL) {}
   public:
     virtual bool not_null() const = 0;
     virtual int size() const = 0;
@@ -111,6 +117,7 @@
     virtual void metaspace_pointers_do_at(MetaspaceClosure *it, address new_loc) const = 0;
     virtual MetaspaceObj::Type msotype() const = 0;
     virtual bool is_read_only_by_default() const = 0;
+    virtual ~Ref() {}
 
     address obj() const {
       // In some rare cases (see CPSlot in constantPool.hpp) we store some flags in the lowest
@@ -119,8 +126,16 @@
       return (address)(p & (~FLAG_MASK));
     }
 
+    address* addr() const {
+      return (address*)mpp();
+    }
+
     void update(address new_loc) const;
 
+    Writability writability() const { return _writability; };
+    void set_next(Ref* n)           { _next = n; }
+    Ref* next() const               { return _next; }
+
   private:
     static const uintx FLAG_MASK = 0x03;
 
@@ -143,7 +158,7 @@
     }
 
   public:
-    ObjectRef(T** mpp) : _mpp(mpp) {}
+    ObjectRef(T** mpp, Writability w) : Ref(w), _mpp(mpp) {}
 
     virtual bool is_read_only_by_default() const { return T::is_read_only_by_default(); }
     virtual bool not_null()                const { return dereference() != NULL; }
@@ -170,7 +185,7 @@
     }
 
   public:
-    PrimitiveArrayRef(Array<T>** mpp) : _mpp(mpp) {}
+    PrimitiveArrayRef(Array<T>** mpp, Writability w) : Ref(w), _mpp(mpp) {}
 
     // all Arrays are read-only by default
     virtual bool is_read_only_by_default() const { return true; }
@@ -200,7 +215,7 @@
     }
 
   public:
-    PointerArrayRef(Array<T*>** mpp) : _mpp(mpp) {}
+    PointerArrayRef(Array<T*>** mpp, Writability w) : Ref(w), _mpp(mpp) {}
 
     // all Arrays are read-only by default
     virtual bool is_read_only_by_default() const { return true; }
@@ -224,9 +239,21 @@
     }
   };
 
-  void push_impl(Ref* ref, Writability w);
+  // If recursion is too deep, save the Refs in _pending_refs, and push them later using
+  // MetaspaceClosure::finish()
+  static const int MAX_NEST_LEVEL = 5;
+  Ref* _pending_refs;
+  int _nest_level;
+
+  void push_impl(Ref* ref);
+  void do_push(Ref* ref);
 
 public:
+  MetaspaceClosure(): _pending_refs(NULL), _nest_level(0) {}
+  ~MetaspaceClosure();
+
+  void finish();
+
   // returns true if we want to keep iterating the pointers embedded inside <ref>
   virtual bool do_ref(Ref* ref, bool read_only) = 0;
 
@@ -237,22 +264,19 @@
   // C++ will try to match the "most specific" template function. This one will
   // will be matched if possible (if mpp is an Array<> of any pointer type).
   template <typename T> void push(Array<T*>** mpp, Writability w = _default) {
-    PointerArrayRef<T> ref(mpp);
-    push_impl(&ref, w);
+    push_impl(new PointerArrayRef<T>(mpp, w));
   }
 
   // If the above function doesn't match (mpp is an Array<>, but T is not a pointer type), then
   // this is the second choice.
   template <typename T> void push(Array<T>** mpp, Writability w = _default) {
-    PrimitiveArrayRef<T> ref(mpp);
-    push_impl(&ref, w);
+    push_impl(new PrimitiveArrayRef<T>(mpp, w));
   }
 
   // If the above function doesn't match (mpp is not an Array<> type), then
   // this will be matched by default.
   template <class T> void push(T** mpp, Writability w = _default) {
-    ObjectRef<T> ref(mpp);
-    push_impl(&ref, w);
+    push_impl(new ObjectRef<T>(mpp, w));
   }
 };
 
@@ -266,7 +290,7 @@
 
 public:
   // Gets called the first time we discover an object.
-  virtual void do_unique_ref(Ref* ref, bool read_only) = 0;
+  virtual bool do_unique_ref(Ref* ref, bool read_only) = 0;
   UniqueMetaspaceClosure() : _has_been_visited(INITIAL_TABLE_SIZE) {}
 
 private:
--- a/src/hotspot/share/memory/metaspaceShared.cpp	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/share/memory/metaspaceShared.cpp	Thu May 23 11:07:37 2019 +0100
@@ -48,10 +48,12 @@
 #include "memory/metaspaceShared.hpp"
 #include "memory/resourceArea.hpp"
 #include "memory/universe.hpp"
+#include "memory/dynamicArchive.hpp"
 #include "oops/compressedOops.inline.hpp"
 #include "oops/instanceClassLoaderKlass.hpp"
 #include "oops/instanceMirrorKlass.hpp"
 #include "oops/instanceRefKlass.hpp"
+#include "oops/methodData.hpp"
 #include "oops/objArrayKlass.hpp"
 #include "oops/objArrayOop.hpp"
 #include "oops/oop.inline.hpp"
@@ -81,6 +83,7 @@
 address MetaspaceShared::_cds_i2i_entry_code_buffers = NULL;
 size_t MetaspaceShared::_cds_i2i_entry_code_buffers_size = 0;
 size_t MetaspaceShared::_core_spaces_size = 0;
+void* MetaspaceShared::_shared_metaspace_static_top = NULL;
 
 // The CDS archive is divided into the following regions:
 //     mc  - misc code (the method entry trampolines)
@@ -112,105 +115,97 @@
 // The s0/s1 and oa0/oa1 regions are populated inside HeapShared::archive_java_heap_objects.
 // Their layout is independent of the other 5 regions.
 
-class DumpRegion {
-private:
-  const char* _name;
-  char* _base;
-  char* _top;
-  char* _end;
-  bool _is_packed;
-
-  char* expand_top_to(char* newtop) {
-    assert(is_allocatable(), "must be initialized and not packed");
-    assert(newtop >= _top, "must not grow backwards");
-    if (newtop > _end) {
-      MetaspaceShared::report_out_of_space(_name, newtop - _top);
-      ShouldNotReachHere();
-    }
-    uintx delta = MetaspaceShared::object_delta_uintx(newtop);
-    if (delta > MAX_SHARED_DELTA) {
-      // This is just a sanity check and should not appear in any real world usage. This
-      // happens only if you allocate more than 2GB of shared objects and would require
-      // millions of shared classes.
-      vm_exit_during_initialization("Out of memory in the CDS archive",
-                                    "Please reduce the number of shared classes.");
-    }
-
-    MetaspaceShared::commit_shared_space_to(newtop);
-    _top = newtop;
-    return _top;
+char* DumpRegion::expand_top_to(char* newtop) {
+  assert(is_allocatable(), "must be initialized and not packed");
+  assert(newtop >= _top, "must not grow backwards");
+  if (newtop > _end) {
+    MetaspaceShared::report_out_of_space(_name, newtop - _top);
+    ShouldNotReachHere();
   }
-
-public:
-  DumpRegion(const char* name) : _name(name), _base(NULL), _top(NULL), _end(NULL), _is_packed(false) {}
-
-  char* allocate(size_t num_bytes, size_t alignment=BytesPerWord) {
-    char* p = (char*)align_up(_top, alignment);
-    char* newtop = p + align_up(num_bytes, alignment);
-    expand_top_to(newtop);
-    memset(p, 0, newtop - p);
-    return p;
+  uintx delta;
+  if (DynamicDumpSharedSpaces) {
+    delta = DynamicArchive::object_delta_uintx(newtop);
+  } else {
+    delta = MetaspaceShared::object_delta_uintx(newtop);
   }
-
-  void append_intptr_t(intptr_t n) {
-    assert(is_aligned(_top, sizeof(intptr_t)), "bad alignment");
-    intptr_t *p = (intptr_t*)_top;
-    char* newtop = _top + sizeof(intptr_t);
-    expand_top_to(newtop);
-    *p = n;
+  if (delta > MAX_SHARED_DELTA) {
+    // This is just a sanity check and should not appear in any real world usage. This
+    // happens only if you allocate more than 2GB of shared objects and would require
+    // millions of shared classes.
+    vm_exit_during_initialization("Out of memory in the CDS archive",
+                                  "Please reduce the number of shared classes.");
   }
 
-  char* base()      const { return _base;        }
-  char* top()       const { return _top;         }
-  char* end()       const { return _end;         }
-  size_t reserved() const { return _end - _base; }
-  size_t used()     const { return _top - _base; }
-  bool is_packed()  const { return _is_packed;   }
-  bool is_allocatable() const {
-    return !is_packed() && _base != NULL;
-  }
+  MetaspaceShared::commit_shared_space_to(newtop);
+  _top = newtop;
+  return _top;
+}
+
+char* DumpRegion::allocate(size_t num_bytes, size_t alignment) {
+  char* p = (char*)align_up(_top, alignment);
+  char* newtop = p + align_up(num_bytes, alignment);
+  expand_top_to(newtop);
+  memset(p, 0, newtop - p);
+  return p;
+}
 
-  void print(size_t total_bytes) const {
-    tty->print_cr("%-3s space: " SIZE_FORMAT_W(9) " [ %4.1f%% of total] out of " SIZE_FORMAT_W(9) " bytes [%5.1f%% used] at " INTPTR_FORMAT,
-                  _name, used(), percent_of(used(), total_bytes), reserved(), percent_of(used(), reserved()), p2i(_base));
+void DumpRegion::print(size_t total_bytes) const {
+  tty->print_cr("%-3s space: " SIZE_FORMAT_W(9) " [ %4.1f%% of total] out of " SIZE_FORMAT_W(9) " bytes [%5.1f%% used] at " INTPTR_FORMAT,
+                _name, used(), percent_of(used(), total_bytes), reserved(), percent_of(used(), reserved()), p2i(_base));
+}
+
+void DumpRegion::print_out_of_space_msg(const char* failing_region, size_t needed_bytes) {
+  tty->print("[%-8s] " PTR_FORMAT " - " PTR_FORMAT " capacity =%9d, allocated =%9d",
+             _name, p2i(_base), p2i(_top), int(_end - _base), int(_top - _base));
+  if (strcmp(_name, failing_region) == 0) {
+    tty->print_cr(" required = %d", int(needed_bytes));
+  } else {
+    tty->cr();
   }
-  void print_out_of_space_msg(const char* failing_region, size_t needed_bytes) {
-    tty->print("[%-8s] " PTR_FORMAT " - " PTR_FORMAT " capacity =%9d, allocated =%9d",
-               _name, p2i(_base), p2i(_top), int(_end - _base), int(_top - _base));
-    if (strcmp(_name, failing_region) == 0) {
-      tty->print_cr(" required = %d", int(needed_bytes));
-    } else {
-      tty->cr();
-    }
-  }
+}
 
-  void init(const ReservedSpace* rs) {
-    _base = _top = rs->base();
-    _end = rs->end();
+void DumpRegion::pack(DumpRegion* next) {
+  assert(!is_packed(), "sanity");
+  _end = (char*)align_up(_top, Metaspace::reserve_alignment());
+  _is_packed = true;
+  if (next != NULL) {
+    next->_base = next->_top = this->_end;
+    next->_end = MetaspaceShared::shared_rs()->end();
   }
-  void init(char* b, char* t, char* e) {
-    _base = b;
-    _top = t;
-    _end = e;
-  }
+}
+
+DumpRegion _mc_region("mc"), _ro_region("ro"), _rw_region("rw"), _md_region("md"), _od_region("od");
+size_t _total_closed_archive_region_size = 0, _total_open_archive_region_size = 0;
 
-  void pack(DumpRegion* next = NULL) {
-    assert(!is_packed(), "sanity");
-    _end = (char*)align_up(_top, Metaspace::reserve_alignment());
-    _is_packed = true;
-    if (next != NULL) {
-      next->_base = next->_top = this->_end;
-      next->_end = MetaspaceShared::shared_rs()->end();
-    }
+void MetaspaceShared::init_shared_dump_space(DumpRegion* first_space, address first_space_bottom) {
+  // Start with 0 committed bytes. The memory will be committed as needed by
+  // MetaspaceShared::commit_shared_space_to().
+  if (!_shared_vs.initialize(_shared_rs, 0)) {
+    vm_exit_during_initialization("Unable to allocate memory for shared space");
   }
-  bool contains(char* p) {
-    return base() <= p && p < top();
-  }
-};
+  first_space->init(&_shared_rs, (char*)first_space_bottom);
+}
+
+DumpRegion* MetaspaceShared::misc_code_dump_space() {
+  return &_mc_region;
+}
+
+DumpRegion* MetaspaceShared::read_write_dump_space() {
+  return &_rw_region;
+}
 
+DumpRegion* MetaspaceShared::read_only_dump_space() {
+  return &_ro_region;
+}
 
-DumpRegion _mc_region("mc"), _ro_region("ro"), _rw_region("rw"), _md_region("md");
-size_t _total_closed_archive_region_size = 0, _total_open_archive_region_size = 0;
+DumpRegion* MetaspaceShared::optional_data_dump_space() {
+  return &_od_region;
+}
+
+void MetaspaceShared::pack_dump_space(DumpRegion* current, DumpRegion* next,
+                                      ReservedSpace* rs) {
+  current->pack(next);
+}
 
 char* MetaspaceShared::misc_code_space_alloc(size_t num_bytes) {
   return _mc_region.allocate(num_bytes);
@@ -226,20 +221,23 @@
   // If using shared space, open the file that contains the shared space
   // and map in the memory before initializing the rest of metaspace (so
   // the addresses don't conflict)
-  address cds_address = NULL;
-  FileMapInfo* mapinfo = new FileMapInfo();
+  FileMapInfo* mapinfo = new FileMapInfo(true);
 
   // Open the shared archive file, read and validate the header. If
   // initialization fails, shared spaces [UseSharedSpaces] are
   // disabled and the file is closed.
   // Map in spaces now also
-  if (mapinfo->initialize() && map_shared_spaces(mapinfo)) {
+  if (mapinfo->initialize(true) && map_shared_spaces(mapinfo)) {
     size_t cds_total = core_spaces_size();
-    cds_address = (address)mapinfo->region_addr(0);
+    address cds_address = (address)mapinfo->region_addr(0);
+    char* cds_end = (char *)align_up(cds_address + cds_total,
+                                     Metaspace::reserve_alignment());
+
+    // Mapping the dynamic archive before allocating the class space
+    cds_end = initialize_dynamic_runtime_shared_spaces((char*)cds_address, cds_end);
+
 #ifdef _LP64
     if (Metaspace::using_class_space()) {
-      char* cds_end = (char*)(cds_address + cds_total);
-      cds_end = (char *)align_up(cds_end, Metaspace::reserve_alignment());
       // If UseCompressedClassPointers is set then allocate the metaspace area
       // above the heap and above the CDS area (if it exists).
       Metaspace::allocate_metaspace_compressed_klass_ptrs(cds_end, cds_address);
@@ -255,6 +253,31 @@
   }
 }
 
+char* MetaspaceShared::initialize_dynamic_runtime_shared_spaces(
+        char* static_start, char* static_end) {
+  assert(UseSharedSpaces, "must be runtime");
+  char* cds_end = static_end;
+  if (!DynamicDumpSharedSpaces) {
+    address dynamic_top = DynamicArchive::map();
+    if (dynamic_top != NULL) {
+      assert(dynamic_top > (address)static_start, "Unexpected layout");
+      MetaspaceObj::expand_shared_metaspace_range(dynamic_top);
+      cds_end = (char *)align_up(dynamic_top, Metaspace::reserve_alignment());
+    }
+  }
+  return cds_end;
+}
+
+ReservedSpace* MetaspaceShared::reserve_shared_rs(size_t size, size_t alignment,
+                                                  bool large, char* requested_address) {
+  if (requested_address != NULL) {
+    _shared_rs = ReservedSpace(size, alignment, large, requested_address);
+  } else {
+    _shared_rs = ReservedSpace(size, alignment, large);
+  }
+  return &_shared_rs;
+}
+
 void MetaspaceShared::initialize_dumptime_shared_and_meta_spaces() {
   assert(DumpSharedSpaces, "should be called for dump time only");
   const size_t reserve_alignment = Metaspace::reserve_alignment();
@@ -280,12 +303,14 @@
 #endif
 
   // First try to reserve the space at the specified SharedBaseAddress.
-  _shared_rs = ReservedSpace(cds_total, reserve_alignment, large_pages, shared_base);
+  //_shared_rs = ReservedSpace(cds_total, reserve_alignment, large_pages, shared_base);
+  reserve_shared_rs(cds_total, reserve_alignment, large_pages, shared_base);
   if (_shared_rs.is_reserved()) {
     assert(shared_base == 0 || _shared_rs.base() == shared_base, "should match");
   } else {
     // Get a mmap region anywhere if the SharedBaseAddress fails.
-    _shared_rs = ReservedSpace(cds_total, reserve_alignment, large_pages);
+    //_shared_rs = ReservedSpace(cds_total, reserve_alignment, large_pages);
+    reserve_shared_rs(cds_total, reserve_alignment, large_pages, NULL);
   }
   if (!_shared_rs.is_reserved()) {
     vm_exit_during_initialization("Unable to reserve memory for shared space",
@@ -324,13 +349,7 @@
                 CompressedClassSpaceSize, p2i(tmp_class_space.base()));
 #endif
 
-  // Start with 0 committed bytes. The memory will be committed as needed by
-  // MetaspaceShared::commit_shared_space_to().
-  if (!_shared_vs.initialize(_shared_rs, 0)) {
-    vm_exit_during_initialization("Unable to allocate memory for shared space");
-  }
-
-  _mc_region.init(&_shared_rs);
+  init_shared_dump_space(&_mc_region);
   SharedBaseAddress = (size_t)_shared_rs.base();
   tty->print_cr("Allocated shared space: " SIZE_FORMAT " bytes at " PTR_FORMAT,
                 _shared_rs.size(), p2i(_shared_rs.base()));
@@ -342,9 +361,16 @@
     int size = FileMapInfo::get_number_of_shared_paths();
     if (size > 0) {
       SystemDictionaryShared::allocate_shared_data_arrays(size, THREAD);
-      FileMapHeader* header = FileMapInfo::current_info()->header();
-      ClassLoaderExt::init_paths_start_index(header->_app_class_paths_start_index);
-      ClassLoaderExt::init_app_module_paths_start_index(header->_app_module_paths_start_index);
+      if (!DynamicDumpSharedSpaces) {
+        FileMapHeader* header;
+        if (FileMapInfo::dynamic_info() == NULL) {
+          header = FileMapInfo::current_info()->header();
+        } else {
+          header = FileMapInfo::dynamic_info()->header();
+        }
+        ClassLoaderExt::init_paths_start_index(header->_app_class_paths_start_index);
+        ClassLoaderExt::init_app_module_paths_start_index(header->_app_module_paths_start_index);
+      }
     }
   }
 }
@@ -405,7 +431,7 @@
 }
 
 void MetaspaceShared::commit_shared_space_to(char* newtop) {
-  assert(DumpSharedSpaces, "dump-time only");
+  assert(DumpSharedSpaces || DynamicDumpSharedSpaces, "dump-time only");
   char* base = _shared_rs.base();
   size_t need_committed_size = newtop - base;
   size_t has_committed_size = _shared_vs.committed_size();
@@ -417,7 +443,8 @@
   size_t preferred_bytes = 1 * M;
   size_t uncommitted = _shared_vs.reserved_size() - has_committed_size;
 
-  size_t commit = MAX2(min_bytes, preferred_bytes);
+  size_t commit =MAX2(min_bytes, preferred_bytes);
+  commit = MIN2(commit, uncommitted);
   assert(commit <= uncommitted, "sanity");
 
   bool result = _shared_vs.expand_by(commit, false);
@@ -465,6 +492,9 @@
   InstanceMirrorKlass::serialize_offsets(soc);
   soc->do_tag(--tag);
 
+  serialize_cloned_cpp_vtptrs(soc);
+  soc->do_tag(--tag);
+
   soc->do_tag(666);
 }
 
@@ -484,6 +514,19 @@
   return _cds_i2i_entry_code_buffers;
 }
 
+uintx MetaspaceShared::object_delta_uintx(void* obj) {
+  assert(DumpSharedSpaces || DynamicDumpSharedSpaces,
+         "supported only for dumping");
+  if (DumpSharedSpaces) {
+    assert(shared_rs()->contains(obj), "must be");
+  } else {
+    assert(is_in_shared_metaspace(obj) || DynamicArchive::is_in_target_space(obj), "must be");
+  }
+  address base_address = address(SharedBaseAddress);
+  uintx deltax = address(obj) - base_address;
+  return deltax;
+}
+
 // Global object for holding classes that have been loaded.  Since this
 // is run at a safepoint just before exit, this is the entire set of classes.
 static GrowableArray<Klass*>* _global_klass_objects;
@@ -589,17 +632,21 @@
     Klass* k = _global_klass_objects->at(i);
     if (k->is_instance_klass()) {
       InstanceKlass* ik = InstanceKlass::cast(k);
-      for (int i = 0; i < ik->methods()->length(); i++) {
-        Method* m = ik->methods()->at(i);
-        rewrite_nofast_bytecode(m);
-        Fingerprinter fp(m);
-        // The side effect of this call sets method's fingerprint field.
-        fp.fingerprint();
-      }
+      MetaspaceShared::rewrite_nofast_bytecodes_and_calculate_fingerprints(ik);
     }
   }
 }
 
+void MetaspaceShared::rewrite_nofast_bytecodes_and_calculate_fingerprints(InstanceKlass* ik) {
+  for (int i = 0; i < ik->methods()->length(); i++) {
+    Method* m = ik->methods()->at(i);
+    rewrite_nofast_bytecode(m);
+    Fingerprinter fp(m);
+    // The side effect of this call sets method's fingerprint field.
+    fp.fingerprint();
+  }
+}
+
 // Objects of the Metadata types (such as Klass and ConstantPool) have C++ vtables.
 // (In GCC this is the field <Type>::_vptr, i.e., first word in the object.)
 //
@@ -686,7 +733,7 @@
   intptr_t* p = clone_vtable(name, _info);
   assert((char*)p == _md_region.top(), "must be");
 
-  return p;
+  return _info->cloned_vtable();
 }
 
 template <class T>
@@ -759,7 +806,7 @@
 }
 
 #define ALLOC_CPP_VTABLE_CLONE(c) \
-  CppVtableCloner<c>::allocate(#c);
+  _cloned_cpp_vtptrs[c##_Kind] = CppVtableCloner<c>::allocate(#c);
 
 #define CLONE_CPP_VTABLE(c) \
   p = CppVtableCloner<c>::clone_vtable(#c, (CppVtableInfo*)p);
@@ -767,6 +814,85 @@
 #define ZERO_CPP_VTABLE(c) \
  CppVtableCloner<c>::zero_vtable_clone();
 
+//------------------------------ for DynamicDumpSharedSpaces - start
+#define DECLARE_CLONED_VTABLE_KIND(c) c ## _Kind,
+
+enum {
+  CPP_VTABLE_PATCH_TYPES_DO(DECLARE_CLONED_VTABLE_KIND)
+  _num_cloned_vtable_kinds
+};
+
+static intptr_t** _cloned_cpp_vtptrs = NULL;
+
+void MetaspaceShared::serialize_cloned_cpp_vtptrs(SerializeClosure* soc) {
+  soc->do_ptr((void**)&_cloned_cpp_vtptrs);
+}
+
+intptr_t* MetaspaceShared::fix_cpp_vtable_for_dynamic_archive(MetaspaceObj::Type msotype, address obj) {
+  assert(DynamicDumpSharedSpaces, "must");
+  int kind = -1;
+  switch (msotype) {
+  case MetaspaceObj::SymbolType:
+  case MetaspaceObj::TypeArrayU1Type:
+  case MetaspaceObj::TypeArrayU2Type:
+  case MetaspaceObj::TypeArrayU4Type:
+  case MetaspaceObj::TypeArrayU8Type:
+  case MetaspaceObj::TypeArrayOtherType:
+  case MetaspaceObj::ConstMethodType:
+  case MetaspaceObj::ConstantPoolCacheType:
+  case MetaspaceObj::AnnotationsType:
+  case MetaspaceObj::MethodCountersType:
+    // These have no vtables.
+    break;
+  case MetaspaceObj::ClassType:
+    {
+      Klass* k = (Klass*)obj;
+      assert(k->is_klass(), "must be");
+      if (k->is_instance_klass()) {
+        kind = InstanceKlass_Kind;
+      } else {
+        assert(k->is_objArray_klass(),
+               "We shouldn't archive any other klasses in DynamicDumpSharedSpaces");
+        kind = ObjArrayKlass_Kind;
+      }
+    }
+    break;
+
+  case MetaspaceObj::MethodType:
+    {
+      Method* m = (Method*)obj;
+      assert(m->is_method(), "must be");
+      kind = Method_Kind;
+    }
+    break;
+
+  case MetaspaceObj::MethodDataType:
+    // We don't archive MethodData <-- should have been removed in removed_unsharable_info
+    ShouldNotReachHere();
+    break;
+
+  case MetaspaceObj::ConstantPoolType:
+    {
+      ConstantPool *cp = (ConstantPool*)obj;
+      assert(cp->is_constantPool(), "must be");
+      kind = ConstantPool_Kind;
+    }
+    break;
+
+  default:
+    ShouldNotReachHere();
+  }
+
+  if (kind >= 0) {
+    assert(kind < _num_cloned_vtable_kinds, "must be");
+    return _cloned_cpp_vtptrs[kind];
+  } else {
+    return NULL;
+  }
+}
+
+//------------------------------ for DynamicDumpSharedSpaces - end
+
 // This can be called at both dump time and run time.
 intptr_t* MetaspaceShared::clone_cpp_vtables(intptr_t* p) {
   assert(DumpSharedSpaces || UseSharedSpaces, "sanity");
@@ -830,55 +956,27 @@
   return CppVtableCloner<Method>::is_valid_shared_object(m);
 }
 
-// Closure for serializing initialization data out to a data area to be
-// written to the shared file.
-
-class WriteClosure : public SerializeClosure {
-private:
-  DumpRegion* _dump_region;
-
-public:
-  WriteClosure(DumpRegion* r) {
-    _dump_region = r;
+void WriteClosure::do_oop(oop* o) {
+  if (*o == NULL) {
+    _dump_region->append_intptr_t(0);
+  } else {
+    assert(HeapShared::is_heap_object_archiving_allowed(),
+           "Archiving heap object is not allowed");
+    _dump_region->append_intptr_t(
+      (intptr_t)CompressedOops::encode_not_null(*o));
   }
-
-  void do_ptr(void** p) {
-    _dump_region->append_intptr_t((intptr_t)*p);
-  }
-
-  void do_u4(u4* p) {
-    void* ptr = (void*)(uintx(*p));
-    do_ptr(&ptr);
-  }
-
-  void do_tag(int tag) {
-    _dump_region->append_intptr_t((intptr_t)tag);
-  }
+}
 
-  void do_oop(oop* o) {
-    if (*o == NULL) {
-      _dump_region->append_intptr_t(0);
-    } else {
-      assert(HeapShared::is_heap_object_archiving_allowed(),
-             "Archiving heap object is not allowed");
-      _dump_region->append_intptr_t(
-        (intptr_t)CompressedOops::encode_not_null(*o));
-    }
+void WriteClosure::do_region(u_char* start, size_t size) {
+  assert((intptr_t)start % sizeof(intptr_t) == 0, "bad alignment");
+  assert(size % sizeof(intptr_t) == 0, "bad size");
+  do_tag((int)size);
+  while (size > 0) {
+    _dump_region->append_intptr_t(*(intptr_t*)start);
+    start += sizeof(intptr_t);
+    size -= sizeof(intptr_t);
   }
-
-  void do_region(u_char* start, size_t size) {
-    assert((intptr_t)start % sizeof(intptr_t) == 0, "bad alignment");
-    assert(size % sizeof(intptr_t) == 0, "bad size");
-    do_tag((int)size);
-    while (size > 0) {
-      _dump_region->append_intptr_t(*(intptr_t*)start);
-      start += sizeof(intptr_t);
-      size -= sizeof(intptr_t);
-    }
-  }
-
-  bool reading() const { return false; }
-};
+}
 
 // This is for dumping detailed statistics for the allocations
 // in the shared spaces.
@@ -1166,20 +1264,22 @@
   public:
     ShallowCopier(bool read_only) : _read_only(read_only) {}
 
-    virtual void do_unique_ref(Ref* ref, bool read_only) {
+    virtual bool do_unique_ref(Ref* ref, bool read_only) {
       if (read_only == _read_only) {
         allocate(ref, read_only);
       }
+      return true; // recurse into ref.obj()
     }
   };
 
   // Relocate embedded pointers within a MetaspaceObj's shallow copy
   class ShallowCopyEmbeddedRefRelocator: public UniqueMetaspaceClosure {
   public:
-    virtual void do_unique_ref(Ref* ref, bool read_only) {
+    virtual bool do_unique_ref(Ref* ref, bool read_only) {
       address new_loc = get_new_loc(ref);
       RefRelocator refer;
       ref->metaspace_pointers_do_at(&refer, new_loc);
+      return true; // recurse into ref.obj()
     }
   };
 
@@ -1294,6 +1394,8 @@
     Universe::metaspace_pointers_do(it);
     SymbolTable::metaspace_pointers_do(it);
     vmSymbols::metaspace_pointers_do(it);
+
+    it->finish();
   }
 
   static Klass* get_relocated_klass(Klass* orig_klass) {
@@ -1336,6 +1438,9 @@
 
   char* start = _ro_region.top();
 
+  size_t vtptrs_bytes = _num_cloned_vtable_kinds * sizeof(intptr_t*);
+  _cloned_cpp_vtptrs = (intptr_t**)_ro_region.allocate(vtptrs_bytes, sizeof(intptr_t*));
+
   // Write the other data to the output array.
   WriteClosure wc(&_ro_region);
   MetaspaceShared::serialize(&wc);
@@ -1354,6 +1459,7 @@
   //     in the VM thread.
   // (2) ArchiveCompactor needs to work with a stable set of MetaspaceObjs.
   Metaspace::freeze();
+  DEBUG_ONLY(SystemDictionaryShared::NoClassLoadingMark nclm);
 
   Thread* THREAD = VMThread::vm_thread();
 
@@ -1441,7 +1547,7 @@
 
   // Create and write the archive file that maps the shared spaces.
 
-  FileMapInfo* mapinfo = new FileMapInfo();
+  FileMapInfo* mapinfo = new FileMapInfo(true);
   mapinfo->populate_header(os::vm_allocation_granularity());
   mapinfo->set_read_only_tables_start(read_only_tables_start);
   mapinfo->set_misc_data_patching_start(vtbl_list);
@@ -1816,67 +1922,55 @@
 }
 #endif // INCLUDE_CDS_JAVA_HEAP
 
-// Closure for serializing initialization data in from a data area
-// (ptr_array) read from the shared file.
-
-class ReadClosure : public SerializeClosure {
-private:
-  intptr_t** _ptr_array;
-
-  inline intptr_t nextPtr() {
-    return *(*_ptr_array)++;
-  }
+void ReadClosure::do_ptr(void** p) {
+  assert(*p == NULL, "initializing previous initialized pointer.");
+  intptr_t obj = nextPtr();
+  assert((intptr_t)obj >= 0 || (intptr_t)obj < -100,
+         "hit tag while initializing ptrs.");
+  *p = (void*)obj;
+}
 
-public:
-  ReadClosure(intptr_t** ptr_array) { _ptr_array = ptr_array; }
+void ReadClosure::do_u4(u4* p) {
+  intptr_t obj = nextPtr();
+  *p = (u4)(uintx(obj));
+}
 
-  void do_ptr(void** p) {
-    assert(*p == NULL, "initializing previous initialized pointer.");
-    intptr_t obj = nextPtr();
-    assert((intptr_t)obj >= 0 || (intptr_t)obj < -100,
-           "hit tag while initializing ptrs.");
-    *p = (void*)obj;
-  }
-
-  void do_u4(u4* p) {
-    intptr_t obj = nextPtr();
-    *p = (u4)(uintx(obj));
-  }
+void ReadClosure::do_tag(int tag) {
+  int old_tag;
+  old_tag = (int)(intptr_t)nextPtr();
+  // do_int(&old_tag);
+  assert(tag == old_tag, "old tag doesn't match");
+  FileMapInfo::assert_mark(tag == old_tag);
+}
 
-  void do_tag(int tag) {
-    int old_tag;
-    old_tag = (int)(intptr_t)nextPtr();
-    // do_int(&old_tag);
-    assert(tag == old_tag, "old tag doesn't match");
-    FileMapInfo::assert_mark(tag == old_tag);
+void ReadClosure::do_oop(oop *p) {
+  narrowOop o = (narrowOop)nextPtr();
+  if (o == 0 || !HeapShared::open_archive_heap_region_mapped()) {
+    p = NULL;
+  } else {
+    assert(HeapShared::is_heap_object_archiving_allowed(),
+           "Archived heap object is not allowed");
+    assert(HeapShared::open_archive_heap_region_mapped(),
+           "Open archive heap region is not mapped");
+    *p = HeapShared::decode_from_archive(o);
   }
+}
 
-  void do_oop(oop *p) {
-    narrowOop o = (narrowOop)nextPtr();
-    if (o == 0 || !HeapShared::open_archive_heap_region_mapped()) {
-      p = NULL;
-    } else {
-      assert(HeapShared::is_heap_object_archiving_allowed(),
-             "Archived heap object is not allowed");
-      assert(HeapShared::open_archive_heap_region_mapped(),
-             "Open archive heap region is not mapped");
-      *p = HeapShared::decode_from_archive(o);
-    }
+void ReadClosure::do_region(u_char* start, size_t size) {
+  assert((intptr_t)start % sizeof(intptr_t) == 0, "bad alignment");
+  assert(size % sizeof(intptr_t) == 0, "bad size");
+  do_tag((int)size);
+  while (size > 0) {
+    *(intptr_t*)start = nextPtr();
+    start += sizeof(intptr_t);
+    size -= sizeof(intptr_t);
   }
+}
 
-  void do_region(u_char* start, size_t size) {
-    assert((intptr_t)start % sizeof(intptr_t) == 0, "bad alignment");
-    assert(size % sizeof(intptr_t) == 0, "bad size");
-    do_tag((int)size);
-    while (size > 0) {
-      *(intptr_t*)start = nextPtr();
-      start += sizeof(intptr_t);
-      size -= sizeof(intptr_t);
-    }
-  }
-
-  bool reading() const { return true; }
-};
+void MetaspaceShared::set_shared_metaspace_range(void* base, void* top) {
+  _shared_metaspace_static_top = top;
+  MetaspaceObj::set_shared_metaspace_range(base, top);
+}
 
 // Return true if given address is in the misc data region
 bool MetaspaceShared::is_in_shared_region(const void* p, int idx) {
@@ -1890,6 +1984,15 @@
   return false;
 }
 
+bool MetaspaceShared::is_shared_dynamic(void* p) {
+  if ((p < MetaspaceObj::shared_metaspace_top()) &&
+      (p >= _shared_metaspace_static_top)) {
+    return true;
+  } else {
+    return false;
+  }
+}
+
 // Map shared spaces at requested addresses and return if succeeded.
 bool MetaspaceShared::map_shared_spaces(FileMapInfo* mapinfo) {
   size_t image_alignment = mapinfo->alignment();
@@ -1904,42 +2007,23 @@
 
   assert(!DumpSharedSpaces, "Should not be called with DumpSharedSpaces");
 
-  char* ro_base = NULL; char* ro_top;
-  char* rw_base = NULL; char* rw_top;
-  char* mc_base = NULL; char* mc_top;
-  char* md_base = NULL; char* md_top;
+  // Map each shared region
+  int regions[] = {mc, rw, ro, md};
+  size_t len = sizeof(regions)/sizeof(int);
+  char* saved_base[] = {NULL, NULL, NULL, NULL};
+  char* top = mapinfo->map_regions(regions, saved_base, len );
 
-  // Map each shared region
-  if ((mc_base = mapinfo->map_region(mc, &mc_top)) != NULL &&
-      (rw_base = mapinfo->map_region(rw, &rw_top)) != NULL &&
-      (ro_base = mapinfo->map_region(ro, &ro_top)) != NULL &&
-      (md_base = mapinfo->map_region(md, &md_top)) != NULL &&
+  if (top != NULL &&
       (image_alignment == (size_t)os::vm_allocation_granularity()) &&
       mapinfo->validate_shared_path_table()) {
     // Success -- set up MetaspaceObj::_shared_metaspace_{base,top} for
     // fast checking in MetaspaceShared::is_in_shared_metaspace() and
     // MetaspaceObj::is_shared().
-    //
-    // We require that mc->rw->ro->md to be laid out consecutively, with no
-    // gaps between them. That way, we can ensure that the OS won't be able to
-    // allocate any new memory spaces inside _shared_metaspace_{base,top}, which
-    // would mess up the simple comparision in MetaspaceShared::is_in_shared_metaspace().
-    assert(mc_base < ro_base && mc_base < rw_base && mc_base < md_base, "must be");
-    assert(md_top  > ro_top  && md_top  > rw_top  && md_top  > mc_top , "must be");
-    assert(mc_top == rw_base, "must be");
-    assert(rw_top == ro_base, "must be");
-    assert(ro_top == md_base, "must be");
-
     _core_spaces_size = mapinfo->core_spaces_size();
-    MetaspaceObj::set_shared_metaspace_range((void*)mc_base, (void*)md_top);
+    set_shared_metaspace_range((void*)saved_base[0], (void*)top);
     return true;
   } else {
-    // If there was a failure in mapping any of the spaces, unmap the ones
-    // that succeeded
-    if (ro_base != NULL) mapinfo->unmap_region(ro);
-    if (rw_base != NULL) mapinfo->unmap_region(rw);
-    if (mc_base != NULL) mapinfo->unmap_region(mc);
-    if (md_base != NULL) mapinfo->unmap_region(md);
+    mapinfo->unmap_regions(regions, saved_base, len);
 #ifndef _WINDOWS
     // Release the entire mapped region
     shared_rs.release();
@@ -1970,6 +2054,9 @@
   // The rest of the data is now stored in the RW region
   buffer = mapinfo->read_only_tables_start();
 
+  // Skip over _cloned_cpp_vtptrs;
+  buffer += _num_cloned_vtable_kinds * sizeof(intptr_t*);
+
   // Verify various attributes of the archive, plus initialize the
   // shared string/symbol tables
   intptr_t* array = (intptr_t*)buffer;
@@ -2009,6 +2096,12 @@
     if (!mapinfo->remap_shared_readonly_as_readwrite()) {
       return false;
     }
+    if (FileMapInfo::dynamic_info() != NULL) {
+      mapinfo = FileMapInfo::dynamic_info();
+      if (!mapinfo->remap_shared_readonly_as_readwrite()) {
+        return false;
+      }
+    }
     _remapped_readwrite = true;
   }
   return true;
--- a/src/hotspot/share/memory/metaspaceShared.hpp	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/share/memory/metaspaceShared.hpp	Thu May 23 11:07:37 2019 +0100
@@ -47,6 +47,124 @@
   CompactHashtableStats string;
 };
 
+#if INCLUDE_CDS
+class DumpRegion {
+private:
+  const char* _name;
+  char* _base;
+  char* _top;
+  char* _end;
+  bool _is_packed;
+
+public:
+  DumpRegion(const char* name) : _name(name), _base(NULL), _top(NULL), _end(NULL), _is_packed(false) {}
+
+  char* expand_top_to(char* newtop);
+  char* allocate(size_t num_bytes, size_t alignment=BytesPerWord);
+
+  void append_intptr_t(intptr_t n) {
+    assert(is_aligned(_top, sizeof(intptr_t)), "bad alignment");
+    intptr_t *p = (intptr_t*)_top;
+    char* newtop = _top + sizeof(intptr_t);
+    expand_top_to(newtop);
+    *p = n;
+  }
+
+  char* base()      const { return _base;        }
+  char* top()       const { return _top;         }
+  char* end()       const { return _end;         }
+  size_t reserved() const { return _end - _base; }
+  size_t used()     const { return _top - _base; }
+  bool is_packed()  const { return _is_packed;   }
+  bool is_allocatable() const {
+    return !is_packed() && _base != NULL;
+  }
+
+  void print(size_t total_bytes) const;
+  void print_out_of_space_msg(const char* failing_region, size_t needed_bytes);
+
+  void init(const ReservedSpace* rs, char* base) {
+    if (base == NULL) {
+      base = rs->base();
+    }
+    assert(rs->contains(base), "must be");
+    _base = _top = base;
+    _end = rs->end();
+  }
+  void init(char* b, char* t, char* e) {
+    _base = b;
+    _top = t;
+    _end = e;
+  }
+
+  void pack(DumpRegion* next = NULL);
+
+  bool contains(char* p) {
+    return base() <= p && p < top();
+  }
+};
+
+// Closure for serializing initialization data out to a data area to be
+// written to the shared file.
+
+class WriteClosure : public SerializeClosure {
+private:
+  DumpRegion* _dump_region;
+
+public:
+  WriteClosure(DumpRegion* r) {
+    _dump_region = r;
+  }
+
+  void do_ptr(void** p) {
+    _dump_region->append_intptr_t((intptr_t)*p);
+  }
+
+  void do_u4(u4* p) {
+    void* ptr = (void*)(uintx(*p));
+    do_ptr(&ptr);
+  }
+
+  void do_tag(int tag) {
+    _dump_region->append_intptr_t((intptr_t)tag);
+  }
+
+  void do_oop(oop* o);
+
+  void do_region(u_char* start, size_t size);
+
+  bool reading() const { return false; }
+};
+
+// Closure for serializing initialization data in from a data area
+// (ptr_array) read from the shared file.
+
+class ReadClosure : public SerializeClosure {
+private:
+  intptr_t** _ptr_array;
+
+  inline intptr_t nextPtr() {
+    return *(*_ptr_array)++;
+  }
+
+public:
+  ReadClosure(intptr_t** ptr_array) { _ptr_array = ptr_array; }
+
+  void do_ptr(void** p);
+
+  void do_u4(u4* p);
+
+  void do_tag(int tag);
+
+  void do_oop(oop *p);
+
+  void do_region(u_char* start, size_t size);
+
+  bool reading() const { return true; }
+};
+
+#endif
+
 // Class Data Sharing Support
 class MetaspaceShared : AllStatic {
 
@@ -61,6 +179,7 @@
   static address _cds_i2i_entry_code_buffers;
   static size_t  _cds_i2i_entry_code_buffers_size;
   static size_t  _core_spaces_size;
+  static void* _shared_metaspace_static_top;
  public:
   enum {
     // core archive spaces
@@ -102,16 +221,12 @@
   }
   static void initialize_dumptime_shared_and_meta_spaces() NOT_CDS_RETURN;
   static void initialize_runtime_shared_and_meta_spaces() NOT_CDS_RETURN;
+  static char* initialize_dynamic_runtime_shared_spaces(
+                     char* static_start, char* static_end) NOT_CDS_RETURN_(NULL);
   static void post_initialize(TRAPS) NOT_CDS_RETURN;
 
-  // Delta of this object from the bottom of the archive.
-  static uintx object_delta_uintx(void* obj) {
-    assert(DumpSharedSpaces, "supported only for dumping");
-    assert(shared_rs()->contains(obj), "must be");
-    address base_address = address(shared_rs()->base());
-    uintx deltax = address(obj) - base_address;
-    return deltax;
-  }
+  // Delta of this object from SharedBaseAddress
+  static uintx object_delta_uintx(void* obj);
 
   static u4 object_delta_u4(void* obj) {
     // offset is guaranteed to be less than MAX_SHARED_DELTA in DumpRegion::expand_top_to()
@@ -134,15 +249,25 @@
     return (p < MetaspaceObj::shared_metaspace_top() && p >= MetaspaceObj::shared_metaspace_base());
   }
 
+  static address shared_metaspace_top() {
+    return (address)MetaspaceObj::shared_metaspace_top();
+  }
+
+  static void set_shared_metaspace_range(void* base, void* top) NOT_CDS_RETURN;
+
   // Return true if given address is in the shared region corresponding to the idx
   static bool is_in_shared_region(const void* p, int idx) NOT_CDS_RETURN_(false);
 
   static bool is_in_trampoline_frame(address addr) NOT_CDS_RETURN_(false);
 
+  static bool is_shared_dynamic(void* p) NOT_CDS_RETURN_(false);
+
   static void allocate_cpp_vtable_clones();
   static intptr_t* clone_cpp_vtables(intptr_t* p);
   static void zero_cpp_vtable_clones_for_writing();
   static void patch_cpp_vtable_pointers();
+  static void serialize_cloned_cpp_vtptrs(SerializeClosure* sc);
+
   static bool is_valid_shared_method(const Method* m) NOT_CDS_RETURN_(false);
   static void serialize(SerializeClosure* sc) NOT_CDS_RETURN;
 
@@ -165,6 +290,20 @@
   static bool try_link_class(InstanceKlass* ik, TRAPS);
   static void link_and_cleanup_shared_classes(TRAPS);
 
+#if INCLUDE_CDS
+  static ReservedSpace* reserve_shared_rs(size_t size, size_t alignment,
+                                          bool large, char* requested_address);
+  static void init_shared_dump_space(DumpRegion* first_space, address first_space_bottom = NULL);
+  static DumpRegion* misc_code_dump_space();
+  static DumpRegion* read_write_dump_space();
+  static DumpRegion* read_only_dump_space();
+  static DumpRegion* optional_data_dump_space();
+  static void pack_dump_space(DumpRegion* current, DumpRegion* next,
+                              ReservedSpace* rs);
+
+  static void rewrite_nofast_bytecodes_and_calculate_fingerprints(InstanceKlass* ik);
+#endif
+
   // Allocate a block of memory from the "mc", "ro", or "rw" regions.
   static char* misc_code_space_alloc(size_t num_bytes);
   static char* read_only_space_alloc(size_t num_bytes);
@@ -181,6 +320,12 @@
 #endif
   }
 
+  template <typename T>
+  static size_t ro_array_bytesize(int length) {
+    size_t byte_size = Array<T>::byte_sizeof(length, sizeof(T));
+    return align_up(byte_size, BytesPerWord);
+  }
+
   static address cds_i2i_entry_code_buffers(size_t total_size);
 
   static address cds_i2i_entry_code_buffers() {
@@ -193,6 +338,8 @@
 
   static Klass* get_relocated_klass(Klass *k);
 
+  static intptr_t* fix_cpp_vtable_for_dynamic_archive(MetaspaceObj::Type msotype, address obj);
+
 private:
   static void read_extra_data(const char* filename, TRAPS) NOT_CDS_RETURN;
 };
--- a/src/hotspot/share/memory/universe.cpp	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/share/memory/universe.cpp	Thu May 23 11:07:37 2019 +0100
@@ -711,13 +711,14 @@
   {
     SymbolTable::create_table();
     StringTable::create_table();
+  }
 
 #if INCLUDE_CDS
-    if (DumpSharedSpaces) {
-      MetaspaceShared::prepare_for_dumping();
-    }
+  if (DumpSharedSpaces || DynamicDumpSharedSpaces) {
+    MetaspaceShared::prepare_for_dumping();
+  }
 #endif
-  }
+
   if (strlen(VerifySubSet) > 0) {
     Universe::initialize_verify_flags();
   }
--- a/src/hotspot/share/oops/constMethod.hpp	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/share/oops/constMethod.hpp	Thu May 23 11:07:37 2019 +0100
@@ -288,12 +288,16 @@
 
   // adapter
   void set_adapter_entry(AdapterHandlerEntry* adapter) {
-    assert(!is_shared(), "shared methods have fixed adapter_trampoline");
+    assert(!is_shared(),
+           "shared methods in archive have fixed adapter_trampoline");
     _adapter = adapter;
   }
   void set_adapter_trampoline(AdapterHandlerEntry** trampoline) {
-    assert(DumpSharedSpaces, "must be");
-    assert(*trampoline == NULL, "must be NULL during dump time, to be initialized at run time");
+    assert(DumpSharedSpaces || DynamicDumpSharedSpaces, "must be");
+    if (DumpSharedSpaces) {
+      assert(*trampoline == NULL,
+             "must be NULL during dump time, to be initialized at run time");
+    }
     _adapter_trampoline = trampoline;
   }
   void update_adapter_trampoline(AdapterHandlerEntry* adapter) {
--- a/src/hotspot/share/oops/constantPool.cpp	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/share/oops/constantPool.cpp	Thu May 23 11:07:37 2019 +0100
@@ -371,7 +371,9 @@
   // If archiving heap objects is not allowed, clear the resolved references.
   // Otherwise, it is cleared after the resolved references array is cached
   // (see archive_resolved_references()).
-  if (!HeapShared::is_heap_object_archiving_allowed()) {
+  // If DynamicDumpSharedSpaces is enabled, clear the resolved references also
+  // as java objects are not archived in the top layer.
+  if (!HeapShared::is_heap_object_archiving_allowed() || DynamicDumpSharedSpaces) {
     set_resolved_references(NULL);
   }
 
@@ -382,7 +384,16 @@
   _flags |= (_on_stack | _is_shared);
   int num_klasses = 0;
   for (int index = 1; index < length(); index++) { // Index 0 is unused
-    assert(!tag_at(index).is_unresolved_klass_in_error(), "This must not happen during dump time");
+    if (!DynamicDumpSharedSpaces) {
+      assert(!tag_at(index).is_unresolved_klass_in_error(), "This must not happen during static dump time");
+    } else {
+      if (tag_at(index).is_unresolved_klass_in_error() ||
+          tag_at(index).is_method_handle_in_error()    ||
+          tag_at(index).is_method_type_in_error()      ||
+          tag_at(index).is_dynamic_constant_in_error()) {
+        tag_at_put(index, JVM_CONSTANT_UnresolvedClass);
+      }
+    }
     if (tag_at(index).is_klass()) {
       // This class was resolved as a side effect of executing Java code
       // during dump time. We need to restore it back to an UnresolvedClass,
--- a/src/hotspot/share/oops/cpCache.cpp	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/share/oops/cpCache.cpp	Thu May 23 11:07:37 2019 +0100
@@ -697,7 +697,7 @@
 }
 
 void ConstantPoolCache::walk_entries_for_initialization(bool check_only) {
-  assert(DumpSharedSpaces, "sanity");
+  assert(DumpSharedSpaces || DynamicDumpSharedSpaces, "sanity");
   // When dumping the archive, we want to clean up the ConstantPoolCache
   // to remove any effect of linking due to the execution of Java code --
   // each ConstantPoolCacheEntry will have the same contents as if
--- a/src/hotspot/share/oops/instanceKlass.cpp	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/share/oops/instanceKlass.cpp	Thu May 23 11:07:37 2019 +0100
@@ -451,7 +451,7 @@
   assert(is_instance_klass(), "is layout incorrect?");
   assert(size_helper() == parser.layout_size(), "incorrect size_helper?");
 
-  if (DumpSharedSpaces) {
+  if (DumpSharedSpaces || DynamicDumpSharedSpaces) {
     SystemDictionaryShared::init_dumptime_info(this);
   }
 }
@@ -601,7 +601,7 @@
   }
   set_annotations(NULL);
 
-  if (DumpSharedSpaces) {
+  if (DumpSharedSpaces || DynamicDumpSharedSpaces) {
     SystemDictionaryShared::remove_dumptime_info(this);
   }
 }
@@ -2225,8 +2225,8 @@
     // (1) We are running AOT to generate a shared library.
     return true;
   }
-  if (DumpSharedSpaces) {
-    // (2) We are running -Xshare:dump to create a shared archive
+  if (DumpSharedSpaces || DynamicDumpSharedSpaces) {
+    // (2) We are running -Xshare:dump or -XX:ArchiveClassesAtExit to create a shared archive
     return true;
   }
   if (UseAOT && is_unsafe_anonymous) {
@@ -2346,15 +2346,13 @@
     array_klasses()->remove_unshareable_info();
   }
 
-  // These are not allocated from metaspace, but they should should all be empty
-  // during dump time, so we don't need to worry about them in InstanceKlass::iterate().
-  guarantee(_source_debug_extension == NULL, "must be");
-  guarantee(_dep_context == NULL, "must be");
-  guarantee(_osr_nmethods_head == NULL, "must be");
-
+  // These are not allocated from metaspace. They are safe to set to NULL.
+  _source_debug_extension = NULL;
+  _dep_context = NULL;
+  _osr_nmethods_head = NULL;
 #if INCLUDE_JVMTI
-  guarantee(_breakpoints == NULL, "must be");
-  guarantee(_previous_versions == NULL, "must be");
+  _breakpoints = NULL;
+  _previous_versions = NULL;
   _cached_class_file = NULL;
 #endif
 
@@ -2475,6 +2473,10 @@
   // notify ClassLoadingService of class unload
   ClassLoadingService::notify_class_unloaded(ik);
 
+  if (DumpSharedSpaces || DynamicDumpSharedSpaces) {
+    SystemDictionaryShared::remove_dumptime_info(ik);
+  }
+
   if (log_is_enabled(Info, class, unload)) {
     ResourceMark rm;
     log_info(class, unload)("unloading class %s " INTPTR_FORMAT, ik->external_name(), p2i(ik));
@@ -3422,7 +3424,12 @@
       info_stream.print(" source: %s", class_loader->klass()->external_name());
     }
   } else {
-    info_stream.print(" source: shared objects file");
+    assert(this->is_shared(), "must be");
+    if (MetaspaceShared::is_shared_dynamic((void*)this)) {
+      info_stream.print(" source: shared objects file (top)");
+    } else {
+      info_stream.print(" source: shared objects file");
+    }
   }
 
   msg.info("%s", info_stream.as_string());
--- a/src/hotspot/share/oops/klass.cpp	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/share/oops/klass.cpp	Thu May 23 11:07:37 2019 +0100
@@ -525,7 +525,8 @@
 }
 
 void Klass::remove_unshareable_info() {
-  assert (DumpSharedSpaces, "only called for DumpSharedSpaces");
+  assert (DumpSharedSpaces || DynamicDumpSharedSpaces,
+          "only called during CDS dump time");
   JFR_ONLY(REMOVE_ID(this);)
   if (log_is_enabled(Trace, cds, unshareable)) {
     ResourceMark rm;
@@ -542,7 +543,7 @@
 }
 
 void Klass::remove_java_mirror() {
-  assert (DumpSharedSpaces, "only called for DumpSharedSpaces");
+  assert(DumpSharedSpaces || DynamicDumpSharedSpaces, "only called during CDS dump time");
   if (log_is_enabled(Trace, cds, unshareable)) {
     ResourceMark rm;
     log_trace(cds, unshareable)("remove java_mirror: %s", external_name());
--- a/src/hotspot/share/oops/method.cpp	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/share/oops/method.cpp	Thu May 23 11:07:37 2019 +0100
@@ -958,23 +958,30 @@
 void Method::unlink_method() {
   _code = NULL;
 
-  assert(DumpSharedSpaces, "dump time only");
+  assert(DumpSharedSpaces || DynamicDumpSharedSpaces, "dump time only");
   // Set the values to what they should be at run time. Note that
   // this Method can no longer be executed during dump time.
   _i2i_entry = Interpreter::entry_for_cds_method(this);
   _from_interpreted_entry = _i2i_entry;
 
+  if (DynamicDumpSharedSpaces) {
+    assert(_from_compiled_entry != NULL, "sanity");
+  } else {
+    // TODO: Simplify the adapter trampoline allocation for static archiving.
+    //       Remove the use of CDSAdapterHandlerEntry.
+    CDSAdapterHandlerEntry* cds_adapter = (CDSAdapterHandlerEntry*)adapter();
+    constMethod()->set_adapter_trampoline(cds_adapter->get_adapter_trampoline());
+    _from_compiled_entry = cds_adapter->get_c2i_entry_trampoline();
+    assert(*((int*)_from_compiled_entry) == 0,
+           "must be NULL during dump time, to be initialized at run time");
+  }
+
   if (is_native()) {
     *native_function_addr() = NULL;
     set_signature_handler(NULL);
   }
   NOT_PRODUCT(set_compiled_invocation_count(0);)
 
-  CDSAdapterHandlerEntry* cds_adapter = (CDSAdapterHandlerEntry*)adapter();
-  constMethod()->set_adapter_trampoline(cds_adapter->get_adapter_trampoline());
-  _from_compiled_entry = cds_adapter->get_c2i_entry_trampoline();
-  assert(*((int*)_from_compiled_entry) == 0, "must be NULL during dump time, to be initialized at run time");
-
   set_method_data(NULL);
   clear_method_counters();
 }
--- a/src/hotspot/share/oops/method.hpp	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/share/oops/method.hpp	Thu May 23 11:07:37 2019 +0100
@@ -468,9 +468,15 @@
   void set_adapter_entry(AdapterHandlerEntry* adapter) {
     constMethod()->set_adapter_entry(adapter);
   }
+  void set_adapter_trampoline(AdapterHandlerEntry** trampoline) {
+    constMethod()->set_adapter_trampoline(trampoline);
+  }
   void update_adapter_trampoline(AdapterHandlerEntry* adapter) {
     constMethod()->update_adapter_trampoline(adapter);
   }
+  void set_from_compiled_entry(address entry) {
+    _from_compiled_entry =  entry;
+  }
 
   address get_i2c_entry();
   address get_c2i_entry();
@@ -511,7 +517,8 @@
   address interpreter_entry() const              { return _i2i_entry; }
   // Only used when first initialize so we can set _i2i_entry and _from_interpreted_entry
   void set_interpreter_entry(address entry) {
-    assert(!is_shared(), "shared method's interpreter entry should not be changed at run time");
+    assert(!is_shared(),
+           "shared method's interpreter entry should not be changed at run time");
     if (_i2i_entry != entry) {
       _i2i_entry = entry;
     }
--- a/src/hotspot/share/oops/methodData.hpp	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/share/oops/methodData.hpp	Thu May 23 11:07:37 2019 +0100
@@ -31,9 +31,6 @@
 #include "oops/oop.hpp"
 #include "runtime/atomic.hpp"
 #include "utilities/align.hpp"
-#if INCLUDE_JVMCI
-#include "jvmci/jvmci_globals.hpp"
-#endif
 
 class BytecodeStream;
 class KlassSizeStats;
--- a/src/hotspot/share/oops/symbol.cpp	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/share/oops/symbol.cpp	Thu May 23 11:07:37 2019 +0100
@@ -74,6 +74,13 @@
   FreeHeap(p);
 }
 
+void Symbol::set_permanent() {
+  // This is called at a safepoint during dumping of a dynamic CDS archive.
+  assert(SafepointSynchronize::is_at_safepoint(), "must be at a safepoint");
+  _length_and_refcount =  pack_length_and_refcount(length(), PERM_REFCOUNT);
+}
+
+
 // ------------------------------------------------------------------
 // Symbol::starts_with
 //
--- a/src/hotspot/share/oops/symbol.hpp	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/share/oops/symbol.hpp	Thu May 23 11:07:37 2019 +0100
@@ -169,6 +169,7 @@
   bool is_permanent() {
     return (refcount() == PERM_REFCOUNT);
   }
+  void set_permanent();
   void make_permanent();
 
   // Function char_at() returns the Symbol's selected u1 byte as a char type.
--- a/src/hotspot/share/opto/arraycopynode.cpp	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/share/opto/arraycopynode.cpp	Thu May 23 11:07:37 2019 +0100
@@ -296,6 +296,10 @@
 
     src_offset = Compile::conv_I2X_index(phase, src_offset, ary_src->size());
     dest_offset = Compile::conv_I2X_index(phase, dest_offset, ary_dest->size());
+    if (src_offset->is_top() || dest_offset->is_top()) {
+      // Offset is out of bounds (the ArrayCopyNode will be removed)
+      return false;
+    }
 
     Node* src_scale = phase->transform(new LShiftXNode(src_offset, phase->intcon(shift)));
     Node* dest_scale = phase->transform(new LShiftXNode(dest_offset, phase->intcon(shift)));
--- a/src/hotspot/share/opto/block.cpp	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/share/opto/block.cpp	Thu May 23 11:07:37 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2019, 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
@@ -267,7 +267,7 @@
 
 #ifndef PRODUCT
 void Block::dump_bidx(const Block* orig, outputStream* st) const {
-  if (_pre_order) st->print("B%d",_pre_order);
+  if (_pre_order) st->print("B%d", _pre_order);
   else st->print("N%d", head()->_idx);
 
   if (Verbose && orig != this) {
@@ -291,30 +291,36 @@
 }
 
 void Block::dump_head(const PhaseCFG* cfg, outputStream* st) const {
-  // Print the basic block
+  // Print the basic block.
   dump_bidx(this, st);
-  st->print(": #\t");
+  st->print(": ");
 
-  // Print the incoming CFG edges and the outgoing CFG edges
+  // Print the outgoing CFG edges.
+  st->print("#\tout( ");
   for( uint i=0; i<_num_succs; i++ ) {
     non_connector_successor(i)->dump_bidx(_succs[i], st);
     st->print(" ");
   }
-  st->print("<- ");
+
+  // Print the incoming CFG edges.
+  st->print(") <- ");
   if( head()->is_block_start() ) {
+    st->print("in( ");
     for (uint i=1; i<num_preds(); i++) {
       Node *s = pred(i);
       if (cfg != NULL) {
         Block *p = cfg->get_block_for_node(s);
         p->dump_pred(cfg, p, st);
       } else {
-        while (!s->is_block_start())
+        while (!s->is_block_start()) {
           s = s->in(0);
+        }
         st->print("N%d ", s->_idx );
       }
     }
+    st->print(") ");
   } else {
-    st->print("BLOCK HEAD IS JUNK  ");
+    st->print("BLOCK HEAD IS JUNK ");
   }
 
   // Print loop, if any
@@ -327,12 +333,15 @@
     while (bx->is_connector()) {
       bx = cfg->get_block_for_node(bx->pred(1));
     }
-    st->print("\tLoop: B%d-B%d ", bhead->_pre_order, bx->_pre_order);
+    st->print("Loop( B%d-B%d ", bhead->_pre_order, bx->_pre_order);
     // Dump any loop-specific bits, especially for CountedLoops.
     loop->dump_spec(st);
+    st->print(")");
   } else if (has_loop_alignment()) {
-    st->print(" top-of-loop");
+    st->print("top-of-loop");
   }
+
+  // Print frequency and other optimization-relevant information
   st->print(" Freq: %g",_freq);
   if( Verbose || WizardMode ) {
     st->print(" IDom: %d/#%d", _idom ? _idom->_pre_order : 0, _dom_depth);
--- a/src/hotspot/share/opto/c2_globals.cpp	Fri May 17 13:21:44 2019 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,38 +0,0 @@
-/*
- * Copyright (c) 2000, 2016, 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.
- *
- */
-
-#include "precompiled.hpp"
-#include "opto/c2_globals.hpp"
-
-C2_FLAGS(MATERIALIZE_DEVELOPER_FLAG, \
-         MATERIALIZE_PD_DEVELOPER_FLAG, \
-         MATERIALIZE_PRODUCT_FLAG, \
-         MATERIALIZE_PD_PRODUCT_FLAG, \
-         MATERIALIZE_DIAGNOSTIC_FLAG, \
-         MATERIALIZE_PD_DIAGNOSTIC_FLAG, \
-         MATERIALIZE_EXPERIMENTAL_FLAG, \
-         MATERIALIZE_NOTPRODUCT_FLAG, \
-         IGNORE_RANGE, \
-         IGNORE_CONSTRAINT, \
-         IGNORE_WRITEABLE)
--- a/src/hotspot/share/opto/c2_globals.hpp	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/share/opto/c2_globals.hpp	Thu May 23 11:07:37 2019 +0100
@@ -25,7 +25,7 @@
 #ifndef SHARE_OPTO_C2_GLOBALS_HPP
 #define SHARE_OPTO_C2_GLOBALS_HPP
 
-#include "runtime/globals.hpp"
+#include "runtime/globals_shared.hpp"
 #include "utilities/macros.hpp"
 
 #include CPU_HEADER(c2_globals)
@@ -758,16 +758,4 @@
   product(bool, UseProfiledLoopPredicate, true,                             \
           "move predicates out of loops based on profiling data")           \
 
-C2_FLAGS(DECLARE_DEVELOPER_FLAG, \
-         DECLARE_PD_DEVELOPER_FLAG, \
-         DECLARE_PRODUCT_FLAG, \
-         DECLARE_PD_PRODUCT_FLAG, \
-         DECLARE_DIAGNOSTIC_FLAG, \
-         DECLARE_PD_DIAGNOSTIC_FLAG, \
-         DECLARE_EXPERIMENTAL_FLAG, \
-         DECLARE_NOTPRODUCT_FLAG, \
-         IGNORE_RANGE, \
-         IGNORE_CONSTRAINT, \
-         IGNORE_WRITEABLE)
-
 #endif // SHARE_OPTO_C2_GLOBALS_HPP
--- a/src/hotspot/share/opto/compile.cpp	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/share/opto/compile.cpp	Thu May 23 11:07:37 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2019, 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
@@ -713,16 +713,19 @@
   TraceTime t1("Total compilation time", &_t_totalCompilation, CITime, CITimeVerbose);
   TraceTime t2(NULL, &_t_methodCompilation, CITime, false);
 
-#ifndef PRODUCT
+#if defined(SUPPORT_ASSEMBLY) || defined(SUPPORT_ABSTRACT_ASSEMBLY)
   bool print_opto_assembly = directive->PrintOptoAssemblyOption;
-  if (!print_opto_assembly) {
-    bool print_assembly = directive->PrintAssemblyOption;
-    if (print_assembly && !Disassembler::can_decode()) {
-      tty->print_cr("PrintAssembly request changed to PrintOptoAssembly");
-      print_opto_assembly = true;
-    }
-  }
-  set_print_assembly(print_opto_assembly);
+  // We can always print a disassembly, either abstract (hex dump) or
+  // with the help of a suitable hsdis library. Thus, we should not
+  // couple print_assembly and print_opto_assembly controls.
+  // But: always print opto and regular assembly on compile command 'print'.
+  bool print_assembly = directive->PrintAssemblyOption;
+  set_print_assembly(print_opto_assembly || print_assembly);
+#else
+  set_print_assembly(false); // must initialize.
+#endif
+
+#ifndef PRODUCT
   set_parsed_irreducible_loop(false);
 
   if (directive->ReplayInlineOption) {
@@ -1027,6 +1030,8 @@
 #ifndef PRODUCT
   set_print_assembly(PrintFrameConverterAssembly);
   set_parsed_irreducible_loop(false);
+#else
+  set_print_assembly(false); // Must initialize.
 #endif
   set_has_irreducible_loop(false); // no loops
 
@@ -2552,12 +2557,25 @@
 
 //------------------------------dump_asm---------------------------------------
 // Dump formatted assembly
-#ifndef PRODUCT
-void Compile::dump_asm(int *pcs, uint pc_limit) {
+#if defined(SUPPORT_OPTO_ASSEMBLY)
+void Compile::dump_asm_on(outputStream* st, int* pcs, uint pc_limit) {
+
+  int pc_digits = 3; // #chars required for pc
+  int sb_chars  = 3; // #chars for "start bundle" indicator
+  int tab_size  = 8;
+  if (pcs != NULL) {
+    int max_pc = 0;
+    for (uint i = 0; i < pc_limit; i++) {
+      max_pc = (max_pc < pcs[i]) ? pcs[i] : max_pc;
+    }
+    pc_digits  = ((max_pc < 4096) ? 3 : ((max_pc < 65536) ? 4 : ((max_pc < 65536*256) ? 6 : 8))); // #chars required for pc
+  }
+  int prefix_len = ((pc_digits + sb_chars + tab_size - 1)/tab_size)*tab_size;
+
   bool cut_short = false;
-  tty->print_cr("#");
-  tty->print("#  ");  _tf->dump();  tty->cr();
-  tty->print_cr("#");
+  st->print_cr("#");
+  st->print("#  ");  _tf->dump_on(st);  st->cr();
+  st->print_cr("#");
 
   // For all blocks
   int pc = 0x0;                 // Program counter
@@ -2575,16 +2593,18 @@
       continue;
     }
     n = block->head();
-    if (pcs && n->_idx < pc_limit) {
-      tty->print("%3.3x   ", pcs[n->_idx]);
-    } else {
-      tty->print("      ");
+    if ((pcs != NULL) && (n->_idx < pc_limit)) {
+      pc = pcs[n->_idx];
+      st->print("%*.*x", pc_digits, pc_digits, pc);
     }
-    block->dump_head(_cfg);
+    st->fill_to(prefix_len);
+    block->dump_head(_cfg, st);
     if (block->is_connector()) {
-      tty->print_cr("        # Empty connector block");
+      st->fill_to(prefix_len);
+      st->print_cr("# Empty connector block");
     } else if (block->num_preds() == 2 && block->pred(1)->is_CatchProj() && block->pred(1)->as_CatchProj()->_con == CatchProjNode::fall_through_index) {
-      tty->print_cr("        # Block is sole successor of call");
+      st->fill_to(prefix_len);
+      st->print_cr("# Block is sole successor of call");
     }
 
     // For all instructions
@@ -2620,34 +2640,39 @@
           !n->is_top() &&       // Debug info table constants
           !(n->is_Con() && !n->is_Mach())// Debug info table constants
           ) {
-        if (pcs && n->_idx < pc_limit)
-          tty->print("%3.3x", pcs[n->_idx]);
-        else
-          tty->print("   ");
-        tty->print(" %c ", starts_bundle);
+        if ((pcs != NULL) && (n->_idx < pc_limit)) {
+          pc = pcs[n->_idx];
+          st->print("%*.*x", pc_digits, pc_digits, pc);
+        } else {
+          st->fill_to(pc_digits);
+        }
+        st->print(" %c ", starts_bundle);
         starts_bundle = ' ';
-        tty->print("\t");
-        n->format(_regalloc, tty);
-        tty->cr();
+        st->fill_to(prefix_len);
+        n->format(_regalloc, st);
+        st->cr();
       }
 
       // If we have an instruction with a delay slot, and have seen a delay,
       // then back up and print it
       if (valid_bundle_info(n) && node_bundling(n)->use_unconditional_delay()) {
-        assert(delay != NULL, "no unconditional delay instruction");
+        // Coverity finding - Explicit null dereferenced.
+        guarantee(delay != NULL, "no unconditional delay instruction");
         if (WizardMode) delay->dump();
 
         if (node_bundling(delay)->starts_bundle())
           starts_bundle = '+';
-        if (pcs && n->_idx < pc_limit)
-          tty->print("%3.3x", pcs[n->_idx]);
-        else
-          tty->print("   ");
-        tty->print(" %c ", starts_bundle);
+        if ((pcs != NULL) && (n->_idx < pc_limit)) {
+          pc = pcs[n->_idx];
+          st->print("%*.*x", pc_digits, pc_digits, pc);
+        } else {
+          st->fill_to(pc_digits);
+        }
+        st->print(" %c ", starts_bundle);
         starts_bundle = ' ';
-        tty->print("\t");
-        delay->format(_regalloc, tty);
-        tty->cr();
+        st->fill_to(prefix_len);
+        delay->format(_regalloc, st);
+        st->cr();
         delay = NULL;
       }
 
@@ -2656,19 +2681,13 @@
         // Print the exception table for this offset
         _handler_table.print_subtable_for(pc);
       }
+      st->bol(); // Make sure we start on a new line
     }
-
-    if (pcs && n->_idx < pc_limit)
-      tty->print_cr("%3.3x", pcs[n->_idx]);
-    else
-      tty->cr();
-
+    st->cr(); // one empty line between blocks
     assert(cut_short || delay == NULL, "no unconditional delay branch");
-
   } // End of per-block dump
-  tty->cr();
-
-  if (cut_short)  tty->print_cr("*** disassembly is cut short ***");
+
+  if (cut_short)  st->print_cr("*** disassembly is cut short ***");
 }
 #endif
 
--- a/src/hotspot/share/opto/compile.hpp	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/share/opto/compile.hpp	Thu May 23 11:07:37 2019 +0100
@@ -1348,7 +1348,13 @@
   static void print_statistics() PRODUCT_RETURN;
 
   // Dump formatted assembly
-  void dump_asm(int *pcs = NULL, uint pc_limit = 0) PRODUCT_RETURN;
+#if defined(SUPPORT_OPTO_ASSEMBLY)
+  void dump_asm_on(outputStream* ost, int* pcs, uint pc_limit);
+  void dump_asm(int* pcs = NULL, uint pc_limit = 0) { dump_asm_on(tty, pcs, pc_limit); }
+#else
+  void dump_asm_on(outputStream* ost, int* pcs, uint pc_limit) { return; }
+  void dump_asm(int* pcs = NULL, uint pc_limit = 0) { return; }
+#endif
   void dump_pc(int *pcs, int pc_limit, Node *n);
 
   // Verify ADLC assumptions during startup
--- a/src/hotspot/share/opto/graphKit.cpp	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/share/opto/graphKit.cpp	Thu May 23 11:07:37 2019 +0100
@@ -1859,6 +1859,18 @@
   }
 }
 
+// Keep track of MergeMems feeding into other MergeMems
+static void add_mergemem_users_to_worklist(Unique_Node_List& wl, Node* mem) {
+  if (!mem->is_MergeMem()) {
+    return;
+  }
+  for (SimpleDUIterator i(mem); i.has_next(); i.next()) {
+    Node* use = i.get();
+    if (use->is_MergeMem()) {
+      wl.push(use);
+    }
+  }
+}
 
 // Replace the call with the current state of the kit.
 void GraphKit::replace_call(CallNode* call, Node* result, bool do_replaced_nodes) {
@@ -1877,6 +1889,7 @@
   CallProjections callprojs;
   call->extract_projections(&callprojs, true);
 
+  Unique_Node_List wl;
   Node* init_mem = call->in(TypeFunc::Memory);
   Node* final_mem = final_state->in(TypeFunc::Memory);
   Node* final_ctl = final_state->in(TypeFunc::Control);
@@ -1892,6 +1905,7 @@
       final_mem = _gvn.transform(final_mem);
     }
     C->gvn_replace_by(callprojs.fallthrough_memproj,   final_mem);
+    add_mergemem_users_to_worklist(wl, final_mem);
   }
   if (callprojs.fallthrough_ioproj != NULL) {
     C->gvn_replace_by(callprojs.fallthrough_ioproj,    final_io);
@@ -1931,7 +1945,9 @@
       ex_ctl = ekit.control();
     }
     if (callprojs.catchall_memproj != NULL) {
-      C->gvn_replace_by(callprojs.catchall_memproj,   ekit.reset_memory());
+      Node* ex_mem = ekit.reset_memory();
+      C->gvn_replace_by(callprojs.catchall_memproj,   ex_mem);
+      add_mergemem_users_to_worklist(wl, ex_mem);
     }
     if (callprojs.catchall_ioproj != NULL) {
       C->gvn_replace_by(callprojs.catchall_ioproj,    ekit.i_o());
@@ -1949,17 +1965,8 @@
 
   // Clean up any MergeMems that feed other MergeMems since the
   // optimizer doesn't like that.
-  if (final_mem->is_MergeMem()) {
-    Node_List wl;
-    for (SimpleDUIterator i(final_mem); i.has_next(); i.next()) {
-      Node* m = i.get();
-      if (m->is_MergeMem() && !wl.contains(m)) {
-        wl.push(m);
-      }
-    }
-    while (wl.size()  > 0) {
-      _gvn.transform(wl.pop());
-    }
+  while (wl.size() > 0) {
+    _gvn.transform(wl.pop());
   }
 
   if (callprojs.fallthrough_catchproj != NULL && !final_ctl->is_top() && do_replaced_nodes) {
--- a/src/hotspot/share/opto/output.cpp	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/share/opto/output.cpp	Thu May 23 11:07:37 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2019, 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
@@ -1106,12 +1106,17 @@
 #endif
 
   // Create an array of unused labels, one for each basic block, if printing is enabled
-#ifndef PRODUCT
+#if defined(SUPPORT_OPTO_ASSEMBLY)
   int *node_offsets      = NULL;
   uint node_offset_limit = unique();
 
-  if (print_assembly())
-    node_offsets         = NEW_RESOURCE_ARRAY(int, node_offset_limit);
+  if (print_assembly()) {
+    node_offsets = NEW_RESOURCE_ARRAY(int, node_offset_limit);
+  }
+  if (node_offsets != NULL) {
+    // We need to initialize. Unused array elements may contain garbage and mess up PrintOptoAssembly.
+    memset(node_offsets, 0, node_offset_limit*sizeof(int));
+  }
 #endif
 
   NonSafepointEmitter non_safepoints(this);  // emit non-safepoints lazily
@@ -1381,9 +1386,10 @@
       }
 
       // Save the offset for the listing
-#ifndef PRODUCT
-      if (node_offsets && n->_idx < node_offset_limit)
+#if defined(SUPPORT_OPTO_ASSEMBLY)
+      if ((node_offsets != NULL) && (n->_idx < node_offset_limit)) {
         node_offsets[n->_idx] = cb->insts_size();
+      }
 #endif
 
       // "Normal" instruction case
@@ -1430,9 +1436,10 @@
         cb->set_insts_end(cb->insts_end() - Pipeline::instr_unit_size());
 
         // Save the offset for the listing
-#ifndef PRODUCT
-        if (node_offsets && delay_slot->_idx < node_offset_limit)
+#if defined(SUPPORT_OPTO_ASSEMBLY)
+        if ((node_offsets != NULL) && (delay_slot->_idx < node_offset_limit)) {
           node_offsets[delay_slot->_idx] = cb->insts_size();
+        }
 #endif
 
         // Support a SafePoint in the delay slot
@@ -1541,7 +1548,14 @@
     return;
   }
 
-#ifndef PRODUCT
+#if defined(SUPPORT_ABSTRACT_ASSEMBLY) || defined(SUPPORT_ASSEMBLY) || defined(SUPPORT_OPTO_ASSEMBLY)
+  if (print_assembly()) {
+    tty->cr();
+    tty->print_cr("============================= C2-compiled nmethod ==============================");
+  }
+#endif
+
+#if defined(SUPPORT_OPTO_ASSEMBLY)
   // Dump the assembly code, including basic-block numbers
   if (print_assembly()) {
     ttyLocker ttyl;  // keep the following output all in one block
@@ -1555,11 +1569,15 @@
                    "");
       }
       if (method() != NULL) {
+        tty->print_cr("----------------------------------- MetaData -----------------------------------");
         method()->print_metadata();
       } else if (stub_name() != NULL) {
-        tty->print_cr("Generating RuntimeStub - %s", stub_name());
+        tty->print_cr("----------------------------- RuntimeStub %s -------------------------------", stub_name());
       }
+      tty->cr();
+      tty->print_cr("--------------------------------- OptoAssembly ---------------------------------");
       dump_asm(node_offsets, node_offset_limit);
+      tty->print_cr("--------------------------------------------------------------------------------");
       if (xtty != NULL) {
         // print_metadata and dump_asm above may safepoint which makes us loose the ttylock.
         // Retake lock too make sure the end tag is coherent, and that xmlStream->pop_tag is done
@@ -1570,7 +1588,6 @@
     }
   }
 #endif
-
 }
 
 void Compile::FillExceptionTables(uint cnt, uint *call_returns, uint *inct_starts, Label *blk_labels) {
--- a/src/hotspot/share/prims/cdsoffsets.cpp	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/share/prims/cdsoffsets.cpp	Thu May 23 11:07:37 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2019, 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
@@ -26,6 +26,7 @@
 #include "utilities/macros.hpp"
 #if INCLUDE_CDS
 #include "runtime/os.hpp"
+#include "memory/dynamicArchive.hpp"
 #include "memory/filemap.hpp"
 #include "memory/allocation.hpp"
 #include "memory/allocation.inline.hpp"
@@ -44,6 +45,7 @@
 
 #define CREATE_OFFSET_MAPS                                                                  \
     _all = new CDSOffsets("size_t_size", sizeof(size_t), NULL);                             \
+    ADD_NEXT(_all, "int_size", sizeof(int));                                                \
     ADD_NEXT(_all, "FileMapHeader::_magic", offset_of(FileMapHeader, _magic));              \
     ADD_NEXT(_all, "FileMapHeader::_crc", offset_of(FileMapHeader, _crc));                  \
     ADD_NEXT(_all, "FileMapHeader::_version", offset_of(FileMapHeader, _version));          \
@@ -52,6 +54,7 @@
     ADD_NEXT(_all, "CDSFileMapRegion::_used", offset_of(CDSFileMapRegion, _used));          \
     ADD_NEXT(_all, "FileMapHeader::_paths_misc_info_size", offset_of(FileMapHeader, _paths_misc_info_size)); \
     ADD_NEXT(_all, "file_header_size", sizeof(FileMapHeader));                              \
+    ADD_NEXT(_all, "DynamicArchiveHeader::_base_archive_crc", offset_of(DynamicArchiveHeader, _base_archive_crc)); \
     ADD_NEXT(_all, "CDSFileMapRegion_size", sizeof(CDSFileMapRegion));
 
 int CDSOffsets::find_offset(const char* name) {
--- a/src/hotspot/share/prims/forte.cpp	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/share/prims/forte.cpp	Thu May 23 11:07:37 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2019, 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
@@ -70,7 +70,7 @@
 // Native interfaces for use by Forte tools.
 
 
-#if !defined(IA64) && !defined(PPC64)
+#if !defined(IA64)
 
 class vframeStreamForte : public vframeStreamCommon {
  public:
@@ -639,16 +639,16 @@
 #endif // !_WINDOWS
 
 } // end extern "C"
-#endif // !IA64 && !PPC64
+#endif // !IA64
 
 void Forte::register_stub(const char* name, address start, address end) {
-#if !defined(_WINDOWS) && !defined(IA64) && !defined(PPC64)
+#if !defined(_WINDOWS) && !defined(IA64)
   assert(pointer_delta(end, start, sizeof(jbyte)) < INT_MAX,
          "Code size exceeds maximum range");
 
   collector_func_load((char*)name, NULL, NULL, start,
     pointer_delta(end, start, sizeof(jbyte)), 0, NULL);
-#endif // !_WINDOWS && !IA64 && !PPC64
+#endif // !_WINDOWS && !IA64
 }
 
 #else // INCLUDE_JVMTI
--- a/src/hotspot/share/prims/jvm.cpp	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/share/prims/jvm.cpp	Thu May 23 11:07:37 2019 +0100
@@ -64,6 +64,7 @@
 #include "runtime/init.hpp"
 #include "runtime/interfaceSupport.inline.hpp"
 #include "runtime/deoptimization.hpp"
+#include "runtime/handshake.hpp"
 #include "runtime/java.hpp"
 #include "runtime/javaCalls.hpp"
 #include "runtime/jfieldIDWorkaround.hpp"
@@ -3006,31 +3007,47 @@
   return JNIHandles::make_local(env, jthread);
 JVM_END
 
+class CountStackFramesTC : public ThreadClosure {
+  int _count;
+  bool _suspended;
+ public:
+  CountStackFramesTC() : _count(0), _suspended(false) {}
+  virtual void do_thread(Thread* thread) {
+    JavaThread* jt = (JavaThread*)thread;
+    if (!jt->is_external_suspend()) {
+      // To keep same behavior we fail this operation,
+      // even if it would work perfectly.
+      return;
+    }
+    _suspended = true;
+     // Count all java activation, i.e., number of vframes.
+    for (vframeStream vfst(jt); !vfst.at_end(); vfst.next()) {
+      // Native frames are not counted.
+      if (!vfst.method()->is_native()) _count++;
+    }
+  }
+  int count() { return _count; }
+  int suspended() { return _suspended; }
+};
 
 JVM_ENTRY(jint, JVM_CountStackFrames(JNIEnv* env, jobject jthread))
   JVMWrapper("JVM_CountStackFrames");
 
-  uint32_t debug_bits = 0;
   ThreadsListHandle tlh(thread);
   JavaThread* receiver = NULL;
   bool is_alive = tlh.cv_internal_thread_to_JavaThread(jthread, &receiver, NULL);
-  int count = 0;
   if (is_alive) {
     // jthread refers to a live JavaThread.
-    if (receiver->is_thread_fully_suspended(true /* wait for suspend completion */, &debug_bits)) {
-      // Count all java activation, i.e., number of vframes.
-      for (vframeStream vfst(receiver); !vfst.at_end(); vfst.next()) {
-        // Native frames are not counted.
-        if (!vfst.method()->is_native()) count++;
-      }
-    } else {
+    CountStackFramesTC csf;
+    Handshake::execute(&csf, receiver);
+    if (!csf.suspended()) {
       THROW_MSG_0(vmSymbols::java_lang_IllegalThreadStateException(),
                   "this thread is not suspended");
     }
+    return csf.count();
   }
   // Implied else: if JavaThread is not alive simply return a count of 0.
-
-  return count;
+  return 0;
 JVM_END
 
 
--- a/src/hotspot/share/prims/whitebox.cpp	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/share/prims/whitebox.cpp	Thu May 23 11:07:37 2019 +0100
@@ -38,6 +38,7 @@
 #include "gc/shared/genArguments.hpp"
 #include "gc/shared/genCollectedHeap.hpp"
 #include "jvmtifiles/jvmtiEnv.hpp"
+#include "memory/filemap.hpp"
 #include "memory/heapShared.inline.hpp"
 #include "memory/metaspaceShared.hpp"
 #include "memory/metadataFactory.hpp"
@@ -1883,6 +1884,10 @@
   return UseSharedSpaces;
 WB_END
 
+WB_ENTRY(jboolean, WB_CDSMemoryMappingFailed(JNIEnv* env, jobject wb))
+  return FileMapInfo::memory_mapping_failed();
+WB_END
+
 WB_ENTRY(jboolean, WB_IsShared(JNIEnv* env, jobject wb, jobject obj))
   oop obj_oop = JNIHandles::resolve(obj);
   return HeapShared::is_archived_object(obj_oop);
@@ -1908,6 +1913,15 @@
   }
 WB_END
 
+WB_ENTRY(void, WB_LinkClass(JNIEnv* env, jobject wb, jclass clazz))
+  Klass *k = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(clazz));
+  if (!k->is_instance_klass()) {
+    return;
+  }
+  InstanceKlass *ik = InstanceKlass::cast(k);
+  ik->link_class(THREAD); // may throw verification error
+WB_END
+
 WB_ENTRY(jboolean, WB_AreOpenArchiveHeapObjectsMapped(JNIEnv* env))
   return HeapShared::open_archive_heap_region_mapped();
 WB_END
@@ -2342,10 +2356,12 @@
   {CC"isSharedClass",      CC"(Ljava/lang/Class;)Z",  (void*)&WB_IsSharedClass },
   {CC"areSharedStringsIgnored",           CC"()Z",    (void*)&WB_AreSharedStringsIgnored },
   {CC"getResolvedReferences", CC"(Ljava/lang/Class;)Ljava/lang/Object;", (void*)&WB_GetResolvedReferences},
+  {CC"linkClass",          CC"(Ljava/lang/Class;)V",  (void*)&WB_LinkClass},
   {CC"areOpenArchiveHeapObjectsMapped",   CC"()Z",    (void*)&WB_AreOpenArchiveHeapObjectsMapped},
   {CC"isCDSIncludedInVmBuild",            CC"()Z",    (void*)&WB_IsCDSIncludedInVmBuild },
   {CC"isJFRIncludedInVmBuild",            CC"()Z",    (void*)&WB_IsJFRIncludedInVmBuild },
-  {CC"isJavaHeapArchiveSupported",      CC"()Z",      (void*)&WB_IsJavaHeapArchiveSupported },
+  {CC"isJavaHeapArchiveSupported",        CC"()Z",    (void*)&WB_IsJavaHeapArchiveSupported },
+  {CC"cdsMemoryMappingFailed",            CC"()Z",    (void*)&WB_CDSMemoryMappingFailed },
 
   {CC"clearInlineCaches0",  CC"(Z)V",                 (void*)&WB_ClearInlineCaches },
   {CC"handshakeWalkStack", CC"(Ljava/lang/Thread;Z)I", (void*)&WB_HandshakeWalkStack },
--- a/src/hotspot/share/runtime/arguments.cpp	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/share/runtime/arguments.cpp	Thu May 23 11:07:37 2019 +0100
@@ -36,6 +36,7 @@
 #include "logging/logStream.hpp"
 #include "logging/logTag.hpp"
 #include "memory/allocation.inline.hpp"
+#include "memory/filemap.hpp"
 #include "oops/oop.inline.hpp"
 #include "prims/jvmtiExport.hpp"
 #include "runtime/arguments.hpp"
@@ -95,6 +96,7 @@
 bool   Arguments::_enable_preview               = false;
 
 char*  Arguments::SharedArchivePath             = NULL;
+char*  Arguments::SharedDynamicArchivePath      = NULL;
 
 AgentLibraryList Arguments::_libraryList;
 AgentLibraryList Arguments::_agentList;
@@ -1469,7 +1471,8 @@
                                       "--patch-module"
                                     };
 void Arguments::check_unsupported_dumping_properties() {
-  assert(DumpSharedSpaces, "this function is only used with -Xshare:dump");
+  assert(DumpSharedSpaces || DynamicDumpSharedSpaces,
+         "this function is only used with CDS dump time");
   assert(ARRAY_SIZE(unsupported_properties) == ARRAY_SIZE(unsupported_options), "must be");
   // If a vm option is found in the unsupported_options array, vm will exit with an error message.
   SystemProperty* sp = system_properties();
@@ -1492,6 +1495,13 @@
 bool Arguments::check_unsupported_cds_runtime_properties() {
   assert(UseSharedSpaces, "this function is only used with -Xshare:{on,auto}");
   assert(ARRAY_SIZE(unsupported_properties) == ARRAY_SIZE(unsupported_options), "must be");
+  if (ArchiveClassesAtExit != NULL) {
+    // dynamic dumping, just return false for now.
+    // check_unsupported_dumping_properties() will be called later to check the same set of
+    // properties, and will exit the VM with the correct error message if the unsupported properties
+    // are used.
+    return false;
+  }
   for (uint i = 0; i < ARRAY_SIZE(unsupported_properties); i++) {
     if (get_property(unsupported_properties[i]) != NULL) {
       if (RequireSharedSpaces) {
@@ -1624,7 +1634,7 @@
   if (max_heap_size <= max_heap_for_compressed_oops()) {
 #if !defined(COMPILER1) || defined(TIERED)
     if (FLAG_IS_DEFAULT(UseCompressedOops)) {
-      FLAG_SET_ERGO(bool, UseCompressedOops, true);
+      FLAG_SET_ERGO(UseCompressedOops, true);
     }
 #endif
   } else {
@@ -1653,7 +1663,7 @@
   } else {
     // Turn on UseCompressedClassPointers too
     if (FLAG_IS_DEFAULT(UseCompressedClassPointers)) {
-      FLAG_SET_ERGO(bool, UseCompressedClassPointers, true);
+      FLAG_SET_ERGO(UseCompressedClassPointers, true);
     }
     // Check the CompressedClassSpaceSize to make sure we use compressed klass ptrs.
     if (UseCompressedClassPointers) {
@@ -1761,7 +1771,7 @@
                                      DefaultHeapBaseMinAddress,
                                      DefaultHeapBaseMinAddress/G,
                                      HeapBaseMinAddress);
-          FLAG_SET_ERGO(size_t, HeapBaseMinAddress, DefaultHeapBaseMinAddress);
+          FLAG_SET_ERGO(HeapBaseMinAddress, DefaultHeapBaseMinAddress);
         }
       }
 
@@ -1783,7 +1793,7 @@
     }
 
     log_trace(gc, heap)("  Maximum heap size " SIZE_FORMAT, (size_t) reasonable_max);
-    FLAG_SET_ERGO(size_t, MaxHeapSize, (size_t)reasonable_max);
+    FLAG_SET_ERGO(MaxHeapSize, (size_t)reasonable_max);
   }
 
   // If the minimum or initial heap_size have not been set or requested to be set
@@ -1804,7 +1814,7 @@
       reasonable_initial = limit_by_allocatable_memory(reasonable_initial);
 
       log_trace(gc, heap)("  Initial heap size " SIZE_FORMAT, (size_t)reasonable_initial);
-      FLAG_SET_ERGO(size_t, InitialHeapSize, (size_t)reasonable_initial);
+      FLAG_SET_ERGO(InitialHeapSize, (size_t)reasonable_initial);
     }
     // If the minimum heap size has not been set (via -Xms),
     // synchronize with InitialHeapSize to avoid errors with the default value.
@@ -1845,10 +1855,10 @@
   initHeapSize = limit_by_allocatable_memory(initHeapSize);
 
   if (FLAG_IS_DEFAULT(MaxHeapSize)) {
-    if (FLAG_SET_CMDLINE(size_t, MaxHeapSize, initHeapSize) != JVMFlag::SUCCESS) {
+    if (FLAG_SET_CMDLINE(MaxHeapSize, initHeapSize) != JVMFlag::SUCCESS) {
       return JNI_EINVAL;
     }
-    if (FLAG_SET_CMDLINE(size_t, InitialHeapSize, initHeapSize) != JVMFlag::SUCCESS) {
+    if (FLAG_SET_CMDLINE(InitialHeapSize, initHeapSize) != JVMFlag::SUCCESS) {
       return JNI_EINVAL;
     }
     // Currently the minimum size and the initial heap sizes are the same.
@@ -1856,11 +1866,11 @@
   }
   if (FLAG_IS_DEFAULT(NewSize)) {
     // Make the young generation 3/8ths of the total heap.
-    if (FLAG_SET_CMDLINE(size_t, NewSize,
+    if (FLAG_SET_CMDLINE(NewSize,
             ((julong) MaxHeapSize / (julong) 8) * (julong) 3) != JVMFlag::SUCCESS) {
       return JNI_EINVAL;
     }
-    if (FLAG_SET_CMDLINE(size_t, MaxNewSize, NewSize) != JVMFlag::SUCCESS) {
+    if (FLAG_SET_CMDLINE(MaxNewSize, NewSize) != JVMFlag::SUCCESS) {
       return JNI_EINVAL;
     }
   }
@@ -1870,20 +1880,20 @@
 #endif
 
   // Increase some data structure sizes for efficiency
-  if (FLAG_SET_CMDLINE(size_t, BaseFootPrintEstimate, MaxHeapSize) != JVMFlag::SUCCESS) {
+  if (FLAG_SET_CMDLINE(BaseFootPrintEstimate, MaxHeapSize) != JVMFlag::SUCCESS) {
     return JNI_EINVAL;
   }
-  if (FLAG_SET_CMDLINE(bool, ResizeTLAB, false) != JVMFlag::SUCCESS) {
+  if (FLAG_SET_CMDLINE(ResizeTLAB, false) != JVMFlag::SUCCESS) {
     return JNI_EINVAL;
   }
-  if (FLAG_SET_CMDLINE(size_t, TLABSize, 256 * K) != JVMFlag::SUCCESS) {
+  if (FLAG_SET_CMDLINE(TLABSize, 256 * K) != JVMFlag::SUCCESS) {
     return JNI_EINVAL;
   }
 
   // See the OldPLABSize comment below, but replace 'after promotion'
   // with 'after copying'.  YoungPLABSize is the size of the survivor
   // space per-gc-thread buffers.  The default is 4kw.
-  if (FLAG_SET_CMDLINE(size_t, YoungPLABSize, 256 * K) != JVMFlag::SUCCESS) { // Note: this is in words
+  if (FLAG_SET_CMDLINE(YoungPLABSize, 256 * K) != JVMFlag::SUCCESS) { // Note: this is in words
     return JNI_EINVAL;
   }
 
@@ -1900,29 +1910,29 @@
   // locality.  A minor effect may be that larger PLABs reduce the
   // number of PLAB allocation events during gc.  The value of 8kw
   // was arrived at by experimenting with specjbb.
-  if (FLAG_SET_CMDLINE(size_t, OldPLABSize, 8 * K) != JVMFlag::SUCCESS) { // Note: this is in words
+  if (FLAG_SET_CMDLINE(OldPLABSize, 8 * K) != JVMFlag::SUCCESS) { // Note: this is in words
     return JNI_EINVAL;
   }
 
   // Enable parallel GC and adaptive generation sizing
-  if (FLAG_SET_CMDLINE(bool, UseParallelGC, true) != JVMFlag::SUCCESS) {
+  if (FLAG_SET_CMDLINE(UseParallelGC, true) != JVMFlag::SUCCESS) {
     return JNI_EINVAL;
   }
 
   // Encourage steady state memory management
-  if (FLAG_SET_CMDLINE(uintx, ThresholdTolerance, 100) != JVMFlag::SUCCESS) {
+  if (FLAG_SET_CMDLINE(ThresholdTolerance, 100) != JVMFlag::SUCCESS) {
     return JNI_EINVAL;
   }
 
   // This appears to improve mutator locality
-  if (FLAG_SET_CMDLINE(bool, ScavengeBeforeFullGC, false) != JVMFlag::SUCCESS) {
+  if (FLAG_SET_CMDLINE(ScavengeBeforeFullGC, false) != JVMFlag::SUCCESS) {
     return JNI_EINVAL;
   }
 
   // Get around early Solaris scheduling bug
   // (affinity vs other jobs on system)
   // but disallow DR and offlining (5008695).
-  if (FLAG_SET_CMDLINE(bool, BindGCTaskThreadsToCPUs, true) != JVMFlag::SUCCESS) {
+  if (FLAG_SET_CMDLINE(BindGCTaskThreadsToCPUs, true) != JVMFlag::SUCCESS) {
     return JNI_EINVAL;
   }
 
@@ -2043,7 +2053,7 @@
 
 #ifndef SUPPORT_RESERVED_STACK_AREA
   if (StackReservedPages != 0) {
-    FLAG_SET_CMDLINE(intx, StackReservedPages, 0);
+    FLAG_SET_CMDLINE(StackReservedPages, 0);
     warning("Reserved Stack Area not supported on this platform");
   }
 #endif
@@ -2362,7 +2372,7 @@
       } else if (!strcmp(tail, ":gc")) {
         LogConfiguration::configure_stdout(LogLevel::Info, true, LOG_TAGS(gc));
       } else if (!strcmp(tail, ":jni")) {
-        if (FLAG_SET_CMDLINE(bool, PrintJNIResolving, true) != JVMFlag::SUCCESS) {
+        if (FLAG_SET_CMDLINE(PrintJNIResolving, true) != JVMFlag::SUCCESS) {
           return JNI_EINVAL;
         }
       }
@@ -2505,24 +2515,24 @@
       set_enable_preview();
     // -Xnoclassgc
     } else if (match_option(option, "-Xnoclassgc")) {
-      if (FLAG_SET_CMDLINE(bool, ClassUnloading, false) != JVMFlag::SUCCESS) {
+      if (FLAG_SET_CMDLINE(ClassUnloading, false) != JVMFlag::SUCCESS) {
         return JNI_EINVAL;
       }
     // -Xconcgc
     } else if (match_option(option, "-Xconcgc")) {
-      if (FLAG_SET_CMDLINE(bool, UseConcMarkSweepGC, true) != JVMFlag::SUCCESS) {
+      if (FLAG_SET_CMDLINE(UseConcMarkSweepGC, true) != JVMFlag::SUCCESS) {
         return JNI_EINVAL;
       }
       handle_extra_cms_flags("-Xconcgc uses UseConcMarkSweepGC");
     // -Xnoconcgc
     } else if (match_option(option, "-Xnoconcgc")) {
-      if (FLAG_SET_CMDLINE(bool, UseConcMarkSweepGC, false) != JVMFlag::SUCCESS) {
+      if (FLAG_SET_CMDLINE(UseConcMarkSweepGC, false) != JVMFlag::SUCCESS) {
         return JNI_EINVAL;
       }
       handle_extra_cms_flags("-Xnoconcgc uses UseConcMarkSweepGC");
     // -Xbatch
     } else if (match_option(option, "-Xbatch")) {
-      if (FLAG_SET_CMDLINE(bool, BackgroundCompilation, false) != JVMFlag::SUCCESS) {
+      if (FLAG_SET_CMDLINE(BackgroundCompilation, false) != JVMFlag::SUCCESS) {
         return JNI_EINVAL;
       }
     // -Xmn for compatibility with other JVM vendors
@@ -2535,10 +2545,10 @@
         describe_range_error(errcode);
         return JNI_EINVAL;
       }
-      if (FLAG_SET_CMDLINE(size_t, MaxNewSize, (size_t)long_initial_young_size) != JVMFlag::SUCCESS) {
+      if (FLAG_SET_CMDLINE(MaxNewSize, (size_t)long_initial_young_size) != JVMFlag::SUCCESS) {
         return JNI_EINVAL;
       }
-      if (FLAG_SET_CMDLINE(size_t, NewSize, (size_t)long_initial_young_size) != JVMFlag::SUCCESS) {
+      if (FLAG_SET_CMDLINE(NewSize, (size_t)long_initial_young_size) != JVMFlag::SUCCESS) {
         return JNI_EINVAL;
       }
     // -Xms
@@ -2555,7 +2565,7 @@
       MinHeapSize = (size_t)long_initial_heap_size;
       // Currently the minimum size and the initial heap sizes are the same.
       // Can be overridden with -XX:InitialHeapSize.
-      if (FLAG_SET_CMDLINE(size_t, InitialHeapSize, (size_t)long_initial_heap_size) != JVMFlag::SUCCESS) {
+      if (FLAG_SET_CMDLINE(InitialHeapSize, (size_t)long_initial_heap_size) != JVMFlag::SUCCESS) {
         return JNI_EINVAL;
       }
     // -Xmx
@@ -2568,7 +2578,7 @@
         describe_range_error(errcode);
         return JNI_EINVAL;
       }
-      if (FLAG_SET_CMDLINE(size_t, MaxHeapSize, (size_t)long_max_heap_size) != JVMFlag::SUCCESS) {
+      if (FLAG_SET_CMDLINE(MaxHeapSize, (size_t)long_max_heap_size) != JVMFlag::SUCCESS) {
         return JNI_EINVAL;
       }
     // Xmaxf
@@ -2581,7 +2591,7 @@
                     option->optionString);
         return JNI_EINVAL;
       } else {
-        if (FLAG_SET_CMDLINE(uintx, MaxHeapFreeRatio, maxf) != JVMFlag::SUCCESS) {
+        if (FLAG_SET_CMDLINE(MaxHeapFreeRatio, maxf) != JVMFlag::SUCCESS) {
             return JNI_EINVAL;
         }
       }
@@ -2595,7 +2605,7 @@
                     option->optionString);
         return JNI_EINVAL;
       } else {
-        if (FLAG_SET_CMDLINE(uintx, MinHeapFreeRatio, minf) != JVMFlag::SUCCESS) {
+        if (FLAG_SET_CMDLINE(MinHeapFreeRatio, minf) != JVMFlag::SUCCESS) {
           return JNI_EINVAL;
         }
       }
@@ -2606,7 +2616,7 @@
       if (err != JNI_OK) {
         return err;
       }
-      if (FLAG_SET_CMDLINE(intx, ThreadStackSize, value) != JVMFlag::SUCCESS) {
+      if (FLAG_SET_CMDLINE(ThreadStackSize, value) != JVMFlag::SUCCESS) {
         return JNI_EINVAL;
       }
     } else if (match_option(option, "-Xmaxjitcodesize", &tail) ||
@@ -2619,7 +2629,7 @@
                     "Invalid maximum code cache size: %s.\n", option->optionString);
         return JNI_EINVAL;
       }
-      if (FLAG_SET_CMDLINE(uintx, ReservedCodeCacheSize, (uintx)long_ReservedCodeCacheSize) != JVMFlag::SUCCESS) {
+      if (FLAG_SET_CMDLINE(ReservedCodeCacheSize, (uintx)long_ReservedCodeCacheSize) != JVMFlag::SUCCESS) {
         return JNI_EINVAL;
       }
     // -green
@@ -2633,7 +2643,7 @@
     // -Xrs
     } else if (match_option(option, "-Xrs")) {
           // Classic/EVM option, new functionality
-      if (FLAG_SET_CMDLINE(bool, ReduceSignalUsage, true) != JVMFlag::SUCCESS) {
+      if (FLAG_SET_CMDLINE(ReduceSignalUsage, true) != JVMFlag::SUCCESS) {
         return JNI_EINVAL;
       }
       // -Xprof
@@ -2685,7 +2695,7 @@
       // Out of the box management support
       if (match_option(option, "-Dcom.sun.management", &tail)) {
 #if INCLUDE_MANAGEMENT
-        if (FLAG_SET_CMDLINE(bool, ManagementServer, true) != JVMFlag::SUCCESS) {
+        if (FLAG_SET_CMDLINE(ManagementServer, true) != JVMFlag::SUCCESS) {
           return JNI_EINVAL;
         }
         // management agent in module jdk.management.agent
@@ -2710,55 +2720,54 @@
           set_mode_flags(_comp);
     // -Xshare:dump
     } else if (match_option(option, "-Xshare:dump")) {
-      if (FLAG_SET_CMDLINE(bool, DumpSharedSpaces, true) != JVMFlag::SUCCESS) {
+      if (FLAG_SET_CMDLINE(DumpSharedSpaces, true) != JVMFlag::SUCCESS) {
         return JNI_EINVAL;
       }
-      set_mode_flags(_int);     // Prevent compilation, which creates objects
     // -Xshare:on
     } else if (match_option(option, "-Xshare:on")) {
-      if (FLAG_SET_CMDLINE(bool, UseSharedSpaces, true) != JVMFlag::SUCCESS) {
+      if (FLAG_SET_CMDLINE(UseSharedSpaces, true) != JVMFlag::SUCCESS) {
         return JNI_EINVAL;
       }
-      if (FLAG_SET_CMDLINE(bool, RequireSharedSpaces, true) != JVMFlag::SUCCESS) {
+      if (FLAG_SET_CMDLINE(RequireSharedSpaces, true) != JVMFlag::SUCCESS) {
         return JNI_EINVAL;
       }
-    // -Xshare:auto
+    // -Xshare:auto || -XX:ArchiveClassesAtExit=<archive file>
     } else if (match_option(option, "-Xshare:auto")) {
-      if (FLAG_SET_CMDLINE(bool, UseSharedSpaces, true) != JVMFlag::SUCCESS) {
+      if (FLAG_SET_CMDLINE(UseSharedSpaces, true) != JVMFlag::SUCCESS) {
         return JNI_EINVAL;
       }
-      if (FLAG_SET_CMDLINE(bool, RequireSharedSpaces, false) != JVMFlag::SUCCESS) {
+      if (FLAG_SET_CMDLINE(RequireSharedSpaces, false) != JVMFlag::SUCCESS) {
         return JNI_EINVAL;
       }
     // -Xshare:off
     } else if (match_option(option, "-Xshare:off")) {
-      if (FLAG_SET_CMDLINE(bool, UseSharedSpaces, false) != JVMFlag::SUCCESS) {
+      if (FLAG_SET_CMDLINE(UseSharedSpaces, false) != JVMFlag::SUCCESS) {
         return JNI_EINVAL;
       }
-      if (FLAG_SET_CMDLINE(bool, RequireSharedSpaces, false) != JVMFlag::SUCCESS) {
+      if (FLAG_SET_CMDLINE(RequireSharedSpaces, false) != JVMFlag::SUCCESS) {
         return JNI_EINVAL;
       }
     // -Xverify
     } else if (match_option(option, "-Xverify", &tail)) {
       if (strcmp(tail, ":all") == 0 || strcmp(tail, "") == 0) {
-        if (FLAG_SET_CMDLINE(bool, BytecodeVerificationLocal, true) != JVMFlag::SUCCESS) {
+        if (FLAG_SET_CMDLINE(BytecodeVerificationLocal, true) != JVMFlag::SUCCESS) {
           return JNI_EINVAL;
         }
-        if (FLAG_SET_CMDLINE(bool, BytecodeVerificationRemote, true) != JVMFlag::SUCCESS) {
+        if (FLAG_SET_CMDLINE(BytecodeVerificationRemote, true) != JVMFlag::SUCCESS) {
           return JNI_EINVAL;
         }
       } else if (strcmp(tail, ":remote") == 0) {
-        if (FLAG_SET_CMDLINE(bool, BytecodeVerificationLocal, false) != JVMFlag::SUCCESS) {
+        if (FLAG_SET_CMDLINE(BytecodeVerificationLocal, false) != JVMFlag::SUCCESS) {
           return JNI_EINVAL;
         }
-        if (FLAG_SET_CMDLINE(bool, BytecodeVerificationRemote, true) != JVMFlag::SUCCESS) {
+        if (FLAG_SET_CMDLINE(BytecodeVerificationRemote, true) != JVMFlag::SUCCESS) {
           return JNI_EINVAL;
         }
       } else if (strcmp(tail, ":none") == 0) {
-        if (FLAG_SET_CMDLINE(bool, BytecodeVerificationLocal, false) != JVMFlag::SUCCESS) {
+        if (FLAG_SET_CMDLINE(BytecodeVerificationLocal, false) != JVMFlag::SUCCESS) {
           return JNI_EINVAL;
         }
-        if (FLAG_SET_CMDLINE(bool, BytecodeVerificationRemote, false) != JVMFlag::SUCCESS) {
+        if (FLAG_SET_CMDLINE(BytecodeVerificationRemote, false) != JVMFlag::SUCCESS) {
           return JNI_EINVAL;
         }
         warning("Options -Xverify:none and -noverify were deprecated in JDK 13 and will likely be removed in a future release.");
@@ -2818,23 +2827,23 @@
     // Need to keep consistency of MaxTenuringThreshold and AlwaysTenure/NeverTenure;
     // and the last option wins.
     } else if (match_option(option, "-XX:+NeverTenure")) {
-      if (FLAG_SET_CMDLINE(bool, NeverTenure, true) != JVMFlag::SUCCESS) {
+      if (FLAG_SET_CMDLINE(NeverTenure, true) != JVMFlag::SUCCESS) {
         return JNI_EINVAL;
       }
-      if (FLAG_SET_CMDLINE(bool, AlwaysTenure, false) != JVMFlag::SUCCESS) {
+      if (FLAG_SET_CMDLINE(AlwaysTenure, false) != JVMFlag::SUCCESS) {
         return JNI_EINVAL;
       }
-      if (FLAG_SET_CMDLINE(uintx, MaxTenuringThreshold, markOopDesc::max_age + 1) != JVMFlag::SUCCESS) {
+      if (FLAG_SET_CMDLINE(MaxTenuringThreshold, markOopDesc::max_age + 1) != JVMFlag::SUCCESS) {
         return JNI_EINVAL;
       }
     } else if (match_option(option, "-XX:+AlwaysTenure")) {
-      if (FLAG_SET_CMDLINE(bool, NeverTenure, false) != JVMFlag::SUCCESS) {
+      if (FLAG_SET_CMDLINE(NeverTenure, false) != JVMFlag::SUCCESS) {
         return JNI_EINVAL;
       }
-      if (FLAG_SET_CMDLINE(bool, AlwaysTenure, true) != JVMFlag::SUCCESS) {
+      if (FLAG_SET_CMDLINE(AlwaysTenure, true) != JVMFlag::SUCCESS) {
         return JNI_EINVAL;
       }
-      if (FLAG_SET_CMDLINE(uintx, MaxTenuringThreshold, 0) != JVMFlag::SUCCESS) {
+      if (FLAG_SET_CMDLINE(MaxTenuringThreshold, 0) != JVMFlag::SUCCESS) {
         return JNI_EINVAL;
       }
     } else if (match_option(option, "-XX:MaxTenuringThreshold=", &tail)) {
@@ -2845,65 +2854,65 @@
         return JNI_EINVAL;
       }
 
-      if (FLAG_SET_CMDLINE(uintx, MaxTenuringThreshold, max_tenuring_thresh) != JVMFlag::SUCCESS) {
+      if (FLAG_SET_CMDLINE(MaxTenuringThreshold, max_tenuring_thresh) != JVMFlag::SUCCESS) {
         return JNI_EINVAL;
       }
 
       if (MaxTenuringThreshold == 0) {
-        if (FLAG_SET_CMDLINE(bool, NeverTenure, false) != JVMFlag::SUCCESS) {
+        if (FLAG_SET_CMDLINE(NeverTenure, false) != JVMFlag::SUCCESS) {
           return JNI_EINVAL;
         }
-        if (FLAG_SET_CMDLINE(bool, AlwaysTenure, true) != JVMFlag::SUCCESS) {
+        if (FLAG_SET_CMDLINE(AlwaysTenure, true) != JVMFlag::SUCCESS) {
           return JNI_EINVAL;
         }
       } else {
-        if (FLAG_SET_CMDLINE(bool, NeverTenure, false) != JVMFlag::SUCCESS) {
+        if (FLAG_SET_CMDLINE(NeverTenure, false) != JVMFlag::SUCCESS) {
           return JNI_EINVAL;
         }
-        if (FLAG_SET_CMDLINE(bool, AlwaysTenure, false) != JVMFlag::SUCCESS) {
+        if (FLAG_SET_CMDLINE(AlwaysTenure, false) != JVMFlag::SUCCESS) {
           return JNI_EINVAL;
         }
       }
     } else if (match_option(option, "-XX:+DisplayVMOutputToStderr")) {
-      if (FLAG_SET_CMDLINE(bool, DisplayVMOutputToStdout, false) != JVMFlag::SUCCESS) {
+      if (FLAG_SET_CMDLINE(DisplayVMOutputToStdout, false) != JVMFlag::SUCCESS) {
         return JNI_EINVAL;
       }
-      if (FLAG_SET_CMDLINE(bool, DisplayVMOutputToStderr, true) != JVMFlag::SUCCESS) {
+      if (FLAG_SET_CMDLINE(DisplayVMOutputToStderr, true) != JVMFlag::SUCCESS) {
         return JNI_EINVAL;
       }
     } else if (match_option(option, "-XX:+DisplayVMOutputToStdout")) {
-      if (FLAG_SET_CMDLINE(bool, DisplayVMOutputToStderr, false) != JVMFlag::SUCCESS) {
+      if (FLAG_SET_CMDLINE(DisplayVMOutputToStderr, false) != JVMFlag::SUCCESS) {
         return JNI_EINVAL;
       }
-      if (FLAG_SET_CMDLINE(bool, DisplayVMOutputToStdout, true) != JVMFlag::SUCCESS) {
+      if (FLAG_SET_CMDLINE(DisplayVMOutputToStdout, true) != JVMFlag::SUCCESS) {
         return JNI_EINVAL;
       }
     } else if (match_option(option, "-XX:+ErrorFileToStderr")) {
-      if (FLAG_SET_CMDLINE(bool, ErrorFileToStdout, false) != JVMFlag::SUCCESS) {
+      if (FLAG_SET_CMDLINE(ErrorFileToStdout, false) != JVMFlag::SUCCESS) {
         return JNI_EINVAL;
       }
-      if (FLAG_SET_CMDLINE(bool, ErrorFileToStderr, true) != JVMFlag::SUCCESS) {
+      if (FLAG_SET_CMDLINE(ErrorFileToStderr, true) != JVMFlag::SUCCESS) {
         return JNI_EINVAL;
       }
     } else if (match_option(option, "-XX:+ErrorFileToStdout")) {
-      if (FLAG_SET_CMDLINE(bool, ErrorFileToStderr, false) != JVMFlag::SUCCESS) {
+      if (FLAG_SET_CMDLINE(ErrorFileToStderr, false) != JVMFlag::SUCCESS) {
         return JNI_EINVAL;
       }
-      if (FLAG_SET_CMDLINE(bool, ErrorFileToStdout, true) != JVMFlag::SUCCESS) {
+      if (FLAG_SET_CMDLINE(ErrorFileToStdout, true) != JVMFlag::SUCCESS) {
         return JNI_EINVAL;
       }
     } else if (match_option(option, "-XX:+ExtendedDTraceProbes")) {
 #if defined(DTRACE_ENABLED)
-      if (FLAG_SET_CMDLINE(bool, ExtendedDTraceProbes, true) != JVMFlag::SUCCESS) {
+      if (FLAG_SET_CMDLINE(ExtendedDTraceProbes, true) != JVMFlag::SUCCESS) {
         return JNI_EINVAL;
       }
-      if (FLAG_SET_CMDLINE(bool, DTraceMethodProbes, true) != JVMFlag::SUCCESS) {
+      if (FLAG_SET_CMDLINE(DTraceMethodProbes, true) != JVMFlag::SUCCESS) {
         return JNI_EINVAL;
       }
-      if (FLAG_SET_CMDLINE(bool, DTraceAllocProbes, true) != JVMFlag::SUCCESS) {
+      if (FLAG_SET_CMDLINE(DTraceAllocProbes, true) != JVMFlag::SUCCESS) {
         return JNI_EINVAL;
       }
-      if (FLAG_SET_CMDLINE(bool, DTraceMonitorProbes, true) != JVMFlag::SUCCESS) {
+      if (FLAG_SET_CMDLINE(DTraceMonitorProbes, true) != JVMFlag::SUCCESS) {
         return JNI_EINVAL;
       }
 #else // defined(DTRACE_ENABLED)
@@ -2913,11 +2922,11 @@
 #endif // defined(DTRACE_ENABLED)
 #ifdef ASSERT
     } else if (match_option(option, "-XX:+FullGCALot")) {
-      if (FLAG_SET_CMDLINE(bool, FullGCALot, true) != JVMFlag::SUCCESS) {
+      if (FLAG_SET_CMDLINE(FullGCALot, true) != JVMFlag::SUCCESS) {
         return JNI_EINVAL;
       }
       // disable scavenge before parallel mark-compact
-      if (FLAG_SET_CMDLINE(bool, ScavengeBeforeFullGC, false) != JVMFlag::SUCCESS) {
+      if (FLAG_SET_CMDLINE(ScavengeBeforeFullGC, false) != JVMFlag::SUCCESS) {
         return JNI_EINVAL;
       }
 #endif
@@ -2950,10 +2959,10 @@
   //   -Xshare:on
   //   -Xlog:class+path=info
   if (PrintSharedArchiveAndExit) {
-    if (FLAG_SET_CMDLINE(bool, UseSharedSpaces, true) != JVMFlag::SUCCESS) {
+    if (FLAG_SET_CMDLINE(UseSharedSpaces, true) != JVMFlag::SUCCESS) {
       return JNI_EINVAL;
     }
-    if (FLAG_SET_CMDLINE(bool, RequireSharedSpaces, true) != JVMFlag::SUCCESS) {
+    if (FLAG_SET_CMDLINE(RequireSharedSpaces, true) != JVMFlag::SUCCESS) {
       return JNI_EINVAL;
     }
     LogConfiguration::configure_stdout(LogLevel::Info, true, LOG_TAGS(class, path));
@@ -3078,7 +3087,7 @@
 
   // eventually fix up InitialTenuringThreshold if only MaxTenuringThreshold is set
   if (FLAG_IS_DEFAULT(InitialTenuringThreshold) && (InitialTenuringThreshold > MaxTenuringThreshold)) {
-    FLAG_SET_ERGO(uintx, InitialTenuringThreshold, MaxTenuringThreshold);
+    FLAG_SET_ERGO(InitialTenuringThreshold, MaxTenuringThreshold);
   }
 
 #if !COMPILER2_OR_JVMCI
@@ -3110,15 +3119,24 @@
     // the archived Klasses and Java string objects (at dump time only).
     UseBiasedLocking = false;
 
+    // Compiler threads may concurrently update the class metadata (such as method entries), so it's
+    // unsafe with DumpSharedSpaces (which modifies the class metadata in place). Let's disable
+    // compiler just to be safe.
+    //
+    // Note: this is not a concern for DynamicDumpSharedSpaces, which makes a copy of the class metadata
+    // instead of modifying them in place. The copy is inaccessible to the compiler.
+    // TODO: revisit the following for the static archive case.
+    set_mode_flags(_int);
+  }
+  if (DumpSharedSpaces || ArchiveClassesAtExit != NULL) {
     // Always verify non-system classes during CDS dump
     if (!BytecodeVerificationRemote) {
       BytecodeVerificationRemote = true;
       log_info(cds)("All non-system classes will be verified (-Xverify:remote) during CDS dump time.");
     }
-
-    // Compilation is already disabled if the user specifies -Xshare:dump.
-    // Disable compilation in case user specifies -XX:+DumpSharedSpaces instead of -Xshare:dump.
-    set_mode_flags(_int);
+  }
+  if (ArchiveClassesAtExit == NULL) {
+    FLAG_SET_DEFAULT(DynamicDumpSharedSpaces, false);
   }
   if (UseSharedSpaces && patch_mod_javabase) {
     no_shared_spaces("CDS is disabled when " JAVA_BASE_NAME " module is patched.");
@@ -3427,6 +3445,7 @@
   }
 }
 
+#if INCLUDE_CDS
 // Sharing support
 // Construct the path to the archive
 char* Arguments::get_default_shared_archive_path() {
@@ -3446,15 +3465,104 @@
   return default_archive_path;
 }
 
-static char* get_shared_archive_path() {
-  char *shared_archive_path;
+int Arguments::num_archives(const char* archive_path) {
+  if (archive_path == NULL) {
+    return 0;
+  }
+  int npaths = 1;
+  char* p = (char*)archive_path;
+  while (*p != '\0') {
+    if (*p == os::path_separator()[0]) {
+      npaths++;
+    }
+    p++;
+  }
+  return npaths;
+}
+
+void Arguments::extract_shared_archive_paths(const char* archive_path,
+                                         char** base_archive_path,
+                                         char** top_archive_path) {
+  char* begin_ptr = (char*)archive_path;
+  char* end_ptr = strchr((char*)archive_path, os::path_separator()[0]);
+  if (end_ptr == NULL || end_ptr == begin_ptr) {
+    vm_exit_during_initialization("Base archive was not specified", archive_path);
+  }
+  size_t len = end_ptr - begin_ptr;
+  char* cur_path = NEW_C_HEAP_ARRAY(char, len + 1, mtInternal);
+  strncpy(cur_path, begin_ptr, len);
+  cur_path[len] = '\0';
+  FileMapInfo::check_archive((const char*)cur_path, true /*is_static*/);
+  *base_archive_path = cur_path;
+
+  begin_ptr = ++end_ptr;
+  if (*begin_ptr == '\0') {
+    vm_exit_during_initialization("Top archive was not specified", archive_path);
+  }
+  end_ptr = strchr(begin_ptr, '\0');
+  assert(end_ptr != NULL, "sanity");
+  len = end_ptr - begin_ptr;
+  cur_path = NEW_C_HEAP_ARRAY(char, len + 1, mtInternal);
+  strncpy(cur_path, begin_ptr, len + 1);
+  //cur_path[len] = '\0';
+  FileMapInfo::check_archive((const char*)cur_path, false /*is_static*/);
+  *top_archive_path = cur_path;
+}
+
+bool Arguments::init_shared_archive_paths() {
+  if (ArchiveClassesAtExit != NULL) {
+    if (DumpSharedSpaces) {
+      vm_exit_during_initialization("-XX:ArchiveClassesAtExit cannot be used with -Xshare:dump");
+    }
+    if (FLAG_SET_CMDLINE(DynamicDumpSharedSpaces, true) != JVMFlag::SUCCESS) {
+      return false;
+    }
+    check_unsupported_dumping_properties();
+    SharedDynamicArchivePath = os::strdup_check_oom(ArchiveClassesAtExit, mtArguments);
+  }
   if (SharedArchiveFile == NULL) {
-    shared_archive_path = Arguments::get_default_shared_archive_path();
+    SharedArchivePath = get_default_shared_archive_path();
   } else {
-    shared_archive_path = os::strdup_check_oom(SharedArchiveFile, mtArguments);
+    int archives = num_archives(SharedArchiveFile);
+    if (DynamicDumpSharedSpaces || DumpSharedSpaces) {
+      if (archives > 1) {
+        vm_exit_during_initialization(
+          "Cannot have more than 1 archive file specified in -XX:SharedArchiveFile during CDS dumping");
+      }
+      if (DynamicDumpSharedSpaces) {
+        if (FileMapInfo::same_files(SharedArchiveFile, ArchiveClassesAtExit)) {
+          vm_exit_during_initialization(
+            "Cannot have the same archive file specified for -XX:SharedArchiveFile and -XX:ArchiveClassesAtExit",
+            SharedArchiveFile);
+        }
+      }
+    }
+    if (!DynamicDumpSharedSpaces && !DumpSharedSpaces){
+      if (archives > 2) {
+        vm_exit_during_initialization(
+          "Cannot have more than 2 archive files specified in the -XX:SharedArchiveFile option");
+      }
+      if (archives == 1) {
+        char* temp_archive_path = os::strdup_check_oom(SharedArchiveFile, mtArguments);
+        int name_size;
+        bool success =
+          FileMapInfo::get_base_archive_name_from_header(temp_archive_path, &name_size, &SharedArchivePath);
+        if (!success) {
+          SharedArchivePath = temp_archive_path;
+        } else {
+          SharedDynamicArchivePath = temp_archive_path;
+        }
+      } else {
+        extract_shared_archive_paths((const char*)SharedArchiveFile,
+                                      &SharedArchivePath, &SharedDynamicArchivePath);
+      }
+    } else { // CDS dumping
+      SharedArchivePath = os::strdup_check_oom(SharedArchiveFile, mtArguments);
+    }
   }
-  return shared_archive_path;
+  return (SharedArchivePath != NULL);
 }
+#endif // INCLUDE_CDS
 
 #ifndef PRODUCT
 // Determine whether LogVMOutput should be implicitly turned on.
@@ -3786,11 +3894,12 @@
     return result;
   }
 
-  // Call get_shared_archive_path() here, after possible SharedArchiveFile option got parsed.
-  SharedArchivePath = get_shared_archive_path();
-  if (SharedArchivePath == NULL) {
+#if INCLUDE_CDS
+  // Initialize shared archive paths which could include both base and dynamic archive paths
+  if (!init_shared_archive_paths()) {
     return JNI_ENOMEM;
   }
+#endif
 
   // Delay warning until here so that we've had a chance to process
   // the -XX:-PrintWarnings flag
@@ -3958,7 +4067,7 @@
 #if defined(IA32)
   // Only server compiler can optimize safepoints well enough.
   if (!is_server_compilation_mode_vm()) {
-    FLAG_SET_ERGO_IF_DEFAULT(bool, ThreadLocalHandshakes, false);
+    FLAG_SET_ERGO_IF_DEFAULT(ThreadLocalHandshakes, false);
   }
 #endif
 
@@ -3975,7 +4084,7 @@
 jint Arguments::adjust_after_os() {
   if (UseNUMA) {
     if (!FLAG_IS_DEFAULT(AllocateHeapAt)) {
-      FLAG_SET_ERGO(bool, UseNUMA, false);
+      FLAG_SET_ERGO(UseNUMA, false);
     } else if (UseParallelGC || UseParallelOldGC) {
       if (FLAG_IS_DEFAULT(MinHeapDeltaBytes)) {
          FLAG_SET_DEFAULT(MinHeapDeltaBytes, 64*M);
@@ -3990,7 +4099,7 @@
     // all platforms and ParallelGC on Windows will interleave all
     // of the heap spaces across NUMA nodes.
     if (FLAG_IS_DEFAULT(UseNUMAInterleaving)) {
-      FLAG_SET_ERGO(bool, UseNUMAInterleaving, true);
+      FLAG_SET_ERGO(UseNUMAInterleaving, true);
     }
   }
   return JNI_OK;
--- a/src/hotspot/share/runtime/arguments.hpp	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/share/runtime/arguments.hpp	Thu May 23 11:07:37 2019 +0100
@@ -484,6 +484,11 @@
   static AliasedLoggingFlag catch_logging_aliases(const char* name, bool on);
 
   static char*  SharedArchivePath;
+  static char*  SharedDynamicArchivePath;
+  static int num_archives(const char* archive_path) NOT_CDS_RETURN_(0);
+  static void extract_shared_archive_paths(const char* archive_path,
+                                         char** base_archive_path,
+                                         char** top_archive_path) NOT_CDS_RETURN;
 
  public:
   // Parses the arguments, first phase
@@ -563,6 +568,7 @@
   static vfprintf_hook_t vfprintf_hook()    { return _vfprintf_hook; }
 
   static const char* GetSharedArchivePath() { return SharedArchivePath; }
+  static const char* GetSharedDynamicArchivePath() { return SharedDynamicArchivePath; }
 
   // Java launcher properties
   static void process_sun_java_launcher_properties(JavaVMInitArgs* args);
@@ -625,7 +631,8 @@
   static char* get_appclasspath() { return _java_class_path->value(); }
   static void  fix_appclasspath();
 
-  static char* get_default_shared_archive_path();
+  static char* get_default_shared_archive_path() NOT_CDS_RETURN_(NULL);
+  static bool  init_shared_archive_paths() NOT_CDS_RETURN_(false);
 
   // Operation modi
   static Mode mode()                        { return _mode; }
--- a/src/hotspot/share/runtime/compilationPolicy.cpp	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/share/runtime/compilationPolicy.cpp	Thu May 23 11:07:37 2019 +0100
@@ -232,7 +232,7 @@
       // Lower the compiler count such that all buffers fit into the code cache
       _compiler_count = MAX2(max_count, 1);
     }
-    FLAG_SET_ERGO(intx, CICompilerCount, _compiler_count);
+    FLAG_SET_ERGO(CICompilerCount, _compiler_count);
   } else {
     _compiler_count = CICompilerCount;
   }
--- a/src/hotspot/share/runtime/flags/jvmFlag.cpp	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/share/runtime/flags/jvmFlag.cpp	Thu May 23 11:07:37 2019 +0100
@@ -957,24 +957,24 @@
 }
 
 // Returns the address of the index'th element
-static JVMFlag* address_of_flag(JVMFlagsWithType flag) {
+static JVMFlag* address_of_flag(JVMFlagsEnum flag) {
   assert((size_t)flag < JVMFlag::numFlags, "bad command line flag index");
   return &JVMFlag::flags[flag];
 }
 
-bool JVMFlagEx::is_default(JVMFlags flag) {
+bool JVMFlagEx::is_default(JVMFlagsEnum flag) {
   assert((size_t)flag < JVMFlag::numFlags, "bad command line flag index");
   JVMFlag* f = &JVMFlag::flags[flag];
   return f->is_default();
 }
 
-bool JVMFlagEx::is_ergo(JVMFlags flag) {
+bool JVMFlagEx::is_ergo(JVMFlagsEnum flag) {
   assert((size_t)flag < JVMFlag::numFlags, "bad command line flag index");
   JVMFlag* f = &JVMFlag::flags[flag];
   return f->is_ergonomic();
 }
 
-bool JVMFlagEx::is_cmdline(JVMFlags flag) {
+bool JVMFlagEx::is_cmdline(JVMFlagsEnum flag) {
   assert((size_t)flag < JVMFlag::numFlags, "bad command line flag index");
   JVMFlag* f = &JVMFlag::flags[flag];
   return f->is_command_line();
@@ -987,7 +987,7 @@
   return true;
 }
 
-void JVMFlagEx::setOnCmdLine(JVMFlagsWithType flag) {
+void JVMFlagEx::setOnCmdLine(JVMFlagsEnum flag) {
   JVMFlag* faddr = address_of_flag(flag);
   assert(faddr != NULL, "Unknown flag");
   faddr->set_command_line();
@@ -1040,7 +1040,7 @@
   return boolAtPut(result, value, origin);
 }
 
-JVMFlag::Error JVMFlagEx::boolAtPut(JVMFlagsWithType flag, bool value, JVMFlag::Flags origin) {
+JVMFlag::Error JVMFlagEx::boolAtPut(JVMFlagsEnum flag, bool value, JVMFlag::Flags origin) {
   JVMFlag* faddr = address_of_flag(flag);
   guarantee(faddr != NULL && faddr->is_bool(), "wrong flag type");
   return JVMFlag::boolAtPut(faddr, &value, origin);
@@ -1089,7 +1089,7 @@
   return intAtPut(result, value, origin);
 }
 
-JVMFlag::Error JVMFlagEx::intAtPut(JVMFlagsWithType flag, int value, JVMFlag::Flags origin) {
+JVMFlag::Error JVMFlagEx::intAtPut(JVMFlagsEnum flag, int value, JVMFlag::Flags origin) {
   JVMFlag* faddr = address_of_flag(flag);
   guarantee(faddr != NULL && faddr->is_int(), "wrong flag type");
   return JVMFlag::intAtPut(faddr, &value, origin);
@@ -1138,7 +1138,7 @@
   return uintAtPut(result, value, origin);
 }
 
-JVMFlag::Error JVMFlagEx::uintAtPut(JVMFlagsWithType flag, uint value, JVMFlag::Flags origin) {
+JVMFlag::Error JVMFlagEx::uintAtPut(JVMFlagsEnum flag, uint value, JVMFlag::Flags origin) {
   JVMFlag* faddr = address_of_flag(flag);
   guarantee(faddr != NULL && faddr->is_uint(), "wrong flag type");
   return JVMFlag::uintAtPut(faddr, &value, origin);
@@ -1187,7 +1187,7 @@
   return intxAtPut(result, value, origin);
 }
 
-JVMFlag::Error JVMFlagEx::intxAtPut(JVMFlagsWithType flag, intx value, JVMFlag::Flags origin) {
+JVMFlag::Error JVMFlagEx::intxAtPut(JVMFlagsEnum flag, intx value, JVMFlag::Flags origin) {
   JVMFlag* faddr = address_of_flag(flag);
   guarantee(faddr != NULL && faddr->is_intx(), "wrong flag type");
   return JVMFlag::intxAtPut(faddr, &value, origin);
@@ -1236,7 +1236,7 @@
   return uintxAtPut(result, value, origin);
 }
 
-JVMFlag::Error JVMFlagEx::uintxAtPut(JVMFlagsWithType flag, uintx value, JVMFlag::Flags origin) {
+JVMFlag::Error JVMFlagEx::uintxAtPut(JVMFlagsEnum flag, uintx value, JVMFlag::Flags origin) {
   JVMFlag* faddr = address_of_flag(flag);
   guarantee(faddr != NULL && faddr->is_uintx(), "wrong flag type");
   return JVMFlag::uintxAtPut(faddr, &value, origin);
@@ -1285,7 +1285,7 @@
   return uint64_tAtPut(result, value, origin);
 }
 
-JVMFlag::Error JVMFlagEx::uint64_tAtPut(JVMFlagsWithType flag, uint64_t value, JVMFlag::Flags origin) {
+JVMFlag::Error JVMFlagEx::uint64_tAtPut(JVMFlagsEnum flag, uint64_t value, JVMFlag::Flags origin) {
   JVMFlag* faddr = address_of_flag(flag);
   guarantee(faddr != NULL && faddr->is_uint64_t(), "wrong flag type");
   return JVMFlag::uint64_tAtPut(faddr, &value, origin);
@@ -1335,7 +1335,7 @@
   return size_tAtPut(result, value, origin);
 }
 
-JVMFlag::Error JVMFlagEx::size_tAtPut(JVMFlagsWithType flag, size_t value, JVMFlag::Flags origin) {
+JVMFlag::Error JVMFlagEx::size_tAtPut(JVMFlagsEnum flag, size_t value, JVMFlag::Flags origin) {
   JVMFlag* faddr = address_of_flag(flag);
   guarantee(faddr != NULL && faddr->is_size_t(), "wrong flag type");
   return JVMFlag::size_tAtPut(faddr, &value, origin);
@@ -1384,7 +1384,7 @@
   return doubleAtPut(result, value, origin);
 }
 
-JVMFlag::Error JVMFlagEx::doubleAtPut(JVMFlagsWithType flag, double value, JVMFlag::Flags origin) {
+JVMFlag::Error JVMFlagEx::doubleAtPut(JVMFlagsEnum flag, double value, JVMFlag::Flags origin) {
   JVMFlag* faddr = address_of_flag(flag);
   guarantee(faddr != NULL && faddr->is_double(), "wrong flag type");
   return JVMFlag::doubleAtPut(faddr, &value, origin);
@@ -1418,7 +1418,7 @@
   return check;
 }
 
-JVMFlag::Error JVMFlagEx::ccstrAtPut(JVMFlagsWithType flag, ccstr value, JVMFlag::Flags origin) {
+JVMFlag::Error JVMFlagEx::ccstrAtPut(JVMFlagsEnum flag, ccstr value, JVMFlag::Flags origin) {
   JVMFlag* faddr = address_of_flag(flag);
   guarantee(faddr != NULL && faddr->is_ccstr(), "wrong flag type");
   ccstr old_value = faddr->get_ccstr();
@@ -1511,4 +1511,3 @@
     va_end(listPointer);
   }
 }
-
--- a/src/hotspot/share/runtime/flags/jvmFlagConstraintList.cpp	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/share/runtime/flags/jvmFlagConstraintList.cpp	Thu May 23 11:07:37 2019 +0100
@@ -31,14 +31,9 @@
 #include "runtime/flags/jvmFlagConstraintList.hpp"
 #include "runtime/flags/jvmFlagConstraintsCompiler.hpp"
 #include "runtime/flags/jvmFlagConstraintsRuntime.hpp"
+#include "runtime/globals.hpp"
 #include "runtime/os.hpp"
 #include "utilities/macros.hpp"
-#ifdef COMPILER1
-#include "c1/c1_globals.hpp"
-#endif
-#ifdef COMPILER2
-#include "opto/c2_globals.hpp"
-#endif
 
 class JVMFlagConstraint_bool : public JVMFlagConstraint {
   JVMFlagConstraintFunc_bool _constraint;
@@ -241,27 +236,31 @@
 }
 
 // Generate code to call emit_constraint_xxx function
-#define EMIT_CONSTRAINT_PRODUCT_FLAG(type, name, value, doc)      ); emit_constraint_##type(#name,&name
-#define EMIT_CONSTRAINT_DIAGNOSTIC_FLAG(type, name, value, doc)   ); emit_constraint_##type(#name,&name
-#define EMIT_CONSTRAINT_EXPERIMENTAL_FLAG(type, name, value, doc) ); emit_constraint_##type(#name,&name
-#define EMIT_CONSTRAINT_MANAGEABLE_FLAG(type, name, value, doc)   ); emit_constraint_##type(#name,&name
-#define EMIT_CONSTRAINT_PRODUCT_RW_FLAG(type, name, value, doc)   ); emit_constraint_##type(#name,&name
-#define EMIT_CONSTRAINT_PD_PRODUCT_FLAG(type, name, doc)          ); emit_constraint_##type(#name,&name
-#define EMIT_CONSTRAINT_PD_DIAGNOSTIC_FLAG(type, name, doc)       ); emit_constraint_##type(#name,&name
+#define EMIT_CONSTRAINT_START       (void)(0
+#define EMIT_CONSTRAINT(type, name) ); emit_constraint_##type(#name, &name
+#define EMIT_CONSTRAINT_NO          ); emit_constraint_no(0
+#define EMIT_CONSTRAINT_PRODUCT_FLAG(type, name, value, doc)      EMIT_CONSTRAINT(type, name)
+#define EMIT_CONSTRAINT_DIAGNOSTIC_FLAG(type, name, value, doc)   EMIT_CONSTRAINT(type, name)
+#define EMIT_CONSTRAINT_EXPERIMENTAL_FLAG(type, name, value, doc) EMIT_CONSTRAINT(type, name)
+#define EMIT_CONSTRAINT_MANAGEABLE_FLAG(type, name, value, doc)   EMIT_CONSTRAINT(type, name)
+#define EMIT_CONSTRAINT_PRODUCT_RW_FLAG(type, name, value, doc)   EMIT_CONSTRAINT(type, name)
+#define EMIT_CONSTRAINT_PD_PRODUCT_FLAG(type, name, doc)          EMIT_CONSTRAINT(type, name)
+#define EMIT_CONSTRAINT_PD_DIAGNOSTIC_FLAG(type, name, doc)       EMIT_CONSTRAINT(type, name)
 #ifndef PRODUCT
-#define EMIT_CONSTRAINT_DEVELOPER_FLAG(type, name, value, doc)    ); emit_constraint_##type(#name,&name
-#define EMIT_CONSTRAINT_PD_DEVELOPER_FLAG(type, name, doc)        ); emit_constraint_##type(#name,&name
-#define EMIT_CONSTRAINT_NOTPRODUCT_FLAG(type, name, value, doc)   ); emit_constraint_##type(#name,&name
+#define EMIT_CONSTRAINT_DEVELOPER_FLAG(type, name, value, doc)    EMIT_CONSTRAINT(type, name)
+#define EMIT_CONSTRAINT_PD_DEVELOPER_FLAG(type, name, doc)        EMIT_CONSTRAINT(type, name)
+#define EMIT_CONSTRAINT_NOTPRODUCT_FLAG(type, name, value, doc)   EMIT_CONSTRAINT(type, name)
 #else
-#define EMIT_CONSTRAINT_DEVELOPER_FLAG(type, name, value, doc)    ); emit_constraint_no(#name,&name
-#define EMIT_CONSTRAINT_PD_DEVELOPER_FLAG(type, name, doc)        ); emit_constraint_no(#name,&name
-#define EMIT_CONSTRAINT_NOTPRODUCT_FLAG(type, name, value, doc)   ); emit_constraint_no(#name,&name
+#define EMIT_CONSTRAINT_DEVELOPER_FLAG(type, name, value, doc)    EMIT_CONSTRAINT_NO
+#define EMIT_CONSTRAINT_PD_DEVELOPER_FLAG(type, name, doc)        EMIT_CONSTRAINT_NO
+#define EMIT_CONSTRAINT_NOTPRODUCT_FLAG(type, name, value, doc)   EMIT_CONSTRAINT_NO
 #endif
 #ifdef _LP64
-#define EMIT_CONSTRAINT_LP64_PRODUCT_FLAG(type, name, value, doc) ); emit_constraint_##type(#name,&name
+#define EMIT_CONSTRAINT_LP64_PRODUCT_FLAG(type, name, value, doc) EMIT_CONSTRAINT(type, name)
 #else
-#define EMIT_CONSTRAINT_LP64_PRODUCT_FLAG(type, name, value, doc) ); emit_constraint_no(#name,&name
+#define EMIT_CONSTRAINT_LP64_PRODUCT_FLAG(type, name, value, doc) EMIT_CONSTRAINT_NO
 #endif
+#define EMIT_CONSTRAINT_END         );
 
 // Generate func argument to pass into emit_constraint_xxx functions
 #define EMIT_CONSTRAINT_CHECK(func, type)                         , func, JVMFlagConstraint::type
@@ -275,59 +274,26 @@
 void JVMFlagConstraintList::init(void) {
   _constraints = new (ResourceObj::C_HEAP, mtArguments) GrowableArray<JVMFlagConstraint*>(INITIAL_CONSTRAINTS_SIZE, true);
 
-  emit_constraint_no(NULL VM_FLAGS(EMIT_CONSTRAINT_DEVELOPER_FLAG,
-                                   EMIT_CONSTRAINT_PD_DEVELOPER_FLAG,
-                                   EMIT_CONSTRAINT_PRODUCT_FLAG,
-                                   EMIT_CONSTRAINT_PD_PRODUCT_FLAG,
-                                   EMIT_CONSTRAINT_DIAGNOSTIC_FLAG,
-                                   EMIT_CONSTRAINT_PD_DIAGNOSTIC_FLAG,
-                                   EMIT_CONSTRAINT_EXPERIMENTAL_FLAG,
-                                   EMIT_CONSTRAINT_NOTPRODUCT_FLAG,
-                                   EMIT_CONSTRAINT_MANAGEABLE_FLAG,
-                                   EMIT_CONSTRAINT_PRODUCT_RW_FLAG,
-                                   EMIT_CONSTRAINT_LP64_PRODUCT_FLAG,
-                                   IGNORE_RANGE,
-                                   EMIT_CONSTRAINT_CHECK,
-                                   IGNORE_WRITEABLE));
+  EMIT_CONSTRAINT_START
+
+  ALL_FLAGS(EMIT_CONSTRAINT_DEVELOPER_FLAG,
+            EMIT_CONSTRAINT_PD_DEVELOPER_FLAG,
+            EMIT_CONSTRAINT_PRODUCT_FLAG,
+            EMIT_CONSTRAINT_PD_PRODUCT_FLAG,
+            EMIT_CONSTRAINT_DIAGNOSTIC_FLAG,
+            EMIT_CONSTRAINT_PD_DIAGNOSTIC_FLAG,
+            EMIT_CONSTRAINT_EXPERIMENTAL_FLAG,
+            EMIT_CONSTRAINT_NOTPRODUCT_FLAG,
+            EMIT_CONSTRAINT_MANAGEABLE_FLAG,
+            EMIT_CONSTRAINT_PRODUCT_RW_FLAG,
+            EMIT_CONSTRAINT_LP64_PRODUCT_FLAG,
+            IGNORE_RANGE,
+            EMIT_CONSTRAINT_CHECK,
+            IGNORE_WRITEABLE)
 
   EMIT_CONSTRAINTS_FOR_GLOBALS_EXT
 
-  emit_constraint_no(NULL ARCH_FLAGS(EMIT_CONSTRAINT_DEVELOPER_FLAG,
-                                     EMIT_CONSTRAINT_PRODUCT_FLAG,
-                                     EMIT_CONSTRAINT_DIAGNOSTIC_FLAG,
-                                     EMIT_CONSTRAINT_EXPERIMENTAL_FLAG,
-                                     EMIT_CONSTRAINT_NOTPRODUCT_FLAG,
-                                     IGNORE_RANGE,
-                                     EMIT_CONSTRAINT_CHECK,
-                                     IGNORE_WRITEABLE));
-
-
-#ifdef COMPILER1
-  emit_constraint_no(NULL C1_FLAGS(EMIT_CONSTRAINT_DEVELOPER_FLAG,
-                                   EMIT_CONSTRAINT_PD_DEVELOPER_FLAG,
-                                   EMIT_CONSTRAINT_PRODUCT_FLAG,
-                                   EMIT_CONSTRAINT_PD_PRODUCT_FLAG,
-                                   EMIT_CONSTRAINT_DIAGNOSTIC_FLAG,
-                                   EMIT_CONSTRAINT_PD_DIAGNOSTIC_FLAG,
-                                   EMIT_CONSTRAINT_NOTPRODUCT_FLAG,
-                                   IGNORE_RANGE,
-                                   EMIT_CONSTRAINT_CHECK,
-                                   IGNORE_WRITEABLE));
-#endif // COMPILER1
-
-#ifdef COMPILER2
-  emit_constraint_no(NULL C2_FLAGS(EMIT_CONSTRAINT_DEVELOPER_FLAG,
-                                   EMIT_CONSTRAINT_PD_DEVELOPER_FLAG,
-                                   EMIT_CONSTRAINT_PRODUCT_FLAG,
-                                   EMIT_CONSTRAINT_PD_PRODUCT_FLAG,
-                                   EMIT_CONSTRAINT_DIAGNOSTIC_FLAG,
-                                   EMIT_CONSTRAINT_PD_DIAGNOSTIC_FLAG,
-                                   EMIT_CONSTRAINT_EXPERIMENTAL_FLAG,
-                                   EMIT_CONSTRAINT_NOTPRODUCT_FLAG,
-                                   IGNORE_RANGE,
-                                   EMIT_CONSTRAINT_CHECK,
-                                   IGNORE_WRITEABLE));
-#endif // COMPILER2
+  EMIT_CONSTRAINT_END
 }
 
 JVMFlagConstraint* JVMFlagConstraintList::find(const char* name) {
--- a/src/hotspot/share/runtime/flags/jvmFlagRangeList.cpp	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/share/runtime/flags/jvmFlagRangeList.cpp	Thu May 23 11:07:37 2019 +0100
@@ -32,7 +32,7 @@
 #include "runtime/flags/jvmFlag.hpp"
 #include "runtime/flags/jvmFlagConstraintList.hpp"
 #include "runtime/flags/jvmFlagRangeList.hpp"
-#include "runtime/globals_extension.hpp"
+#include "runtime/globals.hpp"
 #include "runtime/os.hpp"
 #include "runtime/task.hpp"
 #include "utilities/macros.hpp"
@@ -292,27 +292,31 @@
 }
 
 // Generate code to call emit_range_xxx function
-#define EMIT_RANGE_PRODUCT_FLAG(type, name, value, doc)      ); emit_range_##type(#name,&name
-#define EMIT_RANGE_DIAGNOSTIC_FLAG(type, name, value, doc)   ); emit_range_##type(#name,&name
-#define EMIT_RANGE_EXPERIMENTAL_FLAG(type, name, value, doc) ); emit_range_##type(#name,&name
-#define EMIT_RANGE_MANAGEABLE_FLAG(type, name, value, doc)   ); emit_range_##type(#name,&name
-#define EMIT_RANGE_PRODUCT_RW_FLAG(type, name, value, doc)   ); emit_range_##type(#name,&name
-#define EMIT_RANGE_PD_PRODUCT_FLAG(type, name, doc)          ); emit_range_##type(#name,&name
-#define EMIT_RANGE_PD_DIAGNOSTIC_FLAG(type, name, doc)       ); emit_range_##type(#name,&name
+#define EMIT_RANGE_START       (void)(0
+#define EMIT_RANGE(type, name) ); emit_range_##type(#name, &name
+#define EMIT_RANGE_NO          ); emit_range_no(0
+#define EMIT_RANGE_PRODUCT_FLAG(type, name, value, doc)      EMIT_RANGE(type, name)
+#define EMIT_RANGE_DIAGNOSTIC_FLAG(type, name, value, doc)   EMIT_RANGE(type, name)
+#define EMIT_RANGE_EXPERIMENTAL_FLAG(type, name, value, doc) EMIT_RANGE(type, name)
+#define EMIT_RANGE_MANAGEABLE_FLAG(type, name, value, doc)   EMIT_RANGE(type, name)
+#define EMIT_RANGE_PRODUCT_RW_FLAG(type, name, value, doc)   EMIT_RANGE(type, name)
+#define EMIT_RANGE_PD_PRODUCT_FLAG(type, name, doc)          EMIT_RANGE(type, name)
+#define EMIT_RANGE_PD_DIAGNOSTIC_FLAG(type, name, doc)       EMIT_RANGE(type, name)
 #ifndef PRODUCT
-#define EMIT_RANGE_DEVELOPER_FLAG(type, name, value, doc)    ); emit_range_##type(#name,&name
-#define EMIT_RANGE_PD_DEVELOPER_FLAG(type, name, doc)        ); emit_range_##type(#name,&name
-#define EMIT_RANGE_NOTPRODUCT_FLAG(type, name, value, doc)   ); emit_range_##type(#name,&name
+#define EMIT_RANGE_DEVELOPER_FLAG(type, name, value, doc)    EMIT_RANGE(type, name)
+#define EMIT_RANGE_PD_DEVELOPER_FLAG(type, name, doc)        EMIT_RANGE(type, name)
+#define EMIT_RANGE_NOTPRODUCT_FLAG(type, name, value, doc)   EMIT_RANGE(type, name)
 #else
-#define EMIT_RANGE_DEVELOPER_FLAG(type, name, value, doc)    ); emit_range_no(#name,&name
-#define EMIT_RANGE_PD_DEVELOPER_FLAG(type, name, doc)        ); emit_range_no(#name,&name
-#define EMIT_RANGE_NOTPRODUCT_FLAG(type, name, value, doc)   ); emit_range_no(#name,&name
+#define EMIT_RANGE_DEVELOPER_FLAG(type, name, value, doc)    EMIT_RANGE_NO
+#define EMIT_RANGE_PD_DEVELOPER_FLAG(type, name, doc)        EMIT_RANGE_NO
+#define EMIT_RANGE_NOTPRODUCT_FLAG(type, name, value, doc)   EMIT_RANGE_NO
 #endif
 #ifdef _LP64
-#define EMIT_RANGE_LP64_PRODUCT_FLAG(type, name, value, doc) ); emit_range_##type(#name,&name
+#define EMIT_RANGE_LP64_PRODUCT_FLAG(type, name, value, doc) EMIT_RANGE(type, name)
 #else
-#define EMIT_RANGE_LP64_PRODUCT_FLAG(type, name, value, doc) ); emit_range_no(#name,&name
+#define EMIT_RANGE_LP64_PRODUCT_FLAG(type, name, value, doc) EMIT_RANGE_NO
 #endif
+#define EMIT_RANGE_END         );
 
 // Generate func argument to pass into emit_range_xxx functions
 #define EMIT_RANGE_CHECK(a, b)                               , a, b
@@ -325,72 +329,26 @@
 
   _ranges = new (ResourceObj::C_HEAP, mtArguments) GrowableArray<JVMFlagRange*>(INITIAL_RANGES_SIZE, true);
 
-  emit_range_no(NULL VM_FLAGS(EMIT_RANGE_DEVELOPER_FLAG,
-                              EMIT_RANGE_PD_DEVELOPER_FLAG,
-                              EMIT_RANGE_PRODUCT_FLAG,
-                              EMIT_RANGE_PD_PRODUCT_FLAG,
-                              EMIT_RANGE_DIAGNOSTIC_FLAG,
-                              EMIT_RANGE_PD_DIAGNOSTIC_FLAG,
-                              EMIT_RANGE_EXPERIMENTAL_FLAG,
-                              EMIT_RANGE_NOTPRODUCT_FLAG,
-                              EMIT_RANGE_MANAGEABLE_FLAG,
-                              EMIT_RANGE_PRODUCT_RW_FLAG,
-                              EMIT_RANGE_LP64_PRODUCT_FLAG,
-                              EMIT_RANGE_CHECK,
-                              IGNORE_CONSTRAINT,
-                              IGNORE_WRITEABLE));
+  EMIT_RANGE_START
+
+  ALL_FLAGS(EMIT_RANGE_DEVELOPER_FLAG,
+            EMIT_RANGE_PD_DEVELOPER_FLAG,
+            EMIT_RANGE_PRODUCT_FLAG,
+            EMIT_RANGE_PD_PRODUCT_FLAG,
+            EMIT_RANGE_DIAGNOSTIC_FLAG,
+            EMIT_RANGE_PD_DIAGNOSTIC_FLAG,
+            EMIT_RANGE_EXPERIMENTAL_FLAG,
+            EMIT_RANGE_NOTPRODUCT_FLAG,
+            EMIT_RANGE_MANAGEABLE_FLAG,
+            EMIT_RANGE_PRODUCT_RW_FLAG,
+            EMIT_RANGE_LP64_PRODUCT_FLAG,
+            EMIT_RANGE_CHECK,
+            IGNORE_CONSTRAINT,
+            IGNORE_WRITEABLE)
 
   EMIT_RANGES_FOR_GLOBALS_EXT
 
-  emit_range_no(NULL ARCH_FLAGS(EMIT_RANGE_DEVELOPER_FLAG,
-                                EMIT_RANGE_PRODUCT_FLAG,
-                                EMIT_RANGE_DIAGNOSTIC_FLAG,
-                                EMIT_RANGE_EXPERIMENTAL_FLAG,
-                                EMIT_RANGE_NOTPRODUCT_FLAG,
-                                EMIT_RANGE_CHECK,
-                                IGNORE_CONSTRAINT,
-                                IGNORE_WRITEABLE));
-
-#if INCLUDE_JVMCI
-  emit_range_no(NULL JVMCI_FLAGS(EMIT_RANGE_DEVELOPER_FLAG,
-                                 EMIT_RANGE_PD_DEVELOPER_FLAG,
-                                 EMIT_RANGE_PRODUCT_FLAG,
-                                 EMIT_RANGE_PD_PRODUCT_FLAG,
-                                 EMIT_RANGE_DIAGNOSTIC_FLAG,
-                                 EMIT_RANGE_PD_DIAGNOSTIC_FLAG,
-                                 EMIT_RANGE_EXPERIMENTAL_FLAG,
-                                 EMIT_RANGE_NOTPRODUCT_FLAG,
-                                 EMIT_RANGE_CHECK,
-                                 IGNORE_CONSTRAINT,
-                                 IGNORE_WRITEABLE));
-#endif // INCLUDE_JVMCI
-
-#ifdef COMPILER1
-  emit_range_no(NULL C1_FLAGS(EMIT_RANGE_DEVELOPER_FLAG,
-                              EMIT_RANGE_PD_DEVELOPER_FLAG,
-                              EMIT_RANGE_PRODUCT_FLAG,
-                              EMIT_RANGE_PD_PRODUCT_FLAG,
-                              EMIT_RANGE_DIAGNOSTIC_FLAG,
-                              EMIT_RANGE_PD_DIAGNOSTIC_FLAG,
-                              EMIT_RANGE_NOTPRODUCT_FLAG,
-                              EMIT_RANGE_CHECK,
-                              IGNORE_CONSTRAINT,
-                              IGNORE_WRITEABLE));
-#endif // COMPILER1
-
-#ifdef COMPILER2
-  emit_range_no(NULL C2_FLAGS(EMIT_RANGE_DEVELOPER_FLAG,
-                              EMIT_RANGE_PD_DEVELOPER_FLAG,
-                              EMIT_RANGE_PRODUCT_FLAG,
-                              EMIT_RANGE_PD_PRODUCT_FLAG,
-                              EMIT_RANGE_DIAGNOSTIC_FLAG,
-                              EMIT_RANGE_PD_DIAGNOSTIC_FLAG,
-                              EMIT_RANGE_EXPERIMENTAL_FLAG,
-                              EMIT_RANGE_NOTPRODUCT_FLAG,
-                              EMIT_RANGE_CHECK,
-                              IGNORE_CONSTRAINT,
-                              IGNORE_WRITEABLE));
-#endif // COMPILER2
+  EMIT_RANGE_END
 }
 
 JVMFlagRange* JVMFlagRangeList::find(const char* name) {
--- a/src/hotspot/share/runtime/flags/jvmFlagWriteableList.cpp	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/share/runtime/flags/jvmFlagWriteableList.cpp	Thu May 23 11:07:37 2019 +0100
@@ -25,15 +25,6 @@
 #include "precompiled.hpp"
 #include "runtime/flags/jvmFlagWriteableList.hpp"
 #include "runtime/os.hpp"
-#ifdef COMPILER1
-#include "c1/c1_globals.hpp"
-#endif // COMPILER1
-#ifdef COMPILER2
-#include "opto/c2_globals.hpp"
-#endif // COMPILER2
-#if INCLUDE_JVMCI
-#include "jvmci/jvmci_globals.hpp"
-#endif
 
 bool JVMFlagWriteable::is_writeable(void) {
   return _writeable;
@@ -93,20 +84,23 @@
 }
 
 // Generate code to call emit_writeable_xxx function
-#define EMIT_WRITEABLE_PRODUCT_FLAG(type, name, value, doc)      ); emit_writeable_##type(#name
-#define EMIT_WRITEABLE_DIAGNOSTIC_FLAG(type, name, value, doc)   ); emit_writeable_##type(#name
-#define EMIT_WRITEABLE_EXPERIMENTAL_FLAG(type, name, value, doc) ); emit_writeable_##type(#name
-#define EMIT_WRITEABLE_MANAGEABLE_FLAG(type, name, value, doc)   ); emit_writeable_##type(#name
-#define EMIT_WRITEABLE_PRODUCT_RW_FLAG(type, name, value, doc)   ); emit_writeable_##type(#name
-#define EMIT_WRITEABLE_PD_PRODUCT_FLAG(type, name, doc)          ); emit_writeable_##type(#name
-#define EMIT_WRITEABLE_DEVELOPER_FLAG(type, name, value, doc)    ); emit_writeable_##type(#name
-#define EMIT_WRITEABLE_PD_DEVELOPER_FLAG(type, name, doc)        ); emit_writeable_##type(#name
-#define EMIT_WRITEABLE_PD_DIAGNOSTIC_FLAG(type, name, doc)       ); emit_writeable_##type(#name
-#define EMIT_WRITEABLE_NOTPRODUCT_FLAG(type, name, value, doc)   ); emit_writeable_##type(#name
-#define EMIT_WRITEABLE_LP64_PRODUCT_FLAG(type, name, value, doc) ); emit_writeable_##type(#name
+#define EMIT_WRITEABLE_START       (void)(0
+#define EMIT_WRITEABLE(type, name) ); emit_writeable_##type(#name
+#define EMIT_WRITEABLE_PRODUCT_FLAG(type, name, value, doc)      EMIT_WRITEABLE(type, name)
+#define EMIT_WRITEABLE_DIAGNOSTIC_FLAG(type, name, value, doc)   EMIT_WRITEABLE(type, name)
+#define EMIT_WRITEABLE_EXPERIMENTAL_FLAG(type, name, value, doc) EMIT_WRITEABLE(type, name)
+#define EMIT_WRITEABLE_MANAGEABLE_FLAG(type, name, value, doc)   EMIT_WRITEABLE(type, name)
+#define EMIT_WRITEABLE_PRODUCT_RW_FLAG(type, name, value, doc)   EMIT_WRITEABLE(type, name)
+#define EMIT_WRITEABLE_PD_PRODUCT_FLAG(type, name, doc)          EMIT_WRITEABLE(type, name)
+#define EMIT_WRITEABLE_DEVELOPER_FLAG(type, name, value, doc)    EMIT_WRITEABLE(type, name)
+#define EMIT_WRITEABLE_PD_DEVELOPER_FLAG(type, name, doc)        EMIT_WRITEABLE(type, name)
+#define EMIT_WRITEABLE_PD_DIAGNOSTIC_FLAG(type, name, doc)       EMIT_WRITEABLE(type, name)
+#define EMIT_WRITEABLE_NOTPRODUCT_FLAG(type, name, value, doc)   EMIT_WRITEABLE(type, name)
+#define EMIT_WRITEABLE_LP64_PRODUCT_FLAG(type, name, value, doc) EMIT_WRITEABLE(type, name)
+#define EMIT_WRITEABLE_END         );
 
 // Generate type argument to pass into emit_writeable_xxx functions
-#define EMIT_WRITEABLE(a)                                      , JVMFlagWriteable::a
+#define EMIT_WRITEABLE_CHECK(a)                                  , JVMFlagWriteable::a
 
 #define INITIAL_WRITEABLES_SIZE 2
 GrowableArray<JVMFlagWriteable*>* JVMFlagWriteableList::_controls = NULL;
@@ -115,72 +109,26 @@
 
   _controls = new (ResourceObj::C_HEAP, mtArguments) GrowableArray<JVMFlagWriteable*>(INITIAL_WRITEABLES_SIZE, true);
 
-  emit_writeable_no(NULL VM_FLAGS(EMIT_WRITEABLE_DEVELOPER_FLAG,
-                                  EMIT_WRITEABLE_PD_DEVELOPER_FLAG,
-                                  EMIT_WRITEABLE_PRODUCT_FLAG,
-                                  EMIT_WRITEABLE_PD_PRODUCT_FLAG,
-                                  EMIT_WRITEABLE_DIAGNOSTIC_FLAG,
-                                  EMIT_WRITEABLE_PD_DIAGNOSTIC_FLAG,
-                                  EMIT_WRITEABLE_EXPERIMENTAL_FLAG,
-                                  EMIT_WRITEABLE_NOTPRODUCT_FLAG,
-                                  EMIT_WRITEABLE_MANAGEABLE_FLAG,
-                                  EMIT_WRITEABLE_PRODUCT_RW_FLAG,
-                                  EMIT_WRITEABLE_LP64_PRODUCT_FLAG,
-                                  IGNORE_RANGE,
-                                  IGNORE_CONSTRAINT,
-                                  EMIT_WRITEABLE));
+  EMIT_WRITEABLE_START
+
+  ALL_FLAGS(EMIT_WRITEABLE_DEVELOPER_FLAG,
+            EMIT_WRITEABLE_PD_DEVELOPER_FLAG,
+            EMIT_WRITEABLE_PRODUCT_FLAG,
+            EMIT_WRITEABLE_PD_PRODUCT_FLAG,
+            EMIT_WRITEABLE_DIAGNOSTIC_FLAG,
+            EMIT_WRITEABLE_PD_DIAGNOSTIC_FLAG,
+            EMIT_WRITEABLE_EXPERIMENTAL_FLAG,
+            EMIT_WRITEABLE_NOTPRODUCT_FLAG,
+            EMIT_WRITEABLE_MANAGEABLE_FLAG,
+            EMIT_WRITEABLE_PRODUCT_RW_FLAG,
+            EMIT_WRITEABLE_LP64_PRODUCT_FLAG,
+            IGNORE_RANGE,
+            IGNORE_CONSTRAINT,
+            EMIT_WRITEABLE_CHECK)
 
   EMIT_WRITEABLES_FOR_GLOBALS_EXT
 
-  emit_writeable_no(NULL ARCH_FLAGS(EMIT_WRITEABLE_DEVELOPER_FLAG,
-                                EMIT_WRITEABLE_PRODUCT_FLAG,
-                                EMIT_WRITEABLE_DIAGNOSTIC_FLAG,
-                                EMIT_WRITEABLE_EXPERIMENTAL_FLAG,
-                                EMIT_WRITEABLE_NOTPRODUCT_FLAG,
-                                IGNORE_RANGE,
-                                IGNORE_CONSTRAINT,
-                                EMIT_WRITEABLE));
-
-#if INCLUDE_JVMCI
-  emit_writeable_no(NULL JVMCI_FLAGS(EMIT_WRITEABLE_DEVELOPER_FLAG,
-                                 EMIT_WRITEABLE_PD_DEVELOPER_FLAG,
-                                 EMIT_WRITEABLE_PRODUCT_FLAG,
-                                 EMIT_WRITEABLE_PD_PRODUCT_FLAG,
-                                 EMIT_WRITEABLE_DIAGNOSTIC_FLAG,
-                                 EMIT_WRITEABLE_PD_DIAGNOSTIC_FLAG,
-                                 EMIT_WRITEABLE_EXPERIMENTAL_FLAG,
-                                 EMIT_WRITEABLE_NOTPRODUCT_FLAG,
-                                 IGNORE_RANGE,
-                                 IGNORE_CONSTRAINT,
-                                 EMIT_WRITEABLE));
-#endif // INCLUDE_JVMCI
-
-#ifdef COMPILER1
-  emit_writeable_no(NULL C1_FLAGS(EMIT_WRITEABLE_DEVELOPER_FLAG,
-                              EMIT_WRITEABLE_PD_DEVELOPER_FLAG,
-                              EMIT_WRITEABLE_PRODUCT_FLAG,
-                              EMIT_WRITEABLE_PD_PRODUCT_FLAG,
-                              EMIT_WRITEABLE_DIAGNOSTIC_FLAG,
-                              EMIT_WRITEABLE_PD_DIAGNOSTIC_FLAG,
-                              EMIT_WRITEABLE_NOTPRODUCT_FLAG,
-                              IGNORE_RANGE,
-                              IGNORE_CONSTRAINT,
-                              EMIT_WRITEABLE));
-#endif // COMPILER1
-
-#ifdef COMPILER2
-  emit_writeable_no(NULL C2_FLAGS(EMIT_WRITEABLE_DEVELOPER_FLAG,
-                              EMIT_WRITEABLE_PD_DEVELOPER_FLAG,
-                              EMIT_WRITEABLE_PRODUCT_FLAG,
-                              EMIT_WRITEABLE_PD_PRODUCT_FLAG,
-                              EMIT_WRITEABLE_DIAGNOSTIC_FLAG,
-                              EMIT_WRITEABLE_PD_DIAGNOSTIC_FLAG,
-                              EMIT_WRITEABLE_EXPERIMENTAL_FLAG,
-                              EMIT_WRITEABLE_NOTPRODUCT_FLAG,
-                              IGNORE_RANGE,
-                              IGNORE_CONSTRAINT,
-                              EMIT_WRITEABLE));
-#endif // COMPILER2
+  EMIT_WRITEABLE_END
 }
 
 JVMFlagWriteable* JVMFlagWriteableList::find(const char* name) {
--- a/src/hotspot/share/runtime/globals.cpp	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/share/runtime/globals.cpp	Thu May 23 11:07:37 2019 +0100
@@ -30,6 +30,7 @@
 #include "runtime/arguments.hpp"
 #include "runtime/globals.hpp"
 #include "runtime/globals_extension.hpp"
+#include "runtime/globals_shared.hpp"
 #include "runtime/flags/jvmFlagConstraintList.hpp"
 #include "runtime/flags/jvmFlagWriteableList.hpp"
 #include "runtime/os.hpp"
@@ -38,49 +39,44 @@
 #include "utilities/macros.hpp"
 #include "utilities/ostream.hpp"
 #include "utilities/stringUtils.hpp"
-#ifdef COMPILER1
-#include "c1/c1_globals.hpp"
-#endif
-#if INCLUDE_JVMCI
-#include "jvmci/jvmci_globals.hpp"
-#endif
-#ifdef COMPILER2
-#include "opto/c2_globals.hpp"
-#endif
 
-VM_FLAGS(MATERIALIZE_DEVELOPER_FLAG, \
-         MATERIALIZE_PD_DEVELOPER_FLAG, \
-         MATERIALIZE_PRODUCT_FLAG, \
-         MATERIALIZE_PD_PRODUCT_FLAG, \
-         MATERIALIZE_DIAGNOSTIC_FLAG, \
-         MATERIALIZE_PD_DIAGNOSTIC_FLAG, \
-         MATERIALIZE_EXPERIMENTAL_FLAG, \
-         MATERIALIZE_NOTPRODUCT_FLAG, \
-         MATERIALIZE_MANAGEABLE_FLAG, \
-         MATERIALIZE_PRODUCT_RW_FLAG, \
-         MATERIALIZE_LP64_PRODUCT_FLAG, \
-         IGNORE_RANGE, \
-         IGNORE_CONSTRAINT, \
-         IGNORE_WRITEABLE)
+// Implementation macros
+#define MATERIALIZE_PRODUCT_FLAG(type, name, value, doc)      type name = value;
+#define MATERIALIZE_PD_PRODUCT_FLAG(type, name, doc)          type name = pd_##name;
+#define MATERIALIZE_DIAGNOSTIC_FLAG(type, name, value, doc)   type name = value;
+#define MATERIALIZE_PD_DIAGNOSTIC_FLAG(type, name, doc)       type name = pd_##name;
+#define MATERIALIZE_EXPERIMENTAL_FLAG(type, name, value, doc) type name = value;
+#define MATERIALIZE_MANAGEABLE_FLAG(type, name, value, doc)   type name = value;
+#define MATERIALIZE_PRODUCT_RW_FLAG(type, name, value, doc)   type name = value;
+#ifdef PRODUCT
+#define MATERIALIZE_DEVELOPER_FLAG(type, name, value, doc)
+#define MATERIALIZE_PD_DEVELOPER_FLAG(type, name, doc)
+#define MATERIALIZE_NOTPRODUCT_FLAG(type, name, value, doc)
+#else
+#define MATERIALIZE_DEVELOPER_FLAG(type, name, value, doc)    type name = value;
+#define MATERIALIZE_PD_DEVELOPER_FLAG(type, name, doc)        type name = pd_##name;
+#define MATERIALIZE_NOTPRODUCT_FLAG(type, name, value, doc)   type name = value;
+#endif // PRODUCT
+#ifdef _LP64
+#define MATERIALIZE_LP64_PRODUCT_FLAG(type, name, value, doc) type name = value;
+#else
+#define MATERIALIZE_LP64_PRODUCT_FLAG(type, name, value, doc) /* flag is constant */
+#endif // _LP64
 
-RUNTIME_OS_FLAGS(MATERIALIZE_DEVELOPER_FLAG, \
-                 MATERIALIZE_PD_DEVELOPER_FLAG, \
-                 MATERIALIZE_PRODUCT_FLAG, \
-                 MATERIALIZE_PD_PRODUCT_FLAG, \
-                 MATERIALIZE_DIAGNOSTIC_FLAG, \
-                 MATERIALIZE_PD_DIAGNOSTIC_FLAG, \
-                 MATERIALIZE_NOTPRODUCT_FLAG, \
-                 IGNORE_RANGE, \
-                 IGNORE_CONSTRAINT, \
-                 IGNORE_WRITEABLE)
 
-ARCH_FLAGS(MATERIALIZE_DEVELOPER_FLAG, \
-           MATERIALIZE_PRODUCT_FLAG, \
-           MATERIALIZE_DIAGNOSTIC_FLAG, \
-           MATERIALIZE_EXPERIMENTAL_FLAG, \
-           MATERIALIZE_NOTPRODUCT_FLAG, \
-           IGNORE_RANGE, \
-           IGNORE_CONSTRAINT, \
-           IGNORE_WRITEABLE)
+ALL_FLAGS(MATERIALIZE_DEVELOPER_FLAG,     \
+          MATERIALIZE_PD_DEVELOPER_FLAG,  \
+          MATERIALIZE_PRODUCT_FLAG,       \
+          MATERIALIZE_PD_PRODUCT_FLAG,    \
+          MATERIALIZE_DIAGNOSTIC_FLAG,    \
+          MATERIALIZE_PD_DIAGNOSTIC_FLAG, \
+          MATERIALIZE_EXPERIMENTAL_FLAG,  \
+          MATERIALIZE_NOTPRODUCT_FLAG,    \
+          MATERIALIZE_MANAGEABLE_FLAG,    \
+          MATERIALIZE_PRODUCT_RW_FLAG,    \
+          MATERIALIZE_LP64_PRODUCT_FLAG,  \
+          IGNORE_RANGE,                   \
+          IGNORE_CONSTRAINT,              \
+          IGNORE_WRITEABLE)
 
 MATERIALIZE_FLAGS_EXT
--- a/src/hotspot/share/runtime/globals.hpp	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/share/runtime/globals.hpp	Thu May 23 11:07:37 2019 +0100
@@ -25,115 +25,15 @@
 #ifndef SHARE_RUNTIME_GLOBALS_HPP
 #define SHARE_RUNTIME_GLOBALS_HPP
 
+#include "compiler/compiler_globals.hpp"
 #include "gc/shared/gc_globals.hpp"
+#include "runtime/globals_shared.hpp"
 #include "utilities/align.hpp"
 #include "utilities/globalDefinitions.hpp"
 #include "utilities/macros.hpp"
-
-#include <float.h> // for DBL_MAX
-
-// The larger HeapWordSize for 64bit requires larger heaps
-// for the same application running in 64bit.  See bug 4967770.
-// The minimum alignment to a heap word size is done.  Other
-// parts of the memory system may require additional alignment
-// and are responsible for those alignments.
-#ifdef _LP64
-#define ScaleForWordSize(x) align_down_((x) * 13 / 10, HeapWordSize)
-#else
-#define ScaleForWordSize(x) (x)
-#endif
-
-// use this for flags that are true per default in the tiered build
-// but false in non-tiered builds, and vice versa
-#ifdef TIERED
-#define  trueInTiered true
-#define falseInTiered false
-#else
-#define  trueInTiered false
-#define falseInTiered true
-#endif
-
-// Default and minimum StringTable and SymbolTable size values
-// Must be powers of 2
-const size_t defaultStringTableSize = NOT_LP64(1024) LP64_ONLY(65536);
-const size_t minimumStringTableSize = 128;
-const size_t defaultSymbolTableSize = 32768; // 2^15
-const size_t minimumSymbolTableSize = 1024;
-
 #include CPU_HEADER(globals)
 #include OS_HEADER(globals)
 #include OS_CPU_HEADER(globals)
-#ifdef COMPILER1
-#include CPU_HEADER(c1_globals)
-#include OS_HEADER(c1_globals)
-#endif
-#ifdef COMPILER2
-#include CPU_HEADER(c2_globals)
-#include OS_HEADER(c2_globals)
-#endif
-
-#if !defined(COMPILER1) && !defined(COMPILER2) && !INCLUDE_JVMCI
-define_pd_global(bool, BackgroundCompilation,        false);
-define_pd_global(bool, UseTLAB,                      false);
-define_pd_global(bool, CICompileOSR,                 false);
-define_pd_global(bool, UseTypeProfile,               false);
-define_pd_global(bool, UseOnStackReplacement,        false);
-define_pd_global(bool, InlineIntrinsics,             false);
-define_pd_global(bool, PreferInterpreterNativeStubs, true);
-define_pd_global(bool, ProfileInterpreter,           false);
-define_pd_global(bool, ProfileTraps,                 false);
-define_pd_global(bool, TieredCompilation,            false);
-
-define_pd_global(intx, CompileThreshold,             0);
-
-define_pd_global(intx,   OnStackReplacePercentage,   0);
-define_pd_global(bool,   ResizeTLAB,                 false);
-define_pd_global(intx,   FreqInlineSize,             0);
-define_pd_global(size_t, NewSizeThreadIncrease,      4*K);
-define_pd_global(bool,   InlineClassNatives,         true);
-define_pd_global(bool,   InlineUnsafeOps,            true);
-define_pd_global(uintx,  InitialCodeCacheSize,       160*K);
-define_pd_global(uintx,  ReservedCodeCacheSize,      32*M);
-define_pd_global(uintx,  NonProfiledCodeHeapSize,    0);
-define_pd_global(uintx,  ProfiledCodeHeapSize,       0);
-define_pd_global(uintx,  NonNMethodCodeHeapSize,     32*M);
-
-define_pd_global(uintx,  CodeCacheExpansionSize,     32*K);
-define_pd_global(uintx,  CodeCacheMinBlockLength,    1);
-define_pd_global(uintx,  CodeCacheMinimumUseSpace,   200*K);
-define_pd_global(size_t, MetaspaceSize,              ScaleForWordSize(4*M));
-define_pd_global(bool, NeverActAsServerClassMachine, true);
-define_pd_global(uint64_t,MaxRAM,                    1ULL*G);
-#define CI_COMPILER_COUNT 0
-#else
-
-#if COMPILER2_OR_JVMCI
-#define CI_COMPILER_COUNT 2
-#else
-#define CI_COMPILER_COUNT 1
-#endif // COMPILER2_OR_JVMCI
-
-#endif // no compilers
-
-// use this for flags that are true by default in the debug version but
-// false in the optimized version, and vice versa
-#ifdef ASSERT
-#define trueInDebug  true
-#define falseInDebug false
-#else
-#define trueInDebug  false
-#define falseInDebug true
-#endif
-
-// use this for flags that are true per default in the product build
-// but false in development builds, and vice versa
-#ifdef PRODUCT
-#define trueInProduct  true
-#define falseInProduct false
-#else
-#define trueInProduct  false
-#define falseInProduct true
-#endif
 
 // develop flags are settable / visible only during development and are constant in the PRODUCT version
 // product flags are always settable / visible
@@ -216,6 +116,12 @@
 //    (multiple times allowed)
 //
 
+// Default and minimum StringTable and SymbolTable size values
+// Must be powers of 2
+const size_t defaultStringTableSize = NOT_LP64(1024) LP64_ONLY(65536);
+const size_t minimumStringTableSize = 128;
+const size_t defaultSymbolTableSize = 32768; // 2^15
+const size_t minimumSymbolTableSize = 1024;
 
 #define RUNTIME_FLAGS(develop, \
                       develop_pd, \
@@ -2359,6 +2265,9 @@
           "shared spaces, and dumps the shared spaces to a file to be "     \
           "used in future JVM runs")                                        \
                                                                             \
+  product(bool, DynamicDumpSharedSpaces, false,                             \
+          "Dynamic archive")                                                \
+                                                                            \
   product(bool, PrintSharedArchiveAndExit, false,                           \
           "Print shared archive file contents")                             \
                                                                             \
@@ -2476,6 +2385,9 @@
   product(ccstr, SharedArchiveFile, NULL,                                   \
           "Override the default location of the CDS archive file")          \
                                                                             \
+  product(ccstr, ArchiveClassesAtExit, NULL,                                \
+          "The path and name of the dynamic archive file")                  \
+                                                                            \
   product(ccstr, ExtraSharedClassListFile, NULL,                            \
           "Extra classlist for building the CDS archive file")              \
                                                                             \
@@ -2554,57 +2466,6 @@
   experimental(bool, UseFastUnorderedTimeStamps, false,                     \
           "Use platform unstable time where supported for timestamps only")
 
-#define VM_FLAGS(develop,                                                   \
-                 develop_pd,                                                \
-                 product,                                                   \
-                 product_pd,                                                \
-                 diagnostic,                                                \
-                 diagnostic_pd,                                             \
-                 experimental,                                              \
-                 notproduct,                                                \
-                 manageable,                                                \
-                 product_rw,                                                \
-                 lp64_product,                                              \
-                 range,                                                     \
-                 constraint,                                                \
-                 writeable)                                                 \
-                                                                            \
-  RUNTIME_FLAGS(                                                            \
-    develop,                                                                \
-    develop_pd,                                                             \
-    product,                                                                \
-    product_pd,                                                             \
-    diagnostic,                                                             \
-    diagnostic_pd,                                                          \
-    experimental,                                                           \
-    notproduct,                                                             \
-    manageable,                                                             \
-    product_rw,                                                             \
-    lp64_product,                                                           \
-    range,                                                                  \
-    constraint,                                                             \
-    writeable)                                                              \
-                                                                            \
-  GC_FLAGS(                                                                 \
-    develop,                                                                \
-    develop_pd,                                                             \
-    product,                                                                \
-    product_pd,                                                             \
-    diagnostic,                                                             \
-    diagnostic_pd,                                                          \
-    experimental,                                                           \
-    notproduct,                                                             \
-    manageable,                                                             \
-    product_rw,                                                             \
-    lp64_product,                                                           \
-    range,                                                                  \
-    constraint,                                                             \
-    writeable)                                                              \
-
-/*
- *  Macros for factoring of globals
- */
-
 // Interface macros
 #define DECLARE_PRODUCT_FLAG(type, name, value, doc)      extern "C" type name;
 #define DECLARE_PD_PRODUCT_FLAG(type, name, doc)          extern "C" type name;
@@ -2629,70 +2490,20 @@
 #define DECLARE_LP64_PRODUCT_FLAG(type, name, value, doc) const type name = value;
 #endif // _LP64
 
-// Implementation macros
-#define MATERIALIZE_PRODUCT_FLAG(type, name, value, doc)      type name = value;
-#define MATERIALIZE_PD_PRODUCT_FLAG(type, name, doc)          type name = pd_##name;
-#define MATERIALIZE_DIAGNOSTIC_FLAG(type, name, value, doc)   type name = value;
-#define MATERIALIZE_PD_DIAGNOSTIC_FLAG(type, name, doc)       type name = pd_##name;
-#define MATERIALIZE_EXPERIMENTAL_FLAG(type, name, value, doc) type name = value;
-#define MATERIALIZE_MANAGEABLE_FLAG(type, name, value, doc)   type name = value;
-#define MATERIALIZE_PRODUCT_RW_FLAG(type, name, value, doc)   type name = value;
-#ifdef PRODUCT
-#define MATERIALIZE_DEVELOPER_FLAG(type, name, value, doc)
-#define MATERIALIZE_PD_DEVELOPER_FLAG(type, name, doc)
-#define MATERIALIZE_NOTPRODUCT_FLAG(type, name, value, doc)
-#else
-#define MATERIALIZE_DEVELOPER_FLAG(type, name, value, doc)    type name = value;
-#define MATERIALIZE_PD_DEVELOPER_FLAG(type, name, doc)        type name = pd_##name;
-#define MATERIALIZE_NOTPRODUCT_FLAG(type, name, value, doc)   type name = value;
-#endif // PRODUCT
-#ifdef _LP64
-#define MATERIALIZE_LP64_PRODUCT_FLAG(type, name, value, doc) type name = value;
-#else
-#define MATERIALIZE_LP64_PRODUCT_FLAG(type, name, value, doc) /* flag is constant */
-#endif // _LP64
-
-// Only materialize src code for range checking when required, ignore otherwise
-#define IGNORE_RANGE(a, b)
-// Only materialize src code for contraint checking when required, ignore otherwise
-#define IGNORE_CONSTRAINT(func,type)
-
-#define IGNORE_WRITEABLE(type)
-
-VM_FLAGS(DECLARE_DEVELOPER_FLAG, \
-         DECLARE_PD_DEVELOPER_FLAG, \
-         DECLARE_PRODUCT_FLAG, \
-         DECLARE_PD_PRODUCT_FLAG, \
-         DECLARE_DIAGNOSTIC_FLAG, \
-         DECLARE_PD_DIAGNOSTIC_FLAG, \
-         DECLARE_EXPERIMENTAL_FLAG, \
-         DECLARE_NOTPRODUCT_FLAG, \
-         DECLARE_MANAGEABLE_FLAG, \
-         DECLARE_PRODUCT_RW_FLAG, \
-         DECLARE_LP64_PRODUCT_FLAG, \
-         IGNORE_RANGE, \
-         IGNORE_CONSTRAINT, \
-         IGNORE_WRITEABLE)
-
-RUNTIME_OS_FLAGS(DECLARE_DEVELOPER_FLAG, \
-                 DECLARE_PD_DEVELOPER_FLAG, \
-                 DECLARE_PRODUCT_FLAG, \
-                 DECLARE_PD_PRODUCT_FLAG, \
-                 DECLARE_DIAGNOSTIC_FLAG, \
-                 DECLARE_PD_DIAGNOSTIC_FLAG, \
-                 DECLARE_NOTPRODUCT_FLAG, \
-                 IGNORE_RANGE, \
-                 IGNORE_CONSTRAINT, \
-                 IGNORE_WRITEABLE)
-
-ARCH_FLAGS(DECLARE_DEVELOPER_FLAG, \
-           DECLARE_PRODUCT_FLAG, \
-           DECLARE_DIAGNOSTIC_FLAG, \
-           DECLARE_EXPERIMENTAL_FLAG, \
-           DECLARE_NOTPRODUCT_FLAG, \
-           IGNORE_RANGE, \
-           IGNORE_CONSTRAINT, \
-           IGNORE_WRITEABLE)
+ALL_FLAGS(DECLARE_DEVELOPER_FLAG,     \
+          DECLARE_PD_DEVELOPER_FLAG,  \
+          DECLARE_PRODUCT_FLAG,       \
+          DECLARE_PD_PRODUCT_FLAG,    \
+          DECLARE_DIAGNOSTIC_FLAG,    \
+          DECLARE_PD_DIAGNOSTIC_FLAG, \
+          DECLARE_EXPERIMENTAL_FLAG,  \
+          DECLARE_NOTPRODUCT_FLAG,    \
+          DECLARE_MANAGEABLE_FLAG,    \
+          DECLARE_PRODUCT_RW_FLAG,    \
+          DECLARE_LP64_PRODUCT_FLAG,  \
+          IGNORE_RANGE,               \
+          IGNORE_CONSTRAINT,          \
+          IGNORE_WRITEABLE)
 
 // Extensions
 
--- a/src/hotspot/share/runtime/globals_ext.hpp	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/share/runtime/globals_ext.hpp	Thu May 23 11:07:37 2019 +0100
@@ -29,11 +29,8 @@
 
 // globals_extension.hpp extension
 
-// Additional JVMFlags enum values
-#define JVMFLAGS_EXT
-
-// Additional JVMFlagsWithType enum values
-#define JVMFLAGSWITHTYPE_EXT
+// Additional JVMFlagsEnum values
+#define JVMFLAGSENUM_EXT
 
 
 // globals.cpp extension
--- a/src/hotspot/share/runtime/globals_extension.hpp	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/share/runtime/globals_extension.hpp	Thu May 23 11:07:37 2019 +0100
@@ -27,313 +27,124 @@
 
 #include "runtime/globals.hpp"
 #include "utilities/macros.hpp"
-#if INCLUDE_JVMCI
-#include "jvmci/jvmci_globals.hpp"
-#endif
-#ifdef COMPILER1
-#include "c1/c1_globals.hpp"
-#endif
-#ifdef COMPILER2
-#include "opto/c2_globals.hpp"
-#endif
 
 // Construct enum of Flag_<cmdline-arg> constants.
 
-// Parenthesis left off in the following for the enum decl below.
-#define FLAG_MEMBER(flag) Flag_##flag
+#define FLAG_MEMBER_ENUM(name) Flag_##name##_enum
+#define FLAG_MEMBER_ENUM_(name) FLAG_MEMBER_ENUM(name),
 
-#define RUNTIME_PRODUCT_FLAG_MEMBER(type, name, value, doc)      FLAG_MEMBER(name),
-#define RUNTIME_PD_PRODUCT_FLAG_MEMBER(type, name, doc)          FLAG_MEMBER(name),
-#define RUNTIME_DIAGNOSTIC_FLAG_MEMBER(type, name, value, doc)   FLAG_MEMBER(name),
-#define RUNTIME_PD_DIAGNOSTIC_FLAG_MEMBER(type, name, doc)       FLAG_MEMBER(name),
-#define RUNTIME_EXPERIMENTAL_FLAG_MEMBER(type, name, value, doc) FLAG_MEMBER(name),
-#define RUNTIME_MANAGEABLE_FLAG_MEMBER(type, name, value, doc)   FLAG_MEMBER(name),
-#define RUNTIME_PRODUCT_RW_FLAG_MEMBER(type, name, value, doc)   FLAG_MEMBER(name),
-#define RUNTIME_DEVELOP_FLAG_MEMBER(type, name, value, doc)      FLAG_MEMBER(name),
-#define RUNTIME_PD_DEVELOP_FLAG_MEMBER(type, name, doc)          FLAG_MEMBER(name),
-#define RUNTIME_NOTPRODUCT_FLAG_MEMBER(type, name, value, doc)   FLAG_MEMBER(name),
-
-#define JVMCI_PRODUCT_FLAG_MEMBER(type, name, value, doc)        FLAG_MEMBER(name),
-#define JVMCI_PD_PRODUCT_FLAG_MEMBER(type, name, doc)            FLAG_MEMBER(name),
-#define JVMCI_DEVELOP_FLAG_MEMBER(type, name, value, doc)        FLAG_MEMBER(name),
-#define JVMCI_PD_DEVELOP_FLAG_MEMBER(type, name, doc)            FLAG_MEMBER(name),
-#define JVMCI_DIAGNOSTIC_FLAG_MEMBER(type, name, value, doc)     FLAG_MEMBER(name),
-#define JVMCI_PD_DIAGNOSTIC_FLAG_MEMBER(type, name, doc)         FLAG_MEMBER(name),
-#define JVMCI_EXPERIMENTAL_FLAG_MEMBER(type, name, value, doc)   FLAG_MEMBER(name),
-#define JVMCI_NOTPRODUCT_FLAG_MEMBER(type, name, value, doc)     FLAG_MEMBER(name),
-
+#define FLAG_MEMBER_ENUM_PRODUCT(type, name, value, doc)      FLAG_MEMBER_ENUM_(name)
+#define FLAG_MEMBER_ENUM_PD_PRODUCT(type, name, doc)          FLAG_MEMBER_ENUM_(name)
+#define FLAG_MEMBER_ENUM_DIAGNOSTIC(type, name, value, doc)   FLAG_MEMBER_ENUM_(name)
+#define FLAG_MEMBER_ENUM_PD_DIAGNOSTIC(type, name, doc)       FLAG_MEMBER_ENUM_(name)
+#define FLAG_MEMBER_ENUM_EXPERIMENTAL(type, name, value, doc) FLAG_MEMBER_ENUM_(name)
+#define FLAG_MEMBER_ENUM_MANAGEABLE(type, name, value, doc)   FLAG_MEMBER_ENUM_(name)
+#define FLAG_MEMBER_ENUM_PRODUCT_RW(type, name, value, doc)   FLAG_MEMBER_ENUM_(name)
+#define FLAG_MEMBER_ENUM_DEVELOP(type, name, value, doc)      FLAG_MEMBER_ENUM_(name)
+#define FLAG_MEMBER_ENUM_PD_DEVELOP(type, name, doc)          FLAG_MEMBER_ENUM_(name)
+#define FLAG_MEMBER_ENUM_NOTPRODUCT(type, name, value, doc)   FLAG_MEMBER_ENUM_(name)
 #ifdef _LP64
-#define RUNTIME_LP64_PRODUCT_FLAG_MEMBER(type, name, value, doc) FLAG_MEMBER(name),
+#define FLAG_MEMBER_ENUM_LP64_PRODUCT(type, name, value, doc) FLAG_MEMBER_ENUM_(name)
 #else
-#define RUNTIME_LP64_PRODUCT_FLAG_MEMBER(type, name, value, doc) /* flag is constant */
+#define FLAG_MEMBER_ENUM_LP64_PRODUCT(type, name, value, doc) /* flag is constant */
 #endif // _LP64
 
-#define C1_PRODUCT_FLAG_MEMBER(type, name, value, doc)           FLAG_MEMBER(name),
-#define C1_PD_PRODUCT_FLAG_MEMBER(type, name, doc)               FLAG_MEMBER(name),
-#define C1_DIAGNOSTIC_FLAG_MEMBER(type, name, value, doc)        FLAG_MEMBER(name),
-#define C1_PD_DIAGNOSTIC_FLAG_MEMBER(type, name, doc)            FLAG_MEMBER(name),
-#define C1_DEVELOP_FLAG_MEMBER(type, name, value, doc)           FLAG_MEMBER(name),
-#define C1_PD_DEVELOP_FLAG_MEMBER(type, name, doc)               FLAG_MEMBER(name),
-#define C1_NOTPRODUCT_FLAG_MEMBER(type, name, value, doc)        FLAG_MEMBER(name),
-
-#define C2_PRODUCT_FLAG_MEMBER(type, name, value, doc)           FLAG_MEMBER(name),
-#define C2_PD_PRODUCT_FLAG_MEMBER(type, name, doc)               FLAG_MEMBER(name),
-#define C2_DIAGNOSTIC_FLAG_MEMBER(type, name, value, doc)        FLAG_MEMBER(name),
-#define C2_PD_DIAGNOSTIC_FLAG_MEMBER(type, name, doc)            FLAG_MEMBER(name),
-#define C2_EXPERIMENTAL_FLAG_MEMBER(type, name, value, doc)      FLAG_MEMBER(name),
-#define C2_DEVELOP_FLAG_MEMBER(type, name, value, doc)           FLAG_MEMBER(name),
-#define C2_PD_DEVELOP_FLAG_MEMBER(type, name, doc)               FLAG_MEMBER(name),
-#define C2_NOTPRODUCT_FLAG_MEMBER(type, name, value, doc)        FLAG_MEMBER(name),
-
-#define ARCH_PRODUCT_FLAG_MEMBER(type, name, value, doc)         FLAG_MEMBER(name),
-#define ARCH_DIAGNOSTIC_FLAG_MEMBER(type, name, value, doc)      FLAG_MEMBER(name),
-#define ARCH_EXPERIMENTAL_FLAG_MEMBER(type, name, value, doc)    FLAG_MEMBER(name),
-#define ARCH_DEVELOP_FLAG_MEMBER(type, name, value, doc)         FLAG_MEMBER(name),
-#define ARCH_NOTPRODUCT_FLAG_MEMBER(type, name, value, doc)      FLAG_MEMBER(name),
-
 typedef enum {
- VM_FLAGS(RUNTIME_DEVELOP_FLAG_MEMBER, \
-          RUNTIME_PD_DEVELOP_FLAG_MEMBER, \
-          RUNTIME_PRODUCT_FLAG_MEMBER, \
-          RUNTIME_PD_PRODUCT_FLAG_MEMBER, \
-          RUNTIME_DIAGNOSTIC_FLAG_MEMBER, \
-          RUNTIME_PD_DIAGNOSTIC_FLAG_MEMBER, \
-          RUNTIME_EXPERIMENTAL_FLAG_MEMBER, \
-          RUNTIME_NOTPRODUCT_FLAG_MEMBER, \
-          RUNTIME_MANAGEABLE_FLAG_MEMBER, \
-          RUNTIME_PRODUCT_RW_FLAG_MEMBER, \
-          RUNTIME_LP64_PRODUCT_FLAG_MEMBER, \
-          IGNORE_RANGE, \
-          IGNORE_CONSTRAINT, \
-          IGNORE_WRITEABLE)
-
- RUNTIME_OS_FLAGS(RUNTIME_DEVELOP_FLAG_MEMBER,    \
-                  RUNTIME_PD_DEVELOP_FLAG_MEMBER, \
-                  RUNTIME_PRODUCT_FLAG_MEMBER, \
-                  RUNTIME_PD_PRODUCT_FLAG_MEMBER, \
-                  RUNTIME_DIAGNOSTIC_FLAG_MEMBER, \
-                  RUNTIME_PD_DIAGNOSTIC_FLAG_MEMBER, \
-                  RUNTIME_NOTPRODUCT_FLAG_MEMBER, \
-                  IGNORE_RANGE, \
-                  IGNORE_CONSTRAINT, \
-                  IGNORE_WRITEABLE)
-#if INCLUDE_JVMCI
- JVMCI_FLAGS(JVMCI_DEVELOP_FLAG_MEMBER, \
-             JVMCI_PD_DEVELOP_FLAG_MEMBER, \
-             JVMCI_PRODUCT_FLAG_MEMBER, \
-             JVMCI_PD_PRODUCT_FLAG_MEMBER, \
-             JVMCI_DIAGNOSTIC_FLAG_MEMBER, \
-             JVMCI_PD_DIAGNOSTIC_FLAG_MEMBER, \
-             JVMCI_EXPERIMENTAL_FLAG_MEMBER, \
-             JVMCI_NOTPRODUCT_FLAG_MEMBER, \
-             IGNORE_RANGE, \
-             IGNORE_CONSTRAINT, \
-             IGNORE_WRITEABLE)
-#endif // INCLUDE_JVMCI
-#ifdef COMPILER1
- C1_FLAGS(C1_DEVELOP_FLAG_MEMBER, \
-          C1_PD_DEVELOP_FLAG_MEMBER, \
-          C1_PRODUCT_FLAG_MEMBER, \
-          C1_PD_PRODUCT_FLAG_MEMBER, \
-          C1_DIAGNOSTIC_FLAG_MEMBER, \
-          C1_PD_DIAGNOSTIC_FLAG_MEMBER, \
-          C1_NOTPRODUCT_FLAG_MEMBER, \
-          IGNORE_RANGE, \
-          IGNORE_CONSTRAINT, \
-          IGNORE_WRITEABLE)
-#endif
-#ifdef COMPILER2
- C2_FLAGS(C2_DEVELOP_FLAG_MEMBER, \
-          C2_PD_DEVELOP_FLAG_MEMBER, \
-          C2_PRODUCT_FLAG_MEMBER, \
-          C2_PD_PRODUCT_FLAG_MEMBER, \
-          C2_DIAGNOSTIC_FLAG_MEMBER, \
-          C2_PD_DIAGNOSTIC_FLAG_MEMBER, \
-          C2_EXPERIMENTAL_FLAG_MEMBER, \
-          C2_NOTPRODUCT_FLAG_MEMBER, \
-          IGNORE_RANGE, \
-          IGNORE_CONSTRAINT, \
-          IGNORE_WRITEABLE)
-#endif
- ARCH_FLAGS(ARCH_DEVELOP_FLAG_MEMBER, \
-            ARCH_PRODUCT_FLAG_MEMBER, \
-            ARCH_DIAGNOSTIC_FLAG_MEMBER, \
-            ARCH_EXPERIMENTAL_FLAG_MEMBER, \
-            ARCH_NOTPRODUCT_FLAG_MEMBER, \
-            IGNORE_RANGE, \
-            IGNORE_CONSTRAINT, \
+  ALL_FLAGS(FLAG_MEMBER_ENUM_DEVELOP,
+            FLAG_MEMBER_ENUM_PD_DEVELOP,
+            FLAG_MEMBER_ENUM_PRODUCT,
+            FLAG_MEMBER_ENUM_PD_PRODUCT,
+            FLAG_MEMBER_ENUM_DIAGNOSTIC,
+            FLAG_MEMBER_ENUM_PD_DIAGNOSTIC,
+            FLAG_MEMBER_ENUM_EXPERIMENTAL,
+            FLAG_MEMBER_ENUM_NOTPRODUCT,
+            FLAG_MEMBER_ENUM_MANAGEABLE,
+            FLAG_MEMBER_ENUM_PRODUCT_RW,
+            FLAG_MEMBER_ENUM_LP64_PRODUCT,
+            IGNORE_RANGE,
+            IGNORE_CONSTRAINT,
             IGNORE_WRITEABLE)
- JVMFLAGS_EXT
- NUM_JVMFlags
-} JVMFlags;
-
-// Construct enum of Flag_<cmdline-arg>_<type> constants.
-
-#define FLAG_MEMBER_WITH_TYPE(flag,type) Flag_##flag##_##type
-
-#define RUNTIME_PRODUCT_FLAG_MEMBER_WITH_TYPE(type, name, value, doc)      FLAG_MEMBER_WITH_TYPE(name,type),
-#define RUNTIME_PD_PRODUCT_FLAG_MEMBER_WITH_TYPE(type, name, doc)          FLAG_MEMBER_WITH_TYPE(name,type),
-#define RUNTIME_DIAGNOSTIC_FLAG_MEMBER_WITH_TYPE(type, name, value, doc)   FLAG_MEMBER_WITH_TYPE(name,type),
-#define RUNTIME_PD_DIAGNOSTIC_FLAG_MEMBER_WITH_TYPE(type, name, doc)       FLAG_MEMBER_WITH_TYPE(name,type),
-#define RUNTIME_EXPERIMENTAL_FLAG_MEMBER_WITH_TYPE(type, name, value, doc) FLAG_MEMBER_WITH_TYPE(name,type),
-#define RUNTIME_MANAGEABLE_FLAG_MEMBER_WITH_TYPE(type, name, value, doc)   FLAG_MEMBER_WITH_TYPE(name,type),
-#define RUNTIME_PRODUCT_RW_FLAG_MEMBER_WITH_TYPE(type, name, value, doc)   FLAG_MEMBER_WITH_TYPE(name,type),
-#define RUNTIME_DEVELOP_FLAG_MEMBER_WITH_TYPE(type, name, value, doc)      FLAG_MEMBER_WITH_TYPE(name,type),
-#define RUNTIME_PD_DEVELOP_FLAG_MEMBER_WITH_TYPE(type, name, doc)          FLAG_MEMBER_WITH_TYPE(name,type),
-#define RUNTIME_NOTPRODUCT_FLAG_MEMBER_WITH_TYPE(type, name, value, doc)   FLAG_MEMBER_WITH_TYPE(name,type),
-
-#define JVMCI_PRODUCT_FLAG_MEMBER_WITH_TYPE(type, name, value, doc)        FLAG_MEMBER_WITH_TYPE(name,type),
-#define JVMCI_PD_PRODUCT_FLAG_MEMBER_WITH_TYPE(type, name, doc)            FLAG_MEMBER_WITH_TYPE(name,type),
-#define JVMCI_DEVELOP_FLAG_MEMBER_WITH_TYPE(type, name, value, doc)        FLAG_MEMBER_WITH_TYPE(name,type),
-#define JVMCI_PD_DEVELOP_FLAG_MEMBER_WITH_TYPE(type, name, doc)            FLAG_MEMBER_WITH_TYPE(name,type),
-#define JVMCI_DIAGNOSTIC_FLAG_MEMBER_WITH_TYPE(type, name, value, doc)     FLAG_MEMBER_WITH_TYPE(name,type),
-#define JVMCI_PD_DIAGNOSTIC_FLAG_MEMBER_WITH_TYPE(type, name, doc)         FLAG_MEMBER_WITH_TYPE(name,type),
-#define JVMCI_EXPERIMENTAL_FLAG_MEMBER_WITH_TYPE(type, name, value, doc)   FLAG_MEMBER_WITH_TYPE(name,type),
-#define JVMCI_NOTPRODUCT_FLAG_MEMBER_WITH_TYPE(type, name, value, doc)     FLAG_MEMBER_WITH_TYPE(name,type),
-
-#define C1_PRODUCT_FLAG_MEMBER_WITH_TYPE(type, name, value, doc)           FLAG_MEMBER_WITH_TYPE(name,type),
-#define C1_PD_PRODUCT_FLAG_MEMBER_WITH_TYPE(type, name, doc)               FLAG_MEMBER_WITH_TYPE(name,type),
-#define C1_DIAGNOSTIC_FLAG_MEMBER_WITH_TYPE(type, name, value, doc)        FLAG_MEMBER_WITH_TYPE(name,type),
-#define C1_PD_DIAGNOSTIC_FLAG_MEMBER_WITH_TYPE(type, name, doc)            FLAG_MEMBER_WITH_TYPE(name,type),
-#define C1_DEVELOP_FLAG_MEMBER_WITH_TYPE(type, name, value, doc)           FLAG_MEMBER_WITH_TYPE(name,type),
-#define C1_PD_DEVELOP_FLAG_MEMBER_WITH_TYPE(type, name, doc)               FLAG_MEMBER_WITH_TYPE(name,type),
-#define C1_NOTPRODUCT_FLAG_MEMBER_WITH_TYPE(type, name, value, doc)        FLAG_MEMBER_WITH_TYPE(name,type),
-
-#ifdef _LP64
-#define RUNTIME_LP64_PRODUCT_FLAG_MEMBER_WITH_TYPE(type, name, value, doc) FLAG_MEMBER_WITH_TYPE(name,type),
-#else
-#define RUNTIME_LP64_PRODUCT_FLAG_MEMBER_WITH_TYPE(type, name, value, doc) /* flag is constant */
-#endif // _LP64
-
-#define C2_PRODUCT_FLAG_MEMBER_WITH_TYPE(type, name, value, doc)           FLAG_MEMBER_WITH_TYPE(name,type),
-#define C2_PD_PRODUCT_FLAG_MEMBER_WITH_TYPE(type, name, doc)               FLAG_MEMBER_WITH_TYPE(name,type),
-#define C2_DIAGNOSTIC_FLAG_MEMBER_WITH_TYPE(type, name, value, doc)        FLAG_MEMBER_WITH_TYPE(name,type),
-#define C2_PD_DIAGNOSTIC_FLAG_MEMBER_WITH_TYPE(type, name, doc)            FLAG_MEMBER_WITH_TYPE(name,type),
-#define C2_EXPERIMENTAL_FLAG_MEMBER_WITH_TYPE(type, name, value, doc)      FLAG_MEMBER_WITH_TYPE(name,type),
-#define C2_DEVELOP_FLAG_MEMBER_WITH_TYPE(type, name, value, doc)           FLAG_MEMBER_WITH_TYPE(name,type),
-#define C2_PD_DEVELOP_FLAG_MEMBER_WITH_TYPE(type, name, doc)               FLAG_MEMBER_WITH_TYPE(name,type),
-#define C2_NOTPRODUCT_FLAG_MEMBER_WITH_TYPE(type, name, value, doc)        FLAG_MEMBER_WITH_TYPE(name,type),
-
-#define ARCH_PRODUCT_FLAG_MEMBER_WITH_TYPE(type, name, value, doc)         FLAG_MEMBER_WITH_TYPE(name,type),
-#define ARCH_DIAGNOSTIC_FLAG_MEMBER_WITH_TYPE(type, name, value, doc)      FLAG_MEMBER_WITH_TYPE(name,type),
-#define ARCH_EXPERIMENTAL_FLAG_MEMBER_WITH_TYPE(type, name, value, doc)    FLAG_MEMBER_WITH_TYPE(name,type),
-#define ARCH_DEVELOP_FLAG_MEMBER_WITH_TYPE(type, name, value, doc)         FLAG_MEMBER_WITH_TYPE(name,type),
-#define ARCH_NOTPRODUCT_FLAG_MEMBER_WITH_TYPE(type, name, value, doc)      FLAG_MEMBER_WITH_TYPE(name,type),
-
-typedef enum {
-  VM_FLAGS(RUNTIME_DEVELOP_FLAG_MEMBER_WITH_TYPE,
-           RUNTIME_PD_DEVELOP_FLAG_MEMBER_WITH_TYPE,
-           RUNTIME_PRODUCT_FLAG_MEMBER_WITH_TYPE,
-           RUNTIME_PD_PRODUCT_FLAG_MEMBER_WITH_TYPE,
-           RUNTIME_DIAGNOSTIC_FLAG_MEMBER_WITH_TYPE,
-           RUNTIME_PD_DIAGNOSTIC_FLAG_MEMBER_WITH_TYPE,
-           RUNTIME_EXPERIMENTAL_FLAG_MEMBER_WITH_TYPE,
-           RUNTIME_NOTPRODUCT_FLAG_MEMBER_WITH_TYPE,
-           RUNTIME_MANAGEABLE_FLAG_MEMBER_WITH_TYPE,
-           RUNTIME_PRODUCT_RW_FLAG_MEMBER_WITH_TYPE,
-           RUNTIME_LP64_PRODUCT_FLAG_MEMBER_WITH_TYPE,
-           IGNORE_RANGE,
-           IGNORE_CONSTRAINT,
-           IGNORE_WRITEABLE)
-
- RUNTIME_OS_FLAGS(RUNTIME_DEVELOP_FLAG_MEMBER_WITH_TYPE,
-                  RUNTIME_PD_DEVELOP_FLAG_MEMBER_WITH_TYPE,
-                  RUNTIME_PRODUCT_FLAG_MEMBER_WITH_TYPE,
-                  RUNTIME_PD_PRODUCT_FLAG_MEMBER_WITH_TYPE,
-                  RUNTIME_DIAGNOSTIC_FLAG_MEMBER_WITH_TYPE,
-                  RUNTIME_PD_DIAGNOSTIC_FLAG_MEMBER_WITH_TYPE,
-                  RUNTIME_NOTPRODUCT_FLAG_MEMBER_WITH_TYPE,
-                  IGNORE_RANGE,
-                  IGNORE_CONSTRAINT,
-                  IGNORE_WRITEABLE)
-#if INCLUDE_JVMCI
- JVMCI_FLAGS(JVMCI_DEVELOP_FLAG_MEMBER_WITH_TYPE,
-             JVMCI_PD_DEVELOP_FLAG_MEMBER_WITH_TYPE,
-             JVMCI_PRODUCT_FLAG_MEMBER_WITH_TYPE,
-             JVMCI_PD_PRODUCT_FLAG_MEMBER_WITH_TYPE,
-             JVMCI_DIAGNOSTIC_FLAG_MEMBER_WITH_TYPE,
-             JVMCI_PD_DIAGNOSTIC_FLAG_MEMBER_WITH_TYPE,
-             JVMCI_EXPERIMENTAL_FLAG_MEMBER_WITH_TYPE,
-             JVMCI_NOTPRODUCT_FLAG_MEMBER_WITH_TYPE,
-             IGNORE_RANGE,
-             IGNORE_CONSTRAINT,
-             IGNORE_WRITEABLE)
-#endif // INCLUDE_JVMCI
-#ifdef COMPILER1
- C1_FLAGS(C1_DEVELOP_FLAG_MEMBER_WITH_TYPE,
-          C1_PD_DEVELOP_FLAG_MEMBER_WITH_TYPE,
-          C1_PRODUCT_FLAG_MEMBER_WITH_TYPE,
-          C1_PD_PRODUCT_FLAG_MEMBER_WITH_TYPE,
-          C1_DIAGNOSTIC_FLAG_MEMBER_WITH_TYPE,
-          C1_PD_DIAGNOSTIC_FLAG_MEMBER_WITH_TYPE,
-          C1_NOTPRODUCT_FLAG_MEMBER_WITH_TYPE,
-          IGNORE_RANGE,
-          IGNORE_CONSTRAINT,
-          IGNORE_WRITEABLE)
-#endif
-#ifdef COMPILER2
- C2_FLAGS(C2_DEVELOP_FLAG_MEMBER_WITH_TYPE,
-          C2_PD_DEVELOP_FLAG_MEMBER_WITH_TYPE,
-          C2_PRODUCT_FLAG_MEMBER_WITH_TYPE,
-          C2_PD_PRODUCT_FLAG_MEMBER_WITH_TYPE,
-          C2_DIAGNOSTIC_FLAG_MEMBER_WITH_TYPE,
-          C2_PD_DIAGNOSTIC_FLAG_MEMBER_WITH_TYPE,
-          C2_EXPERIMENTAL_FLAG_MEMBER_WITH_TYPE,
-          C2_NOTPRODUCT_FLAG_MEMBER_WITH_TYPE,
-          IGNORE_RANGE,
-          IGNORE_CONSTRAINT,
-          IGNORE_WRITEABLE)
-#endif
- ARCH_FLAGS(ARCH_DEVELOP_FLAG_MEMBER_WITH_TYPE,
-          ARCH_PRODUCT_FLAG_MEMBER_WITH_TYPE,
-          ARCH_DIAGNOSTIC_FLAG_MEMBER_WITH_TYPE,
-          ARCH_EXPERIMENTAL_FLAG_MEMBER_WITH_TYPE,
-          ARCH_NOTPRODUCT_FLAG_MEMBER_WITH_TYPE,
-          IGNORE_RANGE,
-          IGNORE_CONSTRAINT,
-          IGNORE_WRITEABLE)
-  JVMFLAGSWITHTYPE_EXT
-  NUM_JVMFlagsWithType
-} JVMFlagsWithType;
-
-#define FLAG_IS_DEFAULT(name)         (JVMFlagEx::is_default(FLAG_MEMBER(name)))
-#define FLAG_IS_ERGO(name)            (JVMFlagEx::is_ergo(FLAG_MEMBER(name)))
-#define FLAG_IS_CMDLINE(name)         (JVMFlagEx::is_cmdline(FLAG_MEMBER(name)))
-
-#define FLAG_SET_DEFAULT(name, value) ((name) = (value))
-
-#define FLAG_SET_CMDLINE(type, name, value) (JVMFlagEx::setOnCmdLine(FLAG_MEMBER_WITH_TYPE(name, type)), \
-                                             JVMFlagEx::type##AtPut(FLAG_MEMBER_WITH_TYPE(name, type), (type)(value), JVMFlag::COMMAND_LINE))
-#define FLAG_SET_ERGO(type, name, value)    (JVMFlagEx::type##AtPut(FLAG_MEMBER_WITH_TYPE(name, type), (type)(value), JVMFlag::ERGONOMIC))
-#define FLAG_SET_MGMT(type, name, value)    (JVMFlagEx::type##AtPut(FLAG_MEMBER_WITH_TYPE(name, type), (type)(value), JVMFlag::MANAGEMENT))
-
-#define FLAG_SET_ERGO_IF_DEFAULT(type, name, value) \
-  do {                                              \
-    if (FLAG_IS_DEFAULT(name)) {                    \
-      FLAG_SET_ERGO(type, name, value);             \
-    }                                               \
-  } while (0)
+  JVMFLAGSENUM_EXT
+  NUM_JVMFlagsEnum
+} JVMFlagsEnum;
 
 // Can't put the following in JVMFlags because
 // of a circular dependency on the enum definition.
 class JVMFlagEx : JVMFlag {
  public:
-  static JVMFlag::Error boolAtPut(JVMFlagsWithType flag, bool value, JVMFlag::Flags origin);
-  static JVMFlag::Error intAtPut(JVMFlagsWithType flag, int value, JVMFlag::Flags origin);
-  static JVMFlag::Error uintAtPut(JVMFlagsWithType flag, uint value, JVMFlag::Flags origin);
-  static JVMFlag::Error intxAtPut(JVMFlagsWithType flag, intx value, JVMFlag::Flags origin);
-  static JVMFlag::Error uintxAtPut(JVMFlagsWithType flag, uintx value, JVMFlag::Flags origin);
-  static JVMFlag::Error uint64_tAtPut(JVMFlagsWithType flag, uint64_t value, JVMFlag::Flags origin);
-  static JVMFlag::Error size_tAtPut(JVMFlagsWithType flag, size_t value, JVMFlag::Flags origin);
-  static JVMFlag::Error doubleAtPut(JVMFlagsWithType flag, double value, JVMFlag::Flags origin);
+  static JVMFlag::Error boolAtPut(JVMFlagsEnum flag, bool value, JVMFlag::Flags origin);
+  static JVMFlag::Error intAtPut(JVMFlagsEnum flag, int value, JVMFlag::Flags origin);
+  static JVMFlag::Error uintAtPut(JVMFlagsEnum flag, uint value, JVMFlag::Flags origin);
+  static JVMFlag::Error intxAtPut(JVMFlagsEnum flag, intx value, JVMFlag::Flags origin);
+  static JVMFlag::Error uintxAtPut(JVMFlagsEnum flag, uintx value, JVMFlag::Flags origin);
+  static JVMFlag::Error uint64_tAtPut(JVMFlagsEnum flag, uint64_t value, JVMFlag::Flags origin);
+  static JVMFlag::Error size_tAtPut(JVMFlagsEnum flag, size_t value, JVMFlag::Flags origin);
+  static JVMFlag::Error doubleAtPut(JVMFlagsEnum flag, double value, JVMFlag::Flags origin);
   // Contract:  Flag will make private copy of the incoming value
-  static JVMFlag::Error ccstrAtPut(JVMFlagsWithType flag, ccstr value, JVMFlag::Flags origin);
+  static JVMFlag::Error ccstrAtPut(JVMFlagsEnum flag, ccstr value, JVMFlag::Flags origin);
+  static JVMFlag::Error ccstrlistAtPut(JVMFlagsEnum flag, ccstr value, JVMFlag::Flags origin) {
+    return ccstrAtPut(flag, value, origin);
+  }
 
-  static bool is_default(JVMFlags flag);
-  static bool is_ergo(JVMFlags flag);
-  static bool is_cmdline(JVMFlags flag);
+  static bool is_default(JVMFlagsEnum flag);
+  static bool is_ergo(JVMFlagsEnum flag);
+  static bool is_cmdline(JVMFlagsEnum flag);
 
-  static void setOnCmdLine(JVMFlagsWithType flag);
+  static void setOnCmdLine(JVMFlagsEnum flag);
 };
 
+// Construct set functions for all flags
+
+#define FLAG_MEMBER_SET(name) Flag_##name##_set
+#define FLAG_MEMBER_SET_(type, name) inline JVMFlag::Error FLAG_MEMBER_SET(name)(type value, JVMFlag::Flags origin) { return JVMFlagEx::type##AtPut(FLAG_MEMBER_ENUM(name), value, origin); }
+
+#define FLAG_MEMBER_SET_PRODUCT(type, name, value, doc)      FLAG_MEMBER_SET_(type, name)
+#define FLAG_MEMBER_SET_PD_PRODUCT(type, name, doc)          FLAG_MEMBER_SET_(type, name)
+#define FLAG_MEMBER_SET_DIAGNOSTIC(type, name, value, doc)   FLAG_MEMBER_SET_(type, name)
+#define FLAG_MEMBER_SET_PD_DIAGNOSTIC(type, name, doc)       FLAG_MEMBER_SET_(type, name)
+#define FLAG_MEMBER_SET_EXPERIMENTAL(type, name, value, doc) FLAG_MEMBER_SET_(type, name)
+#define FLAG_MEMBER_SET_MANAGEABLE(type, name, value, doc)   FLAG_MEMBER_SET_(type, name)
+#define FLAG_MEMBER_SET_PRODUCT_RW(type, name, value, doc)   FLAG_MEMBER_SET_(type, name)
+#define FLAG_MEMBER_SET_DEVELOP(type, name, value, doc)      FLAG_MEMBER_SET_(type, name)
+#define FLAG_MEMBER_SET_PD_DEVELOP(type, name, doc)          FLAG_MEMBER_SET_(type, name)
+#define FLAG_MEMBER_SET_NOTPRODUCT(type, name, value, doc)   FLAG_MEMBER_SET_(type, name)
+#ifdef _LP64
+#define FLAG_MEMBER_SET_LP64_PRODUCT(type, name, value, doc) FLAG_MEMBER_SET_(type, name)
+#else
+#define FLAG_MEMBER_SET_LP64_PRODUCT(type, name, value, doc) /* flag is constant */
+#endif // _LP64
+
+ALL_FLAGS(FLAG_MEMBER_SET_DEVELOP,
+          FLAG_MEMBER_SET_PD_DEVELOP,
+          FLAG_MEMBER_SET_PRODUCT,
+          FLAG_MEMBER_SET_PD_PRODUCT,
+          FLAG_MEMBER_SET_DIAGNOSTIC,
+          FLAG_MEMBER_SET_PD_DIAGNOSTIC,
+          FLAG_MEMBER_SET_EXPERIMENTAL,
+          FLAG_MEMBER_SET_NOTPRODUCT,
+          FLAG_MEMBER_SET_MANAGEABLE,
+          FLAG_MEMBER_SET_PRODUCT_RW,
+          FLAG_MEMBER_SET_LP64_PRODUCT,
+          IGNORE_RANGE,
+          IGNORE_CONSTRAINT,
+          IGNORE_WRITEABLE)
+
+#define FLAG_IS_DEFAULT(name)         (JVMFlagEx::is_default(FLAG_MEMBER_ENUM(name)))
+#define FLAG_IS_ERGO(name)            (JVMFlagEx::is_ergo(FLAG_MEMBER_ENUM(name)))
+#define FLAG_IS_CMDLINE(name)         (JVMFlagEx::is_cmdline(FLAG_MEMBER_ENUM(name)))
+
+#define FLAG_SET_DEFAULT(name, value) ((name) = (value))
+
+#define FLAG_SET_CMDLINE(name, value) (JVMFlagEx::setOnCmdLine(FLAG_MEMBER_ENUM(name)), \
+                                       FLAG_MEMBER_SET(name)((value), JVMFlag::COMMAND_LINE))
+#define FLAG_SET_ERGO(name, value)    (FLAG_MEMBER_SET(name)((value), JVMFlag::ERGONOMIC))
+#define FLAG_SET_MGMT(name, value)    (FLAG_MEMBER_SET(name)((value), JVMFlag::MANAGEMENT))
+
+#define FLAG_SET_ERGO_IF_DEFAULT(name, value) \
+  do {                                        \
+    if (FLAG_IS_DEFAULT(name)) {              \
+      FLAG_SET_ERGO(name, value);             \
+    }                                         \
+  } while (0)
+
 #endif // SHARE_RUNTIME_GLOBALS_EXTENSION_HPP
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/runtime/globals_shared.hpp	Thu May 23 11:07:37 2019 +0100
@@ -0,0 +1,223 @@
+/*
+ * Copyright (c) 1997, 2019, 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.
+ *
+ */
+
+#ifndef SHARE_RUNTIME_GLOBALS_SHARED_HPP
+#define SHARE_RUNTIME_GLOBALS_SHARED_HPP
+
+#include "utilities/align.hpp"
+#include "utilities/globalDefinitions.hpp"
+#include "utilities/macros.hpp"
+
+#include <float.h> // for DBL_MAX
+
+// The larger HeapWordSize for 64bit requires larger heaps
+// for the same application running in 64bit.  See bug 4967770.
+// The minimum alignment to a heap word size is done.  Other
+// parts of the memory system may require additional alignment
+// and are responsible for those alignments.
+#ifdef _LP64
+#define ScaleForWordSize(x) align_down_((x) * 13 / 10, HeapWordSize)
+#else
+#define ScaleForWordSize(x) (x)
+#endif
+
+// use this for flags that are true per default in the tiered build
+// but false in non-tiered builds, and vice versa
+#ifdef TIERED
+#define  trueInTiered true
+#define falseInTiered false
+#else
+#define  trueInTiered false
+#define falseInTiered true
+#endif
+
+// use this for flags that are true by default in the debug version but
+// false in the optimized version, and vice versa
+#ifdef ASSERT
+#define trueInDebug  true
+#define falseInDebug false
+#else
+#define trueInDebug  false
+#define falseInDebug true
+#endif
+
+// use this for flags that are true per default in the product build
+// but false in development builds, and vice versa
+#ifdef PRODUCT
+#define trueInProduct  true
+#define falseInProduct false
+#else
+#define trueInProduct  false
+#define falseInProduct true
+#endif
+
+// Only materialize src code for range checking when required, ignore otherwise
+#define IGNORE_RANGE(a, b)
+// Only materialize src code for contraint checking when required, ignore otherwise
+#define IGNORE_CONSTRAINT(func,type)
+
+#define IGNORE_WRITEABLE(type)
+
+#define VM_FLAGS(             \
+    develop,                  \
+    develop_pd,               \
+    product,                  \
+    product_pd,               \
+    diagnostic,               \
+    diagnostic_pd,            \
+    experimental,             \
+    notproduct,               \
+    manageable,               \
+    product_rw,               \
+    lp64_product,             \
+    range,                    \
+    constraint,               \
+    writeable)                \
+                              \
+  RUNTIME_FLAGS(              \
+    develop,                  \
+    develop_pd,               \
+    product,                  \
+    product_pd,               \
+    diagnostic,               \
+    diagnostic_pd,            \
+    experimental,             \
+    notproduct,               \
+    manageable,               \
+    product_rw,               \
+    lp64_product,             \
+    range,                    \
+    constraint,               \
+    writeable)                \
+                              \
+  GC_FLAGS(                   \
+    develop,                  \
+    develop_pd,               \
+    product,                  \
+    product_pd,               \
+    diagnostic,               \
+    diagnostic_pd,            \
+    experimental,             \
+    notproduct,               \
+    manageable,               \
+    product_rw,               \
+    lp64_product,             \
+    range,                    \
+    constraint,               \
+    writeable)                \
+
+
+#define ALL_FLAGS(            \
+    develop,                  \
+    develop_pd,               \
+    product,                  \
+    product_pd,               \
+    diagnostic,               \
+    diagnostic_pd,            \
+    experimental,             \
+    notproduct,               \
+    manageable,               \
+    product_rw,               \
+    lp64_product,             \
+    range,                    \
+    constraint,               \
+    writeable)                \
+                              \
+  VM_FLAGS(                   \
+    develop,                  \
+    develop_pd,               \
+    product,                  \
+    product_pd,               \
+    diagnostic,               \
+    diagnostic_pd,            \
+    experimental,             \
+    notproduct,               \
+    manageable,               \
+    product_rw,               \
+    lp64_product,             \
+    range,                    \
+    constraint,               \
+    writeable)                \
+                              \
+  RUNTIME_OS_FLAGS(           \
+    develop,                  \
+    develop_pd,               \
+    product,                  \
+    product_pd,               \
+    diagnostic,               \
+    diagnostic_pd,            \
+    notproduct,               \
+    range,                    \
+    constraint,               \
+    writeable)                \
+                              \
+  JVMCI_ONLY(JVMCI_FLAGS(     \
+    develop,                  \
+    develop_pd,               \
+    product,                  \
+    product_pd,               \
+    diagnostic,               \
+    diagnostic_pd,            \
+    experimental,             \
+    notproduct,               \
+    range,                    \
+    constraint,               \
+    writeable))               \
+                              \
+  COMPILER1_PRESENT(C1_FLAGS( \
+    develop,                  \
+    develop_pd,               \
+    product,                  \
+    product_pd,               \
+    diagnostic,               \
+    diagnostic_pd,            \
+    notproduct,               \
+    range,                    \
+    constraint,               \
+    writeable))               \
+                              \
+  COMPILER2_PRESENT(C2_FLAGS( \
+    develop,                  \
+    develop_pd,               \
+    product,                  \
+    product_pd,               \
+    diagnostic,               \
+    diagnostic_pd,            \
+    experimental,             \
+    notproduct,               \
+    range,                    \
+    constraint,               \
+    writeable))               \
+                              \
+  ARCH_FLAGS(                 \
+    develop,                  \
+    product,                  \
+    diagnostic,               \
+    experimental,             \
+    notproduct,               \
+    range,                    \
+    constraint,               \
+    writeable)
+
+#endif // SHARE_RUNTIME_GLOBALS_SHARED_HPP
--- a/src/hotspot/share/runtime/java.cpp	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/share/runtime/java.cpp	Thu May 23 11:07:37 2019 +0100
@@ -43,6 +43,7 @@
 #include "logging/logStream.hpp"
 #include "memory/oopFactory.hpp"
 #include "memory/resourceArea.hpp"
+#include "memory/dynamicArchive.hpp"
 #include "memory/universe.hpp"
 #include "oops/constantPool.hpp"
 #include "oops/generateOopMap.hpp"
@@ -498,6 +499,12 @@
   // Note: we don't wait until it actually dies.
   os::terminate_signal_thread();
 
+#if INCLUDE_CDS
+  if (DynamicDumpSharedSpaces) {
+    DynamicArchive::dump();
+  }
+#endif
+
   print_statistics();
   Universe::heap()->print_tracing_info();
 
--- a/src/hotspot/share/runtime/mutexLocker.cpp	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/share/runtime/mutexLocker.cpp	Thu May 23 11:07:37 2019 +0100
@@ -153,9 +153,12 @@
 #if INCLUDE_NMT
 Mutex*   NMTQuery_lock                = NULL;
 #endif
-#if INCLUDE_CDS && INCLUDE_JVMTI
+#if INCLUDE_CDS
+#if INCLUDE_JVMTI
 Mutex*   CDSClassFileStream_lock      = NULL;
 #endif
+Mutex*   DumpTimeTable_lock           = NULL;
+#endif // INCLUDE_CDS
 
 #if INCLUDE_JVMCI
 Monitor* JVMCI_lock                   = NULL;
@@ -351,7 +354,8 @@
 #if INCLUDE_NMT
   def(NMTQuery_lock                , PaddedMutex  , max_nonleaf, false, Monitor::_safepoint_check_always);
 #endif
-#if INCLUDE_CDS && INCLUDE_JVMTI
+#if INCLUDE_CDS
+#if INCLUDE_JVMTI
   def(CDSClassFileStream_lock      , PaddedMutex  , max_nonleaf, false, Monitor::_safepoint_check_always);
 #endif
 
@@ -360,6 +364,8 @@
   def(JVMCIGlobalAlloc_lock        , PaddedMutex  , nonleaf,     true,  Monitor::_safepoint_check_never);
   def(JVMCIGlobalActive_lock       , PaddedMutex  , nonleaf-1,   true,  Monitor::_safepoint_check_never);
 #endif
+  def(DumpTimeTable_lock           , PaddedMutex  , leaf,        true,  Monitor::_safepoint_check_never);
+#endif // INCLUDE_CDS
 }
 
 GCMutexLocker::GCMutexLocker(Monitor * mutex) {
--- a/src/hotspot/share/runtime/mutexLocker.hpp	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/share/runtime/mutexLocker.hpp	Thu May 23 11:07:37 2019 +0100
@@ -132,9 +132,12 @@
 #if INCLUDE_NMT
 extern Mutex*   NMTQuery_lock;                   // serialize NMT Dcmd queries
 #endif
-#if INCLUDE_CDS && INCLUDE_JVMTI
+#if INCLUDE_CDS
+#if INCLUDE_JVMTI
 extern Mutex*   CDSClassFileStream_lock;         // FileMapInfo::open_stream_for_jvmti
 #endif
+extern Mutex*   DumpTimeTable_lock;              // SystemDictionaryShared::find_or_allocate_info_for
+#endif // INCLUDE_CDS
 #if INCLUDE_JFR
 extern Mutex*   JfrStacktrace_lock;              // used to guard access to the JFR stacktrace table
 extern Monitor* JfrMsg_lock;                     // protects JFR messaging
--- a/src/hotspot/share/runtime/safepoint.cpp	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/share/runtime/safepoint.cpp	Thu May 23 11:07:37 2019 +0100
@@ -24,6 +24,7 @@
 
 #include "precompiled.hpp"
 #include "classfile/classLoaderDataGraph.inline.hpp"
+#include "classfile/dictionary.hpp"
 #include "classfile/stringTable.hpp"
 #include "classfile/symbolTable.hpp"
 #include "classfile/systemDictionary.hpp"
@@ -66,9 +67,6 @@
 #include "services/runtimeService.hpp"
 #include "utilities/events.hpp"
 #include "utilities/macros.hpp"
-#ifdef COMPILER1
-#include "c1/c1_globals.hpp"
-#endif
 
 static void post_safepoint_begin_event(EventSafepointBegin& event,
                                        uint64_t safepoint_id,
@@ -516,6 +514,8 @@
   if (ObjectSynchronizer::is_cleanup_needed()) return true;
   // Need a safepoint if some inline cache buffers is non-empty
   if (!InlineCacheBuffer::is_empty()) return true;
+  if (StringTable::needs_rehashing()) return true;
+  if (SymbolTable::needs_rehashing()) return true;
   return false;
 }
 
@@ -608,23 +608,27 @@
     }
 
     if (_subtasks.try_claim_task(SafepointSynchronize::SAFEPOINT_CLEANUP_CLD_PURGE)) {
-      // CMS delays purging the CLDG until the beginning of the next safepoint and to
-      // make sure concurrent sweep is done
-      const char* name = "purging class loader data graph";
-      EventSafepointCleanupTask event;
-      TraceTime timer(name, TRACETIME_LOG(Info, safepoint, cleanup));
-      ClassLoaderDataGraph::purge_if_needed();
+      if (ClassLoaderDataGraph::should_purge_and_reset()) {
+        // CMS delays purging the CLDG until the beginning of the next safepoint and to
+        // make sure concurrent sweep is done
+        const char* name = "purging class loader data graph";
+        EventSafepointCleanupTask event;
+        TraceTime timer(name, TRACETIME_LOG(Info, safepoint, cleanup));
+        ClassLoaderDataGraph::purge();
 
-      post_safepoint_cleanup_task_event(event, safepoint_id, name);
+        post_safepoint_cleanup_task_event(event, safepoint_id, name);
+      }
     }
 
     if (_subtasks.try_claim_task(SafepointSynchronize::SAFEPOINT_CLEANUP_SYSTEM_DICTIONARY_RESIZE)) {
-      const char* name = "resizing system dictionaries";
-      EventSafepointCleanupTask event;
-      TraceTime timer(name, TRACETIME_LOG(Info, safepoint, cleanup));
-      ClassLoaderDataGraph::resize_if_needed();
+      if (Dictionary::does_any_dictionary_needs_resizing()) {
+        const char* name = "resizing system dictionaries";
+        EventSafepointCleanupTask event;
+        TraceTime timer(name, TRACETIME_LOG(Info, safepoint, cleanup));
+        ClassLoaderDataGraph::resize_dictionaries();
 
-      post_safepoint_cleanup_task_event(event, safepoint_id, name);
+        post_safepoint_cleanup_task_event(event, safepoint_id, name);
+      }
     }
 
     _subtasks.all_tasks_completed(_num_workers);
--- a/src/hotspot/share/runtime/stackValue.cpp	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/share/runtime/stackValue.cpp	Thu May 23 11:07:37 2019 +0100
@@ -32,6 +32,9 @@
 #if INCLUDE_ZGC
 #include "gc/z/zBarrier.inline.hpp"
 #endif
+#if INCLUDE_SHENANDOAHGC
+#include "gc/shenandoah/shenandoahBarrierSet.hpp"
+#endif
 
 StackValue* StackValue::create_stack_value(const frame* fr, const RegisterMap* reg_map, ScopeValue* sv) {
   if (sv->is_location()) {
@@ -106,8 +109,15 @@
       } else {
         value.noop = *(narrowOop*) value_addr;
       }
-      // Decode narrowoop and wrap a handle around the oop
-      Handle h(Thread::current(), CompressedOops::decode(value.noop));
+      // Decode narrowoop
+      oop val = CompressedOops::decode(value.noop);
+      // Deoptimization must make sure all oops have passed load barriers
+#if INCLUDE_SHENANDOAHGC
+      if (UseShenandoahGC) {
+        val = ShenandoahBarrierSet::barrier_set()->load_reference_barrier(val);
+      }
+#endif
+      Handle h(Thread::current(), val); // Wrap a handle around the oop
       return new StackValue(h);
     }
 #endif
@@ -122,13 +132,17 @@
          val = (oop)NULL;
       }
 #endif
+      // Deoptimization must make sure all oops have passed load barriers
 #if INCLUDE_ZGC
-      // Deoptimization must make sure all oop have passed load barrier
       if (UseZGC) {
         val = ZBarrier::load_barrier_on_oop_field_preloaded((oop*)value_addr, val);
       }
 #endif
-
+#if INCLUDE_SHENANDOAHGC
+      if (UseShenandoahGC) {
+        val = ShenandoahBarrierSet::barrier_set()->load_reference_barrier(val);
+      }
+#endif
       Handle h(Thread::current(), val); // Wrap a handle around the oop
       return new StackValue(h);
     }
--- a/src/hotspot/share/runtime/stubCodeGenerator.cpp	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/share/runtime/stubCodeGenerator.cpp	Thu May 23 11:07:37 2019 +0100
@@ -60,7 +60,7 @@
   st->print("%s", group());
   st->print("::");
   st->print("%s", name());
-  st->print(" [" INTPTR_FORMAT ", " INTPTR_FORMAT "[ (%d bytes)", p2i(begin()), p2i(end()), size_in_bytes());
+  st->print(" [" INTPTR_FORMAT ", " INTPTR_FORMAT "] (%d bytes)", p2i(begin()), p2i(end()), size_in_bytes());
 }
 
 void StubCodeDesc::print() const { print_on(tty); }
@@ -98,9 +98,12 @@
     // of this stub.
     offset = cdesc->begin() - outer_cbuf->insts()->start();
 #endif
-    cdesc->print();
+    ttyLocker ttyl;
+    tty->print_cr("- - - [BEGIN] - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
+    cdesc->print_on(tty);
     tty->cr();
-    Disassembler::decode(cdesc->begin(), cdesc->end(), NULL, cs, offset);
+    Disassembler::decode(cdesc->begin(), cdesc->end(), tty, cs /*, offset */);
+    tty->print_cr("- - - [END] - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
     tty->cr();
   }
 }
--- a/src/hotspot/share/runtime/thread.cpp	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/share/runtime/thread.cpp	Thu May 23 11:07:37 2019 +0100
@@ -1613,7 +1613,6 @@
   set_deopt_compiled_method(NULL);
   clear_must_deopt_id();
   set_monitor_chunks(NULL);
-  set_next(NULL);
   _on_thread_list = false;
   set_thread_state(_thread_new);
   _terminated = _not_terminated;
@@ -3457,7 +3456,6 @@
 // would like. We are actively migrating Threads_lock uses to other
 // mechanisms in order to reduce Threads_lock contention.
 
-JavaThread* Threads::_thread_list = NULL;
 int         Threads::_number_of_threads = 0;
 int         Threads::_number_of_non_daemon_threads = 0;
 int         Threads::_return_code = 0;
@@ -3764,7 +3762,6 @@
   }
 
   // Initialize Threads state
-  _thread_list = NULL;
   _number_of_threads = 0;
   _number_of_non_daemon_threads = 0;
 
@@ -3964,10 +3961,8 @@
   SystemDictionary::compute_java_loaders(CHECK_JNI_ERR);
 
 #if INCLUDE_CDS
-  if (DumpSharedSpaces) {
-    // capture the module path info from the ModuleEntryTable
-    ClassLoader::initialize_module_path(THREAD);
-  }
+  // capture the module path info from the ModuleEntryTable
+  ClassLoader::initialize_module_path(THREAD);
 #endif
 
 #if INCLUDE_JVMCI
@@ -4169,7 +4164,7 @@
   for (agent = Arguments::agents(); agent != NULL; agent = agent->next()) {
     // CDS dumping does not support native JVMTI agent.
     // CDS dumping supports Java agent if the AllowArchivingWithJavaAgent diagnostic option is specified.
-    if (DumpSharedSpaces) {
+    if (DumpSharedSpaces || DynamicDumpSharedSpaces) {
       if(!agent->is_instrument_lib()) {
         vm_exit_during_cds_dumping("CDS dumping does not support native JVMTI agent, name", agent->name());
       } else if (!AllowArchivingWithJavaAgent) {
@@ -4425,9 +4420,6 @@
 
   BarrierSet::barrier_set()->on_thread_attach(p);
 
-  p->set_next(_thread_list);
-  _thread_list = p;
-
   // Once a JavaThread is added to the Threads list, smr_delete() has
   // to be used to delete it. Otherwise we can just delete it directly.
   p->set_on_thread_list();
@@ -4465,20 +4457,6 @@
     // Maintain fast thread list
     ThreadsSMRSupport::remove_thread(p);
 
-    JavaThread* current = _thread_list;
-    JavaThread* prev    = NULL;
-
-    while (current != p) {
-      prev    = current;
-      current = current->next();
-    }
-
-    if (prev) {
-      prev->set_next(current->next());
-    } else {
-      _thread_list = p->next();
-    }
-
     _number_of_threads--;
     if (!is_daemon) {
       _number_of_non_daemon_threads--;
--- a/src/hotspot/share/runtime/thread.hpp	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/share/runtime/thread.hpp	Thu May 23 11:07:37 2019 +0100
@@ -983,7 +983,6 @@
   friend class JVMCIVMStructs;
   friend class WhiteBox;
  private:
-  JavaThread*    _next;                          // The next thread in the Threads list
   bool           _on_thread_list;                // Is set when this JavaThread is added to the Threads list
   oop            _threadObj;                     // The Java level thread object
 
@@ -1247,10 +1246,6 @@
   virtual bool is_Java_thread() const            { return true;  }
   virtual bool can_call_java() const             { return true; }
 
-  // Thread chain operations
-  JavaThread* next() const                       { return _next; }
-  void set_next(JavaThread* p)                   { _next = p; }
-
   // Thread oop. threadObj() can be NULL for initial JavaThread
   // (or for threads attached via JNI)
   oop threadObj() const                          { return _threadObj; }
@@ -2213,7 +2208,6 @@
 class Threads: AllStatic {
   friend class VMStructs;
  private:
-  static JavaThread* _thread_list;
   static int         _number_of_threads;
   static int         _number_of_non_daemon_threads;
   static int         _return_code;
--- a/src/hotspot/share/runtime/threadSMR.hpp	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/share/runtime/threadSMR.hpp	Thu May 23 11:07:37 2019 +0100
@@ -86,6 +86,7 @@
 // SMR Support for the Threads class.
 //
 class ThreadsSMRSupport : AllStatic {
+  friend class VMStructs;
   friend class SafeThreadsListPtr;  // for _nested_thread_list_max, delete_notify(), release_stable_list_wake_up() access
 
   // The coordination between ThreadsSMRSupport::release_stable_list() and
@@ -158,6 +159,7 @@
 // A fast list of JavaThreads.
 //
 class ThreadsList : public CHeapObj<mtThread> {
+  friend class VMStructs;
   friend class SafeThreadsListPtr;  // for {dec,inc}_nested_handle_cnt() access
   friend class ThreadsSMRSupport;  // for _nested_handle_cnt, {add,remove}_thread(), {,set_}next_list() access
 
--- a/src/hotspot/share/runtime/tieredThresholdPolicy.cpp	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/share/runtime/tieredThresholdPolicy.cpp	Thu May 23 11:07:37 2019 +0100
@@ -238,7 +238,7 @@
       // Lower the compiler count such that all buffers fit into the code cache
       count = MAX2(max_count, c1_only ? 1 : 2);
     }
-    FLAG_SET_ERGO(intx, CICompilerCount, count);
+    FLAG_SET_ERGO(CICompilerCount, count);
   }
 #else
   // On 32-bit systems, the number of compiler threads is limited to 3.
@@ -250,7 +250,7 @@
   /// available to the VM and thus cause the VM to crash.
   if (FLAG_IS_DEFAULT(CICompilerCount)) {
     count = 3;
-    FLAG_SET_ERGO(intx, CICompilerCount, count);
+    FLAG_SET_ERGO(CICompilerCount, count);
   }
 #endif
 
--- a/src/hotspot/share/runtime/vmStructs.cpp	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/share/runtime/vmStructs.cpp	Thu May 23 11:07:37 2019 +0100
@@ -94,6 +94,7 @@
 #include "runtime/sharedRuntime.hpp"
 #include "runtime/stubRoutines.hpp"
 #include "runtime/thread.inline.hpp"
+#include "runtime/threadSMR.hpp"
 #include "runtime/vframeArray.hpp"
 #include "runtime/vmStructs.hpp"
 #include "utilities/globalDefinitions.hpp"
@@ -740,10 +741,13 @@
   /* Threads (NOTE: incomplete) */                                                                                                   \
   /******************************/                                                                                                   \
                                                                                                                                      \
-     static_field(Threads,                     _thread_list,                                  JavaThread*)                           \
-     static_field(Threads,                     _number_of_threads,                            int)                                   \
-     static_field(Threads,                     _number_of_non_daemon_threads,                 int)                                   \
-     static_field(Threads,                     _return_code,                                  int)                                   \
+  static_field(Threads,                     _number_of_threads,                               int)                                   \
+  static_field(Threads,                     _number_of_non_daemon_threads,                    int)                                   \
+  static_field(Threads,                     _return_code,                                     int)                                   \
+                                                                                                                                     \
+  static_ptr_volatile_field(ThreadsSMRSupport, _java_thread_list,                             ThreadsList*)                          \
+  nonstatic_field(ThreadsList,                 _length,                                       const uint)                            \
+  nonstatic_field(ThreadsList,                 _threads,                                      JavaThread *const *const)              \
                                                                                                                                      \
   nonstatic_field(ThreadShadow,                _pending_exception,                            oop)                                   \
   nonstatic_field(ThreadShadow,                _exception_file,                               const char*)                           \
@@ -757,7 +761,6 @@
   nonstatic_field(Thread,                      _current_waiting_monitor,                      ObjectMonitor*)                        \
   nonstatic_field(NamedThread,                 _name,                                         char*)                                 \
   nonstatic_field(NamedThread,                 _processed_thread,                             JavaThread*)                           \
-  nonstatic_field(JavaThread,                  _next,                                         JavaThread*)                           \
   nonstatic_field(JavaThread,                  _threadObj,                                    oop)                                   \
   nonstatic_field(JavaThread,                  _anchor,                                       JavaFrameAnchor)                       \
   nonstatic_field(JavaThread,                  _vm_result,                                    oop)                                   \
@@ -1371,6 +1374,9 @@
   declare_toplevel_type(OSThread)                                         \
   declare_toplevel_type(JavaFrameAnchor)                                  \
                                                                           \
+  declare_toplevel_type(ThreadsSMRSupport)                                \
+  declare_toplevel_type(ThreadsList)                                      \
+                                                                          \
   /***************/                                                       \
   /* Interpreter */                                                       \
   /***************/                                                       \
@@ -1964,6 +1970,7 @@
   declare_toplevel_type(intptr_t*)                                        \
    declare_unsigned_integer_type(InvocationCounter) /* FIXME: wrong type (not integer) */ \
   declare_toplevel_type(JavaThread*)                                      \
+  declare_toplevel_type(JavaThread *const *const)                         \
   declare_toplevel_type(java_lang_Class)                                  \
   declare_integer_type(JavaThread::AsyncRequests)                         \
   declare_integer_type(JavaThread::TerminatedTypes)                       \
--- a/src/hotspot/share/utilities/events.cpp	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/share/utilities/events.cpp	Thu May 23 11:07:37 2019 +0100
@@ -108,7 +108,8 @@
   int index = compute_log_index();
   _records[index].thread = thread;
   _records[index].timestamp = timestamp;
-  stringStream st = _records[index].data.stream();
+  stringStream st(_records[index].data.buffer(),
+                  _records[index].data.size());
   st.print("Unloading class " INTPTR_FORMAT " ", p2i(ik));
   ik->name()->print_value_on(&st);
 }
@@ -121,7 +122,8 @@
   int index = compute_log_index();
   _records[index].thread = thread;
   _records[index].timestamp = timestamp;
-  stringStream st = _records[index].data.stream();
+  stringStream st(_records[index].data.buffer(),
+                  _records[index].data.size());
   st.print("Exception <");
   h_exception->print_value_on(&st);
   st.print("%s%s> (" INTPTR_FORMAT ") \n"
--- a/src/hotspot/share/utilities/events.hpp	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/share/utilities/events.hpp	Thu May 23 11:07:37 2019 +0100
@@ -137,11 +137,6 @@
 // A simple wrapper class for fixed size text messages.
 template <size_t bufsz>
 class FormatStringLogMessage : public FormatBuffer<bufsz> {
- public:
-  // Wrap this buffer in a stringStream.
-  stringStream stream() {
-    return stringStream(this->_buf, this->size());
-  }
 };
 typedef FormatStringLogMessage<256> StringLogMessage;
 typedef FormatStringLogMessage<512> ExtendedStringLogMessage;
--- a/src/hotspot/share/utilities/exceptions.cpp	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/share/utilities/exceptions.cpp	Thu May 23 11:07:37 2019 +0100
@@ -526,17 +526,17 @@
 }
 
 // for logging exceptions
-void Exceptions::log_exception(Handle exception, stringStream tempst) {
+void Exceptions::log_exception(Handle exception, const char* message) {
   ResourceMark rm;
-  Symbol* message = java_lang_Throwable::detail_message(exception());
-  if (message != NULL) {
+  Symbol* detail_message = java_lang_Throwable::detail_message(exception());
+  if (detail_message != NULL) {
     log_info(exceptions)("Exception <%s: %s>\n thrown in %s",
                          exception->print_value_string(),
-                         message->as_C_string(),
-                         tempst.as_string());
+                         detail_message->as_C_string(),
+                         message);
   } else {
     log_info(exceptions)("Exception <%s>\n thrown in %s",
                          exception->print_value_string(),
-                         tempst.as_string());
+                         message);
   }
 }
--- a/src/hotspot/share/utilities/exceptions.hpp	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/share/utilities/exceptions.hpp	Thu May 23 11:07:37 2019 +0100
@@ -186,7 +186,7 @@
   static void debug_check_abort(const char *value_string, const char* message = NULL);
 
   // for logging exceptions
-  static void log_exception(Handle exception, stringStream tempst);
+  static void log_exception(Handle exception, const char* message);
 };
 
 
--- a/src/hotspot/share/utilities/globalDefinitions.hpp	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/share/utilities/globalDefinitions.hpp	Thu May 23 11:07:37 2019 +0100
@@ -43,6 +43,26 @@
 #define ATTRIBUTE_ALIGNED(x)
 #endif
 
+// These are #defines to selectively turn on/off the Print(Opto)Assembly
+// capabilities. Choices should be led by a tradeoff between
+// code size and improved supportability.
+// if PRINT_ASSEMBLY then PRINT_ABSTRACT_ASSEMBLY must be true as well
+// to have a fallback in case hsdis is not available.
+#if defined(PRODUCT)
+  #define SUPPORT_ABSTRACT_ASSEMBLY
+  #define SUPPORT_ASSEMBLY
+  #undef  SUPPORT_OPTO_ASSEMBLY      // Can't activate. In PRODUCT, many dump methods are missing.
+  #undef  SUPPORT_DATA_STRUCTS       // Of limited use. In PRODUCT, many print methods are empty.
+#else
+  #define SUPPORT_ABSTRACT_ASSEMBLY
+  #define SUPPORT_ASSEMBLY
+  #define SUPPORT_OPTO_ASSEMBLY
+  #define SUPPORT_DATA_STRUCTS
+#endif
+#if defined(SUPPORT_ASSEMBLY) && !defined(SUPPORT_ABSTRACT_ASSEMBLY)
+  #define SUPPORT_ABSTRACT_ASSEMBLY
+#endif
+
 // This file holds all globally used constants & types, class (forward)
 // declarations and a few frequently used utility functions.
 
--- a/src/hotspot/share/utilities/ostream.cpp	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/share/utilities/ostream.cpp	Thu May 23 11:07:37 2019 +0100
@@ -309,10 +309,9 @@
 
 stringStream::stringStream(size_t initial_size) : outputStream() {
   buffer_length = initial_size;
-  buffer        = NEW_RESOURCE_ARRAY(char, buffer_length);
+  buffer        = NEW_C_HEAP_ARRAY(char, buffer_length, mtInternal);
   buffer_pos    = 0;
   buffer_fixed  = false;
-  DEBUG_ONLY(rm = Thread::current()->current_resource_mark();)
 }
 
 // useful for output to fixed chunks of memory, such as performance counters
@@ -337,15 +336,7 @@
       if (end < buffer_length * 2) {
         end = buffer_length * 2;
       }
-      char* oldbuf = buffer;
-      assert(rm == NULL || Thread::current()->current_resource_mark() == rm,
-             "StringStream is re-allocated with a different ResourceMark. Current: "
-             PTR_FORMAT " original: " PTR_FORMAT,
-             p2i(Thread::current()->current_resource_mark()), p2i(rm));
-      buffer = NEW_RESOURCE_ARRAY(char, end);
-      if (buffer_pos > 0) {
-        memcpy(buffer, oldbuf, buffer_pos);
-      }
+      buffer = REALLOC_C_HEAP_ARRAY(char, buffer, end, mtInternal);
       buffer_length = end;
     }
   }
@@ -370,7 +361,11 @@
   return copy;
 }
 
-stringStream::~stringStream() {}
+stringStream::~stringStream() {
+  if (buffer_fixed == false && buffer != NULL) {
+    FREE_C_HEAP_ARRAY(char, buffer);
+  }
+}
 
 xmlStream*   xtty;
 outputStream* tty;
--- a/src/hotspot/share/utilities/ostream.hpp	Fri May 17 13:21:44 2019 +0100
+++ b/src/hotspot/share/utilities/ostream.hpp	Thu May 23 11:07:37 2019 +0100
@@ -42,6 +42,10 @@
 // This allows for redirection via -XX:+DisplayVMOutputToStdout and
 // -XX:+DisplayVMOutputToStderr
 class outputStream : public ResourceObj {
+ private:
+   outputStream(const outputStream&);
+   outputStream& operator=(const outputStream&);
+
  protected:
    int _indentation; // current indentation
    int _width;       // width of the page
@@ -186,19 +190,25 @@
   }
 };
 
-// for writing to strings; buffer will expand automatically
+// for writing to strings; buffer will expand automatically.
+// Buffer will always be zero-terminated.
 class stringStream : public outputStream {
  protected:
   char*  buffer;
   size_t buffer_pos;
   size_t buffer_length;
   bool   buffer_fixed;
-  DEBUG_ONLY(ResourceMark* rm;)
  public:
+  // Create a stringStream using an internal buffer of initially initial_bufsize size;
+  // will be enlarged on demand. There is no maximum cap.
   stringStream(size_t initial_bufsize = 256);
+  // Creates a stringStream using a caller-provided buffer. Will truncate silently if
+  // it overflows.
   stringStream(char* fixed_buffer, size_t fixed_buffer_size);
   ~stringStream();
   virtual void write(const char* c, size_t len);
+  // Return number of characters written into buffer, excluding terminating zero and
+  // subject to truncation in static buffer mode.
   size_t      size() { return buffer_pos; }
   const char* base() { return buffer; }
   void  reset() { buffer_pos = 0; _precount = 0; _position = 0; }
--- a/src/java.base/share/classes/java/io/BufferedInputStream.java	Fri May 17 13:21:44 2019 +0100
+++ b/src/java.base/share/classes/java/io/BufferedInputStream.java	Thu May 23 11:07:37 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1994, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1994, 2019, 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
@@ -26,6 +26,7 @@
 package java.io;
 
 import jdk.internal.misc.Unsafe;
+import jdk.internal.util.ArraysSupport;
 
 /**
  * A <code>BufferedInputStream</code> adds
@@ -54,14 +55,6 @@
     private static int DEFAULT_BUFFER_SIZE = 8192;
 
     /**
-     * The maximum size of array to allocate.
-     * Some VMs reserve some header words in an array.
-     * Attempts to allocate larger arrays may result in
-     * OutOfMemoryError: Requested array size exceeds VM limit
-     */
-    private static int MAX_BUFFER_SIZE = Integer.MAX_VALUE - 8;
-
-    /**
      * As this class is used early during bootstrap, it's motivated to use
      * Unsafe.compareAndSetObject instead of AtomicReferenceFieldUpdater
      * (or VarHandles) to reduce dependencies and improve startup time.
@@ -220,7 +213,7 @@
         byte[] buffer = getBufIfOpen();
         if (markpos < 0)
             pos = 0;            /* no mark: throw away the buffer */
-        else if (pos >= buffer.length)  /* no room left in buffer */
+        else if (pos >= buffer.length) { /* no room left in buffer */
             if (markpos > 0) {  /* can throw away early part of the buffer */
                 int sz = pos - markpos;
                 System.arraycopy(buffer, markpos, buffer, 0, sz);
@@ -229,11 +222,10 @@
             } else if (buffer.length >= marklimit) {
                 markpos = -1;   /* buffer got too big, invalidate mark */
                 pos = 0;        /* drop buffer contents */
-            } else if (buffer.length >= MAX_BUFFER_SIZE) {
-                throw new OutOfMemoryError("Required array size too large");
             } else {            /* grow buffer */
-                int nsz = (pos <= MAX_BUFFER_SIZE - pos) ?
-                        pos * 2 : MAX_BUFFER_SIZE;
+                int nsz = ArraysSupport.newLength(pos,
+                        1,  /* minimum growth */
+                        pos /* preferred growth */);
                 if (nsz > marklimit)
                     nsz = marklimit;
                 byte[] nbuf = new byte[nsz];
@@ -248,6 +240,7 @@
                 }
                 buffer = nbuf;
             }
+        }
         count = pos;
         int n = getInIfOpen().read(buffer, pos, buffer.length - pos);
         if (n > 0)
--- a/src/java.base/share/classes/java/io/ByteArrayOutputStream.java	Fri May 17 13:21:44 2019 +0100
+++ b/src/java.base/share/classes/java/io/ByteArrayOutputStream.java	Thu May 23 11:07:37 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1994, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1994, 2019, 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
@@ -29,6 +29,8 @@
 import java.util.Arrays;
 import java.util.Objects;
 
+import jdk.internal.util.ArraysSupport;
+
 /**
  * This class implements an output stream in which the data is
  * written into a byte array. The buffer automatically grows as data
@@ -84,48 +86,20 @@
      * at least the number of elements specified by the minimum
      * capacity argument.
      *
-     * @param  minCapacity the desired minimum capacity
-     * @throws OutOfMemoryError if {@code minCapacity < 0}.  This is
-     * interpreted as a request for the unsatisfiably large capacity
+     * @param  minCapacity the desired minimum capacity.
+     * @throws OutOfMemoryError if {@code minCapacity < 0} and
+     * {@code minCapacity - buf.length > 0}.  This is interpreted as a
+     * request for the unsatisfiably large capacity.
      * {@code (long) Integer.MAX_VALUE + (minCapacity - Integer.MAX_VALUE)}.
      */
     private void ensureCapacity(int minCapacity) {
         // overflow-conscious code
-        if (minCapacity - buf.length > 0)
-            grow(minCapacity);
-    }
-
-    /**
-     * The maximum size of array to allocate.
-     * Some VMs reserve some header words in an array.
-     * Attempts to allocate larger arrays may result in
-     * OutOfMemoryError: Requested array size exceeds VM limit
-     */
-    private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
-
-    /**
-     * Increases the capacity to ensure that it can hold at least the
-     * number of elements specified by the minimum capacity argument.
-     *
-     * @param minCapacity the desired minimum capacity
-     */
-    private void grow(int minCapacity) {
-        // overflow-conscious code
         int oldCapacity = buf.length;
-        int newCapacity = oldCapacity << 1;
-        if (newCapacity - minCapacity < 0)
-            newCapacity = minCapacity;
-        if (newCapacity - MAX_ARRAY_SIZE > 0)
-            newCapacity = hugeCapacity(minCapacity);
-        buf = Arrays.copyOf(buf, newCapacity);
-    }
-
-    private static int hugeCapacity(int minCapacity) {
-        if (minCapacity < 0) // overflow
-            throw new OutOfMemoryError();
-        return (minCapacity > MAX_ARRAY_SIZE) ?
-            Integer.MAX_VALUE :
-            MAX_ARRAY_SIZE;
+        int minGrowth = minCapacity - oldCapacity;
+        if (minGrowth > 0) {
+            buf = Arrays.copyOf(buf, ArraysSupport.newLength(oldCapacity,
+                    minGrowth, oldCapacity /* preferred growth */));
+        }
     }
 
     /**
--- a/src/java.base/share/classes/java/io/ObjectInputFilter.java	Fri May 17 13:21:44 2019 +0100
+++ b/src/java.base/share/classes/java/io/ObjectInputFilter.java	Thu May 23 11:07:37 2019 +0100
@@ -283,7 +283,7 @@
         /**
          * Current configured filter.
          */
-        private static ObjectInputFilter serialFilter = configuredFilter;
+        private static volatile ObjectInputFilter serialFilter = configuredFilter;
 
         /**
          * Returns the system-wide serialization filter or {@code null} if not configured.
@@ -291,9 +291,7 @@
          * @return the system-wide serialization filter or {@code null} if not configured
          */
         public static ObjectInputFilter getSerialFilter() {
-            synchronized (serialFilterLock) {
-                return serialFilter;
-            }
+            return serialFilter;
         }
 
         /**
--- a/src/java.base/share/classes/java/lang/Byte.java	Fri May 17 13:21:44 2019 +0100
+++ b/src/java.base/share/classes/java/lang/Byte.java	Thu May 23 11:07:37 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2019, 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
@@ -356,7 +356,7 @@
     /**
      * Returns the value of this {@code Byte} as a {@code short} after
      * a widening primitive conversion.
-     * @jls 5.1.2 Widening Primitive Conversions
+     * @jls 5.1.2 Widening Primitive Conversion
      */
     public short shortValue() {
         return (short)value;
@@ -365,7 +365,7 @@
     /**
      * Returns the value of this {@code Byte} as an {@code int} after
      * a widening primitive conversion.
-     * @jls 5.1.2 Widening Primitive Conversions
+     * @jls 5.1.2 Widening Primitive Conversion
      */
     public int intValue() {
         return (int)value;
@@ -374,7 +374,7 @@
     /**
      * Returns the value of this {@code Byte} as a {@code long} after
      * a widening primitive conversion.
-     * @jls 5.1.2 Widening Primitive Conversions
+     * @jls 5.1.2 Widening Primitive Conversion
      */
     public long longValue() {
         return (long)value;
@@ -383,7 +383,7 @@
     /**
      * Returns the value of this {@code Byte} as a {@code float} after
      * a widening primitive conversion.
-     * @jls 5.1.2 Widening Primitive Conversions
+     * @jls 5.1.2 Widening Primitive Conversion
      */
     public float floatValue() {
         return (float)value;
@@ -392,7 +392,7 @@
     /**
      * Returns the value of this {@code Byte} as a {@code double}
      * after a widening primitive conversion.
-     * @jls 5.1.2 Widening Primitive Conversions
+     * @jls 5.1.2 Widening Primitive Conversion
      */
     public double doubleValue() {
         return (double)value;
--- a/src/java.base/share/classes/java/lang/Class.java	Fri May 17 13:21:44 2019 +0100
+++ b/src/java.base/share/classes/java/lang/Class.java	Thu May 23 11:07:37 2019 +0100
@@ -999,7 +999,7 @@
      *
      * @since 9
      * @spec JPMS
-     * @jls 6.7  Fully Qualified Names
+     * @jls 6.7 Fully Qualified Names
      */
     public String getPackageName() {
         String pn = this.packageName;
@@ -3910,7 +3910,8 @@
      *         SecurityManager#checkPackageAccess s.checkPackageAccess()}
      *         denies access to the package of the returned class
      * @since 11
-     * @jvms 4.7.28 and 4.7.29 NestHost and NestMembers attributes
+     * @jvms 4.7.28 The {@code NestHost} Attribute
+     * @jvms 4.7.29 The {@code NestMembers} Attribute
      * @jvms 5.4.4 Access Control
      */
     @CallerSensitive
--- a/src/java.base/share/classes/java/lang/ClassLoader.java	Fri May 17 13:21:44 2019 +0100
+++ b/src/java.base/share/classes/java/lang/ClassLoader.java	Thu May 23 11:07:37 2019 +0100
@@ -222,7 +222,7 @@
  * or a fully qualified name as defined by
  * <cite>The Java&trade; Language Specification</cite>.
  *
- * @jls 6.7  Fully Qualified Names
+ * @jls 6.7 Fully Qualified Names
  * @jls 13.1 The Form of a Binary
  * @see      #resolveClass(Class)
  * @since 1.0
@@ -2194,7 +2194,7 @@
      * @revised 9
      * @spec JPMS
      *
-     * @jvms 5.3 Run-time package
+     * @jvms 5.3 Creation and Loading
      * @see <a href="{@docRoot}/../specs/jar/jar.html#package-sealing">
      *      The JAR File Specification: Package Sealing</a>
      */
@@ -2228,7 +2228,7 @@
      * @throws  NullPointerException
      *          if {@code name} is {@code null}.
      *
-     * @jvms 5.3 Run-time package
+     * @jvms 5.3 Creation and Loading
      *
      * @since  9
      * @spec JPMS
@@ -2255,7 +2255,7 @@
      *         this class loader; or an zero length array if no package has been
      *         defined by this class loader.
      *
-     * @jvms 5.3 Run-time package
+     * @jvms 5.3 Creation and Loading
      *
      * @since  9
      * @spec JPMS
--- a/src/java.base/share/classes/java/lang/Double.java	Fri May 17 13:21:44 2019 +0100
+++ b/src/java.base/share/classes/java/lang/Double.java	Thu May 23 11:07:37 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1994, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1994, 2019, 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
@@ -673,7 +673,7 @@
      *
      * @return  the {@code double} value represented by this object
      *          converted to type {@code byte}
-     * @jls 5.1.3 Narrowing Primitive Conversions
+     * @jls 5.1.3 Narrowing Primitive Conversion
      * @since 1.1
      */
     public byte byteValue() {
@@ -686,7 +686,7 @@
      *
      * @return  the {@code double} value represented by this object
      *          converted to type {@code short}
-     * @jls 5.1.3 Narrowing Primitive Conversions
+     * @jls 5.1.3 Narrowing Primitive Conversion
      * @since 1.1
      */
     public short shortValue() {
@@ -696,7 +696,7 @@
     /**
      * Returns the value of this {@code Double} as an {@code int}
      * after a narrowing primitive conversion.
-     * @jls 5.1.3 Narrowing Primitive Conversions
+     * @jls 5.1.3 Narrowing Primitive Conversion
      *
      * @return  the {@code double} value represented by this object
      *          converted to type {@code int}
@@ -711,7 +711,7 @@
      *
      * @return  the {@code double} value represented by this object
      *          converted to type {@code long}
-     * @jls 5.1.3 Narrowing Primitive Conversions
+     * @jls 5.1.3 Narrowing Primitive Conversion
      */
     public long longValue() {
         return (long)value;
@@ -723,7 +723,7 @@
      *
      * @return  the {@code double} value represented by this object
      *          converted to type {@code float}
-     * @jls 5.1.3 Narrowing Primitive Conversions
+     * @jls 5.1.3 Narrowing Primitive Conversion
      * @since 1.0
      */
     public float floatValue() {
--- a/src/java.base/share/classes/java/lang/Float.java	Fri May 17 13:21:44 2019 +0100
+++ b/src/java.base/share/classes/java/lang/Float.java	Thu May 23 11:07:37 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1994, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1994, 2019, 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
@@ -602,7 +602,7 @@
      *
      * @return  the {@code float} value represented by this object
      *          converted to type {@code byte}
-     * @jls 5.1.3 Narrowing Primitive Conversions
+     * @jls 5.1.3 Narrowing Primitive Conversion
      */
     public byte byteValue() {
         return (byte)value;
@@ -614,7 +614,7 @@
      *
      * @return  the {@code float} value represented by this object
      *          converted to type {@code short}
-     * @jls 5.1.3 Narrowing Primitive Conversions
+     * @jls 5.1.3 Narrowing Primitive Conversion
      * @since 1.1
      */
     public short shortValue() {
@@ -627,7 +627,7 @@
      *
      * @return  the {@code float} value represented by this object
      *          converted to type {@code int}
-     * @jls 5.1.3 Narrowing Primitive Conversions
+     * @jls 5.1.3 Narrowing Primitive Conversion
      */
     public int intValue() {
         return (int)value;
@@ -639,7 +639,7 @@
      *
      * @return  the {@code float} value represented by this object
      *          converted to type {@code long}
-     * @jls 5.1.3 Narrowing Primitive Conversions
+     * @jls 5.1.3 Narrowing Primitive Conversion
      */
     public long longValue() {
         return (long)value;
@@ -661,7 +661,7 @@
      *
      * @return the {@code float} value represented by this
      *         object converted to type {@code double}
-     * @jls 5.1.2 Widening Primitive Conversions
+     * @jls 5.1.2 Widening Primitive Conversion
      */
     public double doubleValue() {
         return (double)value;
--- a/src/java.base/share/classes/java/lang/FunctionalInterface.java	Fri May 17 13:21:44 2019 +0100
+++ b/src/java.base/share/classes/java/lang/FunctionalInterface.java	Thu May 23 11:07:37 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2019, 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
@@ -57,7 +57,7 @@
  * regardless of whether or not a {@code FunctionalInterface}
  * annotation is present on the interface declaration.
  *
- * @jls 4.3.2. The Class Object
+ * @jls 4.3.2 The Class Object
  * @jls 9.8 Functional Interfaces
  * @jls 9.4.3 Interface Method Body
  * @jls 9.6.4.9 @FunctionalInterface
--- a/src/java.base/share/classes/java/lang/Integer.java	Fri May 17 13:21:44 2019 +0100
+++ b/src/java.base/share/classes/java/lang/Integer.java	Thu May 23 11:07:37 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1994, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1994, 2019, 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
@@ -1120,7 +1120,7 @@
     /**
      * Returns the value of this {@code Integer} as a {@code byte}
      * after a narrowing primitive conversion.
-     * @jls 5.1.3 Narrowing Primitive Conversions
+     * @jls 5.1.3 Narrowing Primitive Conversion
      */
     public byte byteValue() {
         return (byte)value;
@@ -1129,7 +1129,7 @@
     /**
      * Returns the value of this {@code Integer} as a {@code short}
      * after a narrowing primitive conversion.
-     * @jls 5.1.3 Narrowing Primitive Conversions
+     * @jls 5.1.3 Narrowing Primitive Conversion
      */
     public short shortValue() {
         return (short)value;
@@ -1147,7 +1147,7 @@
     /**
      * Returns the value of this {@code Integer} as a {@code long}
      * after a widening primitive conversion.
-     * @jls 5.1.2 Widening Primitive Conversions
+     * @jls 5.1.2 Widening Primitive Conversion
      * @see Integer#toUnsignedLong(int)
      */
     public long longValue() {
@@ -1157,7 +1157,7 @@
     /**
      * Returns the value of this {@code Integer} as a {@code float}
      * after a widening primitive conversion.
-     * @jls 5.1.2 Widening Primitive Conversions
+     * @jls 5.1.2 Widening Primitive Conversion
      */
     public float floatValue() {
         return (float)value;
@@ -1166,7 +1166,7 @@
     /**
      * Returns the value of this {@code Integer} as a {@code double}
      * after a widening primitive conversion.
-     * @jls 5.1.2 Widening Primitive Conversions
+     * @jls 5.1.2 Widening Primitive Conversion
      */
     public double doubleValue() {
         return (double)value;
--- a/src/java.base/share/classes/java/lang/Long.java	Fri May 17 13:21:44 2019 +0100
+++ b/src/java.base/share/classes/java/lang/Long.java	Thu May 23 11:07:37 2019 +0100
@@ -1339,7 +1339,7 @@
     /**
      * Returns the value of this {@code Long} as a {@code byte} after
      * a narrowing primitive conversion.
-     * @jls 5.1.3 Narrowing Primitive Conversions
+     * @jls 5.1.3 Narrowing Primitive Conversion
      */
     public byte byteValue() {
         return (byte)value;
@@ -1348,7 +1348,7 @@
     /**
      * Returns the value of this {@code Long} as a {@code short} after
      * a narrowing primitive conversion.
-     * @jls 5.1.3 Narrowing Primitive Conversions
+     * @jls 5.1.3 Narrowing Primitive Conversion
      */
     public short shortValue() {
         return (short)value;
@@ -1357,7 +1357,7 @@
     /**
      * Returns the value of this {@code Long} as an {@code int} after
      * a narrowing primitive conversion.
-     * @jls 5.1.3 Narrowing Primitive Conversions
+     * @jls 5.1.3 Narrowing Primitive Conversion
      */
     public int intValue() {
         return (int)value;
@@ -1375,7 +1375,7 @@
     /**
      * Returns the value of this {@code Long} as a {@code float} after
      * a widening primitive conversion.
-     * @jls 5.1.2 Widening Primitive Conversions
+     * @jls 5.1.2 Widening Primitive Conversion
      */
     public float floatValue() {
         return (float)value;
@@ -1384,7 +1384,7 @@
     /**
      * Returns the value of this {@code Long} as a {@code double}
      * after a widening primitive conversion.
-     * @jls 5.1.2 Widening Primitive Conversions
+     * @jls 5.1.2 Widening Primitive Conversion
      */
     public double doubleValue() {
         return (double)value;
--- a/src/java.base/share/classes/java/lang/Number.java	Fri May 17 13:21:44 2019 +0100
+++ b/src/java.base/share/classes/java/lang/Number.java	Thu May 23 11:07:37 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1994, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1994, 2019, 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
@@ -48,12 +48,17 @@
  *
  * @author      Lee Boynton
  * @author      Arthur van Hoff
- * @jls 5.1.2 Widening Primitive Conversions
- * @jls 5.1.3 Narrowing Primitive Conversions
+ * @jls 5.1.2 Widening Primitive Conversion
+ * @jls 5.1.3 Narrowing Primitive Conversion
  * @since   1.0
  */
 public abstract class Number implements java.io.Serializable {
     /**
+     * Constructor for subclasses to call.
+     */
+    public Number() {super();}
+
+    /**
      * Returns the value of the specified number as an {@code int}.
      *
      * @return  the numeric value represented by this object after conversion
--- a/src/java.base/share/classes/java/lang/Package.java	Fri May 17 13:21:44 2019 +0100
+++ b/src/java.base/share/classes/java/lang/Package.java	Thu May 23 11:07:37 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2019, 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
@@ -108,7 +108,7 @@
  * <em>named modules</em>.  Instead those packages are automatically defined
  * and have no specification and implementation versioning information.
  *
- * @jvms 5.3 Run-time package
+ * @jvms 5.3 Creation and Loading
  * @see <a href="{@docRoot}/../specs/jar/jar.html#package-sealing">
  * The JAR File Specification: Package Sealing</a>
  * @see ClassLoader#definePackage(String, String, String, String, String, String, String, URL)
--- a/src/java.base/share/classes/java/lang/Short.java	Fri May 17 13:21:44 2019 +0100
+++ b/src/java.base/share/classes/java/lang/Short.java	Thu May 23 11:07:37 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2019, 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
@@ -352,7 +352,7 @@
     /**
      * Returns the value of this {@code Short} as a {@code byte} after
      * a narrowing primitive conversion.
-     * @jls 5.1.3 Narrowing Primitive Conversions
+     * @jls 5.1.3 Narrowing Primitive Conversion
      */
     public byte byteValue() {
         return (byte)value;
@@ -370,7 +370,7 @@
     /**
      * Returns the value of this {@code Short} as an {@code int} after
      * a widening primitive conversion.
-     * @jls 5.1.2 Widening Primitive Conversions
+     * @jls 5.1.2 Widening Primitive Conversion
      */
     public int intValue() {
         return (int)value;
@@ -379,7 +379,7 @@
     /**
      * Returns the value of this {@code Short} as a {@code long} after
      * a widening primitive conversion.
-     * @jls 5.1.2 Widening Primitive Conversions
+     * @jls 5.1.2 Widening Primitive Conversion
      */
     public long longValue() {
         return (long)value;
@@ -388,7 +388,7 @@
     /**
      * Returns the value of this {@code Short} as a {@code float}
      * after a widening primitive conversion.
-     * @jls 5.1.2 Widening Primitive Conversions
+     * @jls 5.1.2 Widening Primitive Conversion
      */
     public float floatValue() {
         return (float)value;
@@ -397,7 +397,7 @@
     /**
      * Returns the value of this {@code Short} as a {@code double}
      * after a widening primitive conversion.
-     * @jls 5.1.2 Widening Primitive Conversions
+     * @jls 5.1.2 Widening Primitive Conversion
      */
     public double doubleValue() {
         return (double)value;
--- a/src/java.base/share/classes/java/lang/StringLatin1.java	Fri May 17 13:21:44 2019 +0100
+++ b/src/java.base/share/classes/java/lang/StringLatin1.java	Thu May 23 11:07:37 2019 +0100
@@ -35,6 +35,7 @@
 import java.util.stream.Stream;
 import java.util.stream.StreamSupport;
 import jdk.internal.HotSpotIntrinsicCandidate;
+import jdk.internal.util.ArraysSupport;
 
 import static java.lang.String.LATIN1;
 import static java.lang.String.UTF16;
@@ -42,14 +43,6 @@
 
 final class StringLatin1 {
 
-    /**
-     * The maximum size of array to allocate (unless necessary).
-     * Some VMs reserve some header words in an array.
-     * Attempts to allocate larger arrays may result in
-     * OutOfMemoryError: Requested array size exceeds VM limit
-     */
-    private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
-
     public static char charAt(byte[] value, int index) {
         if (index < 0 || index >= value.length) {
             throw new StringIndexOutOfBoundsException(index);
@@ -353,15 +346,7 @@
         i += targLen;
         while ((j = indexOf(value, valLen, targ, targLen, i)) > 0) {
             if (++p == pos.length) {
-                int cap = p + (p >> 1);
-                // overflow-conscious code
-                if (cap - MAX_ARRAY_SIZE > 0) {
-                    if (p == MAX_ARRAY_SIZE) {
-                        throw new OutOfMemoryError();
-                    }
-                    cap = MAX_ARRAY_SIZE;
-                }
-                pos = Arrays.copyOf(pos, cap);
+                pos = Arrays.copyOf(pos, ArraysSupport.newLength(p, 1, p >> 1));
             }
             pos[p] = j;
             i = j + targLen;
--- a/src/java.base/share/classes/java/lang/StringUTF16.java	Fri May 17 13:21:44 2019 +0100
+++ b/src/java.base/share/classes/java/lang/StringUTF16.java	Thu May 23 11:07:37 2019 +0100
@@ -33,6 +33,7 @@
 import java.util.stream.Stream;
 import java.util.stream.StreamSupport;
 import jdk.internal.HotSpotIntrinsicCandidate;
+import jdk.internal.util.ArraysSupport;
 import jdk.internal.vm.annotation.ForceInline;
 import jdk.internal.vm.annotation.DontInline;
 
@@ -649,15 +650,7 @@
                             : indexOf(value, valLen, targ, targLen, i))) > 0)
         {
             if (++p == pos.length) {
-                int cap = p + (p >> 1);
-                // overflow-conscious code
-                if (cap - MAX_ARRAY_SIZE > 0) {
-                    if (p == MAX_ARRAY_SIZE) {
-                        throw new OutOfMemoryError();
-                    }
-                    cap = MAX_ARRAY_SIZE;
-                }
-                pos = Arrays.copyOf(pos, cap);
+                pos = Arrays.copyOf(pos, ArraysSupport.newLength(p, 1, p >> 1));
             }
             pos[p] = j;
             i = j + targLen;
@@ -1554,15 +1547,6 @@
 
     static final int MAX_LENGTH = Integer.MAX_VALUE >> 1;
 
-
-    /**
-     * The maximum size of array to allocate (unless necessary).
-     * Some VMs reserve some header words in an array.
-     * Attempts to allocate larger arrays may result in
-     * OutOfMemoryError: Requested array size exceeds VM limit
-     */
-    private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
-
     // Used by trusted callers.  Assumes all necessary bounds checks have
     // been done by the caller.
 
--- a/src/java.base/share/classes/java/lang/SuppressWarnings.java	Fri May 17 13:21:44 2019 +0100
+++ b/src/java.base/share/classes/java/lang/SuppressWarnings.java	Thu May 23 11:07:37 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2004, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 2019, 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
@@ -49,7 +49,7 @@
  * @jls 4.8 Raw Types
  * @jls 4.12.2 Variables of Reference Type
  * @jls 5.1.9 Unchecked Conversion
- * @jls 5.5.2 Checked Casts and Unchecked Casts
+ * @jls 5.5 Casting Contexts
  * @jls 9.6.4.5 @SuppressWarnings
  */
 @Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE, MODULE})
--- a/src/java.base/share/classes/java/lang/constant/Constable.java	Fri May 17 13:21:44 2019 +0100
+++ b/src/java.base/share/classes/java/lang/constant/Constable.java	Thu May 23 11:07:37 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018, 2019, 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
@@ -59,7 +59,7 @@
  * method handles, but not necessarily those produced by method handle
  * combinators.)
  * @jvms 4.4 The Constant Pool
- * @jvms 4.4.10 The CONSTANT_InvokeDynamic_info Structure
+ * @jvms 4.4.10 The {@code CONSTANT_Dynamic_info} and {@code CONSTANT_InvokeDynamic_info} Structures
  *
  * @since 12
  */
--- a/src/java.base/share/classes/java/lang/constant/ConstantDesc.java	Fri May 17 13:21:44 2019 +0100
+++ b/src/java.base/share/classes/java/lang/constant/ConstantDesc.java	Thu May 23 11:07:37 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018, 2019, 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
@@ -97,6 +97,11 @@
      * @throws ReflectiveOperationException if a class, method, or field
      * could not be reflectively resolved in the course of resolution
      * @throws LinkageError if a linkage error occurs
+     *
+     * @apiNote {@linkplain MethodTypeDesc} can represent method type descriptors
+     * that are not representable by {@linkplain MethodType}, such as methods with
+     * more than 255 parameter slots, so attempts to resolve these may result in errors.
+     *
      * @jvms 5.4.3 Resolution
      * @jvms 5.4.4 Access Control
      */
--- a/src/java.base/share/classes/java/lang/constant/MethodHandleDesc.java	Fri May 17 13:21:44 2019 +0100
+++ b/src/java.base/share/classes/java/lang/constant/MethodHandleDesc.java	Thu May 23 11:07:37 2019 +0100
@@ -70,6 +70,8 @@
      *                         for a field or constructor
      * @return the {@linkplain MethodHandleDesc}
      * @throws NullPointerException if any of the non-ignored arguments are null
+     * @throws IllegalArgumentException if the descriptor string is not a valid
+     * method or field descriptor
      * @jvms 4.4.8 The CONSTANT_MethodHandle_info Structure
      * @jvms 4.2.2 Unqualified Names
      * @jvms 4.3.2 Field Descriptors
--- a/src/java.base/share/classes/java/lang/constant/MethodTypeDesc.java	Fri May 17 13:21:44 2019 +0100
+++ b/src/java.base/share/classes/java/lang/constant/MethodTypeDesc.java	Thu May 23 11:07:37 2019 +0100
@@ -65,7 +65,9 @@
      * @param returnDesc a {@linkplain ClassDesc} describing the return type
      * @param paramDescs {@linkplain ClassDesc}s describing the argument types
      * @return a {@linkplain MethodTypeDesc} describing the desired method type
-     * @throws NullPointerException if any argument is {@code null}
+     * @throws NullPointerException if any argument or its contents are {@code null}
+     * @throws IllegalArgumentException if any element of {@code paramDescs} is a
+     * {@link ClassDesc} for {@code void}
      */
     static MethodTypeDesc of(ClassDesc returnDesc, ClassDesc... paramDescs) {
         return new MethodTypeDescImpl(returnDesc, paramDescs);
@@ -141,8 +143,8 @@
      * @param end the index after the last parameter to remove
      * @return a {@linkplain MethodTypeDesc} describing the desired method type
      * @throws IndexOutOfBoundsException if {@code start} is outside the half-open
-     * range {[0, parameterCount)}, or {@code end} is outside the closed range
-     * {@code [0, parameterCount]}
+     * range {@code [0, parameterCount)}, or {@code end} is outside the closed range
+     * {@code [0, parameterCount]}, or if {@code start > end}
      */
     MethodTypeDesc dropParameterTypes(int start, int end);
 
@@ -154,9 +156,11 @@
      * @param paramTypes {@link ClassDesc}s describing the new parameter types
      *                   to insert
      * @return a {@linkplain MethodTypeDesc} describing the desired method type
-     * @throws NullPointerException if any argument is {@code null}
+     * @throws NullPointerException if any argument or its contents are {@code null}
      * @throws IndexOutOfBoundsException if {@code pos} is outside the closed
      * range {[0, parameterCount]}
+     * @throws IllegalArgumentException if any element of {@code paramTypes}
+     * is a {@link ClassDesc} for {@code void}
      */
     MethodTypeDesc insertParameterTypes(int pos, ClassDesc... paramTypes);
 
--- a/src/java.base/share/classes/java/lang/constant/MethodTypeDescImpl.java	Fri May 17 13:21:44 2019 +0100
+++ b/src/java.base/share/classes/java/lang/constant/MethodTypeDescImpl.java	Thu May 23 11:07:37 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018, 2019, 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
@@ -111,10 +111,8 @@
 
     @Override
     public MethodTypeDesc dropParameterTypes(int start, int end) {
-        if (start < 0 || start >= argTypes.length || end < 0 || end > argTypes.length)
+        if (start < 0 || start >= argTypes.length || end < 0 || end > argTypes.length || start > end)
             throw new IndexOutOfBoundsException();
-        else if (start > end)
-            throw new IllegalArgumentException(String.format("Range (%d, %d) not valid for size %d", start, end, argTypes.length));
         ClassDesc[] newArgs = new ClassDesc[argTypes.length - (end - start)];
         System.arraycopy(argTypes, 0, newArgs, 0, start);
         System.arraycopy(argTypes, end, newArgs, start, argTypes.length - end);
--- a/src/java.base/share/classes/java/lang/reflect/Method.java	Fri May 17 13:21:44 2019 +0100
+++ b/src/java.base/share/classes/java/lang/reflect/Method.java	Thu May 23 11:07:37 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2019, 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
@@ -403,7 +403,7 @@
      * @return a string describing this {@code Method}
      *
      * @jls 8.4.3 Method Modifiers
-     * @jls 9.4   Method Declarations
+     * @jls 9.4 Method Declarations
      * @jls 9.6.1 Annotation Type Elements
      */
     public String toString() {
@@ -474,7 +474,7 @@
      * @since 1.5
      *
      * @jls 8.4.3 Method Modifiers
-     * @jls 9.4   Method Declarations
+     * @jls 9.4 Method Declarations
      * @jls 9.6.1 Annotation Type Elements
      */
     @Override
--- a/src/java.base/share/classes/java/lang/reflect/Modifier.java	Fri May 17 13:21:44 2019 +0100
+++ b/src/java.base/share/classes/java/lang/reflect/Modifier.java	Thu May 23 11:07:37 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2019, 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
@@ -394,7 +394,7 @@
 
     /**
      * The Java source modifiers that can be applied to a field.
-     * @jls 8.3.1  Field Modifiers
+     * @jls 8.3.1 Field Modifiers
      */
     private static final int FIELD_MODIFIERS =
         Modifier.PUBLIC         | Modifier.PROTECTED    | Modifier.PRIVATE |
--- a/src/java.base/share/classes/java/net/Inet6AddressImpl.java	Fri May 17 13:21:44 2019 +0100
+++ b/src/java.base/share/classes/java/net/Inet6AddressImpl.java	Thu May 23 11:07:37 2019 +0100
@@ -32,9 +32,13 @@
  * Package private implementation of InetAddressImpl for dual
  * IPv4/IPv6 stack.
  * <p>
- * If InetAddress.preferIPv6Address is true then anyLocalAddress(),
- * loopbackAddress(), and localHost() will return IPv6 addresses,
- * otherwise IPv4 addresses.
+ * If InetAddress.preferIPv6Address is true then anyLocalAddress()
+ * and localHost() will return IPv6 addresses, otherwise IPv4 addresses.
+ *
+ * loopbackAddress() will return the first valid loopback address in
+ * [IPv6 loopback, IPv4 loopback] if InetAddress.preferIPv6Address is true,
+ * else [IPv4 loopback, IPv6 loopback].
+ * If neither are valid it will fallback to the first address tried.
  *
  * @since 1.4
  */
@@ -103,15 +107,31 @@
 
     public synchronized InetAddress loopbackAddress() {
         if (loopbackAddress == null) {
-             if (InetAddress.preferIPv6Address == PREFER_IPV6_VALUE ||
-                 InetAddress.preferIPv6Address == PREFER_SYSTEM_VALUE) {
-                 byte[] loopback =
-                        {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-                         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01};
-                 loopbackAddress = new Inet6Address("localhost", loopback);
-             } else {
-                loopbackAddress = (new Inet4AddressImpl()).loopbackAddress();
-             }
+            boolean preferIPv6Address =
+                InetAddress.preferIPv6Address == PREFER_IPV6_VALUE ||
+                InetAddress.preferIPv6Address == PREFER_SYSTEM_VALUE;
+            InetAddress loopback4 = (new Inet4AddressImpl()).loopbackAddress();
+            InetAddress loopback6 = new Inet6Address("localhost",
+                new byte[] {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01});
+            // Order the candidate addresses by preference.
+            InetAddress[] addresses = preferIPv6Address
+                ? new InetAddress[] {loopback6, loopback4}
+                : new InetAddress[] {loopback4, loopback6};
+            // In case of failure, default to the preferred address.
+            loopbackAddress = addresses[0];
+            // Pick the first candidate address that actually exists.
+            for (InetAddress address : addresses) {
+                try {
+                    if (NetworkInterface.getByInetAddress(address) == null) {
+                        continue;
+                    }
+                } catch (SocketException e) {
+                    continue;
+                }
+                loopbackAddress = address;
+                break;
+            }
         }
         return loopbackAddress;
     }
--- a/src/java.base/share/classes/java/nio/file/Files.java	Fri May 17 13:21:44 2019 +0100
+++ b/src/java.base/share/classes/java/nio/file/Files.java	Thu May 23 11:07:37 2019 +0100
@@ -77,6 +77,7 @@
 import java.util.stream.Stream;
 import java.util.stream.StreamSupport;
 
+import jdk.internal.util.ArraysSupport;
 import sun.nio.ch.FileChannelImpl;
 import sun.nio.fs.AbstractFileSystemProvider;
 
@@ -3196,14 +3197,6 @@
         }
     }
 
-    /**
-     * The maximum size of array to allocate.
-     * Some VMs reserve some header words in an array.
-     * Attempts to allocate larger arrays may result in
-     * OutOfMemoryError: Requested array size exceeds VM limit
-     */
-    private static final int MAX_BUFFER_SIZE = Integer.MAX_VALUE - 8;
-
     private static final jdk.internal.access.JavaLangAccess JLA =
             jdk.internal.access.SharedSecrets.getJavaLangAccess();
 
@@ -3240,13 +3233,10 @@
                 break;
 
             // one more byte was read; need to allocate a larger buffer
-            if (capacity <= MAX_BUFFER_SIZE - capacity) {
-                capacity = Math.max(capacity << 1, BUFFER_SIZE);
-            } else {
-                if (capacity == MAX_BUFFER_SIZE)
-                    throw new OutOfMemoryError("Required array size too large");
-                capacity = MAX_BUFFER_SIZE;
-            }
+            capacity = Math.max(ArraysSupport.newLength(capacity,
+                                                        1,       /* minimum growth */
+                                                        capacity /* preferred growth */),
+                                BUFFER_SIZE);
             buf = Arrays.copyOf(buf, capacity);
             buf[nread++] = (byte)n;
         }
@@ -3283,7 +3273,7 @@
             if (sbc instanceof FileChannelImpl)
                 ((FileChannelImpl) sbc).setUninterruptible();
             long size = sbc.size();
-            if (size > (long) MAX_BUFFER_SIZE)
+            if (size > (long) Integer.MAX_VALUE)
                 throw new OutOfMemoryError("Required array size too large");
             return read(in, (int)size);
         }
--- a/src/java.base/share/classes/java/util/AbstractCollection.java	Fri May 17 13:21:44 2019 +0100
+++ b/src/java.base/share/classes/java/util/AbstractCollection.java	Thu May 23 11:07:37 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2019, 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
@@ -25,6 +25,8 @@
 
 package java.util;
 
+import jdk.internal.util.ArraysSupport;
+
 /**
  * This class provides a skeletal implementation of the {@code Collection}
  * interface, to minimize the effort required to implement this interface. <p>
@@ -204,14 +206,6 @@
     }
 
     /**
-     * The maximum size of array to allocate.
-     * Some VMs reserve some header words in an array.
-     * Attempts to allocate larger arrays may result in
-     * OutOfMemoryError: Requested array size exceeds VM limit
-     */
-    private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
-
-    /**
      * Reallocates the array being used within toArray when the iterator
      * returned more elements than expected, and finishes filling it from
      * the iterator.
@@ -223,29 +217,19 @@
      */
     @SuppressWarnings("unchecked")
     private static <T> T[] finishToArray(T[] r, Iterator<?> it) {
-        int i = r.length;
+        int len = r.length;
+        int i = len;
         while (it.hasNext()) {
-            int cap = r.length;
-            if (i == cap) {
-                int newCap = cap + (cap >> 1) + 1;
-                // overflow-conscious code
-                if (newCap - MAX_ARRAY_SIZE > 0)
-                    newCap = hugeCapacity(cap + 1);
-                r = Arrays.copyOf(r, newCap);
+            if (i == len) {
+                len = ArraysSupport.newLength(len,
+                        1,             /* minimum growth */
+                        (len >> 1) + 1 /* preferred growth */);
+                r = Arrays.copyOf(r, len);
             }
             r[i++] = (T)it.next();
         }
         // trim if overallocated
-        return (i == r.length) ? r : Arrays.copyOf(r, i);
-    }
-
-    private static int hugeCapacity(int minCapacity) {
-        if (minCapacity < 0) // overflow
-            throw new OutOfMemoryError
-                ("Required array size too large");
-        return (minCapacity > MAX_ARRAY_SIZE) ?
-            Integer.MAX_VALUE :
-            MAX_ARRAY_SIZE;
+        return (i == len) ? r : Arrays.copyOf(r, i);
     }
 
     // Modification Operations
--- a/src/java.base/share/classes/java/util/ArrayList.java	Fri May 17 13:21:44 2019 +0100
+++ b/src/java.base/share/classes/java/util/ArrayList.java	Thu May 23 11:07:37 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2019, 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
@@ -29,6 +29,7 @@
 import java.util.function.Predicate;
 import java.util.function.UnaryOperator;
 import jdk.internal.access.SharedSecrets;
+import jdk.internal.util.ArraysSupport;
 
 /**
  * Resizable-array implementation of the {@code List} interface.  Implements
@@ -219,14 +220,6 @@
     }
 
     /**
-     * The maximum size of array to allocate (unless necessary).
-     * Some VMs reserve some header words in an array.
-     * Attempts to allocate larger arrays may result in
-     * OutOfMemoryError: Requested array size exceeds VM limit
-     */
-    private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
-
-    /**
      * Increases the capacity to ensure that it can hold at least the
      * number of elements specified by the minimum capacity argument.
      *
@@ -234,8 +227,15 @@
      * @throws OutOfMemoryError if minCapacity is less than zero
      */
     private Object[] grow(int minCapacity) {
-        return elementData = Arrays.copyOf(elementData,
-                                           newCapacity(minCapacity));
+        int oldCapacity = elementData.length;
+        if (oldCapacity > 0 || elementData != DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
+            int newCapacity = ArraysSupport.newLength(oldCapacity,
+                    minCapacity - oldCapacity, /* minimum growth */
+                    oldCapacity >> 1           /* preferred growth */);
+            return elementData = Arrays.copyOf(elementData, newCapacity);
+        } else {
+            return elementData = new Object[Math.max(DEFAULT_CAPACITY, minCapacity)];
+        }
     }
 
     private Object[] grow() {
@@ -243,39 +243,6 @@
     }
 
     /**
-     * Returns a capacity at least as large as the given minimum capacity.
-     * Returns the current capacity increased by 50% if that suffices.
-     * Will not return a capacity greater than MAX_ARRAY_SIZE unless
-     * the given minimum capacity is greater than MAX_ARRAY_SIZE.
-     *
-     * @param minCapacity the desired minimum capacity
-     * @throws OutOfMemoryError if minCapacity is less than zero
-     */
-    private int newCapacity(int minCapacity) {
-        // overflow-conscious code
-        int oldCapacity = elementData.length;
-        int newCapacity = oldCapacity + (oldCapacity >> 1);
-        if (newCapacity - minCapacity <= 0) {
-            if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA)
-                return Math.max(DEFAULT_CAPACITY, minCapacity);
-            if (minCapacity < 0) // overflow
-                throw new OutOfMemoryError();
-            return minCapacity;
-        }
-        return (newCapacity - MAX_ARRAY_SIZE <= 0)
-            ? newCapacity
-            : hugeCapacity(minCapacity);
-    }
-
-    private static int hugeCapacity(int minCapacity) {
-        if (minCapacity < 0) // overflow
-            throw new OutOfMemoryError();
-        return (minCapacity > MAX_ARRAY_SIZE)
-            ? Integer.MAX_VALUE
-            : MAX_ARRAY_SIZE;
-    }
-
-    /**
      * Returns the number of elements in this list.
      *
      * @return the number of elements in this list
--- a/src/java.base/share/classes/java/util/PriorityQueue.java	Fri May 17 13:21:44 2019 +0100
+++ b/src/java.base/share/classes/java/util/PriorityQueue.java	Thu May 23 11:07:37 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2019, 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
@@ -28,6 +28,7 @@
 import java.util.function.Consumer;
 import java.util.function.Predicate;
 import jdk.internal.access.SharedSecrets;
+import jdk.internal.util.ArraysSupport;
 
 /**
  * An unbounded priority {@linkplain Queue queue} based on a priority heap.
@@ -282,14 +283,6 @@
     }
 
     /**
-     * The maximum size of array to allocate.
-     * Some VMs reserve some header words in an array.
-     * Attempts to allocate larger arrays may result in
-     * OutOfMemoryError: Requested array size exceeds VM limit
-     */
-    private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
-
-    /**
      * Increases the capacity of the array.
      *
      * @param minCapacity the desired minimum capacity
@@ -297,23 +290,13 @@
     private void grow(int minCapacity) {
         int oldCapacity = queue.length;
         // Double size if small; else grow by 50%
-        int newCapacity = oldCapacity + ((oldCapacity < 64) ?
-                                         (oldCapacity + 2) :
-                                         (oldCapacity >> 1));
-        // overflow-conscious code
-        if (newCapacity - MAX_ARRAY_SIZE > 0)
-            newCapacity = hugeCapacity(minCapacity);
+        int newCapacity = ArraysSupport.newLength(oldCapacity,
+                minCapacity - oldCapacity, /* minimum growth */
+                oldCapacity < 64 ? oldCapacity + 2 : oldCapacity >> 1
+                                           /* preferred growth */);
         queue = Arrays.copyOf(queue, newCapacity);
     }
 
-    private static int hugeCapacity(int minCapacity) {
-        if (minCapacity < 0) // overflow
-            throw new OutOfMemoryError();
-        return (minCapacity > MAX_ARRAY_SIZE) ?
-            Integer.MAX_VALUE :
-            MAX_ARRAY_SIZE;
-    }
-
     /**
      * Inserts the specified element into this priority queue.
      *
--- a/src/java.base/share/classes/java/util/Vector.java	Fri May 17 13:21:44 2019 +0100
+++ b/src/java.base/share/classes/java/util/Vector.java	Thu May 23 11:07:37 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1994, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1994, 2019, 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
@@ -32,6 +32,8 @@
 import java.util.function.Predicate;
 import java.util.function.UnaryOperator;
 
+import jdk.internal.util.ArraysSupport;
+
 /**
  * The {@code Vector} class implements a growable array of
  * objects. Like an array, it contains components that can be
@@ -242,14 +244,6 @@
     }
 
     /**
-     * The maximum size of array to allocate (unless necessary).
-     * Some VMs reserve some header words in an array.
-     * Attempts to allocate larger arrays may result in
-     * OutOfMemoryError: Requested array size exceeds VM limit
-     */
-    private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
-
-    /**
      * Increases the capacity to ensure that it can hold at least the
      * number of elements specified by the minimum capacity argument.
      *
@@ -257,8 +251,12 @@
      * @throws OutOfMemoryError if minCapacity is less than zero
      */
     private Object[] grow(int minCapacity) {
-        return elementData = Arrays.copyOf(elementData,
-                                           newCapacity(minCapacity));
+        int oldCapacity = elementData.length;
+        int newCapacity = ArraysSupport.newLength(oldCapacity,
+                minCapacity - oldCapacity, /* minimum growth */
+                capacityIncrement > 0 ? capacityIncrement : oldCapacity
+                                           /* preferred growth */);
+        return elementData = Arrays.copyOf(elementData, newCapacity);
     }
 
     private Object[] grow() {
@@ -266,37 +264,6 @@
     }
 
     /**
-     * Returns a capacity at least as large as the given minimum capacity.
-     * Will not return a capacity greater than MAX_ARRAY_SIZE unless
-     * the given minimum capacity is greater than MAX_ARRAY_SIZE.
-     *
-     * @param minCapacity the desired minimum capacity
-     * @throws OutOfMemoryError if minCapacity is less than zero
-     */
-    private int newCapacity(int minCapacity) {
-        // overflow-conscious code
-        int oldCapacity = elementData.length;
-        int newCapacity = oldCapacity + ((capacityIncrement > 0) ?
-                                         capacityIncrement : oldCapacity);
-        if (newCapacity - minCapacity <= 0) {
-            if (minCapacity < 0) // overflow
-                throw new OutOfMemoryError();
-            return minCapacity;
-        }
-        return (newCapacity - MAX_ARRAY_SIZE <= 0)
-            ? newCapacity
-            : hugeCapacity(minCapacity);
-    }
-
-    private static int hugeCapacity(int minCapacity) {
-        if (minCapacity < 0) // overflow
-            throw new OutOfMemoryError();
-        return (minCapacity > MAX_ARRAY_SIZE) ?
-            Integer.MAX_VALUE :
-            MAX_ARRAY_SIZE;
-    }
-
-    /**
      * Sets the size of this vector. If the new size is greater than the
      * current size, new {@code null} items are added to the end of
      * the vector. If the new size is less than the current size, all
--- a/src/java.base/share/classes/java/util/regex/Pattern.java	Fri May 17 13:21:44 2019 +0100
+++ b/src/java.base/share/classes/java/util/regex/Pattern.java	Thu May 23 11:07:37 2019 +0100
@@ -43,6 +43,7 @@
 import java.util.stream.Stream;
 import java.util.stream.StreamSupport;
 
+import jdk.internal.util.ArraysSupport;
 
 /**
  * A compiled representation of a regular expression.
@@ -2315,13 +2316,15 @@
         }
     }
 
-    private void append(int ch, int len) {
-        if (len >= buffer.length) {
-            int[] tmp = new int[len+len];
-            System.arraycopy(buffer, 0, tmp, 0, len);
-            buffer = tmp;
-        }
-        buffer[len] = ch;
+    private void append(int ch, int index) {
+        int len = buffer.length;
+        if (index - len >= 0) {
+            len = ArraysSupport.newLength(len,
+                    1 + index - len, /* minimum growth */
+                    len              /* preferred growth */);
+            buffer = Arrays.copyOf(buffer, len);
+        }
+        buffer[index] = ch;
     }
 
     /**
--- a/src/java.base/share/classes/javax/crypto/JceSecurity.java.template	Fri May 17 13:21:44 2019 +0100
+++ b/src/java.base/share/classes/javax/crypto/JceSecurity.java.template	Thu May 23 11:07:37 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2019, 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
@@ -50,6 +50,7 @@
 package javax.crypto;
 
 import java.util.*;
+import java.util.concurrent.ConcurrentHashMap;
 import java.io.*;
 import java.net.URL;
 import java.nio.file.*;
@@ -84,11 +85,11 @@
     private static CryptoPermissions defaultPolicy = null;
     private static CryptoPermissions exemptPolicy = null;
 
-    // Map<Provider,?> of the providers we already have verified
-    // value == PROVIDER_VERIFIED is successfully verified
-    // value is failure cause Exception in error case
-    private static final Map<Provider, Object> verificationResults =
-            new IdentityHashMap<>();
+    // Map of the providers we already have verified.
+    // If verified ok, value == PROVIDER_VERIFIED, otherwise
+    // the cause of verification failure is stored as value.
+    private static final Map<IdentityWrapper, Object>
+        verificationResults = new ConcurrentHashMap<>();
 
     // Map<Provider,?> of the providers currently being verified
     private static final Map<Provider, Object> verifyingProviders =
@@ -199,31 +200,39 @@
      * JCE trusted CA.
      * Return null if ok, failure Exception if verification failed.
      */
-    static synchronized Exception getVerificationResult(Provider p) {
-        Object o = verificationResults.get(p);
-        if (o == PROVIDER_VERIFIED) {
-            return null;
-        } else if (o != null) {
-            return (Exception)o;
-        }
-        if (verifyingProviders.get(p) != null) {
-            // this method is static synchronized, must be recursion
-            // return failure now but do not save the result
-            return new NoSuchProviderException("Recursion during verification");
+    static Exception getVerificationResult(Provider p) {
+        IdentityWrapper pKey = new IdentityWrapper(p);
+        Object o = verificationResults.get(pKey);
+        // no mapping found
+        if (o == null) {
+            synchronized (JceSecurity.class) {
+                // check cache again in case the result is now available
+                o = verificationResults.get(pKey);
+                if (o == null) {
+                    if (verifyingProviders.get(p) != null) {
+                        // recursion; return failure now
+                        return new NoSuchProviderException
+                                ("Recursion during verification");
+                    }
+                    try {
+                        verifyingProviders.put(p, Boolean.FALSE);
+                        URL providerURL = getCodeBase(p.getClass());
+                        verifyProvider(providerURL, p);
+                        o = PROVIDER_VERIFIED;
+                    } catch (Exception e) {
+                        o = e;
+                    } finally {
+                        verifyingProviders.remove(p);
+                    }
+                    verificationResults.put(pKey, o);
+                    if (debug != null) {
+                        debug.println("Provider " + p.getName() +
+                                " verification result: " + o);
+                    }
+                }
+            }
         }
-        try {
-            verifyingProviders.put(p, Boolean.FALSE);
-            URL providerURL = getCodeBase(p.getClass());
-            verifyProvider(providerURL, p);
-            // Verified ok, cache result
-            verificationResults.put(p, PROVIDER_VERIFIED);
-            return null;
-        } catch (Exception e) {
-            verificationResults.put(p, e);
-            return e;
-        } finally {
-            verifyingProviders.remove(p);
-        }
+        return (o == PROVIDER_VERIFIED? null : (Exception) o);
     }
 
     // return whether this provider is properly signed and can be used by JCE
@@ -391,4 +400,29 @@
     static boolean isRestricted() {
         return isRestricted;
     }
+
+    private static final class IdentityWrapper {
+
+        final Provider obj;
+
+        IdentityWrapper(Provider obj) {
+            this.obj = obj;
+        }
+
+        @Override
+        public boolean equals(Object o) {
+            if (this == o) {
+                return true;
+            }
+            if (!(o instanceof IdentityWrapper)) {
+                return false;
+            }
+            return this.obj == ((IdentityWrapper)o).obj;
+        }
+
+        @Override
+        public int hashCode() {
+            return System.identityHashCode(obj);
+        }
+    }
 }
--- a/src/java.base/share/classes/jdk/internal/util/ArraysSupport.java	Fri May 17 13:21:44 2019 +0100
+++ b/src/java.base/share/classes/jdk/internal/util/ArraysSupport.java	Thu May 23 11:07:37 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2019, 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
@@ -28,7 +28,9 @@
 import jdk.internal.misc.Unsafe;
 
 /**
- * Utility methods to find a mismatch between two primitive arrays.
+ * Utility methods to work with arrays.  This includes a set of methods
+ * to find a mismatch between two primitive arrays.  Also included is
+ * a method to calculate the new length of an array to be reallocated.
  *
  * <p>Array equality and lexicographical comparison can be built on top of
  * array mismatch functionality.
@@ -571,4 +573,54 @@
 
         return -1;
     }
+
+    /**
+     * The maximum length of array to allocate (unless necessary).
+     * Some VMs reserve some header words in an array.
+     * Attempts to allocate larger arrays may result in
+     * {@code OutOfMemoryError: Requested array size exceeds VM limit}
+     */
+    public static final int MAX_ARRAY_LENGTH = Integer.MAX_VALUE - 8;
+
+    /**
+     * Calculates a new array length given an array's current length, a preferred
+     * growth value, and a minimum growth value.  If the preferred growth value
+     * is less than the minimum growth value, the minimum growth value is used in
+     * its place.  If the sum of the current length and the preferred growth
+     * value does not exceed {@link #MAX_ARRAY_LENGTH}, that sum is returned.
+     * If the sum of the current length and the minimum growth value does not
+     * exceed {@code MAX_ARRAY_LENGTH}, then {@code MAX_ARRAY_LENGTH} is returned.
+     * If the sum does not overflow an int, then {@code Integer.MAX_VALUE} is
+     * returned.  Otherwise, {@code OutOfMemoryError} is thrown.
+     *
+     * @param oldLength   current length of the array (must be non negative)
+     * @param minGrowth   minimum required growth of the array length (must be
+     *                    positive)
+     * @param prefGrowth  preferred growth of the array length (ignored, if less
+     *                    then {@code minGrowth})
+     * @return the new length of the array
+     * @throws OutOfMemoryError if increasing {@code oldLength} by
+     *                    {@code minGrowth} overflows.
+     */
+    public static int newLength(int oldLength, int minGrowth, int prefGrowth) {
+        // assert oldLength >= 0
+        // assert minGrowth > 0
+
+        int newLength = Math.max(minGrowth, prefGrowth) + oldLength;
+        if (newLength - MAX_ARRAY_LENGTH <= 0) {
+            return newLength;
+        }
+        return hugeLength(oldLength, minGrowth);
+    }
+
+    private static int hugeLength(int oldLength, int minGrowth) {
+        int minLength = oldLength + minGrowth;
+        if (minLength < 0) { // overflow
+            throw new OutOfMemoryError("Required array length too large");
+        }
+        if (minLength <= MAX_ARRAY_LENGTH) {
+            return MAX_ARRAY_LENGTH;
+        }
+        return Integer.MAX_VALUE;
+    }
 }
--- a/src/java.base/share/classes/module-info.java	Fri May 17 13:21:44 2019 +0100
+++ b/src/java.base/share/classes/module-info.java	Thu May 23 11:07:37 2019 +0100
@@ -36,11 +36,11 @@
  *      {@link java.nio.file.FileSystems#newFileSystem
  *      FileSystems.newFileSystem(URI.create("jrt:/"))}.
  *      </dd>
- * <dt class="simpleTagLabel" style="font-family:'DejaVu Sans', Arial, Helvetica, sans serif">Tool Guides:</dt>
- * <dd style="font-family:'DejaVu Sans', Arial, Helvetica, sans serif"> {@extLink java_tool_reference java launcher},
- *      {@extLink keytool_tool_reference keytool}</dd>
  * </dl>
  *
+ * @toolGuide java java launcher
+ * @toolGuide keytool
+ *
  * @provides java.nio.file.spi.FileSystemProvider
  *
  * @uses java.lang.System.LoggerFinder
--- a/src/java.base/share/classes/sun/launcher/resources/launcher.properties	Fri May 17 13:21:44 2019 +0100
+++ b/src/java.base/share/classes/sun/launcher/resources/launcher.properties	Thu May 23 11:07:37 2019 +0100
@@ -132,10 +132,15 @@
 \    -Xdebug           provided for backward compatibility\n\
 \    -Xdiag            show additional diagnostic messages\n\
 \    -Xfuture          enable strictest checks, anticipating future default\n\
+\                      This option is deprecated and may be removed in a\n\
+\                      future release.\n\
 \    -Xint             interpreted mode execution only\n\
 \    -Xinternalversion\n\
 \                      displays more detailed JVM version information than the\n\
 \                      -version option\n\
+\    -Xlog:<opts>      Configure or enable logging with the Java Virtual\n\
+\                      Machine (JVM) unified logging framework. Use -Xlog:help\n\
+\                      for details.\n\
 \    -Xloggc:<file>    log GC status to a file with time stamps\n\
 \    -Xmixed           mixed mode execution (default)\n\
 \    -Xmn<size>        sets the initial and maximum size (in bytes) of the heap\n\
--- a/src/java.base/share/classes/sun/security/util/SecurityProperties.java	Fri May 17 13:21:44 2019 +0100
+++ b/src/java.base/share/classes/sun/security/util/SecurityProperties.java	Thu May 23 11:07:37 2019 +0100
@@ -43,15 +43,20 @@
      * @return the value of the system or security property
      */
     public static String privilegedGetOverridable(String propName) {
-        return AccessController.doPrivileged((PrivilegedAction<String>)
-            () -> {
-                String val = System.getProperty(propName);
-                if (val == null) {
-                    return Security.getProperty(propName);
-                } else {
-                    return val;
-                }
-            });
+        if (System.getSecurityManager() == null) {
+            return getOverridableProperty(propName);
+        } else {
+            return AccessController.doPrivileged((PrivilegedAction<String>) () -> getOverridableProperty(propName));
+        }
+    }
+
+    private static String getOverridableProperty(String propName) {
+        String val = System.getProperty(propName);
+        if (val == null) {
+            return Security.getProperty(propName);
+        } else {
+            return val;
+        }
     }
 
     /**
--- a/src/java.base/share/classes/sun/util/locale/provider/CalendarNameProviderImpl.java	Fri May 17 13:21:44 2019 +0100
+++ b/src/java.base/share/classes/sun/util/locale/provider/CalendarNameProviderImpl.java	Thu May 23 11:07:37 2019 +0100
@@ -257,11 +257,13 @@
         return langtags;
     }
 
+    // Check if each string is unique, except null or empty strings,
+    // as these strings are used for keys in the name-to-value map.
     private boolean hasDuplicates(String[] strings) {
         int len = strings.length;
         for (int i = 0; i < len - 1; i++) {
             String a = strings[i];
-            if (a != null) {
+            if (a != null && !a.isEmpty()) {
                 for (int j = i + 1; j < len; j++) {
                     if (a.equals(strings[j]))  {
                         return true;
--- a/src/java.base/share/man/java.1	Fri May 17 13:21:44 2019 +0100
+++ b/src/java.base/share/man/java.1	Thu May 23 11:07:37 2019 +0100
@@ -716,6 +716,8 @@
 \-Xfuture
 .RS 4
 Enables strict class\-file format checks that enforce close conformance to the class\-file format specification\&. Developers are encouraged to use this flag when developing new code because the stricter checks will become the default in future releases\&.
+.sp
+This option is deprecated and may be removed in a future release.
 .RE
 .PP
 \-Xint
--- a/src/java.base/share/native/libjli/emessages.h	Fri May 17 13:21:44 2019 +0100
+++ b/src/java.base/share/native/libjli/emessages.h	Thu May 23 11:07:37 2019 +0100
@@ -38,6 +38,7 @@
 
 #define ARG_INFO_ENVVAR "NOTE: Picked up %s: %s"
 #define ARG_WARN        "Warning: %s option is no longer supported."
+#define ARG_DEPRECATED  "Warning: %s option is deprecated and may be removed in a future release."
 
 #define ARG_ERROR1      "Error: %s requires class path specification"
 #define ARG_ERROR2      "Error: %s requires jar file specification"
--- a/src/java.base/share/native/libjli/java.c	Fri May 17 13:21:44 2019 +0100
+++ b/src/java.base/share/native/libjli/java.c	Thu May 23 11:07:37 2019 +0100
@@ -1430,6 +1430,7 @@
         } else if (JLI_StrCmp(arg, "-noclassgc") == 0) {
             AddOption("-Xnoclassgc", NULL);
         } else if (JLI_StrCmp(arg, "-Xfuture") == 0) {
+            JLI_ReportErrorMessage(ARG_DEPRECATED, "-Xfuture");
             AddOption("-Xverify:all", NULL);
         } else if (JLI_StrCmp(arg, "-verify") == 0) {
             AddOption("-Xverify:all", NULL);
--- a/src/java.base/unix/native/libjava/canonicalize_md.c	Fri May 17 13:21:44 2019 +0100
+++ b/src/java.base/unix/native/libjava/canonicalize_md.c	Thu May 23 11:07:37 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1994, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1994, 2019, 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
@@ -211,11 +211,10 @@
         char *p, *end, *r = NULL;
         char path[PATH_MAX + 1];
 
-        strncpy(path, original, sizeof(path));
-        if (path[PATH_MAX] != '\0') {
-            errno = ENAMETOOLONG;
-            return -1;
-        }
+        // strlen(original) <= PATH_MAX, see above
+        strncpy(path, original, PATH_MAX);
+        // append null for == case
+        path[PATH_MAX] = '\0';
         end = path + strlen(path);
 
         for (p = end; p > path;) {
--- a/src/java.compiler/share/classes/javax/lang/model/AnnotatedConstruct.java	Fri May 17 13:21:44 2019 +0100
+++ b/src/java.compiler/share/classes/javax/lang/model/AnnotatedConstruct.java	Thu May 23 11:07:37 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2019, 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
@@ -114,7 +114,7 @@
  *
  * @since 1.8
  * @jls 9.6 Annotation Types
- * @jls 9.6.3.3 @Inherited
+ * @jls 9.6.4.3 {@code @Inherited}
  */
 public interface AnnotatedConstruct {
     /**
--- a/src/java.compiler/share/classes/javax/lang/model/element/Element.java	Fri May 17 13:21:44 2019 +0100
+++ b/src/java.compiler/share/classes/javax/lang/model/element/Element.java	Thu May 23 11:07:37 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2019, 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
@@ -196,7 +196,7 @@
      * @see ModuleElement#getEnclosedElements
      * @see Elements#getAllMembers
      * @jls 8.8.9 Default Constructor
-     * @jls 8.9 Enums
+     * @jls 8.9 Enum Types
      * @revised 9
      * @spec JPMS
      */
--- a/src/java.compiler/share/classes/javax/lang/model/element/NestingKind.java	Fri May 17 13:21:44 2019 +0100
+++ b/src/java.compiler/share/classes/javax/lang/model/element/NestingKind.java	Thu May 23 11:07:37 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2019, 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
@@ -111,7 +111,7 @@
      * More specifically, an <i>inner</i> type element is any nested type element that
      * is not {@linkplain Modifier#STATIC static}.
      * @return whether or not the constant is nested
-     * @jls 14.3 Inner Classes and Enclosing Instances
+     * @jls 14.3 Local Class Declarations
      */
     public boolean isNested() {
         return this != TOP_LEVEL;
--- a/src/java.compiler/share/classes/javax/lang/model/util/ElementScanner6.java	Fri May 17 13:21:44 2019 +0100
+++ b/src/java.compiler/share/classes/javax/lang/model/util/ElementScanner6.java	Thu May 23 11:07:37 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2019, 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
@@ -180,6 +180,10 @@
      * {@inheritDoc}
      *
      * @implSpec This implementation scans the enclosed elements.
+     * Note that type parameters are <em>not</em> scanned by this
+     * implementation since type parameters are not considered to be
+     * {@linkplain TypeElement#getEnclosedElements enclosed elements
+     * of a type}.
      *
      * @param e  {@inheritDoc}
      * @param p  {@inheritDoc}
@@ -211,6 +215,8 @@
      * {@inheritDoc}
      *
      * @implSpec This implementation scans the parameters.
+     * Note that type parameters are <em>not</em> scanned by this
+     * implementation.
      *
      * @param e  {@inheritDoc}
      * @param p  {@inheritDoc}
--- a/src/java.compiler/share/classes/javax/lang/model/util/Types.java	Fri May 17 13:21:44 2019 +0100
+++ b/src/java.compiler/share/classes/javax/lang/model/util/Types.java	Thu May 23 11:07:37 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2019, 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
@@ -104,7 +104,7 @@
      * @return {@code true} if and only if the first type is assignable
      *          to the second
      * @throws IllegalArgumentException if given a type for an executable, package, or module
-     * @jls 5.2 Assignment Conversion
+     * @jls 5.2 Assignment Contexts
      */
     boolean isAssignable(TypeMirror t1, TypeMirror t2);
 
@@ -115,7 +115,7 @@
      * @param t2  the second type
      * @return {@code true} if and only if the first type contains the second
      * @throws IllegalArgumentException if given a type for an executable, package, or module
-     * @jls 4.5.1.1 Type Argument Containment and Equivalence
+     * @jls 4.5.1 Type Arguments of Parameterized Types
      */
     boolean contains(TypeMirror t1, TypeMirror t2);
 
--- a/src/java.instrument/share/classes/java/lang/instrument/Instrumentation.java	Fri May 17 13:21:44 2019 +0100
+++ b/src/java.instrument/share/classes/java/lang/instrument/Instrumentation.java	Thu May 23 11:07:37 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2019, 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
@@ -65,6 +65,9 @@
  * <p>
  * Once an agent acquires an <code>Instrumentation</code> instance,
  * the agent may call methods on the instance at any time.
+ * <p>
+ * @apiNote This interface is not intended to be implemented outside of
+ * the java.instrument module.
  *
  * @since   1.5
  */
--- a/src/java.rmi/share/classes/module-info.java	Fri May 17 13:21:44 2019 +0100
+++ b/src/java.rmi/share/classes/module-info.java	Thu May 23 11:07:37 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2019, 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
@@ -31,12 +31,8 @@
  * object registry, and the <em>{@index rmid rmid tool}</em> tool to start
  * the activation system daemon.
  *
- * <dl style="font-family:'DejaVu Sans', Arial, Helvetica, sans serif">
- * <dt class="simpleTagLabel">Tool Guides:</dt>
- * <dd> {@extLink rmiregistry_tool_reference rmiregistry},
- *      {@extLink rmid_tool_reference rmid}
- * </dd>
- * </dl>
+ * @toolGuide rmiregistry
+ * @toolGuide rmid
  *
  * @uses java.rmi.server.RMIClassLoaderSpi
  *
--- a/src/java.scripting/share/classes/module-info.java	Fri May 17 13:21:44 2019 +0100
+++ b/src/java.scripting/share/classes/module-info.java	Thu May 23 11:07:37 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2019, 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
@@ -31,10 +31,7 @@
  * that supports executing JavaScript and other languages if its corresponding
  * script engine is installed.
  *
- * <dl style="font-family:'DejaVu Sans', Arial, Helvetica, sans serif">
- * <dt class="simpleTagLabel">Tool Guides:
- * <dd> {@extLink jrunscript_tool_reference jrunscript}</dd>
- * </dl>
+ * @toolGuide jrunscript
  *
  * @uses javax.script.ScriptEngineFactory
  *
--- a/src/java.xml/share/classes/javax/xml/parsers/DocumentBuilderFactory.java	Fri May 17 13:21:44 2019 +0100
+++ b/src/java.xml/share/classes/javax/xml/parsers/DocumentBuilderFactory.java	Thu May 23 11:07:37 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2019, 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
@@ -39,7 +39,8 @@
  */
 
 public abstract class DocumentBuilderFactory {
-
+    private static final String DEFAULT_IMPL =
+            "com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl";
     private boolean validating = false;
     private boolean namespaceAware = false;
     private boolean whitespace = false;
@@ -55,6 +56,76 @@
     }
 
     /**
+     * Creates a new NamespaceAware instance of the {@code DocumentBuilderFactory}
+     * builtin system-default implementation. Parsers produced by the factory
+     * instance provides support for XML namespaces by default.
+     *
+     * @implSpec
+     * In addition to creating a factory instance using the same process as
+     * {@link #newDefaultInstance()}, this method must set NamespaceAware to true.
+     *
+     * @return a new instance of the {@code DocumentBuilderFactory} builtin
+     *         system-default implementation.
+     *
+     * @since 13
+     */
+    public static DocumentBuilderFactory newDefaultNSInstance() {
+        return makeNSAware(new DocumentBuilderFactoryImpl());
+    }
+
+    /**
+     * Creates a new NamespaceAware instance of a {@code DocumentBuilderFactory}.
+     * Parsers produced by the factory instance provides support for XML namespaces
+     * by default.
+     *
+     * @implSpec
+     * In addition to creating a factory instance using the same process as
+     * {@link #newInstance()}, this method must set NamespaceAware to true.
+     *
+     * @return a new instance of a {@code DocumentBuilderFactory}
+     *
+     * @throws FactoryConfigurationError in case of {@linkplain
+     *         java.util.ServiceConfigurationError service configuration error}
+     *         or if the implementation is not available or cannot be instantiated.
+     *
+     * @since 13
+     */
+    public static DocumentBuilderFactory newNSInstance() {
+        return makeNSAware(FactoryFinder.find(DocumentBuilderFactory.class, DEFAULT_IMPL));
+    }
+
+    /**
+     * Creates a new NamespaceAware instance of a {@code DocumentBuilderFactory}
+     * from the class name. Parsers produced by the factory instance provides
+     * support for XML namespaces by default.
+     *
+     * @implSpec
+     * In addition to creating a factory instance using the same process as
+     * {@link #newInstance(java.lang.String, java.lang.ClassLoader)}, this method
+     * must set NamespaceAware to true.
+     *
+     * @param factoryClassName a fully qualified factory class name that provides
+     *                         implementation of
+     *                         {@code javax.xml.parsers.DocumentBuilderFactory}.
+     *
+     * @param classLoader the {@code ClassLoader} used to load the factory class.
+     *                    If it is {@code null}, the current {@code Thread}'s
+     *                    context classLoader is used to load the factory class.
+     *
+     * @return a new instance of a {@code DocumentBuilderFactory}
+     *
+     * @throws FactoryConfigurationError if {@code factoryClassName} is {@code null}, or
+     *                                   the factory class cannot be loaded, instantiated.
+     *
+     * @since 13
+     */
+    public static DocumentBuilderFactory newNSInstance(String factoryClassName,
+            ClassLoader classLoader) {
+            return makeNSAware(FactoryFinder.newInstance(
+                    DocumentBuilderFactory.class, factoryClassName, classLoader, false));
+    }
+
+    /**
      * Creates a new instance of the {@code DocumentBuilderFactory} builtin
      * system-default implementation.
      *
@@ -141,7 +212,7 @@
                 /* The default property name according to the JAXP spec */
                 DocumentBuilderFactory.class, // "javax.xml.parsers.DocumentBuilderFactory"
                 /* The fallback implementation class name */
-                "com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl");
+                DEFAULT_IMPL);
     }
 
     /**
@@ -185,6 +256,11 @@
                         factoryClassName, classLoader, false);
     }
 
+    private static DocumentBuilderFactory makeNSAware(DocumentBuilderFactory dbf) {
+        dbf.setNamespaceAware(true);
+        return dbf;
+    }
+
     /**
      * Creates a new instance of a {@link javax.xml.parsers.DocumentBuilder}
      * using the currently configured parameters.
--- a/src/java.xml/share/classes/javax/xml/parsers/SAXParserFactory.java	Fri May 17 13:21:44 2019 +0100
+++ b/src/java.xml/share/classes/javax/xml/parsers/SAXParserFactory.java	Thu May 23 11:07:37 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2019, 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
@@ -41,6 +41,8 @@
  * @since 1.4
  */
 public abstract class SAXParserFactory {
+    private static final String DEFAULT_IMPL =
+            "com.sun.org.apache.xerces.internal.jaxp.SAXParserFactoryImpl";
 
     /**
      * Should Parsers be validating?
@@ -60,6 +62,76 @@
     }
 
     /**
+     * Creates a new NamespaceAware instance of the {@code SAXParserFactory}
+     * builtin system-default implementation. Parsers produced by the factory
+     * instance provides support for XML namespaces by default.
+     *
+     * @implSpec
+     * In addition to creating a factory instance using the same process as
+     * {@link #newDefaultInstance()}, this method must set NamespaceAware to true.
+     *
+     * @return a new instance of the {@code SAXParserFactory} builtin
+     *         system-default implementation.
+     *
+     * @since 13
+     */
+    public static SAXParserFactory newDefaultNSInstance() {
+        return makeNSAware(new SAXParserFactoryImpl());
+    }
+
+    /**
+     * Creates a new NamespaceAware instance of a {@code SAXParserFactory}.
+     * Parsers produced by the factory instance provides support for XML
+     * namespaces by default.
+     *
+     * @implSpec
+     * In addition to creating a factory instance using the same process as
+     * {@link #newInstance()}, this method must set NamespaceAware to true.
+     *
+     * @return a new instance of the {@code SAXParserFactory}
+     *
+     * @throws FactoryConfigurationError in case of {@linkplain
+     *         java.util.ServiceConfigurationError service configuration error}
+     *         or if the implementation is not available or cannot be instantiated.
+     *
+     * @since 13
+     */
+    public static SAXParserFactory newNSInstance() {
+        return makeNSAware(FactoryFinder.find(SAXParserFactory.class, DEFAULT_IMPL));
+    }
+
+    /**
+     * Creates a new NamespaceAware instance of a {@code SAXParserFactory} from
+     * the class name. Parsers produced by the factory instance provides
+     * support for XML namespaces by default.
+     *
+     * @implSpec
+     * In addition to creating a factory instance using the same process as
+     * {@link #newInstance(java.lang.String, java.lang.ClassLoader)}, this method
+     * must set NamespaceAware to true.
+     *
+     * @param factoryClassName a fully qualified factory class name that provides
+     *                         implementation of
+     *                         {@code javax.xml.parsers.SAXParserFactory}.
+     *
+     * @param classLoader the {@code ClassLoader} used to load the factory class.
+     *                    If it is {@code null}, the current {@code Thread}'s
+     *                    context classLoader is used to load the factory class.
+     *
+     * @return a new instance of the {@code SAXParserFactory}
+     *
+     * @throws FactoryConfigurationError if {@code factoryClassName} is {@code null}, or
+     *                                   the factory class cannot be loaded, instantiated.
+     *
+     * @since 13
+     */
+    public static SAXParserFactory newNSInstance(String factoryClassName,
+            ClassLoader classLoader) {
+            return makeNSAware(FactoryFinder.newInstance(
+                    SAXParserFactory.class, factoryClassName, classLoader, false));
+    }
+
+    /**
      * Creates a new instance of the {@code SAXParserFactory} builtin
      * system-default implementation.
      *
@@ -148,7 +220,7 @@
                 /* The default property name according to the JAXP spec */
                 SAXParserFactory.class,
                 /* The fallback implementation class name */
-                "com.sun.org.apache.xerces.internal.jaxp.SAXParserFactoryImpl");
+                DEFAULT_IMPL);
     }
 
     /**
@@ -192,6 +264,11 @@
                     factoryClassName, classLoader, false);
     }
 
+    private static SAXParserFactory makeNSAware(SAXParserFactory spf) {
+        spf.setNamespaceAware(true);
+        return spf;
+    }
+
     /**
      * Creates a new instance of a SAXParser using the currently
      * configured factory parameters.
--- a/src/jdk.compiler/share/classes/com/sun/source/tree/BinaryTree.java	Fri May 17 13:21:44 2019 +0100
+++ b/src/jdk.compiler/share/classes/com/sun/source/tree/BinaryTree.java	Thu May 23 11:07:37 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2019, 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
@@ -40,8 +40,8 @@
  * @jls 15.20 Relational Operators
  * @jls 15.21 Equality Operators
  * @jls 15.22 Bitwise and Logical Operators
- * @jls 15.23 Conditional-And Operator &&
- * @jls 15.24 Conditional-Or Operator ||
+ * @jls 15.23 Conditional-And Operator {@code &&}
+ * @jls 15.24 Conditional-Or Operator {@code ||}
  *
  * @author Peter von der Ah&eacute;
  * @author Jonathan Gibbons
--- a/src/jdk.compiler/share/classes/com/sun/source/tree/ModifiersTree.java	Fri May 17 13:21:44 2019 +0100
+++ b/src/jdk.compiler/share/classes/com/sun/source/tree/ModifiersTree.java	Thu May 23 11:07:37 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2019, 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
@@ -45,7 +45,7 @@
  * @jls 8.5.1 Static Member Type Declarations
  * @jls 8.8.3 Constructor Modifiers
  * @jls 9.1.1 Interface Modifiers
- * @jls 9.7   Annotations
+ * @jls 9.7 Annotations
  *
  * @author Peter von der Ah&eacute;
  * @author Jonathan Gibbons
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Types.java	Fri May 17 13:21:44 2019 +0100
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Types.java	Thu May 23 11:07:37 2019 +0100
@@ -2733,7 +2733,7 @@
      * signature</em> of the other.  This is <b>not</b> an equivalence
      * relation.
      *
-     * @jls section 8.4.2.
+     * @jls 8.4.2 Method Signature
      * @see #overrideEquivalent(Type t, Type s)
      * @param t first signature (possibly raw).
      * @param s second signature (could be subjected to erasure).
@@ -2752,7 +2752,7 @@
      * equivalence</em>.  This is the natural extension of
      * isSubSignature to an equivalence relation.
      *
-     * @jls section 8.4.2.
+     * @jls 8.4.2 Method Signature
      * @see #isSubSignature(Type t, Type s)
      * @param t a signature (possible raw, could be subjected to
      * erasure).
@@ -4214,7 +4214,7 @@
 
     /**
      * Return-Type-Substitutable.
-     * @jls section 8.4.5
+     * @jls 8.4.5 Method Result
      */
     public boolean returnTypeSubstitutable(Type r1, Type r2) {
         if (hasSameArgs(r1, r2))
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java	Fri May 17 13:21:44 2019 +0100
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java	Thu May 23 11:07:37 2019 +0100
@@ -4222,7 +4222,7 @@
          * @param tree    The tree making up the variable reference.
          * @param env     The current environment.
          * @param v       The variable's symbol.
-         * @jls  section 8.9 Enums
+         * @jls 8.9 Enum Types
          */
         private void checkEnumInitializer(JCTree tree, Env<AttrContext> env, VarSymbol v) {
             // JLS:
--- a/src/jdk.compiler/share/classes/module-info.java	Fri May 17 13:21:44 2019 +0100
+++ b/src/jdk.compiler/share/classes/module-info.java	Thu May 23 11:07:37 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2019, 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
@@ -55,10 +55,7 @@
  * {@code jdk.zipfs} module, must be available if the compiler is to be able
  * to read JAR files.
  *
- * <dl style="font-family:'DejaVu Sans', Arial, Helvetica, sans serif">
- * <dt class="simpleTagLabel">Tool Guides:
- * <dd>{@extLink javac_tool_reference javac}
- * </dl>
+ * @toolGuide javac
  *
  * @provides java.util.spi.ToolProvider
  * @provides com.sun.tools.javac.platform.PlatformProvider
--- a/src/jdk.hotspot.agent/share/classes/module-info.java	Fri May 17 13:21:44 2019 +0100
+++ b/src/jdk.hotspot.agent/share/classes/module-info.java	Thu May 23 11:07:37 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2019, 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
@@ -30,10 +30,7 @@
  * attach to a running Java Virtual Machine (JVM) or launch a postmortem
  * debugger to analyze the content of a core-dump from a crashed JVM.
  *
- * <dl style="font-family:'DejaVu Sans', Arial, Helvetica, sans serif">
- * <dt class="simpleTagLabel">Tool Guides:</dt>
- * <dd> {@extLink jhsdb_tool_reference jhsdb}</dd>
- * </dl>
+ * @toolGuide jhsdb
  *
  * @moduleGraph
  * @since 9
--- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/CommandProcessor.java	Fri May 17 13:21:44 2019 +0100
+++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/CommandProcessor.java	Thu May 23 11:07:37 2019 +0100
@@ -536,7 +536,8 @@
                 // Not an address
                 boolean all = name.equals("-a");
                 Threads threads = VM.getVM().getThreads();
-                for (JavaThread thread = threads.first(); thread != null; thread = thread.next()) {
+                for (int i = 0; i < threads.getNumberOfThreads(); i++) {
+                    JavaThread thread = threads.getJavaThreadAt(i);
                     ByteArrayOutputStream bos = new ByteArrayOutputStream();
                     thread.printThreadIDOn(new PrintStream(bos));
                     if (all || bos.toString().equals(name)) {
@@ -898,7 +899,8 @@
                     String name = t.nextToken();
                     boolean all = name.equals("-a");
                     Threads threads = VM.getVM().getThreads();
-                    for (JavaThread thread = threads.first(); thread != null; thread = thread.next()) {
+                    for (int i = 0; i < threads.getNumberOfThreads(); i++) {
+                        JavaThread thread = threads.getJavaThreadAt(i);
                         ByteArrayOutputStream bos = new ByteArrayOutputStream();
                         thread.printThreadIDOn(new PrintStream(bos));
                         if (all || bos.toString().equals(name)) {
@@ -927,7 +929,8 @@
                     String name = t.nextToken();
                     boolean all = name.equals("-a");
                     Threads threads = VM.getVM().getThreads();
-                    for (JavaThread thread = threads.first(); thread != null; thread = thread.next()) {
+                    for (int i = 0; i < threads.getNumberOfThreads(); i++) {
+                        JavaThread thread = threads.getJavaThreadAt(i);
                         ByteArrayOutputStream bos = new ByteArrayOutputStream();
                         thread.printThreadIDOn(new PrintStream(bos));
                         if (all || bos.toString().equals(name)) {
@@ -954,7 +957,8 @@
                     String name = t.nextToken();
                     boolean all = name.equals("-a");
                     Threads threads = VM.getVM().getThreads();
-                    for (JavaThread thread = threads.first(); thread != null; thread = thread.next()) {
+                    for (int i = 0; i < threads.getNumberOfThreads(); i++) {
+                        JavaThread thread = threads.getJavaThreadAt(i);
                         ByteArrayOutputStream bos = new ByteArrayOutputStream();
                         thread.printThreadIDOn(new PrintStream(bos));
                         if (all || bos.toString().equals(name)) {
@@ -1437,7 +1441,8 @@
                 final long stride = VM.getVM().getAddressSize();
                 if (type.equals("threads")) {
                     Threads threads = VM.getVM().getThreads();
-                    for (JavaThread thread = threads.first(); thread != null; thread = thread.next()) {
+                    for (int i = 0; i < threads.getNumberOfThreads(); i++) {
+                        JavaThread thread = threads.getJavaThreadAt(i);
                         Address base = thread.getStackBase();
                         Address end = thread.getLastJavaSP();
                         if (end == null) continue;
@@ -1561,7 +1566,8 @@
                     String name = t.nextToken();
                     Threads threads = VM.getVM().getThreads();
                     boolean all = name.equals("-a");
-                    for (JavaThread thread = threads.first(); thread != null; thread = thread.next()) {
+                    for (int i = 0; i < threads.getNumberOfThreads(); i++) {
+                        JavaThread thread = threads.getJavaThreadAt(i);
                         ByteArrayOutputStream bos = new ByteArrayOutputStream();
                         thread.printThreadIDOn(new PrintStream(bos));
                         if (all || bos.toString().equals(name)) {
@@ -1590,7 +1596,8 @@
                     String name = t.nextToken();
                     Threads threads = VM.getVM().getThreads();
                     boolean all = name.equals("-a");
-                    for (JavaThread thread = threads.first(); thread != null; thread = thread.next()) {
+                    for (int i = 0; i < threads.getNumberOfThreads(); i++) {
+                        JavaThread thread = threads.getJavaThreadAt(i);
                         ByteArrayOutputStream bos = new ByteArrayOutputStream();
                         thread.printThreadIDOn(new PrintStream(bos));
                         if (all || bos.toString().equals(name)) {
@@ -1613,7 +1620,8 @@
                     usage();
                 } else {
                     Threads threads = VM.getVM().getThreads();
-                    for (JavaThread thread = threads.first(); thread != null; thread = thread.next()) {
+                    for (int i = 0; i < threads.getNumberOfThreads(); i++) {
+                        JavaThread thread = threads.getJavaThreadAt(i);
                         thread.printThreadIDOn(out);
                         out.println(" " + thread.getThreadName());
                         thread.printInfoOn(out);
@@ -1631,7 +1639,8 @@
                     ArrayList nmethods = new ArrayList();
                     Threads threads = VM.getVM().getThreads();
                     HTMLGenerator gen = new HTMLGenerator(false);
-                    for (JavaThread thread = threads.first(); thread != null; thread = thread.next()) {
+                    for (int i = 0; i < threads.getNumberOfThreads(); i++) {
+                        JavaThread thread = threads.getJavaThreadAt(i);
                         try {
                             for (JavaVFrame vf = thread.getLastJavaVFrameDbg(); vf != null; vf = vf.javaSender()) {
                                 if (vf instanceof CompiledVFrame) {
--- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/debugger/bsd/BsdDebuggerLocal.java	Fri May 17 13:21:44 2019 +0100
+++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/debugger/bsd/BsdDebuggerLocal.java	Thu May 23 11:07:37 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2019, 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
@@ -619,10 +619,10 @@
         Threads threads = VM.getVM().getThreads();
         int len = threads.getNumberOfThreads();
         long[] result = new long[len * 3];    // triple
-        JavaThread t = threads.first();
         long beg, end;
         int i = 0;
-        while (t != null) {
+        for (int k = 0; k < threads.getNumberOfThreads(); k++) {
+            JavaThread t = threads.getJavaThreadAt(k);
             end = t.getStackBaseValue();
             beg = end - t.getStackSize();
             BsdThread bsdt = (BsdThread)t.getThreadProxy();
@@ -631,7 +631,6 @@
             result[i] = uid;
             result[i + 1] = beg;
             result[i + 2] = end;
-            t = t.next();
             i += 3;
         }
         return result;
--- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/ObjectHeap.java	Fri May 17 13:21:44 2019 +0100
+++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/ObjectHeap.java	Thu May 23 11:07:37 2019 +0100
@@ -357,7 +357,9 @@
     // end.
 
     if (VM.getVM().getUseTLAB()) {
-      for (JavaThread thread = VM.getVM().getThreads().first(); thread != null; thread = thread.next()) {
+      Threads threads = VM.getVM().getThreads();
+      for (int i = 0; i < threads.getNumberOfThreads(); i++) {
+        JavaThread thread = threads.getJavaThreadAt(i);
         ThreadLocalAllocBuffer tlab = thread.tlab();
         if (tlab.start() != null) {
           if ((tlab.top() == null) || (tlab.end() == null)) {
--- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/DeadlockDetector.java	Fri May 17 13:21:44 2019 +0100
+++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/DeadlockDetector.java	Thu May 23 11:07:37 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2004, 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 2019, 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
@@ -146,7 +146,9 @@
 
     private static void createThreadTable() {
         threadTable = new HashMap();
-        for (JavaThread cur = threads.first(); cur != null; cur = cur.next()) {
+        Threads threads = VM.getVM().getThreads();
+        for (int i = 0; i < threads.getNumberOfThreads(); i++) {
+            JavaThread cur = threads.getJavaThreadAt(i);
             // initialize dfn for each thread to -1
             threadTable.put(cur, new Integer(-1));
         }
--- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/JavaThread.java	Fri May 17 13:21:44 2019 +0100
+++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/JavaThread.java	Thu May 23 11:07:37 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2019, 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
@@ -41,7 +41,6 @@
 public class JavaThread extends Thread {
   private static final boolean DEBUG = System.getProperty("sun.jvm.hotspot.runtime.JavaThread.DEBUG") != null;
 
-  private static AddressField  nextField;
   private static sun.jvm.hotspot.types.OopField threadObjField;
   private static AddressField  anchorField;
   private static AddressField  lastJavaSPField;
@@ -84,7 +83,6 @@
     Type type = db.lookupType("JavaThread");
     Type anchorType = db.lookupType("JavaFrameAnchor");
 
-    nextField         = type.getAddressField("_next");
     threadObjField    = type.getOopField("_threadObj");
     anchorField       = type.getAddressField("_anchor");
     lastJavaSPField   = anchorType.getAddressField("_last_Java_sp");
@@ -120,15 +118,6 @@
     this.access = access;
   }
 
-  public JavaThread next() {
-    Address threadAddr = nextField.getValue(addr);
-    if (threadAddr == null) {
-      return null;
-    }
-
-    return VM.getVM().getThreads().createJavaThreadWrapper(threadAddr);
-  }
-
   /** NOTE: for convenience, this differs in definition from the underlying VM.
       Only "pure" JavaThreads return true; CompilerThreads, the CodeCacheSweeperThread,
       JVMDIDebuggerThreads return false.
--- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/Threads.java	Fri May 17 13:21:44 2019 +0100
+++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/Threads.java	Thu May 23 11:07:37 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2019, 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
@@ -42,12 +42,41 @@
 import sun.jvm.hotspot.runtime.bsd_amd64.BsdAMD64JavaThreadPDAccess;
 import sun.jvm.hotspot.utilities.*;
 
+class ThreadsList extends VMObject {
+    private static AddressField  threadsField;
+    private static CIntegerField lengthField;
+
+    static {
+        VM.registerVMInitializedObserver((o, d) -> initialize(VM.getVM().getTypeDataBase()));
+    }
+
+    private static synchronized void initialize(TypeDataBase db) {
+        Type type = db.lookupType("ThreadsList");
+        lengthField = type.getCIntegerField("_length");
+        threadsField = type.getAddressField("_threads");
+    }
+
+    public Address getJavaThreadAddressAt(int i) {
+      Address threadAddr = threadsField.getValue(addr);
+      Address at = threadAddr.getAddressAt(VM.getVM().getAddressSize() * i);
+      return at;
+    }
+
+    public long length() {
+        return lengthField.getValue(addr);
+    }
+
+    public ThreadsList(Address addr) {
+        super(addr);
+    }
+}
+
 public class Threads {
     private static JavaThreadFactory threadFactory;
     private static AddressField      threadListField;
-    private static CIntegerField     numOfThreadsField;
     private static VirtualConstructor virtualConstructor;
     private static JavaThreadPDAccess access;
+    private static ThreadsList _list;
 
     static {
         VM.registerVMInitializedObserver(new Observer() {
@@ -58,10 +87,8 @@
     }
 
     private static synchronized void initialize(TypeDataBase db) {
-        Type type = db.lookupType("Threads");
-
-        threadListField = type.getAddressField("_thread_list");
-        numOfThreadsField = type.getCIntegerField("_number_of_threads");
+        Type type = db.lookupType("ThreadsSMRSupport");
+        threadListField = type.getAddressField("_java_thread_list");
 
         // Instantiate appropriate platform-specific JavaThreadFactory
         String os  = VM.getVM().getOS();
@@ -134,6 +161,7 @@
     }
 
     public Threads() {
+        _list = VMObjectFactory.newObject(ThreadsList.class, threadListField.getValue());
     }
 
     /** NOTE: this returns objects of type JavaThread, CompilerThread,
@@ -147,17 +175,15 @@
       false for the three subclasses. FIXME: should reconsider the
       inheritance hierarchy; see {@link
       sun.jvm.hotspot.runtime.JavaThread#isJavaThread}. */
-    public JavaThread first() {
-        Address threadAddr = threadListField.getValue();
-        if (threadAddr == null) {
-            return null;
+    public JavaThread getJavaThreadAt(int i) {
+        if (i < _list.length()) {
+            return createJavaThreadWrapper(_list.getJavaThreadAddressAt(i));
         }
-
-        return createJavaThreadWrapper(threadAddr);
+        return null;
     }
 
     public int getNumberOfThreads() {
-        return (int) numOfThreadsField.getValue();
+        return (int) _list.length();
     }
 
     /** Routine for instantiating appropriately-typed wrapper for a
@@ -177,7 +203,9 @@
     /** Memory operations */
     public void oopsDo(AddressVisitor oopVisitor) {
         // FIXME: add more of VM functionality
-        for (JavaThread thread = first(); thread != null; thread = thread.next()) {
+        Threads threads = VM.getVM().getThreads();
+        for (int i = 0; i < threads.getNumberOfThreads(); i++) {
+            JavaThread thread = threads.getJavaThreadAt(i);
             thread.oopsDo(oopVisitor);
         }
     }
@@ -185,15 +213,17 @@
     // refer to Threads::owning_thread_from_monitor_owner
     public JavaThread owningThreadFromMonitor(Address o) {
         if (o == null) return null;
-        for (JavaThread thread = first(); thread != null; thread = thread.next()) {
+        for (int i = 0; i < getNumberOfThreads(); i++) {
+            JavaThread thread = getJavaThreadAt(i);
             if (o.equals(thread.threadObjectAddress())) {
                 return thread;
             }
         }
 
-        for (JavaThread thread = first(); thread != null; thread = thread.next()) {
-          if (thread.isLockOwned(o))
-            return thread;
+        for (int i = 0; i < getNumberOfThreads(); i++) {
+            JavaThread thread = getJavaThreadAt(i);
+            if (thread.isLockOwned(o))
+                return thread;
         }
         return null;
     }
@@ -206,7 +236,8 @@
     // Get list of Java threads that are waiting to enter the specified monitor.
     public List getPendingThreads(ObjectMonitor monitor) {
         List pendingThreads = new ArrayList();
-        for (JavaThread thread = first(); thread != null; thread = thread.next()) {
+        for (int i = 0; i < getNumberOfThreads(); i++) {
+            JavaThread thread = getJavaThreadAt(i);
             if (thread.isCompilerThread() || thread.isCodeCacheSweeperThread()) {
                 continue;
             }
@@ -221,7 +252,8 @@
     // Get list of Java threads that have called Object.wait on the specified monitor.
     public List getWaitingThreads(ObjectMonitor monitor) {
         List pendingThreads = new ArrayList();
-        for (JavaThread thread = first(); thread != null; thread = thread.next()) {
+        for (int i = 0; i < getNumberOfThreads(); i++) {
+            JavaThread thread = getJavaThreadAt(i);
             ObjectMonitor waiting = thread.getCurrentWaitingMonitor();
             if (monitor.equals(waiting)) {
                 pendingThreads.add(thread);
--- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/tools/PStack.java	Fri May 17 13:21:44 2019 +0100
+++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/tools/PStack.java	Thu May 23 11:07:37 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2019, 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
@@ -201,7 +201,8 @@
       jframeCache = new HashMap();
       proxyToThread = new HashMap();
       Threads threads = VM.getVM().getThreads();
-      for (JavaThread cur = threads.first(); cur != null; cur = cur.next()) {
+      for (int i = 0; i < threads.getNumberOfThreads(); i++) {
+         JavaThread cur = threads.getJavaThreadAt(i);
          List tmp = new ArrayList(10);
          try {
             for (JavaVFrame vf = cur.getLastJavaVFrameDbg(); vf != null; vf = vf.javaSender()) {
--- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/tools/StackTrace.java	Fri May 17 13:21:44 2019 +0100
+++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/tools/StackTrace.java	Thu May 23 11:07:37 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2019, 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
@@ -71,8 +71,8 @@
                 concLocksPrinter = new ConcurrentLocksPrinter();
             }
             Threads threads = VM.getVM().getThreads();
-            int i = 1;
-            for (JavaThread cur = threads.first(); cur != null; cur = cur.next(), i++) {
+            for (int i = 0; i < threads.getNumberOfThreads(); i++) {
+                JavaThread cur = threads.getJavaThreadAt(i);
                 if (cur.isJavaThread()) {
                     cur.printThreadInfoOn(tty);
                     try {
--- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/ui/JavaThreadsPanel.java	Fri May 17 13:21:44 2019 +0100
+++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/ui/JavaThreadsPanel.java	Thu May 23 11:07:37 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2004, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2019, 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
@@ -459,12 +459,13 @@
     }
 
     private void cache() {
-        Threads threads = VM.getVM().getThreads();
-        for (JavaThread t = threads.first(); t != null; t = t.next()) {
-            if (t.isJavaThread()) {
-                cachedThreads.add(new CachedThread(t));
-            }
+      Threads threads = VM.getVM().getThreads();
+      for (int i = 0; i < threads.getNumberOfThreads(); i++) {
+        JavaThread t = threads.getJavaThreadAt(i);
+        if (t.isJavaThread()) {
+            cachedThreads.add(new CachedThread(t));
         }
+      }
     }
 
     private void decache() {
--- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/utilities/AbstractHeapGraphWriter.java	Fri May 17 13:21:44 2019 +0100
+++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/utilities/AbstractHeapGraphWriter.java	Thu May 23 11:07:37 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2004, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 2019, 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
@@ -129,15 +129,12 @@
 
     protected void writeJavaThreads() throws IOException {
         Threads threads = VM.getVM().getThreads();
-        JavaThread jt = threads.first();
-        int index = 1;
-        while (jt != null) {
+        for (int i = 0; i < threads.getNumberOfThreads(); i++) {
+            JavaThread jt = threads.getJavaThreadAt(i);
             if (jt.getThreadObj() != null) {
                 // Note that the thread serial number range is 1-to-N
-                writeJavaThread(jt, index);
-                index++;
+                writeJavaThread(jt, i + 1);
             }
-            jt = jt.next();
         }
     }
 
--- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/utilities/HeapHprofBinWriter.java	Fri May 17 13:21:44 2019 +0100
+++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/utilities/HeapHprofBinWriter.java	Thu May 23 11:07:37 2019 +0100
@@ -708,8 +708,8 @@
         int frameSerialNum = 0;
         int numThreads = 0;
         Threads threads = VM.getVM().getThreads();
-
-        for (JavaThread thread = threads.first(); thread != null; thread = thread.next()) {
+        for (int i = 0; i < threads.getNumberOfThreads(); i++) {
+            JavaThread thread = threads.getJavaThreadAt(i);
             Oop threadObj = thread.getThreadObj();
             if (threadObj != null && !thread.isExiting() && !thread.isHiddenFromExternalView()) {
 
--- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/utilities/PointerFinder.java	Fri May 17 13:21:44 2019 +0100
+++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/utilities/PointerFinder.java	Thu May 23 11:07:37 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2019, 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
@@ -56,7 +56,9 @@
 
         if (VM.getVM().getUseTLAB()) {
           // Try to find thread containing it
-          for (JavaThread t = VM.getVM().getThreads().first(); t != null; t = t.next()) {
+          Threads threads = VM.getVM().getThreads();
+          for (int i = 0; i < threads.getNumberOfThreads(); i++) {
+            JavaThread t = threads.getJavaThreadAt(i);
             ThreadLocalAllocBuffer tlab = t.tlab();
             if (tlab.contains(a)) {
               loc.inTLAB = true;
@@ -125,7 +127,9 @@
       return loc;
     }
     // Look in thread-local handles
-    for (JavaThread t = VM.getVM().getThreads().first(); t != null; t = t.next()) {
+    Threads threads = VM.getVM().getThreads();
+    for (int i = 0; i < threads.getNumberOfThreads(); i++) {
+      JavaThread t = threads.getJavaThreadAt(i);
       JNIHandleBlock handleBlock = t.activeHandles();
       if (handleBlock != null) {
         handleBlock = handleBlock.blockContainingHandle(a);
--- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/utilities/ReversePtrsAnalysis.java	Fri May 17 13:21:44 2019 +0100
+++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/utilities/ReversePtrsAnalysis.java	Thu May 23 11:07:37 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2019, 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
@@ -92,9 +92,9 @@
     heap = vm.getObjectHeap();
 
     // Do each thread's roots
-    for (JavaThread thread = VM.getVM().getThreads().first();
-         thread != null;
-         thread = thread.next()) {
+    Threads threads = VM.getVM().getThreads();
+    for (int i = 0; i < threads.getNumberOfThreads(); i++) {
+      JavaThread thread = threads.getJavaThreadAt(i);
       ByteArrayOutputStream bos = new ByteArrayOutputStream();
       thread.printThreadIDOn(new PrintStream(bos));
       String threadDesc =
--- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/utilities/soql/JSJavaVM.java	Fri May 17 13:21:44 2019 +0100
+++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/utilities/soql/JSJavaVM.java	Thu May 23 11:07:37 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2004, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 2019, 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
@@ -189,12 +189,12 @@
 
     private synchronized JSList getThreads() {
         if (threadsCache == null) {
-            List threads = new ArrayList(0);
-            threadsCache = factory.newJSList(threads);
-            JavaThread jthread = vm.getThreads().first();
-            while (jthread != null) {
-                threads.add(jthread);
-                jthread = jthread.next();
+            List threadsList = new ArrayList(0);
+            threadsCache = factory.newJSList(threadsList);
+            Threads threads = VM.getVM().getThreads();
+            for (int i = 0; i < threads.getNumberOfThreads(); i++) {
+                JavaThread thread = threads.getJavaThreadAt(i);
+                threadsList.add(thread);
             }
         }
         return threadsCache;
--- a/src/jdk.jartool/share/classes/module-info.java	Fri May 17 13:21:44 2019 +0100
+++ b/src/jdk.jartool/share/classes/module-info.java	Thu May 23 11:07:37 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2019, 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
@@ -36,11 +36,8 @@
  * or the {@linkplain java.util.ServiceLoader service loader} with the name
  * {@code "jar"}.
  *
- * <dl style="font-family:'DejaVu Sans', Arial, Helvetica, sans serif">
- * <dt class="simpleTagLabel">Tool Guides:
- * <dd>{@extLink jar_tool_reference jar},
- *     {@extLink jarsigner_tool_reference jarsigner}
- * </dl>
+ * @toolGuide jar
+ * @toolGuide jarsigner
  *
  * @moduleGraph
  * @since 9
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/AnnotationTypeWriterImpl.java	Fri May 17 13:21:44 2019 +0100
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/AnnotationTypeWriterImpl.java	Thu May 23 11:07:37 2019 +0100
@@ -43,6 +43,7 @@
 import jdk.javadoc.internal.doclets.toolkit.Content;
 import jdk.javadoc.internal.doclets.toolkit.util.CommentHelper;
 import jdk.javadoc.internal.doclets.toolkit.util.DocFileIOException;
+import jdk.javadoc.internal.doclets.toolkit.util.DocPath;
 
 /**
  * Generate the Class Information Page.
@@ -154,9 +155,9 @@
     public void printDocument(Content contentTree) throws DocFileIOException {
         String description = getDescription("declaration", annotationType);
         PackageElement pkg = utils.containingPackage(this.annotationType);
-        Content stylesheetContent = getLocalStylesheetContent(pkg);
+        List<DocPath> localStylesheets = getLocalStylesheets(pkg);
         printHtmlDocument(configuration.metakeywords.getMetaKeywords(annotationType),
-                description, stylesheetContent, contentTree);
+                description, localStylesheets, contentTree);
     }
 
     /**
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ClassWriterImpl.java	Fri May 17 13:21:44 2019 +0100
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ClassWriterImpl.java	Thu May 23 11:07:37 2019 +0100
@@ -55,6 +55,7 @@
 import jdk.javadoc.internal.doclets.toolkit.util.ClassTree;
 import jdk.javadoc.internal.doclets.toolkit.util.CommentHelper;
 import jdk.javadoc.internal.doclets.toolkit.util.DocFileIOException;
+import jdk.javadoc.internal.doclets.toolkit.util.DocPath;
 import jdk.javadoc.internal.doclets.toolkit.util.DocletConstants;
 
 /**
@@ -185,9 +186,9 @@
     public void printDocument(Content contentTree) throws DocFileIOException {
         String description = getDescription("declaration", typeElement);
         PackageElement pkg = utils.containingPackage(typeElement);
-        Content stylesheetContent = getLocalStylesheetContent(pkg);
+        List<DocPath> localStylesheets = getLocalStylesheets(pkg);
         printHtmlDocument(configuration.metakeywords.getMetaKeywords(typeElement),
-                description, stylesheetContent, contentTree);
+                description, localStylesheets, contentTree);
     }
 
     /**
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/DocFilesHandlerImpl.java	Fri May 17 13:21:44 2019 +0100
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/DocFilesHandlerImpl.java	Thu May 23 11:07:37 2019 +0100
@@ -206,7 +206,7 @@
         footer.add(navBar.getContent(false));
         docletWriter.addBottom(footer);
         htmlContent.add(footer);
-        docletWriter.printHtmlDocument(Collections.emptyList(), null, localTagsContent, htmlContent);
+        docletWriter.printHtmlDocument(Collections.emptyList(), null, localTagsContent, Collections.emptyList(), htmlContent);
     }
 
 
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlConfiguration.java	Fri May 17 13:21:44 2019 +0100
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlConfiguration.java	Thu May 23 11:07:37 2019 +0100
@@ -452,13 +452,17 @@
         return null;
     }
 
-    public DocFile getMainStylesheet() {
-        return stylesheetfile.isEmpty() ? null : DocFile.createFileForInput(this, stylesheetfile);
+    public DocPath getMainStylesheet() {
+        if(!stylesheetfile.isEmpty()){
+            DocFile docFile = DocFile.createFileForInput(this, stylesheetfile);
+            return DocPath.create(docFile.getName());
+        }
+        return  null;
     }
 
-    public List<DocFile> getAdditionalStylesheets() {
+    public List<DocPath> getAdditionalStylesheets() {
         return additionalStylesheets.stream()
-                .map(ssf -> DocFile.createFileForInput(this, ssf))
+                .map(ssf -> DocFile.createFileForInput(this, ssf)).map(file -> DocPath.create(file.getName()))
                 .collect(Collectors.toList());
     }
 
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlDocletWriter.java	Fri May 17 13:21:44 2019 +0100
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlDocletWriter.java	Thu May 23 11:07:37 2019 +0100
@@ -26,6 +26,7 @@
 package jdk.javadoc.internal.doclets.formats.html;
 
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.ListIterator;
@@ -399,7 +400,26 @@
                                   String description,
                                   Content body)
             throws DocFileIOException {
-        printHtmlDocument(metakeywords, description, new ContentBuilder(), body);
+        printHtmlDocument(metakeywords, description, new ContentBuilder(), Collections.emptyList(), body);
+    }
+
+    /**
+     * Generates the HTML document tree and prints it out.
+     *
+     * @param metakeywords Array of String keywords for META tag. Each element
+     *                     of the array is assigned to a separate META tag.
+     *                     Pass in null for no array
+     * @param description the content for the description META tag.
+     * @param localStylesheets local stylesheets to be included in the HEAD element
+     * @param body the body htmltree to be included in the document
+     * @throws DocFileIOException if there is a problem writing the file
+     */
+    public void printHtmlDocument(List<String> metakeywords,
+                                  String description,
+                                  List<DocPath> localStylesheets,
+                                  Content body)
+            throws DocFileIOException {
+        printHtmlDocument(metakeywords, description, new ContentBuilder(), localStylesheets, body);
     }
 
     /**
@@ -410,15 +430,19 @@
      *                     Pass in null for no array
      * @param description the content for the description META tag.
      * @param extraHeadContent any additional content to be included in the HEAD element
+     * @param localStylesheets local stylesheets to be included in the HEAD element
      * @param body the body htmltree to be included in the document
      * @throws DocFileIOException if there is a problem writing the file
      */
     public void printHtmlDocument(List<String> metakeywords,
                                   String description,
                                   Content extraHeadContent,
+                                  List<DocPath> localStylesheets,
                                   Content body)
             throws DocFileIOException {
         Content htmlComment = contents.newPage;
+        List<DocPath> additionalStylesheets = configuration.getAdditionalStylesheets();
+        additionalStylesheets.addAll(localStylesheets);
         Head head = new Head(path, configuration.docletVersion)
                 .setTimestamp(!configuration.notimestamp)
                 .setDescription(description)
@@ -426,7 +450,7 @@
                 .setTitle(winTitle)
                 .setCharset(configuration.charset)
                 .addKeywords(metakeywords)
-                .setStylesheets(configuration.getMainStylesheet(), configuration.getAdditionalStylesheets())
+                .setStylesheets(configuration.getMainStylesheet(), additionalStylesheets)
                 .setIndex(configuration.createindex, mainBodyScript)
                 .addContent(extraHeadContent);
 
@@ -2188,8 +2212,42 @@
         return mainBodyScript;
     }
 
-    Content getLocalStylesheetContent(Element element) throws DocFileIOException {
-        Content stylesheetContent = new ContentBuilder();
+    /**
+     * Returns the path of module/package specific stylesheets for the element.
+     * @param element module/Package element
+     * @return list of path of module/package specific stylesheets
+     * @throws DocFileIOException
+     */
+    List<DocPath> getLocalStylesheets(Element element) throws DocFileIOException {
+        List<DocPath> stylesheets = new ArrayList<>();
+        DocPath basePath = null;
+        if (element instanceof PackageElement) {
+            stylesheets.addAll(getModuleStylesheets((PackageElement)element));
+            basePath = docPaths.forPackage((PackageElement)element);
+        } else if (element instanceof ModuleElement) {
+            basePath = DocPaths.forModule((ModuleElement)element);
+        }
+        for (DocPath stylesheet : getStylesheets(element)) {
+            stylesheets.add(basePath.resolve(stylesheet.getPath()));
+        }
+        return stylesheets;
+    }
+
+    private List<DocPath> getModuleStylesheets(PackageElement pkgElement) throws
+            DocFileIOException {
+        List<DocPath> moduleStylesheets = new ArrayList<>();
+        ModuleElement moduleElement = utils.containingModule(pkgElement);
+        if (moduleElement != null && !moduleElement.isUnnamed()) {
+            List<DocPath> localStylesheets = getStylesheets(moduleElement);
+            DocPath basePath = DocPaths.forModule(moduleElement);
+            for (DocPath stylesheet : localStylesheets) {
+                moduleStylesheets.add(basePath.resolve(stylesheet));
+            }
+        }
+        return moduleStylesheets;
+    }
+
+    private List<DocPath> getStylesheets(Element element) throws DocFileIOException {
         List<DocPath> localStylesheets = configuration.localStylesheetMap.get(element);
         if (localStylesheets == null) {
             DocFilesHandlerImpl docFilesHandler = (DocFilesHandlerImpl)configuration
@@ -2197,11 +2255,7 @@
             localStylesheets = docFilesHandler.getStylesheets();
             configuration.localStylesheetMap.put(element, localStylesheets);
         }
-        for (DocPath stylesheet : localStylesheets) {
-            stylesheetContent.add(HtmlTree.LINK("stylesheet",
-                    "text/css", stylesheet.getPath(), "Style"));
-        }
-        return stylesheetContent;
+        return localStylesheets;
     }
 
 }
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ModuleWriterImpl.java	Fri May 17 13:21:44 2019 +0100
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ModuleWriterImpl.java	Thu May 23 11:07:37 2019 +0100
@@ -902,8 +902,7 @@
     @Override
     public void printDocument(Content contentTree) throws DocFileIOException {
         printHtmlDocument(configuration.metakeywords.getMetaKeywordsForModule(mdle),
-                getDescription("declaration", mdle),
-                contentTree);
+                getDescription("declaration", mdle), getLocalStylesheets(mdle), contentTree);
     }
 
     /**
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/PackageWriterImpl.java	Fri May 17 13:21:44 2019 +0100
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/PackageWriterImpl.java	Thu May 23 11:07:37 2019 +0100
@@ -47,6 +47,7 @@
 import jdk.javadoc.internal.doclets.toolkit.PackageSummaryWriter;
 import jdk.javadoc.internal.doclets.toolkit.util.CommentHelper;
 import jdk.javadoc.internal.doclets.toolkit.util.DocFileIOException;
+import jdk.javadoc.internal.doclets.toolkit.util.DocPath;
 import jdk.javadoc.internal.doclets.toolkit.util.DocPaths;
 
 /**
@@ -317,9 +318,9 @@
     @Override
     public void printDocument(Content contentTree) throws DocFileIOException {
         String description = getDescription("declaration", packageElement);
-        Content stylesheetContent = getLocalStylesheetContent(packageElement);
+        List<DocPath> localStylesheets = getLocalStylesheets(packageElement);
         printHtmlDocument(configuration.metakeywords.getMetaKeywords(packageElement),
-                description, stylesheetContent, contentTree);
+                description, localStylesheets, contentTree);
     }
 
     /**
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/markup/Head.java	Fri May 17 13:21:44 2019 +0100
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/markup/Head.java	Thu May 23 11:07:37 2019 +0100
@@ -59,8 +59,8 @@
     private String description;
     private String generator;
     private boolean showTimestamp;
-    private DocFile mainStylesheetFile;
-    private List<DocFile> additionalStylesheetFiles = Collections.emptyList();
+    private DocPath mainStylesheet;
+    private List<DocPath> additionalStylesheets = Collections.emptyList();
     private boolean index;
     private Script mainBodyScript;
     private final List<Script> scripts;
@@ -157,14 +157,16 @@
 
     /**
      * Sets the main and any additional stylesheets to be listed in the HEAD element.
+     * The paths for the stylesheets must be relative to the root of the generated
+     * documentation hierarchy.
      *
      * @param main the main stylesheet, or null to use the default
      * @param additional a list of any additional stylesheets to be included
      * @return  this object
      */
-    public Head setStylesheets(DocFile main, List<DocFile> additional) {
-        this.mainStylesheetFile = main;
-        this.additionalStylesheetFiles = additional;
+    public Head setStylesheets(DocPath main, List<DocPath> additional) {
+        this.mainStylesheet = main;
+        this.additionalStylesheets = additional;
         return this;
     }
 
@@ -286,16 +288,13 @@
     }
 
     private void addStylesheets(HtmlTree tree) {
-        DocPath mainStylesheet;
-        if (mainStylesheetFile == null) {
+        if (mainStylesheet == null) {
             mainStylesheet = DocPaths.STYLESHEET;
-        } else {
-            mainStylesheet = DocPath.create(mainStylesheetFile.getName());
         }
         addStylesheet(tree, mainStylesheet);
 
-        for (DocFile file : additionalStylesheetFiles) {
-            addStylesheet(tree, DocPath.create(file.getName()));
+        for (DocPath path : additionalStylesheets) {
+            addStylesheet(tree, path);
         }
 
         if (index) {
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/builders/ModuleSummaryBuilder.java	Fri May 17 13:21:44 2019 +0100
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/builders/ModuleSummaryBuilder.java	Thu May 23 11:07:37 2019 +0100
@@ -28,6 +28,7 @@
 import javax.lang.model.element.ModuleElement;
 
 import jdk.javadoc.internal.doclets.toolkit.Content;
+import jdk.javadoc.internal.doclets.toolkit.DocFilesHandler;
 import jdk.javadoc.internal.doclets.toolkit.DocletException;
 import jdk.javadoc.internal.doclets.toolkit.ModuleSummaryWriter;
 
@@ -116,9 +117,8 @@
 
         moduleWriter.addModuleFooter(contentTree);
         moduleWriter.printDocument(contentTree);
-        // uncomment to support doc-files in modules
-        // DocFilesHandler docFilesHandler = configuration.getWriterFactory().getDocFilesWriter(mdle);
-        // docFilesHandler.copyDocFiles();
+        DocFilesHandler docFilesHandler = configuration.getWriterFactory().getDocFilesHandler(mdle);
+        docFilesHandler.copyDocFiles();
     }
 
     /**
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/resources/doclets.properties	Fri May 17 13:21:44 2019 +0100
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/resources/doclets.properties	Thu May 23 11:07:37 2019 +0100
@@ -160,13 +160,13 @@
 doclet.Properties_Inherited_From_Interface=Properties inherited from interface
 doclet.Properties_Declared_In_Class=Properties declared in class
 doclet.Properties_Declared_In_Interface=Properties declared in interface
-doclet.Annotation_Type_Member_Detail=Element Detail
-doclet.Enum_Constant_Detail=Enum Constant Detail
+doclet.Annotation_Type_Member_Detail=Element Details
+doclet.Enum_Constant_Detail=Enum Constant Details
 doclet.Constants_Summary=Constant Field Values
-doclet.Field_Detail=Field Detail
-doclet.Property_Detail=Property Detail
-doclet.Method_Detail=Method Detail
-doclet.Constructor_Detail=Constructor Detail
+doclet.Field_Detail=Field Details
+doclet.Property_Detail=Property Details
+doclet.Method_Detail=Method Details
+doclet.Constructor_Detail=Constructor Details
 doclet.Deprecated=Deprecated.
 doclet.DeprecatedForRemoval=Deprecated, for removal: This API element is subject to removal in a future version.
 doclet.Groupname_already_used=In -group option, groupname already used: {0}
--- a/src/jdk.javadoc/share/classes/module-info.java	Fri May 17 13:21:44 2019 +0100
+++ b/src/jdk.javadoc/share/classes/module-info.java	Thu May 23 11:07:37 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2019, 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
@@ -42,10 +42,7 @@
  * or the {@linkplain java.util.ServiceLoader service loader} with the name
  * {@code "javadoc"}.
  *
- * <dl style="font-family:'DejaVu Sans', Arial, Helvetica, sans serif">
- * <dt class="simpleTagLabel">Tool Guides:
- * <dd>{@extLink javadoc_tool_reference javadoc}
- * </dl>
+ * @toolGuide javadoc
  *
  * @provides java.util.spi.ToolProvider
  * @provides javax.tools.DocumentationTool
--- a/src/jdk.jcmd/share/classes/module-info.java	Fri May 17 13:21:44 2019 +0100
+++ b/src/jdk.jcmd/share/classes/module-info.java	Thu May 23 11:07:37 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2019, 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
@@ -28,16 +28,12 @@
  * such as the <em>{@index jcmd jcmd tool}</em>, <em>{@index jps jps tool}</em>,
  * <em>{@index jstat jstat tool}</em> tools.
  *
- * <dl style="font-family:'DejaVu Sans', Arial, Helvetica, sans serif">
- * <dt class="simpleTagLabel">Tool Guides:
- * <dd>
- * {@extLink jcmd_tool_reference jcmd},
- * {@extLink jinfo_tool_reference jinfo},
- * {@extLink jmap_tool_reference jmap},
- * {@extLink jps_tool_reference jps},
- * {@extLink jstack_tool_reference jstack},
- * {@extLink jstat_tool_reference jstat}
- * </dl>
+ * @toolGuide jcmd
+ * @toolGuide jinfo
+ * @toolGuide jmap
+ * @toolGuide jps
+ * @toolGuide jstack
+ * @toolGuide jstat
  *
  * @moduleGraph
  * @since 9
--- a/src/jdk.jconsole/share/classes/module-info.java	Fri May 17 13:21:44 2019 +0100
+++ b/src/jdk.jconsole/share/classes/module-info.java	Thu May 23 11:07:37 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2019, 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
@@ -28,11 +28,12 @@
  * for monitoring and managing a running application.
  *
  * <dl style="font-family:'DejaVu Sans', Arial, Helvetica, sans serif">
- * <dt class="simpleTagLabel">Tool Guides:
- * <dd>{@extLink jconsole_tool_reference jconsole},
- *     {@extLink using_jconsole Using JConsole}
+ * <dt class="simpleTagLabel">See Also:
+ * <dd>{@extLink using_jconsole Using JConsole}
  * </dl>
  *
+ * @toolGuide jconsole
+ *
  * @uses com.sun.tools.jconsole.JConsolePlugin
  *
  * @moduleGraph
--- a/src/jdk.jdeps/share/classes/module-info.java	Fri May 17 13:21:44 2019 +0100
+++ b/src/jdk.jdeps/share/classes/module-info.java	Thu May 23 11:07:37 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2019, 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
@@ -44,12 +44,9 @@
  * <em>jdeprscan</em> only exists as a command line tool, and does not provide
  * any direct API.
  *
- * <dl style="font-family:'DejaVu Sans', Arial, Helvetica, sans serif">
- * <dt class="simpleTagLabel">Tool Guides:
- * <dd>{@extLink javap_tool_reference javap},
- *     {@extLink jdeprscan_tool_reference jdeprscan},
- *     {@extLink jdeps_tool_reference jdeps}
- * </dl>
+ * @toolGuide javap
+ * @toolGuide jdeprscan
+ * @toolGuide jdeps
  *
  * @provides java.util.spi.ToolProvider
  *
--- a/src/jdk.jdi/share/classes/module-info.java	Fri May 17 13:21:44 2019 +0100
+++ b/src/jdk.jdi/share/classes/module-info.java	Thu May 23 11:07:37 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2019, 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
@@ -104,10 +104,7 @@
  * </blockquote>
  *
  *
- * <dl style="font-family:'DejaVu Sans', Arial, Helvetica, sans serif">
- * <dt class="simpleTagLabel">Tool Guides:
- * <dd>{@extLink jdb_tool_reference jdb}
- * </dl>
+ * @toolGuide jdb
  *
  * @provides com.sun.jdi.connect.Connector
  *
--- a/src/jdk.jdwp.agent/share/native/libdt_socket/socketTransport.c	Fri May 17 13:21:44 2019 +0100
+++ b/src/jdk.jdwp.agent/share/native/libdt_socket/socketTransport.c	Thu May 23 11:07:37 2019 +0100
@@ -394,6 +394,7 @@
 parseAllowedMask(const char *buffer, int isIPv4, struct in6_addr *result) {
     int prefixLen = 0;
     int maxValue = isIPv4 ? 32 : 128;
+    int i;
 
     do {
         if (*buffer < '0' || *buffer > '9') {
@@ -419,7 +420,7 @@
     memset(result, 0, sizeof(*result));
 
     // prefixLen <= 128, so we won't go over result's size
-    for (int i = 0; prefixLen > 0; i++, prefixLen -= 8) {
+    for (i = 0; prefixLen > 0; i++, prefixLen -= 8) {
         if (prefixLen >= 8) {
             // set the whole byte
             result->s6_addr[i] = 0xFF;
@@ -471,6 +472,7 @@
                          "invalid IP address in allow option");
         }
         if (mask != NULL) {
+            size_t i;
             if (parseAllowedMask(mask, isIPv4, &(_peers[_peers_cnt].netmask)) != JDWPTRANSPORT_ERROR_NONE) {
                 _peers_cnt = 0;
                 fprintf(stderr, "Error in allow option: '%s'\n", mask);
@@ -478,7 +480,7 @@
                              "invalid netmask in allow option");
             }
             // for safety update subnet to satisfy the mask
-            for (size_t i = 0; i < sizeof(_peers[_peers_cnt].subnet); i++) {
+            for (i = 0; i < sizeof(_peers[_peers_cnt].subnet); i++) {
                 _peers[_peers_cnt].subnet.s6_addr[i] &= _peers[_peers_cnt].netmask.s6_addr[i];
             }
         } else {
@@ -521,7 +523,8 @@
 
 static int
 isAddressInSubnet(const struct in6_addr *address, const struct in6_addr *subnet, const struct in6_addr *mask) {
-    for (size_t i = 0; i < sizeof(struct in6_addr); i++) {
+    size_t i;
+    for (i = 0; i < sizeof(struct in6_addr); i++) {
         if ((address->s6_addr[i] & mask->s6_addr[i]) != subnet->s6_addr[i]) {
             return 0;
         }
@@ -533,6 +536,7 @@
 isPeerAllowed(struct sockaddr_storage *peer) {
     struct in6_addr tmp;
     struct in6_addr *addr6;
+    int i;
     // _peers contains IPv6 subnet and mask (IPv4 is converted to mapped IPv6)
     if (peer->ss_family == AF_INET) {
         convertIPv4ToIPv6((struct sockaddr *)peer, &tmp);
@@ -541,7 +545,7 @@
         addr6 = &(((struct sockaddr_in6 *)peer)->sin6_addr);
     }
 
-    for (int i = 0; i < _peers_cnt; ++i) {
+    for (i = 0; i < _peers_cnt; ++i) {
         if (isAddressInSubnet(addr6, &(_peers[i].subnet), &(_peers[i].netmask))) {
             return 1;
         }
@@ -635,8 +639,10 @@
                                char** actualAddress)
 {
     int err;
+    int pass;
     struct addrinfo *addrInfo = NULL;
     struct addrinfo *listenAddr = NULL;
+    struct addrinfo *ai = NULL;
 
     /* no address provided */
     if ((address == NULL) || (address[0] == '\0')) {
@@ -649,8 +655,8 @@
     }
 
     /* 1st pass - preferredAddressFamily (by default IPv4), 2nd pass - the rest */
-    for (int pass = 0; pass < 2 && listenAddr == NULL; pass++) {
-        for (struct addrinfo *ai = addrInfo; ai != NULL; ai = ai->ai_next) {
+    for (pass = 0; pass < 2 && listenAddr == NULL; pass++) {
+        for (ai = addrInfo; ai != NULL; ai = ai->ai_next) {
             if ((pass == 0 && ai->ai_family == preferredAddressFamily) ||
                 (pass == 1 && ai->ai_family != preferredAddressFamily))
             {
@@ -860,7 +866,9 @@
                        jlong handshakeTimeout)
 {
     int err;
+    int pass;
     struct addrinfo *addrInfo = NULL;
+    struct addrinfo *ai;
 
     if (addressString == NULL || addressString[0] == '\0') {
         RETURN_ERROR(JDWPTRANSPORT_ERROR_ILLEGAL_ARGUMENT, "address is missing");
@@ -872,8 +880,8 @@
     }
 
     /* 1st pass - preferredAddressFamily (by default IPv4), 2nd pass - the rest */
-    for (int pass = 0; pass < 2 && socketFD < 0; pass++) {
-        for (struct addrinfo *ai = addrInfo; ai != NULL; ai = ai->ai_next) {
+    for (pass = 0; pass < 2 && socketFD < 0; pass++) {
+        for (ai = addrInfo; ai != NULL; ai = ai->ai_next) {
             if ((pass == 0 && ai->ai_family == preferredAddressFamily) ||
                 (pass == 1 && ai->ai_family != preferredAddressFamily))
             {
--- a/src/jdk.jfr/share/classes/module-info.java	Fri May 17 13:21:44 2019 +0100
+++ b/src/jdk.jfr/share/classes/module-info.java	Thu May 23 11:07:37 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2019, 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
@@ -27,11 +27,6 @@
  * Defines the API for JDK Flight Recorder.
  * <p>
  *
- * <dl style="font-family:'DejaVu Sans', Arial, Helvetica, sans serif">
- * <dt class="simpleTagLabel">Tool Guides:
- * <dd>{@extLink jfr_tool_reference jfr}
- * </dl>
- *
  * @moduleGraph
  * @since 9
  */
--- a/src/jdk.jfr/share/conf/jfr/default.jfc	Fri May 17 13:21:44 2019 +0100
+++ b/src/jdk.jfr/share/conf/jfr/default.jfc	Thu May 23 11:07:37 2019 +0100
@@ -445,6 +445,15 @@
       <setting name="enabled" control="gc-enabled-all">false</setting>
     </event>
 
+    <event name="jdk.ShenandoahHeapRegionInformation">
+      <setting name="enabled" control="gc-enabled-all">false</setting>
+      <setting name="period">everyChunk</setting>
+    </event>
+
+    <event name="jdk.ShenandoahHeapRegionStateChange">
+      <setting name="enabled" control="gc-enabled-all">false</setting>
+    </event>
+
     <event name="jdk.OldObjectSample">
       <setting name="enabled" control="memory-leak-detection-enabled">true</setting>
       <setting name="stackTrace" control="memory-leak-detection-stack-trace">false</setting>
--- a/src/jdk.jfr/share/conf/jfr/profile.jfc	Fri May 17 13:21:44 2019 +0100
+++ b/src/jdk.jfr/share/conf/jfr/profile.jfc	Thu May 23 11:07:37 2019 +0100
@@ -445,6 +445,15 @@
       <setting name="enabled" control="gc-enabled-all">false</setting>
     </event>
 
+    <event name="jdk.ShenandoahHeapRegionInformation">
+      <setting name="enabled" control="gc-enabled-all">false</setting>
+      <setting name="period">everyChunk</setting>
+    </event>
+
+    <event name="jdk.ShenandoahHeapRegionStateChange">
+      <setting name="enabled" control="gc-enabled-all">false</setting>
+    </event>
+
     <event name="jdk.OldObjectSample">
       <setting name="enabled" control="memory-leak-detection-enabled">true</setting>
       <setting name="stackTrace" control="memory-leak-detection-stack-trace">true</setting>
--- a/src/jdk.jlink/share/classes/module-info.java	Fri May 17 13:21:44 2019 +0100
+++ b/src/jdk.jlink/share/classes/module-info.java	Thu May 23 11:07:37 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2019, 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
@@ -30,8 +30,7 @@
  * the JDK implementation-specific container file for classes and resources.
  *
  * <p> This module provides the equivalent of command-line access to the
- * <em>{@extLink jlink_tool_reference jlink}</em> and
- * <em>{@extLink jmod_tool_reference jmod}</em> tools via the
+ * <em>jlink</em> and <em>jmod</em> tools via the
  * {@link java.util.spi.ToolProvider ToolProvider} SPI.
  * Instances of the tools can be obtained by calling
  * {@link java.util.spi.ToolProvider#findFirst ToolProvider.findFirst}
@@ -41,11 +40,8 @@
  * <p> <em>jimage</em> only exists
  * as a command-line tool, and does not provide any direct API.
  *
- * <dl style="font-family:'DejaVu Sans', Arial, Helvetica, sans serif">
- * <dt class="simpleTagLabel">Tool Guides:
- * <dd>{@extLink jlink_tool_reference jlink},
- *     {@extLink jmod_tool_reference jmod}
- * </dl>
+ * @toolGuide jlink
+ * @toolGuide jmod
  *
  * @provides java.util.spi.ToolProvider
  *
--- a/src/jdk.jshell/share/classes/jdk/jshell/ExpressionSnippet.java	Fri May 17 13:21:44 2019 +0100
+++ b/src/jdk.jshell/share/classes/jdk/jshell/ExpressionSnippet.java	Thu May 23 11:07:37 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2019, 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
@@ -36,7 +36,7 @@
  * and thus is thread-safe.
  *
  * @since 9
- * @jls 15: Expression.
+ * @jls 15 Expressions
  */
 public class ExpressionSnippet extends Snippet {
 
--- a/src/jdk.jshell/share/classes/jdk/jshell/ImportSnippet.java	Fri May 17 13:21:44 2019 +0100
+++ b/src/jdk.jshell/share/classes/jdk/jshell/ImportSnippet.java	Thu May 23 11:07:37 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2019, 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
@@ -36,7 +36,7 @@
  * and thus is thread-safe.
  *
  * @since 9
- * @jls 8.3: importDeclaration.
+ * @jls 7.5 Import Declarations
  */
 public class ImportSnippet extends PersistentSnippet {
 
--- a/src/jdk.jshell/share/classes/jdk/jshell/MethodSnippet.java	Fri May 17 13:21:44 2019 +0100
+++ b/src/jdk.jshell/share/classes/jdk/jshell/MethodSnippet.java	Thu May 23 11:07:37 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2019, 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
@@ -37,7 +37,7 @@
  * and thus is thread-safe.
  *
  * @since 9
- * @jls 8.4: MethodDeclaration.
+ * @jls 8.4 Method Declarations
  */
 public class MethodSnippet extends DeclarationSnippet {
 
--- a/src/jdk.jshell/share/classes/jdk/jshell/Snippet.java	Fri May 17 13:21:44 2019 +0100
+++ b/src/jdk.jshell/share/classes/jdk/jshell/Snippet.java	Thu May 23 11:07:37 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2019, 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
@@ -73,7 +73,7 @@
          * ({@link jdk.jshell.Snippet.SubKind#SINGLE_STATIC_IMPORT_SUBKIND}) --
          * use {@link jdk.jshell.Snippet#subKind()} to distinguish.
          *
-         * @jls 8.3: importDeclaration.
+         * @jls 7.5 Import Declarations
          * <P>
          * An import declaration is {@linkplain Kind#isPersistent() persistent}.
          */
@@ -91,7 +91,7 @@
          * annotation interfaces -- see {@link jdk.jshell.Snippet.SubKind} to
          * differentiate.
          *
-         * @jls 7.6: TypeDeclaration.
+         * @jls 7.6 Top Level Type Declarations
          * <P>
          * A type declaration is {@linkplain Kind#isPersistent() persistent}.
          */
@@ -101,7 +101,7 @@
          * A method declaration.
          * The snippet is an instance of {@link jdk.jshell.MethodSnippet}.
          *
-         * @jls 8.4: MethodDeclaration.
+         * @jls 8.4 Method Declarations
          * <P>
          * A method declaration is {@linkplain Kind#isPersistent() persistent}.
          */
@@ -116,7 +116,7 @@
          * variable representing an expression -- see
          * {@link jdk.jshell.Snippet.SubKind}to differentiate.
          *
-         * @jls 8.3: FieldDeclaration.
+         * @jls 8.3 Field Declarations
          * <P>
          * A variable declaration is {@linkplain Kind#isPersistent() persistent}.
          */
@@ -133,7 +133,7 @@
          * All other expression forms (operators, method calls, ...) generate a
          * scratch variable and so are instead of the VAR Kind.
          *
-         * @jls 15: Expression.
+         * @jls 15 Expressions
          */
         EXPRESSION(false),
 
@@ -141,7 +141,7 @@
          * A statement.
          * The snippet is an instance of {@link jdk.jshell.StatementSnippet}.
          *
-         * @jls 14.5: Statement.
+         * @jls 14.5 Statements
          */
         STATEMENT(false),
 
@@ -185,99 +185,97 @@
         /**
          * Single-Type-Import Declaration.
          * An import declaration of a single type.
-         * @jls 7.5.1 SingleTypeImportDeclaration.
+         * @jls 7.5.1 Single-Type-Import Declarations
          */
         SINGLE_TYPE_IMPORT_SUBKIND(Kind.IMPORT),
 
         /**
          * Type-Import-on-Demand Declaration.
          * A non-static "star" import.
-         * @jls 7.5.2. TypeImportOnDemandDeclaration.
+         * @jls 7.5.2 Type-Import-on-Demand Declarations
          */
         TYPE_IMPORT_ON_DEMAND_SUBKIND(Kind.IMPORT),
 
         /**
          * Single-Static-Import Declaration.
          * An import of a static member.
-         * @jls 7.5.3 Single-Static-Import.
+         * @jls 7.5.3 Single-Static-Import Declarations
          */
         SINGLE_STATIC_IMPORT_SUBKIND(Kind.IMPORT),
 
         /**
          * Static-Import-on-Demand Declaration.
          * A static "star" import of all static members of a named type.
-         * @jls 7.5.4. Static-Import-on-Demand Static "star" import.
+         * @jls 7.5.4 Static-Import-on-Demand Declarations
          */
         STATIC_IMPORT_ON_DEMAND_SUBKIND(Kind.IMPORT),
 
         /**
          * A class declaration.
          * A {@code SubKind} of {@link Kind#TYPE_DECL}.
-         * @jls 8.1. NormalClassDeclaration.
+         * @jls 8.1 Class Declarations
          */
         CLASS_SUBKIND(Kind.TYPE_DECL),
 
         /**
          * An interface declaration.
          * A {@code SubKind} of {@link Kind#TYPE_DECL}.
-         * @jls 9.1. NormalInterfaceDeclaration.
+         * @jls 9.1 Interface Declarations
          */
         INTERFACE_SUBKIND(Kind.TYPE_DECL),
 
         /**
          * An enum declaration.
          * A {@code SubKind} of {@link Kind#TYPE_DECL}.
-         * @jls 8.9. EnumDeclaration.
+         * @jls 8.9 Enum Types
          */
         ENUM_SUBKIND(Kind.TYPE_DECL),
 
         /**
          * An annotation interface declaration. A {@code SubKind} of
          * {@link Kind#TYPE_DECL}.
-         * @jls 9.6. AnnotationTypeDeclaration.
+         * @jls 9.6 Annotation Types
          */
         ANNOTATION_TYPE_SUBKIND(Kind.TYPE_DECL),
 
         /**
          * A method. The only {@code SubKind} for {@link Kind#METHOD}.
-         * @jls 8.4. MethodDeclaration.
+         * @jls 8.4 Method Declarations
          */
         METHOD_SUBKIND(Kind.METHOD),
 
         /**
          * A variable declaration without initializer.
          * A {@code SubKind} of {@link Kind#VAR}.
-         * @jls 8.3. VariableDeclarator without VariableInitializer in
-         * FieldDeclaration.
+         * @jls 8.3 Field Declarations
          */
         VAR_DECLARATION_SUBKIND(Kind.VAR, true, true),
 
         /**
          * A variable declaration with an initializer expression. A
          * {@code SubKind} of {@link Kind#VAR}.
-         * @jls 8.3. VariableDeclarator with VariableInitializer in
-         * FieldDeclaration.
+         * @jls 8.3 Field Declarations
          */
         VAR_DECLARATION_WITH_INITIALIZER_SUBKIND(Kind.VAR, true, true),
 
         /**
          * An expression whose value has been stored in a temporary variable. A
          * {@code SubKind} of {@link Kind#VAR}.
-         * @jls 15. Primary.
+         * @jls 15 Expressions
          */
         TEMP_VAR_EXPRESSION_SUBKIND(Kind.VAR, true, true),
 
         /**
          * A simple variable reference expression. A {@code SubKind} of
          * {@link Kind#EXPRESSION}.
-         * @jls 15.11. Field Access as 3.8. Identifier.
+         * @jls 15.11 Field Access Expressions
          */
         VAR_VALUE_SUBKIND(Kind.EXPRESSION, true, true),
 
         /**
          * An assignment expression. A {@code SubKind} of
          * {@link Kind#EXPRESSION}.
-         * @jls 15.26. Assignment.
+         * @jls 15.26 Assignment Operators
          */
         ASSIGNMENT_SUBKIND(Kind.EXPRESSION, true, true),
 
@@ -289,7 +287,7 @@
 
         /**
          * A statement. The only {@code SubKind} for {@link Kind#STATEMENT}.
-         * @jls 14.5. Statement.
+         * @jls 14.5 Statements
          */
         STATEMENT_SUBKIND(Kind.STATEMENT, true, false),
 
--- a/src/jdk.jshell/share/classes/jdk/jshell/StatementSnippet.java	Fri May 17 13:21:44 2019 +0100
+++ b/src/jdk.jshell/share/classes/jdk/jshell/StatementSnippet.java	Thu May 23 11:07:37 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2019, 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
@@ -36,7 +36,7 @@
  * and thus is thread-safe.
  *
  * @since 9
- * @jls 14.5: Statement.
+ * @jls 14.5 Statements
  */
 public class StatementSnippet extends Snippet {
 
--- a/src/jdk.jshell/share/classes/jdk/jshell/VarSnippet.java	Fri May 17 13:21:44 2019 +0100
+++ b/src/jdk.jshell/share/classes/jdk/jshell/VarSnippet.java	Thu May 23 11:07:37 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2019, 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
@@ -39,7 +39,7 @@
  * and thus is thread-safe.
  *
  * @since 9
- * @jls 8.3: FieldDeclaration.
+ * @jls 8.3 Field Declarations
  */
 public class VarSnippet extends DeclarationSnippet {
 
--- a/src/jdk.jshell/share/classes/module-info.java	Fri May 17 13:21:44 2019 +0100
+++ b/src/jdk.jshell/share/classes/module-info.java	Thu May 23 11:07:37 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2019, 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
@@ -24,9 +24,11 @@
  */
 
 /**
- * This module provides support for
- * Java Programming Language 'snippet' evaluating tools, such as
- * Read-Eval-Print Loops (REPLs), including the <em>{@index jshell jshell tool}</em> tool.
+ * Provides the <em>{@index jshell jshell tool}</em> tool for evaluating
+ * snippets of Java code, and defines a JDK-specific API for modeling and
+ * executing snippets.
+ * The JShell API supports Java Programming Language 'snippet' evaluating
+ * tools, such as Read-Eval-Print Loops (REPLs).
  * Separate packages support building tools, configuring the execution of tools,
  * and programmatically launching the existing Java shell tool.
  * <p>
@@ -52,10 +54,7 @@
  *     definitions.
  * </p>
  *
- * <dl style="font-family:'DejaVu Sans', Arial, Helvetica, sans serif">
- * <dt class="simpleTagLabel">Tool Guides:
- * <dd>{@extLink jshell_tool_reference jshell}
- * </dl>
+ * @toolGuide jshell
  *
  * @provides javax.tools.Tool
  * @provides jdk.jshell.spi.ExecutionControlProvider
--- a/src/jdk.jstatd/share/classes/module-info.java	Fri May 17 13:21:44 2019 +0100
+++ b/src/jdk.jstatd/share/classes/module-info.java	Thu May 23 11:07:37 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2019, 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
@@ -27,10 +27,7 @@
  * Defines the <em>{@index jstatd jstatd tool}</em> tool for starting a daemon
  * for the jstat tool to monitor JVM statistics remotely.
  *
- * <dl style="font-family:'DejaVu Sans', Arial, Helvetica, sans serif">
- * <dt class="simpleTagLabel">Tool Guides:
- * <dd>{@extLink jstatd_tool_reference jstatd}
- * </dl>
+ * @toolGuide jstatd
  *
  * @moduleGraph
  * @since 9
--- a/src/jdk.localedata/share/classes/sun/text/resources/ext/FormatData_ar.java	Fri May 17 13:21:44 2019 +0100
+++ b/src/jdk.localedata/share/classes/sun/text/resources/ext/FormatData_ar.java	Thu May 23 11:07:37 2019 +0100
@@ -212,6 +212,7 @@
                     "\u062a\u064a\u0634\u0648",
                     "\u0634\u0648\u0648\u0627",
                     "\u0647\u064a\u0633\u064a",
+                    "\u0631\u064a\u0648\u0627",
                 }
             },
             { "japanese.short.Eras",
@@ -221,6 +222,7 @@
                     "\u062a\u064a\u0634\u0648",
                     "\u0634\u0648\u0648\u0627",
                     "\u0647\u064a\u0633\u064a",
+                    "\u0631\u064a\u0648\u0627",
                 }
             },
             { "buddhist.Eras",
--- a/src/jdk.localedata/share/classes/sun/text/resources/ext/FormatData_es_PE.java	Fri May 17 13:21:44 2019 +0100
+++ b/src/jdk.localedata/share/classes/sun/text/resources/ext/FormatData_es_PE.java	Thu May 23 11:07:37 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2019, 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
@@ -63,6 +63,21 @@
                     "hh:mm a", // short time pattern
                 }
             },
+            { "NumberElements",
+                new String[] {
+                    ".", // decimal separator
+                    ",", // group (thousands) separator
+                    ";", // list separator
+                    "%", // percent sign
+                    "0", // native 0 digit
+                    "#", // pattern digit
+                    "-", // minus sign
+                    "E", // exponential
+                    "\u2030", // per mille
+                    "\u221e", // infinity
+                    "\ufffd" // NaN
+                }
+            },
             { "DatePatterns",
                 new String[] {
                     "EEEE d' de 'MMMM' de 'yyyy", // full date pattern
--- a/src/jdk.localedata/share/classes/sun/text/resources/ext/FormatData_ko.java	Fri May 17 13:21:44 2019 +0100
+++ b/src/jdk.localedata/share/classes/sun/text/resources/ext/FormatData_ko.java	Thu May 23 11:07:37 2019 +0100
@@ -192,6 +192,7 @@
                     "\ub2e4\uc774\uc1fc",
                     "\uc1fc\uc640",
                     "\ud5e4\uc774\uc138\uc774",
+                    "\ub808\uc774\uc640",
                 }
             },
             { "AmPmMarkers",
--- a/src/jdk.localedata/share/classes/sun/text/resources/ext/FormatData_th.java	Fri May 17 13:21:44 2019 +0100
+++ b/src/jdk.localedata/share/classes/sun/text/resources/ext/FormatData_th.java	Thu May 23 11:07:37 2019 +0100
@@ -245,6 +245,7 @@
                     "\u0e17\u0e30\u0e2d\u0e34\u0e42\u0e0a",
                     "\u0e42\u0e0a\u0e27\u0e30",
                     "\u0e40\u0e2e\u0e40\u0e0b",
+                    "\u0e40\u0e23\u0e27\u0e30",
                 }
             },
             { "japanese.short.Eras",
@@ -254,6 +255,7 @@
                     "\u0e17",
                     "\u0e0a",
                     "\u0e2e",
+                    "R",
                 }
             },
             { "buddhist.TimePatterns",
--- a/src/jdk.localedata/share/classes/sun/text/resources/ext/FormatData_zh.java	Fri May 17 13:21:44 2019 +0100
+++ b/src/jdk.localedata/share/classes/sun/text/resources/ext/FormatData_zh.java	Thu May 23 11:07:37 2019 +0100
@@ -282,6 +282,7 @@
                     "\u5927\u6b63",
                     "\u662d\u548c",
                     "\u5e73\u6210",
+                    "\u4ee4\u548c",
                 }
             },
             { "TimePatterns",
--- a/src/jdk.localedata/share/classes/sun/text/resources/ext/JavaTimeSupplementary_ar.java	Fri May 17 13:21:44 2019 +0100
+++ b/src/jdk.localedata/share/classes/sun/text/resources/ext/JavaTimeSupplementary_ar.java	Thu May 23 11:07:37 2019 +0100
@@ -157,6 +157,7 @@
             "\u062a\u064a\u0634\u0648",
             "\u0634\u0648\u0648\u0627",
             "\u0647\u064a\u0633\u064a",
+            "\u0631\u064a\u0648\u0627",
         };
 
         final String[] sharedShortEras = {
--- a/src/jdk.localedata/share/classes/sun/text/resources/ext/JavaTimeSupplementary_hi_IN.java	Fri May 17 13:21:44 2019 +0100
+++ b/src/jdk.localedata/share/classes/sun/text/resources/ext/JavaTimeSupplementary_hi_IN.java	Thu May 23 11:07:37 2019 +0100
@@ -241,6 +241,7 @@
                     "\u0924\u093e\u0908\u0936\u094b",
                     "\u0936\u094b\u0935\u093e",
                     "\u0939\u0947\u0908\u0938\u0947\u0908",
+                    "\u0930\u0947\u0907\u0935\u093e",
                 }
             },
             { "java.time.japanese.short.Eras",
@@ -250,6 +251,7 @@
                     "\u0924\u093e\u0908\u0936\u094b",
                     "\u0936\u094b\u0935\u093e",
                     "\u0939\u0947\u0908\u0938\u0947\u0908",
+                    "\u0930\u0947\u0907\u0935\u093e",
                 }
             },
             { "java.time.long.Eras",
--- a/src/jdk.localedata/share/classes/sun/text/resources/ext/JavaTimeSupplementary_hr.java	Fri May 17 13:21:44 2019 +0100
+++ b/src/jdk.localedata/share/classes/sun/text/resources/ext/JavaTimeSupplementary_hr.java	Thu May 23 11:07:37 2019 +0100
@@ -231,6 +231,7 @@
                     "Taish\u014d",
                     "Sh\u014dwa",
                     "Heisei",
+                    "Reiwa",
                 }
             },
             { "java.time.japanese.short.Eras",
@@ -240,6 +241,7 @@
                     "Taish\u014d",
                     "Sh\u014dwa",
                     "Heisei",
+                    "Reiwa",
                 }
             },
             { "java.time.long.Eras",
--- a/src/jdk.localedata/share/classes/sun/text/resources/ext/JavaTimeSupplementary_in.java	Fri May 17 13:21:44 2019 +0100
+++ b/src/jdk.localedata/share/classes/sun/text/resources/ext/JavaTimeSupplementary_in.java	Thu May 23 11:07:37 2019 +0100
@@ -148,6 +148,7 @@
             "Taish\u014d",
             "Sh\u014dwa",
             "Heisei",
+            "Reiwa",
         };
 
         final String[] sharedEras = {
--- a/src/jdk.localedata/share/classes/sun/text/resources/ext/JavaTimeSupplementary_ko.java	Fri May 17 13:21:44 2019 +0100
+++ b/src/jdk.localedata/share/classes/sun/text/resources/ext/JavaTimeSupplementary_ko.java	Thu May 23 11:07:37 2019 +0100
@@ -143,6 +143,7 @@
             "\ub2e4\uc774\uc1fc",
             "\uc1fc\uc640",
             "\ud5e4\uc774\uc138\uc774",
+            "\ub808\uc774\uc640",
         };
 
         final String[] sharedJavaTimeShortEras2 = {
--- a/src/jdk.localedata/share/classes/sun/text/resources/ext/JavaTimeSupplementary_lt.java	Fri May 17 13:21:44 2019 +0100
+++ b/src/jdk.localedata/share/classes/sun/text/resources/ext/JavaTimeSupplementary_lt.java	Thu May 23 11:07:37 2019 +0100
@@ -223,6 +223,7 @@
                     "Tai\u0161o",
                     "\u0160ova",
                     "Heisei",
+                    "Reiwa",
                 }
             },
             { "java.time.japanese.short.Eras",
@@ -232,6 +233,7 @@
                     "Tai\u0161o",
                     "\u0160ova",
                     "Heisei",
+                    "Reiwa",
                 }
             },
             { "java.time.long.Eras",
--- a/src/jdk.localedata/share/classes/sun/text/resources/ext/JavaTimeSupplementary_nl.java	Fri May 17 13:21:44 2019 +0100
+++ b/src/jdk.localedata/share/classes/sun/text/resources/ext/JavaTimeSupplementary_nl.java	Thu May 23 11:07:37 2019 +0100
@@ -265,6 +265,7 @@
                     "Taish\u014d",
                     "Sh\u014dwa",
                     "Heisei",
+                    "Reiwa",
                 }
             },
             { "java.time.japanese.short.Eras",
@@ -274,6 +275,7 @@
                     "Taish\u014d",
                     "Sh\u014dwa",
                     "Heisei",
+                    "Reiwa",
                 }
             },
             { "java.time.long.Eras",
--- a/src/jdk.localedata/share/classes/sun/text/resources/ext/JavaTimeSupplementary_no.java	Fri May 17 13:21:44 2019 +0100
+++ b/src/jdk.localedata/share/classes/sun/text/resources/ext/JavaTimeSupplementary_no.java	Thu May 23 11:07:37 2019 +0100
@@ -283,6 +283,7 @@
                     "Taish\u014d",
                     "Sh\u014dwa",
                     "Heisei",
+                    "Reiwa",
                 }
             },
             { "java.time.japanese.short.Eras",
@@ -292,6 +293,7 @@
                     "T",
                     "S",
                     "H",
+                    "R",
                 }
             },
             { "java.time.long.Eras",
--- a/src/jdk.localedata/share/classes/sun/text/resources/ext/JavaTimeSupplementary_ru.java	Fri May 17 13:21:44 2019 +0100
+++ b/src/jdk.localedata/share/classes/sun/text/resources/ext/JavaTimeSupplementary_ru.java	Thu May 23 11:07:37 2019 +0100
@@ -237,6 +237,7 @@
                     "\u042d\u043f\u043e\u0445\u0430 \u0422\u0430\u0439\u0441\u044c\u043e",
                     "\u0421\u044c\u043e\u0432\u0430",
                     "\u042d\u043f\u043e\u0445\u0430 \u0425\u044d\u0439\u0441\u044d\u0439",
+                    "\u0420\u044d\u0439\u0432\u0430",
                 }
             },
             { "java.time.japanese.short.Eras",
@@ -246,6 +247,7 @@
                     "\u042d\u043f\u043e\u0445\u0430 \u0422\u0430\u0439\u0441\u044c\u043e",
                     "\u0421\u044c\u043e\u0432\u0430",
                     "\u042d\u043f\u043e\u0445\u0430 \u0425\u044d\u0439\u0441\u044d\u0439",
+                    "\u0420\u044d\u0439\u0432\u0430",
                 }
             },
             { "java.time.long.Eras",
--- a/src/jdk.localedata/share/classes/sun/text/resources/ext/JavaTimeSupplementary_sr.java	Fri May 17 13:21:44 2019 +0100
+++ b/src/jdk.localedata/share/classes/sun/text/resources/ext/JavaTimeSupplementary_sr.java	Thu May 23 11:07:37 2019 +0100
@@ -280,6 +280,7 @@
                     "\u0422\u0430\u0438\u0448\u043e",
                     "\u0428\u043e\u0432\u0430",
                     "\u0425\u0430\u0438\u0441\u0435\u0438",
+                    "\u0420\u0435\u0438\u0432\u0430",
                 }
             },
             { "java.time.japanese.short.Eras",
@@ -289,6 +290,7 @@
                     "\u0422\u0430\u0438\u0448\u043e",
                     "\u0428\u043e\u0432\u0430",
                     "\u0425\u0430\u0438\u0441\u0435\u0438",
+                    "\u0420\u0435\u0438\u0432\u0430",
                 }
             },
             { "java.time.long.Eras",
--- a/src/jdk.localedata/share/classes/sun/text/resources/ext/JavaTimeSupplementary_sr_Latn.java	Fri May 17 13:21:44 2019 +0100
+++ b/src/jdk.localedata/share/classes/sun/text/resources/ext/JavaTimeSupplementary_sr_Latn.java	Thu May 23 11:07:37 2019 +0100
@@ -225,6 +225,7 @@
                     "Tai\u0161o",
                     "\u0160ova",
                     "Haisei",
+                    "Reiva",
                 }
             },
             { "java.time.japanese.short.Eras",
@@ -234,6 +235,7 @@
                     "Tai\u0161o",
                     "\u0160ova",
                     "Haisei",
+                    "Reiva",
                 }
             },
             { "java.time.long.Eras",
--- a/src/jdk.localedata/share/classes/sun/text/resources/ext/JavaTimeSupplementary_sv.java	Fri May 17 13:21:44 2019 +0100
+++ b/src/jdk.localedata/share/classes/sun/text/resources/ext/JavaTimeSupplementary_sv.java	Thu May 23 11:07:37 2019 +0100
@@ -249,6 +249,7 @@
                     "Taish\u014d",
                     "Sh\u014dwa",
                     "Heisei",
+                    "Reiwa",
                 }
             },
             { "java.time.japanese.short.Eras",
@@ -258,6 +259,7 @@
                     "Taish\u014d",
                     "Sh\u014dwa",
                     "Heisei",
+                    "Reiwa",
                 }
             },
             { "java.time.long.Eras",
--- a/src/jdk.localedata/share/classes/sun/text/resources/ext/JavaTimeSupplementary_th.java	Fri May 17 13:21:44 2019 +0100
+++ b/src/jdk.localedata/share/classes/sun/text/resources/ext/JavaTimeSupplementary_th.java	Thu May 23 11:07:37 2019 +0100
@@ -137,6 +137,7 @@
             "\u0e17\u0e30\u0e2d\u0e34\u0e42\u0e0a",
             "\u0e42\u0e0a\u0e27\u0e30",
             "\u0e40\u0e2e\u0e40\u0e0b",
+            "\u0e40\u0e23\u0e27\u0e30",
         };
 
         final String[] sharedShortEras = {
--- a/src/jdk.localedata/share/classes/sun/text/resources/ext/JavaTimeSupplementary_zh.java	Fri May 17 13:21:44 2019 +0100
+++ b/src/jdk.localedata/share/classes/sun/text/resources/ext/JavaTimeSupplementary_zh.java	Thu May 23 11:07:37 2019 +0100
@@ -176,6 +176,7 @@
             "\u5927\u6b63",
             "\u662d\u548c",
             "\u5e73\u6210",
+            "\u4ee4\u548c",
         };
 
         final String[] sharedJavaTimeShortEras2 = {
--- a/src/jdk.localedata/share/classes/sun/text/resources/ext/JavaTimeSupplementary_zh_TW.java	Fri May 17 13:21:44 2019 +0100
+++ b/src/jdk.localedata/share/classes/sun/text/resources/ext/JavaTimeSupplementary_zh_TW.java	Thu May 23 11:07:37 2019 +0100
@@ -135,6 +135,7 @@
             "\u5927\u6b63",
             "\u662d\u548c",
             "\u5e73\u6210",
+            "\u4ee4\u548c",
         };
 
         final String[] sharedJavaTimeShortEras2 = {
--- a/src/jdk.pack/share/classes/module-info.java	Fri May 17 13:21:44 2019 +0100
+++ b/src/jdk.pack/share/classes/module-info.java	Thu May 23 11:07:37 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2019, 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
@@ -29,11 +29,8 @@
  * <em>{@index pack200 pack200 tool}</em> and
  * <em>{@index unpack200 unpack200 tool}</em> tools.
  *
- * <dl style="font-family:'DejaVu Sans', Arial, Helvetica, sans serif">
- * <dt class="simpleTagLabel">Tool Guides:
- * <dd>{@extLink pack200_tool_reference pack200},
- *     {@extLink unpack200_tool_reference unpack200}
- * </dl>
+ * @toolGuide pack200
+ * @toolGuide unpack200
  *
  * @moduleGraph
  * @deprecated This module is deprecated, and is planned for removal in a
--- a/src/jdk.rmic/share/classes/module-info.java	Fri May 17 13:21:44 2019 +0100
+++ b/src/jdk.rmic/share/classes/module-info.java	Thu May 23 11:07:37 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2019, 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
@@ -27,10 +27,7 @@
  * Defines the <em>{@index rmic rmic}</em> compiler for generating stubs and
  * skeletons using the Java Remote Method Protocol (JRMP) for remote objects.
  *
- * <dl style="font-family:'DejaVu Sans', Arial, Helvetica, sans serif">
- * <dt class="simpleTagLabel">Tool Guides:
- * <dd>{@extLink rmic_tool_reference rmic}
- * </dl>
+ * @toolGuide rmic
  *
  * @moduleGraph
  * @since 9
--- a/src/jdk.scripting.nashorn.shell/share/classes/module-info.java	Fri May 17 13:21:44 2019 +0100
+++ b/src/jdk.scripting.nashorn.shell/share/classes/module-info.java	Thu May 23 11:07:37 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2019, 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
@@ -29,10 +29,7 @@
  * <p>This module includes the command line tool <em>{@index jjs jjs tool}</em>
  * to invoke the Nashorn engine.
  *
- * <dl style="font-family:'DejaVu Sans', Arial, Helvetica, sans serif">
- * <dt class="simpleTagLabel">Tool Guides:
- * <dd>{@extLink jjs_tool_reference jjs}
- * </dl>
+ * @toolGuide jjs
  *
  * @moduleGraph
  * @since 9
--- a/src/jdk.zipfs/share/classes/jdk/nio/zipfs/ZipFileSystem.java	Fri May 17 13:21:44 2019 +0100
+++ b/src/jdk.zipfs/share/classes/jdk/nio/zipfs/ZipFileSystem.java	Thu May 23 11:07:37 2019 +0100
@@ -1934,7 +1934,7 @@
             this.pos = pos;
         }
 
-        // constructor for cenInit() (1) remove trailing '/' (2) pad leading '/'
+        // constructor for initCEN() (1) remove trailing '/' (2) pad leading '/'
         IndexNode(byte[] cen, int pos, int nlen) {
             int noff = pos + CENHDR;
             if (cen[noff + nlen - 1] == '/') {
@@ -1948,10 +1948,51 @@
                 System.arraycopy(cen, noff, name, 1, nlen);
                 name[0] = '/';
             }
-            name(name);
+            name(normalize(name));
             this.pos = pos;
         }
 
+        // Normalize the IndexNode.name field.
+        private byte[] normalize(byte[] path) {
+            int len = path.length;
+            if (len == 0)
+                return path;
+            byte prevC = 0;
+            for (int pathPos = 0; pathPos < len; pathPos++) {
+                byte c = path[pathPos];
+                if (c == '/' && prevC == '/')
+                    return normalize(path, pathPos - 1);
+                prevC = c;
+            }
+            if (len > 1 && prevC == '/') {
+                return Arrays.copyOf(path, len - 1);
+            }
+            return path;
+        }
+
+        private byte[] normalize(byte[] path, int off) {
+            // As we know we have at least one / to trim, we can reduce
+            // the size of the resulting array
+            byte[] to = new byte[path.length - 1];
+            int pathPos = 0;
+            while (pathPos < off) {
+                to[pathPos] = path[pathPos];
+                pathPos++;
+            }
+            int toPos = pathPos;
+            byte prevC = 0;
+            while (pathPos < path.length) {
+                byte c = path[pathPos++];
+                if (c == '/' && prevC == '/')
+                    continue;
+                to[toPos++] = c;
+                prevC = c;
+            }
+            if (toPos > 1 && to[toPos - 1] == '/')
+                toPos--;
+            return (toPos == to.length) ? to : Arrays.copyOf(to, toPos);
+        }
+
         private static final ThreadLocal<IndexNode> cachedKey = new ThreadLocal<>();
 
         final static IndexNode keyOf(byte[] name) { // get a lookup key;
--- a/test/fmw/gtest/src/gtest.cc	Fri May 17 13:21:44 2019 +0100
+++ b/test/fmw/gtest/src/gtest.cc	Thu May 23 11:07:37 2019 +0100
@@ -34,6 +34,7 @@
 #include "gtest/internal/custom/gtest.h"
 #include "gtest/gtest-spi.h"
 
+#include <assert.h>
 #include <ctype.h>
 #include <math.h>
 #include <stdarg.h>
@@ -4388,7 +4389,8 @@
       // errors are ignored as there's nothing better we can do and we
       // don't want to fail the test because of this.
       FILE* pfile = posix::FOpen(premature_exit_filepath, "w");
-      fwrite("0", 1, 1, pfile);
+      size_t cnt= fwrite("0", 1, 1, pfile);
+      assert(cnt == (size_t)1);
       fclose(pfile);
     }
   }
--- a/test/hotspot/gtest/gc/shared/test_collectorPolicy.cpp	Fri May 17 13:21:44 2019 +0100
+++ b/test/hotspot/gtest/gc/shared/test_collectorPolicy.cpp	Thu May 23 11:07:37 2019 +0100
@@ -66,10 +66,10 @@
       FLAG_GUARD(OldSize);
 
       MinHeapSize = 40 * M;
-      FLAG_SET_ERGO(size_t, InitialHeapSize, 100 * M);
-      FLAG_SET_ERGO(size_t, OldSize, 4 * M);
-      FLAG_SET_ERGO(size_t, NewSize, 1 * M);
-      FLAG_SET_ERGO(size_t, MaxNewSize, 80 * M);
+      FLAG_SET_ERGO(InitialHeapSize, 100 * M);
+      FLAG_SET_ERGO(OldSize, 4 * M);
+      FLAG_SET_ERGO(NewSize, 1 * M);
+      FLAG_SET_ERGO(MaxNewSize, 80 * M);
 
       ASSERT_NO_FATAL_FAILURE(setter1->execute());
 
@@ -88,7 +88,7 @@
    public:
     SetNewSizeErgo(size_t param) : UnaryExecutor(param) { }
     void execute() {
-      FLAG_SET_ERGO(size_t, NewSize, param);
+      FLAG_SET_ERGO(NewSize, param);
     }
   };
 
@@ -129,7 +129,7 @@
    public:
     SetNewSizeCmd(size_t param) : UnaryExecutor(param) { }
     void execute() {
-      FLAG_SET_CMDLINE(size_t, NewSize, param);
+      FLAG_SET_CMDLINE(NewSize, param);
     }
   };
 
@@ -148,7 +148,7 @@
    public:
     SetOldSizeCmd(size_t param) : UnaryExecutor(param) { }
     void execute() {
-      FLAG_SET_CMDLINE(size_t, OldSize, param);
+      FLAG_SET_CMDLINE(OldSize, param);
     }
   };
 
@@ -159,7 +159,7 @@
       size_t heap_alignment = GCArguments::compute_heap_alignment();
       size_t new_size_value = align_up(MaxHeapSize, heap_alignment)
               - param1 + param2;
-      FLAG_SET_CMDLINE(size_t, MaxNewSize, new_size_value);
+      FLAG_SET_CMDLINE(MaxNewSize, new_size_value);
     }
   };
 
--- a/test/hotspot/gtest/runtime/test_os_windows.cpp	Fri May 17 13:21:44 2019 +0100
+++ b/test/hotspot/gtest/runtime/test_os_windows.cpp	Thu May 23 11:07:37 2019 +0100
@@ -59,8 +59,8 @@
   // set globals to make sure we hit the correct code path
   FLAG_GUARD(UseLargePagesIndividualAllocation);
   FLAG_GUARD(UseNUMAInterleaving);
-  FLAG_SET_CMDLINE(bool, UseLargePagesIndividualAllocation, false);
-  FLAG_SET_CMDLINE(bool, UseNUMAInterleaving, false);
+  FLAG_SET_CMDLINE(UseLargePagesIndividualAllocation, false);
+  FLAG_SET_CMDLINE(UseNUMAInterleaving, false);
 
   const size_t large_allocation_size = os::large_page_size() * 4;
   char* result = os::reserve_memory_special(large_allocation_size, os::large_page_size(), NULL, false);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/gtest/utilities/test_ostream.cpp	Thu May 23 11:07:37 2019 +0100
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2019 SAP SE. 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.
+ *
+ */
+
+#include "precompiled.hpp"
+#include "memory/resourceArea.hpp"
+#include "runtime/os.hpp"
+#include "utilities/globalDefinitions.hpp"
+#include "utilities/ostream.hpp"
+
+#include "unittest.hpp"
+
+static size_t print_lorem(outputStream* st, bool short_len) {
+  // Create a ResourceMark just to make sure the stream does not use ResourceArea
+  ResourceMark rm;
+  static const char* const lorem = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, "
+      "sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Lacinia at quis "
+      "risus sed vulputate odio ut enim blandit. Amet risus nullam eget felis eget. Viverra "
+      "orci sagittis eu volutpat odio facilisis mauris sit. Erat velit scelerisque in dictum non.";
+  static const size_t len_lorem = strlen(lorem);
+  size_t len;
+  if (short_len) {
+    len = os::random() % 10;
+  } else {
+    len = MAX2(1, (int)(os::random() % len_lorem));
+  }
+  st->write(lorem, len);
+  return len;
+}
+
+static void do_test_stringStream_dynamic_realloc(bool short_len) {
+  stringStream ss(2); // small buffer to force lots of reallocations.
+  size_t written = 0;
+  for (int i = 0; i < 1000; i ++) {
+    written += print_lorem(&ss, short_len);
+    ASSERT_EQ(ss.size(), written);
+    // Internal buffer should always be zero-terminated.
+    ASSERT_EQ(ss.base()[ss.size()], '\0');
+  }
+}
+
+TEST_VM(ostream, stringStream_dynamic_realloc_1) {
+  do_test_stringStream_dynamic_realloc(false);
+}
+
+TEST_VM(ostream, stringStream_dynamic_realloc_2) {
+  do_test_stringStream_dynamic_realloc(true);
+}
--- a/test/hotspot/jtreg/ProblemList-graal.txt	Fri May 17 13:21:44 2019 +0100
+++ b/test/hotspot/jtreg/ProblemList-graal.txt	Thu May 23 11:07:37 2019 +0100
@@ -226,14 +226,6 @@
 
 runtime/exceptionMsgs/AbstractMethodError/AbstractMethodErrorTest.java        8222582 generic-all
 
-vmTestbase/nsk/jdi/ObjectReference/referringObjects/referringObjects002/referringObjects002.java 8220032 generic-all
-vmTestbase/nsk/jdi/VirtualMachine/instanceCounts/instancecounts003/instancecounts003.java        8220032 generic-all
-
-vmTestbase/nsk/jdi/ClassLoaderReference/definedClasses/definedclasses003/TestDescription.java 8222422 generic-all
-vmTestbase/nsk/jdi/ClassLoaderReference/definedClasses/definedclasses005/TestDescription.java 8222422 generic-all
-
-runtime/exceptionMsgs/ArrayIndexOutOfBoundsException/ArrayIndexOutOfBoundsExceptionTest.java 8222292 generic-all
-
 serviceability/dcmd/compiler/CodelistTest.java 8220449 generic-all
 
 # Graal unit tests
--- a/test/hotspot/jtreg/ProblemList.txt	Fri May 17 13:21:44 2019 +0100
+++ b/test/hotspot/jtreg/ProblemList.txt	Thu May 23 11:07:37 2019 +0100
@@ -79,7 +79,6 @@
 # :hotspot_runtime
 
 runtime/SharedArchiveFile/SASymbolTableTest.java 8193639 solaris-all
-containers/docker/TestCPUSets.java 8220672 generic-all
 runtime/jni/terminatedThread/TestTerminatedThread.java 8219652 aix-ppc64
 
 #############################################################################
@@ -114,7 +113,6 @@
 serviceability/sa/DeadlockDetectionTest.java 8193639,8211767 solaris-all,linux-ppc64le,linux-ppc64
 serviceability/sa/JhsdbThreadInfoTest.java 8193639,8211767 solaris-all,linux-ppc64le,linux-ppc64
 serviceability/sa/jmap-hprof/JMapHProfLargeHeapTest.java 8193639 solaris-all
-serviceability/sa/sadebugd/SADebugDTest.java 8163805 generic-all
 serviceability/sa/TestClassDump.java 8193639 solaris-all
 serviceability/sa/TestClhsdbJstackLock.java 8193639,8211767 solaris-all,linux-ppc64le,linux-ppc64
 serviceability/sa/TestCpoolForInvokeDynamic.java 8193639,8211767 solaris-all,linux-ppc64le,linux-ppc64
@@ -134,6 +132,7 @@
 serviceability/sa/TestUniverse.java#id0 8193639,8211767 solaris-all,linux-ppc64le,linux-ppc64
 
 serviceability/jvmti/HeapMonitor/MyPackage/HeapMonitorStatIntervalTest.java 8214032 generic-all
+serviceability/jvmti/HeapMonitor/MyPackage/HeapMonitorStatArrayCorrectnessTest.java 8224150 generic-all
 
 #############################################################################
 
--- a/test/hotspot/jtreg/TEST.groups	Fri May 17 13:21:44 2019 +0100
+++ b/test/hotspot/jtreg/TEST.groups	Thu May 23 11:07:37 2019 +0100
@@ -314,6 +314,23 @@
 hotspot_appcds = \
   runtime/appcds/
 
+hotspot_appcds_dynamic = \
+  runtime/appcds/ \
+ -runtime/appcds/cacheObject \
+ -runtime/appcds/customLoader \
+ -runtime/appcds/dynamicArchive \
+ -runtime/appcds/javaldr/ArrayTest.java \
+ -runtime/appcds/javaldr/GCSharedStringsDuringDump.java \
+ -runtime/appcds/javaldr/HumongousDuringDump.java \
+ -runtime/appcds/sharedStrings \
+ -runtime/appcds/DumpClassList.java \
+ -runtime/appcds/ExtraSymbols.java \
+ -runtime/appcds/LongClassListPath.java \
+ -runtime/appcds/LotsOfClasses.java \
+ -runtime/appcds/SharedArchiveConsistency.java \
+ -runtime/appcds/UnusedCPDuringDump.java \
+ -runtime/appcds/VerifierTest_1B.java
+
 # A subset of AppCDS tests to be run in tier1
 tier1_runtime_appcds = \
   runtime/appcds/HelloTest.java \
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/compiler/arraycopy/TestArrayCopyWithBadOffset.java	Thu May 23 11:07:37 2019 +0100
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2019, 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
+ * @bug 8224539
+ * @summary Test arraycopy optimizations with bad src/dst array offsets.
+ * @run main/othervm -Xbatch -XX:+AlwaysIncrementalInline
+ *                   compiler.arraycopy.TestArrayCopyWithBadOffset
+ */
+
+package compiler.arraycopy;
+
+public class TestArrayCopyWithBadOffset {
+
+    public static byte[] getSrc() {
+        return new byte[5];
+    }
+
+    // Test bad src offset
+    public static void test1(byte[] dst) {
+        byte[] src = getSrc();
+        try {
+            System.arraycopy(src, Integer.MAX_VALUE-1, dst, 0, src.length);
+        } catch (Exception e) {
+            // Expected
+        }
+    }
+
+    public static byte[] getDst() {
+        return new byte[5];
+    }
+
+    // Test bad dst offset
+    public static void test2(byte[] src) {
+        byte[] dst = getDst();
+        try {
+            System.arraycopy(src, 0, dst, Integer.MAX_VALUE-1, dst.length);
+        } catch (Exception e) {
+            // Expected
+        }
+    }
+
+    public static void main(String[] args) {
+        byte[] array = new byte[5];
+        for (int i = 0; i < 10_000; ++i) {
+            test1(array);
+            test2(array);
+        }
+    }
+}
--- a/test/hotspot/jtreg/compiler/graalunit/README.md	Fri May 17 13:21:44 2019 +0100
+++ b/test/hotspot/jtreg/compiler/graalunit/README.md	Thu May 23 11:07:37 2019 +0100
@@ -21,14 +21,23 @@
  https://lafo.ssw.uni-linz.ac.at/pub/graal-external-deps/hamcrest-core-1.3.jar
 
  java-allocation-instrumenter.jar:
- https://lafo.ssw.uni-linz.ac.at/pub/java-allocation-instrumenter/java-allocation-instrumenter-8f0db117e64e.jar
+ https://lafo.ssw.uni-linz.ac.at/pub/java-allocation-instrumenter/java-allocation-instrumenter.jar
 
 Before running the tests you need to download these jars from above locations in build/<platform>/images/test/hotspot/jtreg/graal/
-directory. Then you can pass it to jtreg as java option by using "-vmoptions:-Dgraalunit.libs="  or as environment variable
-by using "-e:TEST_IMAGE_GRAAL_DIR=..."
+directory. You can use 'downloadLibs.sh' script which will try to download all these libs using wget.
+
+
+Then you can run Graal unit test(s) using 'make run-test':
+
+> make run-test TEST="compiler/graalunit/ApiTest.java" TEST_VM_OPTS="-server -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI"
+
+
+If you want to use jtreg directly you need to say jtreg where to find external jars.
+You can do it by passing additional option "-vmoptions:-Dgraalunit.libs=" or setting environment variable by using "-e:TEST_IMAGE_GRAAL_DIR=..."
 
 Example:
-> jtreg -vt -jdk:<TESTED_JDK> -vmoptions:"-Dgraalunit.libs=build/<platform>/images/test/hotspot/jtreg/graal"
+> jtreg -vt -jdk:<TESTED_JDK> -vmoptions:"-server -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI"
+        -vmoptions:"-Dgraalunit.libs=build/<platform>/images/test/hotspot/jtreg/graal"
         compiler/graalunit/UtilTest.java
 
 To run Graal unit tests in Graal as JIT mode pass additional -vmoptions to jtreg:
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/compiler/graalunit/downloadLibs.sh	Thu May 23 11:07:37 2019 +0100
@@ -0,0 +1,45 @@
+#!/bin/bash
+#
+# Copyright (c) 2019, 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.
+#
+
+if [ -z "$1" ]; then
+    echo use:
+    echo '$0 <libs dir to download in>'
+    echo
+    exit 0
+fi
+
+LIBS_DIR=$1
+mkdir -p ${LIBS_DIR}
+
+LIBS="https://lafo.ssw.uni-linz.ac.at/pub/graal-external-deps/asm-5.0.4.jar"
+LIBS="$LIBS https://lafo.ssw.uni-linz.ac.at/pub/graal-external-deps/asm-tree-5.0.4.jar"
+LIBS="$LIBS https://lafo.ssw.uni-linz.ac.at/pub/graal-external-deps/junit-4.12.jar"
+LIBS="$LIBS https://lafo.ssw.uni-linz.ac.at/pub/graal-external-deps/hamcrest-core-1.3.jar"
+LIBS="$LIBS https://lafo.ssw.uni-linz.ac.at/pub/java-allocation-instrumenter/java-allocation-instrumenter.jar"
+
+for l in ${LIBS} ;
+do
+   echo "Download $l"
+   wget -P ${LIBS_DIR} $l
+done
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/compiler/intrinsics/Test8215792.java	Thu May 23 11:07:37 2019 +0100
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2019, Arm Limited. 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
+ * @bug 8215792
+ * @summary Fix a bug in AArch64 string intrinsics
+ *
+ * @run main/othervm compiler.intrinsics.Test8215792
+ * @run main/othervm -XX:-CompactStrings compiler.intrinsics.Test8215792
+ */
+
+package compiler.intrinsics;
+
+public class Test8215792 {
+
+    private static final int ITERATIONS = 10000;
+    private static final String pattern = "01234567890123456789";
+
+    public static void main(String[] args) {
+
+        // Repeat many times to trigger compilation
+        for (int iter = 0; iter < ITERATIONS; iter++) {
+            StringBuilder str1 = new StringBuilder("ABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890123456789");
+            StringBuilder str2 = new StringBuilder("\u4f60\u598dCDEFGHIJKLMNOPQRSTUVWXYZ01234567890123456789");
+
+            for (int i = 0; i < 20; i++) {
+                // Remove one character from the tail
+                str1.setLength(str1.length() - 1);
+                str2.setLength(str2.length() - 1);
+                // Pattern string should not be found after characters removed from the tail
+                if (str1.indexOf(pattern) != -1 || str2.indexOf(pattern) != -1) {
+                    System.out.println("FAILED");
+                    System.exit(1);
+                }
+            }
+        }
+        System.out.println("PASSED");
+    }
+}
+
--- a/test/hotspot/jtreg/compiler/intrinsics/sha/cli/SHAOptionsBase.java	Fri May 17 13:21:44 2019 +0100
+++ b/test/hotspot/jtreg/compiler/intrinsics/sha/cli/SHAOptionsBase.java	Thu May 23 11:07:37 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2019, 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
@@ -74,23 +74,17 @@
      *         instructions required by the option are not supported.
      */
     public static String getWarningForUnsupportedCPU(String optionName) {
-        if (Platform.isAArch64() || Platform.isS390x() || Platform.isSparc()
-            || Platform.isX64() || Platform.isX86() || Platform.isPPC()) {
-            switch (optionName) {
-            case SHAOptionsBase.USE_SHA_OPTION:
-                return SHAOptionsBase.SHA_INSTRUCTIONS_ARE_NOT_AVAILABLE;
-            case SHAOptionsBase.USE_SHA1_INTRINSICS_OPTION:
-                return SHAOptionsBase.SHA1_INTRINSICS_ARE_NOT_AVAILABLE;
-            case SHAOptionsBase.USE_SHA256_INTRINSICS_OPTION:
-                return SHAOptionsBase.SHA256_INTRINSICS_ARE_NOT_AVAILABLE;
-            case SHAOptionsBase.USE_SHA512_INTRINSICS_OPTION:
-                return SHAOptionsBase.SHA512_INTRINSICS_ARE_NOT_AVAILABLE;
-            default:
-                throw new Error("Unexpected option " + optionName);
-            }
-        } else {
-            throw new Error("Support for CPUs different from AARCH64, S390x,"
-                            + " SPARC, X86, and PPC is not implemented");
+        switch (optionName) {
+        case SHAOptionsBase.USE_SHA_OPTION:
+            return SHAOptionsBase.SHA_INSTRUCTIONS_ARE_NOT_AVAILABLE;
+        case SHAOptionsBase.USE_SHA1_INTRINSICS_OPTION:
+            return SHAOptionsBase.SHA1_INTRINSICS_ARE_NOT_AVAILABLE;
+        case SHAOptionsBase.USE_SHA256_INTRINSICS_OPTION:
+            return SHAOptionsBase.SHA256_INTRINSICS_ARE_NOT_AVAILABLE;
+        case SHAOptionsBase.USE_SHA512_INTRINSICS_OPTION:
+            return SHAOptionsBase.SHA512_INTRINSICS_ARE_NOT_AVAILABLE;
+        default:
+            throw new Error("Unexpected option " + optionName);
         }
     }
 
--- a/test/hotspot/jtreg/compiler/intrinsics/sha/cli/testcases/GenericTestCaseForOtherCPU.java	Fri May 17 13:21:44 2019 +0100
+++ b/test/hotspot/jtreg/compiler/intrinsics/sha/cli/testcases/GenericTestCaseForOtherCPU.java	Thu May 23 11:07:37 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2019, 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
@@ -32,12 +32,12 @@
 
 /**
  * Generic test case for SHA-related options targeted to any CPU except
- * AArch64, S390x, SPARC and X86.
+ * AArch64, PPC, S390x, SPARC and X86.
  */
 public class GenericTestCaseForOtherCPU extends
         SHAOptionsBase.TestCase {
     public GenericTestCaseForOtherCPU(String optionName) {
-        // Execute the test case on any CPU except AArch64, S390x, SPARC and X86.
+        // Execute the test case on any CPU except AArch64, PPC, S390x, SPARC and X86.
         super(optionName, new NotPredicate(
                               new OrPredicate(Platform::isAArch64,
                               new OrPredicate(Platform::isS390x,
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/compiler/intrinsics/string/TestStringCompareToDifferentLength.java	Thu May 23 11:07:37 2019 +0100
@@ -0,0 +1,101 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2019, BELLSOFT. 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
+ * @requires os.arch=="aarch64"
+ * @summary String::compareTo implementation uses different algorithms for
+ *          different string length. This test creates string with specified
+ *          size and longer string, which is same at beginning.
+ *          Expecting length delta to be returned. Test class takes 2
+ *          parameters: <string length>, <maximum string length delta>
+ *          Input parameters for this test are set according to Aarch64
+ *          String::compareTo intrinsic implementation specifics. Aarch64
+ *          implementation has 1, 4, 8 -characters loops for length < 72 and
+ *          16, 32, 64 -characters loops for length >= 72. Code is also affected
+ *          by SoftwarePrefetchHintDistance vm flag value.
+ * @run main/othervm -XX:SoftwarePrefetchHintDistance=192 compiler.intrinsics.string.TestStringCompareToDifferentLength 4 2 5 10 13 17 20 25 71 72 73 88 90 192 193 208 209
+ * @run main/othervm -XX:SoftwarePrefetchHintDistance=16 compiler.intrinsics.string.TestStringCompareToDifferentLength 4 2 5 10 13 17 20 25 71 72 73 88 90
+ * @run main/othervm -XX:SoftwarePrefetchHintDistance=-1 compiler.intrinsics.string.TestStringCompareToDifferentLength 4 2 5 10 13 17 20 25 71 72 73 88 90
+ */
+
+package compiler.intrinsics.string;
+
+public class TestStringCompareToDifferentLength {
+    private final int size;
+
+    public static void main(String args[]) {
+        if (args.length > 1) {
+            int maxLengthDelta = Integer.parseInt(args[0]);
+            for (int i = 1; i < args.length; i++) {
+                int  size = Integer.parseInt(args[i]);
+                TestStringCompareToDifferentLength test
+                        = new TestStringCompareToDifferentLength(size);
+                for (int delta = 1; delta <= maxLengthDelta; delta++) {
+                    test.testCompareTo(delta);
+                }
+            }
+        } else {
+            System.out.println("Usage: $testClass $maxLengthDelta $testLength [$testLength2 [$testLength3 [...]]]");
+        }
+    }
+
+    private TestStringCompareToDifferentLength(int size) {
+        this.size = size;
+    }
+
+    private void testCompareTo(int delta) {
+        char strsrc[] = new char[size + delta];
+        // generate ASCII string
+        for (int i = 0; i < size + delta; i++) {
+            strsrc[i] = (char) ('a' + (i % 26));
+        }
+
+        String longLatin1 = new String(strsrc);
+        String shortLatin1 = longLatin1.substring(0, size);
+
+        String longUTF16LastChar = longLatin1.substring(0, longLatin1.length() - 1) + '\uBEEF';
+        String longUTF16FirstChar = '\uBEEF' + longLatin1.substring(1, longLatin1.length());
+        String shortUTF16FirstChar = longUTF16FirstChar.substring(0, size);
+
+        for (int i = 0; i < 10000; i++) {
+            checkCase(longLatin1, shortLatin1, delta, "LL"); // Latin1-Latin1.
+            checkCase(longUTF16LastChar, shortLatin1, delta, "UL"); // Latin1-UTF-16 case.
+            checkCase(longUTF16FirstChar, shortUTF16FirstChar, delta, "UU"); // UTF-16-UTF-16 case
+        }
+    }
+
+    private void checkCase(String str2, String str1, int expected, String caseName) {
+        int result = str2.compareTo(str1);
+        int reversedResult = str1.compareTo(str2);
+        if (expected != result || result != -reversedResult) {
+            throw new AssertionError(String.format("%s CASE FAILED: size = %d, "
+                    + "expected = %d, but got result = %d, "
+                    + "reversedResult = %d for string1 = '%s', string2 = '%s'",
+                    caseName, size, expected, result,
+                    reversedResult, str1, str2));
+        }
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/compiler/intrinsics/string/TestStringCompareToSameLength.java	Thu May 23 11:07:37 2019 +0100
@@ -0,0 +1,142 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2019, BELLSOFT. 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
+ * @requires os.arch=="aarch64"
+ * @summary String::compareTo implementation uses different algorithms for
+ *          different string length. This test creates various strings of
+ *          specified size, which are different at all possible index values and
+ *          compares them. Expecting separately calculated result to be returned.
+ *          String size is specified via commandline. Various size values can
+ *          be specified during intrinsic development in order to test cases
+ *          specific for new or modified intrinsic implementation. Aarch64
+ *          implementation has 1, 4, 8 -characters loops for length < 72 and
+ *          16, 32, 64 -characters loops for string length >= 72. Code is also
+ *          affected by SoftwarePrefetchHintDistance flag value.
+ *          Test class can also accept "-fullmode" parameter
+ *          with maxLength paramter after it. Then it will iterate through all
+ *          string length values up to maxLength parameter (inclusive). It takes
+ *          a lot of time but is useful for development.
+ * @run main/othervm -XX:SoftwarePrefetchHintDistance=192 compiler.intrinsics.string.TestStringCompareToSameLength 2 5 10 13 17 20 25 71 72 73 88 90 192 193 208 209
+ * @run main/othervm -XX:SoftwarePrefetchHintDistance=16 compiler.intrinsics.string.TestStringCompareToSameLength 2 5 10 13 17 20 25 71 72 73 88 90
+ * @run main/othervm -XX:SoftwarePrefetchHintDistance=-1 compiler.intrinsics.string.TestStringCompareToSameLength 2 5 10 13 17 20 25 71 72 73 88 90
+ */
+
+package compiler.intrinsics.string;
+
+public class TestStringCompareToSameLength {
+    private final int size;
+
+    public static void main(String args[]) {
+        if (args.length == 0) {
+            throw new IllegalArgumentException("Usage: $testClass $testLength1"
+                    + " [$testLength2 [...]] | -fullmode $maxLength");
+        }
+        if (args.length == 2 && "-fullmode".equals(args[0])) {
+            int maxLength = Integer.parseInt(args[1]);
+            for (int length = 1; length <= maxLength; length++) {
+                TestStringCompareToSameLength test = new TestStringCompareToSameLength(length);
+                for (int mismatchIdx = 0; mismatchIdx <= length; mismatchIdx++) {
+                    test.testCompareTo(mismatchIdx);
+                }
+            }
+        } else {
+            for (String arg : args) {
+                int size = Integer.parseInt(arg);
+                TestStringCompareToSameLength test = new TestStringCompareToSameLength(size);
+                for (int mismatchIdx = 0; mismatchIdx <= size; mismatchIdx++) {
+                    test.testCompareTo(mismatchIdx);
+                }
+            }
+        }
+    }
+
+    private TestStringCompareToSameLength(int size) {
+        this.size = size;
+    }
+
+    private void testCompareTo(int mismatchIdx) {
+        // Create Latin1 strings: latin1, latin2, which are different at index.
+        // Case of index == size is a case of equal strings
+        char latinSrc[] = new char[size];
+        // generate ASCII string
+        for (int i = 0; i < size; i++) {
+            latinSrc[i] = (char) ('a' + (i % 26));
+        }
+        String latinStr1 = new String(latinSrc);
+        if (mismatchIdx != size) latinSrc[mismatchIdx] = (char) ('a' - 1);
+        String latinStr2 = new String(latinSrc);
+
+        // Create 3 utf strings: utfStr1, utfStr2: same as latinStr1, but has UTF-16 character
+        // utfStr1 and utfStr2 are different at requested index and character value is greater
+        // than same index character in latinStr1.
+        // utfStr3 is different at requested index and character value is less than same
+        // index character in latinStr1. Will be a Latin1-encoded string in case difference
+        // is requested at last character. This case not applicable and is skipped below.
+        char cArray[] = latinStr1.toCharArray();
+        cArray[cArray.length - 1] = '\uBEEF'; // at least last character is UTF-16
+        if (mismatchIdx != size) cArray[mismatchIdx] = '\u1234';
+        String utfStr1 = new String(cArray);
+        if (mismatchIdx != size) cArray[mismatchIdx] = '\u5678';
+        String utfStr2 = new String(cArray);
+        if (mismatchIdx != size) cArray[mismatchIdx] = (char) ('a' - 2); // less than Latin1 index position
+        // utfStr3 will be Latin1 if last character differ. Will skip this case
+        String utfStr3 = new String(cArray);
+
+        for (int i = 0; i < 10000; i++) {
+            checkCase(mismatchIdx, latinStr1, latinStr2, "LL"); // compare Latin1 with Latin1
+
+            checkCase(mismatchIdx, utfStr1, utfStr2, "UU"); // compare UTF-16 vs UTF-16
+
+            if (size != mismatchIdx) { // UTF-16 and Latin1 strings can't be equal. Then skip this case
+                // compare UTF16 string, which is expected to be > than Latin1
+                checkCase(mismatchIdx, latinStr1, utfStr1, "U(large)L");
+                if (mismatchIdx != size - 1) {
+                    // compare UTF16 string, which is expected to be < than Latin1
+                    checkCase(mismatchIdx,  latinStr1, utfStr3, "U(small)L");
+                }
+            }
+        }
+    }
+
+    private void checkCase(int mismatchIdx, String str1, String str2, String caseName) {
+        int expected;
+        if (mismatchIdx != size) {
+            expected = str1.charAt(mismatchIdx) - str2.charAt(mismatchIdx);
+        } else {
+            expected = str1.length() - str2.length();
+        }
+        int result = str1.compareTo(str2);
+        int reversedResult = str2.compareTo(str1);
+        if (expected != result || result != -reversedResult) {
+            throw new AssertionError(String.format("%s CASE FAILED: size = %d, "
+                    + "mismatchIdx = %d, expected = %d, but got result = %d, "
+                    + "reversedResult = %d for string1 = '%s', string2 = '%s'",
+                    caseName, size, mismatchIdx, expected, result,
+                    reversedResult, str1, str2));
+        }
+    }
+}
+
--- a/test/hotspot/jtreg/containers/docker/TestCPUSets.java	Fri May 17 13:21:44 2019 +0100
+++ b/test/hotspot/jtreg/containers/docker/TestCPUSets.java	Thu May 23 11:07:37 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2019, 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
@@ -44,7 +44,7 @@
 import jdk.test.lib.Platform;
 import jdk.test.lib.Utils;
 import jdk.test.lib.process.OutputAnalyzer;
-
+import jtreg.SkippedException;
 
 public class TestCPUSets {
     private static final String imageName = Common.imageName("cpusets");
@@ -54,6 +54,7 @@
             return;
         }
 
+
         Common.prepareWhiteBox();
         DockerTestUtils.buildJdkDockerImage(imageName, "Dockerfile-BasicTest", "jdk-docker");
 
@@ -72,22 +73,48 @@
         String cpuSetStr = CPUSetsReader.readFromProcStatus(setType);
 
         if (cpuSetStr == null) {
-            System.out.printf("The %s test is skipped %n", setType);
-        } else {
-            List<Integer> cpuSet = CPUSetsReader.parseCpuSet(cpuSetStr);
+            String msg = String.format("The %s test is skipped: cpuSetStr is null %n", setType);
+            throw new SkippedException(msg);
+        }
+
+        List<Integer> cpuSet = CPUSetsReader.parseCpuSet(cpuSetStr);
+        int availableProcessors = Runtime.getRuntime().availableProcessors();
+
+        // print diagnostic info
+        printSet(setType, cpuSet);
+        log("getNumCpus(): " + CPUSetsReader.getNumCpus());
+        log("Runtime.getRuntime().availableProcessors(): " + availableProcessors);
+
+        int maxSetSize = Math.min(cpuSet.size(), availableProcessors);
+        log("maxSetSize = " + maxSetSize);
 
-            // Test subset of one, full subset, and half of the subset
-            testCpuSet(CPUSetsReader.listToString(cpuSet, 1));
-            if (cpuSet.size() > 1) {
-                testCpuSet(CPUSetsReader.listToString(cpuSet));
-            }
-            if (cpuSet.size() > 2) {
-                testCpuSet(CPUSetsReader.listToString(cpuSet, cpuSet.size()/2 ));
-            }
+        // Test subset of one, full set, and half of the set
+        testCpuSet(CPUSetsReader.listToString(cpuSet, 1));
+        if (maxSetSize >= 2) {
+            String cpuSetParam = CPUSetsReader.listToString(cpuSet, maxSetSize);
+            log("Testing with cpuSetParam = " + cpuSetParam);
+            testCpuSet(cpuSetParam);
+        }
+        if (maxSetSize >= 4) {
+            String cpuSetParam = CPUSetsReader.listToString(cpuSet, maxSetSize/2);
+            log("Testing with cpuSetParam = " + cpuSetParam);
+            testCpuSet(cpuSetParam);
         }
     }
 
 
+    private static void printSet(String setType, List<Integer> set) {
+        System.out.print("printSet(): " + setType + ": ");
+        set.forEach( i -> System.out.print(i + ", "));
+        System.out.println("");
+    }
+
+
+    private static void log(String msg) {
+        System.out.println(msg);
+    }
+
+
     private static DockerRunOptions commonOpts() {
         DockerRunOptions opts = new DockerRunOptions(imageName, "/jdk/bin/java",
                                                      "PrintContainerInfo");
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/gc/z/TestHighUsage.java	Thu May 23 11:07:37 2019 +0100
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 2019, 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 gc.z;
+
+/*
+ * @test TestHighUsage
+ * @requires vm.gc.Z & !vm.graal.enabled
+ * @summary Test ZGC "High Usage" rule
+ * @library /test/lib
+ * @run main/othervm gc.z.TestHighUsage
+ */
+
+import java.util.LinkedList;
+import jdk.test.lib.process.ProcessTools;
+
+public class TestHighUsage {
+    static class Test {
+        private static final int K = 1024;
+        private static final int M = K * K;
+        private static final long startAt = 16 * M;
+        private static final long spikeAt = 4 * M;
+        private static volatile LinkedList<byte[]> keepAlive;
+        private static volatile Object dummy;
+
+        public static void main(String[] args) throws Exception {
+            System.out.println("Allocating live-set");
+
+            // Allocate live-set
+            keepAlive = new LinkedList<>();
+            while (Runtime.getRuntime().freeMemory() > startAt) {
+                while (Runtime.getRuntime().freeMemory() > startAt) {
+                    keepAlive.add(new byte[128 * K]);
+                }
+
+                // Compact live-set and let allocation rate settle down
+                System.gc();
+                Thread.sleep(2000);
+            }
+
+            System.out.println("Allocating garbage slowly");
+
+            // Allocate garbage slowly, such that the sampled allocation rate on
+            // average becomes zero MB/s for the last 1 second windows. If free
+            // memory goes below the spike limit we induce an allocation spike.
+            // The expected behavior is that the "High Usage" rule kicks in before
+            // the spike happens, avoiding an "Allocation Stall".
+            for (int i = 0; i < 300; i++) {
+                final long free = Runtime.getRuntime().freeMemory();
+                System.out.println("Free: " + (free / M) + "M");
+
+                if (free > spikeAt) {
+                    // Low allocation rate
+                    dummy = new byte[128 * K];
+                } else {
+                    // High allocation rate
+                    dummy = new byte[8 * M];
+                }
+
+                Thread.sleep(250);
+            }
+
+            System.out.println("Done");
+        }
+    }
+
+    public static void main(String[] args) throws Exception {
+        ProcessTools.executeTestJvm(new String[]{ "-XX:+UnlockExperimentalVMOptions",
+                                                  "-XX:+UseZGC",
+                                                  "-XX:+UnlockDiagnosticVMOptions",
+                                                  "-XX:-ZProactive",
+                                                  "-Xms128M",
+                                                  "-Xmx128M",
+                                                  "-XX:ParallelGCThreads=1",
+                                                  "-XX:ConcGCThreads=1",
+                                                  "-Xlog:gc",
+                                                  Test.class.getName() })
+                    .shouldNotContain("Allocation Stall")
+                    .shouldContain("High Usage")
+                    .shouldHaveExitValue(0);
+    }
+}
--- a/test/hotspot/jtreg/runtime/ErrorHandling/ErrorHandler.java	Fri May 17 13:21:44 2019 +0100
+++ b/test/hotspot/jtreg/runtime/ErrorHandling/ErrorHandler.java	Thu May 23 11:07:37 2019 +0100
@@ -66,7 +66,7 @@
 
         String[] patterns = {
             "(SIGILL|SIGSEGV|EXCEPTION_ACCESS_VIOLATION).* at pc=",
-            "(SIGBUS|SIGSEGV|SIGILL|EXCEPTION_ACCESS_VIOLATION).* at pc="
+            // -XX:ErrorHandlerTest=13 is too unreliable. It sometimes fails to crash in the expected way.
             // -XX:ErrorHandlerTest=14 is tested by SafeFetchInErrorHandlingTest.java
             // -XX:ErrorHandlerTest=15 is tested by SecondaryErrorTest.java
             // -XX:ErrorHandlerTest=16 is tested by ThreadsListHandleInErrorHandlingTest.java
--- a/test/hotspot/jtreg/runtime/appcds/AppendClasspath.java	Fri May 17 13:21:44 2019 +0100
+++ b/test/hotspot/jtreg/runtime/appcds/AppendClasspath.java	Thu May 23 11:07:37 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2019, 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
@@ -58,23 +58,26 @@
     // FAIL: 2) runtime with classpath different from the one used in dump time
     // (runtime has an extra jar file prepended to the class path)
     TestCommon.run(
+        "-Xlog:cds",
         "-cp", appJar2 + File.pathSeparator + appJar,
         "HelloMore")
-      .assertAbnormalExit(errorMessage1, errorMessage2);
+        .assertAbnormalExit(errorMessage1, errorMessage2);
 
     // FAIL: 3) runtime with classpath part of the one used in dump time
     TestCommon.testDump(appJar + File.pathSeparator + appJar2,
                                       TestCommon.list("Hello"));
     TestCommon.run(
+        "-Xlog:cds",
         "-cp", appJar2,
         "Hello")
-      .assertAbnormalExit(errorMessage1, errorMessage2);
+        .assertAbnormalExit(errorMessage1, errorMessage2);
 
     // FAIL: 4) runtime with same set of jar files in the classpath but
     // with different order
     TestCommon.run(
+        "-Xlog:cds",
         "-cp", appJar2 + File.pathSeparator + appJar,
         "HelloMore")
-      .assertAbnormalExit(errorMessage1, errorMessage2);
+        .assertAbnormalExit(errorMessage1, errorMessage2);
   }
 }
--- a/test/hotspot/jtreg/runtime/appcds/BootClassPathMismatch.java	Fri May 17 13:21:44 2019 +0100
+++ b/test/hotspot/jtreg/runtime/appcds/BootClassPathMismatch.java	Thu May 23 11:07:37 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2019, 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
@@ -55,7 +55,11 @@
         test.testBootClassPathMismatch();
         test.testBootClassPathMismatchWithAppClass();
         test.testBootClassPathMismatchWithBadPath();
-        test.testBootClassPathMatchWithAppend();
+        if (!TestCommon.isDynamicArchive()) {
+            // this test is not applicable to dynamic archive since
+            // there is no class to be archived in the top archive
+            test.testBootClassPathMatchWithAppend();
+        }
         test.testBootClassPathMatch();
     }
 
@@ -77,11 +81,13 @@
 
         TestCommon.dump(appJar, appClasses, "-Xbootclasspath/a:" + appJar);
         TestCommon.run(
+                "-Xlog:cds",
                 "-cp", appJar, "-Xbootclasspath/a:" + otherJar, "Hello")
             .assertAbnormalExit(mismatchMessage);
 
         TestCommon.dump(appJar, appClasses, "-Xbootclasspath/a:" + otherJar);
         TestCommon.run(
+                "-Xlog:cds",
                 "-cp", appJar, "-Xbootclasspath/a:" + appJar, "Hello")
             .assertAbnormalExit(mismatchMessage);
     }
@@ -100,6 +106,7 @@
 
         TestCommon.dump(appJar, appClasses, "-Xbootclasspath/a:" + appJar);
         TestCommon.run(
+                "-Xlog:cds",
                 "-cp", appJar, "-Xbootclasspath/a:" + otherJar, "Hello")
             .assertAbnormalExit(mismatchMessage);
     }
@@ -148,6 +155,7 @@
         String appClasses[] = {"Hello"};
         TestCommon.dump(appJar, appClasses);
         TestCommon.run(
+                "-Xlog:cds",
                 "-cp", appJar, "-Xbootclasspath/a:" + appJar, "Hello")
             .assertAbnormalExit(mismatchMessage);
     }
--- a/test/hotspot/jtreg/runtime/appcds/CDSandJFR.java	Fri May 17 13:21:44 2019 +0100
+++ b/test/hotspot/jtreg/runtime/appcds/CDSandJFR.java	Thu May 23 11:07:37 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018, 2019, 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
@@ -30,7 +30,7 @@
  * @modules jdk.jfr
  * @build Hello GetFlightRecorder
  * @run driver ClassFileInstaller -jar CDSandJFR.jar Hello GetFlightRecorder GetFlightRecorder$TestEvent GetFlightRecorder$SimpleEvent
- * @run driver/timeout=500 CDSandJFR
+ * @run main/othervm/timeout=500 CDSandJFR
  */
 
 import jdk.test.lib.BuildHelper;
--- a/test/hotspot/jtreg/runtime/appcds/CaseSensitiveClassPath.java	Fri May 17 13:21:44 2019 +0100
+++ b/test/hotspot/jtreg/runtime/appcds/CaseSensitiveClassPath.java	Thu May 23 11:07:37 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2019, 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
@@ -78,8 +78,7 @@
         }
         boolean isSameFile = Files.isSameFile(jarPath, jarPathUpper);
 
-        TestCommon.run("-cp", appJarUpper, "Hello", "-Xlog:class+path=info",
-                       "-Xlog:cds")
+        TestCommon.run("-Xlog:class+path=info,cds", "-cp", appJarUpper, "Hello")
             .ifNoMappingFailure(output -> {
                     if (isSameFile) {
                         output.shouldContain("Hello World");
--- a/test/hotspot/jtreg/runtime/appcds/CommandLineFlagCombo.java	Fri May 17 13:21:44 2019 +0100
+++ b/test/hotspot/jtreg/runtime/appcds/CommandLineFlagCombo.java	Thu May 23 11:07:37 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2019, 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
@@ -72,10 +72,22 @@
                 continue;
 
             OutputAnalyzer dumpOutput = TestCommon.dump(appJar, classList, testEntry);
-            TestCommon.checkDump(dumpOutput, "Loading classes to share");
+            if (!TestCommon.isDynamicArchive()) {
+                TestCommon.checkDump(dumpOutput, "Loading classes to share");
+            } else {
+                if (testEntry.contains("ObjectAlignmentInBytes")) {
+                   dumpOutput.shouldHaveExitValue(1)
+                             .shouldMatch("The shared archive file's ObjectAlignmentInBytes of .* does not equal the current ObjectAlignmentInBytes of");
+                } else {
+                   TestCommon.checkDump(dumpOutput, "Loading classes to share");
+                }
+            }
 
-            OutputAnalyzer execOutput = TestCommon.exec(appJar, testEntry, "Hello");
-            TestCommon.checkExec(execOutput, "Hello World");
+            if ((TestCommon.isDynamicArchive() && !testEntry.contains("ObjectAlignmentInBytes")) ||
+                !TestCommon.isDynamicArchive()) {
+                OutputAnalyzer execOutput = TestCommon.exec(appJar, testEntry, "Hello");
+                TestCommon.checkExec(execOutput, "Hello World");
+            }
         }
 
         for (int i=0; i<2; i++) {
--- a/test/hotspot/jtreg/runtime/appcds/CommandLineFlagComboNegative.java	Fri May 17 13:21:44 2019 +0100
+++ b/test/hotspot/jtreg/runtime/appcds/CommandLineFlagComboNegative.java	Thu May 23 11:07:37 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2019, 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
@@ -65,8 +65,10 @@
         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) );
+            if (!TestCommon.isDynamicArchive()) {
+                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",
--- a/test/hotspot/jtreg/runtime/appcds/DirClasspathTest.java	Fri May 17 13:21:44 2019 +0100
+++ b/test/hotspot/jtreg/runtime/appcds/DirClasspathTest.java	Thu May 23 11:07:37 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2019, 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
@@ -27,7 +27,9 @@
  * @summary Handling of directories in -cp is based on the classlist
  * @requires vm.cds
  * @library /test/lib
+ * @modules jdk.jartool/sun.tools.jar
  * @compile test-classes/Hello.java
+ * @compile test-classes/Super.java
  * @run driver DirClasspathTest
  */
 
@@ -42,11 +44,19 @@
 public class DirClasspathTest {
     private static final int MAX_PATH = 260;
 
+    // We add helloJar into the classpath to be compatible with TestCommon.DYNAMIC_DUMP
+    static OutputAnalyzer doDump(String path, String classList[],
+                                        String... suffix) throws Exception {
+        String helloJar = JarBuilder.getOrCreateHelloJar();
+        return TestCommon.dump(helloJar + File.pathSeparator + path, classList, suffix);
+    }
+
     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
         /////////////////////////////////////////////////////////////////
@@ -54,7 +64,7 @@
 
         // Empty dir in -cp: should be OK
         OutputAnalyzer output;
-        output = TestCommon.dump(emptydir.getPath(), bootClassList, "-Xlog:class+path=info");
+        output = doDump(emptydir.getPath(), bootClassList, "-Xlog:class+path=info");
         TestCommon.checkDump(output);
 
         // Long path to empty dir in -cp: should be OK
@@ -71,17 +81,17 @@
         longDir.mkdir();
         File subDir = new File(longDir, "subdir");
         subDir.mkdir();
-        output = TestCommon.dump(subDir.getPath(), bootClassList, "-Xlog:class+path=info");
+        output = doDump(subDir.getPath(), bootClassList, "-Xlog:class+path=info");
         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, "-Xlog:class+path=info");
+        output = doDump(dir.getPath(), bootClassList, "-Xlog:class+path=info");
         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, "-Xlog:class+path=info");
+        output = doDump(longDir.getPath(), bootClassList, "-Xlog:class+path=info");
         TestCommon.checkDump(output);
 
         /////////////////////////////////////////////////////////////////
@@ -90,27 +100,27 @@
         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, "-Xlog:class+path=info");
+        output = doDump(dir.getPath(), appClassList, "-Xlog:class+path=info");
         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, "-Xlog:class+path=info");
+        output = doDump(longDir.getPath(), appClassList, "-Xlog:class+path=info");
         TestCommon.checkDump(output);
 
         /////////////////////////////////////////////////////////////////
         // Loading an app class from a directory
         /////////////////////////////////////////////////////////////////
-        String appClassList2[] = {"Hello", "java/lang/Object", "com/sun/tools/javac/Main"};
+        String appClassList2[] = {"Super", "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, "-Xlog:class+path=info");
+        output = doDump(classDir.toString(), appClassList2, "-Xlog:class+path=info,class+load=trace");
         output.shouldNotHaveExitValue(0);
         output.shouldContain("Cannot have non-empty directory in paths");
 
         // 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");
+        File srcClass = new File(classDir.toFile(), "Super.class");
+        File destClass = new File(longDir, "Super.class");
         Files.copy(srcClass.toPath(), destClass.toPath());
-        output = TestCommon.dump(longDir.getPath(), appClassList2, "-Xlog:class+path=info");
+        output = doDump(longDir.getPath(), appClassList2, "-Xlog:class+path=info");
         output.shouldNotHaveExitValue(0);
         output.shouldContain("Cannot have non-empty directory in paths");
     }
--- a/test/hotspot/jtreg/runtime/appcds/JvmtiAddPath.java	Fri May 17 13:21:44 2019 +0100
+++ b/test/hotspot/jtreg/runtime/appcds/JvmtiAddPath.java	Thu May 23 11:07:37 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2019, 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
@@ -84,7 +84,9 @@
         run(check_appcds_enabled, appJar, "-Xlog:class+load", "JvmtiApp", "noadd"); // appcds should be enabled
 
         System.out.println("Test case 2: add to boot classpath only - should find Hello.class in boot loader");
-        run(check_appcds_disabled, appJar, "-Xlog:class+load", "JvmtiApp", "bootonly", addbootJar); // appcds should be disabled
+        String[] toCheck = (TestCommon.isDynamicArchive()) ? check_appcds_enabled
+                                                           : check_appcds_disabled;
+        run(toCheck, appJar, "-Xlog:class+load", "JvmtiApp", "bootonly", addbootJar); // appcds should be disabled
 
         System.out.println("Test case 3: add to app classpath only - should find Hello.class in app loader");
         run(appJar, "JvmtiApp", "apponly", addappJar);
@@ -97,7 +99,11 @@
 
         System.out.println("Test case 6: add to app using AppCDS, but add to boot using JVMTI - should find Hello.class in boot loader");
         TestCommon.testDump(twoAppJars, TestCommon.list("JvmtiApp", "ExtraClass", "Hello"), use_whitebox_jar);
-        run(twoAppJars, "JvmtiApp", "bootonly", addappJar);
+        if (!TestCommon.isDynamicArchive()) {
+            // skip for dynamic archive, the Hello class will be loaded from
+            // the dynamic archive
+            run(twoAppJars, "JvmtiApp", "bootonly", addappJar);
+        }
 
         System.out.println("Test case 7: add to app using AppCDS, no JVMTI calls - should find Hello.class in app loader");
         run(twoAppJars, "JvmtiApp", "noadd-appcds");
--- a/test/hotspot/jtreg/runtime/appcds/LotsOfClasses.java	Fri May 17 13:21:44 2019 +0100
+++ b/test/hotspot/jtreg/runtime/appcds/LotsOfClasses.java	Thu May 23 11:07:37 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018, 2019, 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
@@ -22,15 +22,7 @@
  *
  */
 
-import java.net.URI;
-import java.nio.file.DirectoryStream;
-import java.nio.file.Files;
-import java.nio.file.FileSystem;
-import java.nio.file.FileSystems;
-import java.nio.file.Path;
 import java.util.ArrayList;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
 
 import jdk.test.lib.cds.CDSTestUtils;
 import jdk.test.lib.cds.CDSOptions;
@@ -41,16 +33,15 @@
  * @summary Try to archive lots of classes by searching for classes from the jrt:/ file system. With JDK 12
  *          this will produce an archive with over 30,000 classes.
  * @requires vm.cds
- * @library /test/lib
+ * @library /test/lib /test/hotspot/jtreg/runtime/appcds
  * @run driver/timeout=500 LotsOfClasses
  */
 
 public class LotsOfClasses {
-    static Pattern pattern;
 
     public static void main(String[] args) throws Throwable {
         ArrayList<String> list = new ArrayList<>();
-        findAllClasses(list);
+        TestCommon.findAllClasses(list);
 
         CDSOptions opts = new CDSOptions();
         opts.setClassList(list);
@@ -64,28 +55,4 @@
         OutputAnalyzer out = CDSTestUtils.createArchive(opts);
         CDSTestUtils.checkDump(out);
     }
-
-    static void findAllClasses(ArrayList<String> list) throws Throwable {
-        // Find all the classes in the jrt file system
-        pattern = Pattern.compile("/modules/[a-z.]*[a-z]+/([^-]*)[.]class");
-        FileSystem fs = FileSystems.getFileSystem(URI.create("jrt:/"));
-        Path base = fs.getPath("/modules/");
-        find(base, list);
-    }
-
-    static void find(Path p, ArrayList<String> list) throws Throwable {
-        try (DirectoryStream<Path> stream = Files.newDirectoryStream(p)) {
-                for (Path entry: stream) {
-                    Matcher matcher = pattern.matcher(entry.toString());
-                    if (matcher.find()) {
-                        String className = matcher.group(1);
-                        list.add(className);
-                        //System.out.println(className);
-                    }
-                    try {
-                        find(entry, list);
-                    } catch (Throwable t) {}
-                }
-            }
-    }
 }
--- a/test/hotspot/jtreg/runtime/appcds/PackageSealing.java	Fri May 17 13:21:44 2019 +0100
+++ b/test/hotspot/jtreg/runtime/appcds/PackageSealing.java	Thu May 23 11:07:37 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2019, 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
@@ -27,14 +27,15 @@
  * @summary AppCDS handling of package.
  * @requires vm.cds
  * @library /test/lib
- * @modules java.base/jdk.internal.misc
- *          java.management
+ * @modules jdk.jartool/sun.tools.jar
  * @compile test-classes/C1.java
  * @compile test-classes/C2.java
  * @compile test-classes/PackageSealingTest.java
+ * @compile test-classes/Hello.java
  * @run driver PackageSealing
  */
 
+import java.io.File;
 import jdk.test.lib.process.OutputAnalyzer;
 
 public class PackageSealing {
@@ -44,16 +45,19 @@
             ClassFileInstaller.Manifest.fromSourceFile("test-classes/package_seal.mf"),
             "PackageSealingTest", "sealed/pkg/C1", "pkg/C2");
 
+        String helloJar = JarBuilder.getOrCreateHelloJar();
+        String jars = helloJar + File.pathSeparator + appJar;
+
         // test shared package from -cp path
-        TestCommon.testDump(appJar, TestCommon.list(classList));
+        TestCommon.testDump(jars, TestCommon.list(classList));
         OutputAnalyzer output;
-        output = TestCommon.exec(appJar, "PackageSealingTest");
+        output = TestCommon.exec(jars, "PackageSealingTest");
         TestCommon.checkExec(output, "OK");
 
         // test shared package from -Xbootclasspath/a
-        TestCommon.dump(appJar, TestCommon.list(classList),
+        TestCommon.dump(helloJar, TestCommon.list(classList),
                         "-Xbootclasspath/a:" + appJar);
-        output = TestCommon.exec(appJar, "-Xbootclasspath/a:" + appJar, "PackageSealingTest");
+        output = TestCommon.exec(helloJar, "-Xbootclasspath/a:" + appJar, "PackageSealingTest");
         TestCommon.checkExec(output, "OK");
     }
 }
--- a/test/hotspot/jtreg/runtime/appcds/ProhibitedPackage.java	Fri May 17 13:21:44 2019 +0100
+++ b/test/hotspot/jtreg/runtime/appcds/ProhibitedPackage.java	Thu May 23 11:07:37 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2019, 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
@@ -27,9 +27,7 @@
  * @summary AppCDS handling of prohibited package.
  * @requires vm.cds
  * @library /test/lib
- * @modules java.base/jdk.internal.misc
- *          java.management
- *          jdk.jartool/sun.tools.jar
+ * @modules jdk.jartool/sun.tools.jar
  * @compile test-classes/ProhibitedHelper.java test-classes/Prohibited.jasm
  * @run driver ProhibitedPackage
  */
@@ -46,7 +44,8 @@
         String appJar = TestCommon.getTestJar("prohibited_pkg.jar");
 
         // Test support for customer loaders
-        if (Platform.areCustomLoadersSupportedForCDS()) {
+        if (Platform.areCustomLoadersSupportedForCDS() &&
+            !TestCommon.isDynamicArchive()) {
             String classlist[] = new String[] {
                 "java/lang/Object id: 1",
                 "java/lang/Prohibited id: 2 super: 1 source: " + appJar
--- a/test/hotspot/jtreg/runtime/appcds/SharedArchiveConsistency.java	Fri May 17 13:21:44 2019 +0100
+++ b/test/hotspot/jtreg/runtime/appcds/SharedArchiveConsistency.java	Thu May 23 11:07:37 2019 +0100
@@ -71,7 +71,18 @@
 
     public static File jsa;        // will be updated during test
     public static File orgJsaFile; // kept the original file not touched.
-    public static String[] shared_region_name = {"MiscCode", "ReadWrite", "ReadOnly", "MiscData"};
+    // The following should be consistent with the enum in the C++ MetaspaceShared class
+    public static String[] shared_region_name = {
+        "mc",          // MiscCode
+        "rw",          // ReadWrite
+        "ro",          // ReadOnly
+        "md",          // MiscData
+        "first_closed_archive",
+        "last_closed_archive",
+        "first_open_archive",
+        "last_open_archive"
+    };
+
     public static int num_regions = shared_region_name.length;
     public static String[] matchMessages = {
         "Unable to use shared archive",
@@ -102,10 +113,11 @@
             return file_header_size;
         }
         // this is not real header size, it is struct size
+        int int_size = wb.getOffsetForName("int_size");
         file_header_size = wb.getOffsetForName("file_header_size");
         int offset_path_misc_info = wb.getOffsetForName("FileMapHeader::_paths_misc_info_size") -
             offset_magic;
-        int path_misc_info_size   = (int)readInt(fc, offset_path_misc_info, size_t_size);
+        int path_misc_info_size   = (int)readInt(fc, offset_path_misc_info, int_size);
         file_header_size += path_misc_info_size; //readInt(fc, offset_path_misc_info, size_t_size);
         System.out.println("offset_path_misc_info = " + offset_path_misc_info);
         System.out.println("path_misc_info_size   = " + path_misc_info_size);
@@ -157,25 +169,26 @@
 
     public static void modifyJsaContentRandomly() throws Exception {
         FileChannel fc = getFileChannel();
-        // corrupt random area in the data areas (MiscCode, ReadWrite, ReadOnly, MiscData)
+        // corrupt random area in the data areas
         long[] used    = new long[num_regions];       // record used bytes
         long start0, start, end, off;
         int used_offset, path_info_size;
 
         int bufSize;
-        System.out.printf("%-12s%-12s%-12s%-12s%-12s\n", "Space Name", "Offset", "Used bytes", "Reg Start", "Random Offset");
+        System.out.printf("%-24s%12s%12s%16s\n", "Space Name", "Used bytes", "Reg Start", "Random Offset");
         start0 = getFileHeaderSize(fc);
         for (int i = 0; i < num_regions; i++) {
-            used_offset = sp_offset + CDSFileMapRegion_size * i + sp_used_offset;
-            // read 'used'
-            used[i] = readInt(fc, used_offset, size_t_size);
+            used[i] = get_region_used_size_aligned(fc, i);
             start = start0;
             for (int j = 0; j < i; j++) {
                 start += align_up_page(used[j]);
             }
             end = start + used[i];
+            if (start == end) {
+                continue; // Ignore empty regions
+            }
             off = getRandomBetween(start, end);
-            System.out.printf("%-12s%-12d%-12d%-12d%-12d\n", shared_region_name[i], used_offset, used[i], start, off);
+            System.out.printf("%-24s%12d%12d%16d\n", shared_region_name[i], used[i], start, off);
             if (end - off < 1024) {
                 bufSize = (int)(end - off + 1);
             } else {
@@ -189,34 +202,50 @@
         }
     }
 
-    public static void modifyJsaContent() throws Exception {
+    static long get_region_used_size_aligned(FileChannel fc, int region) throws Exception {
+        long n = sp_offset + CDSFileMapRegion_size * region + sp_used_offset;
+        long alignment = WhiteBox.getWhiteBox().metaspaceReserveAlignment();
+        long used = readInt(fc, n, size_t_size);
+        used = (used + alignment - 1) & ~(alignment - 1);
+        return used;
+    }
+
+    public static boolean modifyJsaContent(int region) throws Exception {
         FileChannel fc = getFileChannel();
         byte[] buf = new byte[4096];
         ByteBuffer bbuf = ByteBuffer.wrap(buf);
 
         long total = 0L;
-        long used_offset = 0L;
         long[] used = new long[num_regions];
-        System.out.printf("%-12s%-12s\n", "Space name", "Used bytes");
+        System.out.printf("%-24s%12s\n", "Space name", "Used bytes");
         for (int i = 0; i < num_regions; i++) {
-            used_offset = sp_offset + CDSFileMapRegion_size* i + sp_used_offset;
-            // read 'used'
-            used[i] = readInt(fc, used_offset, size_t_size);
-            System.out.printf("%-12s%-12d\n", shared_region_name[i], used[i]);
+            used[i] = get_region_used_size_aligned(fc, i);
+            System.out.printf("%-24s%12d\n", shared_region_name[i], used[i]);
             total += used[i];
         }
-        System.out.printf("%-12s%-12d\n", "Total: ", total);
-        long corrupt_used_offset =  getFileHeaderSize(fc);
-        System.out.println("Corrupt RO section, offset = " + corrupt_used_offset);
-        while (used_offset < used[0]) {
-            writeData(fc, corrupt_used_offset, bbuf);
+        System.out.printf("%-24s%12d\n", "Total: ", total);
+        long header_size = getFileHeaderSize(fc);
+        long region_start_offset = header_size;
+        for (int i=0; i<region; i++) {
+            region_start_offset += used[i];
+        }
+        if (used[region] == 0) {
+            System.out.println("Region " + shared_region_name[region] + " is empty. Nothing to corrupt.");
+            return false;
+        }
+        System.out.println("Corrupt " + shared_region_name[region] + " section, start = " + region_start_offset
+                           + " (header_size + 0x" + Long.toHexString(region_start_offset-header_size) + ")");
+        long bytes_written = 0L;
+        while (bytes_written < used[region]) {
+            writeData(fc, region_start_offset + bytes_written, bbuf);
             bbuf.clear();
-            used_offset += 4096;
+            bytes_written += 4096;
         }
         fc.force(true);
         if (fc.isOpen()) {
             fc.close();
         }
+        return true;
     }
 
     public static void modifyJsaHeader() throws Exception {
@@ -299,11 +328,11 @@
     // read the jsa file
     //   1) run normal
     //   2) modify header
-    //   3) keep header correct but modify content
+    //   3) keep header correct but modify content in each region specified by shared_region_name[]
     //   4) update both header and content, test
     //   5) delete bytes in data begining
     //   6) insert bytes in data begining
-    //   7) randomly corrupt data in four areas: RO, RW. MISC DATA, MISC CODE
+    //   7) randomly corrupt data in each region specified by shared_region_name[]
     public static void main(String... args) throws Exception {
         // must call to get offset info first!!!
         getFileOffsetInfo();
@@ -352,18 +381,23 @@
         output.shouldContain("The shared archive file has the wrong version");
         output.shouldNotContain("Checksum verification failed");
 
+        File newJsaFile = null;
         // modify content
         System.out.println("\n3. Corrupt Content, should fail\n");
-
-        copyFile(orgJsaFile, jsa);
-        modifyJsaContent();
-        testAndCheck(verifyExecArgs);
+        for (int i=0; i<num_regions; i++) {
+            newJsaFile = new File(TestCommon.getNewArchiveName(shared_region_name[i]));
+            copyFile(orgJsaFile, newJsaFile);
+            if (modifyJsaContent(i)) {
+                testAndCheck(execArgs);
+            }
+        }
 
         // modify both header and content, test should fail
         System.out.println("\n4. Corrupt Header and Content, should fail\n");
-        copyFile(orgJsaFile, jsa);
+        newJsaFile = new File(TestCommon.getNewArchiveName("header-and-content"));
+        copyFile(orgJsaFile, newJsaFile);
         modifyJsaHeader();
-        modifyJsaContent();  // this will not be reached since failed on header change first
+        modifyJsaContent(0);  // this will not be reached since failed on header change first
         output = TestCommon.execCommon(execArgs);
         output.shouldContain("The shared archive file has the wrong version");
         output.shouldNotContain("Checksum verification failed");
@@ -379,7 +413,8 @@
         testAndCheck(verifyExecArgs);
 
         System.out.println("\n7. modify Content in random areas, should fail\n");
-        copyFile(orgJsaFile, jsa);
+        newJsaFile = new File(TestCommon.getNewArchiveName("random-areas"));
+        copyFile(orgJsaFile, newJsaFile);
         modifyJsaContentRandomly();
         testAndCheck(verifyExecArgs);
     }
--- a/test/hotspot/jtreg/runtime/appcds/TestCommon.java	Fri May 17 13:21:44 2019 +0100
+++ b/test/hotspot/jtreg/runtime/appcds/TestCommon.java	Thu May 23 11:07:37 2019 +0100
@@ -32,10 +32,28 @@
 import jdk.test.lib.process.ProcessTools;
 import jdk.test.lib.process.OutputAnalyzer;
 import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.InputStream;
+import java.net.URI;
+import java.nio.file.DirectoryStream;
+import java.nio.file.Files;
+import java.nio.file.FileSystem;
+import java.nio.file.FileSystems;
+import java.nio.file.Path;
 import java.text.SimpleDateFormat;
 import java.util.Arrays;
 import java.util.ArrayList;
 import java.util.Date;
+import java.util.Enumeration;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipFile;
+import java.util.zip.ZipOutputStream;
+import jtreg.SkippedException;
+import cdsutils.DynamicDumpHelper;
+
 
 /**
  * This is a test utility class for common AppCDS test functionality.
@@ -51,7 +69,7 @@
  */
 public class TestCommon extends CDSTestUtils {
     private static final String JSA_FILE_PREFIX = System.getProperty("user.dir") +
-        File.separator + "appcds-";
+        File.separator;
 
     private static final SimpleDateFormat timeStampFormat =
         new SimpleDateFormat("HH'h'mm'm'ss's'SSS");
@@ -64,8 +82,7 @@
     // 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";
+        currentArchiveName = getNewArchiveName();
     }
 
     // Call this method to get current archive name
@@ -73,6 +90,18 @@
         return currentArchiveName;
     }
 
+    public static String getNewArchiveName() {
+        return getNewArchiveName(null);
+    }
+
+    public static String getNewArchiveName(String stem) {
+        if (stem == null) {
+            stem = "appcds";
+        }
+        return JSA_FILE_PREFIX + stem + "-" +
+            timeStampFormat.format(new Date()) + ".jsa";
+    }
+
     // 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.
@@ -92,7 +121,6 @@
         }
     }
 
-
     // Create AppCDS archive using most common args - convenience method
     // Legacy name preserved for compatibility
     public static OutputAnalyzer dump(String appJar, String classList[],
@@ -110,10 +138,12 @@
         return createArchive(opts);
     }
 
+    // Simulate -Xshare:dump with -XX:ArchiveClassesAtExit. See comments around patchJarForDynamicDump()
+    private static final Class tmp = DynamicDumpHelper.class;
+
     // Create AppCDS archive using appcds options
     public static OutputAnalyzer createArchive(AppCDSOptions opts)
         throws Exception {
-
         ArrayList<String> cmd = new ArrayList<String>();
         startNewArchiveName();
 
@@ -122,23 +152,73 @@
         if (opts.appJar != null) {
             cmd.add("-cp");
             cmd.add(opts.appJar);
+            File jf = new File(opts.appJar);
+            if (DYNAMIC_DUMP && !jf.isDirectory()) {
+                patchJarForDynamicDump(opts.appJar);
+            }
         } else {
             cmd.add("-Djava.class.path=");
         }
 
-        cmd.add("-Xshare:dump");
-
-        if (opts.archiveName == null)
+        if (opts.archiveName == null) {
             opts.archiveName = getCurrentArchiveName();
-
-        cmd.add("-XX:SharedArchiveFile=" + opts.archiveName);
-
-        if (opts.classList != null) {
-            File classListFile = makeClassList(opts.classList);
-            cmd.add("-XX:ExtraSharedClassListFile=" + classListFile.getPath());
         }
 
-        for (String s : opts.suffix) cmd.add(s);
+        if (DYNAMIC_DUMP) {
+            cmd.add("-Xshare:on");
+            cmd.add("-XX:ArchiveClassesAtExit=" + opts.archiveName);
+
+            cmd.add("-Xlog:cds");
+            cmd.add("-Xlog:cds+dynamic");
+            boolean mainModuleSpecified = false;
+            boolean patchModuleSpecified = false;
+            for (String s : opts.suffix) {
+                if (s.length() == 0) {
+                    continue;
+                }
+                if (s.equals("-m")) {
+                    mainModuleSpecified = true;
+                }
+                if (s.startsWith("--patch-module=")) {
+                    patchModuleSpecified = true;
+                }
+                cmd.add(s);
+            }
+
+            if (opts.appJar != null) {
+                // classlist is supported only when we have a Jar file to patch (to insert
+                // cdsutils.DynamicDumpHelper)
+                if (opts.classList == null) {
+                    throw new RuntimeException("test.dynamic.dump requires classList file");
+                }
+
+                if (!mainModuleSpecified && !patchModuleSpecified) {
+                    cmd.add("cdsutils.DynamicDumpHelper");
+                    File classListFile = makeClassList(opts.classList);
+                    cmd.add(classListFile.getPath());
+                }
+            } else {
+                if (!mainModuleSpecified && !patchModuleSpecified) {
+                    // If you have an empty classpath, you cannot specify a classlist!
+                    if (opts.classList != null && opts.classList.length > 0) {
+                        throw new RuntimeException("test.dynamic.dump not supported empty classpath with non-empty classlist");
+                    }
+                    cmd.add("-version");
+                }
+            }
+        } else {
+            // static dump
+            cmd.add("-Xshare:dump");
+            cmd.add("-XX:SharedArchiveFile=" + opts.archiveName);
+
+            if (opts.classList != null) {
+                File classListFile = makeClassList(opts.classList);
+                cmd.add("-XX:ExtraSharedClassListFile=" + classListFile.getPath());
+            }
+            for (String s : opts.suffix) {
+                cmd.add(s);
+            }
+        }
 
         String[] cmdLine = cmd.toArray(new String[cmd.size()]);
         ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(true, cmdLine);
@@ -154,6 +234,93 @@
     // Some AppCDS tests are not compatible with this mode. See the group
     // hotspot_appcds_with_jfr in ../../TEST.ROOT for details.
     private static final boolean RUN_WITH_JFR = Boolean.getBoolean("test.cds.run.with.jfr");
+    // This method simulates -Xshare:dump with -XX:ArchiveClassesAtExit. This way, we
+    // can re-use many tests (outside of the ./dynamicArchive directory) for testing
+    // general features of JDK-8215311 (JEP 350: Dynamic CDS Archives).
+    //
+    // We insert the cdsutils/DynamicDumpHelper.class into the first Jar file in
+    // the classpath. We use this class to load all the classes specified in the classlist.
+    //
+    // There's no need to change the run-time command-line: in this special mode, two
+    // archives are involved. The command-line specifies only the top archive. However,
+    // the location of the base archive is recorded in the top archive, so it can be
+    // determined by the JVM at runtime start-up.
+    //
+    // To run in this special mode, specify the following in your jtreg command-line
+    //    -Dtest.dynamic.cds.archive=true
+    //
+    // Note that some tests are not compatible with this special mode, including
+    //    + Tests in ./dynamicArchive: these tests are specifically written for
+    //      dynamic archive, and do not use TestCommon.createArchive(), which works
+    //      together with patchJarForDynamicDump().
+    //    + Tests related to cached objects and shared strings: dynamic dumping
+    //      does not support these.
+    //    + Custom loader tests: DynamicDumpHelper doesn't support the required
+    //      classlist syntax. (FIXME).
+    //    + Extra symbols and extra strings.
+    // See the hotspot_appcds_dynamic in ../../TEST.ROOT for details.
+    //
+    // To run all tests that are compatible with this mode:
+    //    cd test/hotspot/jtreg
+    //    jtreg -Dtest.dynamic.cds.archive=true :hotspot_appcds_dynamic
+    //
+    private static void patchJarForDynamicDump(String cp) throws Exception {
+        System.out.println("patchJarForDynamicDump: classpath = " + cp);
+        String firstJar = cp;
+        int n = firstJar.indexOf(File.pathSeparator);
+        if (n > 0) {
+            firstJar = firstJar.substring(0, n);
+        }
+        String classDir = System.getProperty("test.classes");
+        String expected1 = classDir + File.separator;
+        String expected2 = System.getProperty("user.dir") + File.separator;
+
+        if (!firstJar.startsWith(expected1) && !firstJar.startsWith(expected2)) {
+            throw new RuntimeException("FIXME: jar file not at a supported location ('"
+                                       + expected1 + "', or '" + expected2 + "'): " + firstJar);
+        }
+
+        String replaceJar = firstJar + ".tmp";
+        String patchClass = "cdsutils/DynamicDumpHelper.class";
+        ZipFile zipFile = new ZipFile(firstJar);
+        byte[] buf = new byte[1024];
+        int len;
+        if (zipFile.getEntry(patchClass) == null) {
+            FileOutputStream fout = new FileOutputStream(replaceJar);
+            final ZipOutputStream zos = new ZipOutputStream(fout);
+
+            zos.putNextEntry(new ZipEntry(patchClass));
+            InputStream is = new FileInputStream(classDir + File.separator + patchClass);
+            while ((len = (is.read(buf))) > 0) {
+                zos.write(buf, 0, len);
+            }
+            zos.closeEntry();
+            is.close();
+
+            for (Enumeration e = zipFile.entries(); e.hasMoreElements(); ) {
+                ZipEntry entryIn = (ZipEntry) e.nextElement();
+                zos.putNextEntry(entryIn);
+                is = zipFile.getInputStream(entryIn);
+                while ((len = is.read(buf)) > 0) {
+                    zos.write(buf, 0, len);
+                }
+                zos.closeEntry();
+                is.close();
+            }
+
+            zos.close();
+            fout.close();
+            zipFile.close();
+
+            File oldFile = new File(firstJar);
+            File newFile = new File(replaceJar);
+            oldFile.delete();
+            newFile.renameTo(oldFile);
+            System.out.println("firstJar = " + firstJar + " Modified");
+        } else {
+            System.out.println("firstJar = " + firstJar);
+        }
+    }
 
     // Execute JVM using AppCDS archive with specified AppCDSOptions
     public static OutputAnalyzer runWithArchive(AppCDSOptions opts)
@@ -260,12 +427,18 @@
         return runWithArchive(opts);
     }
 
-
     // A common operation: dump, then check results
     public static OutputAnalyzer testDump(String appJar, String classList[],
                                           String... suffix) throws Exception {
         OutputAnalyzer output = dump(appJar, classList, suffix);
-        output.shouldContain("Loading classes to share");
+        if (DYNAMIC_DUMP) {
+            if (isUnableToMap(output)) {
+                throw new SkippedException(UnableToMapMsg);
+            }
+            output.shouldContain("Written dynamic archive");
+        } else {
+            output.shouldContain("Loading classes to share");
+        }
         output.shouldHaveExitValue(0);
         return output;
     }
@@ -301,7 +474,6 @@
         return output;
     }
 
-
     // Convenience concatenation utils
     public static String[] list(String ...args) {
         return args;
@@ -336,6 +508,15 @@
         return list.toArray(new String[list.size()]);
     }
 
+    public static String[] concat(String prefix, String[] extra) {
+        ArrayList<String> list = new ArrayList<String>();
+        list.add(prefix);
+        for (String s : extra) {
+            list.add(s);
+        }
+
+        return list.toArray(new String[list.size()]);
+    }
 
     // ===================== Concatenate paths
     public static String concatPaths(String... paths) {
@@ -384,4 +565,29 @@
         }
         return true;
     }
+
+    static Pattern pattern;
+
+    static void findAllClasses(ArrayList<String> list) throws Throwable {
+        // Find all the classes in the jrt file system
+        pattern = Pattern.compile("/modules/[a-z.]*[a-z]+/([^-]*)[.]class");
+        FileSystem fs = FileSystems.getFileSystem(URI.create("jrt:/"));
+        Path base = fs.getPath("/modules/");
+        findAllClassesAtPath(base, list);
+    }
+
+    private static void findAllClassesAtPath(Path p, ArrayList<String> list) throws Throwable {
+        try (DirectoryStream<Path> stream = Files.newDirectoryStream(p)) {
+            for (Path entry: stream) {
+                Matcher matcher = pattern.matcher(entry.toString());
+                if (matcher.find()) {
+                    String className = matcher.group(1);
+                    list.add(className);
+                }
+                try {
+                    findAllClassesAtPath(entry, list);
+                } catch (Throwable t) {}
+            }
+        }
+    }
 }
--- a/test/hotspot/jtreg/runtime/appcds/TraceLongClasspath.java	Fri May 17 13:21:44 2019 +0100
+++ b/test/hotspot/jtreg/runtime/appcds/TraceLongClasspath.java	Thu May 23 11:07:37 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2019, 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
@@ -31,6 +31,7 @@
  *          java.management
  *          jdk.jartool/sun.tools.jar
  * @compile test-classes/Hello.java
+ * @compile test-classes/Super.java
  * @run driver TraceLongClasspath
  */
 
@@ -43,8 +44,10 @@
 
     public static void main(String[] args) throws Exception {
         String appJar = JarBuilder.getOrCreateHelloJar();
+        String dummyJar = JarBuilder.build("dummy", "Super");
 
         String longClassPath =
+            dummyJar + ps +
             "/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 +
@@ -91,15 +94,15 @@
         // Then try to execute the archive with a different classpath and with -XX:+TraceClassPaths.
         // The diagnosis "expecting" app classpath trace should show the entire classpath.
         TestCommon.run(
-            "-XX:+TraceClassPaths",
+            "-XX:+TraceClassPaths", "-Xlog:cds",
             "-cp", appJar,
             "Hello")
-          .assertAbnormalExit(output -> {
-              output.shouldContain("Unable to use shared archive");
-              output.shouldContain("shared class paths mismatch");
-              // the "expecting" app classpath from -XX:+TraceClassPaths should not
-              // be truncated
-              output.shouldContain(myCP);
-            });
+            .assertAbnormalExit(output -> {
+                output.shouldContain("Unable to use shared archive");
+                output.shouldContain("shared class paths mismatch");
+                // the "expecting" app classpath from -XX:+TraceClassPaths should not
+                // be truncated
+                output.shouldContain(myCP);
+              });
     }
 }
--- a/test/hotspot/jtreg/runtime/appcds/WrongClasspath.java	Fri May 17 13:21:44 2019 +0100
+++ b/test/hotspot/jtreg/runtime/appcds/WrongClasspath.java	Thu May 23 11:07:37 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2019, 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
@@ -47,8 +47,9 @@
     // Then try to execute the archive without -classpath -- it should fail
     TestCommon.run(
         /* "-cp", appJar, */ // <- uncomment this and the execution should succeed
+        "-Xlog:cds",
         "Hello")
-      .assertAbnormalExit("Unable to use shared archive",
-                          "shared class paths mismatch");
+        .assertAbnormalExit("Unable to use shared archive",
+                            "shared class paths mismatch");
   }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/cdsutils/DynamicDumpHelper.java	Thu May 23 11:07:37 2019 +0100
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2019, 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 cdsutils;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileReader;
+
+/**
+ * This class is used to simulate -Xshare:dump with -XX:ArchiveClassesAtExit.
+ * It loads all classes specified in a classlist file. See patchJarForDynamicDump()
+ * in ../TestCommon.java for details.
+ */
+public class DynamicDumpHelper {
+    public static void main(String args[]) throws Throwable {
+        File file = new File(args[0]);
+
+        System.out.println("Loading classes to share...");
+        try (BufferedReader br = new BufferedReader(new FileReader(file))) {
+            String line;
+            while ((line = br.readLine()) != null) {
+                //System.out.println("Loading class: " + line);
+                line = line.replace('/', '.');
+                try {
+                    Class.forName(line);
+                } catch (java.lang.ClassNotFoundException ex) {
+                    try {
+                        Class.forName(line, true, null);
+                    } catch (java.lang.ClassNotFoundException cnfe) {
+                        System.out.println("Preload Warning: Cannot find " + line.replace('.', '/'));
+                    }
+                } catch (Throwable t) {
+                    System.out.println("Error: failed to load \"" + line + "\": " + t);
+                }
+            }
+        }
+        System.out.println("Loading classes to share: done.");
+    }
+}
--- a/test/hotspot/jtreg/runtime/appcds/customLoader/ClassListFormatA.java	Fri May 17 13:21:44 2019 +0100
+++ b/test/hotspot/jtreg/runtime/appcds/customLoader/ClassListFormatA.java	Thu May 23 11:07:37 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2019, 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
@@ -32,7 +32,7 @@
  * @modules java.base/jdk.internal.misc
  *          java.management
  *          jdk.jartool/sun.tools.jar
- * @compile test-classes/Hello.java test-classes/CustomLoadee.java test-classes/CustomLoadee2.java
+ * @compile ../test-classes/Hello.java test-classes/CustomLoadee.java test-classes/CustomLoadee2.java
  *          test-classes/CustomInterface2_ia.java test-classes/CustomInterface2_ib.java
  * @run driver ClassListFormatA
  */
@@ -133,4 +133,3 @@
             "input line too long (must be no longer than " + _max_allowed_line + " chars");
     }
 }
-
--- a/test/hotspot/jtreg/runtime/appcds/customLoader/ClassListFormatB.java	Fri May 17 13:21:44 2019 +0100
+++ b/test/hotspot/jtreg/runtime/appcds/customLoader/ClassListFormatB.java	Thu May 23 11:07:37 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2019, 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
@@ -32,7 +32,7 @@
  * @modules java.base/jdk.internal.misc
  *          java.management
  *          jdk.jartool/sun.tools.jar
- * @compile test-classes/Hello.java test-classes/CustomLoadee.java test-classes/CustomLoadee2.java
+ * @compile ../test-classes/Hello.java test-classes/CustomLoadee.java test-classes/CustomLoadee2.java
  *          test-classes/CustomInterface2_ia.java test-classes/CustomInterface2_ib.java
  * @run driver ClassListFormatB
  */
@@ -69,4 +69,3 @@
             "If source location is specified, id must be also specified");
     }
 }
-
--- a/test/hotspot/jtreg/runtime/appcds/customLoader/ClassListFormatBase.java	Fri May 17 13:21:44 2019 +0100
+++ b/test/hotspot/jtreg/runtime/appcds/customLoader/ClassListFormatBase.java	Thu May 23 11:07:37 2019 +0100
@@ -79,4 +79,3 @@
         return TestCommon.list(args);
     }
 }
-
--- a/test/hotspot/jtreg/runtime/appcds/customLoader/ClassListFormatC.java	Fri May 17 13:21:44 2019 +0100
+++ b/test/hotspot/jtreg/runtime/appcds/customLoader/ClassListFormatC.java	Thu May 23 11:07:37 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2019, 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
@@ -32,7 +32,7 @@
  * @modules java.base/jdk.internal.misc
  *          java.management
  *          jdk.jartool/sun.tools.jar
- * @compile test-classes/Hello.java test-classes/CustomLoadee.java test-classes/CustomLoadee2.java
+ * @compile ../test-classes/Hello.java test-classes/CustomLoadee.java test-classes/CustomLoadee2.java
  *          test-classes/CustomInterface2_ia.java test-classes/CustomInterface2_ib.java
  * @run driver ClassListFormatC
  */
@@ -71,4 +71,3 @@
             "If source location is not specified, interface(s) must not be specified");
     }
 }
-
--- a/test/hotspot/jtreg/runtime/appcds/customLoader/ClassListFormatD.java	Fri May 17 13:21:44 2019 +0100
+++ b/test/hotspot/jtreg/runtime/appcds/customLoader/ClassListFormatD.java	Thu May 23 11:07:37 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2019, 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
@@ -32,7 +32,7 @@
  * @modules java.base/jdk.internal.misc
  *          java.management
  *          jdk.jartool/sun.tools.jar
- * @compile test-classes/Hello.java test-classes/CustomLoadee.java test-classes/CustomLoadee2.java
+ * @compile ../test-classes/Hello.java test-classes/CustomLoadee.java test-classes/CustomLoadee2.java
  *          test-classes/CustomInterface2_ia.java test-classes/CustomInterface2_ib.java
  * @run driver ClassListFormatD
  */
@@ -80,4 +80,3 @@
             "Interface id 2 is not yet loaded");
     }
 }
-
--- a/test/hotspot/jtreg/runtime/appcds/customLoader/ClassListFormatE.java	Fri May 17 13:21:44 2019 +0100
+++ b/test/hotspot/jtreg/runtime/appcds/customLoader/ClassListFormatE.java	Thu May 23 11:07:37 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2019, 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
@@ -32,7 +32,7 @@
  * @modules java.base/jdk.internal.misc
  *          java.management
  *          jdk.jartool/sun.tools.jar
- * @compile test-classes/Hello.java test-classes/CustomLoadee.java test-classes/CustomLoadee2.java
+ * @compile ../test-classes/Hello.java test-classes/CustomLoadee.java test-classes/CustomLoadee2.java
  *          test-classes/CustomInterface2_ia.java test-classes/CustomInterface2_ib.java
  * @run driver ClassListFormatE
  */
@@ -106,4 +106,3 @@
             "The specified super class CustomLoadee (id 4) does not match actual super class java.lang.Object");
     }
 }
-
--- a/test/hotspot/jtreg/runtime/appcds/customLoader/HelloCustom.java	Fri May 17 13:21:44 2019 +0100
+++ b/test/hotspot/jtreg/runtime/appcds/customLoader/HelloCustom.java	Thu May 23 11:07:37 2019 +0100
@@ -27,10 +27,12 @@
  * @summary Hello World test for AppCDS custom loader support
  * @requires vm.cds
  * @requires vm.cds.custom.loaders
- * @library /test/lib /test/hotspot/jtreg/runtime/appcds
- * @compile test-classes/Hello.java test-classes/CustomLoadee.java
- * @build sun.hotspot.WhiteBox
- * @run driver ClassFileInstaller -jar hello.jar Hello
+ * @library /test/lib /test/hotspot/jtreg/runtime/appcds /runtime/testlibrary
+ * @modules java.base/jdk.internal.misc
+ *          java.management
+ * @compile test-classes/HelloUnload.java test-classes/CustomLoadee.java
+ * @build sun.hotspot.WhiteBox ClassUnloadCommon
+ * @run driver ClassFileInstaller -jar hello.jar HelloUnload ClassUnloadCommon ClassUnloadCommon$1 ClassUnloadCommon$TestFailure
  * @run driver ClassFileInstaller -jar hello_custom.jar CustomLoadee
  * @run driver ClassFileInstaller -jar WhiteBox.jar sun.hotspot.WhiteBox
  * @run driver HelloCustom
@@ -52,7 +54,7 @@
 
         // Dump the archive
         String classlist[] = new String[] {
-            "Hello",
+            "HelloUnload",
             "java/lang/Object id: 1",
             "CustomLoadee id: 2 super: 1 source: " + customJarPath
         };
@@ -68,8 +70,7 @@
                                      use_whitebox_jar,
                                      "-XX:+UnlockDiagnosticVMOptions",
                                      "-XX:+WhiteBoxAPI",
-                                     "Hello", customJarPath));
+                                     "HelloUnload", customJarPath, "true", "true"));
         TestCommon.checkExec(output);
     }
 }
-
--- a/test/hotspot/jtreg/runtime/appcds/customLoader/HelloCustom_JFR.java	Fri May 17 13:21:44 2019 +0100
+++ b/test/hotspot/jtreg/runtime/appcds/customLoader/HelloCustom_JFR.java	Thu May 23 11:07:37 2019 +0100
@@ -30,10 +30,10 @@
  * @requires vm.hasJFR
  * @requires vm.cds
  * @requires vm.cds.custom.loaders
- * @library /test/lib /test/hotspot/jtreg/runtime/appcds
- * @compile test-classes/Hello.java test-classes/CustomLoadee.java
- * @build sun.hotspot.WhiteBox
- * @run driver ClassFileInstaller -jar hello.jar Hello
+ * @library /test/lib /test/hotspot/jtreg/runtime/appcds /runtime/testlibrary
+ * @compile test-classes/HelloUnload.java test-classes/CustomLoadee.java
+ * @build sun.hotspot.WhiteBox ClassUnloadCommon
+ * @run driver ClassFileInstaller -jar hello.jar HelloUnload ClassUnloadCommon ClassUnloadCommon$1 ClassUnloadCommon$TestFailure
  * @run driver ClassFileInstaller -jar hello_custom.jar CustomLoadee
  * @run driver ClassFileInstaller -jar WhiteBox.jar sun.hotspot.WhiteBox
  * @run driver HelloCustom_JFR
@@ -47,4 +47,3 @@
         HelloCustom.run("-XX:StartFlightRecording=dumponexit=true", "-Xlog:cds+jvmti=debug");
     }
 }
-
--- a/test/hotspot/jtreg/runtime/appcds/customLoader/ProhibitedPackageNamesTest.java	Fri May 17 13:21:44 2019 +0100
+++ b/test/hotspot/jtreg/runtime/appcds/customLoader/ProhibitedPackageNamesTest.java	Thu May 23 11:07:37 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2019, 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
@@ -31,7 +31,7 @@
  * @modules java.base/jdk.internal.misc
  *          java.management
  *          jdk.jartool/sun.tools.jar
- * @compile ClassListFormatBase.java test-classes/Hello.java test-classes/InProhibitedPkg.java
+ * @compile ClassListFormatBase.java ../test-classes/Hello.java test-classes/InProhibitedPkg.java
  * @run driver ProhibitedPackageNamesTest
  */
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/customLoader/test-classes/HelloUnload.java	Thu May 23 11:07:37 2019 +0100
@@ -0,0 +1,106 @@
+/*
+ * Copyright (c) 2019, 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.File;
+import java.net.URL;
+import java.net.URLClassLoader;
+import sun.hotspot.WhiteBox;
+
+public class HelloUnload {
+    private static String className = "CustomLoadee";
+
+    public static void main(String args[]) throws Exception {
+        if (args.length != 3) {
+            throw new RuntimeException("Unexpected number of arguments: expected 3, actual " + args.length);
+        }
+
+        String path = args[0];
+        URL url = new File(path).toURI().toURL();
+        URL[] urls = new URL[] {url};
+        System.out.println(path);
+        System.out.println(url);
+
+        // unload the custom class loader
+        boolean doUnload = false;
+        if (args[1].equals("true")) {
+            doUnload = true;
+        } else if (args[1].equals("false")) {
+            doUnload = false;
+        } else {
+            throw new RuntimeException("args[1] can only be either \"true\" or \"false\", actual " + args[1]);
+        }
+
+        // should the CustomLoadee class be in the shared archive
+        boolean inArchive = false;
+        if (args[2].equals("true")) {
+            inArchive = true;
+        } else if (args[2].equals("false")) {
+            inArchive = false;
+        } else {
+            throw new RuntimeException("args[2] can only be either \"true\" or \"false\", actual " + args[1]);
+        }
+
+        URLClassLoader urlClassLoader =
+            new URLClassLoader("HelloClassLoader", urls, null);
+        Class c = Class.forName(className, true, urlClassLoader);
+        System.out.println(c);
+        System.out.println(c.getClassLoader());
+        Object o = c.newInstance();
+
+        // [1] Check that CustomLoadee is defined by the correct loader
+        if (c.getClassLoader() != urlClassLoader) {
+            throw new RuntimeException("c.getClassLoader() == " + c.getClassLoader() +
+                                       ", expected == " + urlClassLoader);
+        }
+
+        // [2] Check that CustomLoadee is loaded from shared archive.
+        WhiteBox wb = WhiteBox.getWhiteBox();
+        if(wb.isSharedClass(HelloUnload.class)) {
+            if (inArchive && !wb.isSharedClass(c)) {
+                throw new RuntimeException("wb.isSharedClass(c) should be true");
+            }
+        }
+
+        ClassUnloadCommon.failIf(!wb.isClassAlive(className), "should be live here");
+
+        if (doUnload) {
+            String loaderName = urlClassLoader.getName();
+            int loadedRefcount = wb.getSymbolRefcount(loaderName);
+            System.out.println("Refcount of symbol " + loaderName + " is " + loadedRefcount);
+
+            urlClassLoader = null; c = null; o = null;
+            ClassUnloadCommon.triggerUnloading();
+            System.out.println("Is CustomLoadee alive? " + wb.isClassAlive(className));
+            ClassUnloadCommon.failIf(wb.isClassAlive(className), "should have been unloaded");
+
+            int unloadedRefcount = wb.getSymbolRefcount(loaderName);
+            System.out.println("Refcount of symbol " + loaderName + " is " + unloadedRefcount);
+
+            // refcount of a permanent symbol will not be decremented
+            if (loadedRefcount != 65535) {
+                ClassUnloadCommon.failIf(unloadedRefcount != (loadedRefcount - 1), "Refcount must be decremented");
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/dynamicArchive/AppendClasspath.java	Thu May 23 11:07:37 2019 +0100
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 2019, 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.
+ * @requires vm.cds
+ * @library /test/lib /test/hotspot/jtreg/runtime/appcds
+ * @modules java.base/jdk.internal.misc
+ *          java.management
+ *          jdk.jartool/sun.tools.jar
+ * @compile ../test-classes/Hello.java
+ * @compile ../test-classes/HelloMore.java
+ * @run driver AppendClasspath
+ */
+
+import java.io.File;
+
+public class AppendClasspath extends DynamicArchiveTestBase {
+
+    public static void main(String[] args) throws Exception {
+        runTest(AppendClasspath::testDefaultBase);
+    }
+
+    static void testDefaultBase() throws Exception {
+        String topArchiveName = getNewArchiveName("top");
+        doTest(topArchiveName);
+    }
+
+    private static void doTest(String topArchiveName) throws Exception {
+        String appJar = JarBuilder.getOrCreateHelloJar();
+        String appJar2 = JarBuilder.build("AppendClasspath_HelloMore", "HelloMore");
+
+        // Dump an archive with a specified JAR file in -classpath
+        dump(topArchiveName,
+             "-Xlog:cds",
+             "-Xlog:cds+dynamic=debug",
+             "-cp", appJar, "Hello")
+            .assertNormalExit(output -> {
+                    output.shouldContain("Buffer-space to target-space delta")
+                           .shouldContain("Written dynamic archive 0x");
+                });
+
+        // runtime with classpath containing the one used in dump time,
+        // i.e. the dump time classpath is a prefix of the runtime classpath.
+        run(topArchiveName,
+            "-Xlog:class+load",
+            "-Xlog:cds+dynamic=debug,cds=debug",
+            "-cp", appJar + File.pathSeparator + appJar2,
+            "HelloMore")
+            .assertNormalExit(output -> {
+                    output.shouldContain("Hello source: shared objects file")
+                          .shouldContain("Hello World ... More")
+                          .shouldHaveExitValue(0);
+                });
+
+        // reverse the order of the 2 jar files so that the dump time classpath
+        // is no longer a prefix of the runtime classpath. The Hello class
+        // should be loaded from the jar file.
+        run(topArchiveName,
+            "-Xlog:class+load",
+            "-Xlog:cds+dynamic=debug,cds=debug",
+            "-cp", appJar2 + File.pathSeparator + appJar,
+            "HelloMore")
+            .assertAbnormalExit(output -> {
+                    output.shouldContain("shared class paths mismatch")
+                          .shouldHaveExitValue(1);
+                });
+
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/dynamicArchive/ArchiveConsistency.java	Thu May 23 11:07:37 2019 +0100
@@ -0,0 +1,167 @@
+/*
+ * Copyright (c) 2019, 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 Corrupt the header CRC fields of the top archive. VM should exit with an error.
+ * @requires vm.cds
+ * @library /test/lib /test/hotspot/jtreg/runtime/appcds /test/hotspot/jtreg/runtime/appcds/test-classes
+ * @build Hello sun.hotspot.WhiteBox
+ * @run driver ClassFileInstaller -jar hello.jar Hello
+ * @run driver ClassFileInstaller sun.hotspot.WhiteBox
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI ArchiveConsistency
+ */
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.nio.channels.FileChannel;
+import java.nio.file.StandardOpenOption;
+import static java.nio.file.StandardOpenOption.READ;
+import static java.nio.file.StandardOpenOption.WRITE;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import sun.hotspot.WhiteBox;
+
+public class ArchiveConsistency extends DynamicArchiveTestBase {
+    public static WhiteBox wb;
+    public static int int_size;        // size of int
+    public static String[] shared_region_name = {"MiscCode", "ReadWrite", "ReadOnly", "MiscData"};
+    public static int num_regions = shared_region_name.length;
+
+    public static void main(String[] args) throws Exception {
+        runTest(ArchiveConsistency::testCustomBase);
+    }
+
+    // Test with custom base archive + top archive
+    static void testCustomBase() throws Exception {
+        String topArchiveName = getNewArchiveName("top2");
+        String baseArchiveName = getNewArchiveName("base");
+        dumpBaseArchive(baseArchiveName);
+        doTest(baseArchiveName, topArchiveName);
+    }
+
+    public static void setReadWritePermission(File file) throws Exception {
+        if (!file.canRead()) {
+            if (!file.setReadable(true)) {
+                throw new IOException("Cannot modify file " + file + " as readable");
+            }
+        }
+        if (!file.canWrite()) {
+            if (!file.setWritable(true)) {
+                throw new IOException("Cannot modify file " + file + " as writable");
+            }
+        }
+    }
+
+    public static long readInt(FileChannel fc, long offset, int nbytes) throws Exception {
+        ByteBuffer bb = ByteBuffer.allocate(nbytes);
+        bb.order(ByteOrder.nativeOrder());
+        fc.position(offset);
+        fc.read(bb);
+        return  (nbytes > 4 ? bb.getLong(0) : bb.getInt(0));
+    }
+
+    public static long align_up_page(long l) throws Exception {
+        // wb is obtained in getFileOffsetInfo() which is called first in main() else we should call
+        // WhiteBox.getWhiteBox() here first.
+        int pageSize = wb.getVMPageSize();
+        return (l + pageSize -1) & (~ (pageSize - 1));
+    }
+
+    public static void writeData(FileChannel fc, long offset, ByteBuffer bb) throws Exception {
+        fc.position(offset);
+        fc.write(bb);
+        fc.force(true);
+    }
+
+    public static FileChannel getFileChannel(File jsa) throws Exception {
+        List<StandardOpenOption> arry = new ArrayList<StandardOpenOption>();
+        arry.add(READ);
+        arry.add(WRITE);
+        return FileChannel.open(jsa.toPath(), new HashSet<StandardOpenOption>(arry));
+    }
+
+   public static void modifyJsaHeaderCRC(File jsa) throws Exception {
+        FileChannel fc = getFileChannel(jsa);
+        int_size = wb.getOffsetForName("int_size");
+        System.out.println("    int_size " + int_size);
+        ByteBuffer bbuf = ByteBuffer.allocateDirect(int_size);
+        for (int i = 0; i < int_size; i++) {
+            bbuf.put((byte)0);
+        }
+
+        int baseArchiveCRCOffset = wb.getOffsetForName("DynamicArchiveHeader::_base_archive_crc");
+        int crc = 0;
+        System.out.printf("%-12s%-12s\n", "Space name", "CRC");
+        for (int i = 0; i < 4; i++) {
+            baseArchiveCRCOffset += int_size * i;
+            System.out.println("    baseArchiveCRCOffset " + baseArchiveCRCOffset);
+            crc = (int)readInt(fc, baseArchiveCRCOffset, int_size );
+            System.out.printf("%-11s%-12d\n", shared_region_name[i], crc);
+            bbuf.rewind();
+            writeData(fc, baseArchiveCRCOffset, bbuf);
+        }
+        fc.force(true);
+        if (fc.isOpen()) {
+            fc.close();
+        }
+    }
+
+    private static void doTest(String baseArchiveName, String topArchiveName) throws Exception {
+        String appJar = ClassFileInstaller.getJarPath("hello.jar");
+        String mainClass = "Hello";
+        dump2(baseArchiveName, topArchiveName,
+             "-Xlog:cds",
+             "-Xlog:cds+dynamic=debug",
+             "-cp", appJar, mainClass)
+            .assertNormalExit(output -> {
+                    output.shouldContain("Buffer-space to target-space delta")
+                          .shouldContain("Written dynamic archive 0x");
+                });
+
+        File jsa = new File(topArchiveName);
+        if (!jsa.exists()) {
+            throw new IOException(jsa + " does not exist!");
+        }
+
+        // Modify the CRC values in the header of the top archive.
+        wb = WhiteBox.getWhiteBox();
+        setReadWritePermission(jsa);
+        modifyJsaHeaderCRC(jsa);
+
+        run2(baseArchiveName, topArchiveName,
+            "-Xlog:class+load",
+            "-Xlog:cds+dynamic=debug,cds=debug",
+            "-XX:+VerifySharedSpaces",
+            "-cp", appJar, mainClass)
+            .assertAbnormalExit(output -> {
+                    output.shouldContain("Header checksum verification failed")
+                          .shouldContain("Unable to use shared archive")
+                          .shouldHaveExitValue(1);
+                });
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/dynamicArchive/ArrayKlasses.java	Thu May 23 11:07:37 2019 +0100
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2019, 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 the existence of InstanceKlass::array_klasses()
+ * @requires vm.cds
+ * @library /test/lib /test/hotspot/jtreg/runtime/appcds
+ *          /test/hotspot/jtreg/runtime/appcds/dynamicArchive/test-classes
+ * @build ArrayKlassesApp
+ * @run driver ClassFileInstaller -jar ArrayKlasses.jar
+ *             ArrayKlassesApp
+ * @run driver ArrayKlasses
+ */
+
+public class ArrayKlasses extends DynamicArchiveTestBase {
+    public static void main(String[] args) throws Exception {
+        runTest(ArrayKlasses::test);
+    }
+
+    static void test() throws Exception {
+        String topArchiveName = getNewArchiveName();
+        String appJar = ClassFileInstaller.getJarPath("ArrayKlasses.jar");
+        String mainClass = "ArrayKlassesApp";
+
+        dumpAndRun(topArchiveName, "-Xlog:cds+dynamic=debug", "-cp", appJar, mainClass);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/dynamicArchive/ClassResolutionFailure.java	Thu May 23 11:07:37 2019 +0100
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2019, 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 with a jar file which contains only the main class but not the dependent class.
+ *          The main class should be archived. During run time, the main class
+ *          should be loaded from the archive.
+ * @requires vm.cds
+ * @library /test/lib /test/hotspot/jtreg/runtime/appcds /test/hotspot/jtreg/runtime/appcds/dynamicArchive/test-classes
+ * @build StrConcatApp
+ * @build MissingDependent
+ * @run driver ClassFileInstaller -jar missingDependent.jar MissingDependent
+ * @run driver ClassResolutionFailure
+ */
+
+public class ClassResolutionFailure extends DynamicArchiveTestBase {
+
+    public static void main(String[] args) throws Exception {
+        runTest(ClassResolutionFailure::testDefaultBase);
+    }
+
+    // Test with default base archive + top archive
+    static void testDefaultBase() throws Exception {
+        String topArchiveName = getNewArchiveName("top");
+        doTest(topArchiveName);
+    }
+
+    private static void doTest(String topArchiveName) throws Exception {
+        String appJar = ClassFileInstaller.getJarPath("missingDependent.jar");
+        String mainClass = "MissingDependent";
+
+        dump(topArchiveName,
+             "-Xlog:cds",
+             "-Xlog:cds+dynamic=debug",
+             "-Xlog:class+load=trace",
+             "-cp", appJar, mainClass)
+            .assertNormalExit(output -> {
+                    output.shouldContain("Buffer-space to target-space delta")
+                           .shouldContain("Written dynamic archive 0x");
+                });
+
+        run(topArchiveName,
+            "-Xlog:class+load",
+            "-Xlog:cds+dynamic=debug,cds=debug",
+            "-cp", appJar, mainClass)
+            .assertNormalExit(output -> {
+                    output.shouldContain("MissingDependent source: shared objects file")
+                          .shouldHaveExitValue(0);
+                });
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/dynamicArchive/DynamicArchiveTestBase.java	Thu May 23 11:07:37 2019 +0100
@@ -0,0 +1,246 @@
+/*
+ * Copyright (c) 2019, 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.File;
+import jdk.test.lib.process.OutputAnalyzer;
+import jdk.test.lib.process.ProcessTools;
+import jdk.test.lib.cds.CDSOptions;
+import jdk.test.lib.cds.CDSTestUtils;
+import jdk.test.lib.cds.CDSTestUtils.Result;
+
+/**
+ * Base class for test cases in test/hotspot/jtreg/runtime/appcds/dynamicArchive/
+ */
+class DynamicArchiveTestBase {
+    private static boolean executedIn_run = false;
+
+    public static interface DynamicArchiveTest {
+        public void run() throws Exception;
+    }
+
+    public static interface DynamicArchiveTestWithArgs {
+        public void run(String args[]) throws Exception;
+    }
+
+
+    /*
+     * Tests for dynamic archives should be written using this pattern:
+     *
+     * public class HelloDynamic extends DynamicArchiveTestBase {
+     *     public static void main(String[] args) throws Exception {
+     *        runTest(HelloDynamic::testDefaultBase); // launch one test case
+     *     }
+     *
+     *     // the body of a test case
+     *     static void testDefaultBase() throws Exception {
+     *         String topArchiveName = getNewArchiveName("top");
+     *         doTest(null, topArchiveName);
+     *     }
+     * }
+     *
+     * The reason for this is so that we can clean up the archive files
+     * created by prior test cases. Otherwise tests with lots of
+     * test cases may fill up the scratch directory.
+     */
+    public static void runTest(DynamicArchiveTest t) throws Exception {
+        executedIn_run = true;
+        try {
+            TestCommon.deletePriorArchives();
+            t.run();
+        } finally {
+            executedIn_run = false;
+        }
+    }
+
+    public static void runTest(DynamicArchiveTestWithArgs t, String... args) throws Exception {
+        executedIn_run = true;
+        try {
+            TestCommon.deletePriorArchives();
+            t.run(args);
+        } finally {
+            executedIn_run = false;
+        }
+    }
+
+    public static String getNewArchiveName() {
+        return TestCommon.getNewArchiveName();
+    }
+    public static String getNewArchiveName(String stem) {
+        return TestCommon.getNewArchiveName(stem);
+    }
+
+    /**
+     * Execute a JVM using the base archive (given by baseArchiveName) with the command line
+     * (given by cmdLineSuffix). At JVM exit, dump all eligible classes into the top archive
+     * (give by topArchiveName).
+     *
+     * If baseArchiveName is null, use the JDK's default archive as the base archive.
+     */
+    public static Result dump2(String baseArchiveName, String topArchiveName, String ... cmdLineSuffix)
+        throws Exception
+    {
+        String[] cmdLine = TestCommon.concat(
+            "-XX:ArchiveClassesAtExit=" + topArchiveName);
+        // to allow dynamic archive tests to be run in the "rt-non-cds-mode"
+        cmdLine = TestCommon.concat(cmdLine, "-Xshare:auto");
+        if (baseArchiveName != null) {
+            cmdLine = TestCommon.concat(cmdLine, "-XX:SharedArchiveFile=" + baseArchiveName);
+        }
+        cmdLine = TestCommon.concat(cmdLine, cmdLineSuffix);
+        return execProcess("dump", cmdLine);
+    }
+
+    public static Result dump2_WB(String baseArchiveName, String topArchiveName, String ... cmdLineSuffix)
+        throws Exception
+    {
+        return dump2(baseArchiveName, topArchiveName,
+                     TestCommon.concat(wbRuntimeArgs(), cmdLineSuffix));
+    }
+
+    /**
+     * A convenience method similar to dump2, but always use the JDK's default archive
+     * as the base archive.
+     *
+     * Most dynamicArchive/*.java test cases should be using this method instead of run2.
+     */
+    public static Result dump(String topArchiveName, String ... cmdLineSuffix)
+        throws Exception
+    {
+        return dump2(null, topArchiveName, cmdLineSuffix);
+    }
+
+    /**
+     * Dump the base archive. The JDK's default class list is used (unless otherwise specified
+     * in cmdLineSuffix).
+     */
+    public static void dumpBaseArchive(String baseArchiveName, String ... cmdLineSuffix)
+        throws Exception
+    {
+        CDSOptions opts = new CDSOptions();
+        opts.setArchiveName(baseArchiveName);
+        opts.addSuffix(cmdLineSuffix);
+        opts.addSuffix("-Djava.class.path=");
+        OutputAnalyzer out = CDSTestUtils.createArchive(opts);
+        CDSTestUtils.checkDump(out);
+    }
+
+    /**
+     * Same as dumpBaseArchive, but also add WhiteBox to the bootcp
+     */
+    public static void dumpBaseArchive_WB(String baseArchiveName, String ... cmdLineSuffix)
+        throws Exception
+    {
+        dumpBaseArchive(baseArchiveName,
+                        TestCommon.concat("-Xbootclasspath/a:" + getWhiteBoxJar(), cmdLineSuffix));
+    }
+
+    private static String getWhiteBoxJar() {
+        String wbJar = ClassFileInstaller.getJarPath("WhiteBox.jar");
+        if (!(new File(wbJar)).exists()) {
+            throw new RuntimeException("Test error: your test must have " +
+                                       "'@run driver ClassFileInstaller -jar WhiteBox.jar sun.hotspot.WhiteBox'");
+        }
+        return wbJar;
+    }
+
+    private static String[] wbRuntimeArgs() {
+        return TestCommon.concat("-Xbootclasspath/a:" + getWhiteBoxJar(),
+                                 "-XX:+UnlockDiagnosticVMOptions",
+                                 "-XX:+WhiteBoxAPI");
+    }
+
+    /**
+     * Execute a JVM using the base archive (given by baseArchiveName) and the top archive
+     * (give by topArchiveName), using the command line (given by cmdLineSuffix).
+     *
+     * If baseArchiveName is null, use the JDK's default archive as the base archive.
+     */
+    public static Result run2(String baseArchiveName, String topArchiveName, String ... cmdLineSuffix)
+        throws Exception {
+        if (baseArchiveName == null && topArchiveName == null) {
+            throw new RuntimeException("Both baseArchiveName and topArchiveName cannot be null at the same time.");
+        }
+        String archiveFiles = (baseArchiveName == null) ? topArchiveName :
+            (topArchiveName == null) ? baseArchiveName :
+            baseArchiveName + File.pathSeparator + topArchiveName;
+        String[] cmdLine = TestCommon.concat(
+            "-Xshare:on",
+            "-XX:SharedArchiveFile=" + archiveFiles);
+        cmdLine = TestCommon.concat(cmdLine, cmdLineSuffix);
+        return execProcess("exec", cmdLine);
+    }
+
+    public static Result run2_WB(String baseArchiveName, String topArchiveName, String ... cmdLineSuffix)
+        throws Exception
+    {
+        return run2(baseArchiveName, topArchiveName,
+                    TestCommon.concat(wbRuntimeArgs(), cmdLineSuffix));
+    }
+
+    /**
+     * A convenience method similar to run2, but always use the JDK's default archive
+     * as the base archive.
+     *
+     * Most dynamicArchive/*.java test cases should be using this method instead of run2.
+     */
+    public static Result run(String topArchiveName, String ... cmdLineSuffix)
+        throws Exception
+    {
+        return run2(null, topArchiveName, cmdLineSuffix);
+    }
+
+    private static String getXshareMode(String[] cmdLine) {
+        for (int i = 0; i <= cmdLine.length - 1; i++) {
+            int j = cmdLine[i].indexOf("-Xshare:");
+            if (j != -1) {
+                return (cmdLine[i].substring(j));
+            }
+        }
+        return null;
+   }
+
+
+    private static Result execProcess(String mode, String[] cmdLine) throws Exception {
+        if (!executedIn_run) {
+            throw new Exception("Test error: dynamic archive tests must be executed via DynamicArchiveTestBase.run()");
+        }
+        ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(true, cmdLine);
+        OutputAnalyzer output = TestCommon.executeAndLog(pb, mode);
+        CDSOptions opts = new CDSOptions();
+        String xShareMode = getXshareMode(cmdLine);
+        if (xShareMode != null) {
+            opts.setXShareMode(xShareMode);
+        }
+        return new Result(opts, output);
+    }
+
+    /**
+     * A convenience method for dumping and running, using the default CDS archive from the
+     * JDK. Both dumping and running should exit normally.
+     */
+    public static void dumpAndRun(String topArchiveName, String ... cmdLineSuffix) throws Exception {
+        dump(topArchiveName, cmdLineSuffix).assertNormalExit();
+        run(topArchiveName,  cmdLineSuffix).assertNormalExit();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/dynamicArchive/DynamicFlag.java	Thu May 23 11:07:37 2019 +0100
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2019, 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 The DynamicDumpShareSpaces flag is internal, setting it at the command line should have no effect.
+ * @requires vm.cds
+ * @library /test/lib /test/hotspot/jtreg/runtime/appcds
+ * @modules java.base/jdk.internal.misc
+ *          jdk.jartool/sun.tools.jar
+ * @compile ../test-classes/Hello.java
+ * @run driver DynamicFlag
+ */
+
+public class DynamicFlag {
+  public static void main(String[] args) throws Exception {
+      TestCommon.test(JarBuilder.getOrCreateHelloJar(),
+          TestCommon.list("Hello"), "-XX:+DynamicDumpSharedSpaces", "Hello");
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/dynamicArchive/DynamicLotsOfClasses.java	Thu May 23 11:07:37 2019 +0100
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2019, 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.File;
+import java.nio.charset.Charset;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.List;
+import java.util.ArrayList;
+
+/*
+ * @test
+ * @summary Try to archive lots of classes by searching for classes from the jrt:/ file system. With JDK 12
+ *          this will produce an archive with over 30,000 classes.
+ * @requires vm.cds
+ * @library /test/lib /test/hotspot/jtreg/runtime/appcds /test/hotspot/jtreg/runtime/appcds/dynamicArchive/test-classes
+ * @build LoadClasses
+ * @build sun.hotspot.WhiteBox
+ * @modules jdk.jartool/sun.tools.jar
+ * @run driver ClassFileInstaller -jar loadclasses.jar LoadClasses
+ * @run driver ClassFileInstaller -jar whitebox.jar sun.hotspot.WhiteBox
+ * @run driver/timeout=500 DynamicLotsOfClasses
+ */
+
+public class DynamicLotsOfClasses extends DynamicArchiveTestBase {
+
+    public static void main(String[] args) throws Throwable {
+        runTest(DynamicLotsOfClasses::testDefaultBase);
+    }
+
+    static void testDefaultBase() throws Exception {
+        String topArchiveName = getNewArchiveName("top");
+        try {
+            doTest(topArchiveName);
+         } catch (Throwable th) {
+             System.out.println(th.toString());
+             Exception ex = new Exception(th);
+             throw ex;
+         }
+    }
+
+    private static void doTest(String topArchiveName) throws Throwable {
+        ArrayList<String> list = new ArrayList<>();
+        TestCommon.findAllClasses(list);
+
+        String classList = System.getProperty("user.dir") + File.separator +
+                           "LotsOfClasses.list";
+        List<String> lines = list;
+        Path file = Paths.get(classList);
+        Files.write(file, lines, Charset.forName("UTF-8"));
+
+        String appJar = ClassFileInstaller.getJarPath("loadclasses.jar");
+        String mainClass = "LoadClasses";
+
+        String whiteBoxJar = ClassFileInstaller.getJarPath("whitebox.jar");
+        String bootClassPath = "-Xbootclasspath/a:" + whiteBoxJar;
+        dump(topArchiveName,
+             "--add-modules",
+             "ALL-SYSTEM",
+             "-Xlog:hashtables",
+             "-Xmx500m",
+             "-Xlog:cds,cds+dynamic",
+             bootClassPath,
+             "-XX:+UnlockDiagnosticVMOptions", "-XX:+WhiteBoxAPI",
+             "-cp", appJar, mainClass, classList)
+             .assertNormalExit(output -> {
+                 output.shouldContain("Buffer-space to target-space delta")
+                        .shouldContain("Written dynamic archive 0x");
+             });
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/dynamicArchive/ExcludedClasses.java	Thu May 23 11:07:37 2019 +0100
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2019, 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 Unreferenced app classes during dump time should not be included in the archive.
+ * @requires vm.cds
+ * @library /test/lib /test/hotspot/jtreg/runtime/appcds
+ *          /test/hotspot/jtreg/runtime/appcds/dynamicArchive/test-classes
+ * @build ExcludedClassesApp
+ * @run driver ClassFileInstaller -jar ExcludedClasses.jar
+ *             ExcludedClassesApp
+ *             ExcludedClassesApp$NotLinkedSuper
+ *             ExcludedClassesApp$NotLinkedChild
+ *             ExcludedClassesApp$NotLinkedInterface
+ * @run driver ExcludedClasses
+ */
+
+public class ExcludedClasses extends DynamicArchiveTestBase {
+    public static void main(String[] args) throws Exception {
+        runTest(ExcludedClasses::test);
+    }
+
+    static void test() throws Exception {
+        String topArchiveName = getNewArchiveName();
+        String appJar = ClassFileInstaller.getJarPath("ExcludedClasses.jar");
+        String mainClass = "ExcludedClassesApp";
+
+        dumpAndRun(topArchiveName, "-Xlog:cds+dynamic=debug", "-cp", appJar, mainClass);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/dynamicArchive/HelloDynamic.java	Thu May 23 11:07:37 2019 +0100
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2019, 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 dynamic archive
+ * @requires vm.cds
+ * @library /test/lib /test/hotspot/jtreg/runtime/appcds /test/hotspot/jtreg/runtime/appcds/test-classes
+ * @build Hello
+ * @run driver ClassFileInstaller -jar hello.jar Hello
+ * @run driver HelloDynamic
+ */
+
+public class HelloDynamic extends DynamicArchiveTestBase {
+    public static void main(String[] args) throws Exception {
+        runTest(HelloDynamic::testDefaultBase);
+        runTest(HelloDynamic::testCustomBase);
+    }
+
+    // (1) Test with default base archive + top archive
+    static void testDefaultBase() throws Exception {
+        String topArchiveName = getNewArchiveName("top");
+        doTest(null, topArchiveName);
+    }
+
+    // (2) Test with custom base archive + top archive
+    static void testCustomBase() throws Exception {
+        String topArchiveName = getNewArchiveName("top2");
+        String baseArchiveName = getNewArchiveName("base");
+        dumpBaseArchive(baseArchiveName);
+        doTest(baseArchiveName, topArchiveName);
+    }
+
+    private static void doTest(String baseArchiveName, String topArchiveName) throws Exception {
+        String appJar = ClassFileInstaller.getJarPath("hello.jar");
+        String mainClass = "Hello";
+        dump2(baseArchiveName, topArchiveName,
+             "-Xlog:cds",
+             "-Xlog:cds+dynamic=debug",
+             "-cp", appJar, mainClass)
+            .assertNormalExit(output -> {
+                    output.shouldContain("Buffer-space to target-space delta")
+                           .shouldContain("Written dynamic archive 0x");
+                });
+        run2(baseArchiveName, topArchiveName,
+            "-Xlog:class+load",
+            "-Xlog:cds+dynamic=debug,cds=debug",
+            "-cp", appJar, mainClass)
+            .assertNormalExit(output -> {
+                    output.shouldContain("Hello source: shared objects file")
+                          .shouldHaveExitValue(0);
+                });
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/dynamicArchive/HelloDynamicCustom.java	Thu May 23 11:07:37 2019 +0100
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2019, 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 dynamic archive with custom loader
+ * @requires vm.cds
+ * @library /test/lib /test/hotspot/jtreg/runtime/appcds /test/hotspot/jtreg/runtime/appcds/customLoader/test-classes /runtime/testlibrary
+ * @build HelloUnload CustomLoadee ClassUnloadCommon
+ * @build sun.hotspot.WhiteBox
+ * @run driver ClassFileInstaller -jar hello.jar HelloUnload ClassUnloadCommon ClassUnloadCommon$1 ClassUnloadCommon$TestFailure
+ * @run driver ClassFileInstaller -jar hello_custom.jar CustomLoadee
+ * @run driver ClassFileInstaller -jar WhiteBox.jar sun.hotspot.WhiteBox
+ * @run driver HelloDynamicCustom
+ */
+
+import java.io.File;
+import jdk.test.lib.process.OutputAnalyzer;
+import jdk.test.lib.process.ProcessTools;
+
+public class HelloDynamicCustom {
+    private static final String ARCHIVE_NAME =
+        System.getProperty("test.classes") + File.separator + "HelloDynamicCustom.jsa";
+
+    public static void main(String[] args) throws Exception {
+        String wbJar = ClassFileInstaller.getJarPath("WhiteBox.jar");
+        String use_whitebox_jar = "-Xbootclasspath/a:" + wbJar;
+        String appJar = ClassFileInstaller.getJarPath("hello.jar");
+        String customJarPath = ClassFileInstaller.getJarPath("hello_custom.jar");
+        String mainAppClass = "HelloUnload";
+
+        ProcessBuilder dumpPb = ProcessTools.createJavaProcessBuilder(true,
+            use_whitebox_jar,
+            "-XX:+UnlockDiagnosticVMOptions",
+            "-XX:+WhiteBoxAPI",
+            "-Xlog:cds",
+            "-Xlog:cds+dynamic=debug",
+            "-Xshare:auto",
+            "-XX:ArchiveClassesAtExit=" + ARCHIVE_NAME,
+            "-cp", appJar,
+            mainAppClass, customJarPath, "false", "false");
+        TestCommon.executeAndLog(dumpPb, "dump")
+            .shouldContain("Buffer-space to target-space delta")
+            .shouldContain("Written dynamic archive 0x")
+            .shouldNotContain("klasses.*=.*CustomLoadee")   // Fixme -- use a better way to decide if a class has been archived
+            .shouldHaveExitValue(0);
+
+        ProcessBuilder execPb = ProcessTools.createJavaProcessBuilder(true,
+            use_whitebox_jar,
+            "-XX:+UnlockDiagnosticVMOptions",
+            "-XX:+WhiteBoxAPI",
+            "-Xlog:class+load",
+            "-Xlog:cds=debug",
+            "-Xlog:cds+dynamic=info",
+            "-Xshare:auto",
+            "-XX:SharedArchiveFile=" + ARCHIVE_NAME,
+            "-cp", appJar,
+            mainAppClass, customJarPath, "false", "true");
+        TestCommon.executeAndLog(execPb, "exec")
+            .shouldContain("HelloUnload source: shared objects file")
+            .shouldContain("CustomLoadee source: shared objects file")
+            .shouldHaveExitValue(0);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/dynamicArchive/HelloDynamicCustomUnload.java	Thu May 23 11:07:37 2019 +0100
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2019, 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 dynamic archive with custom loader.
+ *          Attempt will be made to unload the custom loader during
+ *          dump time and run time. The custom loader will be unloaded
+ *          during dump time.
+ * @requires vm.cds
+ * @library /test/lib /test/hotspot/jtreg/runtime/appcds /test/hotspot/jtreg/runtime/appcds/customLoader/test-classes /runtime/testlibrary
+ * @build HelloUnload CustomLoadee ClassUnloadCommon
+ * @build sun.hotspot.WhiteBox
+ * @run driver ClassFileInstaller -jar hello.jar HelloUnload ClassUnloadCommon ClassUnloadCommon$1 ClassUnloadCommon$TestFailure
+ * @run driver ClassFileInstaller -jar hello_custom.jar CustomLoadee
+ * @run driver ClassFileInstaller -jar WhiteBox.jar sun.hotspot.WhiteBox
+ * @run driver HelloDynamicCustomUnload
+ */
+
+import java.io.File;
+
+public class HelloDynamicCustomUnload extends DynamicArchiveTestBase {
+    private static final String ARCHIVE_NAME =
+        System.getProperty("test.classes") + File.separator + "HelloDynamicCustomUnload.jsa";
+
+    public static void main(String[] args) throws Exception {
+        runTest(HelloDynamicCustomUnload::testDefaultBase);
+    }
+
+    static void testDefaultBase() throws Exception {
+        String topArchiveName = getNewArchiveName("HelloDynamicCustomUnload-top");
+        doTest(topArchiveName);
+    }
+
+    private static void doTest(String topArchiveName) throws Exception {
+        String wbJar = ClassFileInstaller.getJarPath("WhiteBox.jar");
+        String use_whitebox_jar = "-Xbootclasspath/a:" + wbJar;
+        String appJar = ClassFileInstaller.getJarPath("hello.jar");
+        String customJarPath = ClassFileInstaller.getJarPath("hello_custom.jar");
+        String mainAppClass = "HelloUnload";
+
+        dump(topArchiveName,
+            use_whitebox_jar,
+            "-XX:+UnlockDiagnosticVMOptions",
+            "-XX:+WhiteBoxAPI",
+            "-Xmn8m",
+            "-Xlog:cds,cds+dynamic=debug,class+unload=debug",
+            "-XX:ArchiveClassesAtExit=" + ARCHIVE_NAME,
+            "-cp", appJar,
+            mainAppClass, customJarPath, "true", "false")
+            .assertNormalExit(output -> {
+                output.shouldContain("Buffer-space to target-space delta")
+                      .shouldContain("Written dynamic archive 0x")
+                      .shouldNotContain("klasses.*=.*CustomLoadee")   // Fixme -- use a better way to decide if a class has been archived
+                      .shouldHaveExitValue(0);
+                });
+
+        run(topArchiveName,
+            use_whitebox_jar,
+            "-XX:+UnlockDiagnosticVMOptions",
+            "-XX:+WhiteBoxAPI",
+            "-Xlog:class+load,cds=debug,class+unload=debug",
+            "-XX:SharedArchiveFile=" + ARCHIVE_NAME,
+            "-cp", appJar,
+            mainAppClass, customJarPath, "true", "false")
+            .assertNormalExit(output -> {
+                output.shouldContain("HelloUnload source: shared objects file")
+                      .shouldMatch(".class.load. CustomLoadee source:.*hello_custom.jar")
+                      .shouldHaveExitValue(0);
+                });
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/dynamicArchive/JITInteraction.java	Thu May 23 11:07:37 2019 +0100
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2019, 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 interaction with JIT threads during vm exit.
+ * @requires vm.cds
+ * @library /test/lib /test/hotspot/jtreg/runtime/appcds /test/hotspot/jtreg/runtime/appcds/dynamicArchive/test-classes
+ * @build TestJIT
+ * @modules jdk.jartool/sun.tools.jar
+ * @build sun.hotspot.WhiteBox
+ * @run driver ClassFileInstaller -jar WhiteBox.jar sun.hotspot.WhiteBox
+ * @run driver ClassFileInstaller -jar testjit.jar TestJIT
+ * @run driver JITInteraction
+ */
+
+public class JITInteraction extends DynamicArchiveTestBase {
+
+    public static void main(String[] args) throws Exception {
+        runTest(JITInteraction::testDefaultBase);
+    }
+
+    // Test with default base archive + top archive
+    static void testDefaultBase() throws Exception {
+        String topArchiveName = getNewArchiveName("top");
+        doTest(topArchiveName);
+    }
+
+    private static void doTest(String topArchiveName) throws Exception {
+        String appJar = ClassFileInstaller.getJarPath("testjit.jar");
+        String mainClass = "TestJIT";
+
+        dump2_WB(null, topArchiveName,
+                 "-Xlog:cds",
+                 "-Xlog:cds+dynamic",
+                 "-XX:-UseOnStackReplacement",
+                 "-XX:+PrintCompilation",
+                 "-cp", appJar, mainClass)
+                .assertNormalExit(output -> {
+                    output.shouldContain("Buffer-space to target-space delta")
+                           .shouldContain("Written dynamic archive 0x");
+                });
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/dynamicArchive/MainModuleOnly.java	Thu May 23 11:07:37 2019 +0100
@@ -0,0 +1,259 @@
+/*
+ * Copyright (c) 2019, 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
+ * @requires vm.cds
+ * @library /test/lib /test/hotspot/jtreg/runtime/appcds
+ * @modules jdk.compiler
+ *          jdk.jartool/sun.tools.jar
+ *          jdk.jlink
+ * @run driver MainModuleOnly
+ * @summary Test some scenarios with a main modular jar specified in the --module-path and -cp options in the command line.
+ */
+
+import java.io.File;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.Arrays;
+
+import jdk.test.lib.process.OutputAnalyzer;
+import jdk.test.lib.Platform;
+
+public class MainModuleOnly extends DynamicArchiveTestBase {
+
+    private static final Path USER_DIR = Paths.get(System.getProperty("user.dir"));
+
+    private static final String FS = File.separator;
+    private static final String TEST_SRC = System.getProperty("test.src") +
+        FS + ".." + FS + "jigsaw" + FS + "modulepath";
+
+    private static final Path SRC_DIR = Paths.get(TEST_SRC, "src");
+    private static final Path MODS_DIR = Paths.get("mods");
+
+    // the module name of the test module
+    private static final String TEST_MODULE1 = "com.simple";
+
+    // the module main class
+    private static final String MAIN_CLASS = "com.simple.Main";
+
+    private static Path moduleDir = null;
+    private static Path moduleDir2 = null;
+    private static Path destJar = null;
+
+    public static void buildTestModule() throws Exception {
+
+        // javac -d mods/$TESTMODULE --module-path MOD_DIR src/$TESTMODULE/**
+        JarBuilder.compileModule(SRC_DIR.resolve(TEST_MODULE1),
+                                 MODS_DIR.resolve(TEST_MODULE1),
+                                 MODS_DIR.toString());
+
+
+        moduleDir = Files.createTempDirectory(USER_DIR, "mlib");
+        moduleDir2 = Files.createTempDirectory(USER_DIR, "mlib2");
+
+        Path srcJar = moduleDir.resolve(TEST_MODULE1 + ".jar");
+        destJar = moduleDir2.resolve(TEST_MODULE1 + ".jar");
+        String classes = MODS_DIR.resolve(TEST_MODULE1).toString();
+        JarBuilder.createModularJar(srcJar.toString(), classes, MAIN_CLASS);
+        Files.copy(srcJar, destJar);
+
+    }
+
+    static void testDefaultBase() throws Exception {
+        String topArchiveName = getNewArchiveName("top");
+        doTest(topArchiveName);
+    }
+
+    public static void main(String... args) throws Exception {
+        runTest(MainModuleOnly::testDefaultBase);
+    }
+
+    public static void doTest(String topArchiveName) throws Exception {
+        // compile the modules and create the modular jar files
+        buildTestModule();
+        // create an archive with both -cp and --module-path in the command line.
+        // Only the class in the modular jar in the --module-path will be archived;
+        // the class in the modular jar in the -cp won't be archived.
+        dump2(null, topArchiveName,
+              "-Xlog:cds+dynamic=debug,cds=debug",
+              "-cp", destJar.toString(),
+              "--module-path", moduleDir.toString(),
+              "-m", TEST_MODULE1)
+              .assertNormalExit(output -> {
+                      output.shouldContain("Buffer-space to target-space delta")
+                            .shouldContain("Written dynamic archive 0x");
+                  });
+
+        // run with the archive using the same command line as in dump time.
+        // The main class should be loaded from the archive.
+        run2(null, topArchiveName,
+             "-Xlog:cds+dynamic=debug,cds=debug,class+load=trace",
+             "-cp", destJar.toString(),
+             "--module-path", moduleDir.toString(),
+             "-m", TEST_MODULE1)
+            .assertNormalExit(output -> {
+                    output.shouldContain("[class,load] com.simple.Main source: shared objects file")
+                          .shouldHaveExitValue(0);
+                });
+
+        // run with the archive with the main class name inserted before the -m.
+        // The main class name will be picked up before the module name. So the
+        // main class should be loaded from the jar in the -cp.
+        run2(null, topArchiveName,
+             "-Xlog:cds+dynamic=debug,cds=debug,class+load=trace",
+             "-cp", destJar.toString(),
+             "--module-path", moduleDir.toString(),
+             MAIN_CLASS, "-m", TEST_MODULE1)
+            .assertNormalExit(out ->
+                out.shouldMatch(".class.load. com.simple.Main source:.*com.simple.jar"));
+
+        // run with the archive with exploded module. Since during dump time, we
+        // only archive classes from the modular jar in the --module-path, the
+        // main class should be loaded from the exploded module directory.
+        run2(null, topArchiveName,
+             "-Xlog:cds+dynamic=debug,cds=debug,class+load=trace",
+             "-cp", destJar.toString(),
+             "--module-path", MODS_DIR.toString(),
+             "-m", TEST_MODULE1 + "/" + MAIN_CLASS)
+            .assertNormalExit(out -> {
+                out.shouldMatch(".class.load. com.simple.Main source:.*com.simple")
+                   .shouldContain(MODS_DIR.toString());
+            });
+
+        // run with the archive with the --upgrade-module-path option.
+        // CDS will be disabled with this options and the main class will be
+        // loaded from the modular jar.
+        run2(null, topArchiveName,
+             "-Xlog:cds+dynamic=debug,cds=debug,class+load=trace",
+             "-cp", destJar.toString(),
+             "--upgrade-module-path", moduleDir.toString(),
+             "--module-path", moduleDir.toString(),
+             "-m", TEST_MODULE1)
+            .assertSilentlyDisabledCDS(out -> {
+                out.shouldHaveExitValue(0)
+                   .shouldMatch("CDS is disabled when the.*option is specified")
+                   .shouldMatch(".class.load. com.simple.Main source:.*com.simple.jar");
+            });
+        // run with the archive with the --limit-modules option.
+        // CDS will be disabled with this options and the main class will be
+        // loaded from the modular jar.
+        run2(null, topArchiveName,
+             "-Xlog:cds+dynamic=debug,cds=debug,class+load=trace",
+             "-cp", destJar.toString(),
+             "--limit-modules", "java.base," + TEST_MODULE1,
+             "--module-path", moduleDir.toString(),
+             "-m", TEST_MODULE1)
+            .assertSilentlyDisabledCDS(out -> {
+                out.shouldHaveExitValue(0)
+                   .shouldMatch("CDS is disabled when the.*option is specified")
+                   .shouldMatch(".class.load. com.simple.Main source:.*com.simple.jar");
+            });
+        // run with the archive with the --patch-module option.
+        // CDS will be disabled with this options and the main class will be
+        // loaded from the modular jar.
+        run2(null, topArchiveName,
+             "-Xlog:cds+dynamic=debug,cds=debug,class+load=trace",
+             "-cp", destJar.toString(),
+             "--patch-module", TEST_MODULE1 + "=" + MODS_DIR.toString(),
+             "--module-path", moduleDir.toString(),
+             "-m", TEST_MODULE1)
+            .assertSilentlyDisabledCDS(out -> {
+                out.shouldHaveExitValue(0)
+                   .shouldMatch("CDS is disabled when the.*option is specified")
+                   .shouldMatch(".class.load. com.simple.Main source:.*com.simple.jar");
+            });
+        // modify the timestamp of the jar file
+        (new File(destJar.toString())).setLastModified(System.currentTimeMillis() + 2000);
+        // run with the archive and the jar with modified timestamp.
+        // It should fail due to timestamp of the jar doesn't match the one
+        // used during dump time.
+        run2(null, topArchiveName,
+             "-Xlog:cds+dynamic=debug,cds=debug,class+load=trace",
+             "-cp", destJar.toString(),
+             "--module-path", moduleDir.toString(),
+             "-m", TEST_MODULE1)
+            .assertAbnormalExit(
+                "A jar file is not the one used while building the shared archive file:");
+        // create an archive with a non-empty directory in the --module-path.
+        // The dumping process will exit with an error due to non-empty directory
+        // in the --module-path.
+        dump2(null, topArchiveName,
+              "-Xlog:cds+dynamic=debug,cds=debug",
+              "-cp", destJar.toString(),
+              "--module-path", MODS_DIR.toString(),
+              "-m", TEST_MODULE1 + "/" + MAIN_CLASS)
+            .assertAbnormalExit(output -> {
+                output.shouldMatch("Error: non-empty directory.*com.simple");
+                });
+
+        // test module path with very long length
+        //
+        // This test can't be run on the windows platform due to an existing
+        // issue in ClassLoader::get_canonical_path() (JDK-8190737).
+        if (Platform.isWindows()) {
+            System.out.println("Long module path test cannot be tested on the Windows platform.");
+            return;
+        }
+        Path longDir = USER_DIR;
+        int pathLen = longDir.toString().length();
+        int PATH_LEN = 2034;
+        int MAX_DIR_LEN = 250;
+        while (pathLen < PATH_LEN) {
+            int remaining = PATH_LEN - pathLen;
+            int subPathLen = remaining > MAX_DIR_LEN ? MAX_DIR_LEN : remaining;
+            char[] chars = new char[subPathLen];
+            Arrays.fill(chars, 'x');
+            String subPath = new String(chars);
+            longDir = Paths.get(longDir.toString(), subPath);
+            pathLen = longDir.toString().length();
+        }
+        File longDirFile = new File(longDir.toString());
+        try {
+            longDirFile.mkdirs();
+        } catch (Exception e) {
+            throw e;
+        }
+        Path longDirJar = longDir.resolve(TEST_MODULE1 + ".jar");
+        // IOException results from the Files.copy() call on platform
+        // such as MacOS X. Test can't be proceeded further with the
+        // exception.
+        try {
+            Files.copy(destJar, longDirJar);
+        } catch (java.io.IOException ioe) {
+            System.out.println("Caught IOException from Files.copy(). Cannot continue.");
+            return;
+        }
+        dump2(null, topArchiveName,
+              "-Xlog:cds+dynamic=debug,cds=debug",
+              "-cp", destJar.toString(),
+              "-Xlog:exceptions=trace",
+              "--module-path", longDirJar.toString(),
+              "-m", TEST_MODULE1)
+            .ifAbnormalExit(output -> {
+                output.shouldMatch("os::stat error.*CDS dump aborted");
+                });
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/dynamicArchive/MethodSorting.java	Thu May 23 11:07:37 2019 +0100
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2019, 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 HelloA and HelloB are copied into the dynamic archive, the Symbols
+ *          for their method's names will have a different sorting order. This requires
+ *          that the dumped InstanceKlass to re-sort their "methods" array and re-layout the vtables/itables.
+ *          A regression test for an earlier bug in DynamicArchiveBuilder::relocate_buffer_to_target().
+ * @requires vm.cds
+ * @library /test/lib /test/hotspot/jtreg/runtime/appcds /test/hotspot/jtreg/runtime/appcds/test-classes
+ *          /test/hotspot/jtreg/runtime/appcds/dynamicArchive/test-classes
+ * @build MethodSortingApp
+ * @run driver ClassFileInstaller -jar method_sorting.jar
+ *             MethodSortingApp
+ *             MethodSortingApp$HelloA
+ *             MethodSortingApp$HelloA1
+ *             MethodSortingApp$HelloB
+ *             MethodSortingApp$HelloB1
+ *             MethodSortingApp$InterfaceA
+ *             MethodSortingApp$InterfaceB
+ *             MethodSortingApp$ImplementorA
+ *             MethodSortingApp$ImplementorA1
+ *             MethodSortingApp$ImplementorB
+ *             MethodSortingApp$ImplementorB1
+ * @run driver MethodSorting
+ */
+
+public class MethodSorting extends DynamicArchiveTestBase {
+    public static void main(String[] args) throws Exception {
+        runTest(MethodSorting::test);
+    }
+
+    static void test() throws Exception {
+        String topArchiveName = getNewArchiveName();
+        String appJar = ClassFileInstaller.getJarPath("method_sorting.jar");
+        String mainClass = "MethodSortingApp";
+
+        dumpAndRun(topArchiveName, "-Xlog:cds+dynamic=debug", "-cp", appJar, mainClass);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/dynamicArchive/MissingArchive.java	Thu May 23 11:07:37 2019 +0100
@@ -0,0 +1,101 @@
+/*
+ * Copyright (c) 2019, 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.File;
+
+/*
+ * @test
+ * @summary error handling when either (or both) of the base/top archives are missing.
+ * @requires vm.cds
+ * @library /test/lib /test/hotspot/jtreg/runtime/appcds /test/hotspot/jtreg/runtime/appcds/test-classes
+ * @build GenericTestApp sun.hotspot.WhiteBox
+ * @run driver ClassFileInstaller -jar WhiteBox.jar sun.hotspot.WhiteBox
+ * @run driver ClassFileInstaller -jar GenericTestApp.jar GenericTestApp
+ * @run driver MissingArchive
+ */
+
+public class MissingArchive extends DynamicArchiveTestBase {
+    private static final String TOP  = "top";
+    private static final String BASE = "base";
+    private static final String BOTH = "base/top";
+    private static final String NONE = "none";
+
+    public static void main(String[] args) throws Exception {
+        runTest(MissingArchive::test, TOP);
+        runTest(MissingArchive::test, BASE);
+        runTest(MissingArchive::test, BOTH);
+        runTest(MissingArchive::test, NONE);
+    }
+
+    static void delete(String fileName) {
+        File f = new File(fileName);
+        f.delete();
+    }
+
+    static void test(String args[]) throws Exception {
+        String topArchiveName = getNewArchiveName("top");
+        String baseArchiveName = getNewArchiveName("base");
+        dumpBaseArchive(baseArchiveName);
+
+        String appJar = ClassFileInstaller.getJarPath("GenericTestApp.jar");
+        String mainClass = "GenericTestApp";
+        dump2_WB(baseArchiveName, topArchiveName,
+                 "-Xlog:cds",
+                 "-Xlog:cds+dynamic=debug",
+                 "-cp", appJar, mainClass)
+            .assertNormalExit(output -> {
+                    output.shouldContain("Buffer-space to target-space delta")
+                           .shouldContain("Written dynamic archive 0x");
+                });
+
+        // Use -Xshare:auto so top archive can fail after base archive has succeeded,
+        // but the app will continue to run.
+        String[] cmdline = TestCommon.concat(
+            "-Xlog:cds*",
+            "-Xshare:auto",
+            "-cp", appJar, mainClass);
+
+
+        String mode = args[0];
+
+        if (mode.contains(BASE)) {
+            delete(baseArchiveName);
+            cmdline = TestCommon.concat(cmdline, "assertNotShared:java.lang.Object");
+        } else {
+            cmdline = TestCommon.concat(cmdline, "assertShared:java.lang.Object");
+        }
+
+        if (mode.contains(TOP)) {
+            delete(topArchiveName);
+        }
+
+        if (mode.equals(NONE)) {
+            cmdline = TestCommon.concat(cmdline, "assertShared:GenericTestApp");
+        } else {
+            cmdline = TestCommon.concat(cmdline, "assertNotShared:GenericTestApp");
+        }
+
+        run2_WB(baseArchiveName, topArchiveName, cmdline).assertNormalExit();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/dynamicArchive/NoClassToArchive.java	Thu May 23 11:07:37 2019 +0100
@@ -0,0 +1,111 @@
+/*
+ * Copyright (c) 2019, 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 A few edge cases where there's no class to be included in the dynamic archive.
+ * @requires vm.cds
+ * @library /test/lib /test/hotspot/jtreg/runtime/appcds /test/hotspot/jtreg/runtime/appcds/dynamicArchive/test-classes
+ * @build StrConcatApp
+ * @run driver ClassFileInstaller -jar strConcatApp.jar StrConcatApp
+ * @run driver NoClassToArchive
+ */
+
+import java.io.File;
+import jdk.test.lib.process.OutputAnalyzer;
+import jdk.test.lib.process.ProcessTools;
+
+public class NoClassToArchive extends DynamicArchiveTestBase {
+    static final String warningMessage =
+        "There is no class to be included in the dynamic archive";
+    static final String classList = System.getProperty("test.classes") +
+        File.separator + "NoClassToArchive.list";
+    static final String appClass = "StrConcatApp";
+
+    public static void main(String[] args) throws Exception {
+        runTest(NoClassToArchive::testDefaultBase);
+        runTest(NoClassToArchive::testCustomBase);
+    }
+
+    // (1) Test with default base archive + top archive
+    static void testDefaultBase() throws Exception {
+        String topArchiveName = getNewArchiveName("top");
+        doTest(null, topArchiveName);
+    }
+
+    // (2) Test with custom base archive + top archive
+    static void testCustomBase() throws Exception {
+        String topArchiveName = getNewArchiveName("top2");
+        String baseArchiveName = getNewArchiveName("base");
+        doTestCustomBase(baseArchiveName, topArchiveName);
+    }
+
+    private static void doTest(String baseArchiveName, String topArchiveName) throws Exception {
+        dump2(baseArchiveName, topArchiveName,
+             "-Xlog:cds",
+             "-Xlog:cds+dynamic=debug",
+             "-Xlog:class+load=trace",
+             "-version")
+            .assertNormalExit(output -> {
+                    if (output.getStdout().contains("jrt:/")) {
+                        System.out.println("test skipped: this platform uses non-archived classes when running -version");
+                    } else {
+                        output.shouldContain(warningMessage);
+                    }
+                });
+
+        dump2(baseArchiveName, topArchiveName,
+             "-Xlog:cds",
+             "-Xlog:cds+dynamic=debug",
+             "-Xlog:class+load=trace",
+             "-help")
+            .assertNormalExit(output -> {
+                    // some classes will be loaded from the java.base module
+                    output.shouldContain("java.text.MessageFormat source: jrt:/java.base");
+                });
+    }
+
+    private static void doTestCustomBase(String baseArchiveName, String topArchiveName) throws Exception {
+        String appJar = ClassFileInstaller.getJarPath("strConcatApp.jar");
+        // dump class list by running the StrConcatApp
+        ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
+            true,
+            "-XX:DumpLoadedClassList=" + classList,
+            "-cp",
+            appJar,
+            appClass);
+        OutputAnalyzer output = TestCommon.executeAndLog(pb, "dumpClassList");
+        TestCommon.checkExecReturn(output, 0, true, "length = 0");
+
+        // create a custom base archive based on the class list
+        dumpBaseArchive(baseArchiveName, "-XX:SharedClassListFile=" + classList);
+
+        // create a dynamic archive with the custom base archive
+        // no class should be included in the dynamic archive
+        dump2(baseArchiveName, topArchiveName, "-version")
+            .assertNormalExit(out -> {
+                    out.shouldMatch(warningMessage);
+                });
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/dynamicArchive/SharedArchiveFileOption.java	Thu May 23 11:07:37 2019 +0100
@@ -0,0 +1,150 @@
+/*
+ * Copyright (c) 2019, 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 Some negative tests for the SharedArchiveFile option
+ * @requires vm.cds
+ * @library /test/lib /test/hotspot/jtreg/runtime/appcds /test/hotspot/jtreg/runtime/appcds/test-classes
+ * @build Hello
+ * @run driver ClassFileInstaller -jar hello.jar Hello
+ * @run driver SharedArchiveFileOption
+ */
+
+import java.io.File;
+
+public class SharedArchiveFileOption extends DynamicArchiveTestBase {
+    public static void main(String[] args) throws Exception {
+        runTest(SharedArchiveFileOption::testCustomBase);
+    }
+
+    static String baseArchiveName2;
+    static void testCustomBase() throws Exception {
+        String topArchiveName = getNewArchiveName("top");
+        String baseArchiveName = getNewArchiveName("base");
+        baseArchiveName2 = getNewArchiveName("base2");
+        dumpBaseArchive(baseArchiveName);
+        dumpBaseArchive(baseArchiveName2);
+        doTest(baseArchiveName, topArchiveName);
+    }
+
+    private static void doTest(String baseArchiveName, String topArchiveName) throws Exception {
+        String appJar = ClassFileInstaller.getJarPath("hello.jar");
+        String mainClass = "Hello";
+        String dummyArchiveName = getNewArchiveName("dummy");
+
+        // -Xshare:dump specified with -XX:ArchiveClassesAtExit
+        dump2(dummyArchiveName, dummyArchiveName,
+            "-Xlog:cds",
+            "-Xlog:cds+dynamic=debug",
+            "-Xshare:dump",
+            "-cp", appJar, mainClass)
+            .assertAbnormalExit(output -> {
+                    output.shouldContain("-XX:ArchiveClassesAtExit cannot be used with -Xshare:dump");
+                });
+
+        // more than 1 archive file specified in -XX:SharedArchiveFile during
+        // dynamic dumpgin
+        String dummyArchives = dummyArchiveName + File.pathSeparator + dummyArchiveName;
+        dump2(dummyArchives, dummyArchiveName,
+            "-Xlog:cds",
+            "-Xlog:cds+dynamic=debug",
+            "-cp", appJar, mainClass)
+            .assertAbnormalExit(output -> {
+                    output.shouldContain("Cannot have more than 1 archive file specified in -XX:SharedArchiveFile during CDS dumping");
+                });
+
+        // normal dynamic archive dumping
+        dump2(baseArchiveName, topArchiveName,
+            "-Xlog:cds",
+            "-Xlog:cds+dynamic=debug",
+            "-cp", appJar, mainClass)
+            .assertNormalExit(output -> {
+                    output.shouldContain("Buffer-space to target-space delta")
+                           .shouldContain("Written dynamic archive 0x");
+                });
+
+        // same archive file specified for -XX:SharedArchiveFile and -XX:ArchiveClassesAtExit
+        dump2(baseArchiveName, baseArchiveName,
+            "-Xlog:cds",
+            "-Xlog:cds+dynamic=debug",
+            "-cp", appJar, mainClass)
+            .assertAbnormalExit(output -> {
+                    output.shouldContain("Cannot have the same archive file specified for -XX:SharedArchiveFile and -XX:ArchiveClassesAtExit: "
+                        + baseArchiveName);
+                });
+
+
+        // a top archive specified in the base archive position
+        run2(topArchiveName, baseArchiveName,
+            "-Xlog:class+load",
+            "-Xlog:cds+dynamic=debug,cds=debug",
+            "-cp", appJar, mainClass)
+            .assertAbnormalExit(output -> {
+                    output.shouldMatch("Not a base shared archive:.*top.*.jsa");
+                });
+
+        // a base archive specified in the top archive position
+        run2(baseArchiveName, baseArchiveName2,
+            "-Xlog:class+load",
+            "-Xlog:cds+dynamic=debug,cds=debug",
+            "-cp", appJar, mainClass)
+            .assertAbnormalExit(output -> {
+                    output.shouldMatch("Not a top shared archive:.*base.*.jsa");
+                });
+
+        // more than 2 archives specified in the -XX:ShareArchiveFile option
+        String baseArchives = baseArchiveName + File.pathSeparator + baseArchiveName2;
+        run2(baseArchives, topArchiveName,
+            "-Xlog:class+load",
+            "-Xlog:cds+dynamic=debug,cds=debug",
+            "-cp", appJar, mainClass)
+            .assertAbnormalExit(output -> {
+                    output.shouldContain(
+                        "Cannot have more than 2 archive files specified in the -XX:SharedArchiveFile option");
+                });
+
+        // base archive not specified
+        final String topArchive = File.pathSeparator + topArchiveName;
+        run2(topArchive, null,
+            "-Xlog:class+load",
+            "-Xlog:cds+dynamic=debug,cds=debug",
+            "-cp", appJar, mainClass)
+            .assertAbnormalExit(output -> {
+                    output.shouldContain(
+                        "Base archive was not specified: " + topArchive);
+                });
+
+        // top archive not specified
+        final String baseArchive = baseArchiveName + File.pathSeparator;
+        run2(baseArchive, null,
+            "-Xlog:class+load",
+            "-Xlog:cds+dynamic=debug,cds=debug",
+            "-cp", appJar, mainClass)
+            .assertAbnormalExit(output -> {
+                    output.shouldContain(
+                        "Top archive was not specified: " + baseArchive);
+                });
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/dynamicArchive/UnsupportedBaseArchive.java	Thu May 23 11:07:37 2019 +0100
@@ -0,0 +1,125 @@
+/*
+ * Copyright (c) 2019, 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.File;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+
+/*
+ * @test
+ * @summary unsupported base archive tests
+ * @requires vm.cds
+ * @library /test/lib /test/hotspot/jtreg/runtime/appcds /test/hotspot/jtreg/runtime/appcds/test-classes
+ * @modules jdk.jartool/sun.tools.jar
+ * @compile ../test-classes/Hello.java
+ * @build sun.hotspot.WhiteBox
+ * @run driver ClassFileInstaller -jar WhiteBox.jar sun.hotspot.WhiteBox
+ * @run driver UnsupportedBaseArchive
+ */
+
+public class UnsupportedBaseArchive extends DynamicArchiveTestBase {
+    private static final Path USER_DIR = Paths.get(System.getProperty("user.dir"));
+
+    private static final String FS = File.separator;
+    private static final String TEST_SRC = System.getProperty("test.src") +
+        FS + ".." + FS + "jigsaw" + FS + "modulepath";
+
+    private static final Path SRC_DIR = Paths.get(TEST_SRC, "src");
+    private static final Path MODS_DIR = Paths.get("mods");
+
+    // the module name of the test module
+    private static final String TEST_MODULE = "com.simple";
+
+    // the module main class
+    private static final String MAIN_CLASS = "com.simple.Main";
+
+    private static Path moduleDir = null;
+    private static Path srcJar = null;
+
+    private static final String warningBCP =
+        "Dynamic archiving is disabled because base layer archive has appended boot classpath";
+
+    private static final String warningModulePath =
+        "Dynamic archiving is disabled because base layer archive has module path";
+
+    public static void buildTestModule() throws Exception {
+
+        // javac -d mods/$TESTMODULE --module-path MOD_DIR src/$TESTMODULE/**
+        JarBuilder.compileModule(SRC_DIR.resolve(TEST_MODULE),
+                                 MODS_DIR.resolve(TEST_MODULE),
+                                 MODS_DIR.toString());
+
+
+        moduleDir = Files.createTempDirectory(USER_DIR, "mlib");
+        srcJar = moduleDir.resolve(TEST_MODULE + ".jar");
+        String classes = MODS_DIR.resolve(TEST_MODULE).toString();
+        JarBuilder.createModularJar(srcJar.toString(), classes, MAIN_CLASS);
+    }
+
+    public static void main(String[] args) throws Exception {
+        runTest(UnsupportedBaseArchive::test);
+    }
+
+    static void test(String args[]) throws Exception {
+        String topArchiveName = getNewArchiveName("top");
+        String baseArchiveName = getNewArchiveName("base");
+
+        // create a base archive with -Xbootclasspath/a:whitebox.jar
+        dumpBaseArchive_WB(baseArchiveName);
+
+        String appJar    = JarBuilder.getOrCreateHelloJar();
+        String mainClass = "Hello";
+
+        // dumping of dynamic archive should be disabled with a warning message
+        // if the base archive contains -Xbootclasspath/a entries.
+        dump2_WB(baseArchiveName, topArchiveName,
+             "-Xlog:cds*",
+             "-Xlog:cds+dynamic=debug",
+             "-Xlog:class+path=info",
+             "-cp", appJar, mainClass)
+            .assertNormalExit(warningBCP);
+
+        // create a base archive with the --module-path option
+        buildTestModule();
+        baseArchiveName = getNewArchiveName("base-with-module");
+        dumpBaseArchive(baseArchiveName,
+                        "-cp", srcJar.toString(),
+                        "--module-path", moduleDir.toString(),
+                        "-m", TEST_MODULE);
+
+        // dumping of dynamic archive should be disabled with a warning message
+        // if the base archive contains --module-path entries.
+        topArchiveName = getNewArchiveName("top-with-module");
+        dump2(baseArchiveName, topArchiveName,
+              "-Xlog:cds*",
+              "-Xlog:cds+dynamic=debug",
+              "-Xlog:class+path=info",
+              "-cp", srcJar.toString(),
+              "--module-path", moduleDir.toString(),
+              "-m", TEST_MODULE)
+            .assertNormalExit(warningModulePath);
+
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/dynamicArchive/UnusedCPDuringDump.java	Thu May 23 11:07:37 2019 +0100
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2019, 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 non-empty dir in -cp should be fine during dump time if only classes
+ *          from the system modules are being loaded even though some are
+ *          defined to the PlatformClassLoader and AppClassLoader.
+ * @requires vm.cds
+ * @library /test/lib /test/hotspot/jtreg/runtime/appcds
+ * @modules jdk.jartool/sun.tools.jar
+ * @compile ../test-classes/Hello.java
+ * @run main/othervm -Dtest.cds.copy.child.stdout=false UnusedCPDuringDump
+ */
+
+import java.io.File;
+
+public class UnusedCPDuringDump extends DynamicArchiveTestBase {
+
+    public static void main(String[] args) throws Exception {
+        runTest(UnusedCPDuringDump::testDefaultBase);
+    }
+
+    static void testDefaultBase() throws Exception {
+        String topArchiveName = getNewArchiveName("top");
+        doTest(topArchiveName);
+    }
+
+    private static void doTest(String topArchiveName) throws Exception {
+        File dir = new File(System.getProperty("user.dir"));
+        File emptydir = new File(dir, "emptydir");
+        emptydir.mkdir();
+        String appJar = JarBuilder.getOrCreateHelloJar();
+        String bootClassPath = "-Xbootclasspath/a:" + appJar;
+
+        // Dumping with a non-empty directory in the -cp.
+        // It should be fine because the app class won't be loaded from the
+        // -cp, it is being loaded from the bootclasspath.
+        dump(topArchiveName,
+             "-Xlog:cds",
+             "-Xlog:cds+dynamic=debug",
+             bootClassPath,
+             "-cp", dir.getPath(),
+             "Hello")
+            .assertNormalExit(output -> {
+                 output.shouldContain("Buffer-space to target-space delta")
+                        .shouldContain("Written dynamic archive 0x");
+                });
+
+        // Running with -cp different from dumping. It should be fine because
+        // the runtime classpath won't be checked against unused classpath
+        // during dump time.
+        run(topArchiveName,
+            "-Xlog:class+load",
+            "-Xlog:cds+dynamic=debug,cds=debug",
+             bootClassPath,
+            "-cp", appJar, "Hello")
+            .assertNormalExit(output -> {
+                    output.shouldContain("Hello World")
+                          .shouldHaveExitValue(0);
+                });
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/dynamicArchive/WrongTopClasspath.java	Thu May 23 11:07:37 2019 +0100
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2019, 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.File;
+
+/*
+ * @test
+ * @summary correct classpath for bottom archive, but bad classpath for top archive
+ * @requires vm.cds
+ * @library /test/lib /test/hotspot/jtreg/runtime/appcds /test/hotspot/jtreg/runtime/appcds/test-classes
+ * @build GenericTestApp sun.hotspot.WhiteBox
+ * @run driver ClassFileInstaller -jar WhiteBox.jar sun.hotspot.WhiteBox
+ * @run driver ClassFileInstaller -jar GenericTestApp.jar GenericTestApp
+ * @run driver ClassFileInstaller -jar WrongJar.jar GenericTestApp
+ * @run driver WrongTopClasspath
+ */
+
+public class WrongTopClasspath extends DynamicArchiveTestBase {
+
+    public static void main(String[] args) throws Exception {
+        runTest(WrongTopClasspath::test);
+    }
+
+    static void test(String args[]) throws Exception {
+        String topArchiveName = getNewArchiveName("top");
+        String baseArchiveName = getNewArchiveName("base");
+        dumpBaseArchive(baseArchiveName);
+
+        String appJar    = ClassFileInstaller.getJarPath("GenericTestApp.jar");
+        String wrongJar  = ClassFileInstaller.getJarPath("WrongJar.jar");
+        String mainClass = "GenericTestApp";
+
+        // Dump the top archive using "-cp GenericTestApp.jar" ...
+        dump2_WB(baseArchiveName, topArchiveName,
+                 "-Xlog:cds*",
+                 "-Xlog:cds+dynamic=debug",
+                 "-cp", appJar, mainClass)
+            .assertNormalExit();
+
+        // ... but try to load the top archive using "-cp WrongJar.jar".
+        // Use -Xshare:auto so top archive can fail after base archive has succeeded,
+        // but the app will continue to run.
+        run2_WB(baseArchiveName, topArchiveName,
+                "-Xlog:cds*",
+                "-Xlog:cds+dynamic=debug",
+                "-Xlog:class+path=info",
+                "-Xshare:auto",
+                "-cp", wrongJar, mainClass,
+                "assertShared:java.lang.Object",  // base archive still useable
+                "assertNotShared:GenericTestApp") // but top archive is not useable
+          .assertNormalExit("The top archive failed to load");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/dynamicArchive/test-classes/ArrayKlassesApp.java	Thu May 23 11:07:37 2019 +0100
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2019, 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 ArrayKlassesApp {
+    public static void main(String args[]) {
+        ArrayKlassesApp[][] array = new ArrayKlassesApp[1][2];
+        for (int i=0; i<1; i++) {
+            for (int j=0; j<2; j++) {
+                array[i][j] = new ArrayKlassesApp();
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/dynamicArchive/test-classes/ExcludedClassesApp.java	Thu May 23 11:07:37 2019 +0100
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2019, 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 ExcludedClassesApp {
+    interface NotLinkedInterface {}
+    static class NotLinkedSuper {
+
+    }
+
+    static class NotLinkedChild extends NotLinkedSuper implements NotLinkedInterface {
+
+    }
+
+    public static NotLinkedSuper notUsedMethod() {
+        return new NotLinkedChild();
+    }
+
+    public static void main(String args[]) {
+
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/dynamicArchive/test-classes/LoadClasses.java	Thu May 23 11:07:37 2019 +0100
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2019, 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.File;
+import java.util.List;
+import java.util.Scanner;
+import sun.hotspot.WhiteBox;
+
+public class LoadClasses {
+
+    public static void main (String[] args) throws Throwable {
+        String classList = args[0];
+        Scanner sc = new Scanner(new File(classList));
+        WhiteBox wb = WhiteBox.getWhiteBox();
+        int count = 0;
+        while (sc.hasNextLine()) {
+            String cn = sc.nextLine().replace('/', '.');
+            try {
+                Class<?> cls = Class.forName(cn, false, LoadClasses.class.getClassLoader());
+                wb.linkClass(cls);
+                count++;
+            } catch (Throwable ex) {
+                System.out.println("Loading failed: " + cn);
+                System.out.println(ex.toString());
+            }
+        }
+        System.out.println("Loaded classes = " + count);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/dynamicArchive/test-classes/MethodSortingApp.java	Thu May 23 11:07:37 2019 +0100
@@ -0,0 +1,177 @@
+/*
+ * Copyright (c) 2019, 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.util.concurrent.BlockingQueue;
+import java.util.concurrent.SynchronousQueue;
+
+public class MethodSortingApp {
+    static class HelloA {
+        String aaaa() { return "aaaa"; }
+        String bbbb() { return "bbbb"; }
+        String dddd() { return "dddd"; }
+        String eeee() { return "eeee"; }
+        String gggg() { return "gggg"; }
+    }
+
+    static class HelloA1 extends HelloA {
+        String aaaa() { return "aaa-"; }
+        String dddd() { return "ddd-"; }
+        String gggg() { return "ggg-"; }
+    }
+
+    static class HelloB {
+        String aaaa() { return "aaaa"; }
+        String cccc() { return "cccc"; }
+        String dddd() { return "dddd"; }
+        String ffff() { return "ffff"; }
+        String gggg() { return "gggg"; }
+    }
+
+    static class HelloB1 extends HelloB {
+        String aaaa() { return "aaa-"; }
+        String dddd() { return "ddd-"; }
+        String gggg() { return "ggg-"; }
+    }
+
+    // Default methods in interfaces must be sorted
+    static interface InterfaceA {
+        default public String aaa() { return "aaa";}
+        default public String bbb() { return "bbb";}
+        default public String ddd() { return "ddd";}
+        default public String eee() { return "eee";}
+        default public String ggg() { return "ggg";}
+    }
+
+    static class ImplementorA implements InterfaceA {
+        public String aaa() { return "aa-";}
+    }
+
+    static class ImplementorA1 extends ImplementorA {
+        public String bbb() { return "bb-";}
+    }
+
+    static interface InterfaceB {
+        default public String aaa() { return "aaa"; }
+        default public String ccc() { return "ccc"; }
+        default public String ddd() { return "ddd"; }
+        default public String fff() { return "fff"; }
+        default public String ggg() { return "ggg"; }
+    }
+
+    static class ImplementorB implements InterfaceB {
+        public String ggg() { return "gg-";}
+    }
+
+    static class ImplementorB1 extends ImplementorB {
+        public String fff() { return "ff-";}
+    }
+
+
+    public static void main(String args[]) {
+        testSimpleMethods();
+        testDefaultMethods();
+        testMixedInterfaces();
+    }
+
+    static void testSimpleMethods() {
+        // When HelloA and HelloB are copied into the dynamic archive, the Symbols
+        // for their method's names will have a different sorting order. This requires
+        // that the dumped InstanceKlass to re-sort their "methods" array and re-layout
+        // the vtables/itables.
+        HelloA1 a1 = new HelloA1();
+        HelloA a = new HelloA();
+        assertEqual(a.aaaa(), "aaaa");
+        assertEqual(a.bbbb(), "bbbb");
+        assertEqual(a.dddd(), "dddd");
+        assertEqual(a.eeee(), "eeee");
+        assertEqual(a.gggg(), "gggg");
+
+        assertEqual(a1.aaaa(), "aaa-");
+        assertEqual(a1.bbbb(), "bbbb");
+        assertEqual(a1.dddd(), "ddd-");
+        assertEqual(a1.eeee(), "eeee");
+        assertEqual(a1.gggg(), "ggg-");
+
+        HelloB b = new HelloB();
+        assertEqual(b.aaaa(), "aaaa");
+        assertEqual(b.cccc(), "cccc");
+        assertEqual(b.dddd(), "dddd");
+        assertEqual(b.ffff(), "ffff");
+        assertEqual(b.gggg(), "gggg");
+
+        HelloB b1 = new HelloB1();
+        assertEqual(b1.aaaa(), "aaa-");
+        assertEqual(b1.cccc(), "cccc");
+        assertEqual(b1.dddd(), "ddd-");
+        assertEqual(b1.ffff(), "ffff");
+        assertEqual(b1.gggg(), "ggg-");
+    }
+
+    static void testDefaultMethods() {
+        InterfaceA a1 = new ImplementorA1();
+        InterfaceA a = new ImplementorA();
+
+        assertEqual(a.aaa(), "aa-");
+        assertEqual(a.bbb(), "bbb");
+        assertEqual(a.ddd(), "ddd");
+        assertEqual(a.eee(), "eee");
+        assertEqual(a.ggg(), "ggg");
+
+        assertEqual(a1.aaa(), "aa-");
+        assertEqual(a1.bbb(), "bb-");
+        assertEqual(a1.ddd(), "ddd");
+        assertEqual(a1.eee(), "eee");
+        assertEqual(a1.ggg(), "ggg");
+
+        InterfaceB b = new ImplementorB();
+        InterfaceB b1 = new ImplementorB1();
+
+        assertEqual(b.aaa(), "aaa");
+        assertEqual(b.ccc(), "ccc");
+        assertEqual(b.ddd(), "ddd");
+        assertEqual(b.fff(), "fff");
+        assertEqual(b.ggg(), "gg-");
+
+        assertEqual(b1.aaa(), "aaa");
+        assertEqual(b1.ccc(), "ccc");
+        assertEqual(b1.ddd(), "ddd");
+        assertEqual(b1.fff(), "ff-");
+        assertEqual(b1.ggg(), "gg-");
+    }
+
+    // This is a regression test for an earlier bug in
+    // DynamicArchiveBuilder::relocate_buffer_to_target()
+    static void testMixedInterfaces() {
+        Object xx = new SynchronousQueue();
+        BlockingQueue yy = (BlockingQueue)xx;
+    }
+
+    static private void assertEqual(String a, String b) {
+        if (!a.equals(b)) {
+            throw new RuntimeException(a + " is not equal to " + b);
+        } else {
+            System.out.println("Expected: " + a + ", got: " + b);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/dynamicArchive/test-classes/MissingDependent.java	Thu May 23 11:07:37 2019 +0100
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2019, 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 MissingDependent {
+    public static void main(String args[]) throws Exception {
+        try {
+            Object obj = new StrConcatApp();
+        } catch (Throwable e) {
+            String cause = e.getCause().toString();
+            if (cause.equals("java.lang.ClassNotFoundException: StrConcatApp")) {
+                e.printStackTrace();
+            } else {
+                throw e;
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/dynamicArchive/test-classes/StrConcatApp.java	Thu May 23 11:07:37 2019 +0100
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2019, 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 StrConcatApp {
+  public static void main(String args[]) {
+    System.out.println("length = " + args.length);
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/dynamicArchive/test-classes/TestJIT.java	Thu May 23 11:07:37 2019 +0100
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2019, 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;
+
+import java.lang.reflect.Method;
+import java.util.HashMap;
+
+public class TestJIT {
+
+    private static final WhiteBox WHITE_BOX = WhiteBox.getWhiteBox();
+
+    static void doSomething() {
+        HashMap<String,String> map = new HashMap<>();
+        for (int i=0; i<400; i++) {
+            // Call these methods so that the class/field/method references used
+            // by these methods are resolved. This allows C2 to compile more code.
+            String x = "Hello" + i;
+            map.put(x, x);
+            map.get(x);
+        }
+    }
+
+    static public void main(String[] args) throws NoSuchMethodException {
+        Method put_method = HashMap.class.getDeclaredMethod("put", Object.class, Object.class);
+        Method get_method = HashMap.class.getDeclaredMethod("get", Object.class);
+        Method test_method = TestJIT.class.getDeclaredMethod("doSomething");
+
+        doSomething();
+
+        // 4 == CompilerWhiteBoxTest.COMP_LEVEL_FULL_OPTIMIZATION => C2
+        WHITE_BOX.enqueueMethodForCompilation(get_method, 4);
+        WHITE_BOX.enqueueMethodForCompilation(put_method, 4);
+        WHITE_BOX.enqueueMethodForCompilation(test_method, 4);
+
+        // Try to start dynamic dumping while the above compilations are still in progesss
+        System.exit(0);
+    }
+}
--- a/test/hotspot/jtreg/runtime/appcds/jigsaw/PatchModule/MismatchedPatchModule.java	Fri May 17 13:21:44 2019 +0100
+++ b/test/hotspot/jtreg/runtime/appcds/jigsaw/PatchModule/MismatchedPatchModule.java	Thu May 23 11:07:37 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2019, 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
@@ -74,11 +74,12 @@
 
         // Case 2: --patch-module specified for run time but not for dump time
         System.out.println("Case 2: --patch-module specified for run time but not for dump time");
+        String appJar = JarBuilder.build("PatchMain-app", "PatchMain");
         output =
-            TestCommon.dump(null,
+            TestCommon.dump(appJar,
                 TestCommon.list("javax/naming/spi/NamingManager"),
                 "PatchMain", "javax.naming.spi.NamingManager");
-        TestCommon.checkDump(output, "Loading classes to share");
+        TestCommon.checkDump(output);
 
         // javax.naming.spi.NamingManager is patched at runtime
         TestCommon.run(
--- a/test/hotspot/jtreg/runtime/appcds/jigsaw/PatchModule/PatchJavaBase.java	Fri May 17 13:21:44 2019 +0100
+++ b/test/hotspot/jtreg/runtime/appcds/jigsaw/PatchModule/PatchJavaBase.java	Thu May 23 11:07:37 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2019, 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
@@ -58,18 +58,25 @@
         moduleJar = TestCommon.getTestJar("javabase.jar");
 
         System.out.println("Test dumping with --patch-module");
+        String runError = "Unable to use shared archive: CDS is disabled when java.base module is patched";
+        String dumpingError = "Cannot use the following option when dumping the shared archive: --patch-module";
+        String errMsg;
+        if (TestCommon.isDynamicArchive()) {
+            errMsg = runError;
+        } else {
+            errMsg = dumpingError;
+        }
         OutputAnalyzer output =
             TestCommon.dump(null, null,
                 "--patch-module=java.base=" + moduleJar,
                 "PatchMain", "java.lang.NewClass");
         output.shouldHaveExitValue(1)
-              .shouldContain("Cannot use the following option when dumping the shared archive: --patch-module");
+              .shouldContain(errMsg);
 
         TestCommon.run(
             "-XX:+UnlockDiagnosticVMOptions",
             "--patch-module=java.base=" + moduleJar,
             "PatchMain", "java.lang.NewClass")
-          .assertAbnormalExit("Unable to use shared archive",
-                              "CDS is disabled when java.base module is patched");
+          .assertAbnormalExit(runError);
     }
 }
--- a/test/hotspot/jtreg/runtime/appcds/jigsaw/PatchModule/PatchMain.java	Fri May 17 13:21:44 2019 +0100
+++ b/test/hotspot/jtreg/runtime/appcds/jigsaw/PatchModule/PatchMain.java	Thu May 23 11:07:37 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2019, 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
@@ -27,6 +27,9 @@
 public class PatchMain {
     public static void main(String[] args) throws Exception {
         for (int i = 0; i < args.length; i++) {
+            if (args[i].equals("cdsutils.DynamicDumpHelper")) {
+                break;
+            }
             Class.forName(args[i]);
         }
     }
--- a/test/hotspot/jtreg/runtime/appcds/jigsaw/modulepath/AddModules.java	Fri May 17 13:21:44 2019 +0100
+++ b/test/hotspot/jtreg/runtime/appcds/jigsaw/modulepath/AddModules.java	Thu May 23 11:07:37 2019 +0100
@@ -29,6 +29,7 @@
  * @modules jdk.compiler
  *          jdk.jartool/sun.tools.jar
  *          jdk.jlink
+ * @compile ../../test-classes/Hello.java
  * @run driver AddModules
  * @summary sanity test the --add-modules option
  */
@@ -63,6 +64,7 @@
     private static Path subJar = null;
     private static Path mainJar1 = null;
     private static Path mainJar2 = null;
+    private static String appJar;
 
     public static void buildTestModule() throws Exception {
 
@@ -96,18 +98,19 @@
     }
 
     public static void main(String... args) throws Exception {
+        appJar = JarBuilder.getOrCreateHelloJar();
         // compile the modules and create the modular jar files
         buildTestModule();
         String appClasses[] = {MAIN_CLASS1, MAIN_CLASS2, APP_CLASS};
         // create an archive with the classes in the modules built in the
         // previous step
         OutputAnalyzer output = TestCommon.createArchive(
-                                        null, appClasses,
+                                        appJar, appClasses,
                                         "--module-path", moduleDir.toString(),
                                         "--add-modules",
                                         MAIN_MODULE1 + "," + MAIN_MODULE2);
         TestCommon.checkDump(output);
-        String prefix[] = {"-Djava.class.path=", "-Xlog:class+load=trace"};
+        String prefix[] = {"-Djava.class.path=" + appJar, "-Xlog:class+load=trace"};
 
         // run the com.greetings module with the archive with the --module-path
         // the same as the one during dump time.
--- a/test/hotspot/jtreg/runtime/appcds/jigsaw/modulepath/JvmtiAddPath.java	Fri May 17 13:21:44 2019 +0100
+++ b/test/hotspot/jtreg/runtime/appcds/jigsaw/modulepath/JvmtiAddPath.java	Thu May 23 11:07:37 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018, 2019, 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
@@ -121,7 +121,9 @@
             "-Xlog:class+load", "JvmtiApp", "noadd", MAIN_CLASS); // appcds should be enabled
 
         System.out.println("Test case 2: add to boot classpath only - should find Hello.class in boot loader");
-        run(check_appcds_disabled, appJar,
+        String[] toCheck = TestCommon.isDynamicArchive() ? check_appcds_enabled :
+                           check_appcds_disabled;
+        run(toCheck, appJar,
             "-Xlog:class+load=trace",
             modulePath,
             "JvmtiApp", "bootonly", addbootJar, MAIN_CLASS); // appcds should be disabled
--- a/test/hotspot/jtreg/runtime/appcds/jigsaw/modulepath/MainModuleOnly.java	Fri May 17 13:21:44 2019 +0100
+++ b/test/hotspot/jtreg/runtime/appcds/jigsaw/modulepath/MainModuleOnly.java	Thu May 23 11:07:37 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018, 2019, 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
@@ -29,7 +29,7 @@
  * @modules jdk.compiler
  *          jdk.jartool/sun.tools.jar
  *          jdk.jlink
- * @run driver MainModuleOnly
+ * @run main/othervm MainModuleOnly
  * @summary Test some scenarios with a main modular jar specified in the --module-path and -cp options in the command line.
  */
 
@@ -39,6 +39,7 @@
 import java.nio.file.Paths;
 import java.util.Arrays;
 
+import jdk.test.lib.cds.CDSTestUtils.Result;
 import jdk.test.lib.process.OutputAnalyzer;
 import jdk.test.lib.Platform;
 
@@ -61,6 +62,8 @@
     private static Path moduleDir2 = null;
     private static Path destJar = null;
 
+    private static final String jarFileError = "A jar file is not the one used while building the shared archive file:";
+
     public static void buildTestModule() throws Exception {
 
         // javac -d mods/$TESTMODULE --module-path MOD_DIR src/$TESTMODULE/**
@@ -167,17 +170,21 @@
         // run with the archive and the jar with modified timestamp.
         // It should fail due to timestamp of the jar doesn't match the one
         // used during dump time.
-        TestCommon.run("-cp", destJar.toString(),
+        Result res = TestCommon.run("-cp", destJar.toString(),
+                       "-Xlog:cds",
                        "--module-path", moduleDir.toString(),
-                       "-m", TEST_MODULE1)
-            .assertAbnormalExit(
-                "A jar file is not the one used while building the shared archive file:");
+                       "-m", TEST_MODULE1);
+        res.assertAbnormalExit(jarFileError);
         // create an archive with a non-empty directory in the --module-path.
         // The dumping process will exit with an error due to non-empty directory
         // in the --module-path.
+        String mainModule = TEST_MODULE1;
+        if (TestCommon.isDynamicArchive()) {
+            mainModule += "/" + MAIN_CLASS;
+        }
         output = TestCommon.createArchive(destJar.toString(), appClasses,
                                           "--module-path", MODS_DIR.toString(),
-                                          "-m", TEST_MODULE1);
+                                          "-m", mainModule);
         output.shouldHaveExitValue(1)
               .shouldMatch("Error: non-empty directory.*com.simple");
 
--- a/test/hotspot/jtreg/runtime/appcds/jigsaw/overridetests/OverrideTests.java	Fri May 17 13:21:44 2019 +0100
+++ b/test/hotspot/jtreg/runtime/appcds/jigsaw/overridetests/OverrideTests.java	Thu May 23 11:07:37 2019 +0100
@@ -26,8 +26,10 @@
  * @test
  * @requires vm.cds
  * @modules java.base/jdk.internal.misc
+ *          jdk.jartool/sun.tools.jar
  * @library ../..
  * @library /test/lib
+ * @compile ../../test-classes/Hello.java
  * @run driver OverrideTests
  * @summary AppCDS tests for overriding archived classes with -p and --upgrade-module-path
  */
@@ -65,7 +67,7 @@
     private static final String TEST_SRC = System.getProperty("test.src");
     private static final Path SRC_DIR = Paths.get(TEST_SRC, "src");
     private static final Path MODS_DIR = Paths.get("mods");
-
+    private static String appJar;
     // the module that is upgraded
     private static final String[] UPGRADED_MODULES = {"jdk.compiler", "java.net.http"};
     private static final Path[] UPGRADEDMODS_DIR = {Paths.get("upgradedmod1"), Paths.get("upgradedmod2")};
@@ -82,6 +84,7 @@
 
 
     public static void main(String[] args) throws Exception {
+        appJar = JarBuilder.getOrCreateHelloJar();
         OverrideTests tests = new OverrideTests();
         tests.compileModulesAndDumpArchive();
         tests.testAppClassOverriding();
@@ -111,7 +114,7 @@
         Asserts.assertTrue(compiled, TEST_MODULE + " did not compile");
 
         // dump the archive with jdk.compiler and java.net.http classes in the class list
-        OutputAnalyzer output  = TestCommon.dump(null /* appJar*/, TestCommon.list(ARCHIVE_CLASSES));
+        OutputAnalyzer output  = TestCommon.dump(appJar, TestCommon.list(ARCHIVE_CLASSES));
         TestCommon.checkDump(output);
         // Make sure all the classes where successfully archived.
         for (String archiveClass : ARCHIVE_CLASSES) {
@@ -160,7 +163,7 @@
         int upgradeModIdx = isAppLoader ? 0 : 1;
         String expectedException = "java.lang.module.FindException: Unable to compute the hash";
         String prefix[] = new String[3];
-        prefix[0] = "-Djava.class.path=";
+        prefix[0] = "-Djava.class.path=" + appJar;
         prefix[1] = "--add-modules";
         prefix[2] = "java.net.http";
 
--- a/test/hotspot/jtreg/runtime/appcds/jvmti/dumpingWithAgent/DumpingWithJavaAgent.java	Fri May 17 13:21:44 2019 +0100
+++ b/test/hotspot/jtreg/runtime/appcds/jvmti/dumpingWithAgent/DumpingWithJavaAgent.java	Thu May 23 11:07:37 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018, 2019, 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
@@ -105,7 +105,7 @@
         if (!TestCommon.isUnableToMap(output)) {
             output.shouldHaveExitValue(0);
             output.shouldContain(errorMessage);
-            output.shouldMatch(".class.load. Hello source:.*DumpingWithJavaAgent.jar");
+            output.shouldMatch(".class.load.* Hello source:.*DumpingWithJavaAgent.jar");
 
         // CDS dumping with a java agent without the AllowArchvingWithJavaAgent diagnostic option.
         // VM will exit with an error message.
@@ -116,4 +116,3 @@
             .shouldHaveExitValue(1);
     }
 }
-
--- a/test/hotspot/jtreg/runtime/appcds/jvmti/transformRelatedClasses/TransformRelatedClassesAppCDS.java	Fri May 17 13:21:44 2019 +0100
+++ b/test/hotspot/jtreg/runtime/appcds/jvmti/transformRelatedClasses/TransformRelatedClassesAppCDS.java	Thu May 23 11:07:37 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2019, 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
@@ -154,6 +154,12 @@
             return;
         }
 
+        if (TestCommon.isDynamicArchive()) {
+            log("custom loader class list not applicable to dynamic archive" +
+                " - skipping test case for custom loader");
+            return;
+        }
+
         String appClasses[] = {
             "CustomLoaderApp",
         };
--- a/test/hotspot/jtreg/runtime/appcds/test-classes/DummyClassHelper.java	Fri May 17 13:21:44 2019 +0100
+++ b/test/hotspot/jtreg/runtime/appcds/test-classes/DummyClassHelper.java	Thu May 23 11:07:37 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2019, 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
@@ -24,6 +24,7 @@
 
 import java.lang.*;
 import java.lang.reflect.*;
+import jdk.test.lib.cds.CDSTestUtils;
 import sun.hotspot.WhiteBox;
 
 public class DummyClassHelper {
@@ -50,9 +51,14 @@
             cls = Class.forName(classNames[i]);
             checkDummyMethod(cls, classNames[i]);
             if (doWBCheck) {
-                if (!wb.isSharedClass(cls)) {
-                    throw new java.lang.RuntimeException(classNames[i] +
-                        ".class should be in shared space.");
+                // FIXME: for dynamic archive, the class loaded from the
+                // bootclasspath jar during dump time is not loaded from the
+                // archive during run time.
+                if (!CDSTestUtils.isDynamicArchive()) {
+                    if (!wb.isSharedClass(cls)) {
+                        throw new java.lang.RuntimeException(classNames[i] +
+                            ".class should be in shared space.");
+                    }
                 }
             }
         }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/test-classes/GenericTestApp.java	Thu May 23 11:07:37 2019 +0100
@@ -0,0 +1,91 @@
+/*
+ * Copyright (c) 2019, 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;
+
+/**
+ * This is a generic test app for testing if classes are loaded from the CDS archive
+ * or not (without having to parse -Xlog:class+load, or writing your own WhiteBox apps).
+ * Usage:
+ *     [1] Create an archive with WhiteBox enabled.
+ *     [2] Run this app with arguments such as
+ *             "assertShared:java.lang.Object"
+ *             "assertNotShared:NotSharedClassName"
+ *
+ * We can probably add other kinds of simple tests as well ....
+ *
+ * FIXME: enhance WB API to check if a particular archive has failed. So you can say
+ *        assertShared:0,java.lang.Object
+ * to assert that java.lang.Object is shared from archive #0 (i.e., base archive).
+ */
+public class GenericTestApp {
+    private static final WhiteBox wb = WhiteBox.getWhiteBox();
+
+    public static void main(String args[]) throws Exception {
+        System.out.println("GenericTestApp started. WhiteBox = " + wb);
+        System.out.println("cdsMemoryMappingFailed() = " + cdsMemoryMappingFailed());
+
+        for (String s : args) {
+            Class c;
+            if ((c = getClass(s, "assertShared:")) != null) {
+                assertShared(c);
+            }
+            else if ((c = getClass(s, "assertNotShared:")) != null) {
+                assertNotShared(c);
+            }
+            else {
+                throw new RuntimeException("Unknown option: " + s);
+            }
+            System.out.println("passed: " + s);
+        }
+    }
+
+    private static Class getClass(String s, String prefix) throws Exception {
+        if (s.startsWith(prefix)) {
+            return Class.forName(s.substring(prefix.length()));
+        } else {
+            return null;
+        }
+    }
+
+    private static boolean cdsMemoryMappingFailed() {
+        return wb.cdsMemoryMappingFailed();
+    }
+
+    private static void assertShared(Class klass) {
+        if (!cdsMemoryMappingFailed()) {
+            if (!wb.isSharedClass(klass)) {
+                throw new RuntimeException("Class should be shared but is not: " + klass);
+            }
+        } else {
+            // FIXME -- need to throw jtreg.SkippedException
+            System.out.println("Cannot test for wb.isSharedClass(" + klass + ") because CDS mapping has failed");
+        }
+    }
+
+    private static void assertNotShared(Class klass) {
+        if (wb.isSharedClass(klass)) {
+            throw new RuntimeException("Class should be shared but is not: " + klass);
+        }
+    }
+}
--- a/test/hotspot/jtreg/runtime/logging/SafepointCleanupTest.java	Fri May 17 13:21:44 2019 +0100
+++ b/test/hotspot/jtreg/runtime/logging/SafepointCleanupTest.java	Thu May 23 11:07:37 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2019, 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
@@ -43,7 +43,6 @@
         output.shouldContain("deflating per-thread idle monitors");
         output.shouldContain("updating inline caches");
         output.shouldContain("compilation policy safepoint handler");
-        output.shouldContain("purging class loader data graph");
         output.shouldHaveExitValue(0);
     }
 
--- a/test/hotspot/jtreg/serviceability/AsyncGetCallTrace/MyPackage/ASGCTBaseTest.java	Fri May 17 13:21:44 2019 +0100
+++ b/test/hotspot/jtreg/serviceability/AsyncGetCallTrace/MyPackage/ASGCTBaseTest.java	Thu May 23 11:07:37 2019 +0100
@@ -29,7 +29,7 @@
  * @summary Verifies that AsyncGetCallTrace is call-able and provides sane information.
  * @compile ASGCTBaseTest.java
  * @requires os.family == "linux"
- * @requires os.arch=="x86" | os.arch=="i386" | os.arch=="amd64" | os.arch=="x86_64" | os.arch=="arm" | os.arch=="sparc" | os.arch=="aarch64"
+ * @requires os.arch=="x86" | os.arch=="i386" | os.arch=="amd64" | os.arch=="x86_64" | os.arch=="arm" | os.arch=="sparc" | os.arch=="aarch64" | os.arch=="ppc64" | os.arch=="s390"
  * @run main/othervm/native -agentlib:AsyncGetCallTraceTest MyPackage.ASGCTBaseTest
  */
 
--- a/test/hotspot/jtreg/serviceability/sa/ClhsdbField.java	Fri May 17 13:21:44 2019 +0100
+++ b/test/hotspot/jtreg/serviceability/sa/ClhsdbField.java	Thu May 23 11:07:37 2019 +0100
@@ -55,7 +55,6 @@
                 "field InstanceKlass _methods Array<Method*>*",
                 "field InstanceKlass _constants ConstantPool*",
                 "field Klass _name Symbol*",
-                "field JavaThread _next JavaThread*",
                 "field JavaThread _osthread OSThread*",
                 "field JVMState _bci",
                 "field TenuredGeneration _the_space ContiguousSpace*",
--- a/test/hotspot/jtreg/serviceability/sa/ClhsdbPrintStatics.java	Fri May 17 13:21:44 2019 +0100
+++ b/test/hotspot/jtreg/serviceability/sa/ClhsdbPrintStatics.java	Thu May 23 11:07:37 2019 +0100
@@ -68,8 +68,7 @@
                     "SystemDictionary::Object_klass_knum"));
             expStrMap.put("printstatics Threads", List.of(
                     "Static fields of Threads",
-                    "_number_of_threads", "_number_of_non_daemon_threads",
-                    "JavaThread\\* Threads"));
+                    "_number_of_threads", "_number_of_non_daemon_threads"));
             expStrMap.put("printstatics Universe", List.of(
                     "Static fields of Universe",
                     "uintptr_t Universe::_verify_oop_mask",
--- a/test/hotspot/jtreg/serviceability/sa/ClhsdbVmStructsDump.java	Fri May 17 13:21:44 2019 +0100
+++ b/test/hotspot/jtreg/serviceability/sa/ClhsdbVmStructsDump.java	Thu May 23 11:07:37 2019 +0100
@@ -57,7 +57,6 @@
                 "field Klass _name Symbol*",
                 "type ClassLoaderData* null",
                 "type DictionaryEntry KlassHashtableEntry",
-                "field JavaThread _next JavaThread*",
                 "field JavaThread _osthread OSThread*",
                 "type TenuredGeneration CardGeneration",
                 "field JVMState _bci",
--- a/test/hotspot/jtreg/serviceability/sa/sadebugd/SADebugDTest.java	Fri May 17 13:21:44 2019 +0100
+++ b/test/hotspot/jtreg/serviceability/sa/sadebugd/SADebugDTest.java	Thu May 23 11:07:37 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2019, 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
@@ -32,50 +32,42 @@
  * @run main/othervm SADebugDTest
  */
 
-import java.io.File;
-import java.util.concurrent.CountDownLatch;
-import java.io.InputStreamReader;
-import java.io.BufferedReader;
-import java.io.Reader;
 import java.util.concurrent.TimeUnit;
-import java.util.function.Predicate;
-import static jdk.test.lib.Asserts.assertTrue;
+
+import jdk.test.lib.apps.LingeredApp;
+import jdk.test.lib.JDKToolLauncher;
 import static jdk.test.lib.process.ProcessTools.startProcess;
 
 public class SADebugDTest {
 
-    private static final String GOLDEN = "Attaching to process ID %d and starting RMI services, please wait...";
-
-    private static final String JAVA_HOME = (System.getProperty("test.jdk") != null)
-            ? System.getProperty("test.jdk") : System.getProperty("java.home");
-
-    private static final String JAVA_BIN_DIR
-            = JAVA_HOME + File.separator + "bin" + File.separator;
-
-    private static final String JHSDB = JAVA_BIN_DIR + "jhsdb";
+    private static final String GOLDEN = "Attaching to process";
 
     public static void main(String[] args) throws Exception {
+        LingeredApp app = null;
 
-        long ourPid = ProcessHandle.current().pid();
+        try {
+            app = LingeredApp.startApp();
+            System.out.println("Started LingeredApp with pid " + app.getPid());
 
-        // The string we are expecting in the debugd ouput
-        String golden = String.format(GOLDEN, ourPid);
+            JDKToolLauncher jhsdbLauncher = JDKToolLauncher.createUsingTestJDK("jhsdb");
+            jhsdbLauncher.addToolArg("debugd");
+            jhsdbLauncher.addToolArg("--pid");
+            jhsdbLauncher.addToolArg(Long.toString(app.getPid()));
+            ProcessBuilder pb = new ProcessBuilder(jhsdbLauncher.getCommand());
 
-        // We are going to run 'jhsdb debugd <our pid>'
-        // The startProcess will block untl the 'golden' string appears in either process' stdout or stderr
-        // In case of timeout startProcess kills the debugd process
-        ProcessBuilder pb = new ProcessBuilder();
-        pb.command(JHSDB, "debugd", String.valueOf(ourPid));
-        Process debugd = startProcess("debugd", pb, null, (line) -> line.trim().contains(golden), 0, TimeUnit.SECONDS);
+            // The startProcess will block untl the 'golden' string appears in either process' stdout or stderr
+            // In case of timeout startProcess kills the debugd process
+            Process debugd = startProcess("debugd", pb, null, l -> l.contains(GOLDEN), 0, TimeUnit.SECONDS);
 
-        // If we are here, this means we have received the golden line and the test has passed
-        // The debugd remains running, we have to kill it
-        debugd.destroy();
+            // If we are here, this means we have received the golden line and the test has passed
+            // The debugd remains running, we have to kill it
+            debugd.destroy();
+        } finally {
+            if (app != null) {
+                LingeredApp.stopApp(app);
+            }
+        }
 
     }
 
-    private static void log(String string) {
-        System.out.println(string);
-    }
-
 }
--- a/test/jaxp/javax/xml/jaxp/unittest/parsers/BaseParsingTest.java	Fri May 17 13:21:44 2019 +0100
+++ b/test/jaxp/javax/xml/jaxp/unittest/parsers/BaseParsingTest.java	Thu May 23 11:07:37 2019 +0100
@@ -26,18 +26,27 @@
 import java.io.StringReader;
 import javax.xml.parsers.DocumentBuilder;
 import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.parsers.SAXParser;
+import javax.xml.parsers.SAXParserFactory;
 import javax.xml.stream.XMLInputFactory;
 import javax.xml.stream.XMLStreamReader;
+import org.testng.Assert;
 import static org.testng.Assert.assertEquals;
 import org.testng.annotations.DataProvider;
 import org.testng.annotations.Listeners;
 import org.testng.annotations.Test;
 import org.w3c.dom.Document;
+import org.w3c.dom.ls.DOMImplementationLS;
+import org.w3c.dom.ls.LSSerializer;
+import org.xml.sax.Attributes;
 import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+import org.xml.sax.helpers.DefaultHandler;
 
 /**
  * @test
- * @bug 8169450 8222415
+ * @bug 8169450 8222415 8219692
  * @library /javax/xml/jaxp/libs /javax/xml/jaxp/unittest
  * @run testng/othervm -DrunSecMngr=true parsers.BaseParsingTest
  * @run testng/othervm parsers.BaseParsingTest
@@ -45,6 +54,84 @@
  */
 @Listeners({jaxp.library.BasePolicy.class})
 public class BaseParsingTest {
+    private static final String DOM_IMPL =
+            "com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl";
+    private static final String SAX_IMPL =
+            "com.sun.org.apache.xerces.internal.jaxp.SAXParserFactoryImpl";
+
+    String xml_8219692 = "<a "
+            + "xmlns=\"http://openjdk_java_net/xml/defaultNS\" "
+            + "xmlns:p1=\"http://openjdk_java_net/xml/serializer/\">"
+            + "<b>in default namespace</b></a>";
+
+    /**
+     * Creates NamespaceAware parsers using old and new factory methods.
+     * @return NamespaceAware parsers
+     * @throws ParserConfigurationException
+     */
+    @DataProvider(name = "NSAwareDOMFactory")
+    public static Object[][] getNSDOMFactory() throws Exception {
+        boolean isNSAware = true;
+
+        return new Object[][]{
+            {getDOMParser(DocumentBuilderFactory.newDefaultInstance(), isNSAware)},
+            {getDOMParser(DocumentBuilderFactory.newInstance(), isNSAware)},
+            {getDOMParser(DocumentBuilderFactory.newInstance(DOM_IMPL, null), isNSAware)},
+            // using the new methods
+            {DocumentBuilderFactory.newDefaultNSInstance().newDocumentBuilder()},
+            {DocumentBuilderFactory.newNSInstance().newDocumentBuilder()},
+            {DocumentBuilderFactory.newNSInstance(DOM_IMPL, null).newDocumentBuilder()}
+        };
+    }
+
+    /**
+     * Creates parsers using the old instance methods. By default, they are
+     * not Namespace Aware.
+     * @return non-NamespaceAware parsers
+     * @throws ParserConfigurationException
+     */
+    @DataProvider(name = "DOMFactory")
+    public static Object[][] getDOMFactory() throws Exception {
+        boolean isNSAware = false;
+
+        return new Object[][]{
+            {getDOMParser(DocumentBuilderFactory.newDefaultInstance(), isNSAware)},
+            {getDOMParser(DocumentBuilderFactory.newInstance(), isNSAware)},
+            {getDOMParser(DocumentBuilderFactory.newInstance(DOM_IMPL, null), isNSAware)}
+        };
+    }
+
+
+    /**
+     * Creates NamespaceAware parsers using old and new factory methods.
+     * @return NamespaceAware parsers
+     * @throws ParserConfigurationException
+     */
+    @DataProvider(name = "NSAwareSAXFactory")
+    public static Object[][] getNSSAXFactory() throws Exception {
+        boolean isNSAware = true;
+
+        return new Object[][]{
+            {getSAXParser(SAXParserFactory.newDefaultInstance(), isNSAware)},
+            {getSAXParser(SAXParserFactory.newInstance(), isNSAware)},
+            {getSAXParser(SAXParserFactory.newInstance(SAX_IMPL, null), isNSAware)},
+            // using the new methods
+            {SAXParserFactory.newDefaultNSInstance().newSAXParser()},
+            {SAXParserFactory.newNSInstance().newSAXParser()},
+            {SAXParserFactory.newNSInstance(SAX_IMPL, null).newSAXParser()},
+        };
+    }
+
+    @DataProvider(name = "SAXFactory")
+    public static Object[][] getSAXFactory() throws Exception {
+        boolean isNSAware = false;
+
+        return new Object[][]{
+            {getSAXParser(SAXParserFactory.newDefaultInstance(), isNSAware)},
+            {getSAXParser(SAXParserFactory.newInstance(), isNSAware)},
+            {getSAXParser(SAXParserFactory.newInstance(SAX_IMPL, null), isNSAware)},
+        };
+    }
 
     @DataProvider(name = "xmlDeclarations")
     public static Object[][] xmlDeclarations() {
@@ -174,4 +261,96 @@
         Document doc = db.parse(is);
         assertEquals("UTF-16LE", doc.getInputEncoding());
     }
+
+    /**
+     * @bug 8219692
+     * Verifies that the default namespace declaration is preserved when
+     * NamespaceAware is set on the parser.
+     * @throws Exception
+     */
+    @Test(dataProvider = "NSAwareDOMFactory")
+    public void testNSAwareDOMFactory(DocumentBuilder db) throws Exception {
+        LSSerializer ls = getSerializer(db);
+        String out = ls.writeToString(getDoc(db, xml_8219692));
+        System.out.println(out);
+        Assert.assertTrue(out.contains("http://openjdk_java_net/xml/defaultNS"));
+    }
+
+    /**
+     * @bug 8219692
+     * Verifies that the default namespace declaration is missing when the
+     * old factory methods are used.
+     * @throws Exception
+     */
+    @Test(dataProvider = "DOMFactory")
+    public void testDOMFactory(DocumentBuilder db) throws Exception {
+        LSSerializer ls = getSerializer(db);
+        String out = ls.writeToString(getDoc(db, xml_8219692));
+        System.out.println(out);
+        Assert.assertFalse(out.contains("http://openjdk_java_net/xml/defaultNS"));
+    }
+
+    /**
+     * @bug 8219692
+     * Verifies that the default namespace declaration is preserved when
+     * NamespaceAware is set on the parser.
+     * @throws Exception
+     */
+    @Test(dataProvider = "NSAwareSAXFactory")
+    public void testNSAwareSAXFactory(SAXParser sp) throws Exception {
+        MyHandler h = new MyHandler();
+        sp.parse(new InputSource(new StringReader(xml_8219692)), h);
+
+        Assert.assertTrue(h.isNSAware);
+    }
+
+    /**
+     * @bug 8219692
+     * Verifies that the default namespace declaration is missing when the
+     * old factory methods are used.
+     * @throws Exception
+     */
+    @Test(dataProvider = "SAXFactory")
+    public void testSAXFactory(SAXParser sp) throws Exception {
+        MyHandler h = new MyHandler();
+        sp.parse(new InputSource(new StringReader(xml_8219692)), h);
+
+        Assert.assertFalse(h.isNSAware);
+    }
+
+    private static DocumentBuilder getDOMParser(DocumentBuilderFactory dbf, boolean isNSAware)
+            throws Exception {
+        dbf.setNamespaceAware(isNSAware);
+        return dbf.newDocumentBuilder();
+    }
+
+    private static SAXParser getSAXParser(SAXParserFactory spf, boolean isNSAware)
+            throws Exception {
+        spf.setNamespaceAware(isNSAware);
+        return spf.newSAXParser();
+    }
+
+    private LSSerializer getSerializer(DocumentBuilder db) throws Exception {
+        DOMImplementationLS di = (DOMImplementationLS) db.getDOMImplementation();
+        return di.createLSSerializer();
+    }
+
+    private Document getDoc(DocumentBuilder db, String xml) throws Exception {
+        InputSource is = new InputSource(new StringReader(xml));
+        return db.parse(is);
+    }
+
+    /**
+     * SAX Handler
+     */
+    class MyHandler extends DefaultHandler {
+        boolean isNSAware = false;
+
+        @Override
+        public void startElement(String uri, String localName, String qName,
+            Attributes attributes) throws SAXException {
+            isNSAware = "http://openjdk_java_net/xml/defaultNS".equals(uri)
+                    && ("a".equals(localName) || "b".equals(localName));
+        }
+    }
 }
--- a/test/jdk/TEST.ROOT	Fri May 17 13:21:44 2019 +0100
+++ b/test/jdk/TEST.ROOT	Thu May 23 11:07:37 2019 +0100
@@ -43,6 +43,7 @@
     sun.arch.data.model \
     java.runtime.name \
     vm.gc.Z \
+    vm.gc.Shenandoah \
     vm.graal.enabled \
     vm.compiler1.enabled \
     vm.compiler2.enabled \
--- a/test/jdk/com/sun/net/httpserver/SimpleHttpServerTest.java	Fri May 17 13:21:44 2019 +0100
+++ b/test/jdk/com/sun/net/httpserver/SimpleHttpServerTest.java	Thu May 23 11:07:37 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2019, 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
@@ -24,8 +24,12 @@
 /**
  * @test
  * @bug 8015692
+ * @key intermittent
  * @summary  Test HttpServer instantiation, start, and stop repeated in a loop
- *           Testing for Bind exception on Windows
+ *           Testing for Bind exception on Windows. This test may fail
+ *           intermittently if other tests / process manage to bind to
+ *           the same port that the test is using in the short window
+ *           time where the port might appear available again.
  */
 
 import java.net.InetSocketAddress;
@@ -41,24 +45,40 @@
         System.out.println(System.getProperty("java.version"));
         InetSocketAddress serverAddr = new InetSocketAddress(0);
         HttpServer server = HttpServer.create(serverAddr, 0);
-        final int serverPort = server.getAddress().getPort();
+        int serverPort = server.getAddress().getPort();
         server.start();
         server.stop(0);
         serverAddr = new InetSocketAddress(serverPort);
         int exceptionCount = 0;
+        boolean failedOnce = false;
         System.out.println("Using serverPort == " + serverPort);
-        for (int i = 0; i < 100; i++) {
-            try {
-                server = HttpServer.create(serverAddr, 0);
-                server.start();
-                server.stop(0);
-            } catch (Exception ex) {
-                ex.printStackTrace();
-                exceptionCount++;
+        RETRY: while (exceptionCount == 0) {
+            for (int i = 0; i < 100; i++) {
+                try {
+                    server = HttpServer.create(serverAddr, 0);
+                    server.start();
+                    server.stop(0);
+                } catch (Exception ex) {
+                    if (!failedOnce) {
+                        failedOnce = true;
+                        server = HttpServer.create(new InetSocketAddress(0), 0);
+                        serverPort = server.getAddress().getPort();
+                        server.start();
+                        server.stop(0);
+                        serverAddr = new InetSocketAddress(serverPort);
+                        System.out.println("Retrying with serverPort == " + serverPort);
+                        continue RETRY;
+                    }
+                    System.err.println("Got exception at iteration: " + i );
+                    ex.printStackTrace();
+                    exceptionCount++;
+                }
             }
+            break;
         }
         if (exceptionCount > 0) {
-           throw new RuntimeException("Test Failed");
+           throw new RuntimeException("Test Failed: got "
+                 + exceptionCount + " exceptions.");
         }
     }
 }
--- a/test/jdk/java/lang/constant/MethodTypeDescTest.java	Fri May 17 13:21:44 2019 +0100
+++ b/test/jdk/java/lang/constant/MethodTypeDescTest.java	Thu May 23 11:07:37 2019 +0100
@@ -171,6 +171,34 @@
         } catch (IndexOutOfBoundsException ex) {
             // good
         }
+
+        try {
+            ClassDesc[] newParamTypes = new ClassDesc[1];
+            newParamTypes[0] = CD_void;
+            MethodTypeDesc newDesc = MethodTypeDesc.of(returnType, CD_int);
+            newDesc = newDesc.insertParameterTypes(0, newParamTypes);
+            fail("shouldn't allow parameters with class descriptor CD_void");
+        } catch (IllegalArgumentException ex) {
+            // good
+        }
+
+        try {
+            MethodTypeDesc newDesc = MethodTypeDesc.of(returnType, CD_int);
+            newDesc = newDesc.insertParameterTypes(0, null);
+            fail("should fail with NPE");
+        } catch (NullPointerException ex) {
+            // good
+        }
+
+        try {
+            ClassDesc[] newParamTypes = new ClassDesc[1];
+            newParamTypes[0] = null;
+            MethodTypeDesc newDesc = MethodTypeDesc.of(returnType, CD_int);
+            newDesc = newDesc.insertParameterTypes(0, newParamTypes);
+            fail("should fail with NPE");
+        } catch (NullPointerException ex) {
+            // good
+        }
     }
 
     private void badDropParametersTypes(ClassDesc returnType, String... paramDescTypes) {
@@ -209,7 +237,7 @@
         try {
             MethodTypeDesc newDesc = mtDesc.dropParameterTypes(1, 0);
             fail("start index > end index should have failed");
-        } catch (IllegalArgumentException ex) {
+        } catch (IndexOutOfBoundsException ex) {
             // good
         }
     }
@@ -258,5 +286,23 @@
         catch (IllegalArgumentException e) {
             // good
         }
+
+        try {
+            MethodTypeDesc r = MethodTypeDesc.of(CD_int, null);
+            fail("ClassDesc array should not be null");
+        }
+        catch (NullPointerException e) {
+            // good
+        }
+
+        try {
+            ClassDesc[] paramDescs = new ClassDesc[1];
+            paramDescs[0] = null;
+            MethodTypeDesc r = MethodTypeDesc.of(CD_int, paramDescs);
+            fail("ClassDesc should not be null");
+        }
+        catch (NullPointerException e) {
+            // good
+        }
     }
 }
--- a/test/jdk/java/net/BindException/Test.java	Fri May 17 13:21:44 2019 +0100
+++ b/test/jdk/java/net/BindException/Test.java	Thu May 23 11:07:37 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2019, 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
@@ -51,18 +51,24 @@
 
     static int count;
     static int failures;
+    static boolean retried;
 
     static void doTest(Object test[], InetAddress ia1, InetAddress ia2,
                        boolean silent) throws Exception {
-        String s1_type = (String)test[0];
-        String s2_type = (String)test[1];
-        int port = 0;
-
         /*
          * Increment test count
          */
         count++;
 
+        doTest(test, count, ia1, ia2, silent, !retried);
+    }
+
+    static void doTest(Object test[], int count, InetAddress ia1, InetAddress ia2,
+                       boolean silent, boolean retry) throws Exception {
+        String s1_type = (String)test[0];
+        String s2_type = (String)test[1];
+        int port = 0;
+
         /*
          * Do the test
          */
@@ -74,6 +80,8 @@
         Socket sock1 = null;
         ServerSocket ss = null;
         DatagramSocket dsock1 = null;
+        boolean firstBound = false;
+
         try {
             /* bind the first socket */
 
@@ -95,6 +103,13 @@
 
             /* bind the second socket */
 
+            // The fact that the port was available for ia1 does not
+            // guarantee that it will also be available for ia2 as something
+            // else might already be bound to that port.
+            // For the sake of test stability we will retry once in
+            // case of unexpected bind exception.
+
+            firstBound = true;
             if (s2_type.equals("Socket")) {
                 try (Socket sock2 = new Socket()) {
                     sock2.bind( new InetSocketAddress(ia2, port));
@@ -148,6 +163,18 @@
             return;
         }
 
+        if (failed && retry && firstBound) {
+            // retry once at the first failure only
+            retried = true;
+            if (!silent) {
+                System.out.println("");
+                System.out.println("**************************");
+                System.out.println("Test " + count + ": Retrying...");
+            }
+            doTest(test, count, ia1, ia2, silent, false);
+            return;
+        }
+
         if (failed || !silent) {
             System.out.println("");
             System.out.println("**************************");
--- a/test/jdk/java/net/InetAddress/CheckJNI.java	Fri May 17 13:21:44 2019 +0100
+++ b/test/jdk/java/net/InetAddress/CheckJNI.java	Thu May 23 11:07:37 2019 +0100
@@ -34,25 +34,27 @@
 import java.util.*;
 import java.util.stream.Collectors;
 import jdk.test.lib.NetworkConfiguration;
+import jdk.test.lib.net.IPSupport;
 
 public class CheckJNI {
-    static Socket s;
-    static ServerSocket server;
-    static DatagramSocket dg1, dg2;
-
     public static void main (String[] args) throws Exception {
         /* try to invoke as much java.net native code as possible */
 
-        System.out.println ("Testing IPv4 Socket/ServerSocket");
-        server = new ServerSocket (0);
-        s = new Socket ("127.0.0.1", server.getLocalPort());
-        s.close();
-        server.close();
+        InetAddress loopback = InetAddress.getLoopbackAddress();
+        System.out.println("Testing loopback Socket/ServerSocket");
+        testSocket(loopback);
+
+        System.out.println("Testing loopback DatagramSocket");
+        testDatagram(loopback);
 
-        System.out.println ("Testing IPv4 DatagramSocket");
-        dg1 = new DatagramSocket (0, InetAddress.getByName ("127.0.0.1"));
-        dg2 = new DatagramSocket (0, InetAddress.getByName ("127.0.0.1"));
-        testDatagrams (dg1, dg2);
+        if (IPSupport.hasIPv4()) {
+            InetAddress loopback4 = InetAddress.getByName("127.0.0.1");
+            System.out.println("Testing IPv4 Socket/ServerSocket");
+            testSocket(loopback4);
+
+            System.out.println("Testing IPv4 DatagramSocket");
+            testDatagram(loopback4);
+        }
 
         /* Find link local IPv6 addrs to test */
         List<Inet6Address> addrs = NetworkConfiguration.probe()
@@ -60,33 +62,38 @@
                 .filter(Inet6Address::isLinkLocalAddress)
                 .collect(Collectors.toList());
 
-        server = new ServerSocket(0);
         for (Inet6Address ia6 : addrs) {
             System.out.println("Address:" + ia6);
             System.out.println("Testing IPv6 Socket");
-            s = new Socket(ia6, server.getLocalPort());
-            s.close();
+            testSocket(ia6);
 
             System.out.println("Testing IPv6 DatagramSocket");
-            dg1 = new DatagramSocket(0, ia6);
-            dg2 = new DatagramSocket(0, ia6);
-            testDatagrams(dg1, dg2);
+            testDatagram(ia6);
         }
-        server.close();
-        System.out.println ("OK");
+        System.out.println("OK");
     }
 
-    static void testDatagrams (DatagramSocket s1, DatagramSocket s2) throws Exception {
+    static void testSocket(InetAddress ia) throws Exception {
+        ServerSocket server = new ServerSocket(0);
+        Socket s = new Socket(ia, server.getLocalPort());
+        s.close();
+        server.close();
+    }
+
+    static void testDatagram(InetAddress ia) throws Exception {
+        DatagramSocket s1 = new DatagramSocket(0, ia);
+        DatagramSocket s2 = new DatagramSocket(0, ia);
+
         DatagramPacket p1 = new DatagramPacket (
                 "hello world".getBytes(),
                 0, "hello world".length(), s2.getLocalAddress(),
                 s2.getLocalPort()
         );
 
-        DatagramPacket p2 = new DatagramPacket (new byte[128], 128);
-        s1.send (p1);
-        s2.receive (p2);
-        s1.close ();
-        s2.close ();
+        DatagramPacket p2 = new DatagramPacket(new byte[128], 128);
+        s1.send(p1);
+        s2.receive(p2);
+        s1.close();
+        s2.close();
     }
 }
--- a/test/jdk/java/net/NetworkInterface/IPv4Only.java	Fri May 17 13:21:44 2019 +0100
+++ b/test/jdk/java/net/NetworkInterface/IPv4Only.java	Thu May 23 11:07:37 2019 +0100
@@ -23,6 +23,7 @@
 
 /* @test
  * @bug   6964714
+ * @library /test/lib
  * @run main/othervm -Djava.net.preferIPv4Stack=true IPv4Only
  * @summary Test the networkinterface listing with java.net.preferIPv4Stack=true.
  */
@@ -30,19 +31,36 @@
 
 import java.net.*;
 import java.util.*;
-
+import jdk.test.lib.net.IPSupport;
 
 public class IPv4Only {
     public static void main(String[] args) throws Exception {
-        Enumeration<NetworkInterface> nifs = NetworkInterface.getNetworkInterfaces();
-        while (nifs.hasMoreElements()) {
-            NetworkInterface nif = nifs.nextElement();
-            Enumeration<InetAddress> addrs = nif.getInetAddresses();
-            while (addrs.hasMoreElements()) {
-               InetAddress hostAddr = addrs.nextElement();
-               if ( hostAddr instanceof Inet6Address ){
-                    throw new RuntimeException( "NetworkInterfaceV6List failed - found v6 address " + hostAddr.getHostAddress() );
-               }
+        if (IPSupport.hasIPv4()) {
+            System.out.println("Testing IPv4");
+            Enumeration<NetworkInterface> nifs = NetworkInterface.getNetworkInterfaces();
+            while (nifs.hasMoreElements()) {
+                NetworkInterface nif = nifs.nextElement();
+                Enumeration<InetAddress> addrs = nif.getInetAddresses();
+                while (addrs.hasMoreElements()) {
+                   InetAddress hostAddr = addrs.nextElement();
+                   if ( hostAddr instanceof Inet6Address ){
+                        throw new RuntimeException( "NetworkInterfaceV6List failed - found v6 address " + hostAddr.getHostAddress() );
+                   }
+                }
+            }
+        } else {
+            try {
+                NetworkInterface.getNetworkInterfaces();
+                throw new RuntimeException("NetworkInterface.getNetworkInterfaces() should throw SocketException");
+            } catch (SocketException expected) {
+                System.out.println("caught expected exception: " + expected);
+            }
+
+            try {
+                NetworkInterface.networkInterfaces();
+                throw new RuntimeException("NetworkInterface.networkInterfaces() should throw SocketException");
+            } catch (SocketException expected) {
+                System.out.println("caught expected exception: " + expected);
             }
         }
     }
--- a/test/jdk/java/net/PlainSocketImpl/SetOption.java	Fri May 17 13:21:44 2019 +0100
+++ b/test/jdk/java/net/PlainSocketImpl/SetOption.java	Thu May 23 11:07:37 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2019, 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
@@ -35,8 +35,10 @@
 
     public static void main(String args[]) throws Exception {
 
-        ServerSocket ss = new ServerSocket(0);
-        Socket s1 = new Socket("localhost", ss.getLocalPort());
+        InetAddress loopback = InetAddress.getLoopbackAddress();
+        ServerSocket ss = new ServerSocket(0, 0, loopback);
+
+        Socket s1 = new Socket(loopback, ss.getLocalPort());
         Socket s2 = ss.accept();
 
         s1.close();
--- a/test/jdk/java/net/Socket/RST.java	Fri May 17 13:21:44 2019 +0100
+++ b/test/jdk/java/net/Socket/RST.java	Thu May 23 11:07:37 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2019, 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
@@ -47,8 +47,10 @@
     }
 
     RST() throws Exception {
-        ServerSocket ss = new ServerSocket(0);
-        client = new Socket("localhost", ss.getLocalPort());
+        InetAddress loopback = InetAddress.getLoopbackAddress();
+        ServerSocket ss = new ServerSocket();
+        ss.bind(new InetSocketAddress(loopback, 0));
+        client = new Socket(loopback, ss.getLocalPort());
         Socket server = ss.accept();
 
         Thread thr = new Thread(this);
--- a/test/jdk/java/net/URLConnection/URLConnectionHeaders.java	Fri May 17 13:21:44 2019 +0100
+++ b/test/jdk/java/net/URLConnection/URLConnectionHeaders.java	Thu May 23 11:07:37 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2019, 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
@@ -27,12 +27,14 @@
  * @summary URLConnection cannot enumerate request properties,
  *          and URLConnection can neither get nor set multiple
  *          request properties w/ same key
+ * @library /test/lib
  *
  */
 
 import java.net.*;
 import java.util.*;
 import java.io.*;
+import jdk.test.lib.net.URIBuilder;
 
 public class URLConnectionHeaders {
 
@@ -77,15 +79,22 @@
         }
     }
 
-    public static void main(String[] args) {
+    public static void main(String[] args) throws Exception {
         try {
-            ServerSocket serversocket = new ServerSocket (0);
-            int port = serversocket.getLocalPort ();
-            XServer server = new XServer (serversocket);
-            server.start ();
-            Thread.sleep (200);
-            URL url = new URL ("http://localhost:"+port+"/index.html");
-            URLConnection uc = url.openConnection ();
+            InetAddress loopback = InetAddress.getLoopbackAddress();
+            ServerSocket serversocket = new ServerSocket();
+            serversocket.bind(new InetSocketAddress(loopback, 0));
+            int port = serversocket.getLocalPort();
+            XServer server = new XServer(serversocket);
+            server.start();
+            Thread.sleep(200);
+            URL url = URIBuilder.newBuilder()
+                      .scheme("http")
+                      .loopback()
+                      .port(port)
+                      .path("/index.html")
+                      .toURL();
+            URLConnection uc = url.openConnection();
 
             // add request properties
             uc.addRequestProperty("Cookie", "cookie1");
@@ -106,6 +115,7 @@
 
         } catch (Exception e) {
             e.printStackTrace();
+            throw e;
         }
     }
 }
--- a/test/jdk/java/net/ipv6tests/UdpTest.java	Fri May 17 13:21:44 2019 +0100
+++ b/test/jdk/java/net/ipv6tests/UdpTest.java	Thu May 23 11:07:37 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2019, 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
@@ -24,11 +24,14 @@
 /*
  * @test
  * @bug 4868820
- * @summary IPv6 support for Windows XP and 2003 server
+ * @key intermittent
+ * @summary IPv6 support for Windows XP and 2003 server.
+ *          This test requires binding to the wildcard address and as such
+ *          may fail intermittently on some platforms.
  * @library /test/lib
  * @build jdk.test.lib.NetworkConfiguration
  *        jdk.test.lib.Platform
- * @run main UdpTest
+ * @run main UdpTest -d
  */
 
 import java.net.DatagramPacket;
@@ -92,6 +95,7 @@
     /* basic UDP connectivity test using IPv6 only and IPv4/IPv6 together */
 
     static void test1 () throws Exception {
+        System.out.println("Test1 starting");
         s1 = new DatagramSocket ();
         s2 = new DatagramSocket ();
         simpleDataExchange (s1, ia4addr, s2, ia4addr);
@@ -130,6 +134,7 @@
     /* check timeouts on receive */
 
     static void test2 () throws Exception {
+        System.out.println("Test2 starting");
         s1 = new DatagramSocket ();
         s2 = new DatagramSocket ();
         s1.setSoTimeout (4000);
@@ -180,6 +185,7 @@
     /* check connected sockets */
 
     static void test3 () throws Exception {
+        System.out.println("Test3 starting");
         s1 = new DatagramSocket ();
         s2 = new DatagramSocket ();
         s1.connect (ia6addr, s2.getLocalPort());
@@ -191,6 +197,7 @@
     /* check PortUnreachable */
 
     static void test4 () throws Exception {
+        System.out.println("Test4 starting");
         s1 = new DatagramSocket ();
         s1.connect (ia6addr, 5000);
         s1.setSoTimeout (3000);
--- a/test/jdk/java/nio/channels/DatagramChannel/BasicMulticastTests.java	Fri May 17 13:21:44 2019 +0100
+++ b/test/jdk/java/nio/channels/DatagramChannel/BasicMulticastTests.java	Thu May 23 11:07:37 2019 +0100
@@ -38,6 +38,7 @@
 import java.io.IOException;
 
 import jdk.test.lib.NetworkConfiguration;
+import jdk.test.lib.net.IPSupport;
 
 public class BasicMulticastTests {
 
@@ -45,17 +46,15 @@
      * Tests that existing membership key is returned by join methods and that
      * membership key methods return the expected results
      */
-    static void membershipKeyTests(NetworkInterface nif,
+    static void membershipKeyTests(StandardProtocolFamily family,
                                    InetAddress group,
+                                   NetworkInterface nif,
                                    InetAddress source)
         throws IOException
     {
         System.out.format("MembershipKey test using %s @ %s\n",
             group.getHostAddress(), nif.getName());
 
-        ProtocolFamily family = (group instanceof Inet4Address) ?
-            StandardProtocolFamily.INET : StandardProtocolFamily.INET6;
-
         DatagramChannel dc = DatagramChannel.open(family)
             .setOption(StandardSocketOptions.SO_REUSEADDR, true)
             .bind(new InetSocketAddress(source, 0));
@@ -114,31 +113,31 @@
     /**
      * Tests exceptions for invalid arguments or scenarios
      */
-    static void exceptionTests(NetworkInterface nif)
+    static void exceptionTests(StandardProtocolFamily family,
+                               InetAddress group,
+                               InetAddress notGroup,
+                               NetworkInterface nif,
+                               InetAddress loopback)
         throws IOException
     {
         System.out.println("Exception Tests");
 
-        DatagramChannel dc = DatagramChannel.open(StandardProtocolFamily.INET)
+        DatagramChannel dc = DatagramChannel.open(family)
             .setOption(StandardSocketOptions.SO_REUSEADDR, true)
             .bind(new InetSocketAddress(0));
 
-        InetAddress group = InetAddress.getByName("225.4.5.6");
-        InetAddress notGroup = InetAddress.getByName("1.2.3.4");
-        InetAddress thisHost = InetAddress.getLocalHost();
-
         // IllegalStateException
         MembershipKey key;
         key = dc.join(group, nif);
         try {
-            dc.join(group, nif, thisHost);
+            dc.join(group, nif, loopback);
             throw new RuntimeException("IllegalStateException not thrown");
         } catch (IllegalStateException x) {
         } catch (UnsupportedOperationException x) {
         }
         key.drop();
         try {
-            key = dc.join(group, nif, thisHost);
+            key = dc.join(group, nif, loopback);
             try {
                 dc.join(group, nif);
                 throw new RuntimeException("IllegalStateException not thrown");
@@ -155,7 +154,7 @@
         } catch (IllegalArgumentException x) {
         }
         try {
-            dc.join(notGroup, nif, thisHost);
+            dc.join(notGroup, nif, loopback);
             throw new RuntimeException("IllegalArgumentException not thrown");
         } catch (IllegalArgumentException x) {
         } catch (UnsupportedOperationException x) {
@@ -188,7 +187,7 @@
         } catch (ClosedChannelException x) {
         }
         try {
-            dc.join(group, nif, thisHost);
+            dc.join(group, nif, loopback);
             throw new RuntimeException("ClosedChannelException not thrown");
         } catch (ClosedChannelException x) {
         } catch (UnsupportedOperationException x) {
@@ -201,26 +200,28 @@
      * and invoke tests.
      */
     public static void main(String[] args) throws IOException {
-
-        // multicast groups used for the test
-        InetAddress ip4Group = InetAddress.getByName("225.4.5.6");
-        InetAddress ip6Group = InetAddress.getByName("ff02::a");
-
-
         NetworkConfiguration config = NetworkConfiguration.probe();
 
-        NetworkInterface nif = config.ip4MulticastInterfaces().iterator().next();
-        InetAddress anySource = config.ip4Addresses(nif).iterator().next();
-        membershipKeyTests(nif, ip4Group, anySource);
-        exceptionTests(nif);
+        // test IPv4 if available
+        if (IPSupport.hasIPv4()) {
+            InetAddress group = InetAddress.getByName("225.4.5.6");
+            InetAddress notGroup = InetAddress.getByName("1.2.3.4");
+            InetAddress loopback = InetAddress.getByName("127.0.0.1");
+            NetworkInterface nif = config.ip4MulticastInterfaces().iterator().next();
+            InetAddress anySource = config.ip4Addresses(nif).iterator().next();
+            membershipKeyTests(StandardProtocolFamily.INET, group, nif, anySource);
+            exceptionTests(StandardProtocolFamily.INET, group, notGroup, nif, loopback);
+        }
 
-        // re-run the membership key tests with IPv6 if available
-
-        Iterator<NetworkInterface> iter = config.ip6MulticastInterfaces().iterator();
-        if (iter.hasNext()) {
-            nif = iter.next();
-            anySource = config.ip6Addresses(nif).iterator().next();
-            membershipKeyTests(nif, ip6Group, anySource);
+        // test IPv6 if available
+        if (IPSupport.hasIPv6()) {
+            InetAddress group = InetAddress.getByName("ff02::a");
+            InetAddress notGroup = InetAddress.getByName("fe80::1234");
+            InetAddress loopback = InetAddress.getByName("::1");
+            NetworkInterface nif = config.ip6MulticastInterfaces().iterator().next();
+            InetAddress anySource = config.ip6Addresses(nif).iterator().next();
+            membershipKeyTests(StandardProtocolFamily.INET6, group, nif, anySource);
+            exceptionTests(StandardProtocolFamily.INET6, group, notGroup, nif, loopback);
         }
     }
 }
--- a/test/jdk/java/security/SecureClassLoader/DefineClass.java	Fri May 17 13:21:44 2019 +0100
+++ b/test/jdk/java/security/SecureClassLoader/DefineClass.java	Thu May 23 11:07:37 2019 +0100
@@ -51,10 +51,13 @@
 import java.util.Enumeration;
 import java.util.List;
 import java.util.PropertyPermission;
+import jdk.test.lib.net.IPSupport;
 
 /*
  * @test
  * @bug 6826789 8131486 8130181
+ * @library /test/lib
+ * @build jdk.test.lib.net.IPSupport
  * @summary Make sure equivalent ProtectionDomains are granted the same
  *          permissions when the CodeSource URLs are different but resolve
  *          to the same ip address after name service resolution.
@@ -85,6 +88,15 @@
         "AAUAAQAGAAAAHQABAAEAAAAFKrcAAbEAAAABAAcAAAAGAAEAAAABAAEACAAA" +
         "AAIACQ==";
 
+    // Base64 encoded bytes of simple class: "package bar2; public class Bar2 {}"
+    private final static String BAR2_CLASS =
+        "yv66vgAAADQADwoAAwAMBwANBwAOAQAGPGluaXQ+AQADKClWAQAEQ29kZQEA" +
+        "D0xpbmVOdW1iZXJUYWJsZQEABG1haW4BABYoW0xqYXZhL2xhbmcvU3RyaW5n" +
+        "OylWAQAKU291cmNlRmlsZQEACUJhcjIuamF2YQwABAAFAQAJYmFyMi9CYXIy" +
+        "AQAQamF2YS9sYW5nL09iamVjdAAhAAIAAwAAAAAAAgABAAQABQABAAYAAAAd" +
+        "AAEAAQAAAAUqtwABsQAAAAEABwAAAAYAAQAAAAEACQAIAAkAAQAGAAAAGQAA" +
+        "AAEAAAABsQAAAAEABwAAAAYAAQAAAAEAAQAKAAAAAgAL";
+
     // Base64 encoded bytes of simple class: "package baz; public class Baz {}"
     private final static String BAZ_CLASS =
         "yv66vgAAADQADQoAAwAKBwALBwAMAQAGPGluaXQ+AQADKClWAQAEQ29kZQEA" +
@@ -137,12 +149,23 @@
                                                       "foo.Foo", FOO_CLASS,
                                                       null);
         checkPerms(perms1, GRANTED_PERMS);
-        ArrayList<Permission> perms2 = getPermissions(scl, p,
-                                                      "http://127.0.0.1/",
-                                                      "bar.Bar", BAR_CLASS,
-                                                      null);
-        checkPerms(perms2, GRANTED_PERMS);
-        assert(perms1.equals(perms2));
+
+        if (IPSupport.hasIPv4()) {
+            ArrayList<Permission> perms2 = getPermissions(scl, p,
+                                                          "http://127.0.0.1/",
+                                                          "bar.Bar", BAR_CLASS,
+                                                          null);
+            checkPerms(perms2, GRANTED_PERMS);
+            assert(perms1.equals(perms2));
+        }
+        if (IPSupport.hasIPv6()) {
+            ArrayList<Permission> perms2 = getPermissions(scl, p,
+                                                          "http://[::1]/",
+                                                          "bar2.Bar2", BAR2_CLASS,
+                                                          null);
+            checkPerms(perms2, GRANTED_PERMS);
+            assert(perms1.equals(perms2));
+        }
 
         // check that class signed by baz is granted an additional permission
         Certificate[] chain = new Certificate[] {getCert(BAZ_CERT)};
--- a/test/jdk/java/security/SecureClassLoader/DefineClass.policy	Fri May 17 13:21:44 2019 +0100
+++ b/test/jdk/java/security/SecureClassLoader/DefineClass.policy	Thu May 23 11:07:37 2019 +0100
@@ -9,6 +9,14 @@
 grant codebase "http://127.0.0.1/" {
     permission java.util.PropertyPermission "user.name", "read";
 };
+grant codebase "http://[::1]/" {
+    permission java.util.PropertyPermission "user.name", "read";
+};
 grant codebase "http://localhost/", signedby "baz" {
     permission java.util.PropertyPermission "user.dir", "read";
 };
+// For IPSupport
+grant codebase "file:${test.classes}/../../../../test/lib/-" {
+    permission java.net.SocketPermission "localhost:0", "listen,resolve";
+    permission java.util.PropertyPermission "java.net.preferIPv4Stack", "read";
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/text/Format/NumberFormat/TestPeruCurrencyFormat.java	Thu May 23 11:07:37 2019 +0100
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2019, 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
+ * @bug 8206879
+ * @summary Currency decimal marker incorrect for Peru.
+ * @modules jdk.localedata
+ * @run main/othervm -Djava.locale.providers=JRE TestPeruCurrencyFormat
+ */
+
+import java.text.NumberFormat;
+import java.util.Locale;
+
+public class TestPeruCurrencyFormat {
+
+    public static void main(String[] args) {
+        final String expected = "S/.1,234.56";
+        NumberFormat currencyFmt =
+                NumberFormat.getCurrencyInstance(new Locale("es", "PE"));
+        String s = currencyFmt.format(1234.56);
+
+        if (!s.equals(expected)) {
+            throw new RuntimeException("Currency format for Peru failed, expected " + expected + ", got " + s);
+        }
+    }
+}
--- a/test/jdk/java/time/test/java/time/chrono/TestEraDisplayName.java	Fri May 17 13:21:44 2019 +0100
+++ b/test/jdk/java/time/test/java/time/chrono/TestEraDisplayName.java	Thu May 23 11:07:37 2019 +0100
@@ -28,7 +28,9 @@
 import java.time.*;
 import java.time.chrono.*;
 import java.time.format.*;
+import java.util.Arrays;
 import java.util.Locale;
+import java.util.stream.Stream;
 
 import org.testng.annotations.DataProvider;
 import org.testng.annotations.Test;
@@ -39,13 +41,18 @@
  * chrono implementation.
  * Note: The exact result may depend on locale data provider's implementation.
  *
- * @bug 8171049
+ * @bug 8171049 8224105
  */
 @Test
 public class TestEraDisplayName {
     private static final Locale THAI = Locale.forLanguageTag("th-TH");
     private static final Locale EGYPT = Locale.forLanguageTag("ar-EG");
 
+    private static final LocalDate REIWA_1ST = LocalDate.of(2019, 5, 1);
+    private static final DateTimeFormatter JAPANESE_FORMATTER =
+         DateTimeFormatter.ofPattern("yyyy MM dd GGGG G GGGGG")
+            .withChronology(JapaneseChronology.INSTANCE);
+
     @DataProvider(name="eraDisplayName")
     Object[][] eraDisplayName() {
         return new Object[][] {
@@ -135,8 +142,22 @@
         };
     }
 
+    @DataProvider
+    Object[][] allLocales() {
+        return Arrays.stream(Locale.getAvailableLocales())
+            .map(Stream::of)
+            .map(Stream::toArray)
+            .toArray(Object[][]::new);
+    }
+
     @Test(dataProvider="eraDisplayName")
     public void test_eraDisplayName(Era era, TextStyle style, Locale locale, String expected) {
         assertEquals(era.getDisplayName(style, locale), expected);
     }
+
+    @Test(dataProvider="allLocales")
+    public void test_reiwaNames(Locale locale) throws DateTimeParseException {
+        DateTimeFormatter f = JAPANESE_FORMATTER.withLocale(locale);
+        assertEquals(LocalDate.parse(REIWA_1ST.format(f), f), REIWA_1ST);
+    }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/util/Calendar/JapanEraNameCompatTest.java	Thu May 23 11:07:37 2019 +0100
@@ -0,0 +1,144 @@
+/*
+ * Copyright (c) 2019, 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
+ * @bug 8218781
+ * @summary Test the localized names of Japanese era Reiwa from COMPAT provider.
+ * @modules jdk.localedata
+ * @run testng/othervm -Djava.locale.providers=COMPAT JapanEraNameCompatTest
+ */
+
+import static java.util.Calendar.*;
+import static java.util.Locale.*;
+
+import java.time.LocalDate;
+import java.time.chrono.JapaneseChronology;
+import java.time.chrono.JapaneseEra;
+import java.time.format.DateTimeFormatter;
+import java.time.format.DateTimeParseException;
+import java.time.format.TextStyle;
+import java.util.Calendar;
+import java.util.Locale;
+
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+import static org.testng.Assert.assertEquals;
+
+@Test
+public class JapanEraNameCompatTest {
+    static final Calendar c = new Calendar.Builder()
+            .setCalendarType("japanese")
+            .setFields(ERA, 5, YEAR, 1, MONTH, MAY, DAY_OF_MONTH, 1)
+            .build();
+    static final String EngName = "Reiwa";
+    static final String CJName = "\u4ee4\u548c";
+    static final String KoreanName = "\ub808\uc774\uc640";
+    static final String ArabicName = "\u0631\u064a\u0648\u0627";
+    static final String ThaiName = "\u0e40\u0e23\u0e27\u0e30";
+    static final String HindiName = "\u0930\u0947\u0907\u0935\u093e";
+    static final String RussianName = "\u0420\u044d\u0439\u0432\u0430";
+    static final String SerbianName = "\u0420\u0435\u0438\u0432\u0430";
+    static final String SerbLatinName = "Reiva";
+
+    @DataProvider(name="UtilCalendar")
+    Object[][] dataUtilCalendar() {
+        return new Object[][] {
+            //locale,   long,       short
+            { JAPAN,    CJName,     "R" },
+            { KOREAN,   KoreanName, "R" },
+            { CHINA,    CJName,     "R" },
+            { TAIWAN,   CJName,     "R" }, // fallback to zh
+            { new Locale("ar"), ArabicName, ArabicName },
+            { new Locale("th"), ThaiName, "R" },
+            // hi_IN fallback to root
+            { new Locale("hi", "IN"), EngName, "R" }
+        };
+    }
+
+    @Test(dataProvider="UtilCalendar")
+    public void testCalendarEraDisplayName(Locale locale,
+            String longName, String shortName) {
+        assertEquals(c.getDisplayName(ERA, LONG, locale), longName);
+        assertEquals(c.getDisplayName(ERA, SHORT, locale), shortName);
+    }
+
+    @DataProvider(name="JavaTime")
+    Object[][] dataJavaTime() {
+        return new Object[][] {
+            // locale, full, short
+            { JAPAN, CJName, CJName },
+            { KOREAN, KoreanName, KoreanName },
+            { CHINA, CJName, CJName },
+            { TAIWAN, CJName, CJName },
+            { new Locale("ar"), ArabicName, ArabicName },
+            { new Locale("th"), ThaiName, ThaiName },
+            { new Locale("hi", "IN"), HindiName, HindiName },
+            { new Locale("ru"), RussianName, RussianName },
+            { new Locale("sr"), SerbianName, SerbianName },
+            { Locale.forLanguageTag("sr-Latn"), SerbLatinName, SerbLatinName },
+            { new Locale("hr"), EngName, EngName },
+            { new Locale("in"), EngName, EngName },
+            { new Locale("lt"), EngName, EngName },
+            { new Locale("nl"), EngName, EngName },
+            { new Locale("no"), EngName, "R" },
+            { new Locale("sv"), EngName, EngName },
+            // el fallback to root
+            { new Locale("el"), EngName, EngName }
+        };
+    }
+
+    @Test(dataProvider="JavaTime")
+    public void testChronoJapanEraDisplayName(Locale locale,
+            String fullName, String shortName) {
+
+        JapaneseEra era = JapaneseEra.valueOf("Reiwa");
+        assertEquals(era.getDisplayName(TextStyle.FULL, locale), fullName);
+        assertEquals(era.getDisplayName(TextStyle.SHORT, locale), shortName);
+        assertEquals(era.getDisplayName(TextStyle.NARROW, locale), "R");
+    }
+
+    @Test
+    public void testFormatParseEraName() {
+        LocalDate date = LocalDate.of(2019, 5, 1);
+        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy MM dd GGGG");
+        formatter = formatter.withChronology(JapaneseChronology.INSTANCE);
+
+        int num = 0;
+        for (Locale locale : Calendar.getAvailableLocales()) {
+            formatter = formatter.withLocale(locale);
+            try {
+                LocalDate.parse(date.format(formatter), formatter);
+            } catch (DateTimeParseException e) {
+                // If an array is defined for Japanese eras in java.time resource,
+                // but an era entry is missing, format fallback to English name
+                // while parse throw DateTimeParseException.
+                num++;
+                System.out.println("Missing java.time resource data for locale: " + locale);
+            }
+        }
+        if (num > 0) {
+            throw new RuntimeException("Missing java.time data for " + num + " locales");
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/jdk/jfr/event/gc/detailed/TestShenandoahHeapRegionInformationEvent.java	Thu May 23 11:07:37 2019 +0100
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2019, Red Hat, Inc. All rights reserved.
+ *
+ * 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 jdk.jfr.event.gc.detailed;
+
+import java.nio.file.Paths;
+import java.util.List;
+
+import jdk.jfr.EventType;
+import jdk.jfr.FlightRecorder;
+import jdk.jfr.Recording;
+import jdk.jfr.consumer.RecordedEvent;
+import jdk.test.lib.Asserts;
+import jdk.test.lib.jfr.EventNames;
+import jdk.test.lib.jfr.Events;
+import jdk.test.lib.jfr.GCHelper;
+
+/**
+ * @test
+ * @bug 8221507
+ * @requires vm.hasJFR & vm.gc.Shenandoah
+ * @key jfr
+ * @library /test/lib /test/jdk
+ * @run main/othervm  -Xmx32m -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:ShenandoahGarbageThreshold=1 jdk.jfr.event.gc.detailed.TestShenandoahHeapRegionInformationEvent
+ */
+
+
+public class TestShenandoahHeapRegionInformationEvent {
+    private final static String EVENT_NAME = EventNames.ShenandoahHeapRegionInformation;
+    public static void main(String[] args) throws Exception {
+        try (Recording recording = new Recording()) {
+            // activate the event we are interested in and start recording
+            for (EventType t : FlightRecorder.getFlightRecorder().getEventTypes()) {
+                System.out.println(t.getName());
+            }
+            recording.enable(EVENT_NAME);
+            recording.start();
+            recording.stop();
+
+            // Verify recording
+            List<RecordedEvent> events = Events.fromRecording(recording);
+            Events.hasEvents(events);
+            for (RecordedEvent event : events) {
+                Events.assertField(event, "index").notEqual(-1);
+                GCHelper.assertIsValidShenandoahHeapRegionState(Events.assertField(event, "state").getValue());
+                Events.assertField(event, "used").atMost(1L*1024*1024);
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/jdk/jfr/event/gc/detailed/TestShenandoahHeapRegionStateChangeEvent.java	Thu May 23 11:07:37 2019 +0100
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2019, Red Hat, Inc. All rights reserved.
+ *
+ * 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 jdk.jfr.event.gc.detailed;
+
+import java.nio.file.Paths;
+import java.time.Duration;
+import java.util.List;
+
+import jdk.jfr.Recording;
+import jdk.jfr.consumer.RecordedEvent;
+import jdk.test.lib.Asserts;
+import jdk.test.lib.jfr.EventNames;
+import jdk.test.lib.jfr.Events;
+import jdk.test.lib.jfr.GCHelper;
+
+/**
+ * @test
+ * @bug 8221507
+ * @requires vm.hasJFR & vm.gc.Shenandoah
+ * @key jfr
+ * @library /test/lib /test/jdk
+ * @run main/othervm  -Xmx32m -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:ShenandoahGarbageThreshold=1 jdk.jfr.event.gc.detailed.TestShenandoahHeapRegionStateChangeEvent
+ */
+
+public class TestShenandoahHeapRegionStateChangeEvent {
+    private final static String EVENT_NAME = EventNames.ShenandoahHeapRegionStateChange;
+
+    public static void main(String[] args) throws Exception {
+        try (Recording recording = new Recording()) {
+            // activate the event we are interested in and start recording
+            recording.enable(EVENT_NAME).withThreshold(Duration.ofMillis(0));
+            recording.start();
+
+            byte[][] array = new byte[1024][];
+            for (int i = 0; i < array.length; i++) {
+                array[i] = new byte[20 * 1024];
+            }
+            recording.stop();
+
+            // Verify recording
+            List<RecordedEvent> events = Events.fromRecording(recording);
+            Asserts.assertFalse(events.isEmpty(), "No events found");
+
+            for (RecordedEvent event : events) {
+                Events.assertField(event, "index").notEqual(-1);
+                GCHelper.assertIsValidShenandoahHeapRegionState(Events.assertField(event, "from").getValue());
+                GCHelper.assertIsValidShenandoahHeapRegionState(Events.assertField(event, "to").getValue());
+                Events.assertField(event, "used").atMost(1L*1024*1024);
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/jdk/nio/zipfs/InvalidZipHeaderTests.java	Thu May 23 11:07:37 2019 +0100
@@ -0,0 +1,129 @@
+/*
+ * Copyright (c) 2019, 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 org.testng.annotations.AfterClass;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.nio.file.FileSystem;
+import java.nio.file.FileSystems;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.List;
+import java.util.jar.JarEntry;
+import java.util.jar.JarOutputStream;
+import java.util.stream.Collectors;
+
+import static java.nio.file.Files.walk;
+import static org.testng.Assert.*;
+
+/**
+ * @test
+ * @bug 8222807
+ * @summary Validate that you can iterate a ZIP file with invalid ZIP header entries
+ * @modules jdk.zipfs
+ * @compile InvalidZipHeaderTests.java
+ * @run testng InvalidZipHeaderTests
+ * @run testng/othervm/java.security.policy=test.policy  InvalidZipHeaderTests
+ */
+public class InvalidZipHeaderTests {
+
+
+    // Name of Jar file used in tests
+    private static final String INVALID_JAR_FILE = "invalid.jar";
+
+    /**
+     * Create the JAR files used by the tests
+     */
+    @BeforeClass
+    public void setUp() throws Exception {
+        createInvalidJarFile();
+    }
+
+    /**
+     * Remove JAR files used by test as part of clean-up
+     */
+    @AfterClass
+    public void tearDown() throws Exception {
+        Files.deleteIfExists(Path.of(INVALID_JAR_FILE));
+    }
+
+
+    /**
+     * Validate that you can walk a ZIP archive with header entries
+     * such as "foo//"
+     */
+    @Test(dataProvider = "startPaths")
+    public void walkInvalidHeaderTest(String startPath, List<String> expectedPaths)
+            throws IOException {
+        try (FileSystem zipfs =
+                     FileSystems.newFileSystem(Path.of(INVALID_JAR_FILE))) {
+            List<String> result = walk(zipfs.getPath(startPath))
+                    .map(f -> f.toString()).collect(Collectors.toList());
+            assertTrue(result.equals(expectedPaths),
+                    String.format("Error: Expected paths not found when walking"
+                                    + "%s,  starting at %s%n", INVALID_JAR_FILE,
+                            startPath));
+        }
+    }
+
+
+    /**
+     * Starting Path for walking the ZIP archive and the expected paths to be returned
+     * when traversing the archive
+     */
+    @DataProvider(name = "startPaths")
+    public static Object[][] Name() {
+        return new Object[][]{
+
+                {"luckydog", List.of("luckydog", "luckydog/outfile.txt")},
+                {"/luckydog", List.of("/luckydog", "/luckydog/outfile.txt")},
+                {"./luckydog", List.of("./luckydog", "./luckydog/outfile.txt")},
+                {"", List.of( "", "luckydog", "luckydog/outfile.txt")},
+                {"/", List.of("/", "/luckydog", "/luckydog/outfile.txt")},
+                {".", List.of(".", "./luckydog", "./luckydog/outfile.txt")},
+                {"./", List.of(".", "./luckydog", "./luckydog/outfile.txt")}
+        };
+    }
+
+    /**
+     * Create a jar file with invalid CEN and LOC headers
+     * @throws IOException
+     */
+    static void createInvalidJarFile() throws IOException {
+
+        try (JarOutputStream jos = new JarOutputStream(new FileOutputStream(INVALID_JAR_FILE))) {
+            JarEntry je = new JarEntry("luckydog//");
+            jos.putNextEntry(je);
+            jos.closeEntry();
+            je = new JarEntry("luckydog//outfile.txt");
+            jos.putNextEntry(je);
+            jos.write("Tennis Anyone!!".getBytes());
+            jos.closeEntry();
+        }
+    }
+
+}
--- a/test/jdk/sun/management/jmxremote/bootstrap/GeneratePropertyPassword.sh	Fri May 17 13:21:44 2019 +0100
+++ b/test/jdk/sun/management/jmxremote/bootstrap/GeneratePropertyPassword.sh	Thu May 23 11:07:37 2019 +0100
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2003, 2019, 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
@@ -70,13 +70,11 @@
     if [ "$OS" = "Windows_NT" ]; then
         USER=`id -u -n`
         CACLS="$SystemRoot/system32/cacls.exe"
-        TEST_SRC=`cygpath ${TESTSRC}`
-        REVOKEALL="$TEST_SRC/../../windows/revokeall.exe"
-        if [ ! -f "$REVOKEALL" ] ; then
-            echo "$REVOKEALL missing"
+        REVOKEALL="$TESTNATIVEPATH/revokeall.exe"
+        if [ ! -x "$REVOKEALL" ] ; then
+            echo "$REVOKEALL doesn't exist or is not executable"
             exit 1
         fi
-        chmod ug+x $REVOKEALL
     fi
     ;;
 *)
--- a/test/jdk/sun/management/windows/README	Fri May 17 13:21:44 2019 +0100
+++ b/test/jdk/sun/management/windows/README	Thu May 23 11:07:37 2019 +0100
@@ -1,6 +1,29 @@
+/*
+ * Copyright (c) 2004, 2019, 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 directory contains the source and the binary version of a Windows 
-utility to remove all non-owner Access Control Entries from a given file.
+
+This directory contains the source of a Windows utility to remove all
+non-owner Access Control Entries from a given file.
 
 The tool is used by regression tests in the following directories :-
 
@@ -10,18 +33,3 @@
 be "secured" (meaning that only the owner should have access to the 
 files). 
 
-Both the source and the binary version are checked into SCCS. If
-you require to make changes to the tool then you need to Visual
-C++ to rebuild revokeall.exe after changing the source.
-
-To rebuild the tool you need to setup your environment (by
-calling the VC++ VCVARS32.BAT script), and then executing the 
-following command :-
-
-cl /mt revokeall.c advapi32.lib
-
-This will generate revokeall.exe.
-
-Note that a 32-bit version of revokeall.exe is checked into SCCS
-- this 32-bit application is also used when running on 64-bit
-versions of Windows (AMD64 and IA64).
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/sun/management/windows/exerevokeall.c	Thu May 23 11:07:37 2019 +0100
@@ -0,0 +1,463 @@
+/*
+ * Copyright (c) 2004, 2019, 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.
+ */
+
+#include <stdio.h>
+#include <windows.h>
+#include <malloc.h>
+#include <string.h>
+
+/*
+ * Simple Windows utility to remove all non-owner access to a given file.
+ */
+
+
+/*
+ * Access mask to represent any file access
+ */
+#define ANY_ACCESS (FILE_GENERIC_READ | FILE_GENERIC_WRITE | FILE_GENERIC_EXECUTE)
+
+
+/*
+ * Print error message to stderr
+ */
+static void printLastError(const char* msg) {
+    int len;
+    char buf[128];
+    DWORD errval;
+
+    buf[0] = '\0';
+    len = sizeof(buf);
+
+    errval = GetLastError();
+    if (errval != 0) {
+        int n = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS,
+                              NULL, errval,
+                              0, buf, len, NULL);
+        if (n > 3) {
+            /* Drop final '.', CR, LF */
+            if (buf[n - 1] == '\n') n--;
+            if (buf[n - 1] == '\r') n--;
+            if (buf[n - 1] == '.') n--;
+            buf[n] = '\0';
+        }
+    }
+
+    if (strlen(buf) > 0) {
+        fprintf(stderr, "revokeall %s: %s\n", msg, buf);
+    } else {
+        fprintf(stderr, "revokeall %s\n", msg);
+    }
+}
+
+
+
+/*
+ * Return a string that includes all the components of a given SID.
+ * See here for a description of the SID components :-
+ * http://msdn.microsoft.com/library/default.asp?url=/library/en-us/security/security/sid_components.asp
+ */
+static char *getTextualSid(SID* sid) {
+    SID_IDENTIFIER_AUTHORITY* sia;
+    DWORD i, count;
+    DWORD len;
+    char* name;
+
+    /*
+     * Get the identifier authority and the number of sub-authorities
+     */
+    sia = GetSidIdentifierAuthority(sid);
+    count = *GetSidSubAuthorityCount(sid);
+
+    /*
+     * Allocate buffer for the string - buffer is :-
+     * S-SID_REVISION- + identifierAuthority- + subauthorities- + NULL
+     */
+    len=(15 + 12 + (12 * count) + 1) * sizeof(char);
+    name = (char*)malloc(len);
+    if (name == NULL) {
+        return NULL;
+    }
+
+    // S-SID_REVISION
+    sprintf(name, "S-%lu-", SID_REVISION );
+
+    // Identifier authority
+    if ((sia->Value[0] != 0) || (sia->Value[1] != 0))
+    {
+        sprintf(name + strlen(name), "0x%02hx%02hx%02hx%02hx%02hx%02hx",
+                (USHORT)sia->Value[0],
+                (USHORT)sia->Value[1],
+                (USHORT)sia->Value[2],
+                (USHORT)sia->Value[3],
+                (USHORT)sia->Value[4],
+                (USHORT)sia->Value[5]);
+    }
+    else
+    {
+        sprintf(name + strlen(name), "%lu",
+                (ULONG)(sia->Value[5]      )   +
+                (ULONG)(sia->Value[4] <<  8)   +
+                (ULONG)(sia->Value[3] << 16)   +
+                (ULONG)(sia->Value[2] << 24)   );
+    }
+
+    // finally, the sub-authorities
+    for (i=0 ; i<count; i++) {
+        sprintf(name + strlen(name), "-%lu",
+                *GetSidSubAuthority(sid, i) );
+    }
+
+    return name;
+}
+
+/*
+ * Returns a string to represent the given security identifier (SID).
+ * If the account is known to the local computer then the account
+ * domain is returned. The format will be \\name or domain\\name depending
+ * on if the computer belongs to a domain.
+ * If the account name is not known then the textual representation of
+ * SID is returned -- eg: S-1-5-21-2818032319-470147023-1036452850-13037.
+ */
+static char *getSIDString(SID* sid) {
+    char domain[255];
+    char name[255];
+    DWORD domainLen = sizeof(domain);
+    DWORD nameLen = sizeof(name);
+    SID_NAME_USE use;
+
+    if(!IsValidSid(sid)) {
+        return strdup("<Invalid SID>");
+    }
+
+    if (LookupAccountSid(NULL, sid, name, &nameLen, domain, &domainLen, &use)) {
+        size_t len = strlen(name) + strlen(domain) + 3;
+        char* s = (char*)malloc(len);
+        if (s != NULL) {
+            strcpy(s, domain);
+            strcat(s, "\\\\");
+            strcat(s, name);
+        }
+        return s;
+    } else {
+        return getTextualSid(sid);
+    }
+}
+
+
+
+/*
+ * Returns 1 if the specified file is on a file system that supports
+ * persistent ACLs (On NTFS file systems returns true, on FAT32 file systems
+ * returns false), otherwise 0. Returns -1 if error.
+ */
+static int isSecuritySupported(const char* path) {
+    char* root;
+    char* p;
+    BOOL res;
+    DWORD dwMaxComponentLength;
+    DWORD dwFlags;
+    char fsName[128];
+    DWORD fsNameLength;
+
+    /*
+     * Get root directory. For UNCs the slash after the share name is required.
+     */
+    root = strdup(path);
+    if (*root == '\\') {
+        /*
+         * \\server\share\file ==> \\server\share\
+         */
+        int slashskip = 3;
+        p = root;
+        while ((*p == '\\') && (slashskip > 0)) {
+            char* p2;
+            p++;
+            p2 = strchr(p, '\\');
+            if ((p2 == NULL) || (*p2 != '\\')) {
+                free(root);
+                fprintf(stderr, "Malformed UNC");
+                return -1;
+            }
+            p = p2;
+            slashskip--;
+        }
+        if (slashskip != 0) {
+            free(root);
+            fprintf(stderr, "Malformed UNC");
+            return -1;
+        }
+        p++;
+        *p = '\0';
+
+    } else {
+        p = strchr(root, '\\');
+
+        /*
+         * Relative path so use current directory
+         */
+        if (p == NULL) {
+            free(root);
+            root = malloc(255);
+            if (GetCurrentDirectory(255, root) == 0) {
+                printLastError("GetCurrentDirectory failed");
+                return -1;
+            }
+            p = strchr(root, '\\');
+            if (p == NULL) {
+                fprintf(stderr, "GetCurrentDirectory doesn't include drive letter!!!!\n");
+                return -1;
+            }
+        }
+        p++;
+        *p = '\0';
+    }
+
+    /*
+     * Get the volume information - this gives us the file system file and
+     * also tells us if the file system supports persistent ACLs.
+     */
+    fsNameLength = sizeof(fsName)-1;
+    res = GetVolumeInformation(root,
+                               NULL,        // address of name of the volume, can be NULL
+                               0,           // length of volume name
+                               NULL,        // address of volume serial number, can be NULL
+                               &dwMaxComponentLength,
+                               &dwFlags,
+                               fsName,
+                               fsNameLength);
+    if (res == 0) {
+        printLastError("GetVolumeInformation failed");
+        free(root);
+        return -1;
+    }
+
+    free(root);
+    return (dwFlags & FS_PERSISTENT_ACLS) ? 1 : 0;
+}
+
+
+/*
+ * Returns the security descriptor for a file.
+ */
+static SECURITY_DESCRIPTOR* getFileSecurityDescriptor(const char* path) {
+    SECURITY_DESCRIPTOR* sd;
+    DWORD len = 0;
+    SECURITY_INFORMATION info =
+        OWNER_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION;
+
+    GetFileSecurity(path, info , 0, 0, &len);
+    if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
+        printLastError("GetFileSecurity failed");
+        return NULL;
+    }
+    sd = (SECURITY_DESCRIPTOR *)malloc(len);
+    if (sd == NULL) {
+        fprintf(stderr, "Out of memory");
+    } else {
+        if (!GetFileSecurity(path, info, sd, len, &len)) {
+            printLastError("GetFileSecurity failed");
+            free(sd);
+            return NULL;
+        }
+    }
+    return sd;
+}
+
+
+/*
+ * Revoke all access to the specific file
+ */
+static int revokeAll(const char* path) {
+    SECURITY_DESCRIPTOR* sd;
+    SID* owner;
+    ACL *acl;
+    BOOL defaulted, present;
+    ACL_SIZE_INFORMATION acl_size_info;
+    DWORD i, count;
+    char* str;
+
+    /*
+     * Get security descriptor for file; From security descriptor get the
+     * owner SID, and the DACL.
+     */
+    sd = getFileSecurityDescriptor(path);
+    if (sd == NULL) {
+        return -1;      /* error already reported */
+    }
+    if (!GetSecurityDescriptorOwner(sd, &owner, &defaulted)) {
+        printLastError("GetSecurityDescriptorOwner failed");
+        return -1;
+    }
+    str = getSIDString(owner);
+    if (str != NULL) {
+        printf("owner: %s\n", str);
+        free(str);
+    }
+    if (!GetSecurityDescriptorDacl(sd, &present, &acl, &defaulted)) {
+        printLastError("GetSecurityDescriptorDacl failed");
+        return -1;
+    }
+    if (!present) {
+        fprintf(stderr, "Security descriptor does not contain a DACL");
+        return -1;
+    }
+
+    /*
+     * If DACL is NULL there is no access to the file - we are done
+     */
+    if (acl == NULL) {
+        return 1;
+    }
+
+    /*
+     * Iterate over the ACEs. For each "allow" type check that the SID
+     * matches the owner - if not we remove the ACE from the ACL
+     */
+    if (!GetAclInformation(acl, (void *) &acl_size_info, sizeof(acl_size_info),
+                                  AclSizeInformation)) {
+        printLastError("GetAclInformation failed");
+        return -1;
+    }
+    count = acl_size_info.AceCount;
+    i = 0;
+    while (count > 0) {
+        void* ace;
+        ACCESS_ALLOWED_ACE *access;
+        SID* sid;
+        BOOL deleted;
+
+        if (!GetAce(acl, i, &ace)) {
+            printLastError("GetAce failed");
+            return -1;
+        }
+        if (((ACCESS_ALLOWED_ACE *)ace)->Header.AceType != ACCESS_ALLOWED_ACE_TYPE) {
+            i++;
+            count--;
+            continue;
+        }
+        access = (ACCESS_ALLOWED_ACE *)ace;
+        sid = (SID *) &access->SidStart;
+
+
+        deleted = FALSE;
+        if (!EqualSid(owner, sid)) {
+            /*
+             * If the ACE allows any access then the file then we
+             * delete it.
+             */
+            if (access->Mask & ANY_ACCESS) {
+                str = getSIDString(sid);
+                if (str != NULL) {
+                    printf("remove ALLOW %s\n", str);
+                    free(str);
+                }
+                if (DeleteAce(acl, i) == 0) {
+                    printLastError("DeleteAce failed");
+                    return -1;
+                }
+                deleted = TRUE;
+            }
+        }
+
+        if (!deleted) {
+            str = getSIDString(sid);
+            if (str != NULL) {
+                printf("ALLOW %s (access mask=%x)\n", str, access->Mask);
+                free(str);
+            }
+
+            /* onto the next ACE */
+            i++;
+        }
+        count--;
+    }
+
+    /*
+     * No changes - only owner has access
+     */
+    if (i == acl_size_info.AceCount) {
+        printf("No changes.\n");
+        return 1;
+    }
+
+    /*
+     * Create security descriptor and set its DACL to the version
+     * that we just edited
+     */
+    if (!InitializeSecurityDescriptor(sd, SECURITY_DESCRIPTOR_REVISION)) {
+        printLastError("InitializeSecurityDescriptor failed");
+        return -1;
+    }
+    if (!SetSecurityDescriptorDacl(sd, present, acl, defaulted)) {
+        printLastError("SetSecurityDescriptorDacl failed");
+        return -1;
+    }
+    if (!SetFileSecurity(path, DACL_SECURITY_INFORMATION, sd)) {
+        printLastError("SetFileSecurity failed");
+        return -1;
+    }
+
+    printf("File updated.\n");
+
+    return 1;
+}
+
+/*
+ * Convert slashes in the pathname to backslashes if needed.
+ */
+static char* convert_path(const char* p) {
+   int i = 0;
+   char* path = strdup(p);
+   while (p[i] != '\0') {
+       if (p[i] == '/') {
+           path[i] = '\\';
+       }
+       i++;
+   }
+   return path;
+}
+
+/*
+ * Usage: revokeall file
+ */
+int main( int argc, char *argv[])
+{
+    int rc;
+    const char* path;
+
+    if (argc != 2) {
+        fprintf(stderr, "Usage: %s file\n", argv[0]);
+        return -1;
+    }
+    path = convert_path(argv[1]);
+    printf("Revoking all non-owner access to %s\n", path);
+    rc = isSecuritySupported(path);
+    if (rc != 1) {
+        if (rc == 0) {
+            printf("File security not supported on this file system\n");
+        }
+        return rc;
+    } else {
+        return revokeAll(path);
+    }
+}
--- a/test/jdk/sun/management/windows/revokeall.c	Fri May 17 13:21:44 2019 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,462 +0,0 @@
-/*
- * Copyright (c) 2004, 2007, 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.
- */
-
-#include <stdio.h>
-#include <windows.h>
-#include <malloc.h>
-#include <string.h>
-
-/*
- * Simple Windows utility to remove all non-owner access to a given
- * file - suitable for NT/2000/XP only.
- */
-
-
-/*
- * Access mask to represent any file access
- */
-#define ANY_ACCESS (FILE_GENERIC_READ | FILE_GENERIC_WRITE | FILE_GENERIC_EXECUTE)
-
-
-/*
- * Print error message to stderr
- */
-static void printLastError(const char* msg) {
-    int len;
-    char buf[128];
-    DWORD errval;
-
-    buf[0] = '\0';
-    len = sizeof(buf);
-
-    errval = GetLastError();
-    if (errval != 0) {
-        int n = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS,
-                              NULL, errval,
-                              0, buf, len, NULL);
-        if (n > 3) {
-            /* Drop final '.', CR, LF */
-            if (buf[n - 1] == '\n') n--;
-            if (buf[n - 1] == '\r') n--;
-            if (buf[n - 1] == '.') n--;
-            buf[n] = '\0';
-        }
-    }
-
-    if (strlen(buf) > 0) {
-        fprintf(stderr, "revokeall %s: %s\n", msg, buf);
-    } else {
-        fprintf(stderr, "revokeall %s\n", msg);
-    }
-}
-
-
-
-/*
- * Return a string that includes all the components of a given SID.
- * See here for a description of the SID components :-
- * http://msdn.microsoft.com/library/default.asp?url=/library/en-us/security/security/sid_components.asp
- */
-static char *getTextualSid(SID* sid) {
-    SID_IDENTIFIER_AUTHORITY* sia;
-    DWORD i, count;
-    DWORD len;
-    char* name;
-
-    /*
-     * Get the identifier authority and the number of sub-authorities
-     */
-    sia = GetSidIdentifierAuthority(sid);
-    count = *GetSidSubAuthorityCount(sid);
-
-    /*
-     * Allocate buffer for the string - buffer is :-
-     * S-SID_REVISION- + identifierAuthority- + subauthorities- + NULL
-     */
-    len=(15 + 12 + (12 * count) + 1) * sizeof(char);
-    name = (char*)malloc(len);
-    if (name == NULL) {
-        return NULL;
-    }
-
-    // S-SID_REVISION
-    sprintf(name, "S-%lu-", SID_REVISION );
-
-    // Identifier authority
-    if ((sia->Value[0] != 0) || (sia->Value[1] != 0))
-    {
-        sprintf(name + strlen(name), "0x%02hx%02hx%02hx%02hx%02hx%02hx",
-                (USHORT)sia->Value[0],
-                (USHORT)sia->Value[1],
-                (USHORT)sia->Value[2],
-                (USHORT)sia->Value[3],
-                (USHORT)sia->Value[4],
-                (USHORT)sia->Value[5]);
-    }
-    else
-    {
-        sprintf(name + strlen(name), "%lu",
-                (ULONG)(sia->Value[5]      )   +
-                (ULONG)(sia->Value[4] <<  8)   +
-                (ULONG)(sia->Value[3] << 16)   +
-                (ULONG)(sia->Value[2] << 24)   );
-    }
-
-    // finally, the sub-authorities
-    for (i=0 ; i<count; i++) {
-        sprintf(name + strlen(name), "-%lu",
-                *GetSidSubAuthority(sid, i) );
-    }
-
-    return name;
-}
-
-/*
- * Returns a string to represent the given security identifier (SID).
- * If the account is known to the local computer then the account
- * domain is returned. The format will be \\name or domain\\name depending
- * on if the computer belongs to a domain.
- * If the account name is not known then the textual representation of
- * SID is returned -- eg: S-1-5-21-2818032319-470147023-1036452850-13037.
- */
-static char *getSIDString(SID* sid) {
-    char domain[255];
-    char name[255];
-    DWORD domainLen = sizeof(domain);
-    DWORD nameLen = sizeof(name);
-    SID_NAME_USE use;
-
-    if(!IsValidSid(sid)) {
-        return strdup("<Invalid SID>");
-    }
-
-    if (LookupAccountSid(NULL, sid, name, &nameLen, domain, &domainLen, &use)) {
-        int len = strlen(name) + strlen(domain) + 3;
-        char* s = (char*)malloc(len);
-        if (s != NULL) {
-            strcpy(s, domain);
-            strcat(s, "\\\\");
-            strcat(s, name);
-        }
-        return s;
-    } else {
-        return getTextualSid(sid);
-    }
-}
-
-
-
-/*
- * Returns 1 if the specified file is on a file system that supports
- * persistent ACLs (On NTFS file systems returns true, on FAT32 file systems
- * returns false), otherwise 0. Returns -1 if error.
- */
-static int isSecuritySupported(const char* path) {
-    char* root;
-    char* p;
-    BOOL res;
-    DWORD dwMaxComponentLength;
-    DWORD dwFlags;
-    char fsName[128];
-    DWORD fsNameLength;
-
-    /*
-     * Get root directory. For UNCs the slash after the share name is required.
-     */
-    root = strdup(path);
-    if (*root == '\\') {
-        /*
-         * \\server\share\file ==> \\server\share\
-         */
-        int slashskip = 3;
-        p = root;
-        while ((*p == '\\') && (slashskip > 0)) {
-            char* p2;
-            p++;
-            p2 = strchr(p, '\\');
-            if ((p2 == NULL) || (*p2 != '\\')) {
-                free(root);
-                fprintf(stderr, "Malformed UNC");
-                return -1;
-            }
-            p = p2;
-            slashskip--;
-        }
-        if (slashskip != 0) {
-            free(root);
-            fprintf(stderr, "Malformed UNC");
-            return -1;
-        }
-        p++;
-        *p = '\0';
-
-    } else {
-        p = strchr(root, '\\');
-
-        /*
-         * Relative path so use current directory
-         */
-        if (p == NULL) {
-            free(root);
-            root = malloc(255);
-            if (GetCurrentDirectory(255, root) == 0) {
-                printLastError("GetCurrentDirectory failed");
-                return -1;
-            }
-            p = strchr(root, '\\');
-            if (p == NULL) {
-                fprintf(stderr, "GetCurrentDirectory doesn't include drive letter!!!!\n");
-                return -1;
-            }
-        }
-        p++;
-        *p = '\0';
-    }
-
-    /*
-     * Get the volume information - this gives us the file system file and
-     * also tells us if the file system supports persistent ACLs.
-     */
-    fsNameLength = sizeof(fsName)-1;
-    res = GetVolumeInformation(root,
-                               NULL,        // address of name of the volume, can be NULL
-                               0,           // length of volume name
-                               NULL,        // address of volume serial number, can be NULL
-                               &dwMaxComponentLength,
-                               &dwFlags,
-                               fsName,
-                               fsNameLength);
-    if (res == 0) {
-        printLastError("GetVolumeInformation failed");
-        free(root);
-        return -1;
-    }
-
-    free(root);
-    return (dwFlags & FS_PERSISTENT_ACLS) ? 1 : 0;
-}
-
-
-/*
- * Returns the security descriptor for a file.
- */
-static SECURITY_DESCRIPTOR* getFileSecurityDescriptor(const char* path) {
-    SECURITY_DESCRIPTOR* sd;
-    DWORD len = 0;
-    SECURITY_INFORMATION info =
-        OWNER_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION;
-
-    GetFileSecurity(path, info , 0, 0, &len);
-    if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
-        printLastError("GetFileSecurity failed");
-        return NULL;
-    }
-    sd = (SECURITY_DESCRIPTOR *)malloc(len);
-    if (sd == NULL) {
-        fprintf(stderr, "Out of memory");
-    } else {
-        if (!GetFileSecurity(path, info, sd, len, &len)) {
-            printLastError("GetFileSecurity failed");
-            free(sd);
-            return NULL;
-        }
-    }
-    return sd;
-}
-
-
-/*
- * Revoke all access to the specific file
- */
-static int revokeAll(const char* path) {
-    SECURITY_DESCRIPTOR* sd;
-    SID* owner;
-    ACL *acl;
-    BOOL defaulted, present;
-    ACL_SIZE_INFORMATION acl_size_info;
-    DWORD i, count;
-    char* str;
-
-    /*
-     * Get security descriptor for file; From security descriptor get the
-     * owner SID, and the DACL.
-     */
-    sd = getFileSecurityDescriptor(path);
-    if (sd == NULL) {
-        return -1;      /* error already reported */
-    }
-    if (!GetSecurityDescriptorOwner(sd, &owner, &defaulted)) {
-        printLastError("GetSecurityDescriptorOwner failed");
-        return -1;
-    }
-    str = getSIDString(owner);
-    if (str != NULL) {
-        printf("owner: %s\n", str);
-        free(str);
-    }
-    if (!GetSecurityDescriptorDacl(sd, &present, &acl, &defaulted)) {
-        printLastError("GetSecurityDescriptorDacl failed");
-        return -1;
-    }
-    if (!present) {
-        fprintf(stderr, "Security descriptor does not contain a DACL");
-        return -1;
-    }
-
-    /*
-     * If DACL is NULL there is no access to the file - we are done
-     */
-    if (acl == NULL) {
-        return 1;
-    }
-
-    /*
-     * Iterate over the ACEs. For each "allow" type check that the SID
-     * matches the owner - if not we remove the ACE from the ACL
-     */
-    if (!GetAclInformation(acl, (void *) &acl_size_info, sizeof(acl_size_info),
-                                  AclSizeInformation)) {
-        printLastError("GetAclInformation failed");
-        return -1;
-    }
-    count = acl_size_info.AceCount;
-    i = 0;
-    while (count > 0) {
-        void* ace;
-        ACCESS_ALLOWED_ACE *access;
-        SID* sid;
-        BOOL deleted;
-
-        if (!GetAce(acl, i, &ace)) {
-            printLastError("GetAce failed");
-            return -1;
-        }
-        if (((ACCESS_ALLOWED_ACE *)ace)->Header.AceType != ACCESS_ALLOWED_ACE_TYPE) {
-            continue;
-        }
-        access = (ACCESS_ALLOWED_ACE *)ace;
-        sid = (SID *) &access->SidStart;
-
-
-        deleted = FALSE;
-        if (!EqualSid(owner, sid)) {
-            /*
-             * If the ACE allows any access then the file then we
-             * delete it.
-             */
-            if (access->Mask & ANY_ACCESS) {
-                str = getSIDString(sid);
-                if (str != NULL) {
-                    printf("remove ALLOW %s\n", str);
-                    free(str);
-                }
-                if (DeleteAce(acl, i) == 0) {
-                    printLastError("DeleteAce failed");
-                    return -1;
-                }
-                deleted = TRUE;
-            }
-        }
-
-        if (!deleted) {
-            str = getSIDString(sid);
-            if (str != NULL) {
-                printf("ALLOW %s (access mask=%x)\n", str, access->Mask);
-                free(str);
-            }
-
-            /* onto the next ACE */
-            i++;
-        }
-        count--;
-    }
-
-    /*
-     * No changes - only owner has access
-     */
-    if (i == acl_size_info.AceCount) {
-        printf("No changes.\n");
-        return 1;
-    }
-
-    /*
-     * Create security descriptor and set its DACL to the version
-     * that we just edited
-     */
-    if (!InitializeSecurityDescriptor(sd, SECURITY_DESCRIPTOR_REVISION)) {
-        printLastError("InitializeSecurityDescriptor failed");
-        return -1;
-    }
-    if (!SetSecurityDescriptorDacl(sd, present, acl, defaulted)) {
-        printLastError("SetSecurityDescriptorDacl failed");
-        return -1;
-    }
-    if (!SetFileSecurity(path, DACL_SECURITY_INFORMATION, sd)) {
-        printLastError("SetFileSecurity failed");
-        return -1;
-    }
-
-    printf("File updated.\n");
-
-    return 1;
-}
-
-/*
- * Convert slashes in the pathname to backslashes if needed.
- */
-static char* convert_path(const char* p) {
-   int i = 0;
-   char* path = strdup(p);
-   while (p[i] != '\0') {
-       if (p[i] == '/') {
-           path[i] = '\\';
-       }
-       i++;
-   }
-   return path;
-}
-
-/*
- * Usage: revokeall file
- */
-int main( int argc, char *argv[])
-{
-    int rc;
-    const char* path;
-
-    if (argc != 2) {
-        fprintf(stderr, "Usage: %s file\n", argv[0]);
-        return -1;
-    }
-    path = convert_path(argv[1]);
-    printf("Revoking all non-owner access to %s\n", path);
-    rc = isSecuritySupported(path);
-    if (rc != 1) {
-        if (rc == 0) {
-            printf("File security not supported on this file system\n");
-        }
-        return rc;
-    } else {
-        return revokeAll(path);
-    }
-}
Binary file test/jdk/sun/management/windows/revokeall.exe has changed
--- a/test/jdk/sun/net/InetAddress/nameservice/simple/DefaultCaching.java	Fri May 17 13:21:44 2019 +0100
+++ b/test/jdk/sun/net/InetAddress/nameservice/simple/DefaultCaching.java	Thu May 23 11:07:37 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2019, 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
@@ -33,98 +33,112 @@
 import java.io.FileWriter;
 import java.io.PrintWriter;
 import java.io.BufferedWriter;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import static java.nio.file.StandardCopyOption.REPLACE_EXISTING;
 
 public class DefaultCaching {
 
     public static void main(String args[]) throws Exception {
 
-        String hostsFileName = System.getProperty("test.src", ".") + "/DefaultCachingHosts";
+        String hostsFileNameSrc = System.getProperty("test.src", ".") + "/DefaultCachingHosts";
+        String hostsFileName = System.getProperty("user.dir", ".") + "/DefaultCachingHosts";
+        if (!hostsFileNameSrc.equals(hostsFileName)) {
+            Files.copy(Path.of(hostsFileNameSrc), Path.of(hostsFileName), REPLACE_EXISTING);
+            System.out.println("Host file created: " + hostsFileName);
+        }
         System.setProperty("jdk.net.hosts.file", hostsFileName);
         // initial mapping
         // name service needs to resolve this.
         addMappingToHostsFile("theclub", "129.156.220.219", hostsFileName, false);
 
-        test ("theclub", "129.156.220.219", true);      // lk: 1
-        test ("luster", "1.16.20.2", false);            // lk: 2
+        test("theclub", "129.156.220.219", true);      // lk: 1
+        test("luster", "1.16.20.2", false);            // lk: 2
 
         // name service now needs to know about luster
         addMappingToHostsFile("luster", "10.5.18.21", hostsFileName, true);
 
-        test ("luster", "1.16.20.2", false);            // lk: 2
-        sleep (10+1);
+        test("luster", "1.16.20.2", false);            // lk: 2
+        sleep(10+1);
         test("luster", "10.5.18.21", true, 3);          // lk: 3
-        sleep (5);
+        sleep(5);
 
         // new mapping for theclub and rewrite existing foo and luster mappings
         addMappingToHostsFile("theclub", "129.156.220.1", hostsFileName, false);
         addMappingToHostsFile("foo", "10.5.18.22", hostsFileName, true);
         addMappingToHostsFile("luster", "10.5.18.21", hostsFileName, true);
 
-        test ("theclub", "129.156.220.219", true, 3);
-        test ("luster", "10.5.18.21", true, 3);
-        test ("bar", "10.5.18.22", false, 4);
-        test ("foo", "10.5.18.22", true, 5);
+        test("theclub", "129.156.220.219", true, 3);
+        test("luster", "10.5.18.21", true, 3);
+        test("bar", "10.5.18.22", false, 4);
+        test("foo", "10.5.18.22", true, 5);
 
         // now delay to see if theclub has expired
-        sleep (5);
+        sleep(5);
 
-        test ("foo", "10.5.18.22", true, 5);
-        test ("theclub", "129.156.220.1", true, 6);
+        test("foo", "10.5.18.22", true, 5);
+        test("theclub", "129.156.220.1", true, 6);
 
-        sleep (11);
+        sleep(11);
         // now see if luster has expired
-        test ("luster", "10.5.18.21", true, 7);
-        test ("theclub", "129.156.220.1", true, 7);
+        test("luster", "10.5.18.21", true, 7);
+        test("theclub", "129.156.220.1", true, 7);
 
         // now delay to see if 3rd has expired
-        sleep (10+6);
+        sleep(10+6);
 
-        test ("theclub", "129.156.220.1", true, 8);
-        test ("luster", "10.5.18.21", true, 8);
-        test ("foo", "10.5.18.22", true, 9);
+        test("theclub", "129.156.220.1", true, 8);
+        test("luster", "10.5.18.21", true, 8);
+        test("foo", "10.5.18.22", true, 9);
     }
 
     /* throws RuntimeException if it fails */
 
-    static void test (String host, String address,
-                        boolean shouldSucceed, int count) {
-        test (host, address, shouldSucceed);
+    static void test(String host, String address,
+                     boolean shouldSucceed, int count) {
+        test(host, address, shouldSucceed);
     }
 
-    static void sleep (int seconds) {
+    static void sleep(int seconds) {
         try {
-            Thread.sleep (seconds * 1000);
+            Thread.sleep(seconds * 1000);
         } catch (InterruptedException e) {}
     }
 
-    static void test (String host, String address, boolean shouldSucceed) {
+    static void test(String host, String address, boolean shouldSucceed) {
         InetAddress addr = null;
         try {
-            addr = InetAddress.getByName (host);
+            addr = InetAddress.getByName(host);
             if (!shouldSucceed) {
-                throw new RuntimeException (host+":"+address+": should fail");
-
+                throw new RuntimeException(host+":"+address+": should fail (got "
+                                           + addr + ")");
             }
             if (!address.equals(addr.getHostAddress())) {
-                throw new RuntimeException(host+":"+address+": compare failed");
+                throw new RuntimeException(host+":"+address+": compare failed (found "
+                                           + addr + ")");
             }
+            System.out.println("test: " + host + "/" + address
+                               + " succeeded - got " + addr);
         } catch (UnknownHostException e) {
             if (shouldSucceed) {
                 throw new RuntimeException(host+":"+address+": should succeed");
+            } else {
+                System.out.println("test: " + host + "/" + address
+                                   + " succeeded - got expected " + e);
             }
         }
     }
 
 
-    private static void addMappingToHostsFile (String host,
-                                               String addr,
-                                               String hostsFileName,
-                                               boolean append)
+    private static void addMappingToHostsFile(String host,
+                                              String addr,
+                                              String hostsFileName,
+                                              boolean append)
                                              throws Exception {
         String mapping = addr + " " + host;
         try (PrintWriter hfPWriter = new PrintWriter(new BufferedWriter(
                 new FileWriter(hostsFileName, append)))) {
             hfPWriter.println(mapping);
-}
+        }
     }
 }
--- a/test/jdk/sun/net/ftp/B6427768.java	Fri May 17 13:21:44 2019 +0100
+++ b/test/jdk/sun/net/ftp/B6427768.java	Thu May 23 11:07:37 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2019, 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
@@ -105,13 +105,14 @@
     }
 
     public static void main(String[] args) throws IOException {
-        FtpServer server = new FtpServer(0);
+        InetAddress loopback = InetAddress.getLoopbackAddress();
+        FtpServer server = new FtpServer(loopback, 0);
         int port = server.getLocalPort();
         server.setFileSystemHandler(new MyFileSystemHandler("/"));
         server.setAuthHandler(new MyAuthHandler());
         server.start();
-        URL url = new URL("ftp://user:passwd@localhost:" + port + "/foo.txt");
-        URLConnection con = url.openConnection();
+        URL url = new URL("ftp://user:passwd@" + server.getAuthority() + "/foo.txt");
+        URLConnection con = url.openConnection(Proxy.NO_PROXY);
         // triggers the connection
         try {
             con.getInputStream();
--- a/test/jdk/sun/net/www/ftptest/FtpCommandHandler.java	Fri May 17 13:21:44 2019 +0100
+++ b/test/jdk/sun/net/www/ftptest/FtpCommandHandler.java	Thu May 23 11:07:37 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2019, 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
@@ -238,14 +238,14 @@
             return;
         }
         try {
-            if (pasv == null)
-                pasv = new ServerSocket(0);
-            int port = pasv.getLocalPort();
             InetAddress rAddress = cmd.getLocalAddress();
             if (rAddress instanceof Inet6Address) {
                 out.println("500 PASV illegal over IPv6 addresses, use EPSV.");
                 return;
             }
+            if (pasv == null)
+                pasv = new ServerSocket(0, 0, rAddress);
+            int port = pasv.getLocalPort();
             byte[] a = rAddress.getAddress();
             out.println("227 Entering Passive Mode " + a[0] + "," + a[1] + "," + a[2] + "," + a[3] + "," +
                         (port >> 8) + "," + (port & 0xff) );
@@ -266,7 +266,7 @@
         }
         try {
             if (pasv == null)
-                pasv = new ServerSocket(0);
+                pasv = new ServerSocket(0, 0, parent.getInetAddress());
             int port = pasv.getLocalPort();
             out.println("229 Entering Extended Passive Mode (|||" + port + "|)");
         } catch (IOException e) {
--- a/test/jdk/sun/net/www/ftptest/FtpServer.java	Fri May 17 13:21:44 2019 +0100
+++ b/test/jdk/sun/net/www/ftptest/FtpServer.java	Thu May 23 11:07:37 2019 +0100
@@ -110,8 +110,12 @@
         return listener.getLocalPort();
     }
 
+    public InetAddress getInetAddress() {
+        return listener.getInetAddress();
+    }
+
     public String getAuthority() {
-        InetAddress address = listener.getInetAddress();
+        InetAddress address = getInetAddress();
         String hostaddr = address.isAnyLocalAddress()
             ? "localhost" : address.getHostAddress();
         if (hostaddr.indexOf(':') > -1) {
--- a/test/jdk/sun/net/www/http/HttpClient/RetryPost.java	Fri May 17 13:21:44 2019 +0100
+++ b/test/jdk/sun/net/www/http/HttpClient/RetryPost.java	Thu May 23 11:07:37 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2019, 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
@@ -25,6 +25,7 @@
  * @test
  * @bug 6427251 6382788
  * @modules jdk.httpserver
+ * @library /test/lib
  * @run main RetryPost
  * @run main/othervm -Dsun.net.http.retryPost=false RetryPost noRetry
  * @summary HttpURLConnection automatically retries non-idempotent method POST
@@ -36,12 +37,14 @@
 import java.io.IOException;
 import java.io.OutputStream;
 import java.net.HttpURLConnection;
+import java.net.InetAddress;
 import java.net.InetSocketAddress;
 import java.net.Proxy;
 import java.net.SocketException;
 import java.net.URL;
 import java.util.concurrent.Executors;
 import java.util.concurrent.ExecutorService;
+import jdk.test.lib.net.URIBuilder;
 
 public class RetryPost
 {
@@ -70,7 +73,12 @@
     void doClient() {
         try {
             InetSocketAddress address = httpServer.getAddress();
-            URL url = new URL("http://localhost:" + address.getPort() + "/test/");
+            URL url = URIBuilder.newBuilder()
+                      .scheme("http")
+                      .host(address.getAddress())
+                      .port(address.getPort())
+                      .path("/test/")
+                      .toURLUnchecked();
             HttpURLConnection uc = (HttpURLConnection)url.openConnection(Proxy.NO_PROXY);
             uc.setDoOutput(true);
             uc.setRequestMethod("POST");
@@ -99,7 +107,8 @@
      * Http Server
      */
     public void startHttpServer(boolean shouldRetry) throws IOException {
-        httpServer = com.sun.net.httpserver.HttpServer.create(new InetSocketAddress(0), 0);
+        InetAddress loopback = InetAddress.getLoopbackAddress();
+        httpServer = com.sun.net.httpserver.HttpServer.create(new InetSocketAddress(loopback, 0), 0);
         httpHandler = new MyHandler(shouldRetry);
 
         HttpContext ctx = httpServer.createContext("/test/", httpHandler);
--- a/test/jdk/sun/net/www/http/KeepAliveCache/KeepAliveTimerThread.java	Fri May 17 13:21:44 2019 +0100
+++ b/test/jdk/sun/net/www/http/KeepAliveCache/KeepAliveTimerThread.java	Thu May 23 11:07:37 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2019, 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
@@ -26,6 +26,8 @@
  * @library /test/lib
  * @bug 4701299
  * @summary Keep-Alive-Timer thread management in KeepAliveCache causes memory leak
+ * @run main KeepAliveTimerThread
+ * @run main/othervm -Djava.net.preferIPv6Addresses=true KeepAliveTimerThread
  */
 
 import java.net.*;
@@ -103,8 +105,10 @@
 
 
     public static void main(String args[]) throws Exception {
-        ServerSocket ss = new ServerSocket(0);
-        Server s = new Server (ss);
+        InetAddress loopback = InetAddress.getLoopbackAddress();
+        ServerSocket ss = new ServerSocket();
+        ss.bind(new InetSocketAddress(loopback, 0));
+        Server s = new Server(ss);
         s.start();
 
         URL url = URIBuilder.newBuilder()
--- a/test/jdk/sun/net/www/http/KeepAliveStream/InfiniteLoop.java	Fri May 17 13:21:44 2019 +0100
+++ b/test/jdk/sun/net/www/http/KeepAliveStream/InfiniteLoop.java	Thu May 23 11:07:37 2019 +0100
@@ -26,6 +26,9 @@
  * @bug 8004863
  * @modules jdk.httpserver
  * @summary Checks for proper close code in KeepAliveStream
+ * @library /test/lib
+ * @run main InfiniteLoop
+ * @run main/othervm -Djava.net.preferIPv6Addresses=true InfiniteLoop
  */
 
 import com.sun.net.httpserver.HttpExchange;
@@ -35,10 +38,14 @@
 import java.io.IOException;
 import java.io.OutputStream;
 import java.net.HttpURLConnection;
+import java.net.InetAddress;
 import java.net.InetSocketAddress;
+import java.net.Proxy;
 import java.net.URL;
 import java.util.concurrent.Phaser;
 
+import jdk.test.lib.net.URIBuilder;
+
 // Racey test, will not always fail, but if it does then we have a problem.
 
 public class InfiniteLoop {
@@ -49,11 +56,16 @@
         server.start();
         try {
             InetSocketAddress address = server.getAddress();
-            URL url = new URL("http://localhost:" + address.getPort()
-                              + "/test/InfiniteLoop");
+            URL url = URIBuilder.newBuilder()
+                      .scheme("http")
+                      .host(server.getAddress().getAddress())
+                      .port(server.getAddress().getPort())
+                      .path("/test/InfiniteLoop")
+                      .toURL();
             final Phaser phaser = new Phaser(2);
             for (int i=0; i<10; i++) {
-                HttpURLConnection uc = (HttpURLConnection)url.openConnection();
+                HttpURLConnection uc = (HttpURLConnection)
+                    url.openConnection(Proxy.NO_PROXY);
                 final InputStream is = uc.getInputStream();
                 final Thread thread = new Thread() {
                     public void run() {
--- a/test/jdk/sun/net/www/protocol/http/B6369510.java	Fri May 17 13:21:44 2019 +0100
+++ b/test/jdk/sun/net/www/protocol/http/B6369510.java	Thu May 23 11:07:37 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2019, 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
@@ -59,11 +59,12 @@
     void doClient() {
         try {
             InetSocketAddress address = httpServer.getAddress();
-            String urlString = "http://" + InetAddress.getLocalHost().getHostName() + ":" + address.getPort() + "/test/";
+            String urlString = "http://" + InetAddress.getLocalHost().getHostName()
+                               + ":" + address.getPort() + "/test/";
             System.out.println("URL == " + urlString);
 
             // GET Request
-            URL url = new URL("http://" + InetAddress.getLocalHost().getHostName() + ":" + address.getPort() + "/test/");
+            URL url = new URL(urlString);
             HttpURLConnection uc = (HttpURLConnection)url.openConnection(Proxy.NO_PROXY);
             int resp = uc.getResponseCode();
             if (resp != 200)
@@ -95,7 +96,8 @@
      * Http Server
      */
     public void startHttpServer() throws IOException {
-        httpServer = com.sun.net.httpserver.HttpServer.create(new InetSocketAddress(0), 0);
+        InetAddress localhost = InetAddress.getLocalHost();
+        httpServer = HttpServer.create(new InetSocketAddress(localhost, 0), 0);
 
         // create HttpServer context
         HttpContext ctx = httpServer.createContext("/test/", new MyHandler());
--- a/test/jdk/sun/net/www/protocol/http/BasicLongCredentials.java	Fri May 17 13:21:44 2019 +0100
+++ b/test/jdk/sun/net/www/protocol/http/BasicLongCredentials.java	Thu May 23 11:07:37 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2019, 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
@@ -26,6 +26,9 @@
  * @bug 6947917
  * @modules jdk.httpserver
  * @summary  Error in basic authentication when user name and password are long
+ * @library /test/lib
+ * @run main BasicLongCredentials
+ * @run main/othervm -Djava.net.preferIPv6Addresses=true BasicLongCredentials
  */
 
 import com.sun.net.httpserver.BasicAuthenticator;
@@ -37,11 +40,15 @@
 import java.io.InputStream;
 import java.io.IOException;
 import java.net.Authenticator;
+import java.net.InetAddress;
 import java.net.InetSocketAddress;
 import java.net.PasswordAuthentication;
+import java.net.Proxy;
 import java.net.HttpURLConnection;
 import java.net.URL;
 
+import jdk.test.lib.net.URIBuilder;
+
 public class BasicLongCredentials {
 
     static final String USERNAME = "ThisIsMyReallyReallyReallyReallyReallyReally" +
@@ -51,7 +58,8 @@
     static final String REALM = "foobar@test.realm";
 
     public static void main (String[] args) throws Exception {
-        HttpServer server = HttpServer.create(new InetSocketAddress(0), 0);
+        InetAddress loopback = InetAddress.getLoopbackAddress();
+        HttpServer server = HttpServer.create(new InetSocketAddress(loopback, 0), 0);
         try {
             Handler handler = new Handler();
             HttpContext ctx = server.createContext("/test", handler);
@@ -66,8 +74,13 @@
 
             Authenticator.setDefault(new MyAuthenticator());
 
-            URL url = new URL("http://localhost:"+server.getAddress().getPort()+"/test/");
-            HttpURLConnection urlc = (HttpURLConnection)url.openConnection();
+            URL url = URIBuilder.newBuilder()
+                      .scheme("http")
+                      .host(server.getAddress().getAddress())
+                      .port(server.getAddress().getPort())
+                      .path("/test/")
+                      .toURL();
+            HttpURLConnection urlc = (HttpURLConnection)url.openConnection(Proxy.NO_PROXY);
             InputStream is = urlc.getInputStream();
             int c = 0;
             while (is.read()!= -1) { c ++; }
--- a/test/jdk/sun/net/www/protocol/http/NTLMTest.java	Fri May 17 13:21:44 2019 +0100
+++ b/test/jdk/sun/net/www/protocol/http/NTLMTest.java	Thu May 23 11:07:37 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 2019, 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
@@ -25,6 +25,7 @@
  * @test
  * @bug 6520665 6357133
  * @modules java.base/sun.net.www
+ * @library /test/lib
  * @run main/othervm NTLMTest
  * @summary 6520665 & 6357133: NTLM authentication issues.
  */
@@ -32,35 +33,41 @@
 import java.net.*;
 import java.io.*;
 import sun.net.www.MessageHeader;
+import jdk.test.lib.net.URIBuilder;
 
 public class NTLMTest
 {
-    public static void main(String[] args) {
+    public static void main(String[] args) throws Exception {
         Authenticator.setDefault(new NullAuthenticator());
 
         try {
+            InetAddress loopback = InetAddress.getLoopbackAddress();
+
             // Test with direct connection.
-            ServerSocket serverSS = new ServerSocket(0);
-            startServer(serverSS, false);
-            runClient(Proxy.NO_PROXY, serverSS.getLocalPort());
-
+            try (NTLMServer server = startServer(new ServerSocket(0, 0, loopback), false)) {
+                runClient(Proxy.NO_PROXY, server.getLocalPort());
+            }
             // Test with proxy.
-            serverSS = new ServerSocket(0);
-            startServer(serverSS, true /*proxy*/);
-            SocketAddress proxyAddr = new InetSocketAddress("localhost", serverSS.getLocalPort());
-            runClient(new Proxy(java.net.Proxy.Type.HTTP, proxyAddr), 8888);
-
+            try (NTLMServer server =
+                    startServer(new ServerSocket(0, 0, loopback), true /*proxy*/)) {
+                SocketAddress proxyAddr = new InetSocketAddress(loopback, server.getLocalPort());
+                runClient(new Proxy(java.net.Proxy.Type.HTTP, proxyAddr), 8888);
+            }
         } catch (IOException e) {
-            e.printStackTrace();
+            throw e;
         }
     }
 
     static void runClient(Proxy proxy, int serverPort) {
         try {
-            String urlStr = "http://localhost:" + serverPort + "/";
-            URL url = new URL(urlStr);
+            URL url = URIBuilder.newBuilder()
+                      .scheme("http")
+                      .loopback()
+                      .port(serverPort)
+                      .path("/")
+                      .toURLUnchecked();
             HttpURLConnection uc = (HttpURLConnection) url.openConnection(proxy);
-            uc.getInputStream();
+            uc.getInputStream().readAllBytes();
 
         } catch (ProtocolException e) {
             /* java.net.ProtocolException: Server redirected too many  times (20) */
@@ -70,6 +77,7 @@
              * returned HTTP response code: 401 for URL: ..."
              */
             //ioe.printStackTrace();
+            System.out.println("Got expected " + ioe);
         } catch (NullPointerException npe) {
             throw new RuntimeException("Failed: NPE thrown ", npe);
         }
@@ -93,34 +101,56 @@
                 "Content-Length: 0\r\n" +
                 "Proxy-Authenticate: NTLM TlRMTVNTUAACAAAAAAAAACgAAAABggAAU3J2Tm9uY2UAAAAAAAAAAA==\r\n\r\n"};
 
-    static void startServer(ServerSocket serverSS, boolean proxy) {
-        final ServerSocket ss = serverSS;
-        final boolean isProxy = proxy;
+    static class NTLMServer extends Thread implements AutoCloseable {
+        final ServerSocket ss;
+        final boolean isProxy;
+        volatile boolean closed;
+
+        NTLMServer(ServerSocket serverSS, boolean proxy) {
+            super();
+            setDaemon(true);
+            ss = serverSS;
+            isProxy = proxy;
+        }
+
+       public int getLocalPort() { return ss.getLocalPort(); }
 
-        Thread thread = new Thread(new Runnable() {
-            public void run() {
-                boolean doing2ndStageNTLM = false;
-                while (true) {
-                    try {
-                        Socket s = ss.accept();
-                        if (!doing2ndStageNTLM) {
-                            handleConnection(s, isProxy ? proxyResp : serverResp, 0, 1);
-                            doing2ndStageNTLM = true;
-                        } else {
-                            handleConnection(s, isProxy ? proxyResp : serverResp, 1, 2);
-                            doing2ndStageNTLM = false;
-                        }
-                        connectionCount++;
-                        //System.out.println("connectionCount = " + connectionCount);
+        @Override
+        public void run() {
+            boolean doing2ndStageNTLM = false;
+            while (!closed) {
+                try {
+                    Socket s = ss.accept();
+                    if (!doing2ndStageNTLM) {
+                        handleConnection(s, isProxy ? proxyResp : serverResp, 0, 1);
+                        doing2ndStageNTLM = true;
+                    } else {
+                        handleConnection(s, isProxy ? proxyResp : serverResp, 1, 2);
+                        doing2ndStageNTLM = false;
+                    }
+                    connectionCount++;
+                    //System.out.println("connectionCount = " + connectionCount);
+                } catch (IOException ioe) {
+                    if (!closed) ioe.printStackTrace();
+                }
+            }
+        }
 
-                    } catch (IOException ioe) {
-                        ioe.printStackTrace();
-                    }
-                }
-            } });
-            thread.setDaemon(true);
-            thread.start();
+        @Override
+        public void close() {
+           if (closed) return;
+           synchronized(this) {
+               if (closed) return;
+               closed = true;
+           }
+           try { ss.close(); } catch (IOException x) { };
+        }
+    }
 
+    public static NTLMServer startServer(ServerSocket serverSS, boolean proxy) {
+        NTLMServer server = new NTLMServer(serverSS, proxy);
+        server.start();
+        return server;
     }
 
     static int connectionCount = 0;
--- a/test/jdk/sun/net/www/protocol/https/HttpsURLConnection/CookieHttpsClientTest.java	Fri May 17 13:21:44 2019 +0100
+++ b/test/jdk/sun/net/www/protocol/https/HttpsURLConnection/CookieHttpsClientTest.java	Thu May 23 11:07:37 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2019, 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
@@ -29,21 +29,25 @@
  * @bug 7129083
  * @summary Cookiemanager does not store cookies if url is read
  *          before setting cookiemanager
+ * @library /test/lib
  * @run main/othervm CookieHttpsClientTest
  */
 
 import java.net.CookieHandler;
 import java.net.CookieManager;
 import java.net.CookiePolicy;
+import java.net.InetAddress;
 import java.net.URL;
 import java.io.InputStream;
 import java.io.IOException;
 import javax.net.ssl.HostnameVerifier;
 import javax.net.ssl.HttpsURLConnection;
+import javax.net.ssl.SSLHandshakeException;
 import javax.net.ssl.SSLServerSocket;
 import javax.net.ssl.SSLServerSocketFactory;
 import javax.net.ssl.SSLSession;
 import javax.net.ssl.SSLSocket;
+import jdk.test.lib.net.URIBuilder;
 
 public class CookieHttpsClientTest {
     static final int TIMEOUT = 10 * 1000;
@@ -91,10 +95,11 @@
      * to avoid infinite hangs.
      */
     void doServerSide() throws Exception {
+        InetAddress loopback = InetAddress.getLoopbackAddress();
         SSLServerSocketFactory sslssf =
             (SSLServerSocketFactory) SSLServerSocketFactory.getDefault();
         SSLServerSocket sslServerSocket =
-            (SSLServerSocket) sslssf.createServerSocket(serverPort);
+            (SSLServerSocket) sslssf.createServerSocket(serverPort, 0, loopback);
         serverPort = sslServerSocket.getLocalPort();
 
         /*
@@ -137,10 +142,17 @@
                 return true;
             }});
 
-        URL url = new URL("https://localhost:" + serverPort +"/");
+        URL url = URIBuilder.newBuilder()
+                  .scheme("https")
+                  .loopback()
+                  .port(serverPort)
+                  .path("/")
+                  .toURL();
+
+        System.out.println("Client ready to connect to: " + url);
 
         // Run without a CookieHandler first
-        InputStream in = url.openConnection().getInputStream();
+        InputStream in = url.openConnection(java.net.Proxy.NO_PROXY).getInputStream();
         while (in.read() != -1);  // read response body so connection can be reused
 
         // Set a CookeHandler and retest using the HttpClient from the KAC
@@ -183,6 +195,10 @@
     volatile Exception serverException = null;
     volatile Exception clientException = null;
 
+    private boolean sslConnectionFailed() {
+        return clientException instanceof SSLHandshakeException;
+    }
+
     public static void main(String args[]) throws Exception {
         String keyFilename =
             System.getProperty("test.src", ".") + "/" + pathToStores +
@@ -229,7 +245,11 @@
          */
         if (separateServerThread) {
             if (serverThread != null) {
-                serverThread.join();
+                // don't join the server thread if the
+                // client failed to connect
+                if (!sslConnectionFailed()) {
+                    serverThread.join();
+                }
             }
         } else {
             if (clientThread != null) {
@@ -259,7 +279,7 @@
          */
         if ((local != null) && (remote != null)) {
             // If both failed, return the curthread's exception.
-            local.initCause(remote);
+            local.addSuppressed(remote);
             exception = local;
         } else if (local != null) {
             exception = local;
@@ -274,7 +294,7 @@
          * output it.
          */
         if (exception != null) {
-            if (exception != startException) {
+            if (exception != startException && startException != null) {
                 exception.addSuppressed(startException);
             }
             throw exception;
@@ -323,7 +343,7 @@
                         /*
                          * Our client thread just died.
                          */
-                        System.err.println("Client died...");
+                        System.err.println("Client died: " + e);
                         clientException = e;
                     }
                 }
@@ -333,6 +353,7 @@
             try {
                 doClientSide();
             } catch (Exception e) {
+                System.err.println("Client died: " + e);
                 clientException = e;
             }
         }
--- a/test/jdk/sun/net/www/protocol/https/HttpsURLConnection/HttpsPost.java	Fri May 17 13:21:44 2019 +0100
+++ b/test/jdk/sun/net/www/protocol/https/HttpsURLConnection/HttpsPost.java	Thu May 23 11:07:37 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2019, 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
@@ -26,7 +26,9 @@
  * @bug 4423074
  * @summary Need to rebase all the duplicated classes from Merlin.
  *          This test will check out http POST
+ * @library /test/lib
  * @run main/othervm HttpsPost
+ * @run main/othervm -Djava.net.preferIPv6Addresses=true HttpsPost
  *
  *     SunJSSE does not support dynamic system properties, no way to re-use
  *     system properties in samevm/agentvm mode.
@@ -35,6 +37,7 @@
 import java.io.*;
 import java.net.*;
 import javax.net.ssl.*;
+import jdk.test.lib.net.URIBuilder;
 
 public class HttpsPost {
 
@@ -95,12 +98,16 @@
      * to avoid infinite hangs.
      */
     void doServerSide() throws Exception {
+        InetAddress loopback = InetAddress.getLoopbackAddress();
         SSLServerSocketFactory sslssf =
             (SSLServerSocketFactory) SSLServerSocketFactory.getDefault();
         SSLServerSocket sslServerSocket =
-            (SSLServerSocket) sslssf.createServerSocket(serverPort);
+            (SSLServerSocket) sslssf.createServerSocket(serverPort, 0, loopback);
         serverPort = sslServerSocket.getLocalPort();
 
+        System.out.println("Starting server at: "
+                            +  sslServerSocket.getInetAddress()
+                            + ":" + serverPort);
         /*
          * Signal Client, we're ready for his connect.
          */
@@ -155,10 +162,15 @@
             }
 
             // Send HTTP POST request to server
-            URL url = new URL("https://localhost:"+serverPort);
+            URL url = URIBuilder.newBuilder()
+                      .scheme("https")
+                      .loopback()
+                      .port(serverPort)
+                      .toURL();
 
+            System.out.println("Client connecting to: " + url);
             HttpsURLConnection.setDefaultHostnameVerifier(new NameVerifier());
-            HttpsURLConnection http = (HttpsURLConnection)url.openConnection();
+            HttpsURLConnection http = (HttpsURLConnection)url.openConnection(Proxy.NO_PROXY);
             http.setDoOutput(true);
 
             http.setRequestMethod("POST");
--- a/test/jdk/sun/net/www/protocol/https/HttpsURLConnection/PostThruProxy.java	Fri May 17 13:21:44 2019 +0100
+++ b/test/jdk/sun/net/www/protocol/https/HttpsURLConnection/PostThruProxy.java	Thu May 23 11:07:37 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2019, 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
@@ -27,8 +27,7 @@
 import javax.net.*;
 import javax.net.ssl.*;
 
-import jdk.test.lib.process.OutputAnalyzer;
-import jdk.test.lib.process.ProcessTools;
+import jdk.test.lib.net.URIBuilder;
 
 /*
  * @test
@@ -39,12 +38,6 @@
  *          that serves http POST method requests in secure channel, and a client
  *          that makes https POST request through a proxy.
  * @library /test/lib
- * @build jdk.test.lib.Utils
- *        jdk.test.lib.Asserts
- *        jdk.test.lib.JDKToolFinder
- *        jdk.test.lib.JDKToolLauncher
- *        jdk.test.lib.Platform
- *        jdk.test.lib.process.*
  * @compile OriginServer.java ProxyTunnelServer.java
  * @run main/othervm PostThruProxy
  */
@@ -62,6 +55,9 @@
     static String passwd = "passphrase";
 
     private static int serverPort = 0;
+    private static ProxyTunnelServer pserver;
+    private static TestServer server;
+    static final String RESPONSE_MSG = "Https POST thru proxy is successful";
 
     /*
      * The TestServer implements a OriginServer that
@@ -79,8 +75,7 @@
          * @return bytes for the data in the response
          */
         public byte[] getBytes() {
-            return "Https POST thru proxy is successful".
-                        getBytes();
+            return RESPONSE_MSG.getBytes();
         }
     }
 
@@ -88,6 +83,7 @@
      * Main method to create the server and client
      */
     public static void main(String args[]) throws Exception {
+
         String keyFilename = TEST_SRC + "/" + pathToStores + "/" + keyStoreFile;
         String trustFilename = TEST_SRC + "/" + pathToStores + "/"
                 + trustStoreFile;
@@ -97,16 +93,18 @@
         System.setProperty("javax.net.ssl.trustStore", trustFilename);
         System.setProperty("javax.net.ssl.trustStorePassword", passwd);
 
+        InetAddress loopback = InetAddress.getLoopbackAddress();
         boolean useSSL = true;
         /*
          * setup the server
          */
         try {
             ServerSocketFactory ssf = getServerSocketFactory(useSSL);
-            ServerSocket ss = ssf.createServerSocket(serverPort);
+            ServerSocket ss = ssf.createServerSocket(serverPort, 0, loopback);
             ss.setSoTimeout(TIMEOUT);  // 30 seconds
             serverPort = ss.getLocalPort();
-            new TestServer(ss);
+            server = new TestServer(ss);
+            System.out.println("Server started at: " + ss);
         } catch (Exception e) {
             System.out.println("Server side failed:" +
                                 e.getMessage());
@@ -120,6 +118,12 @@
                                 e.getMessage());
             throw e;
         }
+        long connectCount = pserver.getConnectCount();
+        if (connectCount == 0) {
+            throw new AssertionError("Proxy was not used!");
+        } else {
+            System.out.println("Proxy CONNECT count: " + connectCount);
+        }
     }
 
     private static ServerSocketFactory getServerSocketFactory
@@ -162,9 +166,15 @@
              */
             HttpsURLConnection.setDefaultHostnameVerifier(
                                           new NameVerifier());
-            URL url = new URL("https://" + getHostname() +":" + serverPort);
+            URL url = URIBuilder.newBuilder()
+                      .scheme("https")
+                      .loopback()
+                      .port(serverPort)
+                      .toURL();
 
             Proxy p = new Proxy(Proxy.Type.HTTP, pAddr);
+            System.out.println("Client connecting to: " + url);
+            System.out.println("Through proxy: " + pAddr);
             HttpsURLConnection https = (HttpsURLConnection)url.openConnection(p);
             https.setConnectTimeout(TIMEOUT);
             https.setReadTimeout(TIMEOUT);
@@ -185,9 +195,15 @@
                                     new InputStreamReader(
                                     https.getInputStream()));
                String inputLine;
-               while ((inputLine = in.readLine()) != null)
+               boolean msgFound = false;
+               while ((inputLine = in.readLine()) != null) {
                     System.out.println("Client received: " + inputLine);
+                    if (inputLine.contains(RESPONSE_MSG)) msgFound = true;
+               }
                in.close();
+               if (!msgFound) {
+                   throw new RuntimeException("POST message not found.");
+               }
             } catch (SSLException e) {
                 if (ps != null)
                     ps.close();
@@ -208,20 +224,13 @@
     }
 
     static SocketAddress setupProxy() throws IOException {
-        ProxyTunnelServer pserver = new ProxyTunnelServer();
+        InetAddress loopback = InetAddress.getLoopbackAddress();
+        pserver = new ProxyTunnelServer(loopback);
 
         // disable proxy authentication
         pserver.needUserAuth(false);
         pserver.start();
-        return new InetSocketAddress("localhost", pserver.getPort());
+        return new InetSocketAddress(loopback, pserver.getPort());
     }
 
-    private static String getHostname() {
-        try {
-            OutputAnalyzer oa = ProcessTools.executeCommand("hostname");
-            return oa.getOutput().trim();
-        } catch (Throwable e) {
-            throw new RuntimeException("Get hostname failed.", e);
-        }
-    }
 }
--- a/test/jdk/sun/net/www/protocol/https/HttpsURLConnection/PostThruProxyWithAuth.java	Fri May 17 13:21:44 2019 +0100
+++ b/test/jdk/sun/net/www/protocol/https/HttpsURLConnection/PostThruProxyWithAuth.java	Thu May 23 11:07:37 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2019, 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
@@ -29,6 +29,7 @@
 
 import jdk.test.lib.process.OutputAnalyzer;
 import jdk.test.lib.process.ProcessTools;
+import jdk.test.lib.net.URIBuilder;
 
 /*
  * @test
@@ -47,6 +48,8 @@
  *        jdk.test.lib.process.*
  * @compile OriginServer.java ProxyTunnelServer.java
  * @run main/othervm -Djdk.http.auth.tunneling.disabledSchemes= PostThruProxyWithAuth
+ * @run main/othervm -Djava.net.preferIPv6Addresses=true
+                     -Djdk.http.auth.tunneling.disabledSchemes= PostThruProxyWithAuth
  */
 public class PostThruProxyWithAuth {
 
@@ -62,6 +65,11 @@
     static String passwd = "passphrase";
 
     volatile private static int serverPort = 0;
+    private static ProxyTunnelServer pserver;
+    private static TestServer server;
+
+    static final String RESPONSE_MSG =
+        "Https POST thru proxy is successful with proxy authentication";
 
     /*
      * The TestServer implements a OriginServer that
@@ -79,9 +87,7 @@
          * @return bytes for the data in the response
          */
         public byte[] getBytes() {
-            return
-                "Https POST thru proxy is successful with proxy authentication".
-                getBytes();
+            return RESPONSE_MSG.getBytes();
         }
     }
 
@@ -103,11 +109,13 @@
          * setup the server
          */
         try {
+            InetAddress localhost = InetAddress.getLocalHost();
             ServerSocketFactory ssf = getServerSocketFactory(useSSL);
-            ServerSocket ss = ssf.createServerSocket(serverPort);
+            ServerSocket ss = ssf.createServerSocket(serverPort, 0, localhost);
             ss.setSoTimeout(TIMEOUT);  // 30 seconds
             serverPort = ss.getLocalPort();
-            new TestServer(ss);
+            server = new TestServer(ss);
+            System.out.println("Server started at: " + ss);
         } catch (Exception e) {
             System.out.println("Server side failed:" +
                                 e.getMessage());
@@ -120,7 +128,13 @@
             System.out.println("Client side failed: " +
                                 e.getMessage());
             throw e;
-          }
+        }
+        long connectCount = pserver.getConnectCount();
+        if (connectCount == 0) {
+            throw new AssertionError("Proxy was not used!");
+        } else {
+            System.out.println("Proxy CONNECT count: " + connectCount);
+        }
     }
 
     private static ServerSocketFactory getServerSocketFactory
@@ -160,9 +174,16 @@
          */
         HttpsURLConnection.setDefaultHostnameVerifier(
                                       new NameVerifier());
-        URL url = new URL("https://" + getHostname() + ":" + serverPort);
+
+        URL url = URIBuilder.newBuilder()
+                      .scheme("https")
+                      .host(getHostname())
+                      .port(serverPort)
+                      .toURL();
 
         Proxy p = new Proxy(Proxy.Type.HTTP, pAddr);
+        System.out.println("Client connecting to: " + url);
+        System.out.println("Through proxy: " + pAddr);
         HttpsURLConnection https = (HttpsURLConnection)url.openConnection(p);
         https.setConnectTimeout(TIMEOUT);
         https.setReadTimeout(TIMEOUT);
@@ -182,9 +203,15 @@
                                 new InputStreamReader(
                                 https.getInputStream()));
            String inputLine;
-           while ((inputLine = in.readLine()) != null)
-                 System.out.println("Client received: " + inputLine);
+           boolean msgFound = false;
+           while ((inputLine = in.readLine()) != null) {
+                System.out.println("Client received: " + inputLine);
+                if (inputLine.contains(RESPONSE_MSG)) msgFound = true;
+           }
            in.close();
+           if (!msgFound) {
+               throw new RuntimeException("POST message not found.");
+           }
         } catch (SSLException e) {
             if (ps != null)
                 ps.close();
@@ -202,7 +229,9 @@
     }
 
     static SocketAddress setupProxy() throws IOException {
-        ProxyTunnelServer pserver = new ProxyTunnelServer();
+
+        InetAddress localhost = InetAddress.getLocalHost();
+        pserver = new ProxyTunnelServer(localhost);
 
         /*
          * register a system wide authenticator and setup the proxy for
@@ -216,7 +245,7 @@
 
         pserver.start();
 
-        return new InetSocketAddress("localhost", pserver.getPort());
+        return new InetSocketAddress(localhost, pserver.getPort());
     }
 
     public static class TestAuthenticator extends Authenticator {
--- a/test/jdk/sun/net/www/protocol/https/HttpsURLConnection/ProxyTunnelServer.java	Fri May 17 13:21:44 2019 +0100
+++ b/test/jdk/sun/net/www/protocol/https/HttpsURLConnection/ProxyTunnelServer.java	Thu May 23 11:07:37 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2019, 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
@@ -63,11 +63,23 @@
      */
     static boolean needAuth = false;
 
+    volatile long connectCount;
+
     public ProxyTunnelServer() throws IOException {
         if (ss == null) {
             ss = (ServerSocket) ServerSocketFactory.getDefault()
                     .createServerSocket(0);
             ss.setSoTimeout(TIMEOUT);
+            System.out.println("Proxy server created: " + ss);
+        }
+    }
+
+    public ProxyTunnelServer(InetAddress address) throws IOException {
+        if (ss == null) {
+            ss = (ServerSocket) ServerSocketFactory.getDefault()
+                    .createServerSocket(0, 0, address);
+            ss.setSoTimeout(TIMEOUT);
+            System.out.println("Proxy server created: " + ss);
         }
     }
 
@@ -86,7 +98,9 @@
 
     public void run() {
         try {
+            System.out.println("Proxy server listening at: " + ss);
             clientSocket = ss.accept();
+            System.out.println("Proxy server accepted connection: " + clientSocket);
             processRequests();
         } catch (SocketTimeoutException e) {
             System.out.println(
@@ -101,7 +115,9 @@
                 System.out.println("ProxyServer close error: " + excep);
                 excep.printStackTrace();
             }
-          }
+         } finally {
+            System.out.println("Proxy server: request served");
+         }
     }
 
     /*
@@ -118,6 +134,7 @@
         String statusLine = mheader.getValue(0);
 
         if (statusLine.startsWith("CONNECT")) {
+            synchronized(this) { connectCount++; }
             // retrieve the host and port info from the status-line
             retrieveConnectInfo(statusLine);
             if (needAuth) {
@@ -154,6 +171,10 @@
         }
     }
 
+    public long getConnectCount() {
+        return connectCount;
+    }
+
     private void respondForConnect(boolean needAuth) throws Exception {
 
         OutputStream out = clientSocket.getOutputStream();
@@ -273,13 +294,19 @@
             endi = connectStr.lastIndexOf(' ');
             connectInfo = connectStr.substring(starti+1, endi).trim();
             // retrieve server name and port
-            endi = connectInfo.indexOf(':');
-            serverName = connectInfo.substring(0, endi);
+            if (connectInfo.charAt(0) == '[') {
+                 endi = connectInfo.indexOf(']');
+                 serverName = connectInfo.substring(1, endi++);
+                 assert connectInfo.charAt(endi) == ':' : "Expected [IPv6]:port";
+            } else {
+                 endi = connectInfo.indexOf(':');
+                 serverName = connectInfo.substring(0, endi);
+            }
             serverPort = Integer.parseInt(connectInfo.substring(endi+1));
         } catch (Exception e) {
             throw new IOException("Proxy recieved a request: "
                                         + connectStr, e);
-          }
+        }
         serverInetAddr = InetAddress.getByName(serverName);
     }
 
--- a/test/jdk/sun/net/www/protocol/https/HttpsURLConnection/ReadTimeout.java	Fri May 17 13:21:44 2019 +0100
+++ b/test/jdk/sun/net/www/protocol/https/HttpsURLConnection/ReadTimeout.java	Thu May 23 11:07:37 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2019, 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
@@ -32,12 +32,14 @@
  * @summary sun.net.client.defaultConnectTimeout should work with
  *     HttpsURLConnection; HTTP client: Connect and read timeouts;
  *     Https needs to support new tiger features that went into http
+ * @library /test/lib
  * @run main/othervm ReadTimeout
  */
 
 import java.io.*;
 import java.net.*;
 import javax.net.ssl.*;
+import jdk.test.lib.net.URIBuilder;
 
 public class ReadTimeout {
 
@@ -93,10 +95,11 @@
      * to avoid infinite hangs.
      */
     void doServerSide() throws Exception {
+        InetAddress loopback = InetAddress.getLoopbackAddress();
         SSLServerSocketFactory sslssf =
             (SSLServerSocketFactory) SSLServerSocketFactory.getDefault();
         SSLServerSocket sslServerSocket =
-            (SSLServerSocket) sslssf.createServerSocket(serverPort);
+            (SSLServerSocket) sslssf.createServerSocket(serverPort, 0, loopback);
         serverPort = sslServerSocket.getLocalPort();
 
         /*
@@ -163,7 +166,11 @@
             }
             HttpsURLConnection http = null;
             try {
-                URL url = new URL("https://localhost:" + serverPort);
+                URL url = URIBuilder.newBuilder()
+                          .scheme("https")
+                          .loopback()
+                          .port(serverPort)
+                          .toURL();
 
                 // set read timeout through system property
                 System.setProperty("sun.net.client.defaultReadTimeout", "2000");
@@ -184,7 +191,11 @@
             }
 
             try {
-                URL url = new URL("https://localhost:" + serverPort);
+                URL url = URIBuilder.newBuilder()
+                          .scheme("https")
+                          .loopback()
+                          .port(serverPort)
+                          .toURL();
 
                 HttpsURLConnection.setDefaultHostnameVerifier(
                                           new NameVerifier());
@@ -239,6 +250,10 @@
     volatile Exception serverException = null;
     volatile Exception clientException = null;
 
+    private boolean sslConnectionFailed() {
+        return clientException instanceof SSLHandshakeException;
+    }
+
     public static void main(String[] args) throws Exception {
         String keyFilename =
             System.getProperty("test.src", "./") + "/" + pathToStores +
@@ -282,7 +297,9 @@
          * Wait for other side to close down.
          */
         if (separateServerThread) {
-            serverThread.join();
+            if (!sslConnectionFailed()) {
+                serverThread.join();
+            }
         } else {
             clientThread.join();
         }
--- a/test/jdk/sun/net/www/protocol/https/HttpsURLConnection/Redirect.java	Fri May 17 13:21:44 2019 +0100
+++ b/test/jdk/sun/net/www/protocol/https/HttpsURLConnection/Redirect.java	Thu May 23 11:07:37 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2019, 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
@@ -26,6 +26,7 @@
  * @bug 4423074
  * @summary Need to rebase all the duplicated classes from Merlin.
  *          This test will check out http POST
+ * @library /test/lib
  * @run main/othervm Redirect
  *
  *     SunJSSE does not support dynamic system properties, no way to re-use
@@ -35,6 +36,7 @@
 import java.io.*;
 import java.net.*;
 import javax.net.ssl.*;
+import jdk.test.lib.net.URIBuilder;
 
 public class Redirect {
 
@@ -95,10 +97,11 @@
      * to avoid infinite hangs.
      */
     void doServerSide() throws Exception {
+        InetAddress loopback = InetAddress.getLoopbackAddress();
         SSLServerSocketFactory sslssf =
             (SSLServerSocketFactory) SSLServerSocketFactory.getDefault();
         SSLServerSocket sslServerSocket =
-            (SSLServerSocket) sslssf.createServerSocket(serverPort);
+            (SSLServerSocket) sslssf.createServerSocket(serverPort, 0, loopback);
         serverPort = sslServerSocket.getLocalPort();
 
         /*
@@ -154,7 +157,11 @@
             }
 
             // Send HTTP POST request to server
-            URL url = new URL("https://localhost:"+serverPort);
+            URL url = URIBuilder.newBuilder()
+                      .scheme("https")
+                      .loopback()
+                      .port(serverPort)
+                      .toURL();
 
             HttpsURLConnection.setDefaultHostnameVerifier(
                                           new NameVerifier());
@@ -190,6 +197,10 @@
     volatile Exception serverException = null;
     volatile Exception clientException = null;
 
+    private boolean sslConnectionFailed() {
+        return clientException instanceof SSLHandshakeException;
+    }
+
     public static void main(String[] args) throws Exception {
         String keyFilename =
             System.getProperty("test.src", "./") + "/" + pathToStores +
@@ -233,7 +244,9 @@
          * Wait for other side to close down.
          */
         if (separateServerThread) {
-            serverThread.join();
+            if (!sslConnectionFailed()) {
+                serverThread.join();
+            }
         } else {
             clientThread.join();
         }
--- a/test/jdk/sun/net/www/protocol/https/HttpsURLConnection/RetryHttps.java	Fri May 17 13:21:44 2019 +0100
+++ b/test/jdk/sun/net/www/protocol/https/HttpsURLConnection/RetryHttps.java	Thu May 23 11:07:37 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2019, 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
@@ -24,7 +24,9 @@
 /* @test
  * @bug 4799427
  * @summary Https can not retry request
+ * @library /test/lib
  * @run main/othervm RetryHttps
+ * @run main/othervm -Djava.net.preferIPv6Addresses=true RetryHttps
  *
  *     SunJSSE does not support dynamic system properties, no way to re-use
  *     system properties in samevm/agentvm mode.
@@ -35,6 +37,7 @@
 import java.util.*;
 import java.io.*;
 import javax.net.ssl.*;
+import jdk.test.lib.net.URIBuilder;
 
 public class RetryHttps {
     static Map cookies;
@@ -80,12 +83,17 @@
      * to avoid infinite hangs.
      */
     void doServerSide() throws Exception {
+        InetAddress loopback = InetAddress.getLoopbackAddress();
         SSLServerSocketFactory sslssf =
             (SSLServerSocketFactory) SSLServerSocketFactory.getDefault();
         sslServerSocket =
-            (SSLServerSocket) sslssf.createServerSocket(serverPort);
+            (SSLServerSocket) sslssf.createServerSocket(serverPort, 0, loopback);
         serverPort = sslServerSocket.getLocalPort();
 
+        System.out.println("Starting server at: "
+                            +  sslServerSocket.getInetAddress()
+                            + ":" + serverPort);
+
         /*
          * Signal Client, we're ready for his connect.
          */
@@ -145,11 +153,16 @@
             try {
                 HttpsURLConnection http = null;
                 /* establish http connection to server */
-                URL url = new URL("https://localhost:" + serverPort+"/file1");
+               URL url = URIBuilder.newBuilder()
+                      .scheme("https")
+                      .loopback()
+                      .port(serverPort)
+                      .path("/file1")
+                      .toURL();
                 System.out.println("url is "+url.toString());
                 HttpsURLConnection.setDefaultHostnameVerifier(
                                                         new NameVerifier());
-                http = (HttpsURLConnection)url.openConnection();
+                http = (HttpsURLConnection)url.openConnection(Proxy.NO_PROXY);
                 int respCode = http.getResponseCode();
                 int cl = http.getContentLength();
                 InputStream is = http.getInputStream ();
@@ -157,8 +170,13 @@
                 while (is.read() != -1 && count++ < cl);
                 System.out.println("respCode1 = "+respCode);
                 Thread.sleep(2000);
-                url = new URL("https://localhost:" + serverPort+"/file2");
-                http = (HttpsURLConnection)url.openConnection();
+                url = URIBuilder.newBuilder()
+                      .scheme("https")
+                      .loopback()
+                      .port(serverPort)
+                      .path("/file2")
+                      .toURL();
+                http = (HttpsURLConnection)url.openConnection(Proxy.NO_PROXY);
                 respCode = http.getResponseCode();
                 System.out.println("respCode2 = "+respCode);
             } catch (IOException ioex) {
--- a/test/jdk/sun/text/resources/LocaleData	Fri May 17 13:21:44 2019 +0100
+++ b/test/jdk/sun/text/resources/LocaleData	Thu May 23 11:07:37 2019 +0100
@@ -614,8 +614,6 @@
 FormatData/es_PE/DatePatterns/2=dd/MM/yyyy
 FormatData/es_PE/DatePatterns/3=dd/MM/yy
 FormatData/es_PE/DateTimePatterns/0={1} {0}
-FormatData/es_PE/NumberElements/0=,
-FormatData/es_PE/NumberElements/1=.
 FormatData/es_PE/NumberElements/2=;
 FormatData/es_PR/NumberPatterns/0=#,##0.###;-#,##0.###
 # FormatData/es_PR/NumberPatterns/1=$#,##0.00;($#,##0.00) # Changed; see bug 4122840
@@ -8323,3 +8321,8 @@
 
 # bug #8208746
 CurrencyNames//ves=Venezuelan Bol\u00edvar Soberano
+
+# bug# 8206879
+# For Peru decimal separator is changed to dot(.) and grouping separator is changed to comma(,)
+FormatData/es_PE/NumberElements/0=.
+FormatData/es_PE/NumberElements/1=,
--- a/test/langtools/jdk/javadoc/doclet/testAnnotationTypes/TestAnnotationTypes.java	Fri May 17 13:21:44 2019 +0100
+++ b/test/langtools/jdk/javadoc/doclet/testAnnotationTypes/TestAnnotationTypes.java	Thu May 23 11:07:37 2019 +0100
@@ -79,7 +79,7 @@
                     "<ul class=\"blockList\">",
                     "<li class=\"blockList\">",
                     "<section class=\"memberDetails\">",
-                    "<h2>Element Detail</h2>",
+                    "<h2>Element Details</h2>",
                     "<a id=\"annotation.type.element.detail\">",
                     "<!--   -->",
                     "</a>",
--- a/test/langtools/jdk/javadoc/doclet/testHtmlVersion/TestHtmlVersion.java	Fri May 17 13:21:44 2019 +0100
+++ b/test/langtools/jdk/javadoc/doclet/testHtmlVersion/TestHtmlVersion.java	Thu May 23 11:07:37 2019 +0100
@@ -24,7 +24,7 @@
 /*
  * @test
  * @bug 8072945 8081854 8141492 8148985 8150188 4649116 8173707 8151743 8169819 8183037 8182765 8196202
- *      8202624 8210047 8184205 8221871
+ *      8202624 8210047 8184205 8221871 8223733
  * @summary Test the version of HTML generated by the javadoc tool.
  * @author bpatel
  * @library ../../lib
@@ -324,17 +324,17 @@
                 + "</a>\n"
                 + "<h2>Method Summary</h2>",
                 "<section class=\"fieldDetails\">\n"
-                + "<h2>Field Detail</h2>\n"
+                + "<h2>Field Details</h2>\n"
                 + "<a id=\"field.detail\">\n"
                 + "<!--   -->\n"
                 + "</a>",
                 "<section class=\"constructorDetails\">\n"
-                + "<h2>Constructor Detail</h2>\n"
+                + "<h2>Constructor Details</h2>\n"
                 + "<a id=\"constructor.detail\">\n"
                 + "<!--   -->\n"
                 + "</a>",
                 "<section class=\"methodDetails\">\n"
-                + "<h2>Method Detail</h2>\n"
+                + "<h2>Method Details</h2>\n"
                 + "<a id=\"method.detail\">\n"
                 + "<!--   -->\n"
                 + "</a>",
@@ -368,12 +368,12 @@
                 + "<div class=\"memberSummary\">\n",
                 "<table aria-labelledby=\"t0\">",
                 "<section class=\"constantDetails\">\n"
-                + "<h2>Enum Constant Detail</h2>\n"
+                + "<h2>Enum Constant Details</h2>\n"
                 + "<a id=\"enum.constant.detail\">\n"
                 + "<!--   -->\n"
                 + "</a>\n",
                 "<section class=\"methodDetails\">\n"
-                + "<h2>Method Detail</h2>\n"
+                + "<h2>Method Details</h2>\n"
                 + "<a id=\"method.detail\">\n"
                 + "<!--   -->\n"
                 + "</a>\n",
@@ -401,7 +401,7 @@
                 + "<div class=\"memberSummary\">\n",
                 "<table aria-labelledby=\"t0\">\n",
                 "<section class=\"methodDetails\">\n"
-                + "<h2>Method Detail</h2>\n"
+                + "<h2>Method Details</h2>\n"
                 + "<a id=\"method.detail\">\n"
                 + "<!--   -->\n"
                 + "</a>\n",
@@ -427,7 +427,7 @@
                 + "</a>\n"
                 + "<h2>Constructor Summary</h2>",
                 "<section class=\"constructorDetails\">\n"
-                + "<h2>Constructor Detail</h2>\n"
+                + "<h2>Constructor Details</h2>\n"
                 + "<a id=\"constructor.detail\">\n"
                 + "<!--   -->\n"
                 + "</a>\n",
@@ -453,7 +453,7 @@
                 + "</a>\n"
                 + "<h2>Constructor Summary</h2>",
                 "<section class=\"constructorDetails\">\n"
-                + "<h2>Constructor Detail</h2>\n"
+                + "<h2>Constructor Details</h2>\n"
                 + "<a id=\"constructor.detail\">\n"
                 + "<!--   -->\n"
                 + "</a>\n",
@@ -485,7 +485,7 @@
                 + "<h2>Optional Element Summary</h2>\n"
                 + "<div class=\"memberSummary\">\n<table>",
                 "<section class=\"memberDetails\">\n"
-                + "<h2>Element Detail</h2>\n"
+                + "<h2>Element Details</h2>\n"
                 + "<a id=\"annotation.type.element.detail\">\n"
                 + "<!--   -->\n"
                 + "</a>\n",
@@ -742,19 +742,19 @@
                 + "<li class=\"blockList\"><a name=\"field.detail\">\n"
                 + "<!--   -->\n"
                 + "</a>\n"
-                + "<h2>Field Detail</h2>",
+                + "<h2>Field Details</h2>",
                 "<!-- ========= CONSTRUCTOR DETAIL ======== -->\n"
                 + "<ul class=\"blockList\">\n"
                 + "<li class=\"blockList\"><a name=\"constructor.detail\">\n"
                 + "<!--   -->\n"
                 + "</a>\n"
-                + "<h2>Constructor Detail</h2>",
+                + "<h2>Constructor Details</h2>",
                 "<!-- ============ METHOD DETAIL ========== -->\n"
                 + "<ul class=\"blockList\">\n"
                 + "<li class=\"blockList\"><a name=\"method.detail\">\n"
                 + "<!--   -->\n"
                 + "</a>\n"
-                + "<h2>Method Detail</h2>");
+                + "<h2>Method Details</h2>");
 
         // Negated test for enum page
         checkOutput("pkg/AnotherClass.ModalExclusionType.html", false,
@@ -786,13 +786,13 @@
                 + "<li class=\"blockList\"><a name=\"enum.constant.detail\">\n"
                 + "<!--   -->\n"
                 + "</a>\n"
-                + "<h2>Enum Constant Detail</h2>",
+                + "<h2>Enum Constant Details</h2>",
                 "<!-- ============ METHOD DETAIL ========== -->\n"
                 + "<ul class=\"blockList\">\n"
                 + "<li class=\"blockList\"><a name=\"method.detail\">\n"
                 + "<!--   -->\n"
                 + "</a>\n"
-                + "<h2>Method Detail</h2>");
+                + "<h2>Method Details</h2>");
 
         // Negated test for interface page
         checkOutput("pkg2/Interface.html", false,
@@ -816,7 +816,7 @@
                 + "<li class=\"blockList\"><a name=\"method.detail\">\n"
                 + "<!--   -->\n"
                 + "</a>\n"
-                + "<h2>Method Detail</h2>");
+                + "<h2>Method Details</h2>");
 
         // Negated test for error page
         checkOutput("pkg/TestError.html", false,
@@ -838,7 +838,7 @@
                 + "<li class=\"blockList\"><a name=\"constructor.detail\">\n"
                 + "<!--   -->\n"
                 + "</a>\n"
-                + "<h2>Constructor Detail</h2>");
+                + "<h2>Constructor Details</h2>");
 
         // Negated test for exception page
         checkOutput("pkg/TestException.html", false,
@@ -860,7 +860,7 @@
                 + "<li class=\"blockList\"><a name=\"constructor.detail\">\n"
                 + "<!--   -->\n"
                 + "</a>\n"
-                + "<h2>Constructor Detail</h2>");
+                + "<h2>Constructor Details</h2>");
 
         // Negated test for annotation page
         checkOutput("pkg2/TestAnnotationType.html", false,
@@ -892,7 +892,7 @@
                 + "<li class=\"blockList\"><a name=\"annotation.type.element.detail\">\n"
                 + "<!--   -->\n"
                 + "</a>\n"
-                + "<h2>Element Detail</h2>");
+                + "<h2>Element Details</h2>");
 
         // Negated test for class use page
         checkOutput("pkg1/class-use/RegClass.html", false,
--- a/test/langtools/jdk/javadoc/doclet/testIndexTaglet/TestIndexTaglet.java	Fri May 17 13:21:44 2019 +0100
+++ b/test/langtools/jdk/javadoc/doclet/testIndexTaglet/TestIndexTaglet.java	Thu May 23 11:07:37 2019 +0100
@@ -75,7 +75,7 @@
         checkExit(Exit.OK);
 
         checkOrder("pkg/A.html",
-                "<h2>Method Detail</h2>\n",
+                "<h2>Method Details</h2>\n",
                 "<div class=\"block\">test description with <a id=\"search_phrase_a\" "
                  +    "class=\"searchTagResult\">search_phrase_a</a></div>");
 
--- a/test/langtools/jdk/javadoc/doclet/testJavaFX/TestJavaFX.java	Fri May 17 13:21:44 2019 +0100
+++ b/test/langtools/jdk/javadoc/doclet/testJavaFX/TestJavaFX.java	Thu May 23 11:07:37 2019 +0100
@@ -213,7 +213,7 @@
                 "pkg2");
         checkExit(Exit.OK);
         checkOutput("pkg2/Test.html", true,
-                "<h2>Property Detail</h2>\n"
+                "<h2>Property Details</h2>\n"
                 + "<a id=\"property.detail\">\n"
                 + "<!--   -->\n"
                 + "</a>\n"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/langtools/jdk/javadoc/doclet/testModuleSpecificStylesheet/TestModuleSpecificStylesheet.java	Thu May 23 11:07:37 2019 +0100
@@ -0,0 +1,103 @@
+/*
+ * Copyright (c) 2019, 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
+ * @bug 8219313
+ * @summary Support module specific stylesheets
+ * @library /tools/lib ../../lib
+ * @modules jdk.compiler/com.sun.tools.javac.api
+ *          jdk.compiler/com.sun.tools.javac.main
+ *          jdk.javadoc/jdk.javadoc.internal.tool
+ * @build javadoc.tester.* toolbox.ToolBox
+ * @run main TestModuleSpecificStylesheet
+ */
+
+
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.List;
+
+import toolbox.ModuleBuilder;
+import toolbox.ToolBox;
+
+import javadoc.tester.JavadocTester;
+
+public class TestModuleSpecificStylesheet extends JavadocTester {
+
+    final ToolBox tb;
+
+    public static void main(String... args) throws Exception {
+        TestModuleSpecificStylesheet tester = new TestModuleSpecificStylesheet();
+        tester.runTests(m -> new Object[]{Paths.get(m.getName())});
+    }
+
+    TestModuleSpecificStylesheet() {
+        tb = new ToolBox();
+    }
+
+    @Test
+    public void test(Path base) throws Exception {
+        Path srcDir = base.resolve("src");
+        Path outDir = base.resolve("out");
+
+        new ModuleBuilder(tb, "ma")
+                .classes("package pa; public class A{}")
+                .classes("package pa.pb; public class B{}")
+                .exports("pa")
+                .exports("pa.pb")
+                .write(srcDir);
+
+        Path docFilesDir = Files.createDirectories(srcDir.resolve("ma").resolve("doc-files"));
+        Path stylesheet = docFilesDir.resolve("spanstyle.css");
+        Files.createFile(stylesheet);
+        Files.write(stylesheet, List.of("span{ color:blue; }"));
+
+        javadoc("-d", outDir.toString(),
+                "--module-source-path", srcDir.toString(),
+                "--module", "ma");
+
+        checkExit(Exit.OK);
+
+        checkOutput("ma/module-summary.html", true,
+                "<link rel=\"stylesheet\" type=\"text/css\" href=\"../ma/doc-files/spanstyle.css\"" +
+                        " title=\"Style\">");
+
+        checkOutput("ma/pa/package-summary.html", true,
+                "<link rel=\"stylesheet\" type=\"text/css\" href=\"../../ma/doc-files/spanstyle.css\"" +
+                        " title=\"Style\">");
+
+        checkOutput("ma/pa/A.html", true,
+                "<link rel=\"stylesheet\" type=\"text/css\" href=\"../../ma/doc-files/spanstyle.css\"" +
+                        " title=\"Style\">");
+
+        checkOutput("ma/pa/pb/B.html", true,
+                "<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../ma/doc-files/spanstyle.css\"" +
+                        " title=\"Style\">");
+
+        checkOutput("ma/pa/pb/package-summary.html", true,
+                "<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../ma/doc-files/spanstyle.css\"" +
+                        " title=\"Style\">");
+    }
+}
--- a/test/langtools/jdk/javadoc/doclet/testOrdering/TestOrdering.java	Fri May 17 13:21:44 2019 +0100
+++ b/test/langtools/jdk/javadoc/doclet/testOrdering/TestOrdering.java	Thu May 23 11:07:37 2019 +0100
@@ -515,7 +515,7 @@
             checkExit(Exit.OK);
 
             checkOrder("pkg5/AnnoFieldTest.html",
-                    "<h2>Field Detail</h2>",
+                    "<h2>Field Details</h2>",
                     "<pre>static final&nbsp;int&nbsp;one</pre>",
                     "<pre>static final&nbsp;int&nbsp;two</pre>",
                     "<pre>static final&nbsp;int&nbsp;three</pre>",
@@ -527,7 +527,7 @@
                     "<a href=\"#one()\">one</a>",
                     "<a href=\"#three()\">three</a>",
                     "<a href=\"#two()\">two</a>",
-                    "<h2>Element Detail</h2>",
+                    "<h2>Element Details</h2>",
                     "<h3>one</h3>",
                     "<h3>two</h3>",
                     "<h3>three</h3>",
@@ -539,7 +539,7 @@
                     "<a href=\"#one()\">one</a>",
                     "<a href=\"#three()\">three</a>",
                     "<a href=\"#two()\">two</a>",
-                    "<h2>Element Detail</h2>",
+                    "<h2>Element Details</h2>",
                     "<h3>one</h3>",
                     "<h3>two</h3>",
                     "<h3>three</h3>",
@@ -551,7 +551,7 @@
                     "<a href=\"#%3Cinit%3E(int,int)\"",
                     "<a href=\"#%3Cinit%3E(int,int,int)\"",
                     "<a href=\"#%3Cinit%3E(int,int,int,int)\"",
-                    "<h2>Constructor Detail</h2>",
+                    "<h2>Constructor Details</h2>",
                     "<a id=\"&lt;init&gt;(int,int,int,int)\">",
                     "<a id=\"&lt;init&gt;(int,int,int)\">",
                     "<a id=\"&lt;init&gt;(int,int)\">",
@@ -563,7 +563,7 @@
                     "<a href=\"#ONE\">ONE</a>",
                     "<a href=\"#THREE\">THREE</a>",
                     "<a href=\"#TWO\">TWO</a>",
-                    "<h2>Enum Constant Detail</h2>",
+                    "<h2>Enum Constant Details</h2>",
                     "<h3>ONE</h3>",
                     "<h3>TWO</h3>",
                     "<h3>THREE</h3>",
@@ -575,7 +575,7 @@
                     "<a href=\"#one\">one</a>",
                     "<a href=\"#three\">three</a>",
                     "<a href=\"#two\">two</a>",
-                    "<h2>Field Detail</h2>",
+                    "<h2>Field Details</h2>",
                     "<h3>one</h3>",
                     "<h3>two</h3>",
                     "<h3>three</h3>",
@@ -587,7 +587,7 @@
                     "<a href=\"#one()\">one</a>",
                     "<a href=\"#three()\">three</a>",
                     "<a href=\"#two()\">two</a>",
-                    "<h2>Method Detail</h2>",
+                    "<h2>Method Details</h2>",
                     "<h3>one</h3>",
                     "<h3>two</h3>",
                     "<h3>three</h3>",
@@ -599,7 +599,7 @@
                     "<a href=\"#one()\">one</a>",
                     "<a href=\"#three()\">three</a>",
                     "<a href=\"#two()\">two</a>",
-                    "<h2>Method Detail</h2>",
+                    "<h2>Method Details</h2>",
                     "<h3>one</h3>",
                     "<h3>two</h3>",
                     "<h3>three</h3>",
@@ -611,7 +611,7 @@
                     "<a href=\"#oneProperty\">one</a>",
                     "<a href=\"#threeProperty\">three</a>",
                     "<a href=\"#twoProperty\">two</a>",
-                    "<h2>Property Detail</h2>",
+                    "<h2>Property Details</h2>",
                     "<h3>oneProperty</h3>",
                     "<h3>twoProperty</h3>",
                     "<h3>threeProperty</h3>",
--- a/test/langtools/jdk/javadoc/doclet/testPackageSpecificStylesheet/TestPackageSpecificStylesheet.java	Fri May 17 13:21:44 2019 +0100
+++ b/test/langtools/jdk/javadoc/doclet/testPackageSpecificStylesheet/TestPackageSpecificStylesheet.java	Thu May 23 11:07:37 2019 +0100
@@ -81,15 +81,15 @@
         checkExit(Exit.OK);
 
         checkOutput("pkg/A.html", true,
-                "<link rel=\"stylesheet\" type=\"text/css\" href=\"doc-files/spanstyle.css\"" +
+                "<link rel=\"stylesheet\" type=\"text/css\" href=\"../pkg/doc-files/spanstyle.css\"" +
                         " title=\"Style\">");
 
         checkOutput("pkg/package-summary.html", true,
-                "<link rel=\"stylesheet\" type=\"text/css\" href=\"doc-files/spanstyle.css\"" +
+                "<link rel=\"stylesheet\" type=\"text/css\" href=\"../pkg/doc-files/spanstyle.css\"" +
                         " title=\"Style\">");
 
         checkOutput("pkg2/B.html", false,
-                "<link rel=\"stylesheet\" type=\"text/css\" href=\"doc-files/spanstyle.css\"" +
+                "<link rel=\"stylesheet\" type=\"text/css\" href=\"../pkg2/doc-files/spanstyle.css\"" +
                         " title=\"Style\">");
 
     }
--- a/test/langtools/jdk/javadoc/doclet/testSystemPropertyTaglet/TestSystemPropertyTaglet.java	Fri May 17 13:21:44 2019 +0100
+++ b/test/langtools/jdk/javadoc/doclet/testSystemPropertyTaglet/TestSystemPropertyTaglet.java	Thu May 23 11:07:37 2019 +0100
@@ -78,7 +78,7 @@
         checkOrder("pkg/A.html",
                 "<h1 title=\"Class A\" class=\"title\">Class A</h1>",
                 "test with <code><a id=\"user.name\" class=\"searchTagResult\">user.name</a></code>",
-                "<h2>Method Detail</h2>",
+                "<h2>Method Details</h2>",
                 "test with <code><a id=\"java.version\" class=\"searchTagResult\">java.version</a></code>");
 
         checkOrder("index-all.html",
--- a/test/lib/jdk/test/lib/cds/CDSTestUtils.java	Fri May 17 13:21:44 2019 +0100
+++ b/test/lib/jdk/test/lib/cds/CDSTestUtils.java	Thu May 23 11:07:37 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2019, 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
@@ -43,6 +43,8 @@
     public static final String MSG_COMPRESSION_MUST_BE_USED =
         "Unable to use shared archive: UseCompressedOops and UseCompressedClassPointers must be on for UseSharedSpaces.";
 
+    public static final boolean DYNAMIC_DUMP = Boolean.getBoolean("test.dynamic.cds.archive");
+
     public interface Checker {
         public void check(OutputAnalyzer output) throws Exception;
     }
@@ -246,7 +248,7 @@
         cmd.add("-Xlog:cds,cds+hashtables");
         if (opts.archiveName == null)
             opts.archiveName = getDefaultArchiveName();
-        cmd.add("-XX:SharedArchiveFile=./" + opts.archiveName);
+        cmd.add("-XX:SharedArchiveFile=" + opts.archiveName);
 
         if (opts.classList != null) {
             File classListFile = makeClassList(opts.classList);
@@ -260,12 +262,20 @@
         return executeAndLog(pb, "dump");
     }
 
+    public static boolean isDynamicArchive() {
+        return DYNAMIC_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");
+        if (!DYNAMIC_DUMP) {
+            output.shouldContain("Loading classes to share");
+        } else {
+            output.shouldContain("Buffer-space to target-space delta")
+                  .shouldContain("Written dynamic archive 0x");
+        }
         output.shouldHaveExitValue(0);
 
         for (String match : extraMatches) {
--- a/test/lib/jdk/test/lib/jfr/EventNames.java	Fri May 17 13:21:44 2019 +0100
+++ b/test/lib/jdk/test/lib/jfr/EventNames.java	Thu May 23 11:07:37 2019 +0100
@@ -101,6 +101,8 @@
     public final static String G1HeapSummary = PREFIX + "G1HeapSummary";
     public final static String G1HeapRegionInformation = PREFIX + "G1HeapRegionInformation";
     public final static String G1HeapRegionTypeChange = PREFIX + "G1HeapRegionTypeChange";
+    public final static String ShenandoahHeapRegionInformation = PREFIX + "ShenandoahHeapRegionInformation";
+    public final static String ShenandoahHeapRegionStateChange = PREFIX + "ShenandoahHeapRegionStateChange";
     public final static String TenuringDistribution = PREFIX + "TenuringDistribution";
     public final static String GarbageCollection = PREFIX + "GarbageCollection";
     public final static String ParallelOldGarbageCollection = PREFIX + "ParallelOldGarbageCollection";
--- a/test/lib/jdk/test/lib/jfr/GCHelper.java	Fri May 17 13:21:44 2019 +0100
+++ b/test/lib/jdk/test/lib/jfr/GCHelper.java	Thu May 23 11:07:37 2019 +0100
@@ -80,6 +80,7 @@
     public static final String pauseLevelEvent = "GCPhasePauseLevel";
 
     private static final List<String> g1HeapRegionTypes;
+    private static final List<String> shenandoahHeapRegionStates;
     private static PrintStream defaultErrorLog = null;
 
     public static int getGcId(RecordedEvent event) {
@@ -207,6 +208,21 @@
                                                          };
 
         g1HeapRegionTypes = Collections.unmodifiableList(Arrays.asList(g1HeapRegionTypeLiterals));
+
+        String[] shenandoahHeapRegionStateLiterals = new String[] {
+                                                                    "Empty Uncommitted",
+                                                                    "Empty Committed",
+                                                                    "Regular",
+                                                                    "Humongous Start",
+                                                                    "Humongous Continuation",
+                                                                    "Humongous Start, Pinned",
+                                                                    "Collection Set",
+                                                                    "Pinned",
+                                                                    "Collection Set, Pinned",
+                                                                    "Trash"
+        };
+
+        shenandoahHeapRegionStates = Collections.unmodifiableList(Arrays.asList(shenandoahHeapRegionStateLiterals));
     }
 
     /**
@@ -443,6 +459,13 @@
         return g1HeapRegionTypes.contains(type);
     }
 
+    public static boolean assertIsValidShenandoahHeapRegionState(final String state) {
+        if (!shenandoahHeapRegionStates.contains(state)) {
+            throw new AssertionError("Unknown state '" + state + "', valid heap region states are " + shenandoahHeapRegionStates);
+        }
+        return true;
+    }
+
     /**
      * Helper function to align heap size up.
      *
--- a/test/lib/sun/hotspot/WhiteBox.java	Fri May 17 13:21:44 2019 +0100
+++ b/test/lib/sun/hotspot/WhiteBox.java	Thu May 23 11:07:37 2019 +0100
@@ -514,6 +514,7 @@
 
   // Sharing & archiving
   public native String  getDefaultArchivePath();
+  public native boolean cdsMemoryMappingFailed();
   public native boolean isSharingEnabled();
   public native boolean isShared(Object o);
   public native boolean isSharedClass(Class<?> c);
@@ -522,6 +523,7 @@
   public native boolean isJFRIncludedInVmBuild();
   public native boolean isJavaHeapArchiveSupported();
   public native Object  getResolvedReferences(Class<?> c);
+  public native void    linkClass(Class<?> c);
   public native boolean areOpenArchiveHeapObjectsMapped();
 
   // Compiler Directive