changeset 59229:7ea5ef097cb5

Merge
author psadhukhan
date Fri, 08 May 2020 09:52:42 +0530
parents ace0a59870a4 f170a0024eb5
children dd652a1b2a39
files test/jdk/ProblemList.txt test/jdk/java/net/DatagramSocket/SetReceiveBufferSize.java
diffstat 708 files changed, 14778 insertions(+), 34603 deletions(-) [+]
line wrap: on
line diff
--- a/.hgtags	Fri May 08 09:45:57 2020 +0530
+++ b/.hgtags	Fri May 08 09:52:42 2020 +0530
@@ -632,3 +632,4 @@
 7cc27caabe6e342151e8baf549beb07a9c755ec2 jdk-15+19
 46bca5e5e6fb26efd07245d26fe96a9c3260f51e jdk-15+20
 12b55fad80f30d24b1f8fdb3b947ea6465ef9518 jdk-15+21
+7223c6d610343fd8323af9d07d501e01fa1a7696 jdk-15+22
--- a/doc/building.html	Fri May 08 09:45:57 2020 +0530
+++ b/doc/building.html	Fri May 08 09:52:42 2020 +0530
@@ -295,7 +295,7 @@
 </tr>
 <tr class="even">
 <td style="text-align: left;">Windows</td>
-<td style="text-align: left;">Microsoft Visual Studio 2017 update 15.9.16</td>
+<td style="text-align: left;">Microsoft Visual Studio 2019 update 16.5.3</td>
 </tr>
 </tbody>
 </table>
--- a/doc/building.md	Fri May 08 09:45:57 2020 +0530
+++ b/doc/building.md	Fri May 08 09:52:42 2020 +0530
@@ -330,7 +330,7 @@
  Linux              gcc 9.2.0
  macOS              Apple Xcode 10.1 (using clang 10.0.0)
  Solaris            Oracle Solaris Studio 12.6 (with compiler version 5.15)
- Windows            Microsoft Visual Studio 2017 update 15.9.16
+ Windows            Microsoft Visual Studio 2019 update 16.5.3
 
 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
--- a/make/Init.gmk	Fri May 08 09:45:57 2020 +0530
+++ b/make/Init.gmk	Fri May 08 09:52:42 2020 +0530
@@ -226,6 +226,9 @@
   # Parse COMPARE_BUILD (for makefile development)
   $(eval $(call ParseCompareBuild))
 
+  # Setup reproducible build environment
+  $(eval $(call SetupReproducibleBuild))
+
   # If no LOG= was given on command line, but we have a non-standard default
   # value, use that instead and re-parse log level.
   ifeq ($(LOG), )
--- a/make/InitSupport.gmk	Fri May 08 09:45:57 2020 +0530
+++ b/make/InitSupport.gmk	Fri May 08 09:52:42 2020 +0530
@@ -306,6 +306,15 @@
     topdir=$(TOPDIR)
   endif
 
+  # Setup the build environment to match the requested specification on
+  # level of reproducible builds
+  define SetupReproducibleBuild
+    ifeq ($$(SOURCE_DATE), updated)
+      SOURCE_DATE := $$(shell $$(DATE) +"%s")
+    endif
+    export SOURCE_DATE_EPOCH := $$(SOURCE_DATE)
+  endef
+
   # Parse COMPARE_BUILD into COMPARE_BUILD_*
   # Syntax: COMPARE_BUILD=CONF=<configure options>:PATCH=<patch file>:
   #         MAKE=<make targets>:COMP_OPTS=<compare script options>:
@@ -471,15 +480,15 @@
   # Remove any javac server logs and port files. This
   # prevents a new make run to reuse the previous servers.
   define PrepareSmartJavac
-	$(if $(SJAVAC_SERVER_DIR), \
-	  $(RM) -r $(SJAVAC_SERVER_DIR) 2> /dev/null && \
-	  $(MKDIR) -p $(SJAVAC_SERVER_DIR) \
+	$(if $(JAVAC_SERVER_DIR), \
+	  $(RM) -r $(JAVAC_SERVER_DIR) 2> /dev/null && \
+	  $(MKDIR) -p $(JAVAC_SERVER_DIR) \
 	)
   endef
 
   define CleanupSmartJavac
-	[ -f $(SJAVAC_SERVER_DIR)/server.port ] && $(ECHO) Stopping sjavac server && \
-	    $(TOUCH) $(SJAVAC_SERVER_DIR)/server.port.stop; true
+	[ -f $(JAVAC_SERVER_DIR)/server.port ] && $(ECHO) Stopping sjavac server && \
+	    $(TOUCH) $(JAVAC_SERVER_DIR)/server.port.stop; true
   endef
 
   ifeq ($(call isBuildOs, windows), true)
@@ -488,7 +497,7 @@
     # synchronization process, wait for a while and hope it helps. This is only
     # used by build comparisons.
     define WaitForSmartJavacFinish
-	$(if $(SJAVAC_SERVER_DIR), \
+	$(if $(JAVAC_SERVER_DIR), \
 	  sleep 5\
 	)
     endef
--- a/make/autoconf/boot-jdk.m4	Fri May 08 09:45:57 2020 +0530
+++ b/make/autoconf/boot-jdk.m4	Fri May 08 09:52:42 2020 +0530
@@ -74,7 +74,8 @@
           BOOT_JDK_FOUND=no
         else
           # Oh, this is looking good! We probably have found a proper JDK. Is it the correct version?
-          BOOT_JDK_VERSION=`"$BOOT_JDK/bin/java$EXE_SUFFIX" $USER_BOOT_JDK_OPTIONS -version 2>&1 | $HEAD -n 1`
+          # Additional [] needed to keep m4 from mangling shell constructs.
+          [ BOOT_JDK_VERSION=`"$BOOT_JDK/bin/java$EXE_SUFFIX" $USER_BOOT_JDK_OPTIONS -version 2>&1 | $AWK '/version \"[0-9\._\-a-zA-Z]+\"/{print $ 0; exit;}'` ]
           if [ [[ "$BOOT_JDK_VERSION" =~ "Picked up" ]] ]; then
             AC_MSG_NOTICE([You have _JAVA_OPTIONS or JAVA_TOOL_OPTIONS set. This can mess up the build. Please use --with-boot-jdk-jvmargs instead.])
             AC_MSG_NOTICE([Java reports: "$BOOT_JDK_VERSION".])
@@ -529,7 +530,8 @@
         BUILD_JDK_FOUND=no
       else
         # Oh, this is looking good! We probably have found a proper JDK. Is it the correct version?
-        BUILD_JDK_VERSION=`"$BUILD_JDK/bin/java" -version 2>&1 | $HEAD -n 1`
+        # Additional [] needed to keep m4 from mangling shell constructs.
+        [ BUILD_JDK_VERSION=`"$BUILD_JDK/bin/java" -version 2>&1 | $AWK '/version \"[0-9\._\-a-zA-Z]+\"/{print $ 0; exit;}'` ]
 
         # Extra M4 quote needed to protect [] in grep expression.
         [FOUND_CORRECT_VERSION=`echo $BUILD_JDK_VERSION | $EGREP "\"$VERSION_FEATURE([\.+-].*)?\""`]
--- a/make/autoconf/bootcycle-spec.gmk.in	Fri May 08 09:45:57 2020 +0530
+++ b/make/autoconf/bootcycle-spec.gmk.in	Fri May 08 09:52:42 2020 +0530
@@ -44,7 +44,8 @@
 # The bootcycle build has a different output directory
 OLD_OUTPUTDIR:=@OUTPUTDIR@
 OUTPUTDIR:=$(OLD_OUTPUTDIR)/bootcycle-build
-SJAVAC_SERVER_DIR:=$(patsubst $(OLD_OUTPUTDIR)%, $(OUTPUTDIR)%, $(SJAVAC_SERVER_DIR))
+# No spaces in patsubst to avoid leading space in variable
+JAVAC_SERVER_DIR:=$(patsubst $(OLD_OUTPUTDIR)%,$(OUTPUTDIR)%,$(JAVAC_SERVER_DIR))
 
 JAVA_CMD:=$(BOOT_JDK)/bin/java
 JAVAC_CMD:=$(BOOT_JDK)/bin/javac
--- a/make/autoconf/build-performance.m4	Fri May 08 09:45:57 2020 +0530
+++ b/make/autoconf/build-performance.m4	Fri May 08 09:52:42 2020 +0530
@@ -32,7 +32,12 @@
   if test -f /proc/cpuinfo; then
     # Looks like a Linux (or cygwin) system
     NUM_CORES=`cat /proc/cpuinfo  | grep -c processor`
-    FOUND_CORES=yes
+    if test "$NUM_CORES" -eq "0"; then
+      NUM_CORES=`cat /proc/cpuinfo  | grep -c ^CPU`
+    fi
+    if test "$NUM_CORES" -ne "0"; then
+      FOUND_CORES=yes
+    fi
   elif test -x /usr/sbin/psrinfo; then
     # Looks like a Solaris system
     NUM_CORES=`/usr/sbin/psrinfo -v | grep -c on-line`
--- a/make/autoconf/configure.ac	Fri May 08 09:45:57 2020 +0530
+++ b/make/autoconf/configure.ac	Fri May 08 09:52:42 2020 +0530
@@ -249,6 +249,7 @@
 JDKOPT_EXCLUDE_TRANSLATIONS
 JDKOPT_ENABLE_DISABLE_MANPAGES
 JDKOPT_ENABLE_DISABLE_CDS_ARCHIVE
+JDKOPT_SETUP_REPRODUCIBLE_BUILD
 
 ###############################################################################
 #
--- a/make/autoconf/jdk-options.m4	Fri May 08 09:45:57 2020 +0530
+++ b/make/autoconf/jdk-options.m4	Fri May 08 09:52:42 2020 +0530
@@ -630,3 +630,59 @@
 
   AC_SUBST(ALLOW_ABSOLUTE_PATHS_IN_OUTPUT)
 ])
+
+################################################################################
+#
+# Check and set options related to reproducible builds.
+#
+AC_DEFUN_ONCE([JDKOPT_SETUP_REPRODUCIBLE_BUILD],
+[
+  AC_ARG_WITH([source-date], [AS_HELP_STRING([--with-source-date],
+      [how to set SOURCE_DATE_EPOCH ('updated', 'current', 'version' a timestamp or an ISO-8601 date) @<:@updated@:>@])],
+      [with_source_date_present=true], [with_source_date_present=false])
+
+  AC_MSG_CHECKING([what source date to use])
+
+  if test "x$with_source_date" = xyes; then
+    AC_MSG_ERROR([--with-source-date must have a value])
+  elif test "x$with_source_date" = xupdated || test "x$with_source_date" = x; then
+    # Tell the makefiles to update at each build
+    SOURCE_DATE=updated
+    AC_MSG_RESULT([determined at build time, from 'updated'])
+  elif test "x$with_source_date" = xcurrent; then
+    # Set the current time
+    SOURCE_DATE=$($DATE +"%s")
+    AC_MSG_RESULT([$SOURCE_DATE, from 'current'])
+  elif test "x$with_source_date" = xversion; then
+    # Use the date from version-numbers
+    UTIL_GET_EPOCH_TIMESTAMP(SOURCE_DATE, $DEFAULT_VERSION_DATE)
+    if test "x$SOURCE_DATE" = x; then
+      AC_MSG_RESULT([unavailable])
+      AC_MSG_ERROR([Cannot convert DEFAULT_VERSION_DATE to timestamp])
+    fi
+    AC_MSG_RESULT([$SOURCE_DATE, from 'version'])
+  else
+    # It's a timestamp, an ISO-8601 date, or an invalid string
+    # Additional [] needed to keep m4 from mangling shell constructs.
+    if [ [[ "$with_source_date" =~ ^[0-9][0-9]*$ ]] ] ; then
+      SOURCE_DATE=$with_source_date
+      AC_MSG_RESULT([$SOURCE_DATE, from timestamp on command line])
+    else
+      UTIL_GET_EPOCH_TIMESTAMP(SOURCE_DATE, $with_source_date)
+      if test "x$SOURCE_DATE" != x; then
+        AC_MSG_RESULT([$SOURCE_DATE, from ISO-8601 date on command line])
+      else
+        AC_MSG_RESULT([unavailable])
+        AC_MSG_ERROR([Cannot parse date string "$with_source_date"])
+      fi
+    fi
+  fi
+
+  UTIL_ARG_ENABLE(NAME: reproducible-build, DEFAULT: $with_source_date_present,
+      RESULT: ENABLE_REPRODUCIBLE_BUILD,
+      DESC: [enable reproducible builds (not yet fully functional)],
+      DEFAULT_DESC: [enabled if --with-source-date is given])
+
+  AC_SUBST(SOURCE_DATE)
+  AC_SUBST(ENABLE_REPRODUCIBLE_BUILD)
+])
--- a/make/autoconf/jdk-version.m4	Fri May 08 09:45:57 2020 +0530
+++ b/make/autoconf/jdk-version.m4	Fri May 08 09:52:42 2020 +0530
@@ -36,7 +36,7 @@
 AC_DEFUN([JDKVER_CHECK_AND_SET_NUMBER],
 [
   # Additional [] needed to keep m4 from mangling shell constructs.
-  if [ ! [[ "$2" =~ ^0*([1-9][0-9]*)|(0)$ ]] ] ; then
+  if [ ! [[ "$2" =~ ^0*([1-9][0-9]*)$|^0*(0)$ ]] ] ; then
     AC_MSG_ERROR(["$2" is not a valid numerical value for $1])
   fi
   # Extract the version number without leading zeros.
--- a/make/autoconf/spec.gmk.in	Fri May 08 09:45:57 2020 +0530
+++ b/make/autoconf/spec.gmk.in	Fri May 08 09:52:42 2020 +0530
@@ -119,6 +119,9 @@
 RELEASE_FILE_OS_NAME:=@RELEASE_FILE_OS_NAME@
 RELEASE_FILE_OS_ARCH:=@RELEASE_FILE_OS_ARCH@
 
+SOURCE_DATE := @SOURCE_DATE@
+ENABLE_REPRODUCIBLE_BUILD := @ENABLE_REPRODUCIBLE_BUILD@
+
 LIBM:=@LIBM@
 LIBDL:=@LIBDL@
 
@@ -356,9 +359,9 @@
 NUM_CORES:=@NUM_CORES@
 MEMORY_SIZE:=@MEMORY_SIZE@
 ENABLE_JAVAC_SERVER:=@ENABLE_JAVAC_SERVER@
-# Store sjavac server synchronization files here, and
-# the sjavac server log files.
-SJAVAC_SERVER_DIR=$(MAKESUPPORT_OUTPUTDIR)/javacservers
+# Store javac server synchronization files here, and
+# the javac server log files.
+JAVAC_SERVER_DIR=$(MAKESUPPORT_OUTPUTDIR)/javacservers
 
 # Number of parallel jobs to use for compilation
 JOBS?=@JOBS@
--- a/make/autoconf/util.m4	Fri May 08 09:45:57 2020 +0530
+++ b/make/autoconf/util.m4	Fri May 08 09:52:42 2020 +0530
@@ -228,6 +228,29 @@
 ])
 
 ###############################################################################
+# Converts an ISO-8601 date/time string to a unix epoch timestamp. If no
+# suitable conversion method was found, an empty string is returned.
+#
+# Sets the specified variable to the resulting list.
+#
+# $1: result variable name
+# $2: input date/time string
+AC_DEFUN([UTIL_GET_EPOCH_TIMESTAMP],
+[
+  timestamp=$($DATE --utc --date=$2 +"%s" 2> /dev/null)
+  if test "x$timestamp" = x; then
+    # GNU date format did not work, try BSD date options
+    timestamp=$($DATE -j -f "%F %T" "$2" "+%s" 2> /dev/null)
+    if test "x$timestamp" = x; then
+      # Perhaps the time was missing
+      timestamp=$($DATE -j -f "%F %T" "$2 00:00:00" "+%s" 2> /dev/null)
+      # If this did not work, we give up and return the empty string
+    fi
+  fi
+  $1=$timestamp
+])
+
+###############################################################################
 # Sort a space-separated list, and remove duplicates.
 #
 # Sets the specified variable to the resulting list.
@@ -320,12 +343,14 @@
 #     option should be available. Must set AVAILABLE to 'false' if not.
 #   IF_GIVEN:  An optional code block to execute if the option was given on the
 #     command line (regardless of the value).
+#   IF_NOT_GIVEN:  An optional code block to execute if the option was not given
+#     on the command line (regardless of the value).
 #   IF_ENABLED:  An optional code block to execute if the option is turned on.
 #   IF_DISABLED:  An optional code block to execute if the option is turned off.
 #
 UTIL_DEFUN_NAMED([UTIL_ARG_ENABLE],
     [*NAME RESULT DEFAULT AVAILABLE DESC DEFAULT_DESC CHECKING_MSG
-    CHECK_AVAILABLE IF_GIVEN IF_ENABLED IF_DISABLED], [$@],
+    CHECK_AVAILABLE IF_GIVEN IF_NOT_GIVEN IF_ENABLED IF_DISABLED], [$@],
 [
   ##########################
   # Part 1: Set up m4 macros
@@ -356,6 +381,7 @@
   # tripping up bash.
   m4_define([ARG_CHECK_AVAILABLE], m4_if(ARG_CHECK_AVAILABLE, , :, ARG_CHECK_AVAILABLE))
   m4_define([ARG_IF_GIVEN], m4_if(ARG_IF_GIVEN, , :, ARG_IF_GIVEN))
+  m4_define([ARG_IF_NOT_GIVEN], m4_if(ARG_IF_NOT_GIVEN, , :, ARG_IF_NOT_GIVEN))
   m4_define([ARG_IF_ENABLED], m4_if(ARG_IF_ENABLED, , :, ARG_IF_ENABLED))
   m4_define([ARG_IF_DISABLED], m4_if(ARG_IF_DISABLED, , :, ARG_IF_DISABLED))
 
@@ -425,6 +451,8 @@
   # Execute result payloads, if present
   if test x$ARG_GIVEN = xtrue; then
     ARG_IF_GIVEN
+  else
+    ARG_IF_NOT_GIVEN
   fi
 
   if test x$ARG_RESULT = xtrue; then
@@ -573,7 +601,7 @@
   UTIL_SETUP_TOOL($1, [AC_PATH_PROGS($1, $2, , $3)])
   if test "x[$]$1" = x; then
     AC_MSG_NOTICE([Required tool $2 not found in PATH, checking built-in])
-    if help $2 > /dev/null 2>&1; then
+    if command -v $2 > /dev/null 2>&1; then
       AC_MSG_NOTICE([Found $2 as shell built-in. Using it])
       $1="$2"
     else
--- a/make/common/JavaCompilation.gmk	Fri May 08 09:45:57 2020 +0530
+++ b/make/common/JavaCompilation.gmk	Fri May 08 09:52:42 2020 +0530
@@ -216,7 +216,7 @@
 
       # The port file contains the tcp/ip on which the server listens
       # and the cookie necessary to talk to the server.
-      $1_JAVA_SERVER_FLAGS := --server:portfile=$$(SJAVAC_SERVER_DIR)/server.port,sjavac=$$($1_ESCAPED_CMD)
+      $1_JAVA_SERVER_FLAGS := --server:portfile=$$(JAVAC_SERVER_DIR)/server.port,sjavac=$$($1_ESCAPED_CMD)
 
       # Always use small to launch client
       $1_JAVAC_CMD := $$(JAVA_SMALL) $$($1_JAVA_FLAGS) $$($1_JAVAC) $$($1_JAVA_SERVER_FLAGS)
--- a/make/conf/jib-profiles.js	Fri May 08 09:45:57 2020 +0530
+++ b/make/conf/jib-profiles.js	Fri May 08 09:52:42 2020 +0530
@@ -986,7 +986,7 @@
         macosx_x64: "Xcode10.1-MacOSX10.14+1.0",
         solaris_x64: "SS12u4-Solaris11u1+1.0",
         solaris_sparcv9: "SS12u6-Solaris11u3+1.0",
-        windows_x64: "VS2017-15.9.16+1.0",
+        windows_x64: "VS2019-16.5.3+1.0",
         linux_aarch64: "gcc9.2.0-OL7.6+1.0",
         linux_arm: "gcc8.2.0-Fedora27+1.0",
         linux_ppc64le: "gcc8.2.0-Fedora27+1.0",
--- a/make/hotspot/symbols/symbols-unix	Fri May 08 09:45:57 2020 +0530
+++ b/make/hotspot/symbols/symbols-unix	Fri May 08 09:52:42 2020 +0530
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2016, 2020, 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
@@ -122,6 +122,7 @@
 JVM_GetPrimitiveArrayElement
 JVM_GetProperties
 JVM_GetProtectionDomain
+JVM_GetRandomSeedForCDSDump
 JVM_GetRecordComponents
 JVM_GetSimpleBinaryName
 JVM_GetStackAccessControlContext
--- a/src/hotspot/cpu/zero/methodHandles_zero.cpp	Fri May 08 09:45:57 2020 +0530
+++ b/src/hotspot/cpu/zero/methodHandles_zero.cpp	Fri May 08 09:52:42 2020 +0530
@@ -24,6 +24,7 @@
  */
 
 #include "precompiled.hpp"
+#include "classfile/javaClasses.inline.hpp"
 #include "interpreter/cppInterpreterGenerator.hpp"
 #include "interpreter/interpreter.hpp"
 #include "interpreter/interpreterRuntime.hpp"
--- a/src/hotspot/os/aix/os_aix.cpp	Fri May 08 09:45:57 2020 +0530
+++ b/src/hotspot/os/aix/os_aix.cpp	Fri May 08 09:52:42 2020 +0530
@@ -1180,14 +1180,6 @@
 void os::abort(bool dump_core, void* siginfo, const void* context) {
   os::shutdown();
   if (dump_core) {
-#ifndef PRODUCT
-    fdStream out(defaultStream::output_fd());
-    out.print_raw("Current thread is ");
-    char buf[16];
-    jio_snprintf(buf, sizeof(buf), UINTX_FORMAT, os::current_thread_id());
-    out.print_raw_cr(buf);
-    out.print_raw_cr("Dumping core ...");
-#endif
     ::abort(); // dump core
   }
 
@@ -3549,10 +3541,9 @@
     return JNI_ERR;
   }
 
-  if (UseNUMA) {
-    UseNUMA = false;
-    warning("NUMA optimizations are not available on this OS.");
-  }
+  // Not supported.
+  FLAG_SET_ERGO(UseNUMA, false);
+  FLAG_SET_ERGO(UseNUMAInterleaving, false);
 
   if (MaxFDLimit) {
     // Set the number of file descriptors to max. print out error
--- a/src/hotspot/os/bsd/os_bsd.cpp	Fri May 08 09:45:57 2020 +0530
+++ b/src/hotspot/os/bsd/os_bsd.cpp	Fri May 08 09:52:42 2020 +0530
@@ -1070,14 +1070,6 @@
 void os::abort(bool dump_core, void* siginfo, const void* context) {
   os::shutdown();
   if (dump_core) {
-#ifndef PRODUCT
-    fdStream out(defaultStream::output_fd());
-    out.print_raw("Current thread is ");
-    char buf[16];
-    jio_snprintf(buf, sizeof(buf), UINTX_FORMAT, os::current_thread_id());
-    out.print_raw_cr(buf);
-    out.print_raw_cr("Dumping core ...");
-#endif
     ::abort(); // dump core
   }
 
@@ -3140,6 +3132,10 @@
     return JNI_ERR;
   }
 
+  // Not supported.
+  FLAG_SET_ERGO(UseNUMA, false);
+  FLAG_SET_ERGO(UseNUMAInterleaving, false);
+
   if (MaxFDLimit) {
     // set the number of file descriptors to max. print out error
     // if getrlimit/setrlimit fails but continue regardless.
--- a/src/hotspot/os/linux/os_linux.cpp	Fri May 08 09:45:57 2020 +0530
+++ b/src/hotspot/os/linux/os_linux.cpp	Fri May 08 09:52:42 2020 +0530
@@ -1520,14 +1520,6 @@
     if (DumpPrivateMappingsInCore) {
       ClassLoader::close_jrt_image();
     }
-#ifndef PRODUCT
-    fdStream out(defaultStream::output_fd());
-    out.print_raw("Current thread is ");
-    char buf[16];
-    jio_snprintf(buf, sizeof(buf), UINTX_FORMAT, os::current_thread_id());
-    out.print_raw_cr(buf);
-    out.print_raw_cr("Dumping core ...");
-#endif
     ::abort(); // dump core
   }
 
@@ -2060,7 +2052,7 @@
 }
 
 static void _print_ascii_file_h(const char* header, const char* filename, outputStream* st) {
-  st->print("%s", header);
+  st->print_cr("%s:", header);
   if (!_print_ascii_file(filename, st)) {
     st->print_cr("<Not Available>");
   }
@@ -2291,39 +2283,24 @@
 
 void os::Linux::print_proc_sys_info(outputStream* st) {
   st->cr();
-  st->print_cr("/proc/sys/kernel/threads-max (system-wide limit on the number of threads):");
-  _print_ascii_file("/proc/sys/kernel/threads-max", st);
-  st->cr();
-  st->cr();
-
-  st->print_cr("/proc/sys/vm/max_map_count (maximum number of memory map areas a process may have):");
-  _print_ascii_file("/proc/sys/vm/max_map_count", st);
-  st->cr();
-  st->cr();
-
-  st->print_cr("/proc/sys/kernel/pid_max (system-wide limit on number of process identifiers):");
-  _print_ascii_file("/proc/sys/kernel/pid_max", st);
-  st->cr();
-  st->cr();
+  _print_ascii_file_h("/proc/sys/kernel/threads-max (system-wide limit on the number of threads)",
+                      "/proc/sys/kernel/threads-max", st);
+  _print_ascii_file_h("/proc/sys/vm/max_map_count (maximum number of memory map areas a process may have)",
+                      "/proc/sys/vm/max_map_count", st);
+  _print_ascii_file_h("/proc/sys/kernel/pid_max (system-wide limit on number of process identifiers)",
+                      "/proc/sys/kernel/pid_max", st);
 }
 
 void os::Linux::print_full_memory_info(outputStream* st) {
-  st->print("\n/proc/meminfo:\n");
-  _print_ascii_file("/proc/meminfo", st);
+  _print_ascii_file_h("\n/proc/meminfo", "/proc/meminfo", st);
   st->cr();
 
   // some information regarding THPs; for details see
   // https://www.kernel.org/doc/Documentation/vm/transhuge.txt
-  st->print_cr("/sys/kernel/mm/transparent_hugepage/enabled:");
-  if (!_print_ascii_file("/sys/kernel/mm/transparent_hugepage/enabled", st)) {
-    st->print_cr("  <Not Available>");
-  }
-  st->cr();
-  st->print_cr("/sys/kernel/mm/transparent_hugepage/defrag (defrag/compaction efforts parameter):");
-  if (!_print_ascii_file("/sys/kernel/mm/transparent_hugepage/defrag", st)) {
-    st->print_cr("  <Not Available>");
-  }
-  st->cr();
+  _print_ascii_file_h("/sys/kernel/mm/transparent_hugepage/enabled",
+                      "/sys/kernel/mm/transparent_hugepage/enabled", st);
+  _print_ascii_file_h("/sys/kernel/mm/transparent_hugepage/defrag (defrag/compaction efforts parameter)",
+                      "/sys/kernel/mm/transparent_hugepage/defrag", st);
 }
 
 void os::Linux::print_ld_preload_file(outputStream* st) {
@@ -2510,8 +2487,8 @@
 
 // additional information about CPU e.g. available frequency ranges
 static void print_sys_devices_cpu_info(outputStream* st, char* buf, size_t buflen) {
-  _print_ascii_file_h("Online cpus:", "/sys/devices/system/cpu/online", st);
-  _print_ascii_file_h("Offline cpus:", "/sys/devices/system/cpu/offline", st);
+  _print_ascii_file_h("Online cpus", "/sys/devices/system/cpu/online", st);
+  _print_ascii_file_h("Offline cpus", "/sys/devices/system/cpu/offline", st);
 
   if (ExtensiveErrorReports) {
     // cache related info (cpu 0, should be similar for other CPUs)
@@ -2525,44 +2502,41 @@
       snprintf(hbuf_size, 60, "/sys/devices/system/cpu/cpu0/cache/index%u/size", i);
       snprintf(hbuf_coherency_line_size, 80, "/sys/devices/system/cpu/cpu0/cache/index%u/coherency_line_size", i);
       if (file_exists(hbuf_level)) {
-        _print_ascii_file_h("cache level:", hbuf_level, st);
-        _print_ascii_file_h("cache type:", hbuf_type, st);
-        _print_ascii_file_h("cache size:", hbuf_size, st);
-        _print_ascii_file_h("cache coherency line size:", hbuf_coherency_line_size, st);
+        _print_ascii_file_h("cache level", hbuf_level, st);
+        _print_ascii_file_h("cache type", hbuf_type, st);
+        _print_ascii_file_h("cache size", hbuf_size, st);
+        _print_ascii_file_h("cache coherency line size", hbuf_coherency_line_size, st);
       }
     }
   }
 
   // we miss the cpufreq entries on Power and s390x
 #if defined(IA32) || defined(AMD64)
-  _print_ascii_file_h("BIOS frequency limitation:", "/sys/devices/system/cpu/cpu0/cpufreq/bios_limit", st);
-  _print_ascii_file_h("Frequency switch latency (ns):", "/sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_transition_latency", st);
-  _print_ascii_file_h("Available cpu frequencies:", "/sys/devices/system/cpu/cpu0/cpufreq/scaling_available_frequencies", st);
+  _print_ascii_file_h("BIOS frequency limitation", "/sys/devices/system/cpu/cpu0/cpufreq/bios_limit", st);
+  _print_ascii_file_h("Frequency switch latency (ns)", "/sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_transition_latency", st);
+  _print_ascii_file_h("Available cpu frequencies", "/sys/devices/system/cpu/cpu0/cpufreq/scaling_available_frequencies", st);
   // min and max should be in the Available range but still print them (not all info might be available for all kernels)
   if (ExtensiveErrorReports) {
-    _print_ascii_file_h("Maximum cpu frequency:", "/sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq", st);
-    _print_ascii_file_h("Minimum cpu frequency:", "/sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_min_freq", st);
-    _print_ascii_file_h("Current cpu frequency:", "/sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq", st);
+    _print_ascii_file_h("Maximum cpu frequency", "/sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq", st);
+    _print_ascii_file_h("Minimum cpu frequency", "/sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_min_freq", st);
+    _print_ascii_file_h("Current cpu frequency", "/sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq", st);
   }
   // governors are power schemes, see https://wiki.archlinux.org/index.php/CPU_frequency_scaling
   if (ExtensiveErrorReports) {
-    _print_ascii_file_h("Available governors:", "/sys/devices/system/cpu/cpu0/cpufreq/scaling_available_governors", st);
-  }
-  _print_ascii_file_h("Current governor:", "/sys/devices/system/cpu/cpu0/cpufreq/scaling_governor", st);
+    _print_ascii_file_h("Available governors", "/sys/devices/system/cpu/cpu0/cpufreq/scaling_available_governors", st);
+  }
+  _print_ascii_file_h("Current governor", "/sys/devices/system/cpu/cpu0/cpufreq/scaling_governor", st);
   // Core performance boost, see https://www.kernel.org/doc/Documentation/cpu-freq/boost.txt
   // Raise operating frequency of some cores in a multi-core package if certain conditions apply, e.g.
   // whole chip is not fully utilized
-  _print_ascii_file_h("Core performance/turbo boost:", "/sys/devices/system/cpu/cpufreq/boost", st);
+  _print_ascii_file_h("Core performance/turbo boost", "/sys/devices/system/cpu/cpufreq/boost", st);
 #endif
 }
 
 void os::pd_print_cpu_info(outputStream* st, char* buf, size_t buflen) {
   // Only print the model name if the platform provides this as a summary
   if (!print_model_name_and_flags(st, buf, buflen)) {
-    st->print("\n/proc/cpuinfo:\n");
-    if (!_print_ascii_file("/proc/cpuinfo", st)) {
-      st->print_cr("  <Not Available>");
-    }
+    _print_ascii_file_h("\n/proc/cpuinfo", "/proc/cpuinfo", st);
   }
   print_sys_devices_cpu_info(st, buf, buflen);
 }
@@ -5175,7 +5149,8 @@
   // bitmask when externally configured to run on all or fewer nodes.
 
   if (!Linux::libnuma_init()) {
-    UseNUMA = false;
+    FLAG_SET_ERGO(UseNUMA, false);
+    FLAG_SET_ERGO(UseNUMAInterleaving, false); // Also depends on libnuma.
   } else {
     if ((Linux::numa_max_node() < 1) || Linux::is_bound_to_single_node()) {
       // If there's only one node (they start from 0) or if the process
@@ -5208,6 +5183,11 @@
     }
   }
 
+  // When NUMA requested, not-NUMA-aware allocations default to interleaving.
+  if (UseNUMA && !UseNUMAInterleaving) {
+    FLAG_SET_ERGO_IF_DEFAULT(UseNUMAInterleaving, true);
+  }
+
   if (UseParallelGC && UseNUMA && UseLargePages && !can_commit_large_page_memory()) {
     // With SHM and HugeTLBFS large pages we cannot uncommit a page, so there's no way
     // we can make the adaptive lgrp chunk resizing work. If the user specified both
@@ -5272,7 +5252,7 @@
   log_info(os)("HotSpot is running with %s, %s",
                Linux::glibc_version(), Linux::libpthread_version());
 
-  if (UseNUMA) {
+  if (UseNUMA || UseNUMAInterleaving) {
     Linux::numa_init();
   }
 
--- a/src/hotspot/os/posix/os_posix.cpp	Fri May 08 09:45:57 2020 +0530
+++ b/src/hotspot/os/posix/os_posix.cpp	Fri May 08 09:52:42 2020 +0530
@@ -1967,7 +1967,8 @@
     while (_event < 0) {
       // OS-level "spurious wakeups" are ignored
       status = pthread_cond_wait(_cond, _mutex);
-      assert_status(status == 0, status, "cond_wait");
+      assert_status(status == 0 MACOS_ONLY(|| status == ETIMEDOUT),
+                    status, "cond_wait");
     }
     --_nParked;
 
@@ -2158,7 +2159,8 @@
   if (time == 0) {
     _cur_index = REL_INDEX; // arbitrary choice when not timed
     status = pthread_cond_wait(&_cond[_cur_index], _mutex);
-    assert_status(status == 0, status, "cond_timedwait");
+    assert_status(status == 0 MACOS_ONLY(|| status == ETIMEDOUT),
+                  status, "cond_wait");
   }
   else {
     _cur_index = isAbsolute ? ABS_INDEX : REL_INDEX;
@@ -2339,7 +2341,8 @@
     return ret;
   } else {
     int status = pthread_cond_wait(cond(), mutex());
-    assert_status(status == 0, status, "cond_wait");
+    assert_status(status == 0 MACOS_ONLY(|| status == ETIMEDOUT),
+                  status, "cond_wait");
     return OS_OK;
   }
 }
--- a/src/hotspot/os/solaris/os_solaris.cpp	Fri May 08 09:45:57 2020 +0530
+++ b/src/hotspot/os/solaris/os_solaris.cpp	Fri May 08 09:52:42 2020 +0530
@@ -1147,14 +1147,6 @@
 void os::abort(bool dump_core, void* siginfo, const void* context) {
   os::shutdown();
   if (dump_core) {
-#ifndef PRODUCT
-    fdStream out(defaultStream::output_fd());
-    out.print_raw("Current thread is ");
-    char buf[16];
-    jio_snprintf(buf, sizeof(buf), UINTX_FORMAT, os::current_thread_id());
-    out.print_raw_cr(buf);
-    out.print_raw_cr("Dumping core ...");
-#endif
     ::abort(); // dump core (for debugging)
   }
 
@@ -3916,7 +3908,7 @@
 
   if (UseNUMA) {
     if (!Solaris::liblgrp_init()) {
-      UseNUMA = false;
+      FLAG_SET_ERGO(UseNUMA, false);
     } else {
       size_t lgrp_limit = os::numa_get_groups_num();
       int *lgrp_ids = NEW_C_HEAP_ARRAY(int, lgrp_limit, mtInternal);
@@ -3930,6 +3922,11 @@
     }
   }
 
+  // When NUMA requested, not-NUMA-aware allocations default to interleaving.
+  if (UseNUMA && !UseNUMAInterleaving) {
+    FLAG_SET_ERGO_IF_DEFAULT(UseNUMAInterleaving, true);
+  }
+
   Solaris::signal_sets_init();
   Solaris::init_signal_mem();
   Solaris::install_signal_handlers();
--- a/src/hotspot/os/windows/os_windows.cpp	Fri May 08 09:45:57 2020 +0530
+++ b/src/hotspot/os/windows/os_windows.cpp	Fri May 08 09:52:42 2020 +0530
@@ -4096,10 +4096,13 @@
     UseNUMA = false; // We don't fully support this yet
   }
 
-  if (UseNUMAInterleaving) {
-    // first check whether this Windows OS supports VirtualAllocExNuma, if not ignore this flag
-    bool success = numa_interleaving_init();
-    if (!success) UseNUMAInterleaving = false;
+  if (UseNUMAInterleaving || (UseNUMA && FLAG_IS_DEFAULT(UseNUMAInterleaving))) {
+    if (!numa_interleaving_init()) {
+      FLAG_SET_ERGO(UseNUMAInterleaving, false);
+    } else if (!UseNUMAInterleaving) {
+      // When NUMA requested, not-NUMA-aware allocations default to interleaving.
+      FLAG_SET_ERGO(UseNUMAInterleaving, true);
+    }
   }
 
   if (initSock() != JNI_OK) {
--- a/src/hotspot/share/c1/c1_Runtime1.cpp	Fri May 08 09:45:57 2020 +0530
+++ b/src/hotspot/share/c1/c1_Runtime1.cpp	Fri May 08 09:52:42 2020 +0530
@@ -30,6 +30,7 @@
 #include "c1/c1_LIRAssembler.hpp"
 #include "c1/c1_MacroAssembler.hpp"
 #include "c1/c1_Runtime1.hpp"
+#include "classfile/javaClasses.inline.hpp"
 #include "classfile/systemDictionary.hpp"
 #include "classfile/vmSymbols.hpp"
 #include "code/codeBlob.hpp"
--- a/src/hotspot/share/classfile/classListParser.cpp	Fri May 08 09:45:57 2020 +0530
+++ b/src/hotspot/share/classfile/classListParser.cpp	Fri May 08 09:52:42 2020 +0530
@@ -27,6 +27,7 @@
 #include "jimage.hpp"
 #include "classfile/classListParser.hpp"
 #include "classfile/classLoaderExt.hpp"
+#include "classfile/javaClasses.inline.hpp"
 #include "classfile/symbolTable.hpp"
 #include "classfile/systemDictionary.hpp"
 #include "classfile/systemDictionaryShared.hpp"
--- a/src/hotspot/share/classfile/classLoader.cpp	Fri May 08 09:45:57 2020 +0530
+++ b/src/hotspot/share/classfile/classLoader.cpp	Fri May 08 09:52:42 2020 +0530
@@ -95,6 +95,7 @@
 static ReadEntry_t       ReadEntry          = NULL;
 static GetNextEntry_t    GetNextEntry       = NULL;
 static Crc32_t           Crc32              = NULL;
+int ClassLoader::_libzip_loaded = 0;
 
 // Entry points for jimage.dll for loading jimage file entries
 
@@ -747,6 +748,7 @@
         // enable call to C land
         ThreadToNativeFromVM ttn(thread);
         HandleMark hm(thread);
+        load_zip_library_if_needed();
         zip = (*ZipOpen)(canonical_path, &error_msg);
       }
       if (zip != NULL && error_msg == NULL) {
@@ -796,6 +798,7 @@
           JavaThread* thread = JavaThread::current();
           ThreadToNativeFromVM ttn(thread);
           HandleMark hm(thread);
+          load_zip_library_if_needed();
           zip = (*ZipOpen)(canonical_path, &error_msg);
         }
         if (zip != NULL && error_msg == NULL) {
@@ -967,6 +970,14 @@
   CanonicalizeEntry = CAST_TO_FN_PTR(canonicalize_fn_t, dll_lookup(javalib_handle, "JDK_Canonicalize", NULL));
 }
 
+void ClassLoader::release_load_zip_library() {
+  MutexLocker locker(Zip_lock, Monitor::_no_safepoint_check_flag);
+  if (_libzip_loaded == 0) {
+    load_zip_library();
+    Atomic::release_store(&_libzip_loaded, 1);
+  }
+}
+
 void ClassLoader::load_zip_library() {
   assert(ZipOpen == NULL, "should not load zip library twice");
   char path[JVM_MAXPATHLEN];
@@ -1008,6 +1019,7 @@
 }
 
 int ClassLoader::crc32(int crc, const char* buf, int len) {
+  load_zip_library_if_needed();
   return (*Crc32)(crc, (const jbyte*)buf, len);
 }
 
@@ -1466,8 +1478,6 @@
 
   // lookup java library entry points
   load_java_library();
-  // lookup zip library entry points
-  load_zip_library();
   // jimage library entry points are loaded below, in lookup_vm_options
   setup_bootstrap_search_path();
 }
--- a/src/hotspot/share/classfile/classLoader.hpp	Fri May 08 09:45:57 2020 +0530
+++ b/src/hotspot/share/classfile/classLoader.hpp	Fri May 08 09:52:42 2020 +0530
@@ -252,6 +252,11 @@
   static void load_zip_library();
   static void load_jimage_library();
 
+ private:
+  static int  _libzip_loaded; // used to sync loading zip.
+  static void release_load_zip_library();
+  static inline void load_zip_library_if_needed();
+
  public:
   static ClassPathEntry* create_class_path_entry(const char *path, const struct stat* st,
                                                  bool throw_exception,
--- a/src/hotspot/share/classfile/classLoader.inline.hpp	Fri May 08 09:45:57 2020 +0530
+++ b/src/hotspot/share/classfile/classLoader.inline.hpp	Fri May 08 09:52:42 2020 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018, 2020, 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,6 +56,12 @@
   }
 }
 
+inline void ClassLoader::load_zip_library_if_needed() {
+  if (Atomic::load_acquire(&_libzip_loaded) == 0) {
+    release_load_zip_library();
+  }
+}
+
 #if INCLUDE_CDS
 
 // Helper function used by CDS code to get the number of boot classpath
--- a/src/hotspot/share/classfile/javaClasses.cpp	Fri May 08 09:45:57 2020 +0530
+++ b/src/hotspot/share/classfile/javaClasses.cpp	Fri May 08 09:52:42 2020 +0530
@@ -1495,14 +1495,6 @@
 }
 
 
-Klass* java_lang_Class::as_Klass(oop java_class) {
-  //%note memory_2
-  assert(java_lang_Class::is_instance(java_class), "must be a Class object");
-  Klass* k = ((Klass*)java_class->metadata_field(_klass_offset));
-  assert(k == NULL || k->is_klass(), "type check");
-  return k;
-}
-
 Klass* java_lang_Class::as_Klass_raw(oop java_class) {
   //%note memory_2
   assert(java_lang_Class::is_instance(java_class), "must be a Class object");
--- a/src/hotspot/share/classfile/javaClasses.inline.hpp	Fri May 08 09:45:57 2020 +0530
+++ b/src/hotspot/share/classfile/javaClasses.inline.hpp	Fri May 08 09:52:42 2020 +0530
@@ -211,6 +211,14 @@
   return obj != NULL && obj->klass() == SystemDictionary::Class_klass();
 }
 
+inline Klass* java_lang_Class::as_Klass(oop java_class) {
+  //%note memory_2
+  assert(java_lang_Class::is_instance(java_class), "must be a Class object");
+  Klass* k = ((Klass*)java_class->metadata_field(_klass_offset));
+  assert(k == NULL || k->is_klass(), "type check");
+  return k;
+}
+
 inline bool java_lang_Class::is_primitive(oop java_class) {
   // should assert:
   //assert(java_lang_Class::is_instance(java_class), "must be a Class object");
--- a/src/hotspot/share/classfile/symbolTable.cpp	Fri May 08 09:45:57 2020 +0530
+++ b/src/hotspot/share/classfile/symbolTable.cpp	Fri May 08 09:52:42 2020 +0530
@@ -176,6 +176,11 @@
 }
 
 void SymbolTable::delete_symbol(Symbol* sym) {
+  if (Arguments::is_dumping_archive()) {
+    // Do not delete symbols as we may be in the middle of preparing the
+    // symbols for dumping.
+    return;
+  }
   if (sym->is_permanent()) {
     MutexLocker ml(SymbolArena_lock, Mutex::_no_safepoint_check_flag); // Protect arena
     // Deleting permanent symbol should not occur very often (insert race condition),
@@ -221,12 +226,18 @@
 
   Symbol* sym;
   if (Arguments::is_dumping_archive()) {
+    // Need to make all symbols permanent -- or else some symbols may be GC'ed
+    // during the archive dumping code that's executed outside of a safepoint.
     c_heap = false;
   }
   if (c_heap) {
     // refcount starts as 1
     sym = new (len) Symbol((const u1*)name, len, 1);
     assert(sym != NULL, "new should call vm_exit_out_of_memory if C_HEAP is exhausted");
+  } else if (DumpSharedSpaces) {
+    // See comments inside Symbol::operator new(size_t, int)
+    sym = new (len) Symbol((const u1*)name, len, PERM_REFCOUNT);
+    assert(sym != NULL, "new should call vm_exit_out_of_memory if failed to allocate symbol during DumpSharedSpaces");
   } else {
     // Allocate to global arena
     MutexLocker ml(SymbolArena_lock, Mutex::_no_safepoint_check_flag); // Protect arena
--- a/src/hotspot/share/classfile/systemDictionary.cpp	Fri May 08 09:45:57 2020 +0530
+++ b/src/hotspot/share/classfile/systemDictionary.cpp	Fri May 08 09:52:42 2020 +0530
@@ -2336,12 +2336,14 @@
     InstanceKlass* klass2 = find_class(d_hash2, constraint_name, dictionary2);
     bool result = constraints()->add_entry(constraint_name, klass1, class_loader1,
                                            klass2, class_loader2);
+#if INCLUDE_CDS
     if (Arguments::is_dumping_archive() && klass_being_linked != NULL &&
         !klass_being_linked->is_shared()) {
          SystemDictionaryShared::record_linking_constraint(constraint_name,
                                      InstanceKlass::cast(klass_being_linked),
                                      class_loader1, class_loader2, THREAD);
     }
+#endif // INCLUDE_CDS
     if (Signature::is_array(class_name)) {
       constraint_name->decrement_refcount();
     }
--- a/src/hotspot/share/classfile/systemDictionaryShared.cpp	Fri May 08 09:45:57 2020 +0530
+++ b/src/hotspot/share/classfile/systemDictionaryShared.cpp	Fri May 08 09:52:42 2020 +0530
@@ -174,10 +174,22 @@
   }
 };
 
+inline unsigned DumpTimeSharedClassTable_hash(InstanceKlass* const& k) {
+  if (DumpSharedSpaces) {
+    // Deterministic archive contents
+    uintx delta = k->name() - MetaspaceShared::symbol_rs_base();
+    return primitive_hash<uintx>(delta);
+  } else {
+    // Deterministic archive is not possible because classes can be loaded
+    // in multiple threads.
+    return primitive_hash<InstanceKlass*>(k);
+  }
+}
+
 class DumpTimeSharedClassTable: public ResourceHashtable<
   InstanceKlass*,
   DumpTimeSharedClassInfo,
-  primitive_hash<InstanceKlass*>,
+  &DumpTimeSharedClassTable_hash,
   primitive_equals<InstanceKlass*>,
   15889, // prime number
   ResourceObj::C_HEAP>
--- a/src/hotspot/share/compiler/compileTask.cpp	Fri May 08 09:45:57 2020 +0530
+++ b/src/hotspot/share/compiler/compileTask.cpp	Fri May 08 09:52:42 2020 +0530
@@ -33,9 +33,6 @@
 #include "runtime/handles.inline.hpp"
 
 CompileTask*  CompileTask::_task_free_list = NULL;
-#ifdef ASSERT
-int CompileTask::_num_allocated_tasks = 0;
-#endif
 
 /**
  * Allocate a CompileTask, from the free list if possible.
@@ -50,8 +47,6 @@
     task->set_next(NULL);
   } else {
     task = new CompileTask();
-    DEBUG_ONLY(_num_allocated_tasks++;)
-    assert (WhiteBoxAPI || JVMCI_ONLY(UseJVMCICompiler ||) _num_allocated_tasks < 10000, "Leaking compilation tasks?");
     task->set_next(NULL);
     task->set_is_free(true);
   }
--- a/src/hotspot/share/compiler/compileTask.hpp	Fri May 08 09:45:57 2020 +0530
+++ b/src/hotspot/share/compiler/compileTask.hpp	Fri May 08 09:52:42 2020 +0530
@@ -75,10 +75,6 @@
 
  private:
   static CompileTask* _task_free_list;
-#ifdef ASSERT
-  static int          _num_allocated_tasks;
-#endif
-
   Monitor*     _lock;
   uint         _compile_id;
   Method*      _method;
--- a/src/hotspot/share/gc/g1/g1RegionToSpaceMapper.cpp	Fri May 08 09:45:57 2020 +0530
+++ b/src/hotspot/share/gc/g1/g1RegionToSpaceMapper.cpp	Fri May 08 09:52:42 2020 +0530
@@ -46,7 +46,7 @@
   _listener(NULL),
   _storage(rs, used_size, page_size),
   _region_granularity(region_granularity),
-  _commit_map(rs.size() * commit_factor / region_granularity, mtGC),
+  _region_commit_map(rs.size() * commit_factor / region_granularity, mtGC),
   _memory_type(type) {
   guarantee(is_power_of_2(page_size), "must be");
   guarantee(is_power_of_2(region_granularity), "must be");
@@ -88,13 +88,13 @@
     if (AlwaysPreTouch) {
       _storage.pretouch(start_page, size_in_pages, pretouch_gang);
     }
-    _commit_map.set_range(start_idx, start_idx + num_regions);
+    _region_commit_map.set_range(start_idx, start_idx + num_regions);
     fire_on_commit(start_idx, num_regions, zero_filled);
   }
 
   virtual void uncommit_regions(uint start_idx, size_t num_regions) {
     _storage.uncommit((size_t)start_idx * _pages_per_region, num_regions * _pages_per_region);
-    _commit_map.clear_range(start_idx, start_idx + num_regions);
+    _region_commit_map.clear_range(start_idx, start_idx + num_regions);
   }
 };
 
@@ -102,18 +102,26 @@
 // than the commit granularity.
 // Basically, the contents of one OS page span several regions.
 class G1RegionsSmallerThanCommitSizeMapper : public G1RegionToSpaceMapper {
- private:
-  class CommitRefcountArray : public G1BiasedMappedArray<uint> {
-   protected:
-     virtual uint default_value() const { return 0; }
-  };
-
   size_t _regions_per_page;
 
-  CommitRefcountArray _refcounts;
+  size_t region_idx_to_page_idx(uint region_idx) const {
+    return region_idx / _regions_per_page;
+  }
 
-  uintptr_t region_idx_to_page_idx(uint region) const {
-    return region / _regions_per_page;
+  bool is_page_committed(size_t page_idx) {
+    size_t region = page_idx * _regions_per_page;
+    size_t region_limit = region + _regions_per_page;
+    // Committed if there is a bit set in the range.
+    return _region_commit_map.get_next_one_offset(region, region_limit) != region_limit;
+  }
+
+  void numa_request_on_node(size_t page_idx) {
+    if (_memory_type == mtJavaHeap) {
+      uint region = (uint)(page_idx * _regions_per_page);
+      void* address = _storage.page_start(page_idx);
+      size_t size_in_bytes = _storage.page_size();
+      G1NUMA::numa()->request_memory_on_node(address, size_in_bytes, region);
+    }
   }
 
  public:
@@ -124,63 +132,76 @@
                                        size_t commit_factor,
                                        MemoryType type) :
     G1RegionToSpaceMapper(rs, actual_size, page_size, alloc_granularity, commit_factor, type),
-    _regions_per_page((page_size * commit_factor) / alloc_granularity), _refcounts() {
+    _regions_per_page((page_size * commit_factor) / alloc_granularity) {
 
     guarantee((page_size * commit_factor) >= alloc_granularity, "allocation granularity smaller than commit granularity");
-    _refcounts.initialize((HeapWord*)rs.base(), (HeapWord*)(rs.base() + align_up(rs.size(), page_size)), page_size);
   }
 
   virtual void commit_regions(uint start_idx, size_t num_regions, WorkGang* pretouch_gang) {
+    uint region_limit = (uint)(start_idx + num_regions);
+    assert(num_regions > 0, "Must commit at least one region");
+    assert(_region_commit_map.get_next_one_offset(start_idx, region_limit) == region_limit,
+           "Should be no committed regions in the range [%u, %u)", start_idx, region_limit);
+
     size_t const NoPage = ~(size_t)0;
 
     size_t first_committed = NoPage;
     size_t num_committed = 0;
 
-    bool all_zero_filled = true;
-    G1NUMA* numa = G1NUMA::numa();
+    size_t start_page = region_idx_to_page_idx(start_idx);
+    size_t end_page = region_idx_to_page_idx(region_limit - 1);
 
-    for (uint region_idx = start_idx; region_idx < start_idx + num_regions; region_idx++) {
-      assert(!_commit_map.at(region_idx), "Trying to commit storage at region %u that is already committed", region_idx);
-      size_t page_idx = region_idx_to_page_idx(region_idx);
-      uint old_refcount = _refcounts.get_by_index(page_idx);
+    bool all_zero_filled = true;
+    for (size_t page = start_page; page <= end_page; page++) {
+      if (!is_page_committed(page)) {
+        // Page not committed.
+        if (num_committed == 0) {
+          first_committed = page;
+        }
+        num_committed++;
 
-      bool zero_filled = false;
-      if (old_refcount == 0) {
-        if (first_committed == NoPage) {
-          first_committed = page_idx;
-          num_committed = 1;
-        } else {
-          num_committed++;
+        if (!_storage.commit(page, 1)) {
+          // Found dirty region during commit.
+          all_zero_filled = false;
         }
-        zero_filled = _storage.commit(page_idx, 1);
-        if (_memory_type == mtJavaHeap) {
-          void* address = _storage.page_start(page_idx);
-          size_t size_in_bytes = _storage.page_size();
-          numa->request_memory_on_node(address, size_in_bytes, region_idx);
-        }
+
+        // Move memory to correct NUMA node for the heap.
+        numa_request_on_node(page);
+      } else {
+        // Page already committed.
+        all_zero_filled = false;
       }
-      all_zero_filled &= zero_filled;
+    }
 
-      _refcounts.set_by_index(page_idx, old_refcount + 1);
-      _commit_map.set_bit(region_idx);
-    }
+    // Update the commit map for the given range.
+    _region_commit_map.set_range(start_idx, region_limit);
+
     if (AlwaysPreTouch && num_committed > 0) {
       _storage.pretouch(first_committed, num_committed, pretouch_gang);
     }
+
     fire_on_commit(start_idx, num_regions, all_zero_filled);
   }
 
   virtual void uncommit_regions(uint start_idx, size_t num_regions) {
-    for (uint i = start_idx; i < start_idx + num_regions; i++) {
-      assert(_commit_map.at(i), "Trying to uncommit storage at region %u that is not committed", i);
-      size_t idx = region_idx_to_page_idx(i);
-      uint old_refcount = _refcounts.get_by_index(idx);
-      assert(old_refcount > 0, "must be");
-      if (old_refcount == 1) {
-        _storage.uncommit(idx, 1);
+    uint region_limit = (uint)(start_idx + num_regions);
+    assert(num_regions > 0, "Must uncommit at least one region");
+    assert(_region_commit_map.get_next_zero_offset(start_idx, region_limit) == region_limit,
+           "Should only be committed regions in the range [%u, %u)", start_idx, region_limit);
+
+    size_t start_page = region_idx_to_page_idx(start_idx);
+    size_t end_page = region_idx_to_page_idx(region_limit - 1);
+
+    // Clear commit map for the given range.
+    _region_commit_map.clear_range(start_idx, region_limit);
+
+    for (size_t page = start_page; page <= end_page; page++) {
+      // We know all pages were committed before clearing the map. If the
+      // the page is still marked as committed after the clear we should
+      // not uncommit it.
+      if (!is_page_committed(page)) {
+        _storage.uncommit(page, 1);
       }
-      _refcounts.set_by_index(idx, old_refcount - 1);
-      _commit_map.clear_bit(i);
     }
   }
 };
--- a/src/hotspot/share/gc/g1/g1RegionToSpaceMapper.hpp	Fri May 08 09:45:57 2020 +0530
+++ b/src/hotspot/share/gc/g1/g1RegionToSpaceMapper.hpp	Fri May 08 09:52:42 2020 +0530
@@ -51,7 +51,7 @@
 
   size_t _region_granularity;
   // Mapping management
-  CHeapBitMap _commit_map;
+  CHeapBitMap _region_commit_map;
 
   MemoryType _memory_type;
 
@@ -68,10 +68,6 @@
 
   virtual ~G1RegionToSpaceMapper() {}
 
-  bool is_committed(uintptr_t idx) const {
-    return _commit_map.at(idx);
-  }
-
   void commit_and_set_special();
   virtual void commit_regions(uint start_idx, size_t num_regions = 1, WorkGang* pretouch_workers = NULL) = 0;
   virtual void uncommit_regions(uint start_idx, size_t num_regions = 1) = 0;
--- a/src/hotspot/share/gc/shared/taskTerminator.cpp	Fri May 08 09:45:57 2020 +0530
+++ b/src/hotspot/share/gc/shared/taskTerminator.cpp	Fri May 08 09:52:42 2020 +0530
@@ -39,8 +39,10 @@
 }
 
 TaskTerminator::~TaskTerminator() {
-  assert(_offered_termination == 0 || !peek_in_queue_set(), "Precondition");
-  assert(_offered_termination == 0 || _offered_termination == _n_threads, "Terminated or aborted" );
+  if (_offered_termination != 0) {
+    assert(_offered_termination == _n_threads, "Must be terminated or aborted");
+    assert_queue_set_empty();
+  }
 
   assert(_spin_master == NULL, "Should have been reset");
   assert(_blocker != NULL, "Can not be NULL");
@@ -48,8 +50,8 @@
 }
 
 #ifdef ASSERT
-bool TaskTerminator::peek_in_queue_set() {
-  return _queue_set->peek();
+void TaskTerminator::assert_queue_set_empty() const {
+  _queue_set->assert_empty();
 }
 #endif
 
@@ -87,7 +89,7 @@
   // Single worker, done
   if (_n_threads == 1) {
     _offered_termination = 1;
-    assert(!peek_in_queue_set(), "Precondition");
+    assert_queue_set_empty();
     return true;
   }
 
@@ -97,7 +99,7 @@
   if (_offered_termination == _n_threads) {
     _blocker->notify_all();
     _blocker->unlock();
-    assert(!peek_in_queue_set(), "Precondition");
+    assert_queue_set_empty();
     return true;
   }
 
@@ -110,7 +112,7 @@
 
       if (do_spin_master_work(terminator)) {
         assert(_offered_termination == _n_threads, "termination condition");
-        assert(!peek_in_queue_set(), "Precondition");
+        assert_queue_set_empty();
         return true;
       } else {
         _blocker->lock_without_safepoint_check();
@@ -118,7 +120,7 @@
         // before returning from do_spin_master_work() and acquiring lock above.
         if (_offered_termination == _n_threads) {
           _blocker->unlock();
-          assert(!peek_in_queue_set(), "Precondition");
+          assert_queue_set_empty();
           return true;
         }
       }
@@ -127,7 +129,7 @@
 
       if (_offered_termination == _n_threads) {
         _blocker->unlock();
-        assert(!peek_in_queue_set(), "Precondition");
+        assert_queue_set_empty();
         return true;
       }
     }
--- a/src/hotspot/share/gc/shared/taskTerminator.hpp	Fri May 08 09:45:57 2020 +0530
+++ b/src/hotspot/share/gc/shared/taskTerminator.hpp	Fri May 08 09:52:42 2020 +0530
@@ -57,9 +57,8 @@
   volatile uint _offered_termination;
   DEFINE_PAD_MINUS_SIZE(1, DEFAULT_CACHE_LINE_SIZE, sizeof(volatile uint));
 
-#ifdef ASSERT
-  bool peek_in_queue_set();
-#endif
+  void assert_queue_set_empty() const NOT_DEBUG_RETURN;
+
   void yield();
 
   Monitor*    _blocker;
--- a/src/hotspot/share/gc/shared/taskqueue.hpp	Fri May 08 09:45:57 2020 +0530
+++ b/src/hotspot/share/gc/shared/taskqueue.hpp	Fri May 08 09:52:42 2020 +0530
@@ -202,12 +202,24 @@
     // threads attempting to perform the pop_global will all perform the same
     // CAS, and only one can succeed.)  Any stealing thread that reads after
     // either the increment or decrement will see an empty queue, and will not
-    // join the competitors.  The "sz == -1 || sz == N-1" state will not be
-    // modified by concurrent queues, so the owner thread can reset the state to
-    // _bottom == top so subsequent pushes will be performed normally.
+    // join the competitors.  The "sz == -1" / "sz == N-1" state will not be
+    // modified by concurrent threads, so the owner thread can reset the state
+    // to _bottom == top so subsequent pushes will be performed normally.
     return (sz == N - 1) ? 0 : sz;
   }
 
+  // Assert that we're not in the underflow state where bottom has
+  // been decremented past top, so that _bottom+1 mod N == top.  See
+  // the discussion in clean_size.
+
+  void assert_not_underflow(uint bot, uint top) const {
+    assert_not_underflow(dirty_size(bot, top));
+  }
+
+  void assert_not_underflow(uint dirty_size) const {
+    assert(dirty_size != N - 1, "invariant");
+  }
+
 private:
   DEFINE_PAD_MINUS_SIZE(0, DEFAULT_CACHE_LINE_SIZE, 0);
 
@@ -228,10 +240,10 @@
 public:
   TaskQueueSuper() : _bottom(0), _age() {}
 
-  // Return true if the TaskQueue contains any tasks.
+  // Assert the queue is empty.
   // Unreliable if there are concurrent pushes or pops.
-  bool peek() const {
-    return bottom_relaxed() != age_top_relaxed();
+  void assert_empty() const {
+    assert(bottom_relaxed() == age_top_relaxed(), "not empty");
   }
 
   bool is_empty() const {
@@ -313,6 +325,7 @@
   using TaskQueueSuper<N, F>::decrement_index;
   using TaskQueueSuper<N, F>::dirty_size;
   using TaskQueueSuper<N, F>::clean_size;
+  using TaskQueueSuper<N, F>::assert_not_underflow;
 
 public:
   using TaskQueueSuper<N, F>::max_elems;
@@ -426,8 +439,10 @@
 
 class TaskQueueSetSuper {
 public:
-  // Returns "true" if some TaskQueue in the set contains a task.
-  virtual bool peek() = 0;
+  // Assert all queues in the set are empty.
+  NOT_DEBUG(void assert_empty() const {})
+  DEBUG_ONLY(virtual void assert_empty() const = 0;)
+
   // Tasks in queue
   virtual uint tasks() const = 0;
 };
@@ -458,8 +473,9 @@
   // Returns if stealing succeeds, and sets "t" to the stolen task.
   bool steal(uint queue_num, E& t);
 
-  bool peek();
-  uint tasks() const;
+  DEBUG_ONLY(virtual void assert_empty() const;)
+
+  virtual uint tasks() const;
 
   uint size() const { return _n; }
 };
@@ -475,15 +491,14 @@
   return _queues[i];
 }
 
+#ifdef ASSERT
 template<class T, MEMFLAGS F>
-bool GenericTaskQueueSet<T, F>::peek() {
-  // Try all the queues.
+void GenericTaskQueueSet<T, F>::assert_empty() const {
   for (uint j = 0; j < _n; j++) {
-    if (_queues[j]->peek())
-      return true;
+    _queues[j]->assert_empty();
   }
-  return false;
 }
+#endif // ASSERT
 
 template<class T, MEMFLAGS F>
 uint GenericTaskQueueSet<T, F>::tasks() const {
--- a/src/hotspot/share/gc/shared/taskqueue.inline.hpp	Fri May 08 09:45:57 2020 +0530
+++ b/src/hotspot/share/gc/shared/taskqueue.inline.hpp	Fri May 08 09:52:42 2020 +0530
@@ -123,7 +123,7 @@
     Age tempAge = cmpxchg_age(oldAge, newAge);
     if (tempAge == oldAge) {
       // We win.
-      assert(dirty_size(localBot, age_top_relaxed()) != N - 1, "sanity");
+      assert_not_underflow(localBot, age_top_relaxed());
       TASKQUEUE_STATS_ONLY(stats.record_pop_slow());
       return true;
     }
@@ -132,7 +132,7 @@
   // and top is greater than bottom.  Fix this representation of the empty queue
   // to become the canonical one.
   set_age_relaxed(newAge);
-  assert(dirty_size(localBot, age_top_relaxed()) != N - 1, "sanity");
+  assert_not_underflow(localBot, age_top_relaxed());
   return false;
 }
 
@@ -144,7 +144,7 @@
   // resets the size to 0 before the next call (which is sequential,
   // since this is pop_local.)
   uint dirty_n_elems = dirty_size(localBot, age_top_relaxed());
-  assert(dirty_n_elems != N - 1, "Shouldn't be possible...");
+  assert_not_underflow(dirty_n_elems);
   if (dirty_n_elems <= threshold) return false;
   localBot = decrement_index(localBot);
   set_bottom_relaxed(localBot);
@@ -158,7 +158,7 @@
   // a "pop_global" operation, and we're done.
   idx_t tp = age_top_relaxed();
   if (clean_size(localBot, tp) > 0) {
-    assert(dirty_size(localBot, tp) != N - 1, "sanity");
+    assert_not_underflow(localBot, tp);
     TASKQUEUE_STATS_ONLY(stats.record_pop());
     return true;
   } else {
@@ -241,7 +241,7 @@
 
   // Note that using "bottom" here might fail, since a pop_local might
   // have decremented it.
-  assert(dirty_size(localBot, newAge.top()) != N - 1, "sanity");
+  assert_not_underflow(localBot, newAge.top());
   return resAge == oldAge;
 }
 
--- a/src/hotspot/share/gc/shenandoah/c2/shenandoahBarrierSetC2.cpp	Fri May 08 09:45:57 2020 +0530
+++ b/src/hotspot/share/gc/shenandoah/c2/shenandoahBarrierSetC2.cpp	Fri May 08 09:52:42 2020 +0530
@@ -481,16 +481,16 @@
   return TypeFunc::make(domain, range);
 }
 
-const TypeFunc* ShenandoahBarrierSetC2::shenandoah_load_reference_barrier_Type() {
+const TypeFunc* ShenandoahBarrierSetC2::shenandoah_load_reference_barrier_Type(const Type* value_type) {
   const Type **fields = TypeTuple::fields(2);
-  fields[TypeFunc::Parms+0] = TypeInstPtr::NOTNULL; // original field value
+  fields[TypeFunc::Parms+0] = value_type;           // original field value
   fields[TypeFunc::Parms+1] = TypeRawPtr::BOTTOM;   // original load address
 
   const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+2, fields);
 
   // create result type (range)
   fields = TypeTuple::fields(1);
-  fields[TypeFunc::Parms+0] = TypeInstPtr::NOTNULL;
+  fields[TypeFunc::Parms+0] = value_type;
   const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+1, fields);
 
   return TypeFunc::make(domain, range);
@@ -1059,37 +1059,10 @@
       }
     }
   }
-  if (n->Opcode() == Op_CmpP) {
-    Node* in1 = n->in(1);
-    Node* in2 = n->in(2);
-    if (in1->bottom_type() == TypePtr::NULL_PTR) {
-      in2 = step_over_gc_barrier(in2);
-    }
-    if (in2->bottom_type() == TypePtr::NULL_PTR) {
-      in1 = step_over_gc_barrier(in1);
-    }
-    PhaseIterGVN* igvn = phase->is_IterGVN();
-    if (in1 != n->in(1)) {
-      if (igvn != NULL) {
-        n->set_req_X(1, in1, igvn);
-      } else {
-        n->set_req(1, in1);
-      }
-      assert(in2 == n->in(2), "only one change");
-      return n;
-    }
-    if (in2 != n->in(2)) {
-      if (igvn != NULL) {
-        n->set_req_X(2, in2, igvn);
-      } else {
-        n->set_req(2, in2);
-      }
-      return n;
-    }
-  } else if (can_reshape &&
-             n->Opcode() == Op_If &&
-             ShenandoahBarrierC2Support::is_heap_stable_test(n) &&
-             n->in(0) != NULL) {
+  if (can_reshape &&
+      n->Opcode() == Op_If &&
+      ShenandoahBarrierC2Support::is_heap_stable_test(n) &&
+      n->in(0) != NULL) {
     Node* dom = n->in(0);
     Node* prev_dom = n;
     int op = n->Opcode();
--- a/src/hotspot/share/gc/shenandoah/c2/shenandoahBarrierSetC2.hpp	Fri May 08 09:45:57 2020 +0530
+++ b/src/hotspot/share/gc/shenandoah/c2/shenandoahBarrierSetC2.hpp	Fri May 08 09:52:42 2020 +0530
@@ -103,7 +103,7 @@
 
   static const TypeFunc* write_ref_field_pre_entry_Type();
   static const TypeFunc* shenandoah_clone_barrier_Type();
-  static const TypeFunc* shenandoah_load_reference_barrier_Type();
+  static const TypeFunc* shenandoah_load_reference_barrier_Type(const Type* value_type);
   virtual bool has_load_barrier_nodes() const { return true; }
 
   // This is the entry-point for the backend to perform accesses through the Access API.
--- a/src/hotspot/share/gc/shenandoah/c2/shenandoahSupport.cpp	Fri May 08 09:45:57 2020 +0530
+++ b/src/hotspot/share/gc/shenandoah/c2/shenandoahSupport.cpp	Fri May 08 09:52:42 2020 +0530
@@ -68,7 +68,7 @@
   return true;
 }
 
-bool ShenandoahBarrierC2Support::is_heap_state_test(Node* iff, int mask) {
+bool ShenandoahBarrierC2Support::is_gc_state_test(Node* iff, int mask) {
   if (!UseShenandoahGC) {
     return false;
   }
@@ -102,7 +102,7 @@
 }
 
 bool ShenandoahBarrierC2Support::is_heap_stable_test(Node* iff) {
-  return is_heap_state_test(iff, ShenandoahHeap::HAS_FORWARDED);
+  return is_gc_state_test(iff, ShenandoahHeap::HAS_FORWARDED);
 }
 
 bool ShenandoahBarrierC2Support::is_gc_state_load(Node *n) {
@@ -860,152 +860,96 @@
   inner->clear_strip_mined();
 }
 
-void ShenandoahBarrierC2Support::test_heap_state(Node*& ctrl, Node* raw_mem, Node*& heap_stable_ctrl,
-                                                 PhaseIdealLoop* phase, int flags) {
-  IdealLoopTree* loop = phase->get_loop(ctrl);
-  Node* thread = new ThreadLocalNode();
-  phase->register_new_node(thread, ctrl);
-  Node* offset = phase->igvn().MakeConX(in_bytes(ShenandoahThreadLocalData::gc_state_offset()));
-  phase->set_ctrl(offset, phase->C->root());
-  Node* gc_state_addr = new AddPNode(phase->C->top(), thread, offset);
-  phase->register_new_node(gc_state_addr, ctrl);
-  uint gc_state_idx = Compile::AliasIdxRaw;
-  const TypePtr* gc_state_adr_type = NULL; // debug-mode-only argument
-  debug_only(gc_state_adr_type = phase->C->get_adr_type(gc_state_idx));
+void ShenandoahBarrierC2Support::test_gc_state(Node*& ctrl, Node* raw_mem, Node*& test_fail_ctrl,
+                                               PhaseIdealLoop* phase, int flags) {
+  PhaseIterGVN& igvn = phase->igvn();
+  Node* old_ctrl = ctrl;
+
+  Node* thread          = new ThreadLocalNode();
+  Node* gc_state_offset = igvn.MakeConX(in_bytes(ShenandoahThreadLocalData::gc_state_offset()));
+  Node* gc_state_addr   = new AddPNode(phase->C->top(), thread, gc_state_offset);
+  Node* gc_state        = new LoadBNode(old_ctrl, raw_mem, gc_state_addr,
+                                        DEBUG_ONLY(phase->C->get_adr_type(Compile::AliasIdxRaw)) NOT_DEBUG(NULL),
+                                        TypeInt::BYTE, MemNode::unordered);
+  Node* gc_state_and    = new AndINode(gc_state, igvn.intcon(flags));
+  Node* gc_state_cmp    = new CmpINode(gc_state_and, igvn.zerocon(T_INT));
+  Node* gc_state_bool   = new BoolNode(gc_state_cmp, BoolTest::ne);
 
-  Node* gc_state = new LoadBNode(ctrl, raw_mem, gc_state_addr, gc_state_adr_type, TypeInt::BYTE, MemNode::unordered);
-  phase->register_new_node(gc_state, ctrl);
-  Node* heap_stable_and = new AndINode(gc_state, phase->igvn().intcon(flags));
-  phase->register_new_node(heap_stable_and, ctrl);
-  Node* heap_stable_cmp = new CmpINode(heap_stable_and, phase->igvn().zerocon(T_INT));
-  phase->register_new_node(heap_stable_cmp, ctrl);
-  Node* heap_stable_test = new BoolNode(heap_stable_cmp, BoolTest::ne);
-  phase->register_new_node(heap_stable_test, ctrl);
-  IfNode* heap_stable_iff = new IfNode(ctrl, heap_stable_test, PROB_UNLIKELY(0.999), COUNT_UNKNOWN);
-  phase->register_control(heap_stable_iff, loop, ctrl);
+  IfNode* gc_state_iff  = new IfNode(old_ctrl, gc_state_bool, PROB_UNLIKELY(0.999), COUNT_UNKNOWN);
+  ctrl                  = new IfTrueNode(gc_state_iff);
+  test_fail_ctrl        = new IfFalseNode(gc_state_iff);
+
+  IdealLoopTree* loop = phase->get_loop(ctrl);
+  phase->register_control(gc_state_iff,   loop, old_ctrl);
+  phase->register_control(ctrl,           loop, gc_state_iff);
+  phase->register_control(test_fail_ctrl, loop, gc_state_iff);
 
-  heap_stable_ctrl = new IfFalseNode(heap_stable_iff);
-  phase->register_control(heap_stable_ctrl, loop, heap_stable_iff);
-  ctrl = new IfTrueNode(heap_stable_iff);
-  phase->register_control(ctrl, loop, heap_stable_iff);
+  phase->register_new_node(thread,        old_ctrl);
+  phase->register_new_node(gc_state_addr, old_ctrl);
+  phase->register_new_node(gc_state,      old_ctrl);
+  phase->register_new_node(gc_state_and,  old_ctrl);
+  phase->register_new_node(gc_state_cmp,  old_ctrl);
+  phase->register_new_node(gc_state_bool, old_ctrl);
 
-  assert(is_heap_state_test(heap_stable_iff, flags), "Should match the shape");
+  phase->set_ctrl(gc_state_offset, phase->C->root());
+
+  assert(is_gc_state_test(gc_state_iff, flags), "Should match the shape");
 }
 
 void ShenandoahBarrierC2Support::test_null(Node*& ctrl, Node* val, Node*& null_ctrl, PhaseIdealLoop* phase) {
-  const Type* val_t = phase->igvn().type(val);
+  Node* old_ctrl = ctrl;
+  PhaseIterGVN& igvn = phase->igvn();
+
+  const Type* val_t = igvn.type(val);
   if (val_t->meet(TypePtr::NULL_PTR) == val_t) {
-    IdealLoopTree* loop = phase->get_loop(ctrl);
-    Node* null_cmp = new CmpPNode(val, phase->igvn().zerocon(T_OBJECT));
-    phase->register_new_node(null_cmp, ctrl);
-    Node* null_test = new BoolNode(null_cmp, BoolTest::ne);
-    phase->register_new_node(null_test, ctrl);
-    IfNode* null_iff = new IfNode(ctrl, null_test, PROB_LIKELY(0.999), COUNT_UNKNOWN);
-    phase->register_control(null_iff, loop, ctrl);
-    ctrl = new IfTrueNode(null_iff);
-    phase->register_control(ctrl, loop, null_iff);
-    null_ctrl = new IfFalseNode(null_iff);
+    Node* null_cmp   = new CmpPNode(val, igvn.zerocon(T_OBJECT));
+    Node* null_test  = new BoolNode(null_cmp, BoolTest::ne);
+
+    IfNode* null_iff = new IfNode(old_ctrl, null_test, PROB_LIKELY(0.999), COUNT_UNKNOWN);
+    ctrl             = new IfTrueNode(null_iff);
+    null_ctrl        = new IfFalseNode(null_iff);
+
+    IdealLoopTree* loop = phase->get_loop(old_ctrl);
+    phase->register_control(null_iff,  loop, old_ctrl);
+    phase->register_control(ctrl,      loop, null_iff);
     phase->register_control(null_ctrl, loop, null_iff);
+
+    phase->register_new_node(null_cmp,  old_ctrl);
+    phase->register_new_node(null_test, old_ctrl);
   }
 }
 
-Node* ShenandoahBarrierC2Support::clone_null_check(Node*& c, Node* val, Node* unc_ctrl, PhaseIdealLoop* phase) {
-  IdealLoopTree *loop = phase->get_loop(c);
-  Node* iff = unc_ctrl->in(0);
-  assert(iff->is_If(), "broken");
-  Node* new_iff = iff->clone();
-  new_iff->set_req(0, c);
-  phase->register_control(new_iff, loop, c);
-  Node* iffalse = new IfFalseNode(new_iff->as_If());
-  phase->register_control(iffalse, loop, new_iff);
-  Node* iftrue = new IfTrueNode(new_iff->as_If());
-  phase->register_control(iftrue, loop, new_iff);
-  c = iftrue;
-  const Type *t = phase->igvn().type(val);
-  assert(val->Opcode() == Op_CastPP, "expect cast to non null here");
-  Node* uncasted_val = val->in(1);
-  val = new CastPPNode(uncasted_val, t);
-  val->init_req(0, c);
-  phase->register_new_node(val, c);
-  return val;
-}
+void ShenandoahBarrierC2Support::test_in_cset(Node*& ctrl, Node*& not_cset_ctrl, Node* val, Node* raw_mem, PhaseIdealLoop* phase) {
+  Node* old_ctrl = ctrl;
+  PhaseIterGVN& igvn = phase->igvn();
 
-void ShenandoahBarrierC2Support::fix_null_check(Node* unc, Node* unc_ctrl, Node* new_unc_ctrl,
-                                                Unique_Node_List& uses, PhaseIdealLoop* phase) {
-  IfNode* iff = unc_ctrl->in(0)->as_If();
-  Node* proj = iff->proj_out(0);
-  assert(proj != unc_ctrl, "bad projection");
-  Node* use = proj->unique_ctrl_out();
-
-  assert(use == unc || use->is_Region(), "what else?");
+  Node* raw_val        = new CastP2XNode(old_ctrl, val);
+  Node* cset_idx       = new URShiftXNode(raw_val, igvn.intcon(ShenandoahHeapRegion::region_size_bytes_shift_jint()));
+  Node* cset_addr      = igvn.makecon(TypeRawPtr::make(ShenandoahHeap::in_cset_fast_test_addr()));
+  Node* cset_load_addr = new AddPNode(phase->C->top(), cset_addr, cset_idx);
+  Node* cset_load      = new LoadBNode(old_ctrl, raw_mem, cset_load_addr,
+                                       DEBUG_ONLY(phase->C->get_adr_type(Compile::AliasIdxRaw)) NOT_DEBUG(NULL),
+                                       TypeInt::BYTE, MemNode::unordered);
+  Node* cset_cmp       = new CmpINode(cset_load, igvn.zerocon(T_INT));
+  Node* cset_bool      = new BoolNode(cset_cmp, BoolTest::ne);
 
-  uses.clear();
-  if (use == unc) {
-    phase->set_idom(use, new_unc_ctrl, phase->dom_depth(use));
-    for (uint i = 1; i < unc->req(); i++) {
-      Node* n = unc->in(i);
-      if (phase->has_ctrl(n) && phase->get_ctrl(n) == proj) {
-        uses.push(n);
-      }
-    }
-  } else {
-    assert(use->is_Region(), "what else?");
-    uint idx = 1;
-    for (; use->in(idx) != proj; idx++);
-    for (DUIterator_Fast imax, i = use->fast_outs(imax); i < imax; i++) {
-      Node* u = use->fast_out(i);
-      if (u->is_Phi() && phase->get_ctrl(u->in(idx)) == proj) {
-        uses.push(u->in(idx));
-      }
-    }
-  }
-  for(uint next = 0; next < uses.size(); next++ ) {
-    Node *n = uses.at(next);
-    assert(phase->get_ctrl(n) == proj, "bad control");
-    phase->set_ctrl_and_loop(n, new_unc_ctrl);
-    if (n->in(0) == proj) {
-      phase->igvn().replace_input_of(n, 0, new_unc_ctrl);
-    }
-    for (uint i = 0; i < n->req(); i++) {
-      Node* m = n->in(i);
-      if (m != NULL && phase->has_ctrl(m) && phase->get_ctrl(m) == proj) {
-        uses.push(m);
-      }
-    }
-  }
+  IfNode* cset_iff     = new IfNode(old_ctrl, cset_bool, PROB_UNLIKELY(0.999), COUNT_UNKNOWN);
+  ctrl                 = new IfTrueNode(cset_iff);
+  not_cset_ctrl        = new IfFalseNode(cset_iff);
+
+  IdealLoopTree *loop = phase->get_loop(old_ctrl);
+  phase->register_control(cset_iff,      loop, old_ctrl);
+  phase->register_control(ctrl,          loop, cset_iff);
+  phase->register_control(not_cset_ctrl, loop, cset_iff);
 
-  phase->igvn().rehash_node_delayed(use);
-  int nb = use->replace_edge(proj, new_unc_ctrl);
-  assert(nb == 1, "only use expected");
-}
+  phase->set_ctrl(cset_addr, phase->C->root());
 
-void ShenandoahBarrierC2Support::in_cset_fast_test(Node*& ctrl, Node*& not_cset_ctrl, Node* val, Node* raw_mem, PhaseIdealLoop* phase) {
-  IdealLoopTree *loop = phase->get_loop(ctrl);
-  Node* raw_rbtrue = new CastP2XNode(ctrl, val);
-  phase->register_new_node(raw_rbtrue, ctrl);
-  Node* cset_offset = new URShiftXNode(raw_rbtrue, phase->igvn().intcon(ShenandoahHeapRegion::region_size_bytes_shift_jint()));
-  phase->register_new_node(cset_offset, ctrl);
-  Node* in_cset_fast_test_base_addr = phase->igvn().makecon(TypeRawPtr::make(ShenandoahHeap::in_cset_fast_test_addr()));
-  phase->set_ctrl(in_cset_fast_test_base_addr, phase->C->root());
-  Node* in_cset_fast_test_adr = new AddPNode(phase->C->top(), in_cset_fast_test_base_addr, cset_offset);
-  phase->register_new_node(in_cset_fast_test_adr, ctrl);
-  uint in_cset_fast_test_idx = Compile::AliasIdxRaw;
-  const TypePtr* in_cset_fast_test_adr_type = NULL; // debug-mode-only argument
-  debug_only(in_cset_fast_test_adr_type = phase->C->get_adr_type(in_cset_fast_test_idx));
-  Node* in_cset_fast_test_load = new LoadBNode(ctrl, raw_mem, in_cset_fast_test_adr, in_cset_fast_test_adr_type, TypeInt::BYTE, MemNode::unordered);
-  phase->register_new_node(in_cset_fast_test_load, ctrl);
-  Node* in_cset_fast_test_cmp = new CmpINode(in_cset_fast_test_load, phase->igvn().zerocon(T_INT));
-  phase->register_new_node(in_cset_fast_test_cmp, ctrl);
-  Node* in_cset_fast_test_test = new BoolNode(in_cset_fast_test_cmp, BoolTest::eq);
-  phase->register_new_node(in_cset_fast_test_test, ctrl);
-  IfNode* in_cset_fast_test_iff = new IfNode(ctrl, in_cset_fast_test_test, PROB_UNLIKELY(0.999), COUNT_UNKNOWN);
-  phase->register_control(in_cset_fast_test_iff, loop, ctrl);
-
-  not_cset_ctrl = new IfTrueNode(in_cset_fast_test_iff);
-  phase->register_control(not_cset_ctrl, loop, in_cset_fast_test_iff);
-
-  ctrl = new IfFalseNode(in_cset_fast_test_iff);
-  phase->register_control(ctrl, loop, in_cset_fast_test_iff);
+  phase->register_new_node(raw_val,        old_ctrl);
+  phase->register_new_node(cset_idx,       old_ctrl);
+  phase->register_new_node(cset_load_addr, old_ctrl);
+  phase->register_new_node(cset_load,      old_ctrl);
+  phase->register_new_node(cset_cmp,       old_ctrl);
+  phase->register_new_node(cset_bool,      old_ctrl);
 }
 
 void ShenandoahBarrierC2Support::call_lrb_stub(Node*& ctrl, Node*& val, Node* load_addr, Node*& result_mem, Node* raw_mem, bool is_native, PhaseIdealLoop* phase) {
@@ -1026,7 +970,7 @@
   address calladdr = is_native ? CAST_FROM_FN_PTR(address, ShenandoahRuntime::load_reference_barrier_native)
                                : target;
   const char* name = is_native ? "load_reference_barrier_native" : "load_reference_barrier";
-  Node* call = new CallLeafNode(ShenandoahBarrierSetC2::shenandoah_load_reference_barrier_Type(), calladdr, name, TypeRawPtr::BOTTOM);
+  Node* call = new CallLeafNode(ShenandoahBarrierSetC2::shenandoah_load_reference_barrier_Type(obj_type), calladdr, name, TypeRawPtr::BOTTOM);
 
   call->init_req(TypeFunc::Control, ctrl);
   call->init_req(TypeFunc::I_O, phase->C->top());
@@ -1042,8 +986,6 @@
   phase->register_new_node(result_mem, call);
   val = new ProjNode(call, TypeFunc::Parms);
   phase->register_new_node(val, call);
-  val = new CheckCastPPNode(ctrl, val, obj_type);
-  phase->register_new_node(val, ctrl);
 }
 
 void ShenandoahBarrierC2Support::fix_ctrl(Node* barrier, Node* region, const MemoryGraphFixer& fixer, Unique_Node_List& uses, Unique_Node_List& uses_to_ignore, uint last, PhaseIdealLoop* phase) {
@@ -1149,119 +1091,6 @@
     }
 
     Node* ctrl = phase->get_ctrl(lrb);
-    Node* val = lrb->in(ShenandoahLoadReferenceBarrierNode::ValueIn);
-
-    CallStaticJavaNode* unc = NULL;
-    Node* unc_ctrl = NULL;
-    Node* uncasted_val = val;
-
-    for (DUIterator_Fast imax, i = lrb->fast_outs(imax); i < imax; i++) {
-      Node* u = lrb->fast_out(i);
-      if (u->Opcode() == Op_CastPP &&
-          u->in(0) != NULL &&
-          phase->is_dominator(u->in(0), ctrl)) {
-        const Type* u_t = phase->igvn().type(u);
-
-        if (u_t->meet(TypePtr::NULL_PTR) != u_t &&
-            u->in(0)->Opcode() == Op_IfTrue &&
-            u->in(0)->as_Proj()->is_uncommon_trap_if_pattern(Deoptimization::Reason_none) &&
-            u->in(0)->in(0)->is_If() &&
-            u->in(0)->in(0)->in(1)->Opcode() == Op_Bool &&
-            u->in(0)->in(0)->in(1)->as_Bool()->_test._test == BoolTest::ne &&
-            u->in(0)->in(0)->in(1)->in(1)->Opcode() == Op_CmpP &&
-            u->in(0)->in(0)->in(1)->in(1)->in(1) == val &&
-            u->in(0)->in(0)->in(1)->in(1)->in(2)->bottom_type() == TypePtr::NULL_PTR) {
-          IdealLoopTree* loop = phase->get_loop(ctrl);
-          IdealLoopTree* unc_loop = phase->get_loop(u->in(0));
-
-          if (!unc_loop->is_member(loop)) {
-            continue;
-          }
-
-          Node* branch = no_branches(ctrl, u->in(0), false, phase);
-          assert(branch == NULL || branch == NodeSentinel, "was not looking for a branch");
-          if (branch == NodeSentinel) {
-            continue;
-          }
-
-          phase->igvn().replace_input_of(u, 1, val);
-          phase->igvn().replace_input_of(lrb, ShenandoahLoadReferenceBarrierNode::ValueIn, u);
-          phase->set_ctrl(u, u->in(0));
-          phase->set_ctrl(lrb, u->in(0));
-          unc = u->in(0)->as_Proj()->is_uncommon_trap_if_pattern(Deoptimization::Reason_none);
-          unc_ctrl = u->in(0);
-          val = u;
-
-          for (DUIterator_Fast jmax, j = val->fast_outs(jmax); j < jmax; j++) {
-            Node* u = val->fast_out(j);
-            if (u == lrb) continue;
-            phase->igvn().rehash_node_delayed(u);
-            int nb = u->replace_edge(val, lrb);
-            --j; jmax -= nb;
-          }
-
-          RegionNode* r = new RegionNode(3);
-          IfNode* iff = unc_ctrl->in(0)->as_If();
-
-          Node* ctrl_use = unc_ctrl->unique_ctrl_out();
-          Node* unc_ctrl_clone = unc_ctrl->clone();
-          phase->register_control(unc_ctrl_clone, loop, iff);
-          Node* c = unc_ctrl_clone;
-          Node* new_cast = clone_null_check(c, val, unc_ctrl_clone, phase);
-          r->init_req(1, new_cast->in(0)->in(0)->as_If()->proj_out(0));
-
-          phase->igvn().replace_input_of(unc_ctrl, 0, c->in(0));
-          phase->set_idom(unc_ctrl, c->in(0), phase->dom_depth(unc_ctrl));
-          phase->lazy_replace(c, unc_ctrl);
-          c = NULL;;
-          phase->igvn().replace_input_of(val, 0, unc_ctrl_clone);
-          phase->set_ctrl(val, unc_ctrl_clone);
-
-          IfNode* new_iff = new_cast->in(0)->in(0)->as_If();
-          fix_null_check(unc, unc_ctrl_clone, r, uses, phase);
-          Node* iff_proj = iff->proj_out(0);
-          r->init_req(2, iff_proj);
-          phase->register_control(r, phase->ltree_root(), iff);
-
-          Node* new_bol = new_iff->in(1)->clone();
-          Node* new_cmp = new_bol->in(1)->clone();
-          assert(new_cmp->Opcode() == Op_CmpP, "broken");
-          assert(new_cmp->in(1) == val->in(1), "broken");
-          new_bol->set_req(1, new_cmp);
-          new_cmp->set_req(1, lrb);
-          phase->register_new_node(new_bol, new_iff->in(0));
-          phase->register_new_node(new_cmp, new_iff->in(0));
-          phase->igvn().replace_input_of(new_iff, 1, new_bol);
-          phase->igvn().replace_input_of(new_cast, 1, lrb);
-
-          for (DUIterator_Fast imax, i = lrb->fast_outs(imax); i < imax; i++) {
-            Node* u = lrb->fast_out(i);
-            if (u == new_cast || u == new_cmp) {
-              continue;
-            }
-            phase->igvn().rehash_node_delayed(u);
-            int nb = u->replace_edge(lrb, new_cast);
-            assert(nb > 0, "no update?");
-            --i; imax -= nb;
-          }
-
-          for (DUIterator_Fast imax, i = val->fast_outs(imax); i < imax; i++) {
-            Node* u = val->fast_out(i);
-            if (u == lrb) {
-              continue;
-            }
-            phase->igvn().rehash_node_delayed(u);
-            int nb = u->replace_edge(val, new_cast);
-            assert(nb > 0, "no update?");
-            --i; imax -= nb;
-          }
-
-          ctrl = unc_ctrl_clone;
-          phase->set_ctrl_and_loop(lrb, ctrl);
-          break;
-        }
-      }
-    }
     if ((ctrl->is_Proj() && ctrl->in(0)->is_CallJava()) || ctrl->is_CallJava()) {
       CallNode* call = ctrl->is_Proj() ? ctrl->in(0)->as_CallJava() : ctrl->as_CallJava();
       if (call->entry_point() == OptoRuntime::rethrow_stub()) {
@@ -1402,90 +1231,45 @@
     Node* ctrl = phase->get_ctrl(lrb);
     Node* val = lrb->in(ShenandoahLoadReferenceBarrierNode::ValueIn);
 
-
     Node* orig_ctrl = ctrl;
 
     Node* raw_mem = fixer.find_mem(ctrl, lrb);
     Node* init_raw_mem = raw_mem;
     Node* raw_mem_for_ctrl = fixer.find_mem(ctrl, NULL);
 
-    IdealLoopTree *loop = phase->get_loop(ctrl);
-    CallStaticJavaNode* unc = lrb->pin_and_expand_null_check(phase->igvn());
-    Node* unc_ctrl = NULL;
-    if (unc != NULL) {
-      if (val->in(ShenandoahLoadReferenceBarrierNode::Control) != ctrl) {
-        unc = NULL;
-      } else {
-        unc_ctrl = val->in(ShenandoahLoadReferenceBarrierNode::Control);
-      }
-    }
-
-    Node* uncasted_val = val;
-    if (unc != NULL) {
-      uncasted_val = val->in(1);
-    }
-
-    Node* heap_stable_ctrl = NULL;
-    Node* null_ctrl = NULL;
+    IdealLoopTree* loop = phase->get_loop(ctrl);
 
     assert(val->bottom_type()->make_oopptr(), "need oop");
     assert(val->bottom_type()->make_oopptr()->const_oop() == NULL, "expect non-constant");
 
-    enum { _heap_stable = 1, _not_cset, _evac_path, _null_path, PATH_LIMIT };
+    enum { _heap_stable = 1, _not_cset, _evac_path, PATH_LIMIT };
     Node* region = new RegionNode(PATH_LIMIT);
-    Node* val_phi = new PhiNode(region, uncasted_val->bottom_type()->is_oopptr());
+    Node* val_phi = new PhiNode(region, val->bottom_type()->is_oopptr());
     Node* raw_mem_phi = PhiNode::make(region, raw_mem, Type::MEMORY, TypeRawPtr::BOTTOM);
 
     // Stable path.
-    test_heap_state(ctrl, raw_mem, heap_stable_ctrl, phase, ShenandoahHeap::HAS_FORWARDED);
+    Node* heap_stable_ctrl = NULL;
+    test_gc_state(ctrl, raw_mem, heap_stable_ctrl, phase, ShenandoahHeap::HAS_FORWARDED);
     IfNode* heap_stable_iff = heap_stable_ctrl->in(0)->as_If();
 
     // Heap stable case
     region->init_req(_heap_stable, heap_stable_ctrl);
-    val_phi->init_req(_heap_stable, uncasted_val);
+    val_phi->init_req(_heap_stable, val);
     raw_mem_phi->init_req(_heap_stable, raw_mem);
 
-    Node* reg2_ctrl = NULL;
-    // Null case
-    test_null(ctrl, val, null_ctrl, phase);
-    if (null_ctrl != NULL) {
-      reg2_ctrl = null_ctrl->in(0);
-      region->init_req(_null_path, null_ctrl);
-      val_phi->init_req(_null_path, uncasted_val);
-      raw_mem_phi->init_req(_null_path, raw_mem);
-    } else {
-      region->del_req(_null_path);
-      val_phi->del_req(_null_path);
-      raw_mem_phi->del_req(_null_path);
-    }
-
     // Test for in-cset.
     // Wires !in_cset(obj) to slot 2 of region and phis
     Node* not_cset_ctrl = NULL;
-    in_cset_fast_test(ctrl, not_cset_ctrl, uncasted_val, raw_mem, phase);
+    test_in_cset(ctrl, not_cset_ctrl, val, raw_mem, phase);
     if (not_cset_ctrl != NULL) {
-      if (reg2_ctrl == NULL) reg2_ctrl = not_cset_ctrl->in(0);
       region->init_req(_not_cset, not_cset_ctrl);
-      val_phi->init_req(_not_cset, uncasted_val);
+      val_phi->init_req(_not_cset, val);
       raw_mem_phi->init_req(_not_cset, raw_mem);
     }
 
-    // Resolve object when orig-value is in cset.
-    // Make the unconditional resolve for fwdptr.
-    Node* new_val = uncasted_val;
-    if (unc_ctrl != NULL) {
-      // Clone the null check in this branch to allow implicit null check
-      new_val = clone_null_check(ctrl, val, unc_ctrl, phase);
-      fix_null_check(unc, unc_ctrl, ctrl->in(0)->as_If()->proj_out(0), uses, phase);
-
-      IfNode* iff = unc_ctrl->in(0)->as_If();
-      phase->igvn().replace_input_of(iff, 1, phase->igvn().intcon(1));
-    }
-
     // Call lrb-stub and wire up that path in slots 4
     Node* result_mem = NULL;
 
-    Node* fwd = new_val;
     Node* addr;
     if (ShenandoahSelfFixing) {
       VectorSet visited(Thread::current()->resource_area());
@@ -1518,9 +1302,9 @@
         }
       }
     }
-    call_lrb_stub(ctrl, fwd, addr, result_mem, raw_mem, lrb->is_native(), phase);
+    call_lrb_stub(ctrl, val, addr, result_mem, raw_mem, lrb->is_native(), phase);
     region->init_req(_evac_path, ctrl);
-    val_phi->init_req(_evac_path, fwd);
+    val_phi->init_req(_evac_path, val);
     raw_mem_phi->init_req(_evac_path, result_mem);
 
     phase->register_control(region, loop, heap_stable_iff);
@@ -1532,20 +1316,6 @@
 
     ctrl = orig_ctrl;
 
-    if (unc != NULL) {
-      for (DUIterator_Fast imax, i = val->fast_outs(imax); i < imax; i++) {
-        Node* u = val->fast_out(i);
-        Node* c = phase->ctrl_or_self(u);
-        if (u != lrb && (c != ctrl || is_dominator_same_ctrl(c, lrb, u, phase))) {
-          phase->igvn().rehash_node_delayed(u);
-          int nb = u->replace_edge(val, out_val);
-          --i, imax -= nb;
-        }
-      }
-      if (val->outcnt() == 0) {
-        phase->igvn()._worklist.push(val);
-      }
-    }
     phase->igvn().replace_node(lrb, out_val);
 
     follow_barrier_uses(out_val, ctrl, uses, phase);
@@ -1608,7 +1378,7 @@
     Node* phi2 = PhiNode::make(region2, raw_mem, Type::MEMORY, TypeRawPtr::BOTTOM);
 
     // Stable path.
-    test_heap_state(ctrl, raw_mem, heap_stable_ctrl, phase, ShenandoahHeap::MARKING);
+    test_gc_state(ctrl, raw_mem, heap_stable_ctrl, phase, ShenandoahHeap::MARKING);
     region->init_req(_heap_stable, heap_stable_ctrl);
     phi->init_req(_heap_stable, raw_mem);
 
@@ -1790,7 +1560,7 @@
 
 }
 
-void ShenandoahBarrierC2Support::move_heap_stable_test_out_of_loop(IfNode* iff, PhaseIdealLoop* phase) {
+void ShenandoahBarrierC2Support::move_gc_state_test_out_of_loop(IfNode* iff, PhaseIdealLoop* phase) {
   IdealLoopTree *loop = phase->get_loop(iff);
   Node* loop_head = loop->_head;
   Node* entry_c = loop_head->in(LoopNode::EntryControl);
@@ -1984,7 +1754,7 @@
             if (head->as_Loop()->is_strip_mined()) {
               head->as_Loop()->verify_strip_mined(0);
             }
-            move_heap_stable_test_out_of_loop(iff, phase);
+            move_gc_state_test_out_of_loop(iff, phase);
 
             AutoNodeBudget node_budget(phase);
 
@@ -3173,6 +2943,11 @@
     bool visit_users = false;
     switch (n->Opcode()) {
       case Op_CallStaticJava:
+        // Uncommon traps don't need barriers, values are handled during deoptimization. It also affects
+        // optimizing null-checks into implicit null-checks.
+        if (n->as_CallStaticJava()->uncommon_trap_request() != 0) {
+          break;
+        }
       case Op_CallDynamicJava:
       case Op_CallLeaf:
       case Op_CallLeafNoFP:
@@ -3314,26 +3089,3 @@
   // No need for barrier found.
   return true;
 }
-
-CallStaticJavaNode* ShenandoahLoadReferenceBarrierNode::pin_and_expand_null_check(PhaseIterGVN& igvn) {
-  Node* val = in(ValueIn);
-
-  const Type* val_t = igvn.type(val);
-
-  if (val_t->meet(TypePtr::NULL_PTR) != val_t &&
-      val->Opcode() == Op_CastPP &&
-      val->in(0) != NULL &&
-      val->in(0)->Opcode() == Op_IfTrue &&
-      val->in(0)->as_Proj()->is_uncommon_trap_if_pattern(Deoptimization::Reason_none) &&
-      val->in(0)->in(0)->is_If() &&
-      val->in(0)->in(0)->in(1)->Opcode() == Op_Bool &&
-      val->in(0)->in(0)->in(1)->as_Bool()->_test._test == BoolTest::ne &&
-      val->in(0)->in(0)->in(1)->in(1)->Opcode() == Op_CmpP &&
-      val->in(0)->in(0)->in(1)->in(1)->in(1) == val->in(1) &&
-      val->in(0)->in(0)->in(1)->in(1)->in(2)->bottom_type() == TypePtr::NULL_PTR) {
-    assert(val->in(0)->in(0)->in(1)->in(1)->in(1) == val->in(1), "");
-    CallStaticJavaNode* unc = val->in(0)->as_Proj()->is_uncommon_trap_if_pattern(Deoptimization::Reason_none);
-    return unc;
-  }
-  return NULL;
-}
--- a/src/hotspot/share/gc/shenandoah/c2/shenandoahSupport.hpp	Fri May 08 09:45:57 2020 +0530
+++ b/src/hotspot/share/gc/shenandoah/c2/shenandoahSupport.hpp	Fri May 08 09:52:42 2020 +0530
@@ -53,19 +53,16 @@
 #endif
   static Node* dom_mem(Node* mem, Node* ctrl, int alias, Node*& mem_ctrl, PhaseIdealLoop* phase);
   static Node* no_branches(Node* c, Node* dom, bool allow_one_proj, PhaseIdealLoop* phase);
-  static bool is_heap_state_test(Node* iff, int mask);
+  static bool is_gc_state_test(Node* iff, int mask);
   static bool has_safepoint_between(Node* start, Node* stop, PhaseIdealLoop *phase);
   static Node* find_bottom_mem(Node* ctrl, PhaseIdealLoop* phase);
   static void follow_barrier_uses(Node* n, Node* ctrl, Unique_Node_List& uses, PhaseIdealLoop* phase);
   static void test_null(Node*& ctrl, Node* val, Node*& null_ctrl, PhaseIdealLoop* phase);
-  static void test_heap_state(Node*& ctrl, Node* raw_mem, Node*& heap_stable_ctrl,
-                              PhaseIdealLoop* phase, int flags);
+  static void test_gc_state(Node*& ctrl, Node* raw_mem, Node*& heap_stable_ctrl,
+                            PhaseIdealLoop* phase, int flags);
   static void call_lrb_stub(Node*& ctrl, Node*& val, Node* load_addr, Node*& result_mem, Node* raw_mem, bool is_native, PhaseIdealLoop* phase);
-  static Node* clone_null_check(Node*& c, Node* val, Node* unc_ctrl, PhaseIdealLoop* phase);
-  static void fix_null_check(Node* unc, Node* unc_ctrl, Node* new_unc_ctrl, Unique_Node_List& uses,
-                             PhaseIdealLoop* phase);
-  static void in_cset_fast_test(Node*& ctrl, Node*& not_cset_ctrl, Node* val, Node* raw_mem, PhaseIdealLoop* phase);
-  static void move_heap_stable_test_out_of_loop(IfNode* iff, PhaseIdealLoop* phase);
+  static void test_in_cset(Node*& ctrl, Node*& not_cset_ctrl, Node* val, Node* raw_mem, PhaseIdealLoop* phase);
+  static void move_gc_state_test_out_of_loop(IfNode* iff, PhaseIdealLoop* phase);
   static void merge_back_to_back_tests(Node* n, PhaseIdealLoop* phase);
   static bool identical_backtoback_ifs(Node *n, PhaseIdealLoop* phase);
   static void fix_ctrl(Node* barrier, Node* region, const MemoryGraphFixer& fixer, Unique_Node_List& uses, Unique_Node_List& uses_to_ignore, uint last, PhaseIdealLoop* phase);
@@ -254,7 +251,6 @@
   virtual bool cmp( const Node &n ) const;
 
   bool is_redundant();
-  CallStaticJavaNode* pin_and_expand_null_check(PhaseIterGVN& igvn);
 
 private:
   bool needs_barrier(PhaseGVN* phase, Node* n);
--- a/src/hotspot/share/gc/shenandoah/heuristics/shenandoahAdaptiveHeuristics.cpp	Fri May 08 09:45:57 2020 +0530
+++ b/src/hotspot/share/gc/shenandoah/heuristics/shenandoahAdaptiveHeuristics.cpp	Fri May 08 09:52:42 2020 +0530
@@ -27,6 +27,7 @@
 #include "gc/shenandoah/heuristics/shenandoahAdaptiveHeuristics.hpp"
 #include "gc/shenandoah/shenandoahCollectionSet.hpp"
 #include "gc/shenandoah/shenandoahFreeSet.hpp"
+#include "gc/shenandoah/shenandoahHeap.inline.hpp"
 #include "gc/shenandoah/shenandoahHeapRegion.inline.hpp"
 #include "logging/log.hpp"
 #include "logging/logTag.hpp"
--- a/src/hotspot/share/gc/shenandoah/heuristics/shenandoahCompactHeuristics.cpp	Fri May 08 09:45:57 2020 +0530
+++ b/src/hotspot/share/gc/shenandoah/heuristics/shenandoahCompactHeuristics.cpp	Fri May 08 09:52:42 2020 +0530
@@ -27,6 +27,7 @@
 #include "gc/shenandoah/shenandoahCollectionSet.hpp"
 #include "gc/shenandoah/heuristics/shenandoahCompactHeuristics.hpp"
 #include "gc/shenandoah/shenandoahFreeSet.hpp"
+#include "gc/shenandoah/shenandoahHeap.inline.hpp"
 #include "gc/shenandoah/shenandoahHeapRegion.inline.hpp"
 #include "logging/log.hpp"
 #include "logging/logTag.hpp"
--- a/src/hotspot/share/gc/shenandoah/heuristics/shenandoahPassiveHeuristics.cpp	Fri May 08 09:45:57 2020 +0530
+++ b/src/hotspot/share/gc/shenandoah/heuristics/shenandoahPassiveHeuristics.cpp	Fri May 08 09:52:42 2020 +0530
@@ -26,6 +26,7 @@
 
 #include "gc/shenandoah/heuristics/shenandoahPassiveHeuristics.hpp"
 #include "gc/shenandoah/shenandoahCollectionSet.hpp"
+#include "gc/shenandoah/shenandoahHeap.inline.hpp"
 #include "gc/shenandoah/shenandoahHeapRegion.inline.hpp"
 #include "logging/log.hpp"
 #include "logging/logTag.hpp"
--- a/src/hotspot/share/gc/shenandoah/heuristics/shenandoahStaticHeuristics.cpp	Fri May 08 09:45:57 2020 +0530
+++ b/src/hotspot/share/gc/shenandoah/heuristics/shenandoahStaticHeuristics.cpp	Fri May 08 09:52:42 2020 +0530
@@ -27,6 +27,7 @@
 #include "gc/shenandoah/heuristics/shenandoahStaticHeuristics.hpp"
 #include "gc/shenandoah/shenandoahCollectionSet.hpp"
 #include "gc/shenandoah/shenandoahFreeSet.hpp"
+#include "gc/shenandoah/shenandoahHeap.inline.hpp"
 #include "gc/shenandoah/shenandoahHeapRegion.inline.hpp"
 #include "logging/log.hpp"
 #include "logging/logTag.hpp"
--- a/src/hotspot/share/gc/shenandoah/shenandoahCodeRoots.cpp	Fri May 08 09:45:57 2020 +0530
+++ b/src/hotspot/share/gc/shenandoah/shenandoahCodeRoots.cpp	Fri May 08 09:52:42 2020 +0530
@@ -194,6 +194,7 @@
   ShenandoahDisarmNMethodsTask() :
     AbstractGangTask("ShenandoahDisarmNMethodsTask"),
     _iterator(ShenandoahCodeRoots::table()) {
+    assert(SafepointSynchronize::is_at_safepoint(), "Only at a safepoint");
     MutexLocker mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
     _iterator.nmethods_do_begin();
   }
@@ -204,6 +205,7 @@
   }
 
   virtual void work(uint worker_id) {
+    ShenandoahParallelWorkerSession worker_session(worker_id);
     _iterator.nmethods_do(&_cl);
   }
 };
--- a/src/hotspot/share/gc/shenandoah/shenandoahConcurrentMark.cpp	Fri May 08 09:45:57 2020 +0530
+++ b/src/hotspot/share/gc/shenandoah/shenandoahConcurrentMark.cpp	Fri May 08 09:52:42 2020 +0530
@@ -351,6 +351,7 @@
     _worker_phase(phase) {}
 
   void work(uint worker_id) {
+    ShenandoahParallelWorkerSession worker_session(worker_id);
     ShenandoahUpdateRefsClosure cl;
     _thread_roots.oops_do(&cl, NULL, worker_id);
   }
@@ -588,6 +589,7 @@
     HandleMark hm;
     assert(ShenandoahSafepoint::is_at_shenandoah_safepoint(), "Must be at a safepoint");
     ShenandoahHeap* heap = ShenandoahHeap::heap();
+    ShenandoahParallelWorkerSession worker_session(worker_id);
     ShenandoahCMDrainMarkingStackClosure complete_gc(worker_id, _terminator);
     if (heap->has_forwarded_objects()) {
       ShenandoahForwardedIsAliveClosure is_alive;
@@ -682,7 +684,11 @@
   ReferenceProcessorPhaseTimes pt(_heap->gc_timer(), rp->num_queues());
 
   {
-    ShenandoahGCPhase phase(phase_process);
+    // Note: Don't emit JFR event for this phase, to avoid overflow nesting phase level.
+    // Reference Processor emits 2 levels JFR event, that can get us over the JFR
+    // event nesting level limits, in case of degenerated GC gets upgraded to
+    // full GC.
+    ShenandoahTimingsTracker phase_timing(phase_process);
 
     if (_heap->has_forwarded_objects()) {
       ShenandoahCMKeepAliveUpdateClosure keep_alive(get_queue(serial_worker_id));
--- a/src/hotspot/share/gc/shenandoah/shenandoahConcurrentMark.inline.hpp	Fri May 08 09:45:57 2020 +0530
+++ b/src/hotspot/share/gc/shenandoah/shenandoahConcurrentMark.inline.hpp	Fri May 08 09:52:42 2020 +0530
@@ -28,6 +28,7 @@
 #include "gc/shenandoah/shenandoahAsserts.hpp"
 #include "gc/shenandoah/shenandoahBarrierSet.inline.hpp"
 #include "gc/shenandoah/shenandoahConcurrentMark.hpp"
+#include "gc/shenandoah/shenandoahHeap.inline.hpp"
 #include "gc/shenandoah/shenandoahMarkingContext.inline.hpp"
 #include "gc/shenandoah/shenandoahStringDedup.inline.hpp"
 #include "gc/shenandoah/shenandoahTaskqueue.inline.hpp"
--- a/src/hotspot/share/gc/shenandoah/shenandoahEvacOOMHandler.cpp	Fri May 08 09:45:57 2020 +0530
+++ b/src/hotspot/share/gc/shenandoah/shenandoahEvacOOMHandler.cpp	Fri May 08 09:52:42 2020 +0530
@@ -24,7 +24,7 @@
 
 #include "precompiled.hpp"
 
-#include "gc/shenandoah/shenandoahHeap.hpp"
+#include "gc/shenandoah/shenandoahHeap.inline.hpp"
 #include "gc/shenandoah/shenandoahUtils.hpp"
 #include "gc/shenandoah/shenandoahEvacOOMHandler.hpp"
 #include "gc/shenandoah/shenandoahThreadLocalData.hpp"
--- a/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp	Fri May 08 09:45:57 2020 +0530
+++ b/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp	Fri May 08 09:52:42 2020 +0530
@@ -1343,6 +1343,7 @@
           _heap(ShenandoahHeap::heap()), _blk(blk), _index(0) {}
 
   void work(uint worker_id) {
+    ShenandoahParallelWorkerSession worker_session(worker_id);
     size_t stride = ShenandoahParallelRegionStride;
 
     size_t max = _heap->num_regions();
@@ -1412,12 +1413,12 @@
   set_concurrent_mark_in_progress(true);
   // We need to reset all TLABs because we'd lose marks on all objects allocated in them.
   {
-    ShenandoahGCSubPhase phase(ShenandoahPhaseTimings::make_parsable);
+    ShenandoahGCPhase phase(ShenandoahPhaseTimings::make_parsable);
     make_parsable(true);
   }
 
   {
-    ShenandoahGCSubPhase phase(ShenandoahPhaseTimings::init_update_region_states);
+    ShenandoahGCPhase phase(ShenandoahPhaseTimings::init_update_region_states);
     ShenandoahInitMarkUpdateRegionStateClosure cl;
     parallel_heap_region_iterate(&cl);
   }
@@ -1428,7 +1429,7 @@
   concurrent_mark()->mark_roots(ShenandoahPhaseTimings::scan_roots);
 
   if (UseTLAB) {
-    ShenandoahGCSubPhase phase(ShenandoahPhaseTimings::resize_tlabs);
+    ShenandoahGCPhase phase(ShenandoahPhaseTimings::resize_tlabs);
     resize_tlabs();
   }
 
@@ -1484,7 +1485,7 @@
 
       // Remember limit for updating refs. It's guaranteed that we get no
       // from-space-refs written from here on.
-      r->set_update_watermark(r->top());
+      r->set_update_watermark_at_safepoint(r->top());
     } else {
       assert(!r->has_live(), "Region " SIZE_FORMAT " should have no live data", r->index());
       assert(_ctx->top_at_mark_start(r) == r->top(),
@@ -1517,7 +1518,7 @@
     }
 
     {
-      ShenandoahGCSubPhase phase(ShenandoahPhaseTimings::final_update_region_states);
+      ShenandoahGCPhase phase(ShenandoahPhaseTimings::final_update_region_states);
       ShenandoahFinalMarkUpdateRegionStateClosure cl;
       parallel_heap_region_iterate(&cl);
 
@@ -1530,19 +1531,19 @@
     // Weaker one: new allocations would happen past update watermark, and so less work would
     // be needed for reference updates (would update the large filler instead).
     {
-      ShenandoahGCSubPhase phase(ShenandoahPhaseTimings::retire_tlabs);
+      ShenandoahGCPhase phase(ShenandoahPhaseTimings::retire_tlabs);
       make_parsable(true);
     }
 
     {
-      ShenandoahGCSubPhase phase(ShenandoahPhaseTimings::choose_cset);
+      ShenandoahGCPhase phase(ShenandoahPhaseTimings::choose_cset);
       ShenandoahHeapLocker locker(lock());
       _collection_set->clear();
       heuristics()->choose_collection_set(_collection_set);
     }
 
     {
-      ShenandoahGCSubPhase phase(ShenandoahPhaseTimings::final_rebuild_freeset);
+      ShenandoahGCPhase phase(ShenandoahPhaseTimings::final_rebuild_freeset);
       ShenandoahHeapLocker locker(lock());
       _free_set->rebuild();
     }
@@ -1555,7 +1556,7 @@
     // If collection set has candidates, start evacuation.
     // Otherwise, bypass the rest of the cycle.
     if (!collection_set()->is_empty()) {
-      ShenandoahGCSubPhase init_evac(ShenandoahPhaseTimings::init_evac);
+      ShenandoahGCPhase init_evac(ShenandoahPhaseTimings::init_evac);
 
       if (ShenandoahVerify) {
         verifier()->verify_before_evacuation();
@@ -1651,6 +1652,7 @@
     _cld_roots(phase) {}
 
   void work(uint worker_id) {
+    ShenandoahConcurrentWorkerSession worker_session(worker_id);
     ShenandoahEvacOOMScope oom;
     {
       // vm_roots and weak_roots are OopStorage backed roots, concurrent iteration
@@ -1789,6 +1791,7 @@
   }
 
   void work(uint worker_id) {
+    ShenandoahConcurrentWorkerSession worker_session(worker_id);
     {
       ShenandoahEvacOOMScope oom;
       // jni_roots and weak_roots are OopStorage backed roots, concurrent iteration
@@ -1892,7 +1895,7 @@
 
   full_gc()->do_it(cause);
   if (UseTLAB) {
-    ShenandoahGCSubPhase phase(ShenandoahPhaseTimings::full_gc_resize_tlabs);
+    ShenandoahGCPhase phase(ShenandoahPhaseTimings::full_gc_resize_tlabs);
     resize_all_tlabs();
   }
 
@@ -2203,9 +2206,9 @@
 
   // Unload classes and purge SystemDictionary.
   {
-    ShenandoahGCSubPhase phase(full_gc ?
-                               ShenandoahPhaseTimings::full_gc_purge_class_unload :
-                               ShenandoahPhaseTimings::purge_class_unload);
+    ShenandoahGCPhase phase(full_gc ?
+                            ShenandoahPhaseTimings::full_gc_purge_class_unload :
+                            ShenandoahPhaseTimings::purge_class_unload);
     bool purged_class = SystemDictionary::do_unloading(gc_timer());
 
     ShenandoahIsAliveSelector is_alive;
@@ -2215,9 +2218,9 @@
   }
 
   {
-    ShenandoahGCSubPhase phase(full_gc ?
-                               ShenandoahPhaseTimings::full_gc_purge_cldg :
-                               ShenandoahPhaseTimings::purge_cldg);
+    ShenandoahGCPhase phase(full_gc ?
+                            ShenandoahPhaseTimings::full_gc_purge_cldg :
+                            ShenandoahPhaseTimings::purge_cldg);
     ClassLoaderDataGraph::purge();
   }
   // Resize and verify metaspace
@@ -2230,14 +2233,14 @@
 // However, we do need to "null" dead oops in the roots, if can not be done
 // in concurrent cycles.
 void ShenandoahHeap::stw_process_weak_roots(bool full_gc) {
-  ShenandoahGCSubPhase root_phase(full_gc ?
-                                  ShenandoahPhaseTimings::full_gc_purge :
-                                  ShenandoahPhaseTimings::purge);
+  ShenandoahGCPhase root_phase(full_gc ?
+                               ShenandoahPhaseTimings::full_gc_purge :
+                               ShenandoahPhaseTimings::purge);
   uint num_workers = _workers->active_workers();
   ShenandoahPhaseTimings::Phase timing_phase = full_gc ?
                                                ShenandoahPhaseTimings::full_gc_purge_weak_par :
                                                ShenandoahPhaseTimings::purge_weak_par;
-  ShenandoahGCSubPhase phase(timing_phase);
+  ShenandoahGCPhase phase(timing_phase);
   ShenandoahGCWorkerPhase worker_phase(timing_phase);
 
   // Cleanup weak roots
@@ -2493,7 +2496,7 @@
   set_evacuation_in_progress(false);
 
   {
-    ShenandoahGCSubPhase phase(ShenandoahPhaseTimings::init_update_refs_retire_gclabs);
+    ShenandoahGCPhase phase(ShenandoahPhaseTimings::init_update_refs_retire_gclabs);
     retire_and_reset_gclabs();
   }
 
@@ -2549,7 +2552,7 @@
 
   // Check if there is left-over work, and finish it
   if (_update_refs_iterator.has_next()) {
-    ShenandoahGCSubPhase phase(ShenandoahPhaseTimings::final_update_refs_finish_work);
+    ShenandoahGCPhase phase(ShenandoahPhaseTimings::final_update_refs_finish_work);
 
     // Finish updating references where we left off.
     clear_cancelled_gc();
@@ -2579,7 +2582,7 @@
   }
 
   {
-    ShenandoahGCSubPhase phase(ShenandoahPhaseTimings::final_update_refs_update_region_states);
+    ShenandoahGCPhase phase(ShenandoahPhaseTimings::final_update_refs_update_region_states);
     ShenandoahFinalUpdateRefsUpdateRegionStateClosure cl;
     parallel_heap_region_iterate(&cl);
 
@@ -2587,7 +2590,7 @@
   }
 
   {
-    ShenandoahGCSubPhase phase(ShenandoahPhaseTimings::final_update_refs_trash_cset);
+    ShenandoahGCPhase phase(ShenandoahPhaseTimings::final_update_refs_trash_cset);
     trash_cset_regions();
   }
 
@@ -2603,7 +2606,7 @@
   }
 
   {
-    ShenandoahGCSubPhase phase(ShenandoahPhaseTimings::final_update_refs_rebuild_freeset);
+    ShenandoahGCPhase phase(ShenandoahPhaseTimings::final_update_refs_rebuild_freeset);
     ShenandoahHeapLocker locker(lock());
     _free_set->rebuild();
   }
@@ -2691,7 +2694,7 @@
 
 void ShenandoahHeap::vmop_entry_init_mark() {
   TraceCollectorStats tcs(monitoring_support()->stw_collection_counters());
-  ShenandoahGCPhase phase(ShenandoahPhaseTimings::init_mark_gross);
+  ShenandoahTimingsTracker timing(ShenandoahPhaseTimings::init_mark_gross);
 
   try_inject_alloc_failure();
   VM_ShenandoahInitMark op;
@@ -2700,7 +2703,7 @@
 
 void ShenandoahHeap::vmop_entry_final_mark() {
   TraceCollectorStats tcs(monitoring_support()->stw_collection_counters());
-  ShenandoahGCPhase phase(ShenandoahPhaseTimings::final_mark_gross);
+  ShenandoahTimingsTracker timing(ShenandoahPhaseTimings::final_mark_gross);
 
   try_inject_alloc_failure();
   VM_ShenandoahFinalMarkStartEvac op;
@@ -2709,7 +2712,7 @@
 
 void ShenandoahHeap::vmop_entry_init_updaterefs() {
   TraceCollectorStats tcs(monitoring_support()->stw_collection_counters());
-  ShenandoahGCPhase phase(ShenandoahPhaseTimings::init_update_refs_gross);
+  ShenandoahTimingsTracker timing(ShenandoahPhaseTimings::init_update_refs_gross);
 
   try_inject_alloc_failure();
   VM_ShenandoahInitUpdateRefs op;
@@ -2718,7 +2721,7 @@
 
 void ShenandoahHeap::vmop_entry_final_updaterefs() {
   TraceCollectorStats tcs(monitoring_support()->stw_collection_counters());
-  ShenandoahGCPhase phase(ShenandoahPhaseTimings::final_update_refs_gross);
+  ShenandoahTimingsTracker timing(ShenandoahPhaseTimings::final_update_refs_gross);
 
   try_inject_alloc_failure();
   VM_ShenandoahFinalUpdateRefs op;
@@ -2727,7 +2730,7 @@
 
 void ShenandoahHeap::vmop_entry_full(GCCause::Cause cause) {
   TraceCollectorStats tcs(monitoring_support()->full_stw_collection_counters());
-  ShenandoahGCPhase phase(ShenandoahPhaseTimings::full_gc_gross);
+  ShenandoahTimingsTracker timing(ShenandoahPhaseTimings::full_gc_gross);
 
   try_inject_alloc_failure();
   VM_ShenandoahFullGC op(cause);
@@ -2736,7 +2739,7 @@
 
 void ShenandoahHeap::vmop_degenerated(ShenandoahDegenPoint point) {
   TraceCollectorStats tcs(monitoring_support()->full_stw_collection_counters());
-  ShenandoahGCPhase phase(ShenandoahPhaseTimings::degen_gc_gross);
+  ShenandoahTimingsTracker timing(ShenandoahPhaseTimings::degen_gc_gross);
 
   VM_ShenandoahDegeneratedGC degenerated_gc((int)point);
   VMThread::execute(&degenerated_gc);
@@ -2744,11 +2747,9 @@
 
 void ShenandoahHeap::entry_init_mark() {
   const char* msg = init_mark_event_message();
-  ShenandoahPausePhase gc_phase(msg);
+  ShenandoahPausePhase gc_phase(msg, ShenandoahPhaseTimings::init_mark);
   EventMark em("%s", msg);
 
-  ShenandoahGCPhase phase(ShenandoahPhaseTimings::init_mark);
-
   ShenandoahWorkerScope scope(workers(),
                               ShenandoahWorkerPolicy::calc_workers_for_init_marking(),
                               "init marking");
@@ -2758,11 +2759,9 @@
 
 void ShenandoahHeap::entry_final_mark() {
   const char* msg = final_mark_event_message();
-  ShenandoahPausePhase gc_phase(msg);
+  ShenandoahPausePhase gc_phase(msg, ShenandoahPhaseTimings::final_mark);
   EventMark em("%s", msg);
 
-  ShenandoahGCPhase phase(ShenandoahPhaseTimings::final_mark);
-
   ShenandoahWorkerScope scope(workers(),
                               ShenandoahWorkerPolicy::calc_workers_for_final_marking(),
                               "final marking");
@@ -2772,11 +2771,9 @@
 
 void ShenandoahHeap::entry_init_updaterefs() {
   static const char* msg = "Pause Init Update Refs";
-  ShenandoahPausePhase gc_phase(msg);
+  ShenandoahPausePhase gc_phase(msg, ShenandoahPhaseTimings::init_update_refs);
   EventMark em("%s", msg);
 
-  ShenandoahGCPhase phase(ShenandoahPhaseTimings::init_update_refs);
-
   // No workers used in this phase, no setup required
 
   op_init_updaterefs();
@@ -2784,11 +2781,9 @@
 
 void ShenandoahHeap::entry_final_updaterefs() {
   static const char* msg = "Pause Final Update Refs";
-  ShenandoahPausePhase gc_phase(msg);
+  ShenandoahPausePhase gc_phase(msg, ShenandoahPhaseTimings::final_update_refs);
   EventMark em("%s", msg);
 
-  ShenandoahGCPhase phase(ShenandoahPhaseTimings::final_update_refs);
-
   ShenandoahWorkerScope scope(workers(),
                               ShenandoahWorkerPolicy::calc_workers_for_final_update_ref(),
                               "final reference update");
@@ -2798,11 +2793,9 @@
 
 void ShenandoahHeap::entry_full(GCCause::Cause cause) {
   static const char* msg = "Pause Full";
-  ShenandoahPausePhase gc_phase(msg, true /* log_heap_usage */);
+  ShenandoahPausePhase gc_phase(msg, ShenandoahPhaseTimings::full_gc, true /* log_heap_usage */);
   EventMark em("%s", msg);
 
-  ShenandoahGCPhase phase(ShenandoahPhaseTimings::full_gc);
-
   ShenandoahWorkerScope scope(workers(),
                               ShenandoahWorkerPolicy::calc_workers_for_fullgc(),
                               "full gc");
@@ -2813,11 +2806,9 @@
 void ShenandoahHeap::entry_degenerated(int point) {
   ShenandoahDegenPoint dpoint = (ShenandoahDegenPoint)point;
   const char* msg = degen_event_message(dpoint);
-  ShenandoahPausePhase gc_phase(msg, true /* log_heap_usage */);
+  ShenandoahPausePhase gc_phase(msg, ShenandoahPhaseTimings::degen_gc, true /* log_heap_usage */);
   EventMark em("%s", msg);
 
-  ShenandoahGCPhase phase(ShenandoahPhaseTimings::degen_gc);
-
   ShenandoahWorkerScope scope(workers(),
                               ShenandoahWorkerPolicy::calc_workers_for_stw_degenerated(),
                               "stw degenerated gc");
@@ -2831,11 +2822,9 @@
   TraceCollectorStats tcs(monitoring_support()->concurrent_collection_counters());
 
   const char* msg = conc_mark_event_message();
-  ShenandoahConcurrentPhase gc_phase(msg);
+  ShenandoahConcurrentPhase gc_phase(msg, ShenandoahPhaseTimings::conc_mark);
   EventMark em("%s", msg);
 
-  ShenandoahGCPhase conc_mark_phase(ShenandoahPhaseTimings::conc_mark);
-
   ShenandoahWorkerScope scope(workers(),
                               ShenandoahWorkerPolicy::calc_workers_for_conc_marking(),
                               "concurrent marking");
@@ -2848,11 +2837,9 @@
   TraceCollectorStats tcs(monitoring_support()->concurrent_collection_counters());
 
   static const char* msg = "Concurrent evacuation";
-  ShenandoahConcurrentPhase gc_phase(msg);
+  ShenandoahConcurrentPhase gc_phase(msg, ShenandoahPhaseTimings::conc_evac);
   EventMark em("%s", msg);
 
-  ShenandoahGCPhase conc_evac_phase(ShenandoahPhaseTimings::conc_evac);
-
   ShenandoahWorkerScope scope(workers(),
                               ShenandoahWorkerPolicy::calc_workers_for_conc_evac(),
                               "concurrent evacuation");
@@ -2863,11 +2850,9 @@
 
 void ShenandoahHeap::entry_updaterefs() {
   static const char* msg = "Concurrent update references";
-  ShenandoahConcurrentPhase gc_phase(msg);
+  ShenandoahConcurrentPhase gc_phase(msg, ShenandoahPhaseTimings::conc_update_refs);
   EventMark em("%s", msg);
 
-  ShenandoahGCPhase phase(ShenandoahPhaseTimings::conc_update_refs);
-
   ShenandoahWorkerScope scope(workers(),
                               ShenandoahWorkerPolicy::calc_workers_for_conc_update_ref(),
                               "concurrent reference update");
@@ -2878,10 +2863,9 @@
 
 void ShenandoahHeap::entry_weak_roots() {
   static const char* msg = "Concurrent weak roots";
-  ShenandoahConcurrentPhase gc_phase(msg);
+  ShenandoahConcurrentPhase gc_phase(msg, ShenandoahPhaseTimings::conc_weak_roots);
   EventMark em("%s", msg);
 
-  ShenandoahGCPhase phase(ShenandoahPhaseTimings::conc_weak_roots);
   ShenandoahGCWorkerPhase worker_phase(ShenandoahPhaseTimings::conc_weak_roots);
 
   ShenandoahWorkerScope scope(workers(),
@@ -2894,11 +2878,9 @@
 
 void ShenandoahHeap::entry_class_unloading() {
   static const char* msg = "Concurrent class unloading";
-  ShenandoahConcurrentPhase gc_phase(msg);
+  ShenandoahConcurrentPhase gc_phase(msg, ShenandoahPhaseTimings::conc_class_unloading);
   EventMark em("%s", msg);
 
-  ShenandoahGCPhase phase(ShenandoahPhaseTimings::conc_class_unloading);
-
   ShenandoahWorkerScope scope(workers(),
                               ShenandoahWorkerPolicy::calc_workers_for_conc_root_processing(),
                               "concurrent class unloading");
@@ -2909,10 +2891,9 @@
 
 void ShenandoahHeap::entry_strong_roots() {
   static const char* msg = "Concurrent strong roots";
-  ShenandoahConcurrentPhase gc_phase(msg);
+  ShenandoahConcurrentPhase gc_phase(msg, ShenandoahPhaseTimings::conc_strong_roots);
   EventMark em("%s", msg);
 
-  ShenandoahGCPhase phase(ShenandoahPhaseTimings::conc_strong_roots);
   ShenandoahGCWorkerPhase worker_phase(ShenandoahPhaseTimings::conc_strong_roots);
 
   ShenandoahWorkerScope scope(workers(),
@@ -2925,11 +2906,9 @@
 
 void ShenandoahHeap::entry_cleanup_early() {
   static const char* msg = "Concurrent cleanup";
-  ShenandoahConcurrentPhase gc_phase(msg,  true /* log_heap_usage */);
+  ShenandoahConcurrentPhase gc_phase(msg, ShenandoahPhaseTimings::conc_cleanup_early, true /* log_heap_usage */);
   EventMark em("%s", msg);
 
-  ShenandoahGCSubPhase phase(ShenandoahPhaseTimings::conc_cleanup_early);
-
   // This phase does not use workers, no need for setup
 
   try_inject_alloc_failure();
@@ -2938,11 +2917,9 @@
 
 void ShenandoahHeap::entry_cleanup_complete() {
   static const char* msg = "Concurrent cleanup";
-  ShenandoahConcurrentPhase gc_phase(msg,  true /* log_heap_usage */);
+  ShenandoahConcurrentPhase gc_phase(msg, ShenandoahPhaseTimings::conc_cleanup_complete, true /* log_heap_usage */);
   EventMark em("%s", msg);
 
-  ShenandoahGCSubPhase phase(ShenandoahPhaseTimings::conc_cleanup_complete);
-
   // This phase does not use workers, no need for setup
 
   try_inject_alloc_failure();
@@ -2951,11 +2928,9 @@
 
 void ShenandoahHeap::entry_reset() {
   static const char* msg = "Concurrent reset";
-  ShenandoahConcurrentPhase gc_phase(msg);
+  ShenandoahConcurrentPhase gc_phase(msg, ShenandoahPhaseTimings::conc_reset);
   EventMark em("%s", msg);
 
-  ShenandoahGCSubPhase phase(ShenandoahPhaseTimings::conc_reset);
-
   ShenandoahWorkerScope scope(workers(),
                               ShenandoahWorkerPolicy::calc_workers_for_conc_reset(),
                               "concurrent reset");
@@ -2967,11 +2942,9 @@
 void ShenandoahHeap::entry_preclean() {
   if (ShenandoahPreclean && process_references()) {
     static const char* msg = "Concurrent precleaning";
-    ShenandoahConcurrentPhase gc_phase(msg);
+    ShenandoahConcurrentPhase gc_phase(msg, ShenandoahPhaseTimings::conc_preclean);
     EventMark em("%s", msg);
 
-    ShenandoahGCSubPhase conc_preclean(ShenandoahPhaseTimings::conc_preclean);
-
     ShenandoahWorkerScope scope(workers(),
                                 ShenandoahWorkerPolicy::calc_workers_for_conc_preclean(),
                                 "concurrent preclean",
@@ -2984,11 +2957,9 @@
 
 void ShenandoahHeap::entry_uncommit(double shrink_before) {
   static const char *msg = "Concurrent uncommit";
-  ShenandoahConcurrentPhase gc_phase(msg, true /* log_heap_usage */);
+  ShenandoahConcurrentPhase gc_phase(msg, ShenandoahPhaseTimings::conc_uncommit, true /* log_heap_usage */);
   EventMark em("%s", msg);
 
-  ShenandoahGCSubPhase phase(ShenandoahPhaseTimings::conc_uncommit);
-
   op_uncommit(shrink_before);
 }
 
--- a/src/hotspot/share/gc/shenandoah/shenandoahHeapRegion.hpp	Fri May 08 09:45:57 2020 +0530
+++ b/src/hotspot/share/gc/shenandoah/shenandoahHeapRegion.hpp	Fri May 08 09:52:42 2020 +0530
@@ -243,7 +243,7 @@
   volatile size_t _live_data;
   volatile size_t _critical_pins;
 
-  HeapWord* _update_watermark;
+  HeapWord* volatile _update_watermark;
 
 public:
   ShenandoahHeapRegion(HeapWord* start, size_t index, bool committed);
@@ -382,19 +382,9 @@
   size_t get_tlab_allocs() const;
   size_t get_gclab_allocs() const;
 
-  HeapWord* get_update_watermark() const {
-    // Updates to the update-watermark only happen at safepoints.
-    // Since those updates are only monotonically increasing, possibly reading
-    // a stale value is only conservative - we would not miss to update any fields.
-    HeapWord* watermark = _update_watermark;
-    assert(bottom() <= watermark && watermark <= top(), "within bounds");
-    return watermark;
-  }
-
-  void set_update_watermark(HeapWord* w) {
-    assert(bottom() <= w && w <= top(), "within bounds");
-    _update_watermark = w;
-  }
+  inline HeapWord* get_update_watermark() const;
+  inline void set_update_watermark(HeapWord* w);
+  inline void set_update_watermark_at_safepoint(HeapWord* w);
 
 private:
   void do_commit();
--- a/src/hotspot/share/gc/shenandoah/shenandoahHeapRegion.inline.hpp	Fri May 08 09:45:57 2020 +0530
+++ b/src/hotspot/share/gc/shenandoah/shenandoahHeapRegion.inline.hpp	Fri May 08 09:52:42 2020 +0530
@@ -114,4 +114,22 @@
   return result;
 }
 
+inline HeapWord* ShenandoahHeapRegion::get_update_watermark() const {
+  HeapWord* watermark = Atomic::load_acquire(&_update_watermark);
+  assert(bottom() <= watermark && watermark <= top(), "within bounds");
+  return watermark;
+}
+
+inline void ShenandoahHeapRegion::set_update_watermark(HeapWord* w) {
+  assert(bottom() <= w && w <= top(), "within bounds");
+  Atomic::release_store(&_update_watermark, w);
+}
+
+// Fast version that avoids synchronization, only to be used at safepoints.
+inline void ShenandoahHeapRegion::set_update_watermark_at_safepoint(HeapWord* w) {
+  assert(bottom() <= w && w <= top(), "within bounds");
+  assert(SafepointSynchronize::is_at_safepoint(), "Should be at Shenandoah safepoint");
+  _update_watermark = w;
+}
+
 #endif // SHARE_GC_SHENANDOAH_SHENANDOAHHEAPREGION_INLINE_HPP
--- a/src/hotspot/share/gc/shenandoah/shenandoahJfrSupport.cpp	Fri May 08 09:45:57 2020 +0530
+++ b/src/hotspot/share/gc/shenandoah/shenandoahJfrSupport.cpp	Fri May 08 09:52:42 2020 +0530
@@ -23,7 +23,7 @@
  */
 
 #include "precompiled.hpp"
-#include "gc/shenandoah/shenandoahHeap.hpp"
+#include "gc/shenandoah/shenandoahHeap.inline.hpp"
 #include "gc/shenandoah/shenandoahHeapRegion.hpp"
 #include "gc/shenandoah/shenandoahJfrSupport.hpp"
 #include "jfr/jfrEvents.hpp"
--- a/src/hotspot/share/gc/shenandoah/shenandoahMarkCompact.cpp	Fri May 08 09:45:57 2020 +0530
+++ b/src/hotspot/share/gc/shenandoah/shenandoahMarkCompact.cpp	Fri May 08 09:52:42 2020 +0530
@@ -348,6 +348,7 @@
   }
 
   void work(uint worker_id) {
+    ShenandoahParallelWorkerSession worker_session(worker_id);
     ShenandoahHeapRegionSet* slice = _worker_slices[worker_id];
     ShenandoahHeapRegionSetIterator it(slice);
     ShenandoahHeapRegion* from_region = it.next();
@@ -727,6 +728,7 @@
   }
 
   void work(uint worker_id) {
+    ShenandoahParallelWorkerSession worker_session(worker_id);
     ShenandoahAdjustPointersObjectClosure obj_cl;
     ShenandoahHeapRegion* r = _regions.next();
     while (r != NULL) {
@@ -749,6 +751,7 @@
     _preserved_marks(preserved_marks) {}
 
   void work(uint worker_id) {
+    ShenandoahParallelWorkerSession worker_session(worker_id);
     ShenandoahAdjustPointersClosure cl;
     _rp->roots_do(worker_id, &cl);
     _preserved_marks->get(worker_id)->adjust_during_full_gc();
@@ -814,6 +817,7 @@
   }
 
   void work(uint worker_id) {
+    ShenandoahParallelWorkerSession worker_session(worker_id);
     ShenandoahHeapRegionSetIterator slice(_worker_slices[worker_id]);
 
     ShenandoahCompactObjectsClosure cl(worker_id);
@@ -960,6 +964,7 @@
   }
 
   void work(uint worker_id) {
+    ShenandoahParallelWorkerSession worker_session(worker_id);
     ShenandoahHeapRegion* region = _regions.next();
     ShenandoahHeap* heap = ShenandoahHeap::heap();
     ShenandoahMarkingContext* const ctx = heap->complete_marking_context();
--- a/src/hotspot/share/gc/shenandoah/shenandoahMarkingContext.cpp	Fri May 08 09:45:57 2020 +0530
+++ b/src/hotspot/share/gc/shenandoah/shenandoahMarkingContext.cpp	Fri May 08 09:52:42 2020 +0530
@@ -24,7 +24,7 @@
 
 #include "precompiled.hpp"
 #include "gc/shared/markBitMap.inline.hpp"
-#include "gc/shenandoah/shenandoahHeap.hpp"
+#include "gc/shenandoah/shenandoahHeap.inline.hpp"
 #include "gc/shenandoah/shenandoahHeapRegion.inline.hpp"
 #include "gc/shenandoah/shenandoahMarkingContext.hpp"
 
--- a/src/hotspot/share/gc/shenandoah/shenandoahOopClosures.hpp	Fri May 08 09:45:57 2020 +0530
+++ b/src/hotspot/share/gc/shenandoah/shenandoahOopClosures.hpp	Fri May 08 09:52:42 2020 +0530
@@ -26,7 +26,7 @@
 #define SHARE_GC_SHENANDOAH_SHENANDOAHOOPCLOSURES_HPP
 
 #include "gc/shared/referenceProcessor.hpp"
-#include "gc/shenandoah/shenandoahHeap.hpp"
+#include "gc/shenandoah/shenandoahHeap.inline.hpp"
 #include "gc/shenandoah/shenandoahStrDedupQueue.hpp"
 #include "gc/shenandoah/shenandoahTaskqueue.hpp"
 #include "memory/iterator.hpp"
--- a/src/hotspot/share/gc/shenandoah/shenandoahPhaseTimings.cpp	Fri May 08 09:45:57 2020 +0530
+++ b/src/hotspot/share/gc/shenandoah/shenandoahPhaseTimings.cpp	Fri May 08 09:52:42 2020 +0530
@@ -27,7 +27,7 @@
 #include "gc/shared/workerDataArray.inline.hpp"
 #include "gc/shenandoah/shenandoahCollectorPolicy.hpp"
 #include "gc/shenandoah/shenandoahPhaseTimings.hpp"
-#include "gc/shenandoah/shenandoahHeap.hpp"
+#include "gc/shenandoah/shenandoahHeap.inline.hpp"
 #include "gc/shenandoah/shenandoahHeuristics.hpp"
 #include "gc/shenandoah/shenandoahUtils.hpp"
 #include "runtime/orderAccess.hpp"
@@ -57,7 +57,7 @@
     _worker_data[i] = NULL;
     SHENANDOAH_PAR_PHASE_DO(,, SHENANDOAH_WORKER_DATA_NULL)
 #undef SHENANDOAH_WORKER_DATA_NULL
-    _cycle_data[i] = 0;
+    _cycle_data[i] = uninitialized();
   }
 
   // Then punch in the worker-related data.
@@ -134,7 +134,7 @@
 void ShenandoahPhaseTimings::set_cycle_data(Phase phase, double time) {
 #ifdef ASSERT
   double d = _cycle_data[phase];
-  assert(d == 0, "Should not be set yet: %s, current value: %lf", phase_name(phase), d);
+  assert(d == uninitialized(), "Should not be set yet: %s, current value: %lf", phase_name(phase), d);
 #endif
   _cycle_data[phase] = time;
 }
@@ -175,23 +175,44 @@
   for (uint pi = 0; pi < _num_phases; pi++) {
     Phase phase = Phase(pi);
     if (is_worker_phase(phase)) {
-      double s = 0;
+      double s = uninitialized();
       for (uint i = 1; i < _num_par_phases; i++) {
-        double t = worker_data(phase, ParPhase(i))->sum();
-        // add to each line in phase
-        set_cycle_data(Phase(phase + i + 1), t);
-        s += t;
+        ShenandoahWorkerData* wd = worker_data(phase, ParPhase(i));
+        double ws = uninitialized();
+        for (uint c = 0; c < _max_workers; c++) {
+          double v = wd->get(c);
+          if (v != ShenandoahWorkerData::uninitialized()) {
+            if (ws == uninitialized()) {
+              ws = v;
+            } else {
+              ws += v;
+            }
+          }
+        }
+        if (ws != uninitialized()) {
+          // add to each line in phase
+          set_cycle_data(Phase(phase + i + 1), ws);
+          if (s == uninitialized()) {
+            s = ws;
+          } else {
+            s += ws;
+          }
+        }
       }
-      // add to total for phase
-      set_cycle_data(Phase(phase + 1), s);
+      if (s != uninitialized()) {
+        // add to total for phase
+        set_cycle_data(Phase(phase + 1), s);
+      }
     }
   }
 }
 
 void ShenandoahPhaseTimings::flush_cycle_to_global() {
   for (uint i = 0; i < _num_phases; i++) {
-    _global_data[i].add(_cycle_data[i]);
-    _cycle_data[i] = 0;
+    if (_cycle_data[i] != uninitialized()) {
+      _global_data[i].add(_cycle_data[i]);
+      _cycle_data[i] = uninitialized();
+    }
     if (_worker_data[i] != NULL) {
       _worker_data[i]->reset();
     }
--- a/src/hotspot/share/gc/shenandoah/shenandoahPhaseTimings.hpp	Fri May 08 09:45:57 2020 +0530
+++ b/src/hotspot/share/gc/shenandoah/shenandoahPhaseTimings.hpp	Fri May 08 09:52:42 2020 +0530
@@ -195,6 +195,7 @@
   Phase worker_par_phase(Phase phase, ParPhase par_phase);
 
   void set_cycle_data(Phase phase, double time);
+  static double uninitialized() { return -1; }
 
 public:
   ShenandoahPhaseTimings(uint _max_workers);
--- a/src/hotspot/share/gc/shenandoah/shenandoahRootProcessor.cpp	Fri May 08 09:45:57 2020 +0530
+++ b/src/hotspot/share/gc/shenandoah/shenandoahRootProcessor.cpp	Fri May 08 09:52:42 2020 +0530
@@ -31,7 +31,7 @@
 #include "gc/shenandoah/shenandoahClosures.inline.hpp"
 #include "gc/shenandoah/shenandoahConcurrentRoots.hpp"
 #include "gc/shenandoah/shenandoahRootProcessor.inline.hpp"
-#include "gc/shenandoah/shenandoahHeap.hpp"
+#include "gc/shenandoah/shenandoahHeap.inline.hpp"
 #include "gc/shenandoah/shenandoahPhaseTimings.hpp"
 #include "gc/shenandoah/shenandoahStringDedup.hpp"
 #include "gc/shenandoah/shenandoahVMOperations.hpp"
--- a/src/hotspot/share/gc/shenandoah/shenandoahRootProcessor.inline.hpp	Fri May 08 09:45:57 2020 +0530
+++ b/src/hotspot/share/gc/shenandoah/shenandoahRootProcessor.inline.hpp	Fri May 08 09:52:42 2020 +0530
@@ -32,6 +32,7 @@
 #include "gc/shenandoah/shenandoahClosures.inline.hpp"
 #include "gc/shenandoah/shenandoahConcurrentRoots.hpp"
 #include "gc/shenandoah/shenandoahHeuristics.hpp"
+#include "gc/shenandoah/shenandoahHeap.inline.hpp"
 #include "gc/shenandoah/shenandoahPhaseTimings.hpp"
 #include "gc/shenandoah/shenandoahRootProcessor.hpp"
 #include "gc/shenandoah/shenandoahUtils.hpp"
--- a/src/hotspot/share/gc/shenandoah/shenandoahThreadLocalData.hpp	Fri May 08 09:45:57 2020 +0530
+++ b/src/hotspot/share/gc/shenandoah/shenandoahThreadLocalData.hpp	Fri May 08 09:52:42 2020 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018, 2019, Red Hat, Inc. All rights reserved.
+ * Copyright (c) 2018, 2020, Red Hat, Inc. 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
@@ -54,7 +54,12 @@
     _gclab(NULL),
     _gclab_size(0),
     _worker_id(INVALID_WORKER_ID),
-    _force_satb_flush(false) {
+    _force_satb_flush(false),
+    _disarmed_value(ShenandoahCodeRoots::disarmed_value()) {
+
+    // At least on x86_64, nmethod entry barrier encodes _disarmed_value offset
+    // in instruction as disp8 immed
+    assert(in_bytes(disarmed_value_offset()) < 128, "Offset range check");
   }
 
   ~ShenandoahThreadLocalData() {
@@ -128,7 +133,6 @@
     assert(data(thread)->_gclab == NULL, "Only initialize once");
     data(thread)->_gclab = new PLAB(PLAB::min_size());
     data(thread)->_gclab_size = 0;
-    data(thread)->_disarmed_value = ShenandoahCodeRoots::disarmed_value();
   }
 
   static PLAB* gclab(Thread* thread) {
--- a/src/hotspot/share/gc/shenandoah/shenandoahUnload.cpp	Fri May 08 09:45:57 2020 +0530
+++ b/src/hotspot/share/gc/shenandoah/shenandoahUnload.cpp	Fri May 08 09:52:42 2020 +0530
@@ -34,6 +34,7 @@
 #include "gc/shenandoah/shenandoahClosures.inline.hpp"
 #include "gc/shenandoah/shenandoahCodeRoots.hpp"
 #include "gc/shenandoah/shenandoahConcurrentRoots.hpp"
+#include "gc/shenandoah/shenandoahHeap.inline.hpp"
 #include "gc/shenandoah/shenandoahNMethod.inline.hpp"
 #include "gc/shenandoah/shenandoahLock.hpp"
 #include "gc/shenandoah/shenandoahRootProcessor.hpp"
--- a/src/hotspot/share/gc/shenandoah/shenandoahUtils.cpp	Fri May 08 09:45:57 2020 +0530
+++ b/src/hotspot/share/gc/shenandoah/shenandoahUtils.cpp	Fri May 08 09:52:42 2020 +0530
@@ -30,12 +30,12 @@
 #include "gc/shared/gcWhen.hpp"
 #include "gc/shenandoah/shenandoahCollectorPolicy.hpp"
 #include "gc/shenandoah/shenandoahMarkCompact.hpp"
-#include "gc/shenandoah/shenandoahHeap.hpp"
+#include "gc/shenandoah/shenandoahHeap.inline.hpp"
 #include "gc/shenandoah/shenandoahHeuristics.hpp"
 #include "gc/shenandoah/shenandoahUtils.hpp"
 #include "utilities/debug.hpp"
 
-ShenandoahPhaseTimings::Phase ShenandoahGCPhase::_current_phase = ShenandoahPhaseTimings::_invalid_phase;
+ShenandoahPhaseTimings::Phase ShenandoahTimingsTracker::_current_phase = ShenandoahPhaseTimings::_invalid_phase;
 
 ShenandoahGCSession::ShenandoahGCSession(GCCause::Cause cause) :
   _heap(ShenandoahHeap::heap()),
@@ -85,7 +85,8 @@
   );
 }
 
-ShenandoahPausePhase::ShenandoahPausePhase(const char* title, bool log_heap_usage) :
+ShenandoahPausePhase::ShenandoahPausePhase(const char* title, ShenandoahPhaseTimings::Phase phase, bool log_heap_usage) :
+  ShenandoahTimingsTracker(phase),
   _tracer(title, NULL, GCCause::_no_gc, log_heap_usage),
   _timer(ShenandoahHeap::heap()->gc_timer()) {
   _timer->register_gc_pause_start(title);
@@ -95,7 +96,8 @@
   _timer->register_gc_pause_end();
 }
 
-ShenandoahConcurrentPhase::ShenandoahConcurrentPhase(const char* title, bool log_heap_usage) :
+ShenandoahConcurrentPhase::ShenandoahConcurrentPhase(const char* title, ShenandoahPhaseTimings::Phase phase, bool log_heap_usage) :
+  ShenandoahTimingsTracker(phase),
   _tracer(title, NULL, GCCause::_no_gc, log_heap_usage),
   _timer(ShenandoahHeap::heap()->gc_timer()) {
   _timer->register_gc_concurrent_start(title);
@@ -105,7 +107,7 @@
   _timer->register_gc_concurrent_end();
 }
 
-ShenandoahGCPhase::ShenandoahGCPhase(ShenandoahPhaseTimings::Phase phase) :
+ShenandoahTimingsTracker::ShenandoahTimingsTracker(ShenandoahPhaseTimings::Phase phase) :
   _timings(ShenandoahHeap::heap()->phase_timings()), _phase(phase) {
   assert(!Thread::current()->is_Worker_thread() &&
               (Thread::current()->is_VM_thread() ||
@@ -116,22 +118,22 @@
   _start = os::elapsedTime();
 }
 
-ShenandoahGCPhase::~ShenandoahGCPhase() {
+ShenandoahTimingsTracker::~ShenandoahTimingsTracker() {
   _timings->record_phase_time(_phase, os::elapsedTime() - _start);
   _current_phase = _parent_phase;
 }
 
-bool ShenandoahGCPhase::is_current_phase_valid() {
+bool ShenandoahTimingsTracker::is_current_phase_valid() {
   return _current_phase < ShenandoahPhaseTimings::_num_phases;
 }
 
-ShenandoahGCSubPhase::ShenandoahGCSubPhase(ShenandoahPhaseTimings::Phase phase) :
-  ShenandoahGCPhase(phase),
+ShenandoahGCPhase::ShenandoahGCPhase(ShenandoahPhaseTimings::Phase phase) :
+  ShenandoahTimingsTracker(phase),
   _timer(ShenandoahHeap::heap()->gc_timer()) {
   _timer->register_gc_phase_start(ShenandoahPhaseTimings::phase_name(phase), Ticks::now());
 }
 
-ShenandoahGCSubPhase::~ShenandoahGCSubPhase() {
+ShenandoahGCPhase::~ShenandoahGCPhase() {
   _timer->register_gc_phase_end(Ticks::now());
 }
 
--- a/src/hotspot/share/gc/shenandoah/shenandoahUtils.hpp	Fri May 08 09:45:57 2020 +0530
+++ b/src/hotspot/share/gc/shenandoah/shenandoahUtils.hpp	Fri May 08 09:52:42 2020 +0530
@@ -54,27 +54,11 @@
   ~ShenandoahGCSession();
 };
 
-class ShenandoahPausePhase : public StackObj {
-private:
-  GCTraceTimeWrapper<LogLevel::Info, LOG_TAGS(gc)> _tracer;
-  ConcurrentGCTimer* const _timer;
-
-public:
-  ShenandoahPausePhase(const char* title, bool log_heap_usage = false);
-  ~ShenandoahPausePhase();
-};
-
-class ShenandoahConcurrentPhase : public StackObj {
-private:
-  GCTraceTimeWrapper<LogLevel::Info, LOG_TAGS(gc)> _tracer;
-  ConcurrentGCTimer* const _timer;
-
-public:
-  ShenandoahConcurrentPhase(const char* title, bool log_heap_usage = false);
-  ~ShenandoahConcurrentPhase();
-};
-
-class ShenandoahGCPhase : public StackObj {
+/*
+ * ShenandoahGCPhaseTiming tracks Shenandoah specific timing information
+ * of a GC phase
+ */
+class ShenandoahTimingsTracker : public StackObj {
 private:
   static ShenandoahPhaseTimings::Phase  _current_phase;
 
@@ -84,21 +68,53 @@
   double _start;
 
 public:
-  ShenandoahGCPhase(ShenandoahPhaseTimings::Phase phase);
-  ~ShenandoahGCPhase();
+  ShenandoahTimingsTracker(ShenandoahPhaseTimings::Phase phase);
+  ~ShenandoahTimingsTracker();
 
   static ShenandoahPhaseTimings::Phase current_phase() { return _current_phase; }
 
   static bool is_current_phase_valid();
 };
 
-class ShenandoahGCSubPhase: public ShenandoahGCPhase {
+/*
+ * ShenandoahPausePhase tracks a STW pause and emits Shenandoah timing and
+ * a corresponding JFR event
+ */
+class ShenandoahPausePhase : public ShenandoahTimingsTracker {
+private:
+  GCTraceTimeWrapper<LogLevel::Info, LOG_TAGS(gc)> _tracer;
+  ConcurrentGCTimer* const _timer;
+
+public:
+  ShenandoahPausePhase(const char* title, ShenandoahPhaseTimings::Phase phase, bool log_heap_usage = false);
+  ~ShenandoahPausePhase();
+};
+
+/*
+ * ShenandoahConcurrentPhase tracks a concurrent GC phase and emits Shenandoah timing and
+ * a corresponding JFR event
+ */
+class ShenandoahConcurrentPhase : public ShenandoahTimingsTracker {
+private:
+  GCTraceTimeWrapper<LogLevel::Info, LOG_TAGS(gc)> _tracer;
+  ConcurrentGCTimer* const _timer;
+
+public:
+  ShenandoahConcurrentPhase(const char* title, ShenandoahPhaseTimings::Phase phase, bool log_heap_usage = false);
+  ~ShenandoahConcurrentPhase();
+};
+
+/*
+ * ShenandoahGCPhase tracks Shenandoah specific timing information
+ * and emits a corresponding JFR event of a GC phase
+ */
+class ShenandoahGCPhase : public ShenandoahTimingsTracker {
 private:
   ConcurrentGCTimer* const _timer;
 
 public:
-  ShenandoahGCSubPhase(ShenandoahPhaseTimings::Phase phase);
-  ~ShenandoahGCSubPhase();
+  ShenandoahGCPhase(ShenandoahPhaseTimings::Phase phase);
+  ~ShenandoahGCPhase();
 };
 
 class ShenandoahGCWorkerPhase : public StackObj {
--- a/src/hotspot/share/include/jvm.h	Fri May 08 09:45:57 2020 +0530
+++ b/src/hotspot/share/include/jvm.h	Fri May 08 09:52:42 2020 +0530
@@ -176,6 +176,9 @@
 JNIEXPORT void JNICALL
 JVM_InitializeFromArchive(JNIEnv* env, jclass cls);
 
+JNIEXPORT jlong JNICALL
+JVM_GetRandomSeedForCDSDump();
+
 /*
  * java.lang.Throwable
  */
--- a/src/hotspot/share/jfr/leakprofiler/chains/edgeUtils.cpp	Fri May 08 09:45:57 2020 +0530
+++ b/src/hotspot/share/jfr/leakprofiler/chains/edgeUtils.cpp	Fri May 08 09:52:42 2020 +0530
@@ -23,7 +23,7 @@
  */
 
 #include "precompiled.hpp"
-#include "classfile/javaClasses.hpp"
+#include "classfile/javaClasses.inline.hpp"
 #include "jfr/leakprofiler/chains/edge.hpp"
 #include "jfr/leakprofiler/chains/edgeStore.hpp"
 #include "jfr/leakprofiler/chains/edgeUtils.hpp"
--- a/src/hotspot/share/jfr/leakprofiler/checkpoint/objectSampleDescription.cpp	Fri May 08 09:45:57 2020 +0530
+++ b/src/hotspot/share/jfr/leakprofiler/checkpoint/objectSampleDescription.cpp	Fri May 08 09:52:42 2020 +0530
@@ -23,7 +23,7 @@
  */
 
 #include "precompiled.hpp"
-#include "classfile/javaClasses.hpp"
+#include "classfile/javaClasses.inline.hpp"
 #include "classfile/symbolTable.hpp"
 #include "classfile/systemDictionary.hpp"
 #include "jfr/leakprofiler/checkpoint/objectSampleDescription.hpp"
--- a/src/hotspot/share/jfr/recorder/checkpoint/types/traceid/jfrTraceId.cpp	Fri May 08 09:45:57 2020 +0530
+++ b/src/hotspot/share/jfr/recorder/checkpoint/types/traceid/jfrTraceId.cpp	Fri May 08 09:52:42 2020 +0530
@@ -24,6 +24,7 @@
 
 #include "precompiled.hpp"
 #include "classfile/classLoaderData.inline.hpp"
+#include "classfile/javaClasses.inline.hpp"
 #include "classfile/symbolTable.hpp"
 #include "jfr/recorder/checkpoint/types/traceid/jfrTraceId.inline.hpp"
 #include "jfr/utilities/jfrTypes.hpp"
--- a/src/hotspot/share/jvmci/jvmciCodeInstaller.cpp	Fri May 08 09:45:57 2020 +0530
+++ b/src/hotspot/share/jvmci/jvmciCodeInstaller.cpp	Fri May 08 09:52:42 2020 +0530
@@ -22,6 +22,7 @@
  */
 
 #include "precompiled.hpp"
+#include "classfile/javaClasses.inline.hpp"
 #include "code/compiledIC.hpp"
 #include "compiler/compileBroker.hpp"
 #include "jvmci/jvmciCodeInstaller.hpp"
--- a/src/hotspot/share/jvmci/jvmciRuntime.cpp	Fri May 08 09:45:57 2020 +0530
+++ b/src/hotspot/share/jvmci/jvmciRuntime.cpp	Fri May 08 09:52:42 2020 +0530
@@ -22,6 +22,7 @@
  */
 
 #include "precompiled.hpp"
+#include "classfile/javaClasses.inline.hpp"
 #include "classfile/symbolTable.hpp"
 #include "compiler/compileBroker.hpp"
 #include "jvmci/jniAccessMark.inline.hpp"
--- a/src/hotspot/share/memory/dynamicArchive.cpp	Fri May 08 09:45:57 2020 +0530
+++ b/src/hotspot/share/memory/dynamicArchive.cpp	Fri May 08 09:52:42 2020 +0530
@@ -503,14 +503,13 @@
   void write_archive(char* serialized_data);
 
   void init_first_dump_space(address reserved_bottom) {
-    address first_space_base = reserved_bottom;
     DumpRegion* mc_space = MetaspaceShared::misc_code_dump_space();
     DumpRegion* rw_space = MetaspaceShared::read_write_dump_space();
 
     // Use the same MC->RW->RO ordering as in the base archive.
-    MetaspaceShared::init_shared_dump_space(mc_space, first_space_base);
+    MetaspaceShared::init_shared_dump_space(mc_space);
     _current_dump_space = mc_space;
-    _last_verified_top = first_space_base;
+    _last_verified_top = reserved_bottom;
     _num_dump_regions_used = 1;
   }
 
--- a/src/hotspot/share/memory/filemap.cpp	Fri May 08 09:45:57 2020 +0530
+++ b/src/hotspot/share/memory/filemap.cpp	Fri May 08 09:52:42 2020 +0530
@@ -1177,6 +1177,10 @@
   _mapped_base = NULL;
 }
 
+static const char* region_names[] = {
+  "mc", "rw", "ro", "bm", "ca0", "ca1", "oa0", "oa1"
+};
+
 void FileMapInfo::write_region(int region, char* base, size_t size,
                                bool read_only, bool allow_exec) {
   Arguments::assert_is_dumping_archive();
@@ -1184,6 +1188,9 @@
   FileMapRegion* si = space_at(region);
   char* target_base;
 
+  const int num_regions = sizeof(region_names)/sizeof(region_names[0]);
+  assert(0 <= region && region < num_regions, "sanity");
+
   if (region == MetaspaceShared::bm) {
     target_base = NULL; // always NULL for bm region.
   } else {
@@ -1197,11 +1204,13 @@
 
   si->set_file_offset(_file_offset);
   char* requested_base = (target_base == NULL) ? NULL : target_base + MetaspaceShared::final_delta();
-  log_debug(cds)("Shared file region  %d: " SIZE_FORMAT_HEX_W(08)
-                 " bytes, addr " INTPTR_FORMAT " file offset " SIZE_FORMAT_HEX_W(08),
-                 region, size, p2i(requested_base), _file_offset);
-
   int crc = ClassLoader::crc32(0, base, (jint)size);
+  if (size > 0) {
+    log_debug(cds)("Shared file region (%-3s)  %d: " SIZE_FORMAT_W(8)
+                   " bytes, addr " INTPTR_FORMAT " file offset " SIZE_FORMAT_HEX_W(08)
+                   " crc 0x%08x",
+                   region_names[region], region, size, p2i(requested_base), _file_offset, crc);
+  }
   si->init(region, target_base, size, read_only, allow_exec, crc);
 
   if (base != NULL) {
@@ -1246,8 +1255,6 @@
     write_oopmaps(open_oopmaps, curr_offset, buffer);
   }
 
-  log_debug(cds)("ptrmap = " INTPTR_FORMAT " (" SIZE_FORMAT " bytes)",
-                 p2i(buffer), size_in_bytes);
   write_region(MetaspaceShared::bm, (char*)buffer, size_in_bytes, /*read_only=*/true, /*allow_exec=*/false);
 }
 
@@ -1297,23 +1304,20 @@
   }
 
   size_t total_size = 0;
-  for (int i = first_region_id, arr_idx = 0;
-           i < first_region_id + max_num_regions;
-           i++, arr_idx++) {
+  for (int i = 0; i < max_num_regions; i++) {
     char* start = NULL;
     size_t size = 0;
-    if (arr_idx < arr_len) {
-      start = (char*)heap_mem->at(arr_idx).start();
-      size = heap_mem->at(arr_idx).byte_size();
+    if (i < arr_len) {
+      start = (char*)heap_mem->at(i).start();
+      size = heap_mem->at(i).byte_size();
       total_size += size;
     }
 
-    log_debug(cds)("Archive heap region %d: " INTPTR_FORMAT " - " INTPTR_FORMAT " = " SIZE_FORMAT_W(8) " bytes",
-                   i, p2i(start), p2i(start + size), size);
-    write_region(i, start, size, false, false);
+    int region_idx = i + first_region_id;
+    write_region(region_idx, start, size, false, false);
     if (size > 0) {
-      space_at(i)->init_oopmap(oopmaps->at(arr_idx)._offset,
-                               oopmaps->at(arr_idx)._oopmap_size_in_bits);
+      space_at(region_idx)->init_oopmap(oopmaps->at(i)._offset,
+                                        oopmaps->at(i)._oopmap_size_in_bits);
     }
   }
   return total_size;
--- a/src/hotspot/share/memory/heapShared.cpp	Fri May 08 09:45:57 2020 +0530
+++ b/src/hotspot/share/memory/heapShared.cpp	Fri May 08 09:52:42 2020 +0530
@@ -142,6 +142,10 @@
   if (archived_oop != NULL) {
     Copy::aligned_disjoint_words(cast_from_oop<HeapWord*>(obj), cast_from_oop<HeapWord*>(archived_oop), len);
     MetaspaceShared::relocate_klass_ptr(archived_oop);
+    // Clear age -- it might have been set if a GC happened during -Xshare:dump
+    markWord mark = archived_oop->mark_raw();
+    mark = mark.set_age(0);
+    archived_oop->set_mark_raw(mark);
     ArchivedObjectCache* cache = archived_object_cache();
     cache->put(obj, archived_oop);
     log_debug(cds, heap)("Archived heap object " PTR_FORMAT " ==> " PTR_FORMAT,
--- a/src/hotspot/share/memory/metaspaceShared.cpp	Fri May 08 09:45:57 2020 +0530
+++ b/src/hotspot/share/memory/metaspaceShared.cpp	Fri May 08 09:52:42 2020 +0530
@@ -77,6 +77,8 @@
 
 ReservedSpace MetaspaceShared::_shared_rs;
 VirtualSpace MetaspaceShared::_shared_vs;
+ReservedSpace MetaspaceShared::_symbol_rs;
+VirtualSpace MetaspaceShared::_symbol_vs;
 MetaspaceSharedStats MetaspaceShared::_stats;
 bool MetaspaceShared::_has_error_classes;
 bool MetaspaceShared::_archive_loading_failed = false;
@@ -120,21 +122,24 @@
     MetaspaceShared::report_out_of_space(_name, newtop - _top);
     ShouldNotReachHere();
   }
-  uintx delta;
-  if (DynamicDumpSharedSpaces) {
-    delta = DynamicArchive::object_delta_uintx(newtop);
-  } else {
-    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.");
+
+  if (_rs == MetaspaceShared::shared_rs()) {
+    uintx delta;
+    if (DynamicDumpSharedSpaces) {
+      delta = DynamicArchive::object_delta_uintx(newtop);
+    } else {
+      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);
+  MetaspaceShared::commit_to(_rs, _vs, newtop);
   _top = newtop;
   return _top;
 }
@@ -172,26 +177,35 @@
   }
 }
 
+void DumpRegion::init(ReservedSpace* rs, VirtualSpace* vs) {
+  _rs = rs;
+  _vs = vs;
+  // Start with 0 committed bytes. The memory will be committed as needed by
+  // MetaspaceShared::commit_to().
+  if (!_vs->initialize(*_rs, 0)) {
+    fatal("Unable to allocate memory for shared space");
+  }
+  _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->_rs = _rs;
+    next->_vs = _vs;
     next->_base = next->_top = this->_end;
-    next->_end = MetaspaceShared::shared_rs()->end();
+    next->_end = _rs->end();
   }
 }
 
-static DumpRegion _mc_region("mc"), _ro_region("ro"), _rw_region("rw");
+static DumpRegion _mc_region("mc"), _ro_region("ro"), _rw_region("rw"), _symbol_region("symbols");
 static size_t _total_closed_archive_region_size = 0, _total_open_archive_region_size = 0;
 
-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)) {
-    fatal("Unable to allocate memory for shared space");
-  }
-  first_space->init(&_shared_rs, (char*)first_space_bottom);
+void MetaspaceShared::init_shared_dump_space(DumpRegion* first_space) {
+  first_space->init(&_shared_rs, &_shared_vs);
 }
 
 DumpRegion* MetaspaceShared::misc_code_dump_space() {
@@ -211,6 +225,10 @@
   current->pack(next);
 }
 
+char* MetaspaceShared::symbol_space_alloc(size_t num_bytes) {
+  return _symbol_region.allocate(num_bytes);
+}
+
 char* MetaspaceShared::misc_code_space_alloc(size_t num_bytes) {
   return _mc_region.allocate(num_bytes);
 }
@@ -320,6 +338,14 @@
   SharedBaseAddress = (size_t)_shared_rs.base();
   log_info(cds)("Allocated shared space: " SIZE_FORMAT " bytes at " PTR_FORMAT,
                 _shared_rs.size(), p2i(_shared_rs.base()));
+
+  size_t symbol_rs_size = LP64_ONLY(3 * G) NOT_LP64(128 * M);
+  _symbol_rs = ReservedSpace(symbol_rs_size);
+  if (!_symbol_rs.is_reserved()) {
+    vm_exit_during_initialization("Unable to reserve memory for symbols",
+                                  err_msg(SIZE_FORMAT " bytes.", symbol_rs_size));
+  }
+  _symbol_region.init(&_symbol_rs, &_symbol_vs);
 }
 
 // Called by universe_post_init()
@@ -397,33 +423,37 @@
   }
 }
 
-void MetaspaceShared::commit_shared_space_to(char* newtop) {
+void MetaspaceShared::commit_to(ReservedSpace* rs, VirtualSpace* vs, char* newtop) {
   Arguments::assert_is_dumping_archive();
-  char* base = _shared_rs.base();
+  char* base = rs->base();
   size_t need_committed_size = newtop - base;
-  size_t has_committed_size = _shared_vs.committed_size();
+  size_t has_committed_size = vs->committed_size();
   if (need_committed_size < has_committed_size) {
     return;
   }
 
   size_t min_bytes = need_committed_size - has_committed_size;
   size_t preferred_bytes = 1 * M;
-  size_t uncommitted = _shared_vs.reserved_size() - has_committed_size;
+  size_t uncommitted = vs->reserved_size() - has_committed_size;
 
   size_t commit =MAX2(min_bytes, preferred_bytes);
   commit = MIN2(commit, uncommitted);
   assert(commit <= uncommitted, "sanity");
 
-  bool result = _shared_vs.expand_by(commit, false);
-  ArchivePtrMarker::expand_ptr_end((address*)_shared_vs.high());
+  bool result = vs->expand_by(commit, false);
+  if (rs == &_shared_rs) {
+    ArchivePtrMarker::expand_ptr_end((address*)vs->high());
+  }
 
   if (!result) {
     vm_exit_during_initialization(err_msg("Failed to expand shared space to " SIZE_FORMAT " bytes",
                                           need_committed_size));
   }
 
-  log_debug(cds)("Expanding shared spaces by " SIZE_FORMAT_W(7) " bytes [total " SIZE_FORMAT_W(9)  " bytes ending at %p]",
-                 commit, _shared_vs.actual_committed_size(), _shared_vs.high());
+  assert(rs == &_shared_rs || rs == &_symbol_rs, "must be");
+  const char* which = (rs == &_shared_rs) ? "shared" : "symbol";
+  log_debug(cds)("Expanding %s spaces by " SIZE_FORMAT_W(7) " bytes [total " SIZE_FORMAT_W(9)  " bytes ending at %p]",
+                 which, commit, vs->actual_committed_size(), vs->high());
 }
 
 void MetaspaceShared::initialize_ptr_marker(CHeapBitMap* ptrmap) {
@@ -506,6 +536,10 @@
 // is run at a safepoint just before exit, this is the entire set of classes.
 static GrowableArray<Klass*>* _global_klass_objects;
 
+static int global_klass_compare(Klass** a, Klass **b) {
+  return a[0]->name()->fast_compare(b[0]->name());
+}
+
 GrowableArray<Klass*>* MetaspaceShared::collected_klasses() {
   return _global_klass_objects;
 }
@@ -1331,7 +1365,14 @@
       RefRelocator ext_reloc;
       iterate_roots(&ext_reloc);
     }
-
+    {
+      log_info(cds)("Fixing symbol identity hash ... ");
+      os::init_random(0x12345678);
+      GrowableArray<Symbol*>* symbols = _ssc->get_sorted_symbols();
+      for (int i=0; i<symbols->length(); i++) {
+        symbols->at(i)->update_identity_hash();
+      }
+    }
 #ifdef ASSERT
     {
       log_info(cds)("Verifying external roots ... ");
@@ -1364,6 +1405,21 @@
   }
 
   static void iterate_roots(MetaspaceClosure* it) {
+    // To ensure deterministic contents in the archive, we just need to ensure that
+    // we iterate the MetsapceObjs in a deterministic order. It doesn't matter where
+    // the MetsapceObjs are located originally, as they are copied sequentially into
+    // the archive during the iteration.
+    //
+    // The only issue here is that the symbol table and the system directories may be
+    // randomly ordered, so we copy the symbols and klasses into two arrays and sort
+    // them deterministically.
+    //
+    // During -Xshare:dump, the order of Symbol creation is strictly determined by
+    // the SharedClassListFile (class loading is done in a single thread and the JIT
+    // is disabled). Also, Symbols are allocated in monotonically increasing addresses
+    // (see Symbol::operator new(size_t, int)). So if we iterate the Symbols by
+    // ascending address order, we ensure that all Symbols are copied into deterministic
+    // locations in the archive.
     GrowableArray<Symbol*>* symbols = _ssc->get_sorted_symbols();
     for (int i=0; i<symbols->length(); i++) {
       it->push(symbols->adr_at(i));
@@ -1525,6 +1581,7 @@
   _global_klass_objects = new GrowableArray<Klass*>(1000);
   CollectClassesClosure collect_classes;
   ClassLoaderDataGraph::loaded_classes_do(&collect_classes);
+  _global_klass_objects->sort(global_klass_compare);
 
   print_class_stats();
 
@@ -1558,8 +1615,10 @@
   _ro_region.pack();
 
   // The vtable clones contain addresses of the current process.
-  // We don't want to write these addresses into the archive.
+  // We don't want to write these addresses into the archive. Same for i2i buffer.
   MetaspaceShared::zero_cpp_vtable_clones_for_writing();
+  memset(MetaspaceShared::i2i_entry_code_buffers(), 0,
+         MetaspaceShared::i2i_entry_code_buffers_size());
 
   // relocate the data so that it can be mapped to Arguments::default_SharedBaseAddress()
   // without runtime relocation.
@@ -1631,7 +1690,7 @@
   _mc_region.print(total_reserved);
   _rw_region.print(total_reserved);
   _ro_region.print(total_reserved);
-  print_bitmap_region_stats(bitmap_reserved, total_reserved);
+  print_bitmap_region_stats(bitmap_used, total_reserved);
   print_heap_region_stats(_closed_archive_heap_regions, "ca", total_reserved);
   print_heap_region_stats(_open_archive_heap_regions, "oa", total_reserved);
 
@@ -1640,8 +1699,8 @@
 }
 
 void VM_PopulateDumpSharedSpace::print_bitmap_region_stats(size_t size, size_t total_size) {
-  log_debug(cds)("bm  space: " SIZE_FORMAT_W(9) " [ %4.1f%% of total] out of " SIZE_FORMAT_W(9) " bytes [100.0%% used] at " INTPTR_FORMAT,
-                 size, size/double(total_size)*100.0, size, p2i(NULL));
+  log_debug(cds)("bm  space: " SIZE_FORMAT_W(9) " [ %4.1f%% of total] out of " SIZE_FORMAT_W(9) " bytes [100.0%% used]",
+                 size, size/double(total_size)*100.0, size);
 }
 
 void VM_PopulateDumpSharedSpace::print_heap_region_stats(GrowableArray<MemRegion> *heap_mem,
--- a/src/hotspot/share/memory/metaspaceShared.hpp	Fri May 08 09:45:57 2020 +0530
+++ b/src/hotspot/share/memory/metaspaceShared.hpp	Fri May 08 09:52:42 2020 +0530
@@ -63,6 +63,8 @@
   char* _top;
   char* _end;
   bool _is_packed;
+  ReservedSpace* _rs;
+  VirtualSpace* _vs;
 
 public:
   DumpRegion(const char* name) : _name(name), _base(NULL), _top(NULL), _end(NULL), _is_packed(false) {}
@@ -85,19 +87,7 @@
   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 init(ReservedSpace* rs, VirtualSpace* vs);
 
   void pack(DumpRegion* next = NULL);
 
@@ -178,6 +168,8 @@
   // CDS support
   static ReservedSpace _shared_rs;
   static VirtualSpace _shared_vs;
+  static ReservedSpace _symbol_rs;
+  static VirtualSpace _symbol_vs;
   static int _max_alignment;
   static MetaspaceSharedStats _stats;
   static bool _has_error_classes;
@@ -222,11 +214,15 @@
     NOT_CDS(return NULL);
   }
 
+  static Symbol* symbol_rs_base() {
+    return (Symbol*)_symbol_rs.base();
+  }
+
   static void set_shared_rs(ReservedSpace rs) {
     CDS_ONLY(_shared_rs = rs);
   }
 
-  static void commit_shared_space_to(char* newtop) NOT_CDS_RETURN;
+  static void commit_to(ReservedSpace* rs, VirtualSpace* vs, char* newtop) NOT_CDS_RETURN;
   static void initialize_dumptime_shared_and_meta_spaces() NOT_CDS_RETURN;
   static void initialize_runtime_shared_and_meta_spaces() NOT_CDS_RETURN;
   static void post_initialize(TRAPS) NOT_CDS_RETURN;
@@ -302,7 +298,7 @@
 #if INCLUDE_CDS
   static ReservedSpace reserve_shared_space(size_t size, char* requested_address = NULL);
   static size_t reserved_space_alignment();
-  static void init_shared_dump_space(DumpRegion* first_space, address first_space_bottom = NULL);
+  static void init_shared_dump_space(DumpRegion* first_space);
   static DumpRegion* misc_code_dump_space();
   static DumpRegion* read_write_dump_space();
   static DumpRegion* read_only_dump_space();
@@ -312,7 +308,10 @@
   static void rewrite_nofast_bytecodes_and_calculate_fingerprints(Thread* thread, InstanceKlass* ik);
 #endif
 
-  // Allocate a block of memory from the "mc", "ro", or "rw" regions.
+  // Allocate a block of memory from the temporary "symbol" region.
+  static char* symbol_space_alloc(size_t num_bytes);
+
+  // Allocate a block of memory from the "mc" or "ro" regions.
   static char* misc_code_space_alloc(size_t num_bytes);
   static char* read_only_space_alloc(size_t num_bytes);
 
--- a/src/hotspot/share/oops/instanceKlass.cpp	Fri May 08 09:45:57 2020 +0530
+++ b/src/hotspot/share/oops/instanceKlass.cpp	Fri May 08 09:52:42 2020 +0530
@@ -505,10 +505,6 @@
   assert(is_instance_klass(), "is layout incorrect?");
   assert(size_helper() == parser.layout_size(), "incorrect size_helper?");
 
-  if (Arguments::is_dumping_archive()) {
-    SystemDictionaryShared::init_dumptime_info(this);
-  }
-
   // Set biased locking bit for all instances of this class; it will be
   // cleared if revocation occurs too often for this type
   if (UseBiasedLocking && BiasedLocking::enabled()) {
--- a/src/hotspot/share/oops/instanceKlass.hpp	Fri May 08 09:45:57 2020 +0530
+++ b/src/hotspot/share/oops/instanceKlass.hpp	Fri May 08 09:52:42 2020 +0530
@@ -958,6 +958,7 @@
   }
   // allocation
   instanceOop allocate_instance(TRAPS);
+  static instanceOop allocate_instance(oop cls, TRAPS);
 
   // additional member function to return a handle
   instanceHandle allocate_instance_handle(TRAPS);
--- a/src/hotspot/share/oops/instanceKlass.inline.hpp	Fri May 08 09:45:57 2020 +0530
+++ b/src/hotspot/share/oops/instanceKlass.inline.hpp	Fri May 08 09:52:42 2020 +0530
@@ -26,6 +26,7 @@
 #define SHARE_OOPS_INSTANCEKLASS_INLINE_HPP
 
 #include "memory/iterator.hpp"
+#include "memory/resourceArea.hpp"
 #include "oops/instanceKlass.hpp"
 #include "oops/klass.hpp"
 #include "oops/oop.inline.hpp"
@@ -157,4 +158,16 @@
   oop_oop_iterate_oop_maps_bounded<T>(obj, closure, mr);
 }
 
+inline instanceOop InstanceKlass::allocate_instance(oop java_class, TRAPS) {
+  Klass* k = java_lang_Class::as_Klass(java_class);
+  if (k == NULL) {
+    ResourceMark rm(THREAD);
+    THROW_(vmSymbols::java_lang_InstantiationException(), NULL);
+  }
+  InstanceKlass* ik = cast(k);
+  ik->check_valid_for_instantiation(false, CHECK_NULL);
+  ik->initialize(CHECK_NULL);
+  return ik->allocate_instance(THREAD);
+}
+
 #endif // SHARE_OOPS_INSTANCEKLASS_INLINE_HPP
--- a/src/hotspot/share/oops/klass.cpp	Fri May 08 09:45:57 2020 +0530
+++ b/src/hotspot/share/oops/klass.cpp	Fri May 08 09:52:42 2020 +0530
@@ -29,6 +29,7 @@
 #include "classfile/javaClasses.hpp"
 #include "classfile/moduleEntry.hpp"
 #include "classfile/systemDictionary.hpp"
+#include "classfile/systemDictionaryShared.hpp"
 #include "classfile/vmSymbols.hpp"
 #include "gc/shared/collectedHeap.inline.hpp"
 #include "logging/log.hpp"
@@ -79,6 +80,10 @@
 void Klass::set_name(Symbol* n) {
   _name = n;
   if (_name != NULL) _name->increment_refcount();
+
+  if (Arguments::is_dumping_archive() && is_instance_klass()) {
+    SystemDictionaryShared::init_dumptime_info(InstanceKlass::cast(this));
+  }
 }
 
 bool Klass::is_subclass_of(const Klass* k) const {
--- a/src/hotspot/share/oops/symbol.cpp	Fri May 08 09:45:57 2020 +0530
+++ b/src/hotspot/share/oops/symbol.cpp	Fri May 08 09:52:42 2020 +0530
@@ -30,6 +30,7 @@
 #include "logging/log.hpp"
 #include "logging/logStream.hpp"
 #include "memory/allocation.inline.hpp"
+#include "memory/metaspaceShared.hpp"
 #include "memory/resourceArea.hpp"
 #include "memory/universe.hpp"
 #include "oops/symbol.hpp"
@@ -56,6 +57,22 @@
 }
 
 void* Symbol::operator new(size_t sz, int len) throw() {
+#if INCLUDE_CDS
+ if (DumpSharedSpaces) {
+    // To get deterministic output from -Xshare:dump, we ensure that Symbols are allocated in
+    // increasing addresses. When the symbols are copied into the archive, we preserve their
+    // relative address order (see SortedSymbolClosure in metaspaceShared.cpp)
+    //
+    // We cannot use arena because arena chunks are allocated by the OS. As a result, for example,
+    // the archived symbol of "java/lang/Object" may sometimes be lower than "java/lang/String", and
+    // sometimes be higher. This would cause non-deterministic contents in the archive.
+   DEBUG_ONLY(static void* last = 0);
+   void* p = (void*)MetaspaceShared::symbol_space_alloc(size(len)*wordSize);
+   assert(p > last, "must increase monotonically");
+   DEBUG_ONLY(last = p);
+   return p;
+ }
+#endif
   int alloc_size = size(len)*wordSize;
   address res = (address) AllocateHeap(alloc_size, mtSymbol);
   return res;
@@ -72,11 +89,21 @@
   FreeHeap(p);
 }
 
+#if INCLUDE_CDS
+void Symbol::update_identity_hash() {
+  // This is called at a safepoint during dumping of a static CDS archive. The caller should have
+  // called os::init_random() with a deterministic seed and then iterate all archived Symbols in
+  // a deterministic order.
+  assert(SafepointSynchronize::is_at_safepoint(), "must be at a safepoint");
+  _hash_and_refcount =  pack_hash_and_refcount((short)os::random(), PERM_REFCOUNT);
+}
+
 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");
   _hash_and_refcount =  pack_hash_and_refcount(extract_hash(_hash_and_refcount), PERM_REFCOUNT);
 }
+#endif
 
 // ------------------------------------------------------------------
 // Symbol::index_of
--- a/src/hotspot/share/oops/symbol.hpp	Fri May 08 09:45:57 2020 +0530
+++ b/src/hotspot/share/oops/symbol.hpp	Fri May 08 09:52:42 2020 +0530
@@ -168,7 +168,8 @@
   bool is_permanent() const {
     return (refcount() == PERM_REFCOUNT);
   }
-  void set_permanent();
+  void update_identity_hash() NOT_CDS_RETURN;
+  void set_permanent() NOT_CDS_RETURN;
   void make_permanent();
 
   // Function char_at() returns the Symbol's selected u1 byte as a char type.
--- a/src/hotspot/share/opto/compile.cpp	Fri May 08 09:45:57 2020 +0530
+++ b/src/hotspot/share/opto/compile.cpp	Fri May 08 09:52:42 2020 +0530
@@ -2478,7 +2478,9 @@
 bool Compile::compute_logic_cone(Node* n, Unique_Node_List& partition, Unique_Node_List& inputs) {
   assert(partition.size() == 0, "not empty");
   assert(inputs.size() == 0, "not empty");
-  assert(!is_vector_ternary_bitwise_op(n), "not supported");
+  if (is_vector_ternary_bitwise_op(n)) {
+    return false;
+  }
 
   bool is_unary_op = is_vector_unary_bitwise_op(n);
   if (is_unary_op) {
@@ -2520,6 +2522,7 @@
          (inputs.size()    == 2 || inputs.size()    == 3);
 }
 
+
 void Compile::process_logic_cone_root(PhaseIterGVN &igvn, Node *n, VectorSet &visited) {
   assert(is_vector_bitwise_op(n), "not a root");
 
--- a/src/hotspot/share/opto/node.cpp	Fri May 08 09:45:57 2020 +0530
+++ b/src/hotspot/share/opto/node.cpp	Fri May 08 09:52:42 2020 +0530
@@ -1594,6 +1594,11 @@
   return n->find(idx);
 }
 
+// call this from debugger with root node as default:
+Node* find_node(int idx) {
+  return Compile::current()->root()->find(idx);
+}
+
 //------------------------------find-------------------------------------------
 Node* Node::find(int idx) const {
   ResourceArea *area = Thread::current()->resource_area();
--- a/src/hotspot/share/prims/jni.cpp	Fri May 08 09:45:57 2020 +0530
+++ b/src/hotspot/share/prims/jni.cpp	Fri May 08 09:52:42 2020 +0530
@@ -49,7 +49,7 @@
 #include "memory/universe.hpp"
 #include "oops/access.inline.hpp"
 #include "oops/arrayOop.inline.hpp"
-#include "oops/instanceKlass.hpp"
+#include "oops/instanceKlass.inline.hpp"
 #include "oops/instanceOop.hpp"
 #include "oops/markWord.hpp"
 #include "oops/method.hpp"
@@ -1064,19 +1064,6 @@
   }
 }
 
-
-static instanceOop alloc_object(jclass clazz, TRAPS) {
-  Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(clazz));
-  if (k == NULL) {
-    ResourceMark rm(THREAD);
-    THROW_(vmSymbols::java_lang_InstantiationException(), NULL);
-  }
-  k->check_valid_for_instantiation(false, CHECK_NULL);
-  k->initialize(CHECK_NULL);
-  instanceOop ih = InstanceKlass::cast(k)->allocate_instance(THREAD);
-  return ih;
-}
-
 DT_RETURN_MARK_DECL(AllocObject, jobject
                     , HOTSPOT_JNI_ALLOCOBJECT_RETURN(_ret_ref));
 
@@ -1088,7 +1075,7 @@
   jobject ret = NULL;
   DT_RETURN_MARK(AllocObject, jobject, (const jobject&)ret);
 
-  instanceOop i = alloc_object(clazz, CHECK_NULL);
+  instanceOop i = InstanceKlass::allocate_instance(JNIHandles::resolve_non_null(clazz), CHECK_NULL);
   ret = JNIHandles::make_local(env, i);
   return ret;
 JNI_END
@@ -1104,7 +1091,7 @@
   jobject obj = NULL;
   DT_RETURN_MARK(NewObjectA, jobject, (const jobject)obj);
 
-  instanceOop i = alloc_object(clazz, CHECK_NULL);
+  instanceOop i = InstanceKlass::allocate_instance(JNIHandles::resolve_non_null(clazz), CHECK_NULL);
   obj = JNIHandles::make_local(env, i);
   JavaValue jvalue(T_VOID);
   JNI_ArgumentPusherArray ap(methodID, args);
@@ -1124,7 +1111,7 @@
   jobject obj = NULL;
   DT_RETURN_MARK(NewObjectV, jobject, (const jobject&)obj);
 
-  instanceOop i = alloc_object(clazz, CHECK_NULL);
+  instanceOop i = InstanceKlass::allocate_instance(JNIHandles::resolve_non_null(clazz), CHECK_NULL);
   obj = JNIHandles::make_local(env, i);
   JavaValue jvalue(T_VOID);
   JNI_ArgumentPusherVaArg ap(methodID, args);
@@ -1144,7 +1131,7 @@
   jobject obj = NULL;
   DT_RETURN_MARK(NewObject, jobject, (const jobject&)obj);
 
-  instanceOop i = alloc_object(clazz, CHECK_NULL);
+  instanceOop i = InstanceKlass::allocate_instance(JNIHandles::resolve_non_null(clazz), CHECK_NULL);
   obj = JNIHandles::make_local(env, i);
   va_list args;
   va_start(args, methodID);
--- a/src/hotspot/share/prims/jvm.cpp	Fri May 08 09:45:57 2020 +0530
+++ b/src/hotspot/share/prims/jvm.cpp	Fri May 08 09:52:42 2020 +0530
@@ -3733,6 +3733,29 @@
   HeapShared::initialize_from_archived_subgraph(k);
 JVM_END
 
+JVM_ENTRY_NO_ENV(jlong, JVM_GetRandomSeedForCDSDump())
+  JVMWrapper("JVM_GetRandomSeedForCDSDump");
+  if (DumpSharedSpaces) {
+    const char* release = Abstract_VM_Version::vm_release();
+    const char* dbg_level = Abstract_VM_Version::jdk_debug_level();
+    const char* version = VM_Version::internal_vm_info_string();
+    jlong seed = (jlong)(java_lang_String::hash_code((const jbyte*)release, (int)strlen(release)) ^
+                         java_lang_String::hash_code((const jbyte*)dbg_level, (int)strlen(dbg_level)) ^
+                         java_lang_String::hash_code((const jbyte*)version, (int)strlen(version)));
+    seed += (jlong)Abstract_VM_Version::vm_major_version();
+    seed += (jlong)Abstract_VM_Version::vm_minor_version();
+    seed += (jlong)Abstract_VM_Version::vm_security_version();
+    seed += (jlong)Abstract_VM_Version::vm_patch_version();
+    if (seed == 0) { // don't let this ever be zero.
+      seed = 0x87654321;
+    }
+    log_debug(cds)("JVM_GetRandomSeedForCDSDump() = " JLONG_FORMAT, seed);
+    return seed;
+  } else {
+    return 0;
+  }
+JVM_END
+
 // Returns an array of all live Thread objects (VM internal JavaThreads,
 // jvmti agent threads, and JNI attaching threads  are skipped)
 // See CR 6404306 regarding JNI attaching threads
--- a/src/hotspot/share/prims/unsafe.cpp	Fri May 08 09:45:57 2020 +0530
+++ b/src/hotspot/share/prims/unsafe.cpp	Fri May 08 09:52:42 2020 +0530
@@ -27,12 +27,14 @@
 #include "jvm.h"
 #include "classfile/classFileStream.hpp"
 #include "classfile/classLoader.hpp"
+#include "classfile/javaClasses.inline.hpp"
 #include "classfile/vmSymbols.hpp"
 #include "jfr/jfrEvents.hpp"
 #include "memory/allocation.inline.hpp"
 #include "memory/resourceArea.hpp"
 #include "oops/access.inline.hpp"
 #include "oops/fieldStreams.inline.hpp"
+#include "oops/instanceKlass.inline.hpp"
 #include "oops/objArrayOop.inline.hpp"
 #include "oops/oop.inline.hpp"
 #include "oops/typeArrayOop.inline.hpp"
@@ -353,8 +355,8 @@
 ////// Allocation requests
 
 UNSAFE_ENTRY(jobject, Unsafe_AllocateInstance(JNIEnv *env, jobject unsafe, jclass cls)) {
-  ThreadToNativeFromVM ttnfv(thread);
-  return env->AllocObject(cls);
+  instanceOop i = InstanceKlass::allocate_instance(JNIHandles::resolve_non_null(cls), CHECK_NULL);
+  return JNIHandles::make_local(env, i);
 } UNSAFE_END
 
 UNSAFE_ENTRY(jlong, Unsafe_AllocateMemory0(JNIEnv *env, jobject unsafe, jlong size)) {
--- a/src/hotspot/share/prims/whitebox.cpp	Fri May 08 09:45:57 2020 +0530
+++ b/src/hotspot/share/prims/whitebox.cpp	Fri May 08 09:52:42 2020 +0530
@@ -27,6 +27,7 @@
 #include <new>
 
 #include "classfile/classLoaderDataGraph.hpp"
+#include "classfile/javaClasses.inline.hpp"
 #include "classfile/modules.hpp"
 #include "classfile/protectionDomainCache.hpp"
 #include "classfile/stringTable.hpp"
--- a/src/hotspot/share/runtime/arguments.cpp	Fri May 08 09:45:57 2020 +0530
+++ b/src/hotspot/share/runtime/arguments.cpp	Fri May 08 09:52:42 2020 +0530
@@ -522,7 +522,6 @@
   { "UseMembar",                    JDK_Version::jdk(10), JDK_Version::jdk(12), JDK_Version::undefined() },
   { "AllowRedefinitionToAddDeleteMethods", JDK_Version::jdk(13), JDK_Version::undefined(), JDK_Version::undefined() },
   { "FlightRecorder",               JDK_Version::jdk(13), JDK_Version::undefined(), JDK_Version::undefined() },
-  { "MonitorBound",                 JDK_Version::jdk(14), JDK_Version::jdk(15), JDK_Version::jdk(16) },
   { "PrintVMQWaitTime",             JDK_Version::jdk(15), JDK_Version::jdk(16), JDK_Version::jdk(17) },
   { "UseNewFieldLayout",            JDK_Version::jdk(15), JDK_Version::jdk(16), JDK_Version::jdk(17) },
   { "ForceNUMA",                    JDK_Version::jdk(15), JDK_Version::jdk(16), JDK_Version::jdk(17) },
@@ -550,6 +549,7 @@
   { "UseSSE",                        JDK_Version::undefined(), JDK_Version::jdk(15), JDK_Version::jdk(16) },
 #endif // !X86
   { "UseAdaptiveGCBoundary",         JDK_Version::undefined(), JDK_Version::jdk(15), JDK_Version::jdk(16) },
+  { "MonitorBound",                  JDK_Version::jdk(14),     JDK_Version::jdk(15), JDK_Version::jdk(16) },
 
 #ifdef TEST_VERIFY_SPECIAL_JVM_FLAGS
   // These entries will generate build errors.  Their purpose is to test the macros.
@@ -4158,14 +4158,6 @@
          FLAG_SET_DEFAULT(MinHeapDeltaBytes, 64*M);
       }
     }
-    // UseNUMAInterleaving is set to ON for all collectors and platforms when
-    // UseNUMA is set to ON. NUMA-aware collectors will interleave old gen and
-    // survivor spaces on top of NUMA allocation policy for the eden space.
-    // Non NUMA-aware collectors will interleave all of the heap spaces across
-    // NUMA nodes.
-    if (FLAG_IS_DEFAULT(UseNUMAInterleaving)) {
-      FLAG_SET_ERGO(UseNUMAInterleaving, true);
-    }
   }
   return JNI_OK;
 }
--- a/src/hotspot/share/runtime/deoptimization.cpp	Fri May 08 09:45:57 2020 +0530
+++ b/src/hotspot/share/runtime/deoptimization.cpp	Fri May 08 09:52:42 2020 +0530
@@ -26,6 +26,7 @@
 
 #include "precompiled.hpp"
 #include "jvm.h"
+#include "classfile/javaClasses.inline.hpp"
 #include "classfile/symbolTable.hpp"
 #include "classfile/systemDictionary.hpp"
 #include "code/codeCache.hpp"
--- a/src/hotspot/share/runtime/flags/jvmFlag.cpp	Fri May 08 09:45:57 2020 +0530
+++ b/src/hotspot/share/runtime/flags/jvmFlag.cpp	Fri May 08 09:52:42 2020 +0530
@@ -426,7 +426,7 @@
     //     double MinRAMPercentage                                   [ 0.000                     ...                   100.000 ]                            {product} {default}
     //      uintx MinSurvivorRatio                                   [ 3                         ...      18446744073709551615 ]                            {product} {default}
     //     size_t MinTLABSize                                        [ 1                         ...       9223372036854775807 ]                            {product} {default}
-    //       intx MonitorBound                                       [ 0                         ...                2147483647 ]                            {product} {default}
+    //       intx MaxInlineSize                                      [ 0                         ...                2147483647 ]                            {product} {default}
     //  |         |                                                  |                                                           |                                    |               |
     //  |         |                                                  |                                                           |                                    |               +-- col7
     //  |         |                                                  |                                                           |                                    +-- col6
--- a/src/hotspot/share/runtime/globals.hpp	Fri May 08 09:45:57 2020 +0530
+++ b/src/hotspot/share/runtime/globals.hpp	Fri May 08 09:52:42 2020 +0530
@@ -691,9 +691,6 @@
           "Use LWP-based instead of libthread-based synchronization "       \
           "(SPARC only)")                                                   \
                                                                             \
-  product(intx, MonitorBound, 0, "(Deprecated) Bound Monitor population")   \
-          range(0, max_jint)                                                \
-                                                                            \
   experimental(intx, MonitorUsedDeflationThreshold, 90,                     \
                 "Percentage of used monitors before triggering cleanup "    \
                 "safepoint which deflates monitors (0 is off). "            \
--- a/src/hotspot/share/runtime/mutexLocker.cpp	Fri May 08 09:45:57 2020 +0530
+++ b/src/hotspot/share/runtime/mutexLocker.cpp	Fri May 08 09:52:42 2020 +0530
@@ -120,6 +120,7 @@
 Monitor* PeriodicTask_lock            = NULL;
 Monitor* RedefineClasses_lock         = NULL;
 Mutex*   Verify_lock                  = NULL;
+Monitor* Zip_lock                     = NULL;
 
 #if INCLUDE_JFR
 Mutex*   JfrStacktrace_lock           = NULL;
@@ -309,6 +310,7 @@
   def(PeriodicTask_lock            , PaddedMonitor, nonleaf+5,   true,  _safepoint_check_always);
   def(RedefineClasses_lock         , PaddedMonitor, nonleaf+5,   true,  _safepoint_check_always);
   def(Verify_lock                  , PaddedMutex,   nonleaf+5,   true,  _safepoint_check_always);
+  def(Zip_lock                     , PaddedMonitor, leaf,        true,  _safepoint_check_never);
 
   if (WhiteBoxAPI) {
     def(Compilation_lock           , PaddedMonitor, leaf,        false, _safepoint_check_never);
--- a/src/hotspot/share/runtime/mutexLocker.hpp	Fri May 08 09:45:57 2020 +0530
+++ b/src/hotspot/share/runtime/mutexLocker.hpp	Fri May 08 09:52:42 2020 +0530
@@ -115,6 +115,7 @@
 extern Monitor* PeriodicTask_lock;               // protects the periodic task structure
 extern Monitor* RedefineClasses_lock;            // locks classes from parallel redefinition
 extern Mutex*   Verify_lock;                     // synchronize initialization of verify library
+extern Monitor* Zip_lock;                        // synchronize initialization of zip library
 extern Monitor* ThreadsSMRDelete_lock;           // Used by ThreadsSMRSupport to take pressure off the Threads_lock
 extern Mutex*   ThreadIdTableCreate_lock;        // Used by ThreadIdTable to lazily create the thread id table
 extern Mutex*   SharedDecoder_lock;              // serializes access to the decoder during normal (not error reporting) use
--- a/src/hotspot/share/runtime/safepoint.cpp	Fri May 08 09:45:57 2020 +0530
+++ b/src/hotspot/share/runtime/safepoint.cpp	Fri May 08 09:52:42 2020 +0530
@@ -499,10 +499,6 @@
   return false;
 }
 
-bool SafepointSynchronize::is_forced_cleanup_needed() {
-  return ObjectSynchronizer::needs_monitor_scavenge();
-}
-
 class ParallelSPCleanupThreadClosure : public ThreadClosure {
 private:
   CodeBlobClosure* _nmethod_cl;
--- a/src/hotspot/share/runtime/safepoint.hpp	Fri May 08 09:45:57 2020 +0530
+++ b/src/hotspot/share/runtime/safepoint.hpp	Fri May 08 09:52:42 2020 +0530
@@ -162,7 +162,6 @@
   static void handle_polling_page_exception(JavaThread *thread);
 
   static bool is_cleanup_needed();
-  static bool is_forced_cleanup_needed();
   static void do_cleanup_tasks();
 
   static void set_is_at_safepoint()             { _state = _synchronized; }
--- a/src/hotspot/share/runtime/synchronizer.cpp	Fri May 08 09:45:57 2020 +0530
+++ b/src/hotspot/share/runtime/synchronizer.cpp	Fri May 08 09:52:42 2020 +0530
@@ -781,7 +781,6 @@
 };
 
 static SharedGlobals GVars;
-static int _forceMonitorScavenge = 0; // Scavenge required and pending
 
 static markWord read_stable_mark(oop obj) {
   markWord mark = obj->mark();
@@ -1170,27 +1169,8 @@
   return false;
 }
 
-// Returns true if MonitorBound is set (> 0) and if the specified
-// cnt is > MonitorBound. Otherwise returns false.
-static bool is_MonitorBound_exceeded(const int cnt) {
-  const int mx = MonitorBound;
-  return mx > 0 && cnt > mx;
-}
-
 bool ObjectSynchronizer::is_cleanup_needed() {
-  if (monitors_used_above_threshold()) {
-    // Too many monitors in use.
-    return true;
-  }
-  return needs_monitor_scavenge();
-}
-
-bool ObjectSynchronizer::needs_monitor_scavenge() {
-  if (Atomic::load(&_forceMonitorScavenge) == 1) {
-    log_info(monitorinflation)("Monitor scavenge needed, triggering safepoint cleanup.");
-    return true;
-  }
-  return false;
+  return monitors_used_above_threshold();
 }
 
 void ObjectSynchronizer::oops_do(OopClosure* f) {
@@ -1237,41 +1217,6 @@
 // --   assigned to an object.  The object is inflated and the mark refers
 //      to the ObjectMonitor.
 
-
-// Constraining monitor pool growth via MonitorBound ...
-//
-// If MonitorBound is not set (<= 0), MonitorBound checks are disabled.
-//
-// The monitor pool is grow-only.  We scavenge at STW safepoint-time, but the
-// the rate of scavenging is driven primarily by GC.  As such,  we can find
-// an inordinate number of monitors in circulation.
-// To avoid that scenario we can artificially induce a STW safepoint
-// if the pool appears to be growing past some reasonable bound.
-// Generally we favor time in space-time tradeoffs, but as there's no
-// natural back-pressure on the # of extant monitors we need to impose some
-// type of limit.  Beware that if MonitorBound is set to too low a value
-// we could just loop. In addition, if MonitorBound is set to a low value
-// we'll incur more safepoints, which are harmful to performance.
-// See also: GuaranteedSafepointInterval
-//
-// If MonitorBound is set, the boundry applies to
-//     (om_list_globals._population - om_list_globals._free_count)
-// i.e., if there are not enough ObjectMonitors on the global free list,
-// then a safepoint deflation is induced. Picking a good MonitorBound value
-// is non-trivial.
-
-static void InduceScavenge(Thread* self, const char * Whence) {
-  // Induce STW safepoint to trim monitors
-  // Ultimately, this results in a call to deflate_idle_monitors() in the near future.
-  // More precisely, trigger a cleanup safepoint as the number
-  // of active monitors passes the specified threshold.
-  // TODO: assert thread state is reasonable
-
-  if (Atomic::xchg(&_forceMonitorScavenge, 1) == 0) {
-    VMThread::check_for_forced_cleanup();
-  }
-}
-
 ObjectMonitor* ObjectSynchronizer::om_alloc(Thread* self) {
   // A large MAXPRIVATE value reduces both list lock contention
   // and list coherency traffic, but also tends to increase the
@@ -1315,15 +1260,6 @@
       }
       self->om_free_provision += 1 + (self->om_free_provision / 2);
       if (self->om_free_provision > MAXPRIVATE) self->om_free_provision = MAXPRIVATE;
-
-      if (is_MonitorBound_exceeded(Atomic::load(&om_list_globals._population) -
-                                   Atomic::load(&om_list_globals._free_count))) {
-        // Not enough ObjectMonitors on the global free list.
-        // We can't safely induce a STW safepoint from om_alloc() as our thread
-        // state may not be appropriate for such activities and callers may hold
-        // naked oops, so instead we defer the action.
-        InduceScavenge(self, "om_alloc");
-      }
       continue;
     }
 
@@ -2025,8 +1961,6 @@
                                Atomic::load(&om_list_globals._free_count));
   }
 
-  Atomic::store(&_forceMonitorScavenge, 0);    // Reset
-
   OM_PERFDATA_OP(Deflations, inc(counters->n_scavenged));
   OM_PERFDATA_OP(MonExtant, set_value(counters->n_in_circulation));
 
--- a/src/hotspot/share/runtime/synchronizer.hpp	Fri May 08 09:45:57 2020 +0530
+++ b/src/hotspot/share/runtime/synchronizer.hpp	Fri May 08 09:52:42 2020 +0530
@@ -145,7 +145,6 @@
                               ObjectMonitor** free_head_p,
                               ObjectMonitor** free_tail_p);
   static bool is_cleanup_needed();
-  static bool needs_monitor_scavenge();
   static void oops_do(OopClosure* f);
   // Process oops in thread local used monitors
   static void thread_local_used_oops_do(Thread* thread, OopClosure* f);
--- a/src/hotspot/share/runtime/vframe.cpp	Fri May 08 09:45:57 2020 +0530
+++ b/src/hotspot/share/runtime/vframe.cpp	Fri May 08 09:52:42 2020 +0530
@@ -23,7 +23,7 @@
  */
 
 #include "precompiled.hpp"
-#include "classfile/javaClasses.hpp"
+#include "classfile/javaClasses.inline.hpp"
 #include "classfile/systemDictionary.hpp"
 #include "classfile/vmSymbols.hpp"
 #include "code/codeCache.hpp"
--- a/src/hotspot/share/runtime/vmThread.cpp	Fri May 08 09:45:57 2020 +0530
+++ b/src/hotspot/share/runtime/vmThread.cpp	Fri May 08 09:52:42 2020 +0530
@@ -400,11 +400,6 @@
   }
 };
 
-void VMThread::check_for_forced_cleanup() {
-  MonitorLocker mq(VMOperationQueue_lock,  Mutex::_no_safepoint_check_flag);
-  mq.notify();
-}
-
 VM_Operation* VMThread::no_op_safepoint() {
   // Check for handshakes first since we may need to return a VMop.
   if (HandshakeALot) {
@@ -415,8 +410,7 @@
   long interval_ms = SafepointTracing::time_since_last_safepoint_ms();
   bool max_time_exceeded = GuaranteedSafepointInterval != 0 &&
                            (interval_ms >= GuaranteedSafepointInterval);
-  if ((max_time_exceeded && SafepointSynchronize::is_cleanup_needed()) ||
-      SafepointSynchronize::is_forced_cleanup_needed()) {
+  if (max_time_exceeded && SafepointSynchronize::is_cleanup_needed()) {
     return &cleanup_op;
   }
   if (SafepointALot) {
--- a/src/hotspot/share/runtime/vmThread.hpp	Fri May 08 09:45:57 2020 +0530
+++ b/src/hotspot/share/runtime/vmThread.hpp	Fri May 08 09:52:42 2020 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2020, 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,7 +136,6 @@
 
   // The ever running loop for the VMThread
   void loop();
-  static void check_for_forced_cleanup();
 
   // Called to stop the VM thread
   static void wait_for_vm_thread_exit();
--- a/src/hotspot/share/utilities/macros.hpp	Fri May 08 09:45:57 2020 +0530
+++ b/src/hotspot/share/utilities/macros.hpp	Fri May 08 09:52:42 2020 +0530
@@ -404,6 +404,14 @@
 #define NOT_LINUX(code) code
 #endif
 
+#ifdef __APPLE__
+#define MACOS_ONLY(code) code
+#define NOT_MACOS(code)
+#else
+#define MACOS_ONLY(code)
+#define NOT_MACOS(code) code
+#endif
+
 #ifdef AIX
 #define AIX_ONLY(code) code
 #define NOT_AIX(code)
--- a/src/java.base/share/classes/java/lang/Boolean.java	Fri May 08 09:45:57 2020 +0530
+++ b/src/java.base/share/classes/java/lang/Boolean.java	Fri May 08 09:52:42 2020 +0530
@@ -27,6 +27,15 @@
 
 import jdk.internal.HotSpotIntrinsicCandidate;
 
+import java.lang.constant.Constable;
+import java.lang.constant.ConstantDesc;
+import java.lang.constant.ConstantDescs;
+import java.lang.constant.DynamicConstantDesc;
+import java.util.Optional;
+
+import static java.lang.constant.ConstantDescs.BSM_GET_STATIC_FINAL;
+import static java.lang.constant.ConstantDescs.CD_Boolean;
+
 /**
  * The Boolean class wraps a value of the primitive type
  * {@code boolean} in an object. An object of type
@@ -43,7 +52,7 @@
  * @since   1.0
  */
 public final class Boolean implements java.io.Serializable,
-                                      Comparable<Boolean>
+                                      Comparable<Boolean>, Constable
 {
     /**
      * The {@code Boolean} object corresponding to the primitive
@@ -344,4 +353,16 @@
     public static boolean logicalXor(boolean a, boolean b) {
         return a ^ b;
     }
+
+    /**
+     * Returns an {@link Optional} containing the nominal descriptor for this
+     * instance.
+     *
+     * @return an {@link Optional} describing the {@linkplain Boolean} instance
+     * @since 15
+     */
+    @Override
+    public Optional<DynamicConstantDesc<Boolean>> describeConstable() {
+        return Optional.of(value ? ConstantDescs.TRUE : ConstantDescs.FALSE);
+    }
 }
--- a/src/java.base/share/classes/java/lang/Byte.java	Fri May 08 09:45:57 2020 +0530
+++ b/src/java.base/share/classes/java/lang/Byte.java	Fri May 08 09:52:42 2020 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2020, 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,15 @@
 import jdk.internal.HotSpotIntrinsicCandidate;
 import jdk.internal.misc.VM;
 
+import java.lang.constant.Constable;
+import java.lang.constant.DynamicConstantDesc;
+import java.util.Optional;
+
+import static java.lang.constant.ConstantDescs.BSM_EXPLICIT_CAST;
+import static java.lang.constant.ConstantDescs.CD_byte;
+import static java.lang.constant.ConstantDescs.CD_int;
+import static java.lang.constant.ConstantDescs.DEFAULT_NAME;
+
 /**
  *
  * The {@code Byte} class wraps a value of primitive type {@code byte}
@@ -44,7 +53,7 @@
  * @see     java.lang.Number
  * @since   1.1
  */
-public final class Byte extends Number implements Comparable<Byte> {
+public final class Byte extends Number implements Comparable<Byte>, Constable {
 
     /**
      * A constant holding the minimum value a {@code byte} can
@@ -77,6 +86,18 @@
         return Integer.toString((int)b, 10);
     }
 
+    /**
+     * Returns an {@link Optional} containing the nominal descriptor for this
+     * instance.
+     *
+     * @return an {@link Optional} describing the {@linkplain Byte} instance
+     * @since 15
+     */
+    @Override
+    public Optional<DynamicConstantDesc<Byte>> describeConstable() {
+        return Optional.of(DynamicConstantDesc.ofNamed(BSM_EXPLICIT_CAST, DEFAULT_NAME, CD_byte, intValue()));
+    }
+
     private static class ByteCache {
         private ByteCache() {}
 
--- a/src/java.base/share/classes/java/lang/Character.java	Fri May 08 09:45:57 2020 +0530
+++ b/src/java.base/share/classes/java/lang/Character.java	Fri May 08 09:52:42 2020 +0530
@@ -25,13 +25,21 @@
 
 package java.lang;
 
+import jdk.internal.HotSpotIntrinsicCandidate;
+import jdk.internal.misc.VM;
+
+import java.lang.constant.Constable;
+import java.lang.constant.DynamicConstantDesc;
 import java.util.Arrays;
-import java.util.Map;
 import java.util.HashMap;
 import java.util.Locale;
-
-import jdk.internal.HotSpotIntrinsicCandidate;
-import jdk.internal.misc.VM;
+import java.util.Map;
+import java.util.Optional;
+
+import static java.lang.constant.ConstantDescs.BSM_EXPLICIT_CAST;
+import static java.lang.constant.ConstantDescs.CD_char;
+import static java.lang.constant.ConstantDescs.CD_int;
+import static java.lang.constant.ConstantDescs.DEFAULT_NAME;
 
 /**
  * The {@code Character} class wraps a value of the primitive
@@ -122,7 +130,7 @@
  * @since   1.0
  */
 public final
-class Character implements java.io.Serializable, Comparable<Character> {
+class Character implements java.io.Serializable, Comparable<Character>, Constable {
     /**
      * The minimum radix available for conversion to and from strings.
      * The constant value of this field is the smallest value permitted
@@ -602,6 +610,17 @@
      */
     public static final int MAX_CODE_POINT = 0X10FFFF;
 
+    /**
+     * Returns an {@link Optional} containing the nominal descriptor for this
+     * instance.
+     *
+     * @return an {@link Optional} describing the {@linkplain Character} instance
+     * @since 15
+     */
+    @Override
+    public Optional<DynamicConstantDesc<Character>> describeConstable() {
+        return Optional.of(DynamicConstantDesc.ofNamed(BSM_EXPLICIT_CAST, DEFAULT_NAME, CD_char, (int) value));
+    }
 
     /**
      * Instances of this class represent particular subsets of the Unicode
--- a/src/java.base/share/classes/java/lang/ModuleLayer.java	Fri May 08 09:45:57 2020 +0530
+++ b/src/java.base/share/classes/java/lang/ModuleLayer.java	Fri May 08 09:52:42 2020 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2020, 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
@@ -489,7 +489,7 @@
                                                         List<ModuleLayer> parentLayers,
                                                         ClassLoader parentLoader)
     {
-        List<ModuleLayer> parents = new ArrayList<>(parentLayers);
+        List<ModuleLayer> parents = List.copyOf(parentLayers);
         checkConfiguration(cf, parents);
 
         checkCreateClassLoaderPermission();
@@ -565,7 +565,7 @@
                                                           List<ModuleLayer> parentLayers,
                                                           ClassLoader parentLoader)
     {
-        List<ModuleLayer> parents = new ArrayList<>(parentLayers);
+        List<ModuleLayer> parents = List.copyOf(parentLayers);
         checkConfiguration(cf, parents);
 
         checkCreateClassLoaderPermission();
@@ -649,7 +649,7 @@
                                            List<ModuleLayer> parentLayers,
                                            Function<String, ClassLoader> clf)
     {
-        List<ModuleLayer> parents = new ArrayList<>(parentLayers);
+        List<ModuleLayer> parents = List.copyOf(parentLayers);
         checkConfiguration(cf, parents);
         Objects.requireNonNull(clf);
 
@@ -752,13 +752,12 @@
         return cf;
     }
 
-
     /**
-     * Returns the list of this layer's parents unless this is the
-     * {@linkplain #empty empty layer}, which has no parents and so an
+     * Returns an unmodifiable list of this layer's parents, in search
+     * order. If this is the {@linkplain #empty() empty layer} then an
      * empty list is returned.
      *
-     * @return The list of this layer's parents
+     * @return A possibly-empty unmodifiable list of this layer's parents
      */
     public List<ModuleLayer> parents() {
         return parents;
@@ -803,7 +802,7 @@
     private volatile List<ModuleLayer> allLayers;
 
     /**
-     * Returns the set of the modules in this layer.
+     * Returns an unmodifiable set of the modules in this layer.
      *
      * @return A possibly-empty unmodifiable set of the modules in this layer
      */
--- a/src/java.base/share/classes/java/lang/Short.java	Fri May 08 09:45:57 2020 +0530
+++ b/src/java.base/share/classes/java/lang/Short.java	Fri May 08 09:52:42 2020 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2020, 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,15 @@
 import jdk.internal.HotSpotIntrinsicCandidate;
 import jdk.internal.misc.VM;
 
+import java.lang.constant.Constable;
+import java.lang.constant.DynamicConstantDesc;
+import java.util.Optional;
+
+import static java.lang.constant.ConstantDescs.BSM_EXPLICIT_CAST;
+import static java.lang.constant.ConstantDescs.CD_int;
+import static java.lang.constant.ConstantDescs.CD_short;
+import static java.lang.constant.ConstantDescs.DEFAULT_NAME;
+
 /**
  * The {@code Short} class wraps a value of primitive type {@code
  * short} in an object.  An object of type {@code Short} contains a
@@ -43,7 +52,7 @@
  * @see     java.lang.Number
  * @since   1.1
  */
-public final class Short extends Number implements Comparable<Short> {
+public final class Short extends Number implements Comparable<Short>, Constable {
 
     /**
      * A constant holding the minimum value a {@code short} can
@@ -203,6 +212,18 @@
         return valueOf(s, 10);
     }
 
+    /**
+     * Returns an {@link Optional} containing the nominal descriptor for this
+     * instance.
+     *
+     * @return an {@link Optional} describing the {@linkplain Short} instance
+     * @since 15
+     */
+    @Override
+    public Optional<DynamicConstantDesc<Short>> describeConstable() {
+        return Optional.of(DynamicConstantDesc.ofNamed(BSM_EXPLICIT_CAST, DEFAULT_NAME, CD_short, intValue()));
+    }
+
     private static class ShortCache {
         private ShortCache() {}
 
--- a/src/java.base/share/classes/java/lang/constant/ConstantDescs.java	Fri May 08 09:45:57 2020 +0530
+++ b/src/java.base/share/classes/java/lang/constant/ConstantDescs.java	Fri May 08 09:52:42 2020 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018, 2020, 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
@@ -194,10 +194,18 @@
             = ofConstantBootstrap(CD_ConstantBootstraps, "enumConstant",
             CD_Enum);
 
+    /**
+     * {@link MethodHandleDesc} representing {@link ConstantBootstraps#getStaticFinal(Lookup, String, Class, Class) ConstantBootstraps.getStaticFinal}
+     * @since 15
+     */
+    public static final DirectMethodHandleDesc BSM_GET_STATIC_FINAL
+            = ofConstantBootstrap(CD_ConstantBootstraps, "getStaticFinal",
+            CD_Object, CD_Class);
+
     /** {@link MethodHandleDesc} representing {@link ConstantBootstraps#nullConstant(Lookup, String, Class) ConstantBootstraps.nullConstant} */
     public static final DirectMethodHandleDesc BSM_NULL_CONSTANT
             = ofConstantBootstrap(CD_ConstantBootstraps, "nullConstant",
-                                  ConstantDescs.CD_Object);
+            CD_Object);
 
     /** {@link MethodHandleDesc} representing {@link ConstantBootstraps#fieldVarHandle(Lookup, String, Class, Class, Class) ConstantBootstraps.fieldVarHandle} */
     public static final DirectMethodHandleDesc BSM_VARHANDLE_FIELD
@@ -219,6 +227,14 @@
             = ofConstantBootstrap(CD_ConstantBootstraps, "invoke",
             CD_Object, CD_MethodHandle, CD_Object.arrayType());
 
+    /**
+     * {@link MethodHandleDesc} representing {@link ConstantBootstraps#explicitCast(Lookup, String, Class, Object)} ConstantBootstraps.explicitCast}
+     * @since 15
+     */
+    public static final DirectMethodHandleDesc BSM_EXPLICIT_CAST
+            = ofConstantBootstrap(CD_ConstantBootstraps, "explicitCast",
+            CD_Object, CD_Object);
+
     /** {@link ClassDesc} representing the primitive type {@code int} */
     public static final ClassDesc CD_int = ClassDesc.ofDescriptor("I");
 
@@ -251,6 +267,22 @@
             = DynamicConstantDesc.ofNamed(ConstantDescs.BSM_NULL_CONSTANT,
                                           DEFAULT_NAME, ConstantDescs.CD_Object);
 
+    /**
+     * Nominal descriptor representing the constant {@linkplain Boolean#TRUE}
+     * @since 15
+     */
+    public static final DynamicConstantDesc<Boolean> TRUE
+            = DynamicConstantDesc.ofNamed(BSM_GET_STATIC_FINAL,
+                                          "TRUE", CD_Boolean, CD_Boolean);
+
+    /**
+     * Nominal descriptor representing the constant {@linkplain Boolean#TRUE}
+     * @since 15
+     */
+    public static final DynamicConstantDesc<Boolean> FALSE
+            = DynamicConstantDesc.ofNamed(BSM_GET_STATIC_FINAL,
+                                          "FALSE", CD_Boolean, CD_Boolean);
+
     static final DirectMethodHandleDesc MHD_METHODHANDLE_ASTYPE
             = MethodHandleDesc.ofMethod(Kind.VIRTUAL, CD_MethodHandle, "asType",
                                         MethodTypeDesc.of(CD_MethodHandle, CD_MethodType));
--- a/src/java.base/share/classes/java/lang/invoke/ConstantBootstraps.java	Fri May 08 09:45:57 2020 +0530
+++ b/src/java.base/share/classes/java/lang/invoke/ConstantBootstraps.java	Fri May 08 09:52:42 2020 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2020, 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
@@ -355,6 +355,71 @@
         return MethodHandles.arrayElementVarHandle(validateClassAccess(lookup, arrayClass));
     }
 
+    /**
+     * Applies a conversion from a source type to a destination type.
+     * <p>
+     * Given a destination type {@code dstType} and an input
+     * value {@code value}, one of the following will happen:
+     * <ul>
+     * <li>If {@code dstType} is {@code void.class},
+     *     a {@link ClassCastException} is thrown.
+     * <li>If {@code dstType} is {@code Object.class}, {@code value} is returned as is.
+     * </ul>
+     * <p>
+     * Otherwise one of the following conversions is applied to {@code value}:
+     * <ol>
+     * <li>If {@code dstType} is a reference type, a reference cast
+     *     is applied to {@code value} as if by calling {@code dstType.cast(value)}.
+     * <li>If {@code dstType} is a primitive type, then, if the runtime type
+     *     of {@code value} is a primitive wrapper type (such as {@link Integer}),
+     *     a Java unboxing conversion is applied {@jls 5.1.8} followed by a
+     *     Java casting conversion {@jls 5.5} converting either directly to
+     *     {@code dstType}, or, if {@code dstType} is {@code boolean},
+     *     to {@code int}, which is then converted to either {@code true}
+     *     or {@code false} depending on whether the least-significant-bit
+     *     is 1 or 0 respectively. If the runtime type of {@code value} is
+     *     not a primitive wrapper type a {@link ClassCastException} is thrown.
+     * </ol>
+     * <p>
+     * The result is the same as when using the following code:
+     * <blockquote><pre>{@code
+     * MethodHandle id = MethodHandles.identity(dstType);
+     * MethodType mt = MethodType.methodType(dstType, Object.class);
+     * MethodHandle conv = MethodHandles.explicitCastArguments(id, mt);
+     * return conv.invoke(value);
+     * }</pre></blockquote>
+     *
+     * @param lookup unused
+     * @param name unused
+     * @param dstType the destination type of the conversion
+     * @param value the value to be converted
+     * @return the converted value
+     * @throws ClassCastException when {@code dstType} is {@code void},
+     *         when a cast per (1) fails, or when {@code dstType} is a primitive type
+     *         and the runtime type of {@code value} is not a primitive wrapper type
+     *         (such as {@link Integer})
+     *
+     * @since 15
+     */
+    public static Object explicitCast(MethodHandles.Lookup lookup, String name, Class<?> dstType, Object value)
+            throws ClassCastException {
+        if (dstType == void.class)
+            throw new ClassCastException("Can not convert to void");
+        if (dstType == Object.class)
+            return value;
+
+        MethodHandle id = MethodHandles.identity(dstType);
+        MethodType mt = MethodType.methodType(dstType, Object.class);
+        MethodHandle conv = MethodHandles.explicitCastArguments(id, mt);
+        try {
+            return conv.invoke(value);
+        } catch (ClassCastException e) {
+            throw e; // specified, let CCE through
+        } catch (Throwable throwable) {
+            throw new InternalError(throwable); // Not specified, throw InternalError
+        }
+    }
+
     private static <T> Class<T> validateClassAccess(MethodHandles.Lookup lookup, Class<T> type) {
         try {
             lookup.accessClass(type);
--- a/src/java.base/share/classes/java/lang/invoke/DelegatingMethodHandle.java	Fri May 08 09:45:57 2020 +0530
+++ b/src/java.base/share/classes/java/lang/invoke/DelegatingMethodHandle.java	Fri May 08 09:52:42 2020 +0530
@@ -62,6 +62,20 @@
     }
 
     @Override
+    boolean isCrackable() {
+        MemberName member = internalMemberName();
+        return member != null &&
+                (member.isResolved() ||
+                 member.isMethodHandleInvoke() ||
+                 member.isVarHandleMethodInvoke());
+    }
+
+    @Override
+    MethodHandle viewAsType(MethodType newType, boolean strict) {
+        return getTarget().viewAsType(newType, strict);
+    }
+
+    @Override
     boolean isInvokeSpecial() {
         return getTarget().isInvokeSpecial();
     }
--- a/src/java.base/share/classes/java/lang/invoke/DirectMethodHandle.java	Fri May 08 09:45:57 2020 +0530
+++ b/src/java.base/share/classes/java/lang/invoke/DirectMethodHandle.java	Fri May 08 09:52:42 2020 +0530
@@ -51,9 +51,10 @@
  */
 class DirectMethodHandle extends MethodHandle {
     final MemberName member;
+    final boolean crackable;
 
     // Constructors and factory methods in this class *must* be package scoped or private.
-    private DirectMethodHandle(MethodType mtype, LambdaForm form, MemberName member) {
+    private DirectMethodHandle(MethodType mtype, LambdaForm form, MemberName member, boolean crackable) {
         super(mtype, form);
         if (!member.isResolved())  throw new InternalError();
 
@@ -70,6 +71,7 @@
         }
 
         this.member = member;
+        this.crackable = crackable;
     }
 
     // Factory methods:
@@ -92,18 +94,18 @@
                         throw new InternalError("callerClass must not be null for REF_invokeSpecial");
                     }
                     LambdaForm lform = preparedLambdaForm(member, callerClass.isInterface());
-                    return new Special(mtype, lform, member, callerClass);
+                    return new Special(mtype, lform, member, true, callerClass);
                 }
                 case REF_invokeInterface: {
                     // for interfaces we always need the receiver typecheck,
                     // so we always pass 'true' to ensure we adapt if needed
                     // to include the REF_invokeSpecial case
                     LambdaForm lform = preparedLambdaForm(member, true);
-                    return new Interface(mtype, lform, member, refc);
+                    return new Interface(mtype, lform, member, true, refc);
                 }
                 default: {
                     LambdaForm lform = preparedLambdaForm(member);
-                    return new DirectMethodHandle(mtype, lform, member);
+                    return new DirectMethodHandle(mtype, lform, member, true);
                 }
             }
         } else {
@@ -111,11 +113,11 @@
             if (member.isStatic()) {
                 long offset = MethodHandleNatives.staticFieldOffset(member);
                 Object base = MethodHandleNatives.staticFieldBase(member);
-                return new StaticAccessor(mtype, lform, member, base, offset);
+                return new StaticAccessor(mtype, lform, member, true, base, offset);
             } else {
                 long offset = MethodHandleNatives.objectFieldOffset(member);
                 assert(offset == (int)offset);
-                return new Accessor(mtype, lform, member, (int)offset);
+                return new Accessor(mtype, lform, member, true, (int)offset);
             }
         }
     }
@@ -139,7 +141,7 @@
         LambdaForm lform = preparedLambdaForm(ctor);
         MemberName init = ctor.asSpecial();
         assert(init.getMethodType().returnType() == void.class);
-        return new Constructor(mtype, lform, ctor, init, instanceClass);
+        return new Constructor(mtype, lform, ctor, true, init, instanceClass);
     }
 
     @Override
@@ -150,7 +152,22 @@
     @Override
     MethodHandle copyWith(MethodType mt, LambdaForm lf) {
         assert(this.getClass() == DirectMethodHandle.class);  // must override in subclasses
-        return new DirectMethodHandle(mt, lf, member);
+        return new DirectMethodHandle(mt, lf, member, crackable);
+    }
+
+    @Override
+    MethodHandle viewAsType(MethodType newType, boolean strict) {
+        // No actual conversions, just a new view of the same method.
+        // However, we must not expose a DMH that is crackable into a
+        // MethodHandleInfo, so we return a cloned, uncrackable DMH
+        assert(viewAsTypeChecks(newType, strict));
+        assert(this.getClass() == DirectMethodHandle.class);  // must override in subclasses
+        return new DirectMethodHandle(newType, form, member, false);
+    }
+
+    @Override
+    boolean isCrackable() {
+        return crackable;
     }
 
     @Override
@@ -406,8 +423,8 @@
     /** This subclass represents invokespecial instructions. */
     static class Special extends DirectMethodHandle {
         private final Class<?> caller;
-        private Special(MethodType mtype, LambdaForm form, MemberName member, Class<?> caller) {
-            super(mtype, form, member);
+        private Special(MethodType mtype, LambdaForm form, MemberName member, boolean crackable, Class<?> caller) {
+            super(mtype, form, member, crackable);
             this.caller = caller;
         }
         @Override
@@ -416,7 +433,12 @@
         }
         @Override
         MethodHandle copyWith(MethodType mt, LambdaForm lf) {
-            return new Special(mt, lf, member, caller);
+            return new Special(mt, lf, member, crackable, caller);
+        }
+        @Override
+        MethodHandle viewAsType(MethodType newType, boolean strict) {
+            assert(viewAsTypeChecks(newType, strict));
+            return new Special(newType, form, member, false, caller);
         }
         Object checkReceiver(Object recv) {
             if (!caller.isInstance(recv)) {
@@ -431,14 +453,19 @@
     /** This subclass represents invokeinterface instructions. */
     static class Interface extends DirectMethodHandle {
         private final Class<?> refc;
-        private Interface(MethodType mtype, LambdaForm form, MemberName member, Class<?> refc) {
-            super(mtype, form, member);
-            assert refc.isInterface() : refc;
+        private Interface(MethodType mtype, LambdaForm form, MemberName member, boolean crackable, Class<?> refc) {
+            super(mtype, form, member, crackable);
+            assert(refc.isInterface()) : refc;
             this.refc = refc;
         }
         @Override
         MethodHandle copyWith(MethodType mt, LambdaForm lf) {
-            return new Interface(mt, lf, member, refc);
+            return new Interface(mt, lf, member, crackable, refc);
+        }
+        @Override
+        MethodHandle viewAsType(MethodType newType, boolean strict) {
+            assert(viewAsTypeChecks(newType, strict));
+            return new Interface(newType, form, member, false, refc);
         }
         @Override
         Object checkReceiver(Object recv) {
@@ -456,22 +483,26 @@
         throw new InternalError("Should only be invoked on a subclass");
     }
 
-
     /** This subclass handles constructor references. */
     static class Constructor extends DirectMethodHandle {
         final MemberName initMethod;
         final Class<?>   instanceClass;
 
         private Constructor(MethodType mtype, LambdaForm form, MemberName constructor,
-                            MemberName initMethod, Class<?> instanceClass) {
-            super(mtype, form, constructor);
+                            boolean crackable, MemberName initMethod, Class<?> instanceClass) {
+            super(mtype, form, constructor, crackable);
             this.initMethod = initMethod;
             this.instanceClass = instanceClass;
             assert(initMethod.isResolved());
         }
         @Override
         MethodHandle copyWith(MethodType mt, LambdaForm lf) {
-            return new Constructor(mt, lf, member, initMethod, instanceClass);
+            return new Constructor(mt, lf, member, crackable, initMethod, instanceClass);
+        }
+        @Override
+        MethodHandle viewAsType(MethodType newType, boolean strict) {
+            assert(viewAsTypeChecks(newType, strict));
+            return new Constructor(newType, form, member, false, initMethod, instanceClass);
         }
     }
 
@@ -492,8 +523,8 @@
         final Class<?> fieldType;
         final int      fieldOffset;
         private Accessor(MethodType mtype, LambdaForm form, MemberName member,
-                         int fieldOffset) {
-            super(mtype, form, member);
+                         boolean crackable, int fieldOffset) {
+            super(mtype, form, member, crackable);
             this.fieldType   = member.getFieldType();
             this.fieldOffset = fieldOffset;
         }
@@ -503,7 +534,12 @@
         }
         @Override
         MethodHandle copyWith(MethodType mt, LambdaForm lf) {
-            return new Accessor(mt, lf, member, fieldOffset);
+            return new Accessor(mt, lf, member, crackable, fieldOffset);
+        }
+        @Override
+        MethodHandle viewAsType(MethodType newType, boolean strict) {
+            assert(viewAsTypeChecks(newType, strict));
+            return new Accessor(newType, form, member, false, fieldOffset);
         }
     }
 
@@ -535,8 +571,8 @@
         private final long     staticOffset;
 
         private StaticAccessor(MethodType mtype, LambdaForm form, MemberName member,
-                               Object staticBase, long staticOffset) {
-            super(mtype, form, member);
+                               boolean crackable, Object staticBase, long staticOffset) {
+            super(mtype, form, member, crackable);
             this.fieldType    = member.getFieldType();
             this.staticBase   = staticBase;
             this.staticOffset = staticOffset;
@@ -547,7 +583,12 @@
         }
         @Override
         MethodHandle copyWith(MethodType mt, LambdaForm lf) {
-            return new StaticAccessor(mt, lf, member, staticBase, staticOffset);
+            return new StaticAccessor(mt, lf, member, crackable, staticBase, staticOffset);
+        }
+        @Override
+        MethodHandle viewAsType(MethodType newType, boolean strict) {
+            assert(viewAsTypeChecks(newType, strict));
+            return new StaticAccessor(newType, form, member, false, staticBase, staticOffset);
         }
     }
 
--- a/src/java.base/share/classes/java/lang/invoke/MethodHandle.java	Fri May 08 09:45:57 2020 +0530
+++ b/src/java.base/share/classes/java/lang/invoke/MethodHandle.java	Fri May 08 09:52:42 2020 +0530
@@ -1640,12 +1640,9 @@
     /*non-public*/
     MethodHandle viewAsType(MethodType newType, boolean strict) {
         // No actual conversions, just a new view of the same method.
-        // Note that this operation must not produce a DirectMethodHandle,
-        // because retyped DMHs, like any transformed MHs,
-        // cannot be cracked into MethodHandleInfo.
-        assert viewAsTypeChecks(newType, strict);
-        BoundMethodHandle mh = rebind();
-        return mh.copyWith(newType, mh.form);
+        // Overridden in DMH, which has special rules
+        assert(viewAsTypeChecks(newType, strict));
+        return copyWith(newType, form);
     }
 
     /*non-public*/
@@ -1693,7 +1690,7 @@
         } else {
             // The following case is rare. Mask the internalMemberName by wrapping the MH in a BMH.
             MethodHandle result = rebind();
-            assert (result.internalMemberName() == null);
+            assert(result.internalMemberName() == null);
             return result;
         }
     }
@@ -1704,6 +1701,11 @@
     }
 
     /*non-public*/
+    boolean isCrackable() {
+        return false;
+    }
+
+    /*non-public*/
     Object internalValues() {
         return null;
     }
--- a/src/java.base/share/classes/java/lang/invoke/MethodHandles.java	Fri May 08 09:45:57 2020 +0530
+++ b/src/java.base/share/classes/java/lang/invoke/MethodHandles.java	Fri May 08 09:52:42 2020 +0530
@@ -3282,11 +3282,10 @@
          * @since 1.8
          */
         public MethodHandleInfo revealDirect(MethodHandle target) {
+            if (!target.isCrackable()) {
+                throw newIllegalArgumentException("not a direct method handle");
+            }
             MemberName member = target.internalMemberName();
-            if (member == null || (!member.isResolved() &&
-                                   !member.isMethodHandleInvoke() &&
-                                   !member.isVarHandleMethodInvoke()))
-                throw newIllegalArgumentException("not a direct method handle");
             Class<?> defc = member.getDeclaringClass();
             byte refKind = member.getReferenceKind();
             assert(MethodHandleNatives.refKindIsValid(refKind));
--- a/src/java.base/share/classes/java/lang/module/Configuration.java	Fri May 08 09:45:57 2020 +0530
+++ b/src/java.base/share/classes/java/lang/module/Configuration.java	Fri May 08 09:52:42 2020 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2020, 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
@@ -509,7 +509,7 @@
 
     /**
      * Returns an unmodifiable list of this configuration's parents, in search
-     * order. If this is the {@linkplain #empty empty configuration} then an
+     * order. If this is the {@linkplain #empty() empty configuration} then an
      * empty list is returned.
      *
      * @return A possibly-empty unmodifiable list of this parent configurations
@@ -520,7 +520,7 @@
 
 
     /**
-     * Returns an immutable set of the resolved modules in this configuration.
+     * Returns an unmodifiable set of the resolved modules in this configuration.
      *
      * @return A possibly-empty unmodifiable set of the resolved modules
      *         in this configuration
--- a/src/java.base/share/classes/java/time/format/DateTimeFormatter.java	Fri May 08 09:45:57 2020 +0530
+++ b/src/java.base/share/classes/java/time/format/DateTimeFormatter.java	Fri May 08 09:52:42 2020 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2020, 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
@@ -1499,18 +1499,20 @@
             return this;
         }
 
-        // Check for decimalStyle/chronology/timezone in locale object
-        Chronology c = locale.getUnicodeLocaleType("ca") != null ?
-                       Chronology.ofLocale(locale) : chrono;
-        DecimalStyle ds = locale.getUnicodeLocaleType("nu") != null ?
-                       DecimalStyle.of(locale) : decimalStyle;
+        // Override decimalStyle/chronology/timezone for the locale object
         String tzType = locale.getUnicodeLocaleType("tz");
-        ZoneId z  = tzType != null ?
+        ZoneId z = tzType != null ?
                     TimeZoneNameUtility.convertLDMLShortID(tzType)
                         .map(ZoneId::of)
                         .orElse(zone) :
                     zone;
-        return new DateTimeFormatter(printerParser, locale, ds, resolverStyle, resolverFields, c, z);
+        return new DateTimeFormatter(printerParser,
+                locale,
+                DecimalStyle.of(locale),
+                resolverStyle,
+                resolverFields,
+                Chronology.ofLocale(locale),
+                z);
     }
 
     //-----------------------------------------------------------------------
--- a/src/java.base/share/classes/java/util/ImmutableCollections.java	Fri May 08 09:45:57 2020 +0530
+++ b/src/java.base/share/classes/java/util/ImmutableCollections.java	Fri May 08 09:52:42 2020 +0530
@@ -64,14 +64,22 @@
     private static final boolean REVERSE;
     static {
         // to generate a reasonably random and well-mixed SALT, use an arbitrary
-        // value (a slice of pi), multiply with the System.nanoTime, then pick
+        // value (a slice of pi), multiply with a random seed, then pick
         // the mid 32-bits from the product. By picking a SALT value in the
         // [0 ... 0xFFFF_FFFFL == 2^32-1] range, we ensure that for any positive
         // int N, (SALT32L * N) >> 32 is a number in the [0 ... N-1] range. This
         // property will be used to avoid more expensive modulo-based
         // calculations.
         long color = 0x243F_6A88_85A3_08D3L; // slice of pi
-        long seed = System.nanoTime();
+
+        // When running with -Xshare:dump, the VM will supply a "random" seed that's
+        // derived from the JVM build/version, so can we generate the exact same
+        // CDS archive for the same JDK build. This makes it possible to verify the
+        // consistency of the JDK build.
+        long seed = VM.getRandomSeedForCDSDump();
+        if (seed == 0) {
+          seed = System.nanoTime();
+        }
         SALT32L = (int)((color * seed) >> 16) & 0xFFFF_FFFFL;
         // use the lowest bit to determine if we should reverse iteration
         REVERSE = (SALT32L & 1) == 0;
--- a/src/java.base/share/classes/java/util/Objects.java	Fri May 08 09:45:57 2020 +0530
+++ b/src/java.base/share/classes/java/util/Objects.java	Fri May 08 09:52:42 2020 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2020, 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,20 +37,6 @@
  * hash code of an object, returning a string for an object, comparing two
  * objects, and checking if indexes or sub-range values are out of bounds.
  *
- * @apiNote
- * Static methods such as {@link Objects#checkIndex},
- * {@link Objects#checkFromToIndex}, and {@link Objects#checkFromIndexSize} are
- * provided for the convenience of checking if values corresponding to indexes
- * and sub-ranges are out of bounds.
- * Variations of these static methods support customization of the runtime
- * exception, and corresponding exception detail message, that is thrown when
- * values are out of bounds.  Such methods accept a functional interface
- * argument, instances of {@code BiFunction}, that maps out-of-bound values to a
- * runtime exception.  Care should be taken when using such methods in
- * combination with an argument that is a lambda expression, method reference or
- * class that capture values.  In such cases the cost of capture, related to
- * functional interface allocation, may exceed the cost of checking bounds.
- *
  * @since 1.7
  */
 public final class Objects {
--- a/src/java.base/share/classes/jdk/internal/misc/VM.java	Fri May 08 09:45:57 2020 +0530
+++ b/src/java.base/share/classes/jdk/internal/misc/VM.java	Fri May 08 09:52:42 2020 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2020, 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
@@ -421,6 +421,8 @@
      */
     public static native void initializeFromArchive(Class<?> c);
 
+    public static native long getRandomSeedForCDSDump();
+
     /**
      * Provides access to information on buffer usage.
      */
--- a/src/java.base/share/classes/sun/security/provider/certpath/DistributionPointFetcher.java	Fri May 08 09:45:57 2020 +0530
+++ b/src/java.base/share/classes/sun/security/provider/certpath/DistributionPointFetcher.java	Fri May 08 09:52:42 2020 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2020, 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,6 +33,7 @@
 import java.util.*;
 
 import sun.security.util.Debug;
+import sun.security.util.Event;
 import sun.security.validator.Validator;
 import static sun.security.x509.PKIXExtensions.*;
 import sun.security.x509.*;
@@ -246,6 +247,8 @@
         if (debug != null) {
             debug.println("Trying to fetch CRL from DP " + uri);
         }
+
+        Event.report("event.crl.check", uri.toString());
         CertStore ucs = null;
         try {
             ucs = URICertStore.getInstance(new URICertStoreParameters(uri));
--- a/src/java.base/share/classes/sun/security/provider/certpath/OCSP.java	Fri May 08 09:45:57 2020 +0530
+++ b/src/java.base/share/classes/sun/security/provider/certpath/OCSP.java	Fri May 08 09:52:42 2020 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2020, 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,6 +45,7 @@
 
 import sun.security.action.GetIntegerAction;
 import sun.security.util.Debug;
+import sun.security.util.Event;
 import sun.security.validator.Validator;
 import sun.security.x509.AccessDescription;
 import sun.security.x509.AuthorityInfoAccessExtension;
@@ -232,6 +233,8 @@
             if (debug != null) {
                 debug.println("connecting to OCSP service at: " + url);
             }
+
+            Event.report("event.ocsp.check", url.toString());
             HttpURLConnection con = (HttpURLConnection)url.openConnection();
             con.setConnectTimeout(CONNECT_TIMEOUT);
             con.setReadTimeout(CONNECT_TIMEOUT);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.base/share/classes/sun/security/util/Event.java	Fri May 08 09:52:42 2020 +0530
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2020, 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 sun.security.util;
+
+/**
+ * This class implements an event model with services for reporter and listener.
+ * Reporter uses report() method to generate an event.
+ * Listener uses setReportListener() to register for listening to an event,
+ * and uses clearReportListener() to unregister a listening session.
+ * Listener should implement the event handling of the Reporter interface.
+ */
+public final class Event {
+    private Event() {}
+
+    public interface Reporter {
+        public void handle(String type, Object... args);
+    }
+
+    private static Reporter reporter;
+    public static void setReportListener(Reporter re) {
+        reporter = re;
+    }
+
+    public static void clearReportListener() {
+        reporter = null;
+    }
+
+    public static void report(String type, Object... args) {
+        Reporter currentReporter = reporter;
+
+        if (currentReporter != null) {
+            currentReporter.handle(type, args);
+        }
+    }
+}
--- a/src/java.base/share/classes/sun/util/cldr/CLDRLocaleProviderAdapter.java	Fri May 08 09:45:57 2020 +0530
+++ b/src/java.base/share/classes/sun/util/cldr/CLDRLocaleProviderAdapter.java	Fri May 08 09:52:42 2020 +0530
@@ -225,7 +225,7 @@
             return Collections.emptySet();
         }
         StringTokenizer tokens = new StringTokenizer(supportedLocaleString);
-        Set<String> tagset = new HashSet<>(Math.max((int)(tokens.countTokens() / 0.75f) + 1, 16));
+        Set<String> tagset = new HashSet<>((tokens.countTokens() * 4 + 2) / 3);
         while (tokens.hasMoreTokens()) {
             tagset.add(tokens.nextToken());
         }
--- a/src/java.base/share/classes/sun/util/locale/provider/JRELocaleProviderAdapter.java	Fri May 08 09:45:57 2020 +0530
+++ b/src/java.base/share/classes/sun/util/locale/provider/JRELocaleProviderAdapter.java	Fri May 08 09:52:42 2020 +0530
@@ -445,7 +445,7 @@
             return Collections.emptySet();
         }
         StringTokenizer tokens = new StringTokenizer(supportedLocaleString);
-        Set<String> tagset = new HashSet<>(Math.max((int)(tokens.countTokens() / 0.75f) + 1, 16));
+        Set<String> tagset = new HashSet<>((tokens.countTokens() * 4 + 2) / 3);
         while (tokens.hasMoreTokens()) {
             tagset.add(tokens.nextToken());
         }
--- a/src/java.base/share/native/libjava/VM.c	Fri May 08 09:45:57 2020 +0530
+++ b/src/java.base/share/native/libjava/VM.c	Fri May 08 09:52:42 2020 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2004, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 2020, 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
@@ -61,3 +61,8 @@
                                                 jclass c) {
     JVM_InitializeFromArchive(env, c);
 }
+
+JNIEXPORT jlong JNICALL
+Java_jdk_internal_misc_VM_getRandomSeedForCDSDump(JNIEnv *env, jclass ignore) {
+    return JVM_GetRandomSeedForCDSDump();
+}
--- a/src/java.base/share/native/libjimage/imageDecompressor.cpp	Fri May 08 09:45:57 2020 +0530
+++ b/src/java.base/share/native/libjimage/imageDecompressor.cpp	Fri May 08 09:52:42 2020 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2020, Oracle and/or its affiliates. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -61,7 +61,10 @@
 #ifdef WIN32
     HMODULE handle = GetModuleHandle("zip.dll");
     if (handle == NULL) {
-        return NULL;
+      handle = LoadLibrary("zip.dll");
+    }
+    if (handle == NULL) {
+      return NULL;
     }
     addr = (void*) GetProcAddress(handle, name);
     return addr;
--- a/src/java.base/share/native/libjli/java.c	Fri May 08 09:45:57 2020 +0530
+++ b/src/java.base/share/native/libjli/java.c	Fri May 08 09:52:42 2020 +0530
@@ -1958,7 +1958,7 @@
     NULL_CHECK(cls);
     NULL_CHECK(describeModuleID = (*env)->GetStaticMethodID(env, cls,
             "describeModule", "(Ljava/lang/String;)V"));
-    NULL_CHECK(joptString = (*env)->NewStringUTF(env, optString));
+    NULL_CHECK(joptString = NewPlatformString(env, optString));
     (*env)->CallStaticVoidMethod(env, cls, describeModuleID, joptString);
 }
 
--- a/src/java.naming/share/classes/com/sun/jndi/ldap/Connection.java	Fri May 08 09:45:57 2020 +0530
+++ b/src/java.naming/share/classes/com/sun/jndi/ldap/Connection.java	Fri May 08 09:52:42 2020 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2020, 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
@@ -419,22 +419,34 @@
             }
         }
 
+        NamingException namingException = null;
         try {
             // if no timeout is set so we wait infinitely until
-            // a response is received
+            // a response is received OR until the connection is closed or cancelled
             // http://docs.oracle.com/javase/8/docs/technotes/guides/jndi/jndi-ldap.html#PROP
             rber = ldr.getReplyBer(readTimeout);
         } catch (InterruptedException ex) {
             throw new InterruptedNamingException(
                 "Interrupted during LDAP operation");
+        } catch (CommunicationException ce) {
+            // Re-throw
+            throw ce;
+        } catch (NamingException ne) {
+            // Connection is timed out OR closed/cancelled
+            namingException = ne;
+            rber = null;
         }
 
         if (rber == null) {
             abandonRequest(ldr, null);
-            throw new NamingException(
-                    "LDAP response read timed out, timeout used:"
-                            + readTimeout + "ms." );
-
+        }
+        // namingException can be not null in the following cases:
+        //  a) The response is timed-out
+        //  b) LDAP request connection has been closed or cancelled
+        // The exception message is initialized in LdapRequest::getReplyBer
+        if (namingException != null) {
+            // Re-throw NamingException after all cleanups are done
+            throw namingException;
         }
         return rber;
     }
@@ -853,15 +865,6 @@
                     inbuf = Arrays.copyOf(inbuf, offset + left.length);
                     System.arraycopy(left, 0, inbuf, offset, left.length);
                     offset += left.length;
-/*
-if (dump > 0) {
-System.err.println("seqlen: " + seqlen);
-System.err.println("bufsize: " + offset);
-System.err.println("bytesleft: " + bytesleft);
-System.err.println("bytesread: " + bytesread);
-}
-*/
-
 
                     try {
                         retBer = new BerDecoder(inbuf, 0, offset);
@@ -969,36 +972,4 @@
         }
         return buf;
     }
-
-    // This code must be uncommented to run the LdapAbandonTest.
-    /*public void sendSearchReqs(String dn, int numReqs) {
-        int i;
-        String attrs[] = null;
-        for(i = 1; i <= numReqs; i++) {
-            BerEncoder ber = new BerEncoder(2048);
-
-            try {
-            ber.beginSeq(Ber.ASN_SEQUENCE | Ber.ASN_CONSTRUCTOR);
-                ber.encodeInt(i);
-                ber.beginSeq(LdapClient.LDAP_REQ_SEARCH);
-                    ber.encodeString(dn == null ? "" : dn);
-                    ber.encodeInt(0, LdapClient.LBER_ENUMERATED);
-                    ber.encodeInt(3, LdapClient.LBER_ENUMERATED);
-                    ber.encodeInt(0);
-                    ber.encodeInt(0);
-                    ber.encodeBoolean(true);
-                    LdapClient.encodeFilter(ber, "");
-                    ber.beginSeq(Ber.ASN_SEQUENCE | Ber.ASN_CONSTRUCTOR);
-                        ber.encodeStringArray(attrs);
-                    ber.endSeq();
-                ber.endSeq();
-            ber.endSeq();
-            writeRequest(ber, i);
-            //System.err.println("wrote request " + i);
-            } catch (Exception ex) {
-            //System.err.println("ldap.search: Caught " + ex + " building req");
-            }
-
-        }
-    } */
 }
--- a/src/java.naming/share/classes/com/sun/jndi/ldap/LdapRequest.java	Fri May 08 09:45:57 2020 +0530
+++ b/src/java.naming/share/classes/com/sun/jndi/ldap/LdapRequest.java	Fri May 08 09:52:42 2020 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2020, 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,14 @@
 import java.util.concurrent.BlockingQueue;
 import java.util.concurrent.LinkedBlockingQueue;
 import javax.naming.CommunicationException;
+import javax.naming.NamingException;
 import java.util.concurrent.TimeUnit;
 
 final class LdapRequest {
 
     private final static BerDecoder EOF = new BerDecoder(new byte[]{}, -1, 0);
+    private final static String CLOSE_MSG = "LDAP connection has been closed";
+    private final static String TIMEOUT_MSG_FMT = "LDAP response read timed out, timeout used: %d ms.";
 
     LdapRequest next;   // Set/read in synchronized Connection methods
     final int msgId;          // read-only
@@ -95,14 +98,22 @@
         return pauseAfterReceipt;
     }
 
-    BerDecoder getReplyBer(long millis) throws CommunicationException,
+    /**
+     * Read reply BER
+     * @param millis timeout, infinite if the value is negative
+     * @return BerDecoder if reply was read successfully
+     * @throws CommunicationException request has been canceled and request does not need to be abandoned
+     * @throws NamingException request has been closed or timed out. Request does need to be abandoned
+     * @throws InterruptedException LDAP operation has been interrupted
+     */
+    BerDecoder getReplyBer(long millis) throws NamingException,
                                                InterruptedException {
         if (cancelled) {
             throw new CommunicationException("Request: " + msgId +
                 " cancelled");
         }
         if (isClosed()) {
-            return null;
+            throw new NamingException(CLOSE_MSG);
         }
 
         BerDecoder result = millis > 0 ?
@@ -113,7 +124,15 @@
                 " cancelled");
         }
 
-        return result == EOF ? null : result;
+        // poll from 'replies' blocking queue ended-up with timeout
+        if (result == null) {
+            throw new NamingException(String.format(TIMEOUT_MSG_FMT, millis));
+        }
+        // Unexpected EOF can be caused by connection closure or cancellation
+        if (result == EOF) {
+            throw new NamingException(CLOSE_MSG);
+        }
+        return result;
     }
 
     boolean hasSearchCompleted() {
--- a/src/java.net.http/share/classes/jdk/internal/net/http/AsyncSSLConnection.java	Fri May 08 09:45:57 2020 +0530
+++ b/src/java.net.http/share/classes/jdk/internal/net/http/AsyncSSLConnection.java	Fri May 08 09:52:42 2020 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2020, 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,6 +92,11 @@
     }
 
     @Override
+    InetSocketAddress proxy() {
+        return null;
+    }
+
+    @Override
     SocketChannel channel() {
         return plainConnection.channel();
     }
--- a/src/java.net.http/share/classes/jdk/internal/net/http/AsyncSSLTunnelConnection.java	Fri May 08 09:45:57 2020 +0530
+++ b/src/java.net.http/share/classes/jdk/internal/net/http/AsyncSSLTunnelConnection.java	Fri May 08 09:52:42 2020 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2020, 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
@@ -124,6 +124,11 @@
     }
 
     @Override
+    InetSocketAddress proxy() {
+        return plainConnection.proxyAddr;
+    }
+
+    @Override
     SSLTube getConnectionFlow() {
        return flow;
    }
--- a/src/java.net.http/share/classes/jdk/internal/net/http/Http2Connection.java	Fri May 08 09:45:57 2020 +0530
+++ b/src/java.net.http/share/classes/jdk/internal/net/http/Http2Connection.java	Fri May 08 09:52:42 2020 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2020, 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
@@ -514,45 +514,59 @@
         boolean isProxy = connection.isProxied(); // tunnel or plain clear connection through proxy
         boolean isSecure = connection.isSecure();
         InetSocketAddress addr = connection.address();
+        InetSocketAddress proxyAddr = connection.proxy();
+        assert isProxy == (proxyAddr != null);
 
-        return keyString(isSecure, isProxy, addr.getHostString(), addr.getPort());
+        return keyString(isSecure, proxyAddr, addr.getHostString(), addr.getPort());
     }
 
     static String keyFor(URI uri, InetSocketAddress proxy) {
         boolean isSecure = uri.getScheme().equalsIgnoreCase("https");
-        boolean isProxy = proxy != null;
 
-        String host;
-        int port;
-
-        if (proxy != null && !isSecure) {
-            // clear connection through proxy: use
-            // proxy host / proxy port
-            host = proxy.getHostString();
-            port = proxy.getPort();
-        } else {
-            // either secure tunnel connection through proxy
-            // or direct connection to host, but in either
-            // case only that host can be reached through
-            // the connection: use target host / target port
-            host = uri.getHost();
-            port = uri.getPort();
-        }
-        return keyString(isSecure, isProxy, host, port);
+        String host = uri.getHost();
+        int port = uri.getPort();
+        return keyString(isSecure, proxy, host, port);
     }
 
-    // {C,S}:{H:P}:host:port
+
+    // Compute the key for an HttpConnection in the Http2ClientImpl pool:
+    // The key string follows one of the three forms below:
+    //    {C,S}:H:host:port
+    //    C:P:proxy-host:proxy-port
+    //    S:T:H:host:port;P:proxy-host:proxy-port
     // C indicates clear text connection "http"
     // S indicates secure "https"
     // H indicates host (direct) connection
     // P indicates proxy
-    // Eg: "S:H:foo.com:80"
-    static String keyString(boolean secure, boolean proxy, String host, int port) {
+    // T indicates a tunnel connection through a proxy
+    //
+    // The first form indicates a direct connection to a server:
+    //   - direct clear connection to an HTTP host:
+    //     e.g.: "C:H:foo.com:80"
+    //   - direct secure connection to an HTTPS host:
+    //     e.g.: "S:H:foo.com:443"
+    // The second form indicates a clear connection to an HTTP/1.1 proxy:
+    //     e.g.: "C:P:myproxy:8080"
+    // The third form indicates a secure tunnel connection to an HTTPS
+    // host through an HTTP/1.1 proxy:
+    //     e.g: "S:T:H:foo.com:80;P:myproxy:8080"
+    static String keyString(boolean secure, InetSocketAddress proxy, String host, int port) {
         if (secure && port == -1)
             port = 443;
         else if (!secure && port == -1)
             port = 80;
-        return (secure ? "S:" : "C:") + (proxy ? "P:" : "H:") + host + ":" + port;
+        var key = (secure ? "S:" : "C:");
+        if (proxy != null && !secure) {
+            // clear connection through proxy
+            key = key + "P:" + proxy.getHostString() + ":" + proxy.getPort();
+        } else if (proxy == null) {
+            // direct connection to host
+            key = key + "H:" + host + ":" + port;
+        } else {
+            // tunnel connection through proxy
+            key = key + "T:H:" + host + ":" + port + ";P:" + proxy.getHostString() + ":" + proxy.getPort();
+        }
+        return  key;
     }
 
     String key() {
--- a/src/java.net.http/share/classes/jdk/internal/net/http/HttpConnection.java	Fri May 08 09:45:57 2020 +0530
+++ b/src/java.net.http/share/classes/jdk/internal/net/http/HttpConnection.java	Fri May 08 09:52:42 2020 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2020, 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 @@
      */
     abstract boolean isProxied();
 
+    /**
+     * Returns the address of the proxy used by this connection.
+     * Returns the proxy address for tunnel connections, or
+     * clear connection to any host through proxy.
+     * Returns {@code null} otherwise.
+     */
+    abstract InetSocketAddress proxy();
+
     /** Tells whether, or not, this connection is open. */
     final boolean isOpen() {
         return channel().isOpen() &&
--- a/src/java.net.http/share/classes/jdk/internal/net/http/PlainHttpConnection.java	Fri May 08 09:45:57 2020 +0530
+++ b/src/java.net.http/share/classes/jdk/internal/net/http/PlainHttpConnection.java	Fri May 08 09:52:42 2020 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2020, 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
@@ -302,4 +302,8 @@
         return false;
     }
 
+    @Override
+    InetSocketAddress proxy() {
+        return null;
+    }
 }
--- a/src/java.net.http/share/classes/jdk/internal/net/http/PlainProxyConnection.java	Fri May 08 09:45:57 2020 +0530
+++ b/src/java.net.http/share/classes/jdk/internal/net/http/PlainProxyConnection.java	Fri May 08 09:52:42 2020 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2020, 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,4 +40,9 @@
 
     @Override
     public boolean isProxied() { return true; }
+
+    @Override
+    InetSocketAddress proxy() {
+        return address;
+    }
 }
--- a/src/java.net.http/share/classes/jdk/internal/net/http/PlainTunnelingConnection.java	Fri May 08 09:45:57 2020 +0530
+++ b/src/java.net.http/share/classes/jdk/internal/net/http/PlainTunnelingConnection.java	Fri May 08 09:52:42 2020 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2020, 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
@@ -171,4 +171,8 @@
         return true;
     }
 
+    @Override
+    InetSocketAddress proxy() {
+        return proxyAddr;
+    }
 }
--- a/src/java.net.http/share/classes/jdk/internal/net/http/websocket/OpeningHandshake.java	Fri May 08 09:45:57 2020 +0530
+++ b/src/java.net.http/share/classes/jdk/internal/net/http/websocket/OpeningHandshake.java	Fri May 08 09:52:42 2020 +0530
@@ -188,7 +188,7 @@
 
     public CompletableFuture<Result> send() {
         PrivilegedAction<CompletableFuture<Result>> pa = () ->
-                client.sendAsync(this.request, BodyHandlers.discarding())
+                client.sendAsync(this.request, BodyHandlers.ofString())
                       .thenCompose(this::resultFrom);
         return AccessController.doPrivileged(pa);
     }
--- a/src/java.rmi/share/classes/java/rmi/AlreadyBoundException.java	Fri May 08 09:45:57 2020 +0530
+++ b/src/java.rmi/share/classes/java/rmi/AlreadyBoundException.java	Fri May 08 09:52:42 2020 +0530
@@ -26,8 +26,8 @@
 
 /**
  * An <code>AlreadyBoundException</code> is thrown if an attempt
- * is made to bind an object in the registry to a name that already
- * has an associated binding.
+ * is made to bind an object to a name that already
+ * has an associated binding in the registry.
  *
  * @since   1.1
  * @author  Ann Wollrath
--- a/src/java.security.jgss/share/classes/sun/security/krb5/Config.java	Fri May 08 09:45:57 2020 +0530
+++ b/src/java.security.jgss/share/classes/sun/security/krb5/Config.java	Fri May 08 09:52:42 2020 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2020, 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,7 @@
         KdcComm.initStatic();
         EType.initStatic();
         Checksum.initStatic();
+        KrbAsReqBuilder.ReferralsState.initStatic();
     }
 
 
--- a/src/java.security.jgss/share/classes/sun/security/krb5/KrbAsReqBuilder.java	Fri May 08 09:45:57 2020 +0530
+++ b/src/java.security.jgss/share/classes/sun/security/krb5/KrbAsReqBuilder.java	Fri May 08 09:52:42 2020 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2020, 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
@@ -278,7 +278,9 @@
         }
         options = (options == null) ? new KDCOptions() : options;
         if (referralsState.isEnabled()) {
-            options.set(KDCOptions.CANONICALIZE, true);
+            if (referralsState.sendCanonicalize()) {
+                options.set(KDCOptions.CANONICALIZE, true);
+            }
             extraPAs = new PAData[]{ new PAData(Krb5.PA_REQ_ENC_PA_REP,
                     new byte[]{}) };
         } else {
@@ -333,7 +335,7 @@
         boolean preAuthFailedOnce = false;
         KdcComm comm = null;
         EncryptionKey pakey = null;
-        ReferralsState referralsState = new ReferralsState();
+        ReferralsState referralsState = new ReferralsState(this);
         while (true) {
             if (referralsState.refreshComm()) {
                 comm = new KdcComm(refCname.getRealmAsString());
@@ -379,43 +381,88 @@
         }
     }
 
-    private final class ReferralsState {
+    static final class ReferralsState {
+        private static boolean canonicalizeConfig;
         private boolean enabled;
+        private boolean sendCanonicalize;
+        private boolean isEnterpriseCname;
         private int count;
         private boolean refreshComm;
+        private KrbAsReqBuilder reqBuilder;
 
-        ReferralsState() throws KrbException {
-            if (Config.DISABLE_REFERRALS) {
-                if (refCname.getNameType() == PrincipalName.KRB_NT_ENTERPRISE) {
-                    throw new KrbException("NT-ENTERPRISE principals only allowed" +
-                            " when referrals are enabled.");
+        static {
+            initStatic();
+        }
+
+        // Config may be refreshed while running so the setting
+        // value may need to be updated. See Config::refresh.
+        static void initStatic() {
+            canonicalizeConfig = false;
+            try {
+                canonicalizeConfig = Config.getInstance()
+                        .getBooleanObject("libdefaults", "canonicalize") ==
+                        Boolean.TRUE;
+            } catch (KrbException e) {
+                if (Krb5.DEBUG) {
+                    System.out.println("Exception in getting canonicalize," +
+                            " using default value " +
+                            Boolean.valueOf(canonicalizeConfig) + ": " +
+                            e.getMessage());
                 }
-                enabled = false;
-            } else {
-                enabled = true;
+            }
+        }
+
+        ReferralsState(KrbAsReqBuilder reqBuilder) throws KrbException {
+            this.reqBuilder = reqBuilder;
+            sendCanonicalize = canonicalizeConfig;
+            isEnterpriseCname = reqBuilder.refCname.getNameType() ==
+                    PrincipalName.KRB_NT_ENTERPRISE;
+            updateStatus();
+            if (!enabled && isEnterpriseCname) {
+                throw new KrbException("NT-ENTERPRISE principals only" +
+                        " allowed when referrals are enabled.");
             }
             refreshComm = true;
         }
 
+        private void updateStatus() {
+            enabled = !Config.DISABLE_REFERRALS &&
+                    (isEnterpriseCname || sendCanonicalize);
+        }
+
         boolean handleError(KrbException ke) throws RealmException {
             if (enabled) {
                 if (ke.returnCode() == Krb5.KRB_ERR_WRONG_REALM) {
                     Realm referredRealm = ke.getError().getClientRealm();
-                    if (req.getMessage().reqBody.kdcOptions.get(KDCOptions.CANONICALIZE) &&
-                            referredRealm != null && referredRealm.toString().length() > 0 &&
+                    if (referredRealm != null &&
+                            !referredRealm.toString().isEmpty() &&
                             count < Config.MAX_REFERRALS) {
-                        refCname = new PrincipalName(refCname.getNameType(),
-                                refCname.getNameStrings(), referredRealm);
+                        // A valid referral was received while referrals
+                        // were enabled. Change the cname realm to the referred
+                        // realm and set refreshComm to send a new request.
+                        reqBuilder.refCname = new PrincipalName(
+                                reqBuilder.refCname.getNameType(),
+                                reqBuilder.refCname.getNameStrings(),
+                                referredRealm);
                         refreshComm = true;
                         count++;
                         return true;
                     }
                 }
-                if (count < Config.MAX_REFERRALS &&
-                        refCname.getNameType() != PrincipalName.KRB_NT_ENTERPRISE) {
-                    // Server may raise an error if CANONICALIZE is true.
-                    // Try CANONICALIZE false.
-                    enabled = false;
+                if (count < Config.MAX_REFERRALS && sendCanonicalize) {
+                    if (Krb5.DEBUG) {
+                        System.out.println("KrbAsReqBuilder: AS-REQ failed." +
+                                " Retrying with CANONICALIZE false.");
+                    }
+
+                    // Server returned an unexpected error with
+                    // CANONICALIZE true. Retry with false.
+                    sendCanonicalize = false;
+
+                    // Setting CANONICALIZE to false may imply that referrals
+                    // are now disabled (if cname is not of NT-ENTERPRISE type).
+                    updateStatus();
+
                     return true;
                 }
             }
@@ -431,6 +478,10 @@
         boolean isEnabled() {
             return enabled;
         }
+
+        boolean sendCanonicalize() {
+            return sendCanonicalize;
+        }
     }
 
     /**
--- a/src/java.security.jgss/share/classes/sun/security/krb5/KrbKdcRep.java	Fri May 08 09:45:57 2020 +0530
+++ b/src/java.security.jgss/share/classes/sun/security/krb5/KrbKdcRep.java	Fri May 08 09:52:42 2020 +0530
@@ -44,11 +44,13 @@
                       ) throws KrbApErrException {
 
         // cname change in AS-REP is allowed only if the client
-        // sent CANONICALIZE and the server supports RFC 6806 - Section 11
-        // FAST scheme (ENC-PA-REP flag).
+        // sent CANONICALIZE or an NT-ENTERPRISE cname in the request, and the
+        // server supports RFC 6806 - Section 11 FAST scheme (ENC-PA-REP flag).
         if (isAsReq && !req.reqBody.cname.equals(rep.cname) &&
-                (!req.reqBody.kdcOptions.get(KDCOptions.CANONICALIZE) ||
-                 !rep.encKDCRepPart.flags.get(Krb5.TKT_OPTS_ENC_PA_REP))) {
+                ((!req.reqBody.kdcOptions.get(KDCOptions.CANONICALIZE) &&
+                req.reqBody.cname.getNameType() !=
+                PrincipalName.KRB_NT_ENTERPRISE) ||
+                !rep.encKDCRepPart.flags.get(Krb5.TKT_OPTS_ENC_PA_REP))) {
             rep.encKDCRepPart.key.destroy();
             throw new KrbApErrException(Krb5.KRB_AP_ERR_MODIFIED);
         }
@@ -138,14 +140,16 @@
         }
 
         // RFC 6806 - Section 11 mechanism check
-        if (rep.encKDCRepPart.flags.get(Krb5.TKT_OPTS_ENC_PA_REP) &&
-                req.reqBody.kdcOptions.get(KDCOptions.CANONICALIZE)) {
+        // The availability of the ENC-PA-REP flag in the KDC response is
+        // mandatory on some cases (see Krb5.TKT_OPTS_ENC_PA_REP check above).
+        if (rep.encKDCRepPart.flags.get(Krb5.TKT_OPTS_ENC_PA_REP)) {
             boolean reqPaReqEncPaRep = false;
             boolean repPaReqEncPaRepValid = false;
 
-            // PA_REQ_ENC_PA_REP only required for AS requests
             for (PAData pa : req.pAData) {
                 if (pa.getType() == Krb5.PA_REQ_ENC_PA_REP) {
+                    // The KDC supports RFC 6806 and ENC-PA-REP was sent in
+                    // the request (AS-REQ). A valid checksum is now required.
                     reqPaReqEncPaRep = true;
                     break;
                 }
--- a/src/java.xml/share/classes/javax/xml/xpath/XPathEvaluationResult.java	Fri May 08 09:45:57 2020 +0530
+++ b/src/java.xml/share/classes/javax/xml/xpath/XPathEvaluationResult.java	Fri May 08 09:52:42 2020 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2020, 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
@@ -85,25 +85,38 @@
         /**
          * Compares this type to the specified class type.
          * @param clsType class type
-         * @return true if the argument is not null and is a class type that
+         * @return true if the argument is not null and is a class type or accepted subtype that
          * matches that this type represents, false otherwise.
          */
         private boolean equalsClassType(Class<?> clsType) {
-            Objects.nonNull(clsType);
-            if (clsType.isAssignableFrom(this.clsType)) {
+            if (Objects.nonNull(clsType) && this.clsType.isAssignableFrom(clsType)) {
+                if (this.clsType == Number.class) {
+                    return isAcceptedNumberSubType(clsType);
+                }
                 return true;
             }
             return false;
         }
 
         /**
+         * Compares the specified class type to accepted subtypes of number.
+         * @param clsType class type
+         * @return true if class type is an accepted subtype of Number, false otherwise
+         */
+        private boolean isAcceptedNumberSubType(Class<?> clsType) {
+            return clsType.isAssignableFrom(Double.class) ||
+                    clsType.isAssignableFrom(Integer.class) ||
+                    clsType.isAssignableFrom(Long.class);
+        }
+
+        /**
          * Returns the QName type as specified in {@link XPathConstants} that
          * corresponds to the specified class type.
          * @param clsType a class type that the enum type supports
          * @return the QName type that matches with the specified class type,
          * null if there is no match
          */
-        static public QName getQNameType(Class<?> clsType) {
+            static public QName getQNameType(Class<?> clsType) {
             for (XPathResultType type : XPathResultType.values()) {
                 if (type.equalsClassType(clsType)) {
                     return type.qnameType;
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Flow.java	Fri May 08 09:45:57 2020 +0530
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Flow.java	Fri May 08 09:52:42 2020 +0530
@@ -30,7 +30,6 @@
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Set;
-import java.util.stream.Collectors;
 
 import com.sun.source.tree.LambdaExpressionTree.BodyKind;
 import com.sun.tools.javac.code.*;
@@ -44,6 +43,7 @@
 import com.sun.tools.javac.util.JCDiagnostic.Error;
 import com.sun.tools.javac.util.JCDiagnostic.Warning;
 
+import com.sun.tools.javac.code.Kinds.Kind;
 import com.sun.tools.javac.code.Symbol.*;
 import com.sun.tools.javac.tree.JCTree.*;
 
@@ -697,9 +697,12 @@
             pendingExits = new ListBuffer<>();
             scan(tree.selector);
             Set<Object> constants = null;
-            if ((tree.selector.type.tsym.flags() & ENUM) != 0) {
+            TypeSymbol selectorSym = tree.selector.type.tsym;
+            if ((selectorSym.flags() & ENUM) != 0) {
                 constants = new HashSet<>();
-                for (Symbol s : tree.selector.type.tsym.members().getSymbols(s -> (s.flags() & ENUM) != 0)) {
+                Filter<Symbol> enumConstantFilter =
+                        s -> (s.flags() & ENUM) != 0 && s.kind == Kind.VAR;
+                for (Symbol s : selectorSym.members().getSymbols(enumConstantFilter)) {
                     constants.add(s.name);
                 }
             }
@@ -1266,7 +1269,8 @@
                         ctypes = ctypes.append(exc);
                         if (types.isSameType(exc, syms.objectType))
                             continue;
-                        checkCaughtType(l.head.pos(), exc, thrownInTry, caughtInTry);
+                        var pos = subClauses.size() > 1 ? ct.pos() : l.head.pos();
+                        checkCaughtType(pos, exc, thrownInTry, caughtInTry);
                         caughtInTry = chk.incl(exc, caughtInTry);
                     }
                 }
--- a/src/jdk.incubator.jpackage/macosx/classes/jdk/incubator/jpackage/internal/MacBaseInstallerBundler.java	Fri May 08 09:45:57 2020 +0530
+++ b/src/jdk.incubator.jpackage/macosx/classes/jdk/incubator/jpackage/internal/MacBaseInstallerBundler.java	Fri May 08 09:52:42 2020 +0530
@@ -167,12 +167,14 @@
             Pattern p = Pattern.compile("\"alis\"<blob>=\"([^\"]+)\"");
             Matcher m = p.matcher(baos.toString());
             if (!m.find()) {
-                Log.error("Did not find a key matching '" + key + "'");
+                Log.error(MessageFormat.format(I18N.getString(
+                        "error.cert.not.found"), key, keychainName));
                 return null;
             }
             String matchedKey = m.group(1);
             if (m.find()) {
-                Log.error("Found more than one key matching '"  + key + "'");
+                Log.error(MessageFormat.format(I18N.getString(
+                        "error.multiple.certs.found"), key, keychainName));
                 return null;
             }
             Log.verbose("Using key '" + matchedKey + "'");
--- a/src/jdk.incubator.jpackage/macosx/classes/jdk/incubator/jpackage/internal/resources/MacResources.properties	Fri May 08 09:45:57 2020 +0530
+++ b/src/jdk.incubator.jpackage/macosx/classes/jdk/incubator/jpackage/internal/resources/MacResources.properties	Fri May 08 09:52:42 2020 +0530
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2017, 2020, 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,10 @@
 
 error.invalid-cfbundle-version=Invalid CFBundleVersion: [{0}]
 error.invalid-cfbundle-version.advice=Set a compatible 'appVersion' or set a 'mac.CFBundleVersion'. Valid versions are one to three integers separated by dots.
-error.explicit-sign-no-cert=Signature explicitly requested but no signing certificate specified
-error.explicit-sign-no-cert.advice=Either specify a valid cert in 'mac.signing-key-developer-id-app' or unset 'signBundle' or set 'signBundle' to false.
+error.explicit-sign-no-cert=Signature explicitly requested but no signing certificate found
+error.explicit-sign-no-cert.advice=Specify a valid mac-signing-key-user-name and mac-signing-keychain
 error.must-sign-app-store=Mac App Store apps must be signed, and signing has been disabled by bundler configuration
-error.must-sign-app-store.advice=Either unset 'signBundle' or set 'signBundle' to true
+error.must-sign-app-store.advice=Use --mac-sign option with appropriate user-name and keychain
 error.no-app-signing-key=No Mac App Store App Signing Key
 error.no-app-signing-key.advice=Install your app signing keys into your Mac Keychain using XCode.
 error.no-pkg-signing-key=No Mac App Store Installer Signing Key
@@ -42,7 +42,8 @@
 error.certificate.expired=Error: Certificate expired {0}
 error.no.xcode.signing=Xcode with command line developer tools is required for signing
 error.no.xcode.signing.advice=Install Xcode with command line developer tools.
-
+error.cert.not.found=No certificate found matching [{0}] using keychain [{1}]
+error.multiple.certs.found=Multiple certificates found matching [{0}] using keychain [{1}]
 resource.bundle-config-file=Bundle config file
 resource.app-info-plist=Application Info.plist
 resource.runtime-info-plist=Java Runtime Info.plist
--- a/src/jdk.incubator.jpackage/macosx/classes/jdk/incubator/jpackage/internal/resources/MacResources_ja.properties	Fri May 08 09:45:57 2020 +0530
+++ b/src/jdk.incubator.jpackage/macosx/classes/jdk/incubator/jpackage/internal/resources/MacResources_ja.properties	Fri May 08 09:52:42 2020 +0530
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2017, 2020, 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,10 @@
 
 error.invalid-cfbundle-version=\u7121\u52B9\u306ACFBundleVersion: [{0}]
 error.invalid-cfbundle-version.advice=\u4E92\u63DB\u6027\u306E\u3042\u308B'appVersion'\u3092\u8A2D\u5B9A\u3059\u308B\u304B\u3001'mac.CFBundleVersion'\u3092\u8A2D\u5B9A\u3057\u307E\u3059\u3002\u6709\u52B9\u306A\u30D0\u30FC\u30B8\u30E7\u30F3\u306F\u3001\u30C9\u30C3\u30C8\u3067\u533A\u5207\u3089\u308C\u305F1\u304B\u30893\u3064\u306E\u6574\u6570\u3067\u3059\u3002
-error.explicit-sign-no-cert=\u7F72\u540D\u304C\u660E\u793A\u7684\u306B\u8981\u6C42\u3055\u308C\u307E\u3057\u305F\u304C\u3001\u7F72\u540D\u8A3C\u660E\u66F8\u304C\u6307\u5B9A\u3055\u308C\u3066\u3044\u307E\u305B\u3093
-error.explicit-sign-no-cert.advice=\u6709\u52B9\u306A\u8A3C\u660E\u66F8\u3092'mac.signing-key-developer-id-app'\u3067\u6307\u5B9A\u3059\u308B\u304B\u3001'signBundle'\u3092\u8A2D\u5B9A\u89E3\u9664\u3059\u308B\u304B\u3001\u307E\u305F\u306F'signBundle'\u3092false\u306B\u8A2D\u5B9A\u3057\u307E\u3059\u3002
+error.explicit-sign-no-cert=Signature explicitly requested but no signing certificate found
+error.explicit-sign-no-cert.advice=Specify a valid mac-signing-key-user-name and mac-signing-keychain
 error.must-sign-app-store=Mac App Store\u30A2\u30D7\u30EA\u30B1\u30FC\u30B7\u30E7\u30F3\u306F\u7F72\u540D\u3055\u308C\u3066\u3044\u308B\u5FC5\u8981\u304C\u3042\u308A\u307E\u3059\u304C\u3001\u7F72\u540D\u306F\u30D0\u30F3\u30C9\u30E9\u69CB\u6210\u306B\u3088\u3063\u3066\u7121\u52B9\u5316\u3055\u308C\u3066\u3044\u307E\u3059
-error.must-sign-app-store.advice='signBundle'\u3092\u8A2D\u5B9A\u89E3\u9664\u3059\u308B\u304B\u3001'signBundle'\u3092true\u306B\u8A2D\u5B9A\u3057\u3066\u304F\u3060\u3055\u3044
+error.must-sign-app-store.advice=Use --mac-sign option with appropriate user-name and keychain
 error.no-app-signing-key=Mac App Store\u30A2\u30D7\u30EA\u30B1\u30FC\u30B7\u30E7\u30F3\u306E\u7F72\u540D\u30AD\u30FC\u304C\u3042\u308A\u307E\u305B\u3093
 error.no-app-signing-key.advice=XCode\u3092\u4F7F\u7528\u3057\u3066\u30A2\u30D7\u30EA\u30B1\u30FC\u30B7\u30E7\u30F3\u306E\u7F72\u540D\u30AD\u30FC\u3092Mac\u30AD\u30FC\u30C1\u30A7\u30FC\u30F3\u306B\u30A4\u30F3\u30B9\u30C8\u30FC\u30EB\u3057\u307E\u3059\u3002
 error.no-pkg-signing-key=Mac App Store\u30A4\u30F3\u30B9\u30C8\u30FC\u30E9\u306E\u7F72\u540D\u30AD\u30FC\u304C\u3042\u308A\u307E\u305B\u3093
@@ -42,6 +42,8 @@
 error.certificate.expired=\u30A8\u30E9\u30FC: \u8A3C\u660E\u66F8\u306F{0}\u306B\u671F\u9650\u304C\u5207\u308C\u307E\u3057\u305F
 error.no.xcode.signing=\u7F72\u540D\u306B\u306F\u3001Xcode\u3068\u30B3\u30DE\u30F3\u30C9\u30E9\u30A4\u30F3\u30FB\u30C7\u30D9\u30ED\u30C3\u30D1\u30FB\u30C4\u30FC\u30EB\u304C\u5FC5\u8981\u3067\u3059
 error.no.xcode.signing.advice=Xcode\u3068\u30B3\u30DE\u30F3\u30C9\u30E9\u30A4\u30F3\u30FB\u30C7\u30D9\u30ED\u30C3\u30D1\u30FB\u30C4\u30FC\u30EB\u3092\u30A4\u30F3\u30B9\u30C8\u30FC\u30EB\u3057\u3066\u304F\u3060\u3055\u3044\u3002
+error.cert.not.found=No certificate found matching [{0}] using keychain [{1}]
+error.multiple.certs.found=Multiple certificates found matching [{0}] using keychain [{1}]
 
 resource.bundle-config-file=\u30D0\u30F3\u30C9\u30EB\u69CB\u6210\u30D5\u30A1\u30A4\u30EB
 resource.app-info-plist=\u30A2\u30D7\u30EA\u30B1\u30FC\u30B7\u30E7\u30F3\u306EInfo.plist
--- a/src/jdk.incubator.jpackage/macosx/classes/jdk/incubator/jpackage/internal/resources/MacResources_zh_CN.properties	Fri May 08 09:45:57 2020 +0530
+++ b/src/jdk.incubator.jpackage/macosx/classes/jdk/incubator/jpackage/internal/resources/MacResources_zh_CN.properties	Fri May 08 09:52:42 2020 +0530
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2017, 2020, 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,10 @@
 
 error.invalid-cfbundle-version=\u65E0\u6548\u7684 CFBundleVersion\uFF1A[{0}]
 error.invalid-cfbundle-version.advice=\u8BBE\u7F6E\u517C\u5BB9\u7684 'appVersion' \u6216\u8005\u8BBE\u7F6E 'mac.CFBundleVersion'\u3002\u6709\u6548\u7248\u672C\u5305\u542B\u4E00\u5230\u4E09\u4E2A\u7528\u70B9\u5206\u9694\u7684\u6574\u6570\u3002
-error.explicit-sign-no-cert=\u5DF2\u660E\u786E\u8BF7\u6C42\u7B7E\u540D, \u4F46\u672A\u6307\u5B9A\u7B7E\u540D\u8BC1\u4E66
-error.explicit-sign-no-cert.advice=\u5728 'mac.signing-key-developer-id-app' \u4E2D\u6307\u5B9A\u6709\u6548\u7684\u8BC1\u4E66, \u6216\u8005\u53D6\u6D88\u8BBE\u7F6E 'signBundle', \u6216\u8005\u5C06 'signBundle' \u8BBE\u7F6E\u4E3A\u201C\u5047\u201D\u3002
+error.explicit-sign-no-cert=Signature explicitly requested but no signing certificate found
+error.explicit-sign-no-cert.advice=Specify a valid mac-signing-key-user-name and mac-signing-keychain
 error.must-sign-app-store=Mac App Store \u5E94\u7528\u7A0B\u5E8F\u5FC5\u987B\u7B7E\u540D, \u800C\u6253\u5305\u7A0B\u5E8F\u914D\u7F6E\u5DF2\u7981\u7528\u7B7E\u540D
-error.must-sign-app-store.advice=\u53D6\u6D88\u8BBE\u7F6E 'signBundle' \u6216\u8005\u5C06 'signBundle' \u8BBE\u7F6E\u4E3A true
+error.must-sign-app-store.advice=Use --mac-sign option with appropriate user-name and keychain
 error.no-app-signing-key=\u65E0 Mac App Store \u5E94\u7528\u7A0B\u5E8F\u7B7E\u540D\u5BC6\u94A5
 error.no-app-signing-key.advice=\u4F7F\u7528 XCode \u5C06\u5E94\u7528\u7A0B\u5E8F\u7B7E\u540D\u5BC6\u94A5\u5B89\u88C5\u5230 Mac \u5BC6\u94A5\u94FE\u4E2D\u3002
 error.no-pkg-signing-key=\u65E0 Mac App Store \u5B89\u88C5\u7A0B\u5E8F\u7B7E\u540D\u5BC6\u94A5
@@ -42,6 +42,8 @@
 error.certificate.expired=\u9519\u8BEF: \u8BC1\u4E66\u5DF2\u5931\u6548 {0}
 error.no.xcode.signing=\u9700\u8981\u4F7F\u7528\u5E26\u547D\u4EE4\u884C\u5F00\u53D1\u4EBA\u5458\u5DE5\u5177\u7684 Xcode \u8FDB\u884C\u7B7E\u540D
 error.no.xcode.signing.advice=\u5B89\u88C5\u5E26\u547D\u4EE4\u884C\u5F00\u53D1\u4EBA\u5458\u5DE5\u5177\u7684 Xcode\u3002
+error.cert.not.found=No certificate found matching [{0}] using keychain [{1}]
+error.multiple.certs.found=Multiple certificates found matching [{0}] using keychain [{1}]
 
 resource.bundle-config-file=\u5305\u914D\u7F6E\u6587\u4EF6
 resource.app-info-plist=\u5E94\u7528\u7A0B\u5E8F Info.plist
--- a/src/jdk.incubator.jpackage/share/classes/jdk/incubator/jpackage/internal/DeployParams.java	Fri May 08 09:45:57 2020 +0530
+++ b/src/jdk.incubator.jpackage/share/classes/jdk/incubator/jpackage/internal/DeployParams.java	Fri May 08 09:52:42 2020 +0530
@@ -83,10 +83,13 @@
         if (!Files.isSymbolicLink(root.toPath())) {
             if (root.isDirectory()) {
                 File[] children = root.listFiles();
-                if (children != null) {
+                if (children != null && children.length > 0) {
                     for (File f : children) {
                         files.addAll(expandFileset(f));
                     }
+                } else {
+                    // Include empty folders
+                    files.add(root);
                 }
             } else {
                 files.add(root);
@@ -295,6 +298,17 @@
                 throw new PackagerException("ERR_LicenseFileNotExit");
             }
         }
+
+        // Validate icon file if set
+        String icon = (String)bundlerArguments.get(
+                Arguments.CLIOptions.ICON.getId());
+        if (icon != null) {
+            File iconFile = new File(icon);
+            if (!iconFile.exists()) {
+                throw new PackagerException("ERR_IconFileNotExit",
+                        iconFile.getAbsolutePath());
+            }
+        }
     }
 
     void setTargetFormat(String t) {
--- a/src/jdk.incubator.jpackage/share/classes/jdk/incubator/jpackage/internal/resources/MainResources.properties	Fri May 08 09:45:57 2020 +0530
+++ b/src/jdk.incubator.jpackage/share/classes/jdk/incubator/jpackage/internal/resources/MainResources.properties	Fri May 08 09:52:42 2020 +0530
@@ -90,6 +90,7 @@
 ERR_NoJreInstallerName=Error: Jre Installers require a name parameter
 ERR_InvalidAppName=Error: Invalid Application name: {0}
 ERR_InvalidSLName=Error: Invalid Add Launcher name: {0}
+ERR_IconFileNotExit=Error: Specified icon file [{0}] does not exist
 ERR_LicenseFileNotExit=Error: Specified license file does not exist
 ERR_BuildRootInvalid=Error: temp ({0}) must be non-existant or empty directory
 ERR_InvalidOption=Error: Invalid Option: [{0}]
--- a/src/jdk.incubator.jpackage/share/classes/jdk/incubator/jpackage/internal/resources/MainResources_ja.properties	Fri May 08 09:45:57 2020 +0530
+++ b/src/jdk.incubator.jpackage/share/classes/jdk/incubator/jpackage/internal/resources/MainResources_ja.properties	Fri May 08 09:52:42 2020 +0530
@@ -89,6 +89,7 @@
 ERR_NoJreInstallerName=\u30A8\u30E9\u30FC: Jre\u30A4\u30F3\u30B9\u30C8\u30FC\u30E9\u306B\u306F\u540D\u524D\u30D1\u30E9\u30E1\u30FC\u30BF\u304C\u5FC5\u8981\u3067\u3059
 ERR_InvalidAppName=\u30A8\u30E9\u30FC: \u7121\u52B9\u306A\u30A2\u30D7\u30EA\u30B1\u30FC\u30B7\u30E7\u30F3\u540D: {0}
 ERR_InvalidSLName=\u30A8\u30E9\u30FC: \u7121\u52B9\u306A\u8FFD\u52A0\u30E9\u30F3\u30C1\u30E3\u540D: {0}
+ERR_IconFileNotExit=Error: Specified icon file [{0}] does not exist
 ERR_LicenseFileNotExit=\u30A8\u30E9\u30FC: \u6307\u5B9A\u3055\u308C\u305F\u30E9\u30A4\u30BB\u30F3\u30B9\u30FB\u30D5\u30A1\u30A4\u30EB\u306F\u5B58\u5728\u3057\u307E\u305B\u3093
 ERR_BuildRootInvalid=\u30A8\u30E9\u30FC: \u4E00\u6642({0})\u306F\u5B58\u5728\u3057\u306A\u3044\u304B\u3001\u7A7A\u306E\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u3067\u3042\u308B\u5FC5\u8981\u304C\u3042\u308A\u307E\u3059
 ERR_InvalidOption=\u30A8\u30E9\u30FC: \u7121\u52B9\u306A\u30AA\u30D7\u30B7\u30E7\u30F3: [{0}]
--- a/src/jdk.incubator.jpackage/share/classes/jdk/incubator/jpackage/internal/resources/MainResources_zh_CN.properties	Fri May 08 09:45:57 2020 +0530
+++ b/src/jdk.incubator.jpackage/share/classes/jdk/incubator/jpackage/internal/resources/MainResources_zh_CN.properties	Fri May 08 09:52:42 2020 +0530
@@ -89,6 +89,7 @@
 ERR_NoJreInstallerName=\u9519\u8BEF\uFF1AJre \u5B89\u88C5\u7A0B\u5E8F\u9700\u8981\u4E00\u4E2A\u540D\u79F0\u53C2\u6570
 ERR_InvalidAppName=\u9519\u8BEF\uFF1A\u5E94\u7528\u7A0B\u5E8F\u540D\u79F0 {0} \u65E0\u6548
 ERR_InvalidSLName=\u9519\u8BEF\uFF1A\u6DFB\u52A0\u542F\u52A8\u7A0B\u5E8F\u540D\u79F0 {0} \u65E0\u6548
+ERR_IconFileNotExit=Error: Specified icon file [{0}] does not exist
 ERR_LicenseFileNotExit=\u9519\u8BEF\uFF1A\u6307\u5B9A\u7684\u8BB8\u53EF\u8BC1\u6587\u4EF6\u4E0D\u5B58\u5728
 ERR_BuildRootInvalid=\u9519\u8BEF\uFF1A\u4E34\u65F6\u76EE\u5F55 ({0}) \u5FC5\u987B\u662F\u4E0D\u5B58\u5728\u7684\u76EE\u5F55\u6216\u7A7A\u767D\u76EE\u5F55
 ERR_InvalidOption=\u9519\u8BEF\uFF1A\u9009\u9879 [{0}] \u65E0\u6548
--- a/src/jdk.incubator.jpackage/windows/native/libjpackage/JniUtils.h	Fri May 08 09:45:57 2020 +0530
+++ b/src/jdk.incubator.jpackage/windows/native/libjpackage/JniUtils.h	Fri May 08 09:52:42 2020 +0530
@@ -48,6 +48,10 @@
         return ! operator == (other);
     }
 
+    explicit operator bool() const {
+        return env && obj;
+    }
+
     JNIEnv *env;
     jobject obj;
 
--- a/src/jdk.jartool/share/classes/sun/security/tools/jarsigner/Main.java	Fri May 08 09:45:57 2020 +0530
+++ b/src/jdk.jartool/share/classes/sun/security/tools/jarsigner/Main.java	Fri May 08 09:52:42 2020 +0530
@@ -158,6 +158,7 @@
     boolean signManifest = true; // "sign" the whole manifest
     boolean externalSF = true; // leave the .SF out of the PKCS7 block
     boolean strict = false;  // treat warnings as error
+    boolean revocationCheck = false; // Revocation check flag
 
     // read zip entry raw bytes
     private String altSignerClass = null;
@@ -293,6 +294,7 @@
                 Arrays.fill(storepass, ' ');
                 storepass = null;
             }
+            Event.clearReportListener();
         }
 
         if (strict) {
@@ -484,6 +486,8 @@
                        // -help: legacy.
                        collator.compare(flags, "-help") == 0) {
                 fullusage();
+            } else if (collator.compare(flags, "-revCheck") == 0) {
+                revocationCheck = true;
             } else {
                 System.err.println(
                         rb.getString("Illegal.option.") + flags);
@@ -627,6 +631,9 @@
                 (".certs.display.certificates.when.verbose.and.verifying"));
         System.out.println();
         System.out.println(rb.getString
+                (".certs.revocation.check"));
+        System.out.println();
+        System.out.println(rb.getString
                 (".tsa.url.location.of.the.Timestamping.Authority"));
         System.out.println();
         System.out.println(rb.getString
@@ -2053,7 +2060,13 @@
                                     .map(c -> new TrustAnchor(c, null))
                                     .collect(Collectors.toSet()),
                             null);
-                    pkixParameters.setRevocationEnabled(false);
+
+                    if (revocationCheck) {
+                        Security.setProperty("ocsp.enable", "true");
+                        System.setProperty("com.sun.security.enableCRLDP", "true");
+                        Event.setReportListener((t, o) -> System.out.println(String.format(rb.getString(t), o)));
+                    }
+                    pkixParameters.setRevocationEnabled(revocationCheck);
                 } catch (InvalidAlgorithmParameterException ex) {
                     // Only if tas is empty
                 }
--- a/src/jdk.jartool/share/classes/sun/security/tools/jarsigner/Resources.java	Fri May 08 09:45:57 2020 +0530
+++ b/src/jdk.jartool/share/classes/sun/security/tools/jarsigner/Resources.java	Fri May 08 09:52:42 2020 +0530
@@ -83,6 +83,8 @@
                 "                            suboptions can be all, grouped or summary"},
         {".certs.display.certificates.when.verbose.and.verifying",
                 "[-certs]                    display certificates when verbose and verifying"},
+        {".certs.revocation.check",
+                "[-revCheck]                 Enable certificate revocation check"},
         {".tsa.url.location.of.the.Timestamping.Authority",
                 "[-tsa <url>]                location of the Timestamping Authority"},
         {".tsacert.alias.public.key.certificate.for.Timestamping.Authority",
@@ -310,6 +312,8 @@
         {"Cannot.find.environment.variable.",
                 "Cannot find environment variable: "},
         {"Cannot.find.file.", "Cannot find file: "},
+        {"event.ocsp.check", "Contacting OCSP server at %s ..."},
+        {"event.crl.check", "Downloading CRL from %s ..."},
     };
 
     /**
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/search.js	Fri May 08 09:45:57 2020 +0530
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/search.js	Fri May 08 09:52:42 2020 +0530
@@ -310,6 +310,9 @@
             }
         },
         autoFocus: true,
+        focus: function(event, ui) {
+            return false;
+        },
         position: {
             collision: "flip"
         },
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/JavadocTool.java	Fri May 08 09:45:57 2020 +0530
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/JavadocTool.java	Fri May 08 09:52:42 2020 +0530
@@ -127,8 +127,10 @@
     }
 
     public DocletEnvironment getEnvironment(ToolOptions toolOptions,
-            List<String> javaNames,
-            Iterable<? extends JavaFileObject> fileObjects) throws ToolException {
+                                            List<String> javaNames,
+                                            Iterable<? extends JavaFileObject> fileObjects)
+            throws ToolException
+    {
         toolEnv = ToolEnvironment.instance(context);
         toolEnv.initialize(toolOptions);
         ElementsTable etable = new ElementsTable(context, toolOptions);
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/Main.java	Fri May 08 09:45:57 2020 +0530
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/Main.java	Fri May 08 09:52:42 2020 +0530
@@ -46,7 +46,7 @@
      * The main entry point called by the launcher. This will call
      * System.exit with an appropriate return value.
      *
-     * @param args The command line parameters.
+     * @param args the command-line parameters
      */
     public static void main(String... args) {
         System.exit(execute(args));
@@ -55,7 +55,7 @@
     /**
      * Programmatic interface.
      *
-     * @param args The command line parameters.
+     * @param args the command-line parameters
      * @return The return code.
      */
     public static int execute(String... args) {
@@ -67,7 +67,7 @@
      * Programmatic interface.
      *
      * @param writer a stream for all output
-     * @param args The command line parameters.
+     * @param args the command-line parameters
      * @return The return code.
      */
     public static int execute(String[] args, PrintWriter writer) {
@@ -80,7 +80,7 @@
      *
      * @param outWriter a stream for expected output
      * @param errWriter a stream for diagnostic output
-     * @param args The command line parameters.
+     * @param args the command-line parameters
      * @return The return code.
      */
     public static int execute(String[] args, PrintWriter outWriter, PrintWriter errWriter) {
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/Start.java	Fri May 08 09:45:57 2020 +0530
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/Start.java	Fri May 08 09:52:42 2020 +0530
@@ -495,7 +495,12 @@
         arguments.allowEmpty();
 
         doclet.init(locale, messager);
-        parseArgs(argList, javaNames);
+        int beforeCount = messager.nerrors;
+        boolean success = parseArgs(argList, javaNames);
+        int afterCount = messager.nerrors;
+        if (!success && beforeCount == afterCount) { // if there were failures but they have not been reported
+            return CMDERR;
+        }
 
         if (!arguments.handleReleaseOptions(extra -> true)) {
             // Arguments does not always increase the error count in the
@@ -579,8 +584,13 @@
     }
 
     private Set<? extends Doclet.Option> docletOptions = null;
-    int handleDocletOption(int idx, List<String> args, boolean isToolOption)
-            throws OptionException {
+
+    /*
+     * Consumes an option along with its arguments. Returns an advanced index
+     * modulo the sign. If the value is negative, it means there was a failure
+     * processing one or more options.
+     */
+    int consumeDocletOption(int idx, List<String> args, boolean isToolOption) throws OptionException {
         if (docletOptions == null) {
             docletOptions = getSupportedOptionsOf(doclet);
         }
@@ -594,6 +604,7 @@
             argBase = arg;
             argVal = null;
         }
+        int m = 1;
         String text = null;
         for (Doclet.Option opt : docletOptions) {
             if (matches(opt, argBase)) {
@@ -603,21 +614,25 @@
                             text = messager.getText("main.unnecessary_arg_provided", argBase);
                             throw new OptionException(ERROR, this::showUsage, text);
                         case 1:
-                            opt.process(arg, Arrays.asList(argVal));
+                            if (!opt.process(arg, Collections.singletonList(argVal))) {
+                                m = -1;
+                            }
                             break;
                         default:
                             text = messager.getText("main.only_one_argument_with_equals", argBase);
                             throw new OptionException(ERROR, this::showUsage, text);
                     }
                 } else {
-                    if (args.size() - idx -1 < opt.getArgumentCount()) {
+                    if (args.size() - idx - 1 < opt.getArgumentCount()) {
                         text = messager.getText("main.requires_argument", arg);
                         throw new OptionException(ERROR, this::showUsage, text);
                     }
-                    opt.process(arg, args.subList(idx + 1, args.size()));
+                    if (!opt.process(arg, args.subList(idx + 1, idx + 1 + opt.getArgumentCount()))) {
+                        m = -1;
+                    }
                     idx += opt.getArgumentCount();
                 }
-                return idx;
+                return m * idx;
             }
         }
         // check if arg is accepted by the tool before emitting error
@@ -625,7 +640,7 @@
             text = messager.getText("main.invalid_flag", arg);
             throw new OptionException(ERROR, this::showUsage, text);
         }
-        return idx;
+        return m * idx;
     }
 
     private static Set<? extends Option> getSupportedOptionsOf(Doclet doclet) {
@@ -649,8 +664,7 @@
      * @throws ToolException if an error occurs initializing the doclet
      * @throws OptionException if an error occurs while processing an option
      */
-    private Doclet preprocess(List<String> argv)
-            throws ToolException, OptionException {
+    private Doclet preprocess(List<String> argv) throws ToolException, OptionException {
         // doclet specifying arguments
         String userDocletPath = null;
         String userDocletName = null;
@@ -774,15 +788,19 @@
         }
     }
 
-    private void parseArgs(List<String> args, List<String> javaNames) throws ToolException,
-            OptionException, com.sun.tools.javac.main.Option.InvalidValueException {
+    private boolean parseArgs(List<String> args, List<String> javaNames)
+            throws OptionException, com.sun.tools.javac.main.Option.InvalidValueException
+    {
+        boolean success = true;
         for (int i = 0; i < args.size(); i++) {
             String arg = args.get(i);
             ToolOption o = options.getOption(arg);
             if (o != null) {
                 // handle a doclet argument that may be needed however
                 // don't increment the index, and allow the tool to consume args
-                handleDocletOption(i, args, true);
+                if (consumeDocletOption(i, args, true) < 0) {
+                    success = false;
+                }
                 if (o.hasArg) {
                     if (arg.startsWith("--") && arg.contains("=")) {
                         o.process(arg.substring(arg.indexOf('=') + 1));
@@ -800,14 +818,19 @@
                 String s = arg.substring("-XD".length());
                 int eq = s.indexOf('=');
                 String key = (eq < 0) ? s : s.substring(0, eq);
-                String value = (eq < 0) ? s : s.substring(eq+1);
+                String value = (eq < 0) ? s : s.substring(eq + 1);
                 options.compilerOptions().put(key, value);
             } else if (arg.startsWith("-")) {
-                i = handleDocletOption(i, args, false);
+                i = consumeDocletOption(i, args, false);
+                if (i < 0) {
+                    i = -i;
+                    success = false;
+                }
             } else {
                 javaNames.add(arg);
             }
         }
+        return success;
     }
 
     private <T> boolean isEmpty(Iterable<T> iter) {
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/ToolOptions.java	Fri May 08 09:45:57 2020 +0530
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/ToolOptions.java	Fri May 08 09:52:42 2020 +0530
@@ -696,7 +696,7 @@
     }
 
     void setDumpOnError(boolean v) {
-        dumpOnError = true;
+        dumpOnError = v;
     }
 
     /**
@@ -816,7 +816,7 @@
     /**
      * Returns an {@code IllegalOptionValue} exception.
      *
-     * @param arg the arghument to include in the detail message
+     * @param arg the argument to include in the detail message
      * @return the exception
      */
     private IllegalOptionValue illegalOptionValue(String arg) {
--- a/src/jdk.jfr/share/classes/jdk/jfr/internal/PlatformRecorder.java	Fri May 08 09:45:57 2020 +0530
+++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/PlatformRecorder.java	Fri May 08 09:52:42 2020 +0530
@@ -36,6 +36,7 @@
 import java.security.AccessController;
 import java.time.Duration;
 import java.time.Instant;
+import java.time.ZonedDateTime;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.HashMap;
@@ -219,7 +220,8 @@
 
     synchronized long start(PlatformRecording recording) {
         // State can only be NEW or DELAYED because of previous checks
-        Instant now = Instant.now();
+        ZonedDateTime zdtNow = ZonedDateTime.now();
+        Instant now = zdtNow.toInstant();
         recording.setStartTime(now);
         recording.updateTimer();
         Duration duration = recording.getDuration();
@@ -242,8 +244,8 @@
         if (beginPhysical) {
             RepositoryChunk newChunk = null;
             if (toDisk) {
-                newChunk = repository.newChunk(now);
-                MetadataRepository.getInstance().setOutput(newChunk.getUnfinishedFile().toString());
+                newChunk = repository.newChunk(zdtNow);
+                MetadataRepository.getInstance().setOutput(newChunk.getFile().toString());
             } else {
                 MetadataRepository.getInstance().setOutput(null);
             }
@@ -256,9 +258,9 @@
         } else {
             RepositoryChunk newChunk = null;
             if (toDisk) {
-                newChunk = repository.newChunk(now);
+                newChunk = repository.newChunk(zdtNow);
                 RequestEngine.doChunkEnd();
-                MetadataRepository.getInstance().setOutput(newChunk.getUnfinishedFile().toString());
+                MetadataRepository.getInstance().setOutput(newChunk.getFile().toString());
                 startNanos = jvm.getChunkStartNanos();
             }
             recording.setState(RecordingState.RUNNING);
@@ -286,7 +288,8 @@
         if (Utils.isBefore(state, RecordingState.RUNNING)) {
             throw new IllegalStateException("Recording must be started before it can be stopped.");
         }
-        Instant now = Instant.now();
+        ZonedDateTime zdtNow = ZonedDateTime.now();
+        Instant now = zdtNow.toInstant();
         boolean toDisk = false;
         boolean endPhysical = true;
         long streamInterval = Long.MAX_VALUE;
@@ -325,8 +328,8 @@
             RequestEngine.doChunkEnd();
             updateSettingsButIgnoreRecording(recording);
             if (toDisk) {
-                newChunk = repository.newChunk(now);
-                MetadataRepository.getInstance().setOutput(newChunk.getUnfinishedFile().toString());
+                newChunk = repository.newChunk(zdtNow);
+                MetadataRepository.getInstance().setOutput(newChunk.getFile().toString());
             } else {
                 MetadataRepository.getInstance().setOutput(null);
             }
@@ -375,13 +378,13 @@
 
 
     synchronized void rotateDisk() {
-        Instant now = Instant.now();
+        ZonedDateTime now = ZonedDateTime.now();
         RepositoryChunk newChunk = repository.newChunk(now);
         RequestEngine.doChunkEnd();
-        MetadataRepository.getInstance().setOutput(newChunk.getUnfinishedFile().toString());
+        MetadataRepository.getInstance().setOutput(newChunk.getFile().toString());
         writeMetaEvents();
         if (currentChunk != null) {
-            finishChunk(currentChunk, now, null);
+            finishChunk(currentChunk, now.toInstant(), null);
         }
         currentChunk = newChunk;
         RequestEngine.doChunkBegin();
--- a/src/jdk.jfr/share/classes/jdk/jfr/internal/Repository.java	Fri May 08 09:45:57 2020 +0530
+++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/Repository.java	Fri May 08 09:52:42 2020 +0530
@@ -27,9 +27,8 @@
 
 import java.io.IOException;
 import java.nio.file.Path;
-import java.time.Instant;
 import java.time.LocalDateTime;
-import java.time.format.DateTimeFormatter;
+import java.time.ZonedDateTime;
 import java.util.HashSet;
 import java.util.Set;
 
@@ -41,8 +40,6 @@
     private static final JVM jvm = JVM.getJVM();
     private static final Repository instance = new Repository();
 
-    public final static DateTimeFormatter REPO_DATE_FORMAT = DateTimeFormatter
-            .ofPattern("yyyy_MM_dd_HH_mm_ss");
     private static final String JFR_REPOSITORY_LOCATION_PROPERTY = "jdk.jfr.repository";
 
     private final Set<SafePath> cleanupDirectories = new HashSet<>();
@@ -80,7 +77,7 @@
         }
     }
 
-    synchronized RepositoryChunk newChunk(Instant timestamp) {
+    synchronized RepositoryChunk newChunk(ZonedDateTime timestamp) {
         try {
             if (!SecuritySupport.existDirectory(repository)) {
                 this.repository = createRepository(baseLocation);
@@ -90,7 +87,7 @@
             }
             return new RepositoryChunk(repository, timestamp);
         } catch (Exception e) {
-            String errorMsg = String.format("Could not create chunk in repository %s, %s", repository, e.getMessage());
+            String errorMsg = String.format("Could not create chunk in repository %s, %s: %s", repository, e.getClass(), e.getMessage());
             Logger.log(LogTag.JFR, LogLevel.ERROR, errorMsg);
             jvm.abort(errorMsg);
             throw new InternalError("Could not abort after JFR disk creation error");
@@ -101,7 +98,7 @@
         SafePath canonicalBaseRepositoryPath = createRealBasePath(basePath);
         SafePath f = null;
 
-        String basename = REPO_DATE_FORMAT.format(LocalDateTime.now()) + "_" + JVM.getJVM().getPid();
+        String basename = Utils.formatDateTime(LocalDateTime.now()) + "_" + JVM.getJVM().getPid();
         String name = basename;
 
         int i = 0;
--- a/src/jdk.jfr/share/classes/jdk/jfr/internal/RepositoryChunk.java	Fri May 08 09:45:57 2020 +0530
+++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/RepositoryChunk.java	Fri May 08 09:52:42 2020 +0530
@@ -33,12 +33,12 @@
 import java.time.LocalDateTime;
 import java.time.ZonedDateTime;
 import java.util.Comparator;
-import java.util.Objects;
 
 import jdk.jfr.internal.SecuritySupport.SafePath;
 
 final class RepositoryChunk {
     private static final int MAX_CHUNK_NAMES = 100;
+    private static final String FILE_EXTENSION = ".jfr";
 
     static final Comparator<RepositoryChunk> END_TIME_COMPARATOR = new Comparator<RepositoryChunk>() {
         @Override
@@ -48,8 +48,7 @@
     };
 
     private final SafePath repositoryPath;
-    private final SafePath unFinishedFile;
-    private final SafePath file;
+    private final SafePath chunkFile;
     private final Instant startTime;
     private final RandomAccessFile unFinishedRAF;
 
@@ -57,34 +56,26 @@
     private int refCount = 0;
     private long size;
 
-    RepositoryChunk(SafePath path, Instant startTime) throws Exception {
-        ZonedDateTime z = ZonedDateTime.now();
-        String fileName = Repository.REPO_DATE_FORMAT.format(
-                LocalDateTime.ofInstant(startTime, z.getZone()));
-        this.startTime = startTime;
+    RepositoryChunk(SafePath path, ZonedDateTime timestamp) throws Exception {
+        this.startTime = timestamp.toInstant();
         this.repositoryPath = path;
-        this.unFinishedFile = findFileName(repositoryPath, fileName, ".jfr");
-        this.file = findFileName(repositoryPath, fileName, ".jfr");
-        this.unFinishedRAF = SecuritySupport.createRandomAccessFile(unFinishedFile);
- //       SecuritySupport.touch(file);
+        this.chunkFile = findFileName(repositoryPath, timestamp.toLocalDateTime());
+        this.unFinishedRAF = SecuritySupport.createRandomAccessFile(chunkFile);
     }
 
-    private static SafePath findFileName(SafePath directory, String name, String extension) throws Exception {
-        Path p = directory.toPath().resolve(name + extension);
+    private static SafePath findFileName(SafePath directory, LocalDateTime time) throws Exception {
+        String filename = Utils.formatDateTime(time);
+        Path p = directory.toPath().resolve(filename + FILE_EXTENSION);
         for (int i = 1; i < MAX_CHUNK_NAMES; i++) {
             SafePath s = new SafePath(p);
             if (!SecuritySupport.exists(s)) {
                 return s;
             }
-            String extendedName = String.format("%s_%02d%s", name, i, extension);
+            String extendedName = String.format("%s_%02d%s", filename, i, FILE_EXTENSION);
             p = directory.toPath().resolve(extendedName);
         }
-        p = directory.toPath().resolve(name + "_" + System.currentTimeMillis() + extension);
-        return SecuritySupport.toRealPath(new SafePath(p));
-    }
-
-    public SafePath getUnfinishedFile() {
-        return unFinishedFile;
+        p = directory.toPath().resolve(filename + "_" + System.currentTimeMillis() + FILE_EXTENSION);
+        return new SafePath(p);
     }
 
     void finish(Instant endTime) {
@@ -97,15 +88,9 @@
 
     private void finishWithException(Instant endTime) throws IOException {
         unFinishedRAF.close();
-        this.size = finish(unFinishedFile, file);
+        this.size = SecuritySupport.getFileSize(chunkFile);
         this.endTime = endTime;
-        Logger.log(LogTag.JFR_SYSTEM, LogLevel.DEBUG, () -> "Chunk finished: " + file);
-    }
-
-    private static long finish(SafePath unFinishedFile, SafePath file) throws IOException {
-        Objects.requireNonNull(unFinishedFile);
-        Objects.requireNonNull(file);
-        return SecuritySupport.getFileSize(file);
+        Logger.log(LogTag.JFR_SYSTEM, LogLevel.DEBUG, () -> "Chunk finished: " + chunkFile);
     }
 
     public Instant getStartTime() {
@@ -134,13 +119,11 @@
         if (!isFinished()) {
             finish(Instant.MIN);
         }
-        if (file != null) {
-            delete(file);
-        }
+         delete(chunkFile);
         try {
             unFinishedRAF.close();
         } catch (IOException e) {
-            Logger.log(LogTag.JFR, LogLevel.ERROR, () -> "Could not close random access file: " + unFinishedFile.toString() + ". File will not be deleted due to: " + e.getMessage());
+            Logger.log(LogTag.JFR, LogLevel.ERROR, () -> "Could not close random access file: " + chunkFile.toString() + ". File will not be deleted due to: " + e.getMessage());
         }
     }
 
@@ -181,17 +164,14 @@
 
     @Override
     public String toString() {
-        if (isFinished()) {
-            return file.toString();
-        }
-        return unFinishedFile.toString();
+        return chunkFile.toString();
     }
 
     ReadableByteChannel newChannel() throws IOException {
         if (!isFinished()) {
             throw new IOException("Chunk not finished");
         }
-        return ((SecuritySupport.newFileChannelToRead(file)));
+        return ((SecuritySupport.newFileChannelToRead(chunkFile)));
     }
 
     public boolean inInterval(Instant startTime, Instant endTime) {
@@ -205,6 +185,6 @@
     }
 
     public SafePath getFile() {
-        return file;
+        return chunkFile;
     }
 }
--- a/src/jdk.jfr/share/classes/jdk/jfr/internal/Utils.java	Fri May 08 09:45:57 2020 +0530
+++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/Utils.java	Fri May 08 09:52:42 2020 +0530
@@ -180,6 +180,30 @@
         return String.format("%d%s%s", value, separation, result.text);
     }
 
+    // This method reduces the number of loaded classes
+    // compared to DateTimeFormatter
+    static String formatDateTime(LocalDateTime time) {
+        StringBuilder sb = new StringBuilder(19);
+        sb.append(time.getYear() / 100);
+        appendPadded(sb, time.getYear() % 100, true);
+        appendPadded(sb, time.getMonth().getValue(), true);
+        appendPadded(sb, time.getDayOfMonth(), true);
+        appendPadded(sb, time.getHour(), true);
+        appendPadded(sb, time.getMinute(), true);
+        appendPadded(sb, time.getSecond(), false);
+        return sb.toString();
+    }
+
+    private static void appendPadded(StringBuilder text, int number, boolean separator) {
+        if (number < 10) {
+            text.append('0');
+        }
+        text.append(number);
+        if (separator) {
+            text.append('_');
+        }
+    }
+
     public static long parseTimespanWithInfinity(String s) {
         if (INFINITY.equals(s)) {
             return Long.MAX_VALUE;
@@ -604,7 +628,7 @@
 
     public static String makeFilename(Recording recording) {
         String pid = JVM.getJVM().getPid();
-        String date = Repository.REPO_DATE_FORMAT.format(LocalDateTime.now());
+        String date = formatDateTime(LocalDateTime.now());
         String idText = recording == null ? "" :  "-id-" + Long.toString(recording.getId());
         return "hotspot-" + "pid-" + pid + idText + "-" + date + ".jfr";
     }
--- a/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/DirArchive.java	Fri May 08 09:45:57 2020 +0530
+++ b/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/DirArchive.java	Fri May 08 09:52:42 2020 +0530
@@ -153,4 +153,20 @@
     private static String getPathName(Path path) {
         return path.toString().replace(File.separatorChar, '/');
     }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(dirPath, moduleName);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (obj instanceof DirArchive) {
+            DirArchive other = (DirArchive)obj;
+            return Objects.equals(dirPath, other.dirPath) &&
+                   Objects.equals(moduleName, other.moduleName);
+        }
+
+        return false;
+    }
 }
--- a/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/JarArchive.java	Fri May 08 09:45:57 2020 +0530
+++ b/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/JarArchive.java	Fri May 08 09:52:42 2020 +0530
@@ -133,4 +133,21 @@
     protected JarFile getJarFile() {
         return jarFile;
     }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(file, moduleName, version);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (obj instanceof JarArchive) {
+            JarArchive other = (JarArchive)obj;
+            return Objects.equals(file, other.file) &&
+                   Objects.equals(moduleName, other.moduleName) &&
+                   Objects.equals(version, other.version);
+        }
+
+        return false;
+    }
 }
--- a/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/JmodArchive.java	Fri May 08 09:45:57 2020 +0530
+++ b/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/JmodArchive.java	Fri May 08 09:52:42 2020 +0530
@@ -174,4 +174,20 @@
 
         return new JmodEntry(path, resourceName, type, entry);
     }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(file, moduleName);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (obj instanceof JmodArchive) {
+            JmodArchive other = (JmodArchive)obj;
+            return Objects.equals(file, other.file) &&
+                   Objects.equals(moduleName, other.moduleName);
+        }
+
+        return false;
+    }
 }
--- a/test/hotspot/jtreg/ProblemList.txt	Fri May 08 09:45:57 2020 +0530
+++ b/test/hotspot/jtreg/ProblemList.txt	Fri May 08 09:52:42 2020 +0530
@@ -95,6 +95,7 @@
 
 runtime/jni/terminatedThread/TestTerminatedThread.java 8219652 aix-ppc64
 runtime/ReservedStack/ReservedStackTest.java 8231031 generic-all
+runtime/cds/DeterministicDump.java 8244536 windows-all 
 
 #############################################################################
 
--- a/test/hotspot/jtreg/TEST.groups	Fri May 08 09:45:57 2020 +0530
+++ b/test/hotspot/jtreg/TEST.groups	Fri May 08 09:52:42 2020 +0530
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2013, 2020, 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
@@ -348,7 +348,8 @@
   runtime/modules/PatchModule/PatchModuleCDS.java \
   runtime/modules/PatchModule/PatchModuleClassList.java \
   runtime/NMT \
-  serviceability/sa
+  serviceability/sa \
+ -runtime/cds/DeterministicDump.java
 
 # A subset of AppCDS tests to be run in tier1
 tier1_runtime_appcds = \
@@ -376,17 +377,15 @@
  -runtime/cds/appcds/jigsaw/modulepath/MainModuleOnly.java
 
 tier1_serviceability = \
-  serviceability/dcmd/compiler \
+  serviceability/ \
   -serviceability/dcmd/compiler/CompilerQueueTest.java \
-  serviceability/jvmti/RedefineClasses \
   -serviceability/jvmti/RedefineClasses/RedefineLeak.java \
   -serviceability/jvmti/RedefineClasses/RedefinePreviousVersions.java \
   -serviceability/jvmti/RedefineClasses/RedefineRunningMethods.java \
   -serviceability/jvmti/RedefineClasses/RedefineRunningMethodsWithBacktrace.java \
   -serviceability/jvmti/RedefineClasses/TestRedefineObject.java \
-  serviceability/logging \
-  serviceability/sa \
   -serviceability/sa/ClhsdbScanOops.java \
+  -serviceability/sa/ClhsdbJstackXcompStress.java \
   -serviceability/sa/TestJmapCore.java \
   -serviceability/sa/TestJmapCoreMetaspace.java
 
--- a/test/hotspot/jtreg/compiler/aot/verification/ClassAndLibraryNotMatchTest.java	Fri May 08 09:45:57 2020 +0530
+++ b/test/hotspot/jtreg/compiler/aot/verification/ClassAndLibraryNotMatchTest.java	Fri May 08 09:52:42 2020 +0530
@@ -92,7 +92,7 @@
     private void runAndCheckHelloWorld(String checkString) {
         ProcessBuilder pb;
         try {
-            pb = ProcessTools.createJavaProcessBuilder(true, "-cp", ".",
+            pb = ProcessTools.createTestJvm("-cp", ".",
                     "-XX:+UnlockExperimentalVMOptions", "-XX:+UseAOT",
                     "-XX:AOTLibrary=./" + LIB_NAME, HELLO_WORLD_CLASS_NAME);
         } catch (Exception e) {
--- a/test/hotspot/jtreg/compiler/aot/verification/vmflags/BasicFlagsChange.java	Fri May 08 09:45:57 2020 +0530
+++ b/test/hotspot/jtreg/compiler/aot/verification/vmflags/BasicFlagsChange.java	Fri May 08 09:52:42 2020 +0530
@@ -87,7 +87,7 @@
                so, a message like "skipped $pathTolibrary aot library" or
                "loaded    $pathToLibrary  aot library" is present for cases of
                incompatible or compatible flags respectively */
-            pb = ProcessTools.createJavaProcessBuilder(true, "-XX:+UnlockExperimentalVMOptions",
+            pb = ProcessTools.createTestJvm("-XX:+UnlockExperimentalVMOptions",
                     "-XX:+UseAOT", "-XX:+PrintAOT", "-XX:AOTLibrary=./" + libName, option,
                     HelloWorldPrinter.class.getName());
         } catch (Exception ex) {
--- a/test/hotspot/jtreg/compiler/ciReplay/CiReplayBase.java	Fri May 08 09:45:57 2020 +0530
+++ b/test/hotspot/jtreg/compiler/ciReplay/CiReplayBase.java	Fri May 08 09:52:42 2020 +0530
@@ -142,11 +142,10 @@
             options.add(needCoreDump ? ENABLE_COREDUMP_ON_CRASH : DISABLE_COREDUMP_ON_CRASH);
             options.add(EmptyMain.class.getName());
             if (needCoreDump) {
-                crashOut = ProcessTools.executeProcess(getTestJavaCommandlineWithPrefix(
+                crashOut = ProcessTools.executeProcess(getTestJvmCommandlineWithPrefix(
                         RUN_SHELL_NO_LIMIT, options.toArray(new String[0])));
             } else {
-                crashOut = ProcessTools.executeProcess(ProcessTools.createJavaProcessBuilder(true,
-                        options));
+                crashOut = ProcessTools.executeProcess(ProcessTools.createTestJvm(options));
             }
             crashOutputString = crashOut.getOutput();
             Asserts.assertNotEquals(crashOut.getExitValue(), 0, "Crash JVM exits gracefully");
@@ -190,7 +189,7 @@
             List<String> allAdditionalOpts = new ArrayList<>();
             allAdditionalOpts.addAll(Arrays.asList(REPLAY_OPTIONS));
             allAdditionalOpts.addAll(Arrays.asList(additionalVmOpts));
-            OutputAnalyzer oa = ProcessTools.executeProcess(getTestJavaCommandlineWithPrefix(
+            OutputAnalyzer oa = ProcessTools.executeProcess(getTestJvmCommandlineWithPrefix(
                     RUN_SHELL_ZERO_LIMIT, allAdditionalOpts.toArray(new String[0])));
             return oa.getExitValue();
         } catch (Throwable t) {
@@ -290,9 +289,9 @@
         return null;
     }
 
-    private String[] getTestJavaCommandlineWithPrefix(String prefix, String... args) {
+    private String[] getTestJvmCommandlineWithPrefix(String prefix, String... args) {
         try {
-            String cmd = ProcessTools.getCommandLine(ProcessTools.createJavaProcessBuilder(true, args));
+            String cmd = ProcessTools.getCommandLine(ProcessTools.createTestJvm(args));
             return new String[]{"sh", "-c", prefix
                 + (Platform.isWindows() ? cmd.replace('\\', '/').replace(";", "\\;").replace("|", "\\|") : cmd)};
         } catch(Throwable t) {
--- a/test/hotspot/jtreg/compiler/ciReplay/SABase.java	Fri May 08 09:45:57 2020 +0530
+++ b/test/hotspot/jtreg/compiler/ciReplay/SABase.java	Fri May 08 09:52:42 2020 +0530
@@ -57,7 +57,7 @@
         }
         ProcessBuilder pb;
         try {
-            pb = ProcessTools.createJavaProcessBuilder(true, "--add-modules", "jdk.hotspot.agent",
+            pb = ProcessTools.createTestJvm("--add-modules", "jdk.hotspot.agent",
                    "--add-exports=jdk.hotspot.agent/sun.jvm.hotspot=ALL-UNNAMED",
                     "sun.jvm.hotspot.CLHSDB", JDKToolFinder.getTestJDKTool("java"),
                     TEST_CORE_FILE_NAME);
--- a/test/hotspot/jtreg/compiler/classUnloading/methodUnloading/TestOverloadCompileQueues.java	Fri May 08 09:45:57 2020 +0530
+++ b/test/hotspot/jtreg/compiler/classUnloading/methodUnloading/TestOverloadCompileQueues.java	Fri May 08 09:52:42 2020 +0530
@@ -23,12 +23,12 @@
 
 /*
  * @test TestOverloadCompileQueues
- * @bug 8163511
+ * @bug 8163511 8230402
  * @summary Test overloading the C1 and C2 compile queues with tasks.
  * @requires !vm.graal.enabled
- * @run main/othervm -XX:-TieredCompilation -XX:CompileThreshold=2 -XX:CICompilerCount=1
+ * @run main/othervm/timeout=300 -XX:-TieredCompilation -XX:CompileThreshold=2 -XX:CICompilerCount=1
  *                   compiler.classUnloading.methodUnloading.TestOverloadCompileQueues
- * @run main/othervm -XX:TieredCompileTaskTimeout=1000 -XX:CompileThresholdScaling=0.001 -XX:CICompilerCount=2
+ * @run main/othervm/timeout=300 -XX:TieredCompileTaskTimeout=1000 -XX:CompileThresholdScaling=0.001 -XX:CICompilerCount=2
  *                   compiler.classUnloading.methodUnloading.TestOverloadCompileQueues
  */
 
@@ -37,9 +37,13 @@
 import java.lang.reflect.Method;
 import java.net.URL;
 import java.net.URLClassLoader;
+import java.util.Arrays;
 
 public class TestOverloadCompileQueues {
     public static final int ITERS = 500; // Increase for longer stress testing
+    public static final int ITERS_A = 1000; // Increase for longer stress testing
+
+    public static int iArr[] = new int[100];
 
     // Some methods to fill up the compile queue
     public static void test0() { }
@@ -63,7 +67,65 @@
     public static void test18() { }
     public static void test19() { }
 
+    // More methods that do some more complex things. Therefore, the compiler needs to spend some more time compiling them.
+    // With 50 methods, a queue size of 10000 is also reached in the second run with TieredCompilation enabled.
+    public static void testA0()  { Arrays.sort(iArr); }
+    public static void testA1()  { Arrays.sort(iArr); }
+    public static void testA2()  { Arrays.sort(iArr); }
+    public static void testA3()  { Arrays.sort(iArr); }
+    public static void testA4()  { Arrays.sort(iArr); }
+    public static void testA5()  { Arrays.sort(iArr); }
+    public static void testA6()  { Arrays.sort(iArr); }
+    public static void testA7()  { Arrays.sort(iArr); }
+    public static void testA8()  { Arrays.sort(iArr); }
+    public static void testA9()  { Arrays.sort(iArr); }
+    public static void testA10() { Arrays.sort(iArr); }
+    public static void testA11() { Arrays.sort(iArr); }
+    public static void testA12() { Arrays.sort(iArr); }
+    public static void testA13() { Arrays.sort(iArr); }
+    public static void testA14() { Arrays.sort(iArr); }
+    public static void testA15() { Arrays.sort(iArr); }
+    public static void testA16() { Arrays.sort(iArr); }
+    public static void testA17() { Arrays.sort(iArr); }
+    public static void testA18() { Arrays.sort(iArr); }
+    public static void testA19() { Arrays.sort(iArr); }
+    public static void testA20() { Arrays.sort(iArr); }
+    public static void testA21() { Arrays.sort(iArr); }
+    public static void testA22() { Arrays.sort(iArr); }
+    public static void testA23() { Arrays.sort(iArr); }
+    public static void testA24() { Arrays.sort(iArr); }
+    public static void testA25() { Arrays.sort(iArr); }
+    public static void testA26() { Arrays.sort(iArr); }
+    public static void testA27() { Arrays.sort(iArr); }
+    public static void testA28() { Arrays.sort(iArr); }
+    public static void testA29() { Arrays.sort(iArr); }
+    public static void testA30() { Arrays.sort(iArr); }
+    public static void testA31() { Arrays.sort(iArr); }
+    public static void testA32() { Arrays.sort(iArr); }
+    public static void testA33() { Arrays.sort(iArr); }
+    public static void testA34() { Arrays.sort(iArr); }
+    public static void testA35() { Arrays.sort(iArr); }
+    public static void testA36() { Arrays.sort(iArr); }
+    public static void testA37() { Arrays.sort(iArr); }
+    public static void testA38() { Arrays.sort(iArr); }
+    public static void testA39() { Arrays.sort(iArr); }
+    public static void testA40() { Arrays.sort(iArr); }
+    public static void testA41() { Arrays.sort(iArr); }
+    public static void testA42() { Arrays.sort(iArr); }
+    public static void testA43() { Arrays.sort(iArr); }
+    public static void testA44() { Arrays.sort(iArr); }
+    public static void testA45() { Arrays.sort(iArr); }
+    public static void testA46() { Arrays.sort(iArr); }
+    public static void testA47() { Arrays.sort(iArr); }
+    public static void testA48() { Arrays.sort(iArr); }
+    public static void testA49() { Arrays.sort(iArr); }
+
     public static void main(String[] args) throws Throwable {
+        run();
+        runA();
+    }
+
+    public static void run() throws Throwable {
         Class<?> thisClass = TestOverloadCompileQueues.class;
         ClassLoader defaultLoader = thisClass.getClassLoader();
         URL classesDir = thisClass.getProtectionDomain().getCodeSource().getLocation();
@@ -84,4 +146,23 @@
             System.gc();
         }
     }
+
+    public static void runA() throws Throwable {
+        Class<?> thisClass = TestOverloadCompileQueues.class;
+        ClassLoader defaultLoader = thisClass.getClassLoader();
+        URL classesDir = thisClass.getProtectionDomain().getCodeSource().getLocation();
+
+        for (int i = 0; i < ITERS_A; ++i) {
+            // Load test class with own class loader
+            URLClassLoader myLoader = URLClassLoader.newInstance(new URL[] {classesDir}, defaultLoader.getParent());
+            Class<?> testClass = Class.forName(thisClass.getCanonicalName(), true, myLoader);
+
+            // Execute all test methods to trigger compilation and fill up compile queue
+            for (int j = 0; j < 50; ++j) {
+                Method method = testClass.getDeclaredMethod("testA" + j);
+                method.invoke(null);
+                method.invoke(null);
+            }
+        }
+    }
 }
--- a/test/hotspot/jtreg/compiler/graalunit/common/GraalUnitTestLauncher.java	Fri May 08 09:45:57 2020 +0530
+++ b/test/hotspot/jtreg/compiler/graalunit/common/GraalUnitTestLauncher.java	Fri May 08 09:52:42 2020 +0530
@@ -113,7 +113,7 @@
         String classPath = String.join(File.pathSeparator, System.getProperty("java.class.path"),
                 String.join(File.separator, libsDir, MXTOOL_JARFILE));
 
-        ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(false,
+        ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
                 "-cp",  classPath,
                 "com.oracle.mxtool.junit.FindClassesByAnnotatedMethods", graalUnitTestFilePath, testAnnotationName);
 
@@ -277,8 +277,7 @@
 
         javaFlags.add("@"+GENERATED_TESTCLASSES_FILENAME);
 
-        ProcessBuilder javaPB = ProcessTools.createJavaProcessBuilder(true,
-                javaFlags);
+        ProcessBuilder javaPB = ProcessTools.createTestJvm(javaFlags);
 
         // Some tests rely on MX_SUBPROCESS_COMMAND_FILE env variable which contains
         // name of the file with java executable and java args used to launch the current process.
--- a/test/hotspot/jtreg/compiler/runtime/cr8015436/Driver8015436.java	Fri May 08 09:45:57 2020 +0530
+++ b/test/hotspot/jtreg/compiler/runtime/cr8015436/Driver8015436.java	Fri May 08 09:52:42 2020 +0530
@@ -30,8 +30,8 @@
     public static void main(String args[]) {
         OutputAnalyzer oa;
         try {
-            oa = ProcessTools.executeProcess(ProcessTools.createJavaProcessBuilder(
-                    /* add test vm options */ true, Test8015436.class.getName()));
+            oa = ProcessTools.executeProcess(ProcessTools.createTestJvm(
+                    Test8015436.class.getName()));
         } catch (Exception ex) {
             throw new Error("TESTBUG: exception while running child process: " + ex, ex);
         }
--- a/test/hotspot/jtreg/compiler/types/correctness/OffTest.java	Fri May 08 09:45:57 2020 +0530
+++ b/test/hotspot/jtreg/compiler/types/correctness/OffTest.java	Fri May 08 09:52:42 2020 +0530
@@ -86,7 +86,7 @@
         OPTIONS[TYPE_PROFILE_INDEX] = typeProfileLevel;
         OPTIONS[USE_TYPE_SPECULATION_INDEX] = useTypeSpeculation;
         OPTIONS[PROFILING_TYPE_INDEX] = type.name();
-        ProcessBuilder processBuilder = ProcessTools.createJavaProcessBuilder(/* addTestVmOptions= */ true, OPTIONS);
+        ProcessBuilder processBuilder = ProcessTools.createTestJvm(OPTIONS);
         OutputAnalyzer outputAnalyzer = new OutputAnalyzer(processBuilder.start());
         outputAnalyzer.shouldHaveExitValue(0);
     }
--- a/test/hotspot/jtreg/gc/TestAllocateHeapAt.java	Fri May 08 09:45:57 2020 +0530
+++ b/test/hotspot/jtreg/gc/TestAllocateHeapAt.java	Fri May 08 09:52:42 2020 +0530
@@ -40,8 +40,7 @@
 
 public class TestAllocateHeapAt {
   public static void main(String args[]) throws Exception {
-    ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
-        true,
+    ProcessBuilder pb = ProcessTools.createTestJvm(
         "-XX:AllocateHeapAt=" + System.getProperty("test.dir", "."),
         "-Xlog:gc+heap=info",
         "-Xmx32m",
--- a/test/hotspot/jtreg/gc/TestAllocateHeapAtError.java	Fri May 08 09:45:57 2020 +0530
+++ b/test/hotspot/jtreg/gc/TestAllocateHeapAtError.java	Fri May 08 09:52:42 2020 +0530
@@ -46,8 +46,7 @@
       f = new File(test_dir, UUID.randomUUID().toString());
     } while(f.exists());
 
-    ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
-        true,
+    ProcessBuilder pb = ProcessTools.createTestJvm(
         "-XX:AllocateHeapAt=" + f.getName(),
         "-Xlog:gc+heap=info",
         "-Xmx32m",
--- a/test/hotspot/jtreg/gc/TestAllocateHeapAtMultiple.java	Fri May 08 09:45:57 2020 +0530
+++ b/test/hotspot/jtreg/gc/TestAllocateHeapAtMultiple.java	Fri May 08 09:52:42 2020 +0530
@@ -62,7 +62,7 @@
                                               "-Xlog:gc+heap=info",
                                               "-version"});
 
-      ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(true, flags);
+      ProcessBuilder pb = ProcessTools.createTestJvm(flags);
       OutputAnalyzer output = new OutputAnalyzer(pb.start());
 
       System.out.println("Output:\n" + output.getOutput());
--- a/test/hotspot/jtreg/gc/TestVerifyDuringStartup.java	Fri May 08 09:45:57 2020 +0530
+++ b/test/hotspot/jtreg/gc/TestVerifyDuringStartup.java	Fri May 08 09:52:42 2020 +0530
@@ -38,8 +38,7 @@
 
 public class TestVerifyDuringStartup {
   public static void main(String args[]) throws Exception {
-    ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
-        true,
+    ProcessBuilder pb = ProcessTools.createTestJvm(
         "-XX:-UseTLAB",
         "-XX:+UnlockDiagnosticVMOptions",
         "-XX:+VerifyDuringStartup",
--- a/test/hotspot/jtreg/gc/arguments/GCArguments.java	Fri May 08 09:45:57 2020 +0530
+++ b/test/hotspot/jtreg/gc/arguments/GCArguments.java	Fri May 08 09:52:42 2020 +0530
@@ -67,22 +67,18 @@
     }
 
     static public ProcessBuilder createJavaProcessBuilder(List<String> arguments) {
-        return createJavaProcessBuilder(false, arguments);
-    }
-
-    static public ProcessBuilder createJavaProcessBuilder(boolean addTestVmAndJavaOptions,
-                                                          List<String> arguments) {
-        return createJavaProcessBuilder(addTestVmAndJavaOptions,
-                                        arguments.toArray(String[]::new));
+        return createJavaProcessBuilder(arguments.toArray(String[]::new));
     }
 
     static public ProcessBuilder createJavaProcessBuilder(String... arguments) {
-        return createJavaProcessBuilder(false, arguments);
+        return ProcessTools.createJavaProcessBuilder(withDefaults(arguments));
     }
 
-    static public ProcessBuilder createJavaProcessBuilder(boolean addTestVmAndJavaOptions,
-                                                          String... arguments) {
-        return ProcessTools.createJavaProcessBuilder(addTestVmAndJavaOptions,
-                                                     withDefaults(arguments));
+    static public ProcessBuilder createTestJvm(List<String> arguments) {
+        return createTestJvm(arguments.toArray(String[]::new));
+    }
+
+    static public ProcessBuilder createTestJvm(String... arguments) {
+        return ProcessTools.createTestJvm(withDefaults(arguments));
     }
 }
--- a/test/hotspot/jtreg/gc/arguments/TestUseNUMAInterleaving.java	Fri May 08 09:45:57 2020 +0530
+++ b/test/hotspot/jtreg/gc/arguments/TestUseNUMAInterleaving.java	Fri May 08 09:52:42 2020 +0530
@@ -41,8 +41,7 @@
 public class TestUseNUMAInterleaving {
 
     public static void main(String[] args) throws Exception {
-        ProcessBuilder pb = GCArguments.createJavaProcessBuilder(
-            true,
+        ProcessBuilder pb = GCArguments.createTestJvm(
             "-XX:+UseNUMA",
             "-XX:+PrintFlagsFinal",
             "-version");
--- a/test/hotspot/jtreg/gc/g1/TestShrinkAuxiliaryData.java	Fri May 08 09:45:57 2020 +0530
+++ b/test/hotspot/jtreg/gc/g1/TestShrinkAuxiliaryData.java	Fri May 08 09:52:42 2020 +0530
@@ -102,7 +102,7 @@
     }
 
     private void performTest(List<String> opts) throws Exception {
-        ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(true, opts);
+        ProcessBuilder pb = ProcessTools.createTestJvm(opts);
 
         OutputAnalyzer output = new OutputAnalyzer(pb.start());
         System.out.println(output.getStdout());
--- a/test/hotspot/jtreg/gc/g1/mixedgc/TestLogging.java	Fri May 08 09:45:57 2020 +0530
+++ b/test/hotspot/jtreg/gc/g1/mixedgc/TestLogging.java	Fri May 08 09:52:42 2020 +0530
@@ -90,8 +90,7 @@
         Collections.addAll(testOpts, extraFlags);
         testOpts.add(RunMixedGC.class.getName());
         System.out.println(testOpts);
-        ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(false,
-                testOpts);
+        ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(testOpts);
         return new OutputAnalyzer(pb.start());
     }
 }
--- a/test/hotspot/jtreg/gc/logging/TestMetaSpaceLog.java	Fri May 08 09:45:57 2020 +0530
+++ b/test/hotspot/jtreg/gc/logging/TestMetaSpaceLog.java	Fri May 08 09:52:42 2020 +0530
@@ -84,8 +84,7 @@
     String testSrc= "-Dtest.src=" + System.getProperty("test.src", ".");
 
     ProcessBuilder pb =
-      ProcessTools.createJavaProcessBuilder(
-          true,
+      ProcessTools.createTestJvm(
           "-Xlog:gc*",
           "-Xbootclasspath/a:.",
           "-XX:+UnlockDiagnosticVMOptions",
--- a/test/hotspot/jtreg/gc/metaspace/CompressedClassSpaceSizeInJmapHeap.java	Fri May 08 09:45:57 2020 +0530
+++ b/test/hotspot/jtreg/gc/metaspace/CompressedClassSpaceSizeInJmapHeap.java	Fri May 08 09:52:42 2020 +0530
@@ -36,7 +36,6 @@
  */
 
 import jdk.test.lib.JDKToolLauncher;
-import jdk.test.lib.Platform;
 import jdk.test.lib.process.OutputAnalyzer;
 import jdk.test.lib.process.ProcessTools;
 import jdk.test.lib.SA.SATestUtils;
@@ -50,11 +49,6 @@
     public static void main(String[] args) throws Exception {
         SATestUtils.skipIfCannotAttach(); // throws SkippedException if attach not expected to work.
 
-        if (!Platform.is64bit()) {
-            // Compressed Class Space is only available on 64-bit JVMs
-            return;
-        }
-
         String pid = Long.toString(ProcessTools.getProcessId());
 
         JDKToolLauncher jmap = JDKToolLauncher.create("jhsdb")
--- a/test/hotspot/jtreg/gc/metaspace/TestCapacityUntilGCWrapAround.java	Fri May 08 09:45:57 2020 +0530
+++ b/test/hotspot/jtreg/gc/metaspace/TestCapacityUntilGCWrapAround.java	Fri May 08 09:52:42 2020 +0530
@@ -30,6 +30,7 @@
  * @library /test/lib
  * @modules java.base/jdk.internal.misc
  *          java.management
+ * @requires vm.bits == 32
  * @build sun.hotspot.WhiteBox
  * @run driver ClassFileInstaller sun.hotspot.WhiteBox
  * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI gc.metaspace.TestCapacityUntilGCWrapAround
@@ -38,7 +39,6 @@
 import sun.hotspot.WhiteBox;
 
 import jdk.test.lib.Asserts;
-import jdk.test.lib.Platform;
 
 public class TestCapacityUntilGCWrapAround {
     private static long MB = 1024 * 1024;
@@ -46,17 +46,15 @@
     private static long MAX_UINT = 4 * GB - 1; // On 32-bit platforms
 
     public static void main(String[] args) {
-        if (Platform.is32bit()) {
-            WhiteBox wb = WhiteBox.getWhiteBox();
+        WhiteBox wb = WhiteBox.getWhiteBox();
 
-            long before = wb.metaspaceCapacityUntilGC();
-            // Now force possible overflow of capacity_until_GC.
-            long after = wb.incMetaspaceCapacityUntilGC(MAX_UINT);
+        long before = wb.metaspaceCapacityUntilGC();
+        // Now force possible overflow of capacity_until_GC.
+        long after = wb.incMetaspaceCapacityUntilGC(MAX_UINT);
 
-            Asserts.assertGTE(after, before,
-                              "Increasing with MAX_UINT should not cause wrap around: " + after + " < " + before);
-            Asserts.assertLTE(after, MAX_UINT,
-                              "Increasing with MAX_UINT should not cause value larger than MAX_UINT:" + after);
-        }
+        Asserts.assertGTE(after, before,
+                          "Increasing with MAX_UINT should not cause wrap around: " + after + " < " + before);