merge JDK-8200758-branch
authorherrick
Mon, 18 Nov 2019 12:40:06 -0500
branchJDK-8200758-branch
changeset 59127 4ad81e9e30fd
parent 59126 4d58a35f3cfa (current diff)
parent 59125 5ac4a49f5399 (diff)
child 59159 d1fe86ccc832
merge
test/jdk/sun/security/tools/keytool/DeprecateKeyalg.java
--- a/.hgtags	Wed Nov 13 17:21:31 2019 -0500
+++ b/.hgtags	Mon Nov 18 12:40:06 2019 -0500
@@ -595,3 +595,4 @@
 54ffb15c48399dd59922ee22bb592d815307e77c jdk-14+20
 c16ac7a2eba4e73cb4f7ee9294dd647860eebff0 jdk-14+21
 83810b7d12e7ff761ad3dd91f323a22dad96f108 jdk-14+22
+15936b142f86731afa4b1a2c0fe4a01e806c4944 jdk-14+23
--- a/make/RunTests.gmk	Wed Nov 13 17:21:31 2019 -0500
+++ b/make/RunTests.gmk	Mon Nov 18 12:40:06 2019 -0500
@@ -247,11 +247,29 @@
       CORES_DIVIDER := 4
     endif
   endif
+  # For some big multi-core machines with low ulimit -u setting we hit the max
+  # threads/process limit. In such a setup the memory/cores-only-guided
+  # TEST_JOBS config is insufficient. From experience a concurrency setting of
+  # 14 works reasonably well for low ulimit values (<= 4096). Thus, use
+  # divider 4096/14. For high ulimit -u values this shouldn't make a difference.
+  ULIMIT_DIVIDER := (4096/14)
+  PROC_ULIMIT := -1
+  ifneq ($(OPENJDK_TARGET_OS), windows)
+    PROC_ULIMIT := $(shell $(ULIMIT) -u)
+    ifeq ($(PROC_ULIMIT), unlimited)
+      PROC_ULIMIT := -1
+    endif
+  endif
   MEMORY_DIVIDER := 2048
   TEST_JOBS := $(shell $(AWK) \
     'BEGIN { \
       c = $(NUM_CORES) / $(CORES_DIVIDER); \
       m = $(MEMORY_SIZE) / $(MEMORY_DIVIDER); \
+      u = $(PROC_ULIMIT); \
+      if (u > -1) { \
+        u = u / $(ULIMIT_DIVIDER); \
+        if (u < c) c = u; \
+      } \
       if (c > m) c = m; \
       c = c * $(TEST_JOBS_FACTOR); \
       c = c * $(TEST_JOBS_FACTOR_JDL); \
--- a/make/RunTestsPrebuiltSpec.gmk	Wed Nov 13 17:21:31 2019 -0500
+++ b/make/RunTestsPrebuiltSpec.gmk	Mon Nov 18 12:40:06 2019 -0500
@@ -175,6 +175,7 @@
 EXPR := expr
 FILE := file
 HG := hg
+ULIMIT := ulimit
 
 # On Solaris gnu versions of some tools are required.
 ifeq ($(OPENJDK_BUILD_OS), solaris)
--- a/make/autoconf/basics.m4	Wed Nov 13 17:21:31 2019 -0500
+++ b/make/autoconf/basics.m4	Mon Nov 18 12:40:06 2019 -0500
@@ -574,6 +574,26 @@
 ])
 
 ###############################################################################
+# Like BASIC_REQUIRE_PROGS but also allows for bash built-ins
+# $1: variable to set
+# $2: executable name (or list of names) to look for
+# $3: [path]
+AC_DEFUN([BASIC_REQUIRE_BUILTIN_PROGS],
+[
+  BASIC_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
+      AC_MSG_NOTICE([Found $2 as shell built-in. Using it])
+      $1="$2"
+    else
+      AC_MSG_ERROR([Required tool $2 also not found as built-in.])
+    fi
+  fi
+  BASIC_CHECK_NONEMPTY($1)
+])
+
+###############################################################################
 # Setup the most fundamental tools that relies on not much else to set up,
 # but is used by much of the early bootstrap code.
 AC_DEFUN_ONCE([BASIC_SETUP_FUNDAMENTAL_TOOLS],
@@ -1284,6 +1304,9 @@
   elif test "x$OPENJDK_TARGET_OS" = "xsolaris"; then
     BASIC_REQUIRE_PROGS(ELFEDIT, elfedit)
   fi
+  if ! test "x$OPENJDK_TARGET_OS" = "xwindows"; then
+    BASIC_REQUIRE_BUILTIN_PROGS(ULIMIT, ulimit)
+  fi
 ])
 
 ###############################################################################
--- a/make/autoconf/spec.gmk.in	Wed Nov 13 17:21:31 2019 -0500
+++ b/make/autoconf/spec.gmk.in	Mon Nov 18 12:40:06 2019 -0500
@@ -767,6 +767,7 @@
 XCODEBUILD=@XCODEBUILD@
 DTRACE := @DTRACE@
 FIXPATH:=@FIXPATH@
+ULIMIT:=@ULIMIT@
 
 TAR_TYPE:=@TAR_TYPE@
 TAR_CREATE_EXTRA_PARAM:=@TAR_CREATE_EXTRA_PARAM@
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/make/data/cacerts/luxtrustglobalroot2ca	Mon Nov 18 12:40:06 2019 -0500
@@ -0,0 +1,40 @@
+Owner: CN=LuxTrust Global Root 2, O=LuxTrust S.A., C=LU
+Issuer: CN=LuxTrust Global Root 2, O=LuxTrust S.A., C=LU
+Serial number: a7ea6df4b449eda6a24859ee6b815d3167fbbb1
+Valid from: Thu Mar 05 13:21:57 GMT 2015 until: Mon Mar 05 13:21:57 GMT 2035
+Signature algorithm name: SHA256withRSA
+Subject Public Key Algorithm: 4096-bit RSA key
+Version: 3
+-----BEGIN CERTIFICATE-----
+MIIFwzCCA6ugAwIBAgIUCn6m30tEntpqJIWe5rgV0xZ/u7EwDQYJKoZIhvcNAQEL
+BQAwRjELMAkGA1UEBhMCTFUxFjAUBgNVBAoMDUx1eFRydXN0IFMuQS4xHzAdBgNV
+BAMMFkx1eFRydXN0IEdsb2JhbCBSb290IDIwHhcNMTUwMzA1MTMyMTU3WhcNMzUw
+MzA1MTMyMTU3WjBGMQswCQYDVQQGEwJMVTEWMBQGA1UECgwNTHV4VHJ1c3QgUy5B
+LjEfMB0GA1UEAwwWTHV4VHJ1c3QgR2xvYmFsIFJvb3QgMjCCAiIwDQYJKoZIhvcN
+AQEBBQADggIPADCCAgoCggIBANeFl78RmOnwYoNMPIf5U2o3C/IPPIfOb9wmKb3F
+ibrJgz337spbxm1Jc7TJRqMbNBM/wYlFV/TZsfs2ZUv7COJIcRHIbjuend+JZTem
+hfY7RBi2xjcwYkSSl2l9QjAk5A0MiWtj3sXh306pFGxT4GHO9hcvHTy95iJMHZP1
+EMShduxq3sVs35a0VkBCwGKSMKEtFZSg0iAGCW5qbeXrt77U8PEVfIvmTroTzEsn
+Xpk8F12PgX8zPU/TPxvsXD/wPEx1bvKm1Z3aLQdjAsZy6ZS8TEmVT4hSyNvoaYL4
+zDRbIvCGp4m9SAptZoFtyMhk+wHh9OHe2Z7d21vUKpkmFRseTJIpgp7VkoGSQXAZ
+96Tlk0u8d2cx3Rz9MXANF5kM+Qw5GSoXtTBxVdUPrljhPS80m8+f9niFwpN6cj5m
+j5wWEWCPnolvZ77gR1o7DJpni89Gxq44o/KnvObWhWszJHAiS8sIm7vI+AIpHb4g
+DEa/a4ebsypmQjVGbKq6rfmYe+lQVRQxv7HaLe2ArWgk+2mr2HETMOZns4dA/Yl+
+8kPREd8vZS9kzl8UubG/Mb2HeFpZZYiq/FkySIbWTLkpS5XTdvN3JW1CHDiDTf2j
+X5t/Lax5Gw5CMZdjpPuKadUiDTSQMC6otOBttpSsvItO13D8xTiOZCXhTTmQzsmH
+hFhxAgMBAAGjgagwgaUwDwYDVR0TAQH/BAUwAwEB/zBCBgNVHSAEOzA5MDcGByuB
+KwEBAQowLDAqBggrBgEFBQcCARYeaHR0cHM6Ly9yZXBvc2l0b3J5Lmx1eHRydXN0
+Lmx1MA4GA1UdDwEB/wQEAwIBBjAfBgNVHSMEGDAWgBT/GCh2+UgFLKGu8SsbK7JT
++Et8szAdBgNVHQ4EFgQU/xgodvlIBSyhrvErGyuyU/hLfLMwDQYJKoZIhvcNAQEL
+BQADggIBAGoZFO1uecEsh9QNcH7X9njJCwROxLHOk3D+sFTAMs2ZMGQXvw/l4jP9
+BzZAcg4atmpZ1gDlaCDdLnINH2pkMSCEfUmmWjfrRcmF9dTHF5kH5ptV5AzoqbTO
+jFu1EVzPig4N1qx3gf4ynCSecs5U89BvolbW7MM3LGVYvlcAGvI1+ut7MV3CwRI9
+loGIlonBWVx65n9wNOeD4rHh4bhY79SV5GCc8JaXcozrhAIuZY+kt9J/Z93I055c
+qqmkoCUUBpvsT34tC38ddfEz2O3OuHVtPlu5mB0xDVbYQw8wkbIEa91WvpWAVWe+
+2M2D2RjuLg+GLZKecBPs3lHJQ3gCpU3I+V/EkVhGFndadKpAvAefMLmx9xIX3eP/
+JEAdemrRTxgKqpAd60Ae36EeRJIQmvKN4dFLRp7oRUKX6kWZ8+xm1QL68qZKJKre
+zrnK+T+Tb/mjuuqlPpmt/f97mfVl7vBZKGfXkJWkE4SphMHozs51k2MavDzq1WQf
+LSoSOcbDWjLtR5EWDrw4wVDej8oqkDQc7kGUnF4ZLvhFSZl0kbAEb+MEWrGrKqv+
+x9CWttrhSmQGbmBNvUJO/3jaJMobtNeWOWyu8Q6qp31IiyBMz2TWuJdGsE7RKlY6
+oJO9r4Ak4Ap+58rVyuiFVdw2KuGUaJPHZnJED4AhMmwlxyOAgwrr
+-----END CERTIFICATE-----
--- a/make/hotspot/lib/CompileJvm.gmk	Wed Nov 13 17:21:31 2019 -0500
+++ b/make/hotspot/lib/CompileJvm.gmk	Mon Nov 18 12:40:06 2019 -0500
@@ -57,7 +57,7 @@
 JVM_EXCLUDE_FILES += args.cc
 JVM_EXCLUDES += adlc
 
-# Needed by vm_version.cpp
+# Needed by abstract_vm_version.cpp
 ifeq ($(call isTargetCpu, x86_64), true)
   OPENJDK_TARGET_CPU_VM_VERSION := amd64
 else ifeq ($(call isTargetCpu, sparcv9), true)
@@ -183,7 +183,7 @@
     EXCLUDE_PATTERNS := $(JVM_EXCLUDE_PATTERNS), \
     EXTRA_OBJECT_FILES := $(DTRACE_EXTRA_OBJECT_FILES), \
     CFLAGS := $(JVM_CFLAGS), \
-    vm_version.cpp_CXXFLAGS := $(CFLAGS_VM_VERSION), \
+    abstract_vm_version.cpp_CXXFLAGS := $(CFLAGS_VM_VERSION), \
     arguments.cpp_CXXFLAGS := $(CFLAGS_VM_VERSION), \
     DISABLED_WARNINGS_gcc := $(DISABLED_WARNINGS_gcc), \
     DISABLED_WARNINGS_clang := $(DISABLED_WARNINGS_clang), \
@@ -206,11 +206,11 @@
     DEFINE_THIS_FILE := false, \
 ))
 
-# Always recompile vm_version.cpp if libjvm needs to be relinked. This ensures
+# Always recompile abstract_vm_version.cpp if libjvm needs to be relinked. This ensures
 # that the internal vm version is updated as it relies on __DATE__ and __TIME__
 # macros.
-VM_VERSION_OBJ := $(JVM_OUTPUTDIR)/objs/vm_version$(OBJ_SUFFIX)
-$(VM_VERSION_OBJ): $(filter-out $(VM_VERSION_OBJ) $(JVM_MAPFILE), \
+ABSTRACT_VM_VERSION_OBJ := $(JVM_OUTPUTDIR)/objs/abstract_vm_version$(OBJ_SUFFIX)
+$(ABSTRACT_VM_VERSION_OBJ): $(filter-out $(ABSTRACT_VM_VERSION_OBJ) $(JVM_MAPFILE), \
     $(BUILD_LIBJVM_TARGET_DEPS))
 
 ifneq ($(GENERATE_COMPILE_COMMANDS_ONLY), true)
--- a/src/hotspot/cpu/aarch64/vm_version_aarch64.cpp	Wed Nov 13 17:21:31 2019 -0500
+++ b/src/hotspot/cpu/aarch64/vm_version_aarch64.cpp	Mon Nov 18 12:40:06 2019 -0500
@@ -30,8 +30,8 @@
 #include "runtime/java.hpp"
 #include "runtime/os.hpp"
 #include "runtime/stubCodeGenerator.hpp"
+#include "runtime/vm_version.hpp"
 #include "utilities/macros.hpp"
-#include "vm_version_aarch64.hpp"
 
 #include OS_HEADER_INLINE(os)
 
--- a/src/hotspot/cpu/aarch64/vm_version_aarch64.hpp	Wed Nov 13 17:21:31 2019 -0500
+++ b/src/hotspot/cpu/aarch64/vm_version_aarch64.hpp	Mon Nov 18 12:40:06 2019 -0500
@@ -26,8 +26,8 @@
 #ifndef CPU_AARCH64_VM_VERSION_AARCH64_HPP
 #define CPU_AARCH64_VM_VERSION_AARCH64_HPP
 
+#include "runtime/abstract_vm_version.hpp"
 #include "runtime/globals_extension.hpp"
-#include "runtime/vm_version.hpp"
 #include "utilities/sizes.hpp"
 
 class VM_Version : public Abstract_VM_Version {
--- a/src/hotspot/cpu/aarch64/vm_version_ext_aarch64.hpp	Wed Nov 13 17:21:31 2019 -0500
+++ b/src/hotspot/cpu/aarch64/vm_version_ext_aarch64.hpp	Mon Nov 18 12:40:06 2019 -0500
@@ -25,8 +25,8 @@
 #ifndef CPU_AARCH64_VM_VERSION_EXT_AARCH64_HPP
 #define CPU_AARCH64_VM_VERSION_EXT_AARCH64_HPP
 
+#include "runtime/vm_version.hpp"
 #include "utilities/macros.hpp"
-#include "vm_version_aarch64.hpp"
 
 class VM_Version_Ext : public VM_Version {
  private:
--- a/src/hotspot/cpu/arm/register_arm.hpp	Wed Nov 13 17:21:31 2019 -0500
+++ b/src/hotspot/cpu/arm/register_arm.hpp	Mon Nov 18 12:40:06 2019 -0500
@@ -26,7 +26,7 @@
 #define CPU_ARM_REGISTER_ARM_HPP
 
 #include "asm/register.hpp"
-#include "vm_version_arm.hpp"
+#include "runtime/vm_version.hpp"
 
 class VMRegImpl;
 typedef VMRegImpl* VMReg;
--- a/src/hotspot/cpu/arm/vm_version_arm.hpp	Wed Nov 13 17:21:31 2019 -0500
+++ b/src/hotspot/cpu/arm/vm_version_arm.hpp	Mon Nov 18 12:40:06 2019 -0500
@@ -25,8 +25,8 @@
 #ifndef CPU_ARM_VM_VERSION_ARM_HPP
 #define CPU_ARM_VM_VERSION_ARM_HPP
 
+#include "runtime/abstract_vm_version.hpp"
 #include "runtime/globals_extension.hpp"
-#include "runtime/vm_version.hpp"
 
 class VM_Version: public Abstract_VM_Version {
   friend class JVMCIVMStructs;
--- a/src/hotspot/cpu/arm/vm_version_arm_32.cpp	Wed Nov 13 17:21:31 2019 -0500
+++ b/src/hotspot/cpu/arm/vm_version_arm_32.cpp	Mon Nov 18 12:40:06 2019 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -29,7 +29,7 @@
 #include "runtime/java.hpp"
 #include "runtime/os.inline.hpp"
 #include "runtime/stubCodeGenerator.hpp"
-#include "vm_version_arm.hpp"
+#include "runtime/vm_version.hpp"
 
 int  VM_Version::_stored_pc_adjustment = 4;
 int  VM_Version::_arm_arch             = 5;
--- a/src/hotspot/cpu/arm/vm_version_ext_arm.hpp	Wed Nov 13 17:21:31 2019 -0500
+++ b/src/hotspot/cpu/arm/vm_version_ext_arm.hpp	Mon Nov 18 12:40:06 2019 -0500
@@ -25,8 +25,8 @@
 #ifndef CPU_ARM_VM_VERSION_EXT_ARM_HPP
 #define CPU_ARM_VM_VERSION_EXT_ARM_HPP
 
+#include "runtime/vm_version.hpp"
 #include "utilities/macros.hpp"
-#include "vm_version_arm.hpp"
 
 class VM_Version_Ext : public VM_Version {
  private:
--- a/src/hotspot/cpu/ppc/vm_version_ext_ppc.hpp	Wed Nov 13 17:21:31 2019 -0500
+++ b/src/hotspot/cpu/ppc/vm_version_ext_ppc.hpp	Mon Nov 18 12:40:06 2019 -0500
@@ -25,8 +25,8 @@
 #ifndef CPU_PPC_VM_VERSION_EXT_PPC_HPP
 #define CPU_PPC_VM_VERSION_EXT_PPC_HPP
 
+#include "runtime/vm_version.hpp"
 #include "utilities/macros.hpp"
-#include "vm_version_ppc.hpp"
 
 #define CPU_INFO        "cpu_info"
 #define CPU_TYPE        "fpu_type"
--- a/src/hotspot/cpu/ppc/vm_version_ppc.cpp	Wed Nov 13 17:21:31 2019 -0500
+++ b/src/hotspot/cpu/ppc/vm_version_ppc.cpp	Mon Nov 18 12:40:06 2019 -0500
@@ -32,10 +32,10 @@
 #include "runtime/java.hpp"
 #include "runtime/os.hpp"
 #include "runtime/stubCodeGenerator.hpp"
+#include "runtime/vm_version.hpp"
 #include "utilities/align.hpp"
 #include "utilities/defaultStream.hpp"
 #include "utilities/globalDefinitions.hpp"
-#include "vm_version_ppc.hpp"
 
 #include <sys/sysinfo.h>
 #if defined(_AIX)
--- a/src/hotspot/cpu/ppc/vm_version_ppc.hpp	Wed Nov 13 17:21:31 2019 -0500
+++ b/src/hotspot/cpu/ppc/vm_version_ppc.hpp	Mon Nov 18 12:40:06 2019 -0500
@@ -26,8 +26,8 @@
 #ifndef CPU_PPC_VM_VERSION_PPC_HPP
 #define CPU_PPC_VM_VERSION_PPC_HPP
 
+#include "runtime/abstract_vm_version.hpp"
 #include "runtime/globals_extension.hpp"
-#include "runtime/vm_version.hpp"
 
 class VM_Version: public Abstract_VM_Version {
 protected:
--- a/src/hotspot/cpu/s390/register_s390.hpp	Wed Nov 13 17:21:31 2019 -0500
+++ b/src/hotspot/cpu/s390/register_s390.hpp	Mon Nov 18 12:40:06 2019 -0500
@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2016, 2017 SAP SE. All rights reserved.
+ * Copyright (c) 2016, 2019 SAP SE. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -27,7 +27,7 @@
 #define CPU_S390_REGISTER_S390_HPP
 
 #include "asm/register.hpp"
-#include "vm_version_s390.hpp"
+#include "runtime/vm_version.hpp"
 
 class Address;
 class VMRegImpl;
--- a/src/hotspot/cpu/s390/vm_version_ext_s390.hpp	Wed Nov 13 17:21:31 2019 -0500
+++ b/src/hotspot/cpu/s390/vm_version_ext_s390.hpp	Mon Nov 18 12:40:06 2019 -0500
@@ -25,8 +25,8 @@
 #ifndef CPU_S390_VM_VERSION_EXT_S390_HPP
 #define CPU_S390_VM_VERSION_EXT_S390_HPP
 
+#include "runtime/vm_version.hpp"
 #include "utilities/macros.hpp"
-#include "vm_version_s390.hpp"
 
 #define CPU_INFO        "cpu_info"
 #define CPU_TYPE        "fpu_type"
--- a/src/hotspot/cpu/s390/vm_version_s390.cpp	Wed Nov 13 17:21:31 2019 -0500
+++ b/src/hotspot/cpu/s390/vm_version_s390.cpp	Mon Nov 18 12:40:06 2019 -0500
@@ -31,7 +31,7 @@
 #include "memory/resourceArea.hpp"
 #include "runtime/java.hpp"
 #include "runtime/stubCodeGenerator.hpp"
-#include "vm_version_s390.hpp"
+#include "runtime/vm_version.hpp"
 
 # include <sys/sysinfo.h>
 
@@ -44,8 +44,8 @@
 unsigned int  VM_Version::_nfeatures                                = 0;
 unsigned int  VM_Version::_ncipher_features                         = 0;
 unsigned int  VM_Version::_nmsgdigest_features                      = 0;
-unsigned int  VM_Version::_Dcache_lineSize                          = 256;
-unsigned int  VM_Version::_Icache_lineSize                          = 256;
+unsigned int  VM_Version::_Dcache_lineSize                          = DEFAULT_CACHE_LINE_SIZE;
+unsigned int  VM_Version::_Icache_lineSize                          = DEFAULT_CACHE_LINE_SIZE;
 
 static const char* z_gen[]     = {"  ",   "G1",   "G2", "G3",    "G4",     "G5",      "G6",   "G7"   };
 static const char* z_machine[] = {"  ", "2064", "2084", "2094",  "2097",   "2817",    "  ",   "2964" };
--- a/src/hotspot/cpu/s390/vm_version_s390.hpp	Wed Nov 13 17:21:31 2019 -0500
+++ b/src/hotspot/cpu/s390/vm_version_s390.hpp	Mon Nov 18 12:40:06 2019 -0500
@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2016, 2018 SAP SE. All rights reserved.
+ * Copyright (c) 2016, 2019 SAP SE. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -27,8 +27,8 @@
 #define CPU_S390_VM_VERSION_S390_HPP
 
 
+#include "runtime/abstract_vm_version.hpp"
 #include "runtime/globals_extension.hpp"
-#include "runtime/vm_version.hpp"
 
 class VM_Version: public Abstract_VM_Version {
 
--- a/src/hotspot/cpu/sparc/vm_version_ext_sparc.hpp	Wed Nov 13 17:21:31 2019 -0500
+++ b/src/hotspot/cpu/sparc/vm_version_ext_sparc.hpp	Mon Nov 18 12:40:06 2019 -0500
@@ -25,8 +25,8 @@
 #ifndef CPU_SPARC_VM_VERSION_EXT_SPARC_HPP
 #define CPU_SPARC_VM_VERSION_EXT_SPARC_HPP
 
+#include "runtime/vm_version.hpp"
 #include "utilities/macros.hpp"
-#include "vm_version_sparc.hpp"
 
 #if defined(SOLARIS)
 #include <kstat.h>
--- a/src/hotspot/cpu/sparc/vm_version_sparc.cpp	Wed Nov 13 17:21:31 2019 -0500
+++ b/src/hotspot/cpu/sparc/vm_version_sparc.cpp	Mon Nov 18 12:40:06 2019 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -32,7 +32,7 @@
 #include "runtime/java.hpp"
 #include "runtime/os.hpp"
 #include "runtime/stubCodeGenerator.hpp"
-#include "vm_version_sparc.hpp"
+#include "runtime/vm_version.hpp"
 
 #include <sys/mman.h>
 
--- a/src/hotspot/cpu/sparc/vm_version_sparc.hpp	Wed Nov 13 17:21:31 2019 -0500
+++ b/src/hotspot/cpu/sparc/vm_version_sparc.hpp	Mon Nov 18 12:40:06 2019 -0500
@@ -25,8 +25,8 @@
 #ifndef CPU_SPARC_VM_VERSION_SPARC_HPP
 #define CPU_SPARC_VM_VERSION_SPARC_HPP
 
+#include "runtime/abstract_vm_version.hpp"
 #include "runtime/globals_extension.hpp"
-#include "runtime/vm_version.hpp"
 
 class VM_Version: public Abstract_VM_Version {
   friend class VMStructs;
--- a/src/hotspot/cpu/x86/assembler_x86.hpp	Wed Nov 13 17:21:31 2019 -0500
+++ b/src/hotspot/cpu/x86/assembler_x86.hpp	Mon Nov 18 12:40:06 2019 -0500
@@ -26,7 +26,7 @@
 #define CPU_X86_ASSEMBLER_X86_HPP
 
 #include "asm/register.hpp"
-#include "vm_version_x86.hpp"
+#include "runtime/vm_version.hpp"
 
 class BiasedLockingCounters;
 
--- a/src/hotspot/cpu/x86/sharedRuntime_x86_32.cpp	Wed Nov 13 17:21:31 2019 -0500
+++ b/src/hotspot/cpu/x86/sharedRuntime_x86_32.cpp	Mon Nov 18 12:40:06 2019 -0500
@@ -38,6 +38,7 @@
 #include "runtime/safepointMechanism.hpp"
 #include "runtime/sharedRuntime.hpp"
 #include "runtime/vframeArray.hpp"
+#include "runtime/vm_version.hpp"
 #include "utilities/align.hpp"
 #include "vmreg_x86.inline.hpp"
 #ifdef COMPILER1
@@ -46,7 +47,6 @@
 #ifdef COMPILER2
 #include "opto/runtime.hpp"
 #endif
-#include "vm_version_x86.hpp"
 
 #define __ masm->
 
--- a/src/hotspot/cpu/x86/sharedRuntime_x86_64.cpp	Wed Nov 13 17:21:31 2019 -0500
+++ b/src/hotspot/cpu/x86/sharedRuntime_x86_64.cpp	Mon Nov 18 12:40:06 2019 -0500
@@ -45,9 +45,9 @@
 #include "runtime/safepointMechanism.hpp"
 #include "runtime/sharedRuntime.hpp"
 #include "runtime/vframeArray.hpp"
+#include "runtime/vm_version.hpp"
 #include "utilities/align.hpp"
 #include "utilities/formatBuffer.hpp"
-#include "vm_version_x86.hpp"
 #include "vmreg_x86.inline.hpp"
 #ifdef COMPILER1
 #include "c1/c1_Runtime1.hpp"
--- a/src/hotspot/cpu/x86/vm_version_ext_x86.hpp	Wed Nov 13 17:21:31 2019 -0500
+++ b/src/hotspot/cpu/x86/vm_version_ext_x86.hpp	Mon Nov 18 12:40:06 2019 -0500
@@ -25,8 +25,8 @@
 #ifndef CPU_X86_VM_VERSION_EXT_X86_HPP
 #define CPU_X86_VM_VERSION_EXT_X86_HPP
 
+#include "runtime/vm_version.hpp"
 #include "utilities/macros.hpp"
-#include "vm_version_x86.hpp"
 
 class VM_Version_Ext : public VM_Version {
 
--- a/src/hotspot/cpu/x86/vm_version_x86.cpp	Wed Nov 13 17:21:31 2019 -0500
+++ b/src/hotspot/cpu/x86/vm_version_x86.cpp	Mon Nov 18 12:40:06 2019 -0500
@@ -32,8 +32,8 @@
 #include "runtime/java.hpp"
 #include "runtime/os.hpp"
 #include "runtime/stubCodeGenerator.hpp"
+#include "runtime/vm_version.hpp"
 #include "utilities/virtualizationSupport.hpp"
-#include "vm_version_x86.hpp"
 
 #include OS_HEADER_INLINE(os)
 
--- a/src/hotspot/cpu/x86/vm_version_x86.hpp	Wed Nov 13 17:21:31 2019 -0500
+++ b/src/hotspot/cpu/x86/vm_version_x86.hpp	Mon Nov 18 12:40:06 2019 -0500
@@ -26,8 +26,8 @@
 #define CPU_X86_VM_VERSION_X86_HPP
 
 #include "memory/universe.hpp"
+#include "runtime/abstract_vm_version.hpp"
 #include "runtime/globals_extension.hpp"
-#include "runtime/vm_version.hpp"
 
 class VM_Version : public Abstract_VM_Version {
   friend class VMStructs;
--- a/src/hotspot/cpu/zero/register_zero.hpp	Wed Nov 13 17:21:31 2019 -0500
+++ b/src/hotspot/cpu/zero/register_zero.hpp	Mon Nov 18 12:40:06 2019 -0500
@@ -27,7 +27,7 @@
 #define CPU_ZERO_REGISTER_ZERO_HPP
 
 #include "asm/register.hpp"
-#include "vm_version_zero.hpp"
+#include "runtime/vm_version.hpp"
 
 class VMRegImpl;
 typedef VMRegImpl* VMReg;
--- a/src/hotspot/cpu/zero/vm_version_ext_zero.hpp	Wed Nov 13 17:21:31 2019 -0500
+++ b/src/hotspot/cpu/zero/vm_version_ext_zero.hpp	Mon Nov 18 12:40:06 2019 -0500
@@ -25,8 +25,8 @@
 #ifndef CPU_ZERO_VM_VERSION_EXT_ZERO_HPP
 #define CPU_ZERO_VM_VERSION_EXT_ZERO_HPP
 
+#include "runtime/vm_version.hpp"
 #include "utilities/macros.hpp"
-#include "vm_version_zero.hpp"
 
 class VM_Version_Ext : public VM_Version {
  private:
--- a/src/hotspot/cpu/zero/vm_version_zero.cpp	Wed Nov 13 17:21:31 2019 -0500
+++ b/src/hotspot/cpu/zero/vm_version_zero.cpp	Mon Nov 18 12:40:06 2019 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved.
  * Copyright 2009 Red Hat, Inc.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
@@ -28,7 +28,7 @@
 #include "memory/resourceArea.hpp"
 #include "runtime/java.hpp"
 #include "runtime/stubCodeGenerator.hpp"
-#include "vm_version_zero.hpp"
+#include "runtime/vm_version.hpp"
 
 
 void VM_Version::initialize() {
--- a/src/hotspot/cpu/zero/vm_version_zero.hpp	Wed Nov 13 17:21:31 2019 -0500
+++ b/src/hotspot/cpu/zero/vm_version_zero.hpp	Mon Nov 18 12:40:06 2019 -0500
@@ -26,8 +26,8 @@
 #ifndef CPU_ZERO_VM_VERSION_ZERO_HPP
 #define CPU_ZERO_VM_VERSION_ZERO_HPP
 
+#include "runtime/abstract_vm_version.hpp"
 #include "runtime/globals_extension.hpp"
-#include "runtime/vm_version.hpp"
 
 class VM_Version : public Abstract_VM_Version {
  public:
--- a/src/hotspot/os/aix/os_aix.cpp	Wed Nov 13 17:21:31 2019 -0500
+++ b/src/hotspot/os/aix/os_aix.cpp	Mon Nov 18 12:40:06 2019 -0500
@@ -2341,6 +2341,10 @@
   return 0;
 }
 
+int os::numa_get_group_id_for_address(const void* address) {
+  return 0;
+}
+
 bool os::get_page_info(char *start, page_info* info) {
   return false;
 }
--- a/src/hotspot/os/bsd/os_perf_bsd.cpp	Wed Nov 13 17:21:31 2019 -0500
+++ b/src/hotspot/os/bsd/os_perf_bsd.cpp	Mon Nov 18 12:40:06 2019 -0500
@@ -26,7 +26,7 @@
 #include "memory/resourceArea.hpp"
 #include "runtime/os.hpp"
 #include "runtime/os_perf.hpp"
-#include "vm_version_ext_x86.hpp"
+#include CPU_HEADER(vm_version_ext)
 
 #ifdef __APPLE__
   #import <libproc.h>
--- a/src/hotspot/os/posix/os_posix.cpp	Wed Nov 13 17:21:31 2019 -0500
+++ b/src/hotspot/os/posix/os_posix.cpp	Mon Nov 18 12:40:06 2019 -0500
@@ -2075,10 +2075,12 @@
   // the ThreadBlockInVM() CTOR and DTOR may grab Threads_lock.
   ThreadBlockInVM tbivm(jt);
 
+  // Can't access interrupt state now that we are _thread_blocked. If we've
+  // been interrupted since we checked above then _counter will be > 0.
+
   // Don't wait if cannot get lock since interference arises from
-  // unparking. Also re-check interrupt before trying wait.
-  if (jt->is_interrupted(false) ||
-      pthread_mutex_trylock(_mutex) != 0) {
+  // unparking.
+  if (pthread_mutex_trylock(_mutex) != 0) {
     return;
   }
 
--- a/src/hotspot/os/solaris/os_solaris.cpp	Wed Nov 13 17:21:31 2019 -0500
+++ b/src/hotspot/os/solaris/os_solaris.cpp	Mon Nov 18 12:40:06 2019 -0500
@@ -4925,10 +4925,12 @@
   // the ThreadBlockInVM() CTOR and DTOR may grab Threads_lock.
   ThreadBlockInVM tbivm(jt);
 
+  // Can't access interrupt state now that we are _thread_blocked. If we've
+  // been interrupted since we checked above then _counter will be > 0.
+
   // Don't wait if cannot get lock since interference arises from
-  // unblocking.  Also. check interrupt before trying wait
-  if (jt->is_interrupted(false) ||
-      os::Solaris::mutex_trylock(_mutex) != 0) {
+  // unblocking.
+  if (os::Solaris::mutex_trylock(_mutex) != 0) {
     return;
   }
 
--- a/src/hotspot/os/windows/os_perf_windows.cpp	Wed Nov 13 17:21:31 2019 -0500
+++ b/src/hotspot/os/windows/os_perf_windows.cpp	Mon Nov 18 12:40:06 2019 -0500
@@ -31,7 +31,7 @@
 #include "runtime/os_perf.hpp"
 #include "runtime/os.hpp"
 #include "utilities/macros.hpp"
-#include "vm_version_ext_x86.hpp"
+#include CPU_HEADER(vm_version_ext)
 #include <math.h>
 #include <psapi.h>
 #include <TlHelp32.h>
--- a/src/hotspot/os_cpu/bsd_x86/vm_version_bsd_x86.cpp	Wed Nov 13 17:21:31 2019 -0500
+++ b/src/hotspot/os_cpu/bsd_x86/vm_version_bsd_x86.cpp	Mon Nov 18 12:40:06 2019 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -24,4 +24,4 @@
 
 #include "precompiled.hpp"
 #include "runtime/os.hpp"
-#include "vm_version_x86.hpp"
+#include "runtime/vm_version.hpp"
--- a/src/hotspot/os_cpu/bsd_zero/vm_version_bsd_zero.cpp	Wed Nov 13 17:21:31 2019 -0500
+++ b/src/hotspot/os_cpu/bsd_zero/vm_version_bsd_zero.cpp	Mon Nov 18 12:40:06 2019 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved.
  * Copyright 2009 Red Hat, Inc.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
@@ -25,6 +25,6 @@
 
 #include "precompiled.hpp"
 #include "runtime/os.hpp"
-#include "vm_version_zero.hpp"
+#include "runtime/vm_version.hpp"
 
 // This file is intentionally empty
--- a/src/hotspot/os_cpu/linux_aarch64/atomic_linux_aarch64.hpp	Wed Nov 13 17:21:31 2019 -0500
+++ b/src/hotspot/os_cpu/linux_aarch64/atomic_linux_aarch64.hpp	Mon Nov 18 12:40:06 2019 -0500
@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 1999, 2019, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2014, Red Hat Inc. All rights reserved.
+ * Copyright (c) 2014, 2019, 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
@@ -26,9 +26,11 @@
 #ifndef OS_CPU_LINUX_AARCH64_ATOMIC_LINUX_AARCH64_HPP
 #define OS_CPU_LINUX_AARCH64_ATOMIC_LINUX_AARCH64_HPP
 
-#include "vm_version_aarch64.hpp"
+#include "runtime/vm_version.hpp"
 
 // Implementation of class atomic
+// Note that memory_order_conservative requires a full barrier after atomic stores.
+// See https://patchwork.kernel.org/patch/3575821/
 
 #define FULL_MEM_BARRIER  __sync_synchronize()
 #define READ_MEM_BARRIER  __atomic_thread_fence(__ATOMIC_ACQUIRE);
@@ -52,7 +54,7 @@
                                                      T volatile* dest,
                                                      atomic_memory_order order) const {
   STATIC_ASSERT(byte_size == sizeof(T));
-  T res = __sync_lock_test_and_set(dest, exchange_value);
+  T res = __atomic_exchange_n(dest, exchange_value, __ATOMIC_RELEASE);
   FULL_MEM_BARRIER;
   return res;
 }
@@ -70,7 +72,12 @@
                               __ATOMIC_RELAXED, __ATOMIC_RELAXED);
     return value;
   } else {
-    return __sync_val_compare_and_swap(dest, compare_value, exchange_value);
+    T value = compare_value;
+    FULL_MEM_BARRIER;
+    __atomic_compare_exchange(dest, &value, &exchange_value, /*weak*/false,
+                              __ATOMIC_RELAXED, __ATOMIC_RELAXED);
+    FULL_MEM_BARRIER;
+    return value;
   }
 }
 
--- a/src/hotspot/os_cpu/linux_aarch64/orderAccess_linux_aarch64.hpp	Wed Nov 13 17:21:31 2019 -0500
+++ b/src/hotspot/os_cpu/linux_aarch64/orderAccess_linux_aarch64.hpp	Mon Nov 18 12:40:06 2019 -0500
@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2014, Red Hat Inc. All rights reserved.
+ * Copyright (c) 2014, 2019, 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
@@ -28,7 +28,7 @@
 
 // Included in orderAccess.hpp header file.
 
-#include "vm_version_aarch64.hpp"
+#include "runtime/vm_version.hpp"
 
 // Implementation of class OrderAccess.
 
--- a/src/hotspot/os_cpu/linux_aarch64/vm_version_linux_aarch64.cpp	Wed Nov 13 17:21:31 2019 -0500
+++ b/src/hotspot/os_cpu/linux_aarch64/vm_version_linux_aarch64.cpp	Mon Nov 18 12:40:06 2019 -0500
@@ -1,6 +1,6 @@
 /*
- * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2014, Red Hat Inc. All rights reserved.
+ * Copyright (c) 2006, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2019, 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
@@ -25,5 +25,5 @@
 
 #include "precompiled.hpp"
 #include "runtime/os.hpp"
-#include "vm_version_aarch64.hpp"
+#include "runtime/vm_version.hpp"
 
--- a/src/hotspot/os_cpu/linux_arm/atomic_linux_arm.hpp	Wed Nov 13 17:21:31 2019 -0500
+++ b/src/hotspot/os_cpu/linux_arm/atomic_linux_arm.hpp	Mon Nov 18 12:40:06 2019 -0500
@@ -26,7 +26,7 @@
 #define OS_CPU_LINUX_ARM_ATOMIC_LINUX_ARM_HPP
 
 #include "runtime/os.hpp"
-#include "vm_version_arm.hpp"
+#include "runtime/vm_version.hpp"
 
 // Implementation of class atomic
 
--- a/src/hotspot/os_cpu/linux_arm/orderAccess_linux_arm.hpp	Wed Nov 13 17:21:31 2019 -0500
+++ b/src/hotspot/os_cpu/linux_arm/orderAccess_linux_arm.hpp	Mon Nov 18 12:40:06 2019 -0500
@@ -28,7 +28,7 @@
 // Included in orderAccess.hpp header file.
 
 #include "runtime/os.hpp"
-#include "vm_version_arm.hpp"
+#include "runtime/vm_version.hpp"
 
 // Implementation of class OrderAccess.
 // - we define the high level barriers below and use the general
--- a/src/hotspot/os_cpu/linux_arm/vm_version_linux_arm_32.cpp	Wed Nov 13 17:21:31 2019 -0500
+++ b/src/hotspot/os_cpu/linux_arm/vm_version_linux_arm_32.cpp	Mon Nov 18 12:40:06 2019 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -24,7 +24,7 @@
 
 #include "precompiled.hpp"
 #include "runtime/os.hpp"
-#include "vm_version_arm.hpp"
+#include "runtime/vm_version.hpp"
 
 # include <sys/utsname.h>
 
--- a/src/hotspot/os_cpu/linux_s390/atomic_linux_s390.hpp	Wed Nov 13 17:21:31 2019 -0500
+++ b/src/hotspot/os_cpu/linux_s390/atomic_linux_s390.hpp	Mon Nov 18 12:40:06 2019 -0500
@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2016, 2018 SAP SE. All rights reserved.
+ * Copyright (c) 2016, 2019 SAP SE. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -28,7 +28,7 @@
 
 #include "runtime/atomic.hpp"
 #include "runtime/os.hpp"
-#include "vm_version_s390.hpp"
+#include "runtime/vm_version.hpp"
 
 // Note that the compare-and-swap instructions on System z perform
 // a serialization function before the storage operand is fetched
--- a/src/hotspot/os_cpu/linux_s390/orderAccess_linux_s390.hpp	Wed Nov 13 17:21:31 2019 -0500
+++ b/src/hotspot/os_cpu/linux_s390/orderAccess_linux_s390.hpp	Mon Nov 18 12:40:06 2019 -0500
@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2016 SAP SE. All rights reserved.
+ * Copyright (c) 2016, 2019 SAP SE. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -28,7 +28,7 @@
 
 // Included in orderAccess.hpp header file.
 
-#include "vm_version_s390.hpp"
+#include "runtime/vm_version.hpp"
 
 // Implementation of class OrderAccess.
 
--- a/src/hotspot/os_cpu/linux_sparc/vm_version_linux_sparc.cpp	Wed Nov 13 17:21:31 2019 -0500
+++ b/src/hotspot/os_cpu/linux_sparc/vm_version_linux_sparc.cpp	Mon Nov 18 12:40:06 2019 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -25,7 +25,7 @@
 #include "logging/log.hpp"
 #include "precompiled.hpp"
 #include "runtime/os.hpp"
-#include "vm_version_sparc.hpp"
+#include "runtime/vm_version.hpp"
 
 
 #define CPUINFO_LINE_SIZE 1024
--- a/src/hotspot/os_cpu/linux_x86/vm_version_linux_x86.cpp	Wed Nov 13 17:21:31 2019 -0500
+++ b/src/hotspot/os_cpu/linux_x86/vm_version_linux_x86.cpp	Mon Nov 18 12:40:06 2019 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -24,5 +24,5 @@
 
 #include "precompiled.hpp"
 #include "runtime/os.hpp"
-#include "vm_version_x86.hpp"
+#include "runtime/vm_version.hpp"
 
--- a/src/hotspot/os_cpu/linux_zero/vm_version_linux_zero.cpp	Wed Nov 13 17:21:31 2019 -0500
+++ b/src/hotspot/os_cpu/linux_zero/vm_version_linux_zero.cpp	Mon Nov 18 12:40:06 2019 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved.
  * Copyright 2009 Red Hat, Inc.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
@@ -25,6 +25,6 @@
 
 #include "precompiled.hpp"
 #include "runtime/os.hpp"
-#include "vm_version_zero.hpp"
+#include "runtime/vm_version.hpp"
 
 // This file is intentionally empty
--- a/src/hotspot/os_cpu/solaris_sparc/vm_version_solaris_sparc.cpp	Wed Nov 13 17:21:31 2019 -0500
+++ b/src/hotspot/os_cpu/solaris_sparc/vm_version_solaris_sparc.cpp	Mon Nov 18 12:40:06 2019 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -27,7 +27,7 @@
 #include "memory/allocation.hpp"
 #include "memory/allocation.inline.hpp"
 #include "runtime/os.hpp"
-#include "vm_version_sparc.hpp"
+#include "runtime/vm_version.hpp"
 
 #include <sys/auxv.h>
 #include <sys/systeminfo.h>
--- a/src/hotspot/os_cpu/solaris_x86/vm_version_solaris_x86.cpp	Wed Nov 13 17:21:31 2019 -0500
+++ b/src/hotspot/os_cpu/solaris_x86/vm_version_solaris_x86.cpp	Mon Nov 18 12:40:06 2019 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -24,5 +24,5 @@
 
 #include "precompiled.hpp"
 #include "runtime/os.hpp"
-#include "vm_version_x86.hpp"
+#include "runtime/vm_version.hpp"
 
--- a/src/hotspot/os_cpu/windows_x86/vm_version_windows_x86.cpp	Wed Nov 13 17:21:31 2019 -0500
+++ b/src/hotspot/os_cpu/windows_x86/vm_version_windows_x86.cpp	Mon Nov 18 12:40:06 2019 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -24,5 +24,5 @@
 
 #include "precompiled.hpp"
 #include "runtime/os.hpp"
-#include "vm_version_x86.hpp"
+#include "runtime/vm_version.hpp"
 
--- a/src/hotspot/share/classfile/javaClasses.cpp	Wed Nov 13 17:21:31 2019 -0500
+++ b/src/hotspot/share/classfile/javaClasses.cpp	Mon Nov 18 12:40:06 2019 -0500
@@ -1077,7 +1077,7 @@
       Klass *ak = (Klass*)(archived_m->metadata_field(_array_klass_offset));
       assert(ak != NULL || t == T_VOID, "should not be NULL");
       if (ak != NULL) {
-        Klass *reloc_ak = MetaspaceShared::get_relocated_klass(ak);
+        Klass *reloc_ak = MetaspaceShared::get_relocated_klass(ak, true);
         archived_m->metadata_field_put(_array_klass_offset, reloc_ak);
       }
 
@@ -1222,7 +1222,7 @@
   // The archived mirror's field at _klass_offset is still pointing to the original
   // klass. Updated the field in the archived mirror to point to the relocated
   // klass in the archive.
-  Klass *reloc_k = MetaspaceShared::get_relocated_klass(as_Klass(mirror));
+  Klass *reloc_k = MetaspaceShared::get_relocated_klass(as_Klass(mirror), true);
   log_debug(cds, heap, mirror)(
     "Relocate mirror metadata field at _klass_offset from " PTR_FORMAT " ==> " PTR_FORMAT,
     p2i(as_Klass(mirror)), p2i(reloc_k));
@@ -1232,7 +1232,7 @@
   // higher array klass if exists. Relocate the pointer.
   Klass *arr = array_klass_acquire(mirror);
   if (arr != NULL) {
-    Klass *reloc_arr = MetaspaceShared::get_relocated_klass(arr);
+    Klass *reloc_arr = MetaspaceShared::get_relocated_klass(arr, true);
     log_debug(cds, heap, mirror)(
       "Relocate mirror metadata field at _array_klass_offset from " PTR_FORMAT " ==> " PTR_FORMAT,
       p2i(arr), p2i(reloc_arr));
@@ -1241,6 +1241,33 @@
   return archived_mirror;
 }
 
+void java_lang_Class::update_archived_primitive_mirror_native_pointers(oop archived_mirror) {
+  if (MetaspaceShared::relocation_delta() != 0) {
+    assert(archived_mirror->metadata_field(_klass_offset) == NULL, "must be for primitive class");
+
+    Klass* ak = ((Klass*)archived_mirror->metadata_field(_array_klass_offset));
+    if (ak != NULL) {
+      archived_mirror->metadata_field_put(_array_klass_offset,
+          (Klass*)(address(ak) + MetaspaceShared::relocation_delta()));
+    }
+  }
+}
+
+void java_lang_Class::update_archived_mirror_native_pointers(oop archived_mirror) {
+  if (MetaspaceShared::relocation_delta() != 0) {
+    Klass* k = ((Klass*)archived_mirror->metadata_field(_klass_offset));
+    archived_mirror->metadata_field_put(_klass_offset,
+        (Klass*)(address(k) + MetaspaceShared::relocation_delta()));
+
+    Klass* ak = ((Klass*)archived_mirror->metadata_field(_array_klass_offset));
+    if (ak != NULL) {
+      archived_mirror->metadata_field_put(_array_klass_offset,
+          (Klass*)(address(ak) + MetaspaceShared::relocation_delta()));
+    }
+  }
+}
+
+
 // Returns true if the mirror is updated, false if no archived mirror
 // data is present. After the archived mirror object is restored, the
 // shared klass' _has_raw_archived_mirror flag is cleared.
@@ -1256,15 +1283,15 @@
   }
 
   oop m = HeapShared::materialize_archived_object(k->archived_java_mirror_raw_narrow());
-
   if (m == NULL) {
     return false;
   }
 
+  // mirror is archived, restore
   log_debug(cds, mirror)("Archived mirror is: " PTR_FORMAT, p2i(m));
-
-  // mirror is archived, restore
   assert(HeapShared::is_archived_object(m), "must be archived mirror object");
+  update_archived_mirror_native_pointers(m);
+  assert(as_Klass(m) == k, "must be");
   Handle mirror(THREAD, m);
 
   if (!k->is_array_klass()) {
@@ -1681,10 +1708,20 @@
 }
 
 bool java_lang_Thread::interrupted(oop java_thread) {
+  // Make sure the caller can safely access oops.
+  assert(Thread::current()->is_VM_thread() ||
+         (JavaThread::current()->thread_state() != _thread_blocked &&
+          JavaThread::current()->thread_state() != _thread_in_native),
+         "Unsafe access to oop");
   return java_thread->bool_field_volatile(_interrupted_offset);
 }
 
 void java_lang_Thread::set_interrupted(oop java_thread, bool val) {
+  // Make sure the caller can safely access oops.
+  assert(Thread::current()->is_VM_thread() ||
+         (JavaThread::current()->thread_state() != _thread_blocked &&
+          JavaThread::current()->thread_state() != _thread_in_native),
+         "Unsafe access to oop");
   java_thread->bool_field_put_volatile(_interrupted_offset, val);
 }
 
@@ -4649,6 +4686,28 @@
 }
 #endif
 
+#if INCLUDE_CDS_JAVA_HEAP
+bool JavaClasses::is_supported_for_archiving(oop obj) {
+  Klass* klass = obj->klass();
+
+  if (klass == SystemDictionary::ClassLoader_klass() ||  // ClassLoader::loader_data is malloc'ed.
+      klass == SystemDictionary::Module_klass() ||       // Module::module_entry is malloc'ed
+      // The next 3 classes are used to implement java.lang.invoke, and are not used directly in
+      // regular Java code. The implementation of java.lang.invoke uses generated anonymoys classes
+      // (e.g., as referenced by ResolvedMethodName::vmholder) that are not yet supported by CDS.
+      // So for now we cannot not support these classes for archiving.
+      //
+      // These objects typically are not referenced by static fields, but rather by resolved
+      // constant pool entries, so excluding them shouldn't affect the archiving of static fields.
+      klass == SystemDictionary::ResolvedMethodName_klass() ||
+      klass == SystemDictionary::MemberName_klass() ||
+      klass == SystemDictionary::Context_klass()) {
+    return false;
+  }
+
+  return true;
+}
+#endif
 
 #ifndef PRODUCT
 
--- a/src/hotspot/share/classfile/javaClasses.hpp	Wed Nov 13 17:21:31 2019 -0500
+++ b/src/hotspot/share/classfile/javaClasses.hpp	Mon Nov 18 12:40:06 2019 -0500
@@ -281,6 +281,8 @@
                             Handle protection_domain, TRAPS);
   static void fixup_mirror(Klass* k, TRAPS);
   static oop  create_basic_type_mirror(const char* basic_type_name, BasicType type, TRAPS);
+  static void update_archived_primitive_mirror_native_pointers(oop archived_mirror) NOT_CDS_JAVA_HEAP_RETURN;
+  static void update_archived_mirror_native_pointers(oop archived_mirror) NOT_CDS_JAVA_HEAP_RETURN;
 
   // Archiving
   static void serialize_offsets(SerializeClosure* f) NOT_CDS_RETURN;
@@ -1662,6 +1664,7 @@
   static void check_offsets() PRODUCT_RETURN;
   static void serialize_offsets(SerializeClosure* soc) NOT_CDS_RETURN;
   static InjectedField* get_injected(Symbol* class_name, int* field_count);
+  static bool is_supported_for_archiving(oop obj) NOT_CDS_JAVA_HEAP_RETURN_(false);
 };
 
 #undef DECLARE_INJECTED_FIELD_ENUM
--- a/src/hotspot/share/classfile/systemDictionaryShared.cpp	Wed Nov 13 17:21:31 2019 -0500
+++ b/src/hotspot/share/classfile/systemDictionaryShared.cpp	Mon Nov 18 12:40:06 2019 -0500
@@ -38,6 +38,7 @@
 #include "classfile/vmSymbols.hpp"
 #include "logging/log.hpp"
 #include "memory/allocation.hpp"
+#include "memory/archiveUtils.hpp"
 #include "memory/filemap.hpp"
 #include "memory/metadataFactory.hpp"
 #include "memory/metaspaceClosure.hpp"
@@ -294,6 +295,7 @@
     if (DynamicDumpSharedSpaces) {
       _klass = DynamicArchive::original_to_target(info._klass);
     }
+    ArchivePtrMarker::mark_pointer(&_klass);
   }
 
   bool matches(int clsfile_size, int clsfile_crc32) const {
@@ -337,6 +339,8 @@
     } else {
       *info_pointer_addr(klass) = record;
     }
+
+    ArchivePtrMarker::mark_pointer(info_pointer_addr(klass));
   }
 
   // Used by RunTimeSharedDictionary to implement OffsetCompactHashtable::EQUALS
@@ -1354,7 +1358,7 @@
       if (DynamicDumpSharedSpaces) {
         name = DynamicArchive::original_to_target(name);
       }
-      hash = primitive_hash<Symbol*>(name);
+      hash = SystemDictionaryShared::hash_for_shared_dictionary(name);
       u4 delta;
       if (DynamicDumpSharedSpaces) {
         delta = MetaspaceShared::object_delta_u4(DynamicArchive::buffer_to_target(record));
@@ -1413,7 +1417,7 @@
     return NULL;
   }
 
-  unsigned int hash = primitive_hash<Symbol*>(name);
+  unsigned int hash = SystemDictionaryShared::hash_for_shared_dictionary(name);
   const RunTimeSharedClassInfo* record = NULL;
   if (!MetaspaceShared::is_shared_dynamic(name)) {
     // The names of all shared classes in the static dict must also be in the
--- a/src/hotspot/share/classfile/systemDictionaryShared.hpp	Wed Nov 13 17:21:31 2019 -0500
+++ b/src/hotspot/share/classfile/systemDictionaryShared.hpp	Mon Nov 18 12:40:06 2019 -0500
@@ -323,6 +323,12 @@
   };
 #endif
 
+  template <typename T>
+  static unsigned int hash_for_shared_dictionary(T* ptr) {
+    assert(ptr > (T*)SharedBaseAddress, "must be");
+    address p = address(ptr) - SharedBaseAddress;
+    return primitive_hash<address>(p);
+  }
 };
 
 #endif // SHARE_CLASSFILE_SYSTEMDICTIONARYSHARED_HPP
--- a/src/hotspot/share/compiler/compileBroker.cpp	Wed Nov 13 17:21:31 2019 -0500
+++ b/src/hotspot/share/compiler/compileBroker.cpp	Mon Nov 18 12:40:06 2019 -0500
@@ -596,7 +596,7 @@
 // CompileBroker::compilation_init
 //
 // Initialize the Compilation object
-void CompileBroker::compilation_init_phase1(TRAPS) {
+void CompileBroker::compilation_init_phase1(Thread* THREAD) {
   // No need to initialize compilation system if we do not use it.
   if (!UseCompiler) {
     return;
@@ -647,6 +647,7 @@
   // totalTime performance counter is always created as it is required
   // by the implementation of java.lang.management.CompilationMBean.
   {
+    // Ensure OOM leads to vm_exit_during_initialization.
     EXCEPTION_MARK;
     _perf_total_compilation =
                  PerfDataManager::create_counter(JAVA_CI, "totalTime",
@@ -761,17 +762,17 @@
 }
 
 
-JavaThread* CompileBroker::make_thread(jobject thread_handle, CompileQueue* queue, AbstractCompiler* comp, TRAPS) {
-  JavaThread* thread = NULL;
+JavaThread* CompileBroker::make_thread(jobject thread_handle, CompileQueue* queue, AbstractCompiler* comp, Thread* THREAD) {
+  JavaThread* new_thread = NULL;
   {
     MutexLocker mu(Threads_lock, THREAD);
     if (comp != NULL) {
       if (!InjectCompilerCreationFailure || comp->num_compiler_threads() == 0) {
         CompilerCounters* counters = new CompilerCounters();
-        thread = new CompilerThread(queue, counters);
+        new_thread = new CompilerThread(queue, counters);
       }
     } else {
-      thread = new CodeCacheSweeperThread();
+      new_thread = new CodeCacheSweeperThread();
     }
     // At this point the new CompilerThread data-races with this startup
     // thread (which I believe is the primoridal thread and NOT the VM
@@ -786,9 +787,9 @@
     // exceptions anyway, check and abort if this fails. But first release the
     // lock.
 
-    if (thread != NULL && thread->osthread() != NULL) {
+    if (new_thread != NULL && new_thread->osthread() != NULL) {
 
-      java_lang_Thread::set_thread(JNIHandles::resolve_non_null(thread_handle), thread);
+      java_lang_Thread::set_thread(JNIHandles::resolve_non_null(thread_handle), new_thread);
 
       // Note that this only sets the JavaThread _priority field, which by
       // definition is limited to Java priorities and not OS priorities.
@@ -809,24 +810,24 @@
           native_prio = os::java_to_os_priority[NearMaxPriority];
         }
       }
-      os::set_native_priority(thread, native_prio);
+      os::set_native_priority(new_thread, native_prio);
 
       java_lang_Thread::set_daemon(JNIHandles::resolve_non_null(thread_handle));
 
-      thread->set_threadObj(JNIHandles::resolve_non_null(thread_handle));
+      new_thread->set_threadObj(JNIHandles::resolve_non_null(thread_handle));
       if (comp != NULL) {
-        thread->as_CompilerThread()->set_compiler(comp);
+        new_thread->as_CompilerThread()->set_compiler(comp);
       }
-      Threads::add(thread);
-      Thread::start(thread);
+      Threads::add(new_thread);
+      Thread::start(new_thread);
     }
   }
 
   // First release lock before aborting VM.
-  if (thread == NULL || thread->osthread() == NULL) {
+  if (new_thread == NULL || new_thread->osthread() == NULL) {
     if (UseDynamicNumberOfCompilerThreads && comp != NULL && comp->num_compiler_threads() > 0) {
-      if (thread != NULL) {
-        thread->smr_delete();
+      if (new_thread != NULL) {
+        new_thread->smr_delete();
       }
       return NULL;
     }
@@ -837,11 +838,12 @@
   // Let go of Threads_lock before yielding
   os::naked_yield(); // make sure that the compiler thread is started early (especially helpful on SOLARIS)
 
-  return thread;
+  return new_thread;
 }
 
 
 void CompileBroker::init_compiler_sweeper_threads() {
+  // Ensure any exceptions lead to vm_exit_during_initialization.
   EXCEPTION_MARK;
 #if !defined(ZERO)
   assert(_c2_count > 0 || _c1_count > 0, "No compilers?");
@@ -875,7 +877,7 @@
     _compiler2_logs[i] = NULL;
 
     if (!UseDynamicNumberOfCompilerThreads || i == 0) {
-      JavaThread *ct = make_thread(thread_handle, _c2_compile_queue, _compilers[1], CHECK);
+      JavaThread *ct = make_thread(thread_handle, _c2_compile_queue, _compilers[1], THREAD);
       assert(ct != NULL, "should have been handled for initial thread");
       _compilers[1]->set_num_compiler_threads(i + 1);
       if (TraceCompilerThreads) {
@@ -895,7 +897,7 @@
     _compiler1_logs[i] = NULL;
 
     if (!UseDynamicNumberOfCompilerThreads || i == 0) {
-      JavaThread *ct = make_thread(thread_handle, _c1_compile_queue, _compilers[0], CHECK);
+      JavaThread *ct = make_thread(thread_handle, _c1_compile_queue, _compilers[0], THREAD);
       assert(ct != NULL, "should have been handled for initial thread");
       _compilers[0]->set_num_compiler_threads(i + 1);
       if (TraceCompilerThreads) {
@@ -914,12 +916,11 @@
     // Initialize the sweeper thread
     Handle thread_oop = create_thread_oop("Sweeper thread", CHECK);
     jobject thread_handle = JNIHandles::make_local(THREAD, thread_oop());
-    make_thread(thread_handle, NULL, NULL, CHECK);
+    make_thread(thread_handle, NULL, NULL, THREAD);
   }
 }
 
-void CompileBroker::possibly_add_compiler_threads() {
-  EXCEPTION_MARK;
+void CompileBroker::possibly_add_compiler_threads(Thread* THREAD) {
 
   julong available_memory = os::available_memory();
   // If SegmentedCodeCache is off, both values refer to the single heap (with type CodeBlobType::All).
@@ -970,7 +971,7 @@
         _compiler2_objects[i] = thread_handle;
       }
 #endif
-      JavaThread *ct = make_thread(compiler2_object(i), _c2_compile_queue, _compilers[1], CHECK);
+      JavaThread *ct = make_thread(compiler2_object(i), _c2_compile_queue, _compilers[1], THREAD);
       if (ct == NULL) break;
       _compilers[1]->set_num_compiler_threads(i + 1);
       if (TraceCompilerThreads) {
@@ -990,7 +991,7 @@
         (int)(available_cc_p / (128*K)));
 
     for (int i = old_c1_count; i < new_c1_count; i++) {
-      JavaThread *ct = make_thread(compiler1_object(i), _c1_compile_queue, _compilers[0], CHECK);
+      JavaThread *ct = make_thread(compiler1_object(i), _c1_compile_queue, _compilers[0], THREAD);
       if (ct == NULL) break;
       _compilers[0]->set_num_compiler_threads(i + 1);
       if (TraceCompilerThreads) {
@@ -1511,14 +1512,6 @@
 }
 
 // ------------------------------------------------------------------
-// CompileBroker::preload_classes
-void CompileBroker::preload_classes(const methodHandle& method, TRAPS) {
-  // Move this code over from c1_Compiler.cpp
-  ShouldNotReachHere();
-}
-
-
-// ------------------------------------------------------------------
 // CompileBroker::create_compile_task
 //
 // Create a CompileTask object representing the current request for
@@ -1865,7 +1858,8 @@
       }
 
       if (UseDynamicNumberOfCompilerThreads) {
-        possibly_add_compiler_threads();
+        possibly_add_compiler_threads(thread);
+        assert(!thread->has_pending_exception(), "should have been handled");
       }
     }
   }
--- a/src/hotspot/share/compiler/compileBroker.hpp	Wed Nov 13 17:21:31 2019 -0500
+++ b/src/hotspot/share/compiler/compileBroker.hpp	Mon Nov 18 12:40:06 2019 -0500
@@ -226,11 +226,10 @@
   static volatile int _print_compilation_warning;
 
   static Handle create_thread_oop(const char* name, TRAPS);
-  static JavaThread* make_thread(jobject thread_oop, CompileQueue* queue, AbstractCompiler* comp, TRAPS);
+  static JavaThread* make_thread(jobject thread_oop, CompileQueue* queue, AbstractCompiler* comp, Thread* THREAD);
   static void init_compiler_sweeper_threads();
-  static void possibly_add_compiler_threads();
+  static void possibly_add_compiler_threads(Thread* THREAD);
   static bool compilation_is_prohibited(const methodHandle& method, int osr_bci, int comp_level, bool excluded);
-  static void preload_classes          (const methodHandle& method, TRAPS);
 
   static CompileTask* create_compile_task(CompileQueue*       queue,
                                           int                 compile_id,
@@ -292,7 +291,7 @@
     CompileQueue *q = compile_queue(comp_level);
     return q != NULL ? q->size() : 0;
   }
-  static void compilation_init_phase1(TRAPS);
+  static void compilation_init_phase1(Thread* THREAD);
   static void compilation_init_phase2();
   static void init_compiler_thread_log();
   static nmethod* compile_method(const methodHandle& method,
--- a/src/hotspot/share/gc/g1/g1CollectedHeap.cpp	Wed Nov 13 17:21:31 2019 -0500
+++ b/src/hotspot/share/gc/g1/g1CollectedHeap.cpp	Mon Nov 18 12:40:06 2019 -0500
@@ -2001,7 +2001,6 @@
 
 bool G1CollectedHeap::should_do_concurrent_full_gc(GCCause::Cause cause) {
   switch (cause) {
-    case GCCause::_gc_locker:               return GCLockerInvokesConcurrent;
     case GCCause::_g1_humongous_allocation: return true;
     case GCCause::_g1_periodic_collection:  return G1PeriodicGCInvokesConcurrent;
     default:                                return is_user_requested_concurrent_full_gc(cause);
@@ -2009,7 +2008,7 @@
 }
 
 bool G1CollectedHeap::should_upgrade_to_full_gc(GCCause::Cause cause) {
-  if(policy()->force_upgrade_to_full()) {
+  if (policy()->force_upgrade_to_full()) {
     return true;
   } else if (should_do_concurrent_full_gc(_gc_cause)) {
     return false;
@@ -2056,7 +2055,7 @@
 }
 
 void G1CollectedHeap::increment_old_marking_cycles_completed(bool concurrent) {
-  MonitorLocker x(FullGCCount_lock, Mutex::_no_safepoint_check_flag);
+  MonitorLocker ml(G1OldGCCount_lock, Mutex::_no_safepoint_check_flag);
 
   // We assume that if concurrent == true, then the caller is a
   // concurrent thread that was joined the Suspendible Thread
@@ -2096,91 +2095,210 @@
     _cm_thread->set_idle();
   }
 
-  // This notify_all() will ensure that a thread that called
-  // System.gc() with (with ExplicitGCInvokesConcurrent set or not)
-  // and it's waiting for a full GC to finish will be woken up. It is
-  // waiting in VM_G1CollectForAllocation::doit_epilogue().
-  FullGCCount_lock->notify_all();
+  // Notify threads waiting in System.gc() (with ExplicitGCInvokesConcurrent)
+  // for a full GC to finish that their wait is over.
+  ml.notify_all();
 }
 
 void G1CollectedHeap::collect(GCCause::Cause cause) {
-  try_collect(cause, true);
+  try_collect(cause);
+}
+
+// Return true if (x < y) with allowance for wraparound.
+static bool gc_counter_less_than(uint x, uint y) {
+  return (x - y) > (UINT_MAX/2);
 }
 
-bool G1CollectedHeap::try_collect(GCCause::Cause cause, bool retry_on_gc_failure) {
+// LOG_COLLECT_CONCURRENTLY(cause, msg, args...)
+// Macro so msg printing is format-checked.
+#define LOG_COLLECT_CONCURRENTLY(cause, ...)                            \
+  do {                                                                  \
+    LogTarget(Trace, gc) LOG_COLLECT_CONCURRENTLY_lt;                   \
+    if (LOG_COLLECT_CONCURRENTLY_lt.is_enabled()) {                     \
+      ResourceMark rm; /* For thread name. */                           \
+      LogStream LOG_COLLECT_CONCURRENTLY_s(&LOG_COLLECT_CONCURRENTLY_lt); \
+      LOG_COLLECT_CONCURRENTLY_s.print("%s: Try Collect Concurrently (%s): ", \
+                                       Thread::current()->name(),       \
+                                       GCCause::to_string(cause));      \
+      LOG_COLLECT_CONCURRENTLY_s.print(__VA_ARGS__);                    \
+    }                                                                   \
+  } while (0)
+
+#define LOG_COLLECT_CONCURRENTLY_COMPLETE(cause, result) \
+  LOG_COLLECT_CONCURRENTLY(cause, "complete %s", BOOL_TO_STR(result))
+
+bool G1CollectedHeap::try_collect_concurrently(GCCause::Cause cause,
+                                               uint gc_counter,
+                                               uint old_marking_started_before) {
   assert_heap_not_locked();
-
-  bool gc_succeeded;
-  bool should_retry_gc;
-
-  do {
-    should_retry_gc = false;
-
-    uint gc_count_before;
-    uint old_marking_count_before;
-    uint full_gc_count_before;
-
+  assert(should_do_concurrent_full_gc(cause),
+         "Non-concurrent cause %s", GCCause::to_string(cause));
+
+  for (uint i = 1; true; ++i) {
+    // Try to schedule an initial-mark evacuation pause that will
+    // start a concurrent cycle.
+    LOG_COLLECT_CONCURRENTLY(cause, "attempt %u", i);
+    VM_G1TryInitiateConcMark op(gc_counter,
+                                cause,
+                                policy()->max_pause_time_ms());
+    VMThread::execute(&op);
+
+    // Request is trivially finished.
+    if (cause == GCCause::_g1_periodic_collection) {
+      LOG_COLLECT_CONCURRENTLY_COMPLETE(cause, op.gc_succeeded());
+      return op.gc_succeeded();
+    }
+
+    // Lock to get consistent set of values.
+    uint old_marking_started_after;
+    uint old_marking_completed_after;
     {
       MutexLocker ml(Heap_lock);
-
-      // Read the GC count while holding the Heap_lock
-      gc_count_before = total_collections();
-      full_gc_count_before = total_full_collections();
-      old_marking_count_before = _old_marking_cycles_started;
+      // Update gc_counter for retrying VMOp if needed. Captured here to be
+      // consistent with the values we use below for termination tests.  If
+      // a retry is needed after a possible wait, and another collection
+      // occurs in the meantime, it will cause our retry to be skipped and
+      // we'll recheck for termination with updated conditions from that
+      // more recent collection.  That's what we want, rather than having
+      // our retry possibly perform an unnecessary collection.
+      gc_counter = total_collections();
+      old_marking_started_after = _old_marking_cycles_started;
+      old_marking_completed_after = _old_marking_cycles_completed;
     }
 
-    if (should_do_concurrent_full_gc(cause)) {
-      // Schedule an initial-mark evacuation pause that will start a
-      // concurrent cycle. We're setting word_size to 0 which means that
-      // we are not requesting a post-GC allocation.
-      VM_G1CollectForAllocation op(0,     /* word_size */
-                                   gc_count_before,
-                                   cause,
-                                   true,  /* should_initiate_conc_mark */
-                                   policy()->max_pause_time_ms());
-      VMThread::execute(&op);
-      gc_succeeded = op.gc_succeeded();
-      if (!gc_succeeded && retry_on_gc_failure) {
-        if (old_marking_count_before == _old_marking_cycles_started) {
-          should_retry_gc = op.should_retry_gc();
-        } else {
-          // A Full GC happened while we were trying to schedule the
-          // concurrent cycle. No point in starting a new cycle given
-          // that the whole heap was collected anyway.
+    if (!GCCause::is_user_requested_gc(cause)) {
+      // For an "automatic" (not user-requested) collection, we just need to
+      // ensure that progress is made.
+      //
+      // Request is finished if any of
+      // (1) the VMOp successfully performed a GC,
+      // (2) a concurrent cycle was already in progress,
+      // (3) a new cycle was started (by this thread or some other), or
+      // (4) a Full GC was performed.
+      // Cases (3) and (4) are detected together by a change to
+      // _old_marking_cycles_started.
+      //
+      // Note that (1) does not imply (3).  If we're still in the mixed
+      // phase of an earlier concurrent collection, the request to make the
+      // collection an initial-mark won't be honored.  If we don't check for
+      // both conditions we'll spin doing back-to-back collections.
+      if (op.gc_succeeded() ||
+          op.cycle_already_in_progress() ||
+          (old_marking_started_before != old_marking_started_after)) {
+        LOG_COLLECT_CONCURRENTLY_COMPLETE(cause, true);
+        return true;
+      }
+    } else {                    // User-requested GC.
+      // For a user-requested collection, we want to ensure that a complete
+      // full collection has been performed before returning, but without
+      // waiting for more than needed.
+
+      // For user-requested GCs (unlike non-UR), a successful VMOp implies a
+      // new cycle was started.  That's good, because it's not clear what we
+      // should do otherwise.  Trying again just does back to back GCs.
+      // Can't wait for someone else to start a cycle.  And returning fails
+      // to meet the goal of ensuring a full collection was performed.
+      assert(!op.gc_succeeded() ||
+             (old_marking_started_before != old_marking_started_after),
+             "invariant: succeeded %s, started before %u, started after %u",
+             BOOL_TO_STR(op.gc_succeeded()),
+             old_marking_started_before, old_marking_started_after);
+
+      // Request is finished if a full collection (concurrent or stw)
+      // was started after this request and has completed, e.g.
+      // started_before < completed_after.
+      if (gc_counter_less_than(old_marking_started_before,
+                               old_marking_completed_after)) {
+        LOG_COLLECT_CONCURRENTLY_COMPLETE(cause, true);
+        return true;
+      }
+
+      if (old_marking_started_after != old_marking_completed_after) {
+        // If there is an in-progress cycle (possibly started by us), then
+        // wait for that cycle to complete, e.g.
+        // while completed_now < started_after.
+        LOG_COLLECT_CONCURRENTLY(cause, "wait");
+        MonitorLocker ml(G1OldGCCount_lock);
+        while (gc_counter_less_than(_old_marking_cycles_completed,
+                                    old_marking_started_after)) {
+          ml.wait();
         }
-
-        if (should_retry_gc && GCLocker::is_active_and_needs_gc()) {
-          GCLocker::stall_until_clear();
+        // Request is finished if the collection we just waited for was
+        // started after this request.
+        if (old_marking_started_before != old_marking_started_after) {
+          LOG_COLLECT_CONCURRENTLY(cause, "complete after wait");
+          return true;
         }
       }
-    } else if (GCLocker::should_discard(cause, gc_count_before)) {
-      // Return false to be consistent with VMOp failure due to
-      // another collection slipping in after our gc_count but before
-      // our request is processed.  _gc_locker collections upgraded by
-      // GCLockerInvokesConcurrent are handled above and never discarded.
-      return false;
-    } else {
-      if (cause == GCCause::_gc_locker || cause == GCCause::_wb_young_gc
-          DEBUG_ONLY(|| cause == GCCause::_scavenge_alot)) {
-
-        // Schedule a standard evacuation pause. We're setting word_size
-        // to 0 which means that we are not requesting a post-GC allocation.
-        VM_G1CollectForAllocation op(0,     /* word_size */
-                                     gc_count_before,
-                                     cause,
-                                     false, /* should_initiate_conc_mark */
-                                     policy()->max_pause_time_ms());
-        VMThread::execute(&op);
-        gc_succeeded = op.gc_succeeded();
-      } else {
-        // Schedule a Full GC.
-        VM_G1CollectFull op(gc_count_before, full_gc_count_before, cause);
-        VMThread::execute(&op);
-        gc_succeeded = op.gc_succeeded();
+
+      // If VMOp was successful then it started a new cycle that the above
+      // wait &etc should have recognized as finishing this request.  This
+      // differs from a non-user-request, where gc_succeeded does not imply
+      // a new cycle was started.
+      assert(!op.gc_succeeded(), "invariant");
+
+      // If VMOp failed because a cycle was already in progress, it is now
+      // complete.  But it didn't finish this user-requested GC, so try
+      // again.
+      if (op.cycle_already_in_progress()) {
+        LOG_COLLECT_CONCURRENTLY(cause, "retry after in-progress");
+        continue;
       }
     }
-  } while (should_retry_gc);
-  return gc_succeeded;
+
+    // Collection failed and should be retried.
+    assert(op.transient_failure(), "invariant");
+
+    // If GCLocker is active, wait until clear before retrying.
+    if (GCLocker::is_active_and_needs_gc()) {
+      LOG_COLLECT_CONCURRENTLY(cause, "gc-locker stall");
+      GCLocker::stall_until_clear();
+    }
+
+    LOG_COLLECT_CONCURRENTLY(cause, "retry");
+  }
+}
+
+bool G1CollectedHeap::try_collect(GCCause::Cause cause) {
+  assert_heap_not_locked();
+
+  // Lock to get consistent set of values.
+  uint gc_count_before;
+  uint full_gc_count_before;
+  uint old_marking_started_before;
+  {
+    MutexLocker ml(Heap_lock);
+    gc_count_before = total_collections();
+    full_gc_count_before = total_full_collections();
+    old_marking_started_before = _old_marking_cycles_started;
+  }
+
+  if (should_do_concurrent_full_gc(cause)) {
+    return try_collect_concurrently(cause,
+                                    gc_count_before,
+                                    old_marking_started_before);
+  } else if (GCLocker::should_discard(cause, gc_count_before)) {
+    // Indicate failure to be consistent with VMOp failure due to
+    // another collection slipping in after our gc_count but before
+    // our request is processed.
+    return false;
+  } else if (cause == GCCause::_gc_locker || cause == GCCause::_wb_young_gc
+             DEBUG_ONLY(|| cause == GCCause::_scavenge_alot)) {
+
+    // Schedule a standard evacuation pause. We're setting word_size
+    // to 0 which means that we are not requesting a post-GC allocation.
+    VM_G1CollectForAllocation op(0,     /* word_size */
+                                 gc_count_before,
+                                 cause,
+                                 policy()->max_pause_time_ms());
+    VMThread::execute(&op);
+    return op.gc_succeeded();
+  } else {
+    // Schedule a Full GC.
+    VM_G1CollectFull op(gc_count_before, full_gc_count_before, cause);
+    VMThread::execute(&op);
+    return op.gc_succeeded();
+  }
 }
 
 bool G1CollectedHeap::is_in(const void* p) const {
@@ -2611,7 +2729,6 @@
   VM_G1CollectForAllocation op(word_size,
                                gc_count_before,
                                gc_cause,
-                               false, /* should_initiate_conc_mark */
                                policy()->max_pause_time_ms());
   VMThread::execute(&op);
 
--- a/src/hotspot/share/gc/g1/g1CollectedHeap.hpp	Wed Nov 13 17:21:31 2019 -0500
+++ b/src/hotspot/share/gc/g1/g1CollectedHeap.hpp	Mon Nov 18 12:40:06 2019 -0500
@@ -133,6 +133,7 @@
   friend class VM_CollectForMetadataAllocation;
   friend class VM_G1CollectForAllocation;
   friend class VM_G1CollectFull;
+  friend class VM_G1TryInitiateConcMark;
   friend class VMStructs;
   friend class MutatorAllocRegion;
   friend class G1FullCollector;
@@ -259,16 +260,21 @@
 
   G1HRPrinter _hr_printer;
 
-  // It decides whether an explicit GC should start a concurrent cycle
-  // instead of doing a STW GC. Currently, a concurrent cycle is
-  // explicitly started if:
-  // (a) cause == _gc_locker and +GCLockerInvokesConcurrent, or
-  // (b) cause == _g1_humongous_allocation
-  // (c) cause == _java_lang_system_gc and +ExplicitGCInvokesConcurrent.
-  // (d) cause == _dcmd_gc_run and +ExplicitGCInvokesConcurrent.
-  // (e) cause == _wb_conc_mark
+  // Return true if an explicit GC should start a concurrent cycle instead
+  // of doing a STW full GC. A concurrent cycle should be started if:
+  // (a) cause == _g1_humongous_allocation,
+  // (b) cause == _java_lang_system_gc and +ExplicitGCInvokesConcurrent,
+  // (c) cause == _dcmd_gc_run and +ExplicitGCInvokesConcurrent,
+  // (d) cause == _wb_conc_mark,
+  // (e) cause == _g1_periodic_collection and +G1PeriodicGCInvokesConcurrent.
   bool should_do_concurrent_full_gc(GCCause::Cause cause);
 
+  // Attempt to start a concurrent cycle with the indicated cause.
+  // precondition: should_do_concurrent_full_gc(cause)
+  bool try_collect_concurrently(GCCause::Cause cause,
+                                uint gc_counter,
+                                uint old_marking_started_before);
+
   // Return true if should upgrade to full gc after an incremental one.
   bool should_upgrade_to_full_gc(GCCause::Cause cause);
 
@@ -630,7 +636,7 @@
   // Full GC). If concurrent is true, the caller is the outer caller
   // in this nesting (i.e., the concurrent cycle). Further nesting is
   // not currently supported. The end of this call also notifies
-  // the FullGCCount_lock in case a Java thread is waiting for a full
+  // the G1OldGCCount_lock in case a Java thread is waiting for a full
   // GC to happen (e.g., it called System.gc() with
   // +ExplicitGCInvokesConcurrent).
   void increment_old_marking_cycles_completed(bool concurrent);
@@ -1088,10 +1094,9 @@
   // "CollectedHeap" supports.
   virtual void collect(GCCause::Cause cause);
 
-  // Perform a collection of the heap with the given cause; if the VM operation
-  // fails to execute for any reason, retry only if retry_on_gc_failure is set.
+  // Perform a collection of the heap with the given cause.
   // Returns whether this collection actually executed.
-  bool try_collect(GCCause::Cause cause, bool retry_on_gc_failure);
+  bool try_collect(GCCause::Cause cause);
 
   // True iff an evacuation has failed in the most-recent collection.
   bool evacuation_failed() { return _evacuation_failed; }
--- a/src/hotspot/share/gc/g1/g1ConcurrentMarkThread.cpp	Wed Nov 13 17:21:31 2019 -0500
+++ b/src/hotspot/share/gc/g1/g1ConcurrentMarkThread.cpp	Mon Nov 18 12:40:06 2019 -0500
@@ -393,7 +393,7 @@
     }
 
     // Update the number of full collections that have been
-    // completed. This will also notify the FullGCCount_lock in case a
+    // completed. This will also notify the G1OldGCCount_lock in case a
     // Java thread is waiting for a full GC to happen (e.g., it
     // called System.gc() with +ExplicitGCInvokesConcurrent).
     {
--- a/src/hotspot/share/gc/g1/g1Policy.hpp	Wed Nov 13 17:21:31 2019 -0500
+++ b/src/hotspot/share/gc/g1/g1Policy.hpp	Mon Nov 18 12:40:06 2019 -0500
@@ -250,14 +250,6 @@
 public:
   size_t pending_cards_at_gc_start() const { return _pending_cards_at_gc_start; }
 
-  size_t total_concurrent_refined_cards() const {
-    return _total_concurrent_refined_cards;
-  }
-
-  size_t total_mutator_refined_cards() const {
-    return _total_mutator_refined_cards;
-  }
-
   // Calculate the minimum number of old regions we'll add to the CSet
   // during a mixed GC.
   uint calc_min_old_cset_length() const;
--- a/src/hotspot/share/gc/g1/g1RemSetSummary.cpp	Wed Nov 13 17:21:31 2019 -0500
+++ b/src/hotspot/share/gc/g1/g1RemSetSummary.cpp	Mon Nov 18 12:40:06 2019 -0500
@@ -23,11 +23,11 @@
  */
 
 #include "precompiled.hpp"
+#include "gc/g1/g1BarrierSet.hpp"
 #include "gc/g1/g1CollectedHeap.inline.hpp"
 #include "gc/g1/g1ConcurrentRefine.hpp"
 #include "gc/g1/g1ConcurrentRefineThread.hpp"
 #include "gc/g1/g1DirtyCardQueue.hpp"
-#include "gc/g1/g1Policy.hpp"
 #include "gc/g1/g1RemSet.hpp"
 #include "gc/g1/g1RemSetSummary.hpp"
 #include "gc/g1/g1YoungRemSetSamplingThread.hpp"
@@ -36,36 +36,24 @@
 #include "memory/allocation.inline.hpp"
 #include "runtime/thread.inline.hpp"
 
-class GetRSThreadVTimeClosure : public ThreadClosure {
-private:
-  G1RemSetSummary* _summary;
-  uint _counter;
-
-public:
-  GetRSThreadVTimeClosure(G1RemSetSummary * summary) : ThreadClosure(), _summary(summary), _counter(0) {
-    assert(_summary != NULL, "just checking");
-  }
-
-  virtual void do_thread(Thread* t) {
-    G1ConcurrentRefineThread* crt = (G1ConcurrentRefineThread*) t;
-    _summary->set_rs_thread_vtime(_counter, crt->vtime_accum());
-    _counter++;
-  }
-};
-
 void G1RemSetSummary::update() {
+  class CollectData : public ThreadClosure {
+    G1RemSetSummary* _summary;
+    uint _counter;
+  public:
+    CollectData(G1RemSetSummary * summary) : _summary(summary),  _counter(0) {}
+    virtual void do_thread(Thread* t) {
+      G1ConcurrentRefineThread* crt = static_cast<G1ConcurrentRefineThread*>(t);
+      _summary->set_rs_thread_vtime(_counter, crt->vtime_accum());
+      _counter++;
+      _summary->_total_concurrent_refined_cards += crt->total_refined_cards();
+    }
+  } collector(this);
   G1CollectedHeap* g1h = G1CollectedHeap::heap();
-
-  const G1Policy* policy = g1h->policy();
-  _total_mutator_refined_cards = policy->total_mutator_refined_cards();
-  _total_concurrent_refined_cards = policy->total_concurrent_refined_cards();
-
+  g1h->concurrent_refine()->threads_do(&collector);
+  _total_mutator_refined_cards = G1BarrierSet::dirty_card_queue_set().total_mutator_refined_cards();
   _num_coarsenings = HeapRegionRemSet::n_coarsenings();
 
-  if (_rs_threads_vtimes != NULL) {
-    GetRSThreadVTimeClosure p(this);
-    g1h->concurrent_refine()->threads_do(&p);
-  }
   set_sampling_thread_vtime(g1h->sampling_thread()->vtime_accum());
 }
 
--- a/src/hotspot/share/gc/g1/g1RemSetSummary.hpp	Wed Nov 13 17:21:31 2019 -0500
+++ b/src/hotspot/share/gc/g1/g1RemSetSummary.hpp	Mon Nov 18 12:40:06 2019 -0500
@@ -34,8 +34,6 @@
 
 class G1RemSetSummary {
 private:
-  friend class GetRSThreadVTimeClosure;
-
   size_t _total_mutator_refined_cards;
   size_t _total_concurrent_refined_cards;
 
--- a/src/hotspot/share/gc/g1/g1VMOperations.cpp	Wed Nov 13 17:21:31 2019 -0500
+++ b/src/hotspot/share/gc/g1/g1VMOperations.cpp	Mon Nov 18 12:40:06 2019 -0500
@@ -40,17 +40,61 @@
   _gc_succeeded = g1h->do_full_collection(true /* explicit_gc */, false /* clear_all_soft_refs */);
 }
 
+VM_G1TryInitiateConcMark::VM_G1TryInitiateConcMark(uint gc_count_before,
+                                                   GCCause::Cause gc_cause,
+                                                   double target_pause_time_ms) :
+  VM_GC_Operation(gc_count_before, gc_cause),
+  _target_pause_time_ms(target_pause_time_ms),
+  _transient_failure(false),
+  _cycle_already_in_progress(false),
+  _gc_succeeded(false)
+{}
+
+bool VM_G1TryInitiateConcMark::doit_prologue() {
+  bool result = VM_GC_Operation::doit_prologue();
+  // The prologue can fail for a couple of reasons. The first is that another GC
+  // got scheduled and prevented the scheduling of the initial mark GC. The
+  // second is that the GC locker may be active and the heap can't be expanded.
+  // In both cases we want to retry the GC so that the initial mark pause is
+  // actually scheduled. In the second case, however, we should stall until
+  // until the GC locker is no longer active and then retry the initial mark GC.
+  if (!result) _transient_failure = true;
+  return result;
+}
+
+void VM_G1TryInitiateConcMark::doit() {
+  G1CollectedHeap* g1h = G1CollectedHeap::heap();
+
+  GCCauseSetter x(g1h, _gc_cause);
+  if (!g1h->policy()->force_initial_mark_if_outside_cycle(_gc_cause)) {
+    // Failure to force the next GC pause to be an initial mark indicates
+    // there is already a concurrent marking cycle in progress.  Set flag
+    // to notify the caller and return immediately.
+    _cycle_already_in_progress = true;
+  } else if (!g1h->do_collection_pause_at_safepoint(_target_pause_time_ms)) {
+    // Failure to perform the collection at all occurs because GCLocker is
+    // active, and we have the bad luck to be the collection request that
+    // makes a later _gc_locker collection needed.  (Else we would have hit
+    // the GCLocker check in the prologue.)
+    _transient_failure = true;
+  } else if (g1h->should_upgrade_to_full_gc(_gc_cause)) {
+    // GC ran, but we're still in trouble and need a full GC.
+    log_info(gc, ergo)("Attempting maximally compacting collection");
+    _gc_succeeded = g1h->do_full_collection(false, /* explicit gc */
+                                            true /* clear_all_soft_refs */);
+    guarantee(_gc_succeeded, "Elevated collections during the safepoint must always succeed");
+  } else {
+    _gc_succeeded = true;
+  }
+}
+
 VM_G1CollectForAllocation::VM_G1CollectForAllocation(size_t         word_size,
                                                      uint           gc_count_before,
                                                      GCCause::Cause gc_cause,
-                                                     bool           should_initiate_conc_mark,
                                                      double         target_pause_time_ms) :
   VM_CollectForAllocation(word_size, gc_count_before, gc_cause),
   _gc_succeeded(false),
-  _should_initiate_conc_mark(should_initiate_conc_mark),
-  _should_retry_gc(false),
-  _target_pause_time_ms(target_pause_time_ms),
-  _old_marking_cycles_completed_before(0) {
+  _target_pause_time_ms(target_pause_time_ms) {
 
   guarantee(target_pause_time_ms > 0.0,
             "target_pause_time_ms = %1.6lf should be positive",
@@ -58,26 +102,8 @@
   _gc_cause = gc_cause;
 }
 
-bool VM_G1CollectForAllocation::doit_prologue() {
-  bool res = VM_CollectForAllocation::doit_prologue();
-  if (!res) {
-    if (_should_initiate_conc_mark) {
-      // The prologue can fail for a couple of reasons. The first is that another GC
-      // got scheduled and prevented the scheduling of the initial mark GC. The
-      // second is that the GC locker may be active and the heap can't be expanded.
-      // In both cases we want to retry the GC so that the initial mark pause is
-      // actually scheduled. In the second case, however, we should stall until
-      // until the GC locker is no longer active and then retry the initial mark GC.
-      _should_retry_gc = true;
-    }
-  }
-  return res;
-}
-
 void VM_G1CollectForAllocation::doit() {
   G1CollectedHeap* g1h = G1CollectedHeap::heap();
-  assert(!_should_initiate_conc_mark || g1h->should_do_concurrent_full_gc(_gc_cause),
-      "only a GC locker, a System.gc(), stats update, whitebox, or a hum allocation induced GC should start a cycle");
 
   if (_word_size > 0) {
     // An allocation has been requested. So, try to do that first.
@@ -92,44 +118,6 @@
   }
 
   GCCauseSetter x(g1h, _gc_cause);
-  if (_should_initiate_conc_mark) {
-    // It's safer to read old_marking_cycles_completed() here, given
-    // that noone else will be updating it concurrently. Since we'll
-    // only need it if we're initiating a marking cycle, no point in
-    // setting it earlier.
-    _old_marking_cycles_completed_before = g1h->old_marking_cycles_completed();
-
-    // At this point we are supposed to start a concurrent cycle. We
-    // will do so if one is not already in progress.
-    bool res = g1h->policy()->force_initial_mark_if_outside_cycle(_gc_cause);
-
-    // The above routine returns true if we were able to force the
-    // next GC pause to be an initial mark; it returns false if a
-    // marking cycle is already in progress.
-    //
-    // If a marking cycle is already in progress just return and skip the
-    // pause below - if the reason for requesting this initial mark pause
-    // was due to a System.gc() then the requesting thread should block in
-    // doit_epilogue() until the marking cycle is complete.
-    //
-    // If this initial mark pause was requested as part of a humongous
-    // allocation then we know that the marking cycle must just have
-    // been started by another thread (possibly also allocating a humongous
-    // object) as there was no active marking cycle when the requesting
-    // thread checked before calling collect() in
-    // attempt_allocation_humongous(). Retrying the GC, in this case,
-    // will cause the requesting thread to spin inside collect() until the
-    // just started marking cycle is complete - which may be a while. So
-    // we do NOT retry the GC.
-    if (!res) {
-      assert(_word_size == 0, "Concurrent Full GC/Humongous Object IM shouldn't be allocating");
-      if (_gc_cause != GCCause::_g1_humongous_allocation) {
-        _should_retry_gc = true;
-      }
-      return;
-    }
-  }
-
   // Try a partial collection of some kind.
   _gc_succeeded = g1h->do_collection_pause_at_safepoint(_target_pause_time_ms);
 
@@ -138,66 +126,15 @@
       // An allocation had been requested. Do it, eventually trying a stronger
       // kind of GC.
       _result = g1h->satisfy_failed_allocation(_word_size, &_gc_succeeded);
-    } else {
-      bool should_upgrade_to_full = g1h->should_upgrade_to_full_gc(_gc_cause);
-
-      if (should_upgrade_to_full) {
-        // There has been a request to perform a GC to free some space. We have no
-        // information on how much memory has been asked for. In case there are
-        // absolutely no regions left to allocate into, do a maximally compacting full GC.
-        log_info(gc, ergo)("Attempting maximally compacting collection");
-        _gc_succeeded = g1h->do_full_collection(false, /* explicit gc */
-                                                   true   /* clear_all_soft_refs */);
-      }
+    } else if (g1h->should_upgrade_to_full_gc(_gc_cause)) {
+      // There has been a request to perform a GC to free some space. We have no
+      // information on how much memory has been asked for. In case there are
+      // absolutely no regions left to allocate into, do a maximally compacting full GC.
+      log_info(gc, ergo)("Attempting maximally compacting collection");
+      _gc_succeeded = g1h->do_full_collection(false, /* explicit gc */
+                                              true   /* clear_all_soft_refs */);
     }
     guarantee(_gc_succeeded, "Elevated collections during the safepoint must always succeed.");
-  } else {
-    assert(_result == NULL, "invariant");
-    // The only reason for the pause to not be successful is that, the GC locker is
-    // active (or has become active since the prologue was executed). In this case
-    // we should retry the pause after waiting for the GC locker to become inactive.
-    _should_retry_gc = true;
-  }
-}
-
-void VM_G1CollectForAllocation::doit_epilogue() {
-  VM_CollectForAllocation::doit_epilogue();
-
-  // If the pause was initiated by a System.gc() and
-  // +ExplicitGCInvokesConcurrent, we have to wait here for the cycle
-  // that just started (or maybe one that was already in progress) to
-  // finish.
-  if (GCCause::is_user_requested_gc(_gc_cause) &&
-      _should_initiate_conc_mark) {
-    assert(ExplicitGCInvokesConcurrent,
-           "the only way to be here is if ExplicitGCInvokesConcurrent is set");
-
-    G1CollectedHeap* g1h = G1CollectedHeap::heap();
-
-    // In the doit() method we saved g1h->old_marking_cycles_completed()
-    // in the _old_marking_cycles_completed_before field. We have to
-    // wait until we observe that g1h->old_marking_cycles_completed()
-    // has increased by at least one. This can happen if a) we started
-    // a cycle and it completes, b) a cycle already in progress
-    // completes, or c) a Full GC happens.
-
-    // If the condition has already been reached, there's no point in
-    // actually taking the lock and doing the wait.
-    if (g1h->old_marking_cycles_completed() <=
-                                          _old_marking_cycles_completed_before) {
-      // The following is largely copied from CMS
-
-      Thread* thr = Thread::current();
-      assert(thr->is_Java_thread(), "invariant");
-      JavaThread* jt = (JavaThread*)thr;
-      ThreadToNativeFromVM native(jt);
-
-      MonitorLocker ml(FullGCCount_lock, Mutex::_no_safepoint_check_flag);
-      while (g1h->old_marking_cycles_completed() <=
-                                          _old_marking_cycles_completed_before) {
-        ml.wait();
-      }
-    }
   }
 }
 
--- a/src/hotspot/share/gc/g1/g1VMOperations.hpp	Wed Nov 13 17:21:31 2019 -0500
+++ b/src/hotspot/share/gc/g1/g1VMOperations.hpp	Mon Nov 18 12:40:06 2019 -0500
@@ -45,29 +45,39 @@
     _gc_succeeded(false) { }
   virtual VMOp_Type type() const { return VMOp_G1CollectFull; }
   virtual void doit();
-  bool gc_succeeded() { return _gc_succeeded; }
+  bool gc_succeeded() const { return _gc_succeeded; }
+};
+
+class VM_G1TryInitiateConcMark : public VM_GC_Operation {
+  double _target_pause_time_ms;
+  bool _transient_failure;
+  bool _cycle_already_in_progress;
+  bool _gc_succeeded;
+
+public:
+  VM_G1TryInitiateConcMark(uint gc_count_before,
+                           GCCause::Cause gc_cause,
+                           double target_pause_time_ms);
+  virtual VMOp_Type type() const { return VMOp_G1TryInitiateConcMark; }
+  virtual bool doit_prologue();
+  virtual void doit();
+  bool transient_failure() const { return _transient_failure; }
+  bool cycle_already_in_progress() const { return _cycle_already_in_progress; }
+  bool gc_succeeded() const { return _gc_succeeded; }
 };
 
 class VM_G1CollectForAllocation : public VM_CollectForAllocation {
   bool _gc_succeeded;
-
-  bool _should_initiate_conc_mark;
-  bool _should_retry_gc;
   double _target_pause_time_ms;
-  uint  _old_marking_cycles_completed_before;
 
 public:
   VM_G1CollectForAllocation(size_t         word_size,
                             uint           gc_count_before,
                             GCCause::Cause gc_cause,
-                            bool           should_initiate_conc_mark,
                             double         target_pause_time_ms);
   virtual VMOp_Type type() const { return VMOp_G1CollectForAllocation; }
-  virtual bool doit_prologue();
   virtual void doit();
-  virtual void doit_epilogue();
-  bool should_retry_gc() const { return _should_retry_gc; }
-  bool gc_succeeded() { return _gc_succeeded; }
+  bool gc_succeeded() const { return _gc_succeeded; }
 };
 
 // Concurrent G1 stop-the-world operations such as remark and cleanup.
--- a/src/hotspot/share/gc/g1/g1YoungRemSetSamplingThread.cpp	Wed Nov 13 17:21:31 2019 -0500
+++ b/src/hotspot/share/gc/g1/g1YoungRemSetSamplingThread.cpp	Mon Nov 18 12:40:06 2019 -0500
@@ -90,8 +90,7 @@
   if ((os::elapsedTime() - _last_periodic_gc_attempt_s) > (G1PeriodicGCInterval / 1000.0)) {
     log_debug(gc, periodic)("Checking for periodic GC.");
     if (should_start_periodic_gc()) {
-      if (!G1CollectedHeap::heap()->try_collect(GCCause::_g1_periodic_collection,
-                                                    false /* retry_on_vmop_failure */)) {
+      if (!G1CollectedHeap::heap()->try_collect(GCCause::_g1_periodic_collection)) {
         log_debug(gc, periodic)("GC request denied. Skipping.");
       }
     }
--- a/src/hotspot/share/gc/shared/gc_globals.hpp	Wed Nov 13 17:21:31 2019 -0500
+++ b/src/hotspot/share/gc/shared/gc_globals.hpp	Mon Nov 18 12:40:06 2019 -0500
@@ -228,10 +228,6 @@
           "A System.gc() request invokes a concurrent collection; "         \
           "(effective only when using concurrent collectors)")              \
                                                                             \
-  product(bool, GCLockerInvokesConcurrent, false,                           \
-          "The exit of a JNI critical section necessitating a scavenge, "   \
-          "also kicks off a background concurrent collection")              \
-                                                                            \
   product(uintx, GCLockerEdenExpansionPercent, 5,                           \
           "How much the GC can expand the eden by while the GC locker "     \
           "is active (as a percentage)")                                    \
--- a/src/hotspot/share/include/cds.h	Wed Nov 13 17:21:31 2019 -0500
+++ b/src/hotspot/share/include/cds.h	Mon Nov 18 12:40:06 2019 -0500
@@ -33,26 +33,29 @@
 //
 // Also, this is a C header file. Do not use C++ here.
 
-#define NUM_CDS_REGIONS 8 // this must be the same as MetaspaceShared::n_regions
+#define NUM_CDS_REGIONS 9 // this must be the same as MetaspaceShared::n_regions
 #define CDS_ARCHIVE_MAGIC 0xf00baba2
 #define CDS_DYNAMIC_ARCHIVE_MAGIC 0xf00baba8
-#define CURRENT_CDS_ARCHIVE_VERSION 8
+#define CURRENT_CDS_ARCHIVE_VERSION 9
 #define INVALID_CDS_ARCHIVE_VERSION -1
 
 struct CDSFileMapRegion {
-  int        _crc;            // crc checksum of the current space
-  size_t     _file_offset;    // sizeof(this) rounded to vm page size
-  union {
-    char*    _base;           // copy-on-write base address
-    size_t   _offset;         // offset from the compressed oop encoding base, only used
-                              // by archive heap space
-  } _addr;
-  size_t     _used;           // for setting space top on read
-  int        _read_only;      // read only space?
-  int        _allow_exec;     // executable code in space?
-  void*      _oopmap;         // bitmap for relocating embedded oops
-  size_t     _oopmap_size_in_bits;
-  int        _is_heap_region; // used in debug build only.
+  int     _crc;               // CRC checksum of this region.
+  int     _read_only;         // read only region?
+  int     _allow_exec;        // executable code in this region?
+  int     _is_heap_region;    // Used by SA and debug build.
+  int     _is_bitmap_region;  // Relocation bitmap for RO/RW/MC/MD regions (used by SA and debug build).
+  int     _mapped_from_file;  // Is this region mapped from a file?
+                              // If false, this region was initialized using os::read().
+  size_t  _file_offset;       // Data for this region starts at this offset in the archive file.
+  size_t  _mapping_offset;    // This region should be mapped at this offset from the base address
+                              // - for non-heap regions, the base address is SharedBaseAddress
+                              // - for heap regions, the base address is the compressed oop encoding base
+  size_t  _used;              // Number of bytes actually used by this region (excluding padding bytes added
+                              // for alignment purposed.
+  size_t  _oopmap_offset;     // Bitmap for relocating embedded oops (offset from SharedBaseAddress).
+  size_t  _oopmap_size_in_bits;
+  char*   _mapped_base;       // Actually mapped address (NULL if this region is not mapped).
 };
 
 struct CDSFileMapHeaderBase {
--- a/src/hotspot/share/interpreter/bytecodeInterpreter.cpp	Wed Nov 13 17:21:31 2019 -0500
+++ b/src/hotspot/share/interpreter/bytecodeInterpreter.cpp	Mon Nov 18 12:40:06 2019 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -2462,8 +2462,8 @@
         if (VerifyOops) method->verify();
 
         if (cache->has_appendix()) {
-          ConstantPool* constants = METHOD->constants();
-          SET_STACK_OBJECT(cache->appendix_if_resolved(constants), 0);
+          constantPoolHandle cp(THREAD, METHOD->constants());
+          SET_STACK_OBJECT(cache->appendix_if_resolved(cp), 0);
           MORE_STACK(1);
         }
 
@@ -2493,8 +2493,8 @@
         if (VerifyOops) method->verify();
 
         if (cache->has_appendix()) {
-          ConstantPool* constants = METHOD->constants();
-          SET_STACK_OBJECT(cache->appendix_if_resolved(constants), 0);
+          constantPoolHandle cp(THREAD, METHOD->constants());
+          SET_STACK_OBJECT(cache->appendix_if_resolved(cp), 0);
           MORE_STACK(1);
         }
 
--- a/src/hotspot/share/interpreter/interpreterRuntime.cpp	Wed Nov 13 17:21:31 2019 -0500
+++ b/src/hotspot/share/interpreter/interpreterRuntime.cpp	Mon Nov 18 12:40:06 2019 -0500
@@ -356,7 +356,7 @@
 #ifdef CC_INTERP
 // As legacy note_trap, but we have more arguments.
 JRT_ENTRY(void, InterpreterRuntime::note_trap(JavaThread* thread, int reason, Method *method, int trap_bci))
-  methodHandle trap_method(method);
+  methodHandle trap_method(thread, method);
   note_trap_inner(thread, reason, trap_method, trap_bci, THREAD);
 JRT_END
 
--- a/src/hotspot/share/libadt/vectset.cpp	Wed Nov 13 17:21:31 2019 -0500
+++ b/src/hotspot/share/libadt/vectset.cpp	Mon Nov 18 12:40:06 2019 -0500
@@ -26,62 +26,50 @@
 #include "libadt/vectset.hpp"
 #include "memory/allocation.inline.hpp"
 #include "memory/arena.hpp"
+#include "utilities/count_leading_zeros.hpp"
 
-VectorSet::VectorSet(Arena *arena) {
-  _set_arena = arena;
-  size = 2;                     // Small initial size
-  data = (uint32_t *)_set_arena->Amalloc(size*sizeof(uint32_t));
-  data[0] = 0;                  // No elements
-  data[1] = 0;
+VectorSet::VectorSet(Arena *arena) : _size(2),
+    _data(NEW_ARENA_ARRAY(arena, uint32_t, 2)),
+    _set_arena(arena) {
+  _data[0] = 0;
+  _data[1] = 0;
 }
 
 // Expand the existing set to a bigger size
-void VectorSet::grow(uint newsize) {
-  newsize = (newsize+31) >> 5;
-  uint x = size;
-  while (x < newsize) {
-    x <<= 1;
-  }
-  data = (uint32_t *)_set_arena->Arealloc(data, size*sizeof(uint32_t), x*sizeof(uint32_t));
-  memset((char*)(data + size), 0, (x - size) * sizeof(uint32_t));
-  size = x;
+void VectorSet::grow(uint new_size) {
+  new_size = (new_size + bit_mask) >> word_bits;
+  assert(new_size != 0 && new_size < (1U << 31), "");
+  uint x = (1U << 31) >> (count_leading_zeros(new_size) - 1);
+  _data = REALLOC_ARENA_ARRAY(_set_arena, uint32_t, _data, _size, x);
+  Copy::zero_to_bytes(_data + _size, (x - _size) * sizeof(uint32_t));
+  _size = x;
 }
 
 // Insert a member into an existing Set.
 void VectorSet::insert(uint elem) {
-  uint word = elem >> 5;
-  uint32_t mask = 1L << (elem & 31);
-  if (word >= size) {
+  uint32_t word = elem >> word_bits;
+  uint32_t mask = 1U << (elem & bit_mask);
+  if (word >= _size) {
     grow(elem + 1);
   }
-  data[word] |= mask;
+  _data[word] |= mask;
 }
 
-// Clear a set
-void VectorSet::clear() {
-  if( size > 100 ) {            // Reclaim storage only if huge
-    FREE_RESOURCE_ARRAY(uint32_t,data,size);
-    size = 2;                   // Small initial size
-    data = NEW_RESOURCE_ARRAY(uint32_t,size);
-  }
-  memset(data, 0, size*sizeof(uint32_t));
+// Resets the storage
+void VectorSet::reset_memory() {
+  assert(_size >= 2, "_size can never be less than 2");
+  _data = REALLOC_ARENA_ARRAY(_set_arena, uint32_t, _data, _size, 2);
+  _size = 2;
+  _data[0] = 0;
+  _data[1] = 0;
 }
 
 // Return true if the set is empty
 bool VectorSet::is_empty() const {
-  for (uint32_t i = 0; i < size; i++) {
-    if (data[i] != 0) {
+  for (uint32_t i = 0; i < _size; i++) {
+    if (_data[i] != 0) {
       return false;
     }
   }
   return true;
 }
-
-int VectorSet::hash() const {
-  uint32_t _xor = 0;
-  uint lim = ((size < 4) ? size : 4);
-  for (uint i = 0; i < lim; i++) {
-    _xor ^= data[i];
-  }
-  return (int)_xor;
-}
--- a/src/hotspot/share/libadt/vectset.hpp	Wed Nov 13 17:21:31 2019 -0500
+++ b/src/hotspot/share/libadt/vectset.hpp	Mon Nov 18 12:40:06 2019 -0500
@@ -26,6 +26,7 @@
 #define SHARE_LIBADT_VECTSET_HPP
 
 #include "memory/allocation.hpp"
+#include "utilities/copy.hpp"
 
 // Vector Sets
 
@@ -35,26 +36,33 @@
 //------------------------------VectorSet--------------------------------------
 class VectorSet : public ResourceObj {
 private:
-  uint size;                    // Size of data IN LONGWORDS (32bits)
-  uint32_t* data;               // The data, bit packed
-  Arena *_set_arena;
+
+  static const uint word_bits = 5;
+  static const uint bit_mask  = 31;
+
+  uint       _size;             // Size of data in 32-bit words
+  uint32_t*  _data;             // The data, bit packed
+  Arena*     _set_arena;
 
   void grow(uint newsize);      // Grow vector to required bitsize
-
+  void reset_memory();
 public:
   VectorSet(Arena *arena);
   ~VectorSet() {}
+
   void insert(uint elem);
-
-  void clear();
   bool is_empty() const;
-  int hash() const;
   void reset() {
-    memset(data, 0, size*sizeof(uint32_t));
+    Copy::zero_to_bytes(_data, _size * sizeof(uint32_t));
   }
-
-  // Expose internals for speed-critical fast iterators
-  uint word_size() const { return size; }
+  void clear() {
+    // Reclaim storage if huge
+    if (_size > 100) {
+      reset_memory();
+    } else {
+      reset();
+    }
+  }
 
   // Fast inlined "test and set".  Replaces the idiom:
   //     if (visited.test(idx)) return;
@@ -62,46 +70,46 @@
   // With:
   //     if (visited.test_set(idx)) return;
   //
-  int test_set(uint elem) {
-    uint word = elem >> 5;           // Get the longword offset
-    if (word >= size) {
+  bool test_set(uint elem) {
+    uint32_t word = elem >> word_bits;
+    if (word >= _size) {
       // Then grow; set; return 0;
       this->insert(elem);
-      return 0;
+      return false;
     }
-    uint32_t mask = 1L << (elem & 31); // Get bit mask
-    uint32_t datum = data[word] & mask;// Get bit
-    data[word] |= mask;              // Set bit
-    return datum;                    // Return bit
+    uint32_t mask = 1U << (elem & bit_mask);
+    uint32_t data = _data[word];
+    _data[word] = data | mask;
+    return (data & mask) != 0;
   }
 
   // Fast inlined test
-  int test(uint elem) const {
-    uint word = elem >> 5;
-    if (word >= size) {
-      return 0;
+  bool test(uint elem) const {
+    uint32_t word = elem >> word_bits;
+    if (word >= _size) {
+      return false;
     }
-    uint32_t mask = 1L << (elem & 31);
-    return data[word] & mask;
+    uint32_t mask = 1U << (elem & bit_mask);
+    return (_data[word] & mask) != 0;
   }
 
   void remove(uint elem) {
-    uint word = elem >> 5;
-    if (word >= size) {
+    uint32_t word = elem >> word_bits;
+    if (word >= _size) {
       return;
     }
-    uint32_t mask = 1L << (elem & 31);
-    data[word] &= ~mask; // Clear bit
+    uint32_t mask = 1U << (elem & bit_mask);
+    _data[word] &= ~mask; // Clear bit
   }
 
   // Fast inlined set
   void set(uint elem) {
-    uint word = elem >> 5;
-    if (word >= size) {
+    uint32_t word = elem >> word_bits;
+    if (word >= _size) {
       this->insert(elem);
     } else {
-      uint32_t mask = 1L << (elem & 31);
-      data[word] |= mask;
+      uint32_t mask = 1U << (elem & bit_mask);
+      _data[word] |= mask;
     }
   }
 };
--- a/src/hotspot/share/memory/allocation.hpp	Wed Nov 13 17:21:31 2019 -0500
+++ b/src/hotspot/share/memory/allocation.hpp	Mon Nov 18 12:40:06 2019 -0500
@@ -283,11 +283,6 @@
     _shared_metaspace_top = top;
   }
 
-  static void expand_shared_metaspace_range(void* top) {
-    assert(top >= _shared_metaspace_top, "must be");
-    _shared_metaspace_top = top;
-  }
-
   static void* shared_metaspace_base() { return _shared_metaspace_base; }
   static void* shared_metaspace_top()  { return _shared_metaspace_top;  }
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/memory/archiveUtils.cpp	Mon Nov 18 12:40:06 2019 -0500
@@ -0,0 +1,118 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#include "precompiled.hpp"
+#include "memory/archiveUtils.hpp"
+#include "memory/metaspace.hpp"
+#include "utilities/bitMap.inline.hpp"
+
+#if INCLUDE_CDS
+
+CHeapBitMap* ArchivePtrMarker::_ptrmap = NULL;
+address* ArchivePtrMarker::_ptr_base;
+address* ArchivePtrMarker::_ptr_end;
+bool ArchivePtrMarker::_compacted;
+
+void ArchivePtrMarker::initialize(CHeapBitMap* ptrmap, address* ptr_base, address* ptr_end) {
+  assert(_ptrmap == NULL, "initialize only once");
+  _ptr_base = ptr_base;
+  _ptr_end = ptr_end;
+  _compacted = false;
+  _ptrmap = ptrmap;
+
+  // Use this as initial guesstimate. We should need less space in the
+  // archive, but if we're wrong the bitmap will be expanded automatically.
+  size_t estimated_archive_size = MetaspaceGC::capacity_until_GC();
+  // But set it smaller in debug builds so we always test the expansion code.
+  // (Default archive is about 12MB).
+  DEBUG_ONLY(estimated_archive_size = 6 * M);
+
+  // We need one bit per pointer in the archive.
+  _ptrmap->initialize(estimated_archive_size / sizeof(intptr_t));
+}
+
+void ArchivePtrMarker::mark_pointer(address* ptr_loc) {
+  assert(_ptrmap != NULL, "not initialized");
+  assert(!_compacted, "cannot mark anymore");
+
+  if (_ptr_base <= ptr_loc && ptr_loc < _ptr_end) {
+    address value = *ptr_loc;
+    if (value != NULL) {
+      assert(uintx(ptr_loc) % sizeof(intptr_t) == 0, "pointers must be stored in aligned addresses");
+      size_t idx = ptr_loc - _ptr_base;
+      if (_ptrmap->size() <= idx) {
+        _ptrmap->resize((idx + 1) * 2);
+      }
+      assert(idx < _ptrmap->size(), "must be");
+      _ptrmap->set_bit(idx);
+      //tty->print_cr("Marking pointer [%p] -> %p @ " SIZE_FORMAT_W(9), ptr_loc, *ptr_loc, idx);
+    }
+  }
+}
+
+class ArchivePtrBitmapCleaner: public BitMapClosure {
+  CHeapBitMap* _ptrmap;
+  address* _ptr_base;
+  address  _relocatable_base;
+  address  _relocatable_end;
+  size_t   _max_non_null_offset;
+
+public:
+  ArchivePtrBitmapCleaner(CHeapBitMap* ptrmap, address* ptr_base, address relocatable_base, address relocatable_end) :
+    _ptrmap(ptrmap), _ptr_base(ptr_base),
+    _relocatable_base(relocatable_base), _relocatable_end(relocatable_end), _max_non_null_offset(0) {}
+
+  bool do_bit(size_t offset) {
+    address* ptr_loc = _ptr_base + offset;
+    address  ptr_value = *ptr_loc;
+    if (ptr_value != NULL) {
+      assert(_relocatable_base <= ptr_value && ptr_value < _relocatable_end, "do not point to arbitrary locations!");
+      if (_max_non_null_offset < offset) {
+        _max_non_null_offset = offset;
+      }
+    } else {
+      _ptrmap->clear_bit(offset);
+      DEBUG_ONLY(log_trace(cds, reloc)("Clearing pointer [" PTR_FORMAT  "] -> NULL @ " SIZE_FORMAT_W(9), p2i(ptr_loc), offset));
+    }
+
+    return true;
+  }
+
+  size_t max_non_null_offset() const { return _max_non_null_offset; }
+};
+
+void ArchivePtrMarker::compact(address relocatable_base, address relocatable_end) {
+  assert(!_compacted, "cannot compact again");
+  ArchivePtrBitmapCleaner cleaner(_ptrmap, _ptr_base, relocatable_base, relocatable_end);
+  _ptrmap->iterate(&cleaner);
+  compact(cleaner.max_non_null_offset());
+}
+
+void ArchivePtrMarker::compact(size_t max_non_null_offset) {
+  assert(!_compacted, "cannot compact again");
+  _ptrmap->resize(max_non_null_offset + 1);
+  _compacted = true;
+}
+
+#endif // INCLUDE_CDS
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/memory/archiveUtils.hpp	Mon Nov 18 12:40:06 2019 -0500
@@ -0,0 +1,136 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#ifndef SHARE_MEMORY_ARCHIVEUTILS_HPP
+#define SHARE_MEMORY_ARCHIVEUTILS_HPP
+
+#include "logging/log.hpp"
+#include "runtime/arguments.hpp"
+#include "utilities/bitMap.hpp"
+
+// ArchivePtrMarker is used to mark the location of pointers embedded in a CDS archive. E.g., when an
+// InstanceKlass k is dumped, we mark the location of the k->_name pointer by effectively calling
+// mark_pointer(/*ptr_loc=*/&k->_name). It's required that (_prt_base <= ptr_loc < _ptr_end). _ptr_base is
+// fixed, but _ptr_end can be expanded as more objects are dumped.
+class ArchivePtrMarker : AllStatic {
+  static CHeapBitMap* _ptrmap;
+  static address*     _ptr_base;
+  static address*     _ptr_end;
+
+  // Once _ptrmap is compacted, we don't allow bit marking anymore. This is to
+  // avoid unintentional copy operations after the bitmap has been finalized and written.
+  static bool         _compacted;
+public:
+  static void initialize(CHeapBitMap* ptrmap, address* ptr_base, address* ptr_end);
+  static void mark_pointer(address* ptr_loc);
+  static void compact(address relocatable_base, address relocatable_end);
+  static void compact(size_t max_non_null_offset);
+
+  template <typename T>
+  static void mark_pointer(T* ptr_loc) {
+    mark_pointer((address*)ptr_loc);
+  }
+
+  static void expand_ptr_end(address *new_ptr_end) {
+    assert(_ptr_end <= new_ptr_end, "must be");
+    _ptr_end = new_ptr_end;
+  }
+
+  static CHeapBitMap* ptrmap() {
+    return _ptrmap;
+  }
+};
+
+// SharedDataRelocator is used to shift pointers in the CDS archive.
+//
+// The CDS archive is basically a contiguous block of memory (divided into several regions)
+// that contains multiple objects. The objects may contain direct pointers that point to other objects
+// within the archive (e.g., InstanceKlass::_name points to a Symbol in the archive). During dumping, we
+// built a bitmap that marks the locations of all these pointers (using ArchivePtrMarker, see comments above).
+//
+// The contents of the archive assumes that it’s mapped at the default SharedBaseAddress (e.g. 0x800000000).
+// If the archive ends up being mapped at a different address (e.g. 0x810000000), SharedDataRelocator
+// is used to shift each marked pointer by a delta (0x10000000 in this example), so that it points to
+// the actually mapped location of the target object.
+template <bool COMPACTING>
+class SharedDataRelocator: public BitMapClosure {
+  // for all (address** p), where (is_marked(p) && _patch_base <= p && p < _patch_end) { *p += delta; }
+
+  // Patch all pointers within this region that are marked.
+  address* _patch_base;
+  address* _patch_end;
+
+  // Before patching, all pointers must point to this region.
+  address _valid_old_base;
+  address _valid_old_end;
+
+  // After patching, all pointers must point to this region.
+  address _valid_new_base;
+  address _valid_new_end;
+
+  // How much to relocate for each pointer.
+  intx _delta;
+
+  // The following fields are used only when COMPACTING == true;
+  // The highest offset (inclusive) in the bitmap that contains a non-null pointer.
+  // This is used at dump time to reduce the size of the bitmap (which may have been over-allocated).
+  size_t _max_non_null_offset;
+  CHeapBitMap* _ptrmap;
+
+ public:
+  SharedDataRelocator(address* patch_base, address* patch_end,
+                      address valid_old_base, address valid_old_end,
+                      address valid_new_base, address valid_new_end, intx delta,
+                      CHeapBitMap* ptrmap = NULL) :
+    _patch_base(patch_base), _patch_end(patch_end),
+    _valid_old_base(valid_old_base), _valid_old_end(valid_old_end),
+    _valid_new_base(valid_new_base), _valid_new_end(valid_new_end),
+    _delta(delta) {
+    log_debug(cds, reloc)("SharedDataRelocator::_patch_base     = " PTR_FORMAT, p2i(_patch_base));
+    log_debug(cds, reloc)("SharedDataRelocator::_patch_end      = " PTR_FORMAT, p2i(_patch_end));
+    log_debug(cds, reloc)("SharedDataRelocator::_valid_old_base = " PTR_FORMAT, p2i(_valid_old_base));
+    log_debug(cds, reloc)("SharedDataRelocator::_valid_old_end  = " PTR_FORMAT, p2i(_valid_old_end));
+    log_debug(cds, reloc)("SharedDataRelocator::_valid_new_base = " PTR_FORMAT, p2i(_valid_new_base));
+    log_debug(cds, reloc)("SharedDataRelocator::_valid_new_end  = " PTR_FORMAT, p2i(_valid_new_end));
+    if (COMPACTING) {
+      assert(ptrmap != NULL, "must be");
+      _max_non_null_offset = 0;
+      _ptrmap = ptrmap;
+    } else {
+      // Don't touch the _max_non_null_offset and _ptrmap fields. Hopefully a good C++ compiler can
+      // elide them.
+      assert(ptrmap == NULL, "must be");
+    }
+  }
+
+  size_t max_non_null_offset() {
+    assert(COMPACTING, "must be");
+    return _max_non_null_offset;
+  }
+
+  inline bool do_bit(size_t offset);
+};
+
+
+#endif // SHARE_MEMORY_ARCHIVEUTILS_HPP
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/memory/archiveUtils.inline.hpp	Mon Nov 18 12:40:06 2019 -0500
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#ifndef SHARE_MEMORY_ARCHIVEUTILS_INLINE_HPP
+#define SHARE_MEMORY_ARCHIVEUTILS_INLINE_HPP
+
+#include "memory/archiveUtils.hpp"
+#include "utilities/bitMap.inline.hpp"
+
+template <bool COMPACTING>
+inline bool SharedDataRelocator<COMPACTING>::do_bit(size_t offset) {
+  address* p = _patch_base + offset;
+  assert(_patch_base <= p && p < _patch_end, "must be");
+
+  address old_ptr = *p;
+  assert(_valid_old_base <= old_ptr && old_ptr < _valid_old_end, "must be");
+
+  if (COMPACTING) {
+    // Start-up performance: use a template parameter to elide this block for run-time archive
+    // relocation.
+    assert(Arguments::is_dumping_archive(), "Don't do this during run-time archive loading!");
+    if (old_ptr == NULL) {
+      _ptrmap->clear_bit(offset);
+      DEBUG_ONLY(log_trace(cds, reloc)("Clearing pointer [" PTR_FORMAT  "] -> NULL @ " SIZE_FORMAT_W(9), p2i(p), offset));
+      return true;
+    } else {
+      _max_non_null_offset = offset;
+    }
+  } else {
+    assert(old_ptr != NULL, "bits for NULL pointers should have been cleaned at dump time");
+  }
+
+  address new_ptr = old_ptr + _delta;
+  assert(_valid_new_base <= new_ptr && new_ptr < _valid_new_end, "must be");
+
+  DEBUG_ONLY(log_trace(cds, reloc)("Patch2: @%8d [" PTR_FORMAT "] " PTR_FORMAT " -> " PTR_FORMAT,
+                                   (int)offset, p2i(p), p2i(old_ptr), p2i(new_ptr)));
+  *p = new_ptr;
+  return true; // keep iterating
+}
+
+#endif // SHARE_MEMORY_ARCHIVEUTILS_INLINE_HPP
--- a/src/hotspot/share/memory/dynamicArchive.cpp	Wed Nov 13 17:21:31 2019 -0500
+++ b/src/hotspot/share/memory/dynamicArchive.cpp	Mon Nov 18 12:40:06 2019 -0500
@@ -29,12 +29,13 @@
 #include "classfile/systemDictionary.hpp"
 #include "classfile/systemDictionaryShared.hpp"
 #include "logging/log.hpp"
+#include "memory/archiveUtils.inline.hpp"
+#include "memory/dynamicArchive.hpp"
 #include "memory/metadataFactory.hpp"
 #include "memory/metaspace.hpp"
 #include "memory/metaspaceClosure.hpp"
 #include "memory/metaspaceShared.hpp"
 #include "memory/resourceArea.hpp"
-#include "memory/dynamicArchive.hpp"
 #include "oops/compressedOops.hpp"
 #include "oops/objArrayKlass.hpp"
 #include "prims/jvmtiRedefineClasses.hpp"
@@ -50,7 +51,6 @@
 #endif
 
 class DynamicArchiveBuilder : ResourceObj {
-  CHeapBitMap _ptrmap;
   static unsigned my_hash(const address& a) {
     return primitive_hash<address>(a);
   }
@@ -64,7 +64,7 @@
       16384, ResourceObj::C_HEAP> RelocationTable;
   RelocationTable _new_loc_table;
 
-  intx _buffer_to_target_delta;
+  static intx _buffer_to_target_delta;
 
   DumpRegion* _current_dump_space;
 
@@ -77,10 +77,7 @@
 
 public:
   void mark_pointer(address* ptr_loc) {
-    if (is_in_buffer_space(ptr_loc)) {
-      size_t idx = pointer_delta(ptr_loc, _alloc_bottom, sizeof(address));
-      _ptrmap.set_bit(idx);
-    }
+    ArchivePtrMarker::mark_pointer(ptr_loc);
   }
 
   DumpRegion* current_dump_space() const {
@@ -128,6 +125,28 @@
     return pp != NULL;
   }
 
+  static int dynamic_dump_method_comparator(Method* a, Method* b) {
+    Symbol* a_name = a->name();
+    Symbol* b_name = b->name();
+
+    if (a_name == b_name) {
+      return 0;
+    }
+
+    if (!MetaspaceShared::is_in_shared_metaspace(a_name)) {
+      // a_name points to a Symbol in the top archive.
+      // When this method is called, a_name is still pointing to the output space.
+      // Translate it to point to the output space, so that it can be compared with
+      // Symbols in the base archive.
+      a_name = (Symbol*)(address(a_name) + _buffer_to_target_delta);
+    }
+    if (!MetaspaceShared::is_in_shared_metaspace(b_name)) {
+      b_name = (Symbol*)(address(b_name) + _buffer_to_target_delta);
+    }
+
+    return a_name->fast_compare(b_name);
+  }
+
 protected:
   enum FollowMode {
     make_a_copy, point_to_it, set_to_null
@@ -240,6 +259,16 @@
 
       return true; // keep recursing until every object is visited exactly once.
     }
+
+    virtual void push_special(SpecialRef type, Ref* ref, intptr_t* p) {
+      assert(type == _method_entry_ref, "only special type allowed for now");
+      address obj = ref->obj();
+      address new_obj = _builder->get_new_loc(ref);
+      size_t offset = pointer_delta(p, obj,  sizeof(u1));
+      intptr_t* new_p = (intptr_t*)(new_obj + offset);
+      assert(*p == *new_p, "must be a copy");
+      ArchivePtrMarker::mark_pointer((address*)new_p);
+    }
   };
 
   class EmbeddedRefUpdater: public MetaspaceClosure {
@@ -331,7 +360,7 @@
   public:
     EmbeddedRefMarker(DynamicArchiveBuilder* shuffler) : _builder(shuffler) {}
     virtual bool do_ref(Ref* ref, bool read_only) {
-      if (ref->not_null() && _builder->is_in_buffer_space(ref->obj())) {
+      if (ref->not_null()) {
         _builder->mark_pointer(ref->addr());
       }
       return false; // Do not recurse.
@@ -441,10 +470,10 @@
                             p2i(obj), p2i(p), bytes,
                             MetaspaceObj::type_name(ref->msotype()));
     memcpy(p, obj, bytes);
-
     intptr_t* cloned_vtable = MetaspaceShared::fix_cpp_vtable_for_dynamic_archive(ref->msotype(), p);
     if (cloned_vtable != NULL) {
       update_pointer((address*)p, (address)cloned_vtable, "vtb", 0, /*is_mso_pointer*/false);
+      mark_pointer((address*)p);
     }
 
     return (address)p;
@@ -551,6 +580,9 @@
     address reserved_bottom = reserve_space_and_init_buffer_to_target_delta();
     init_header(reserved_bottom);
 
+    CHeapBitMap ptrmap;
+    ArchivePtrMarker::initialize(&ptrmap, (address*)reserved_bottom, (address*)current_dump_space()->top());
+
     verify_estimate_size(sizeof(DynamicArchiveHeader), "header");
 
     log_info(cds, dynamic)("Copying %d klasses and %d symbols",
@@ -576,10 +608,6 @@
       iterate_roots(&ro_copier);
     }
 
-    size_t bitmap_size = pointer_delta(current_dump_space()->top(),
-                                       _alloc_bottom, sizeof(address));
-    _ptrmap.initialize(bitmap_size);
-
     {
       log_info(cds)("Relocating embedded pointers ... ");
       ResourceMark rm;
@@ -653,7 +681,7 @@
       it->push(&_symbols->at(i));
     }
 
-    _header->shared_path_table_metaspace_pointers_do(it);
+    FileMapInfo::metaspace_pointers_do(it);
 
     // Do not call these again, as we have already collected all the classes and symbols
     // that we want to archive. Also, these calls would corrupt the tables when
@@ -666,6 +694,9 @@
   }
 };
 
+intx DynamicArchiveBuilder::_buffer_to_target_delta;
+
+
 size_t DynamicArchiveBuilder::estimate_archive_size() {
   // size of the symbol table and two dictionaries, plus the RunTimeSharedClassInfo's
   _estimated_hashtable_bytes = 0;
@@ -688,26 +719,16 @@
 
 address DynamicArchiveBuilder::reserve_space_and_init_buffer_to_target_delta() {
   size_t total = estimate_archive_size();
-  bool large_pages = false; // No large pages when dumping the CDS archive.
-  size_t increment = align_up(1*G, reserve_alignment());
-  char* addr = (char*)align_up(CompressedKlassPointers::base() + MetaspaceSize + increment,
-                               reserve_alignment());
-
-  ReservedSpace* rs = MetaspaceShared::reserve_shared_rs(
-                          total, reserve_alignment(), large_pages, addr);
-  while (!rs->is_reserved() && (addr + increment > addr)) {
-    addr += increment;
-    rs = MetaspaceShared::reserve_shared_rs(
-           total, reserve_alignment(), large_pages, addr);
-  }
-  if (!rs->is_reserved()) {
+  ReservedSpace rs = MetaspaceShared::reserve_shared_space(total);
+  if (!rs.is_reserved()) {
     log_error(cds, dynamic)("Failed to reserve %d bytes of output buffer.", (int)total);
     vm_direct_exit(0);
   }
 
-  address buffer_base = (address)rs->base();
+  address buffer_base = (address)rs.base();
   log_info(cds, dynamic)("Reserved output buffer space at    : " PTR_FORMAT " [%d bytes]",
                          p2i(buffer_base), (int)total);
+  MetaspaceShared::set_shared_rs(rs);
 
   // At run time, we will mmap the dynamic archive at target_space_bottom.
   // However, at dump time, we may not be able to write into the target_space,
@@ -788,6 +809,7 @@
 void DynamicArchiveBuilder::make_klasses_shareable() {
   int i, count = _klasses->length();
 
+  InstanceKlass::disable_method_binary_search();
   for (i = 0; i < count; i++) {
     InstanceKlass* ik = _klasses->at(i);
     sort_methods(ik);
@@ -847,18 +869,24 @@
   }
 
 #ifdef ASSERT
-  {
+  if (ik->methods() != NULL) {
     for (int m = 0; m < ik->methods()->length(); m++) {
       Symbol* name = ik->methods()->at(m)->name();
       assert(MetaspaceShared::is_in_shared_metaspace(name) || is_in_buffer_space(name), "must be");
     }
   }
+  if (ik->default_methods() != NULL) {
+    for (int m = 0; m < ik->default_methods()->length(); m++) {
+      Symbol* name = ik->default_methods()->at(m)->name();
+      assert(MetaspaceShared::is_in_shared_metaspace(name) || is_in_buffer_space(name), "must be");
+    }
+  }
 #endif
 
   Thread* THREAD = Thread::current();
-  Method::sort_methods(ik->methods());
+  Method::sort_methods(ik->methods(), /*set_idnums=*/true, dynamic_dump_method_comparator);
   if (ik->default_methods() != NULL) {
-    Method::sort_methods(ik->default_methods(), /*set_idnums=*/false);
+    Method::sort_methods(ik->default_methods(), /*set_idnums=*/false, dynamic_dump_method_comparator);
   }
   ik->vtable().initialize_vtable(true, THREAD); assert(!HAS_PENDING_EXCEPTION, "cannot fail");
   ik->itable().initialize_itable(true, THREAD); assert(!HAS_PENDING_EXCEPTION, "cannot fail");
@@ -902,14 +930,60 @@
   }
 };
 
-
 void DynamicArchiveBuilder::relocate_buffer_to_target() {
   RelocateBufferToTarget patcher(this, (address*)_alloc_bottom, _buffer_to_target_delta);
-  _ptrmap.iterate(&patcher);
+  ArchivePtrMarker::ptrmap()->iterate(&patcher);
+
+  Array<u8>* table = FileMapInfo::shared_path_table().table();
+  SharedPathTable runtime_table(to_target(table), FileMapInfo::shared_path_table().size());
+  _header->set_shared_path_table(runtime_table);
+
+  address relocatable_base = (address)SharedBaseAddress;
+  address relocatable_end = (address)(current_dump_space()->top()) + _buffer_to_target_delta;
+
+  intx addr_delta = MetaspaceShared::final_delta();
+  if (addr_delta == 0) {
+    ArchivePtrMarker::compact(relocatable_base, relocatable_end);
+  } else {
+    // The base archive is NOT mapped at Arguments::default_SharedBaseAddress() (due to ASLR).
+    // This means that the current content of the dynamic archive is based on a random
+    // address. Let's relocate all the pointers, so that it can be mapped to
+    // Arguments::default_SharedBaseAddress() without runtime relocation.
+    //
+    // Note: both the base and dynamic archive are written with
+    // FileMapHeader::_shared_base_address == Arguments::default_SharedBaseAddress()
+
+    // Patch all pointers that are marked by ptrmap within this region,
+    // where we have just dumped all the metaspace data.
+    address patch_base = (address)_alloc_bottom;
+    address patch_end  = (address)current_dump_space()->top();
 
-  Array<u8>* table = _header->shared_path_table().table();
-  table = to_target(table);
- _header->relocate_shared_path_table(table);
+    // the current value of the pointers to be patched must be within this
+    // range (i.e., must point to either the top archive (as currently mapped), or to the
+    // (targeted address of) the top archive)
+    address valid_old_base = relocatable_base;
+    address valid_old_end  = relocatable_end;
+    size_t base_plus_top_size = valid_old_end - valid_old_base;
+    size_t top_size = patch_end - patch_base;
+    size_t base_size = base_plus_top_size - top_size;
+    assert(base_plus_top_size > base_size, "no overflow");
+    assert(base_plus_top_size > top_size, "no overflow");
+
+    // after patching, the pointers must point inside this range
+    // (the requested location of the archive, as mapped at runtime).
+    address valid_new_base = (address)Arguments::default_SharedBaseAddress();
+    address valid_new_end  = valid_new_base + base_plus_top_size;
+
+    log_debug(cds)("Relocating archive from [" INTPTR_FORMAT " - " INTPTR_FORMAT "] to "
+                   "[" INTPTR_FORMAT " - " INTPTR_FORMAT "], delta = " INTX_FORMAT " bytes",
+                   p2i(patch_base + base_size), p2i(patch_end),
+                   p2i(valid_new_base + base_size), p2i(valid_new_end), addr_delta);
+
+    SharedDataRelocator<true> patcher((address*)patch_base, (address*)patch_end, valid_old_base, valid_old_end,
+                                      valid_new_base, valid_new_end, addr_delta, ArchivePtrMarker::ptrmap());
+    ArchivePtrMarker::ptrmap()->iterate(&patcher);
+    ArchivePtrMarker::compact(patcher.max_non_null_offset());
+  }
 }
 
 void DynamicArchiveBuilder::write_regions(FileMapInfo* dynamic_info) {
@@ -925,6 +999,7 @@
                              MetaspaceShared::misc_code_dump_space()->base(),
                              MetaspaceShared::misc_code_dump_space()->used(),
                              /*read_only=*/false,/*allow_exec=*/true);
+  dynamic_info->write_bitmap_region(ArchivePtrMarker::ptrmap());
 }
 
 void DynamicArchiveBuilder::write_archive(char* serialized_data_start) {
@@ -940,6 +1015,7 @@
   const char* archive_name = Arguments::GetSharedDynamicArchivePath();
   dynamic_info->open_for_write(archive_name);
   write_regions(dynamic_info);
+  dynamic_info->set_final_requested_base((char*)Arguments::default_SharedBaseAddress());
   dynamic_info->set_header_crc(dynamic_info->compute_header_crc());
   dynamic_info->write_header();
   dynamic_info->close();
@@ -948,6 +1024,8 @@
   address top  = address(current_dump_space()->top()) + _buffer_to_target_delta;
   size_t file_size = pointer_delta(top, base, sizeof(char));
 
+  base += MetaspaceShared::final_delta();
+  top += MetaspaceShared::final_delta();
   log_info(cds, dynamic)("Written dynamic archive " PTR_FORMAT " - " PTR_FORMAT
                          " [" SIZE_FORMAT " bytes header, " SIZE_FORMAT " bytes total]",
                          p2i(base), p2i(top), _header->header_size(), file_size);
@@ -1036,79 +1114,8 @@
 }
 
 
-static DynamicArchiveHeader *_dynamic_header = NULL;
 DynamicArchiveBuilder* DynamicArchive::_builder = NULL;
 
-void DynamicArchive::map_failed(FileMapInfo* mapinfo) {
-  if (mapinfo->dynamic_header() != NULL) {
-    os::free((void*)mapinfo->dynamic_header());
-  }
-  delete mapinfo;
-}
-
-// Returns the top of the mapped address space
-address DynamicArchive::map() {
-  assert(UseSharedSpaces, "Sanity");
-
-  // Create the dynamic archive map info
-  FileMapInfo* mapinfo;
-  const char* filename = Arguments::GetSharedDynamicArchivePath();
-  struct stat st;
-  address result;
-  if ((filename != NULL) && (os::stat(filename, &st) == 0)) {
-    mapinfo = new FileMapInfo(false);
-    if (!mapinfo->open_for_read(filename)) {
-      result = NULL;
-    }
-    result = map_impl(mapinfo);
-    if (result == NULL) {
-      map_failed(mapinfo);
-      mapinfo->restore_shared_path_table();
-    }
-  } else {
-    if (filename != NULL) {
-      log_warning(cds, dynamic)("specified dynamic archive doesn't exist: %s", filename);
-    }
-    result = NULL;
-  }
-  return result;
-}
-
-address DynamicArchive::map_impl(FileMapInfo* mapinfo) {
-  // Read header
-  if (!mapinfo->initialize(false)) {
-    return NULL;
-  }
-
-  _dynamic_header = mapinfo->dynamic_header();
-  int regions[] = {MetaspaceShared::rw,
-                   MetaspaceShared::ro,
-                   MetaspaceShared::mc};
-
-  size_t len = sizeof(regions)/sizeof(int);
-  char* saved_base[] = {NULL, NULL, NULL};
-  char* top = mapinfo->map_regions(regions, saved_base, len);
-  if (top == NULL) {
-    mapinfo->unmap_regions(regions, saved_base, len);
-    FileMapInfo::fail_continue("Unable to use dynamic archive. Failed map_region for using -Xshare:on.");
-    return NULL;
-  }
-
-  if (!validate(mapinfo)) {
-    return NULL;
-  }
-
-  if (_dynamic_header == NULL) {
-    return NULL;
-  }
-
-  intptr_t* buffer = (intptr_t*)_dynamic_header->serialized_data_start();
-  ReadClosure rc(&buffer);
-  SymbolTable::serialize_shared_table_header(&rc, false);
-  SystemDictionaryShared::serialize_dictionary_headers(&rc, false);
-
-  return (address)top;
-}
 
 bool DynamicArchive::validate(FileMapInfo* dynamic_info) {
   // Check if the recorded base archive matches with the current one
@@ -1136,11 +1143,3 @@
   }
   return true;
 }
-
-bool DynamicArchive::is_mapped() {
-  return (_dynamic_header != NULL);
-}
-
-void DynamicArchive::disable() {
-  _dynamic_header = NULL;
-}
--- a/src/hotspot/share/memory/dynamicArchive.hpp	Wed Nov 13 17:21:31 2019 -0500
+++ b/src/hotspot/share/memory/dynamicArchive.hpp	Mon Nov 18 12:40:06 2019 -0500
@@ -99,13 +99,8 @@
   // archive?
   static bool is_in_target_space(void *obj);
 
-  static address map();
-  static bool is_mapped();
+  static bool is_mapped() { return FileMapInfo::dynamic_info() != NULL; }
   static bool validate(FileMapInfo* dynamic_info);
-  static void disable();
-private:
-  static address map_impl(FileMapInfo* mapinfo);
-  static void map_failed(FileMapInfo* mapinfo);
 };
 #endif // INCLUDE_CDS
 #endif // SHARE_VM_MEMORY_DYNAMICARCHIVE_HPP
--- a/src/hotspot/share/memory/filemap.cpp	Wed Nov 13 17:21:31 2019 -0500
+++ b/src/hotspot/share/memory/filemap.cpp	Mon Nov 18 12:40:06 2019 -0500
@@ -34,6 +34,7 @@
 #include "logging/log.hpp"
 #include "logging/logStream.hpp"
 #include "logging/logMessage.hpp"
+#include "memory/archiveUtils.inline.hpp"
 #include "memory/dynamicArchive.hpp"
 #include "memory/filemap.hpp"
 #include "memory/heapShared.inline.hpp"
@@ -55,6 +56,7 @@
 #include "runtime/vm_version.hpp"
 #include "services/memTracker.hpp"
 #include "utilities/align.hpp"
+#include "utilities/bitMap.inline.hpp"
 #include "utilities/classpathStream.hpp"
 #include "utilities/defaultStream.hpp"
 #if INCLUDE_G1GC
@@ -69,9 +71,6 @@
 #define O_BINARY 0     // otherwise do nothing.
 #endif
 
-extern address JVM_FunctionAtStart();
-extern address JVM_FunctionAtEnd();
-
 // Complain and stop. All error conditions occurring during the writing of
 // an archive file should stop the process.  Unrecoverable errors during
 // the reading of the archive file should stop the process.
@@ -104,12 +103,6 @@
 void FileMapInfo::fail_continue(const char *msg, ...) {
   va_list ap;
   va_start(ap, msg);
-  if (_dynamic_archive_info == NULL) {
-    MetaspaceShared::set_archive_loading_failed();
-  } else {
-    // _dynamic_archive_info has been setup after mapping the base archive
-    DynamicArchive::disable();
-  }
   if (PrintSharedArchiveAndExit && _validating_shared_path_table) {
     // If we are doing PrintSharedArchiveAndExit and some of the classpath entries
     // do not validate, we can still continue "limping" to validate the remaining
@@ -128,15 +121,6 @@
         ls.vprint_cr(msg, ap);
       }
     }
-    if (_dynamic_archive_info == NULL) {
-      UseSharedSpaces = false;
-      assert(current_info() != NULL, "singleton must be registered");
-      current_info()->close();
-    } else {
-      // We are failing when loading the top archive, but the base archive should
-      // continue to work.
-      log_warning(cds, dynamic)("Unable to use shared archive. The top archive failed to load: %s", _dynamic_archive_info->_full_path);
-    }
   }
   va_end(ap);
 }
@@ -227,9 +211,7 @@
   _narrow_oop_base = CompressedOops::base();
   _narrow_oop_shift = CompressedOops::shift();
   _max_heap_size = MaxHeapSize;
-  _narrow_klass_base = CompressedKlassPointers::base();
   _narrow_klass_shift = CompressedKlassPointers::shift();
-  _shared_path_table = mapinfo->_shared_path_table;
   if (HeapShared::is_heap_object_archiving_allowed()) {
     _heap_end = CompressedOops::end();
   }
@@ -249,11 +231,16 @@
   _verify_local = BytecodeVerificationLocal;
   _verify_remote = BytecodeVerificationRemote;
   _has_platform_or_app_classes = ClassLoaderExt::has_platform_or_app_classes();
-  _shared_base_address = SharedBaseAddress;
+  _requested_base_address = (char*)SharedBaseAddress;
+  _mapped_base_address = (char*)SharedBaseAddress;
   _allow_archiving_with_java_agent = AllowArchivingWithJavaAgent;
   // the following 2 fields will be set in write_header for dynamic archive header
   _base_archive_name_size = 0;
   _base_archive_is_default = false;
+
+  if (!DynamicDumpSharedSpaces) {
+    set_shared_path_table(mapinfo->_shared_path_table);
+  }
 }
 
 void SharedClassPathEntry::init_as_non_existent(const char* path, TRAPS) {
@@ -615,9 +602,11 @@
   return path_array;
 }
 
-bool FileMapInfo::fail(const char* msg, const char* name) {
+bool FileMapInfo::classpath_failure(const char* msg, const char* name) {
   ClassLoader::trace_class_path(msg, name);
-  MetaspaceShared::set_archive_loading_failed();
+  if (PrintSharedArchiveAndExit) {
+    MetaspaceShared::set_archive_loading_failed();
+  }
   return false;
 }
 
@@ -692,7 +681,7 @@
 
   if (mismatch) {
     // The paths are different
-    return fail("[BOOT classpath mismatch, actual =", runtime_boot_path);
+    return classpath_failure("[BOOT classpath mismatch, actual =", runtime_boot_path);
   }
   return true;
 }
@@ -703,7 +692,7 @@
   int rp_len = num_paths(appcp);
   bool mismatch = false;
   if (rp_len < shared_app_paths_len) {
-    return fail("Run time APP classpath is shorter than the one at dump time: ", appcp);
+    return classpath_failure("Run time APP classpath is shorter than the one at dump time: ", appcp);
   }
   if (shared_app_paths_len != 0 && rp_len != 0) {
     // Prefix is OK: E.g., dump with -cp foo.jar, but run with -cp foo.jar:bar.jar.
@@ -711,7 +700,7 @@
     GrowableArray<const char*>* rp_array = create_path_array(appcp);
     if (rp_array->length() == 0) {
       // None of the jar file specified in the runtime -cp exists.
-      return fail("None of the jar file specified in the runtime -cp exists: -Djava.class.path=", appcp);
+      return classpath_failure("None of the jar file specified in the runtime -cp exists: -Djava.class.path=", appcp);
     }
 
     // Handling of non-existent entries in the classpath: we eliminate all the non-existent
@@ -726,7 +715,7 @@
     int j = header()->app_class_paths_start_index();
     mismatch = check_paths(j, shared_app_paths_len, rp_array);
     if (mismatch) {
-      return fail("[APP classpath mismatch, actual: -Djava.class.path=", appcp);
+      return classpath_failure("[APP classpath mismatch, actual: -Djava.class.path=", appcp);
     }
   }
   return true;
@@ -952,8 +941,8 @@
 
 // Read the FileMapInfo information from the file.
 
-bool FileMapInfo::init_from_file(int fd, bool is_static) {
-  size_t sz = is_static ? sizeof(FileMapHeader) : sizeof(DynamicArchiveHeader);
+bool FileMapInfo::init_from_file(int fd) {
+  size_t sz = is_static() ? sizeof(FileMapHeader) : sizeof(DynamicArchiveHeader);
   size_t n = os::read(fd, header(), (unsigned int)sz);
   if (n != sz) {
     fail_continue("Unable to read the file header.");
@@ -965,7 +954,7 @@
     return false;
   }
 
-  unsigned int expected_magic = is_static ? CDS_ARCHIVE_MAGIC : CDS_DYNAMIC_ARCHIVE_MAGIC;
+  unsigned int expected_magic = is_static() ? CDS_ARCHIVE_MAGIC : CDS_DYNAMIC_ARCHIVE_MAGIC;
   if (header()->magic() != expected_magic) {
     log_info(cds)("_magic expected: 0x%08x", expected_magic);
     log_info(cds)("         actual: 0x%08x", header()->magic());
@@ -1016,7 +1005,7 @@
 
   _file_offset = n + header()->base_archive_name_size(); // accounts for the size of _base_archive_name
 
-  if (is_static) {
+  if (is_static()) {
     // just checking the last region is sufficient since the archive is written
     // in sequential order
     size_t len = lseek(fd, 0, SEEK_END);
@@ -1026,8 +1015,6 @@
       fail_continue("The shared archive file has been truncated.");
       return false;
     }
-
-    SharedBaseAddress = header()->shared_base_address();
   }
 
   return true;
@@ -1040,23 +1027,27 @@
 }
 
 // Read the FileMapInfo information from the file.
-bool FileMapInfo::open_for_read(const char* path) {
+bool FileMapInfo::open_for_read() {
   if (_file_open) {
     return true;
   }
-  if (path == NULL) {
+  if (is_static()) {
     _full_path = Arguments::GetSharedArchivePath();
   } else {
-    _full_path = path;
+    _full_path = Arguments::GetSharedDynamicArchivePath();
   }
   int fd = os::open(_full_path, O_RDONLY | O_BINARY, 0);
   if (fd < 0) {
-    if (errno == ENOENT) {
-      // Not locating the shared archive is ok.
-      fail_continue("Specified shared archive not found (%s).", _full_path);
+    if (is_static()) {
+      if (errno == ENOENT) {
+        // Not locating the shared archive is ok.
+        fail_continue("Specified shared archive not found (%s).", _full_path);
+      } else {
+        fail_continue("Failed to open shared archive file (%s).",
+                      os::strerror(errno));
+      }
     } else {
-      fail_continue("Failed to open shared archive file (%s).",
-                    os::strerror(errno));
+      log_warning(cds, dynamic)("specified dynamic archive doesn't exist: %s", _full_path);
     }
     return false;
   }
@@ -1127,25 +1118,35 @@
   }
 }
 
-void FileMapRegion::init(bool is_heap_region, char* base, size_t size, bool read_only,
+size_t FileMapRegion::used_aligned() const {
+  return align_up(used(), os::vm_allocation_granularity());
+}
+
+void FileMapRegion::init(int region_index, char* base, size_t size, bool read_only,
                          bool allow_exec, int crc) {
-  _is_heap_region = is_heap_region;
+  _is_heap_region = HeapShared::is_heap_region(region_index);
+  _is_bitmap_region = (region_index == MetaspaceShared::bm);
+  _mapping_offset = 0;
 
-  if (is_heap_region) {
+  if (_is_heap_region) {
     assert(!DynamicDumpSharedSpaces, "must be");
     assert((base - (char*)CompressedKlassPointers::base()) % HeapWordSize == 0, "Sanity");
     if (base != NULL) {
-      _addr._offset = (intx)CompressedOops::encode_not_null((oop)base);
-    } else {
-      _addr._offset = 0;
+      _mapping_offset = (size_t)CompressedOops::encode_not_null((oop)base);
+      assert(_mapping_offset >> 32 == 0, "must be 32-bit only");
     }
   } else {
-    _addr._base = base;
+    if (base != NULL) {
+      assert(base >= (char*)SharedBaseAddress, "must be");
+      _mapping_offset = base - (char*)SharedBaseAddress;
+    }
   }
   _used = size;
   _read_only = read_only;
   _allow_exec = allow_exec;
   _crc = crc;
+  _mapped_from_file = false;
+  _mapped_base = NULL;
 }
 
 void FileMapInfo::write_region(int region, char* base, size_t size,
@@ -1153,25 +1154,47 @@
   Arguments::assert_is_dumping_archive();
 
   FileMapRegion* si = space_at(region);
-  char* target_base = base;
-  if (DynamicDumpSharedSpaces) {
-    assert(!HeapShared::is_heap_region(region), "dynamic archive doesn't support heap regions");
-    target_base = DynamicArchive::buffer_to_target(base);
+  char* target_base;
+
+  if (region == MetaspaceShared::bm) {
+    target_base = NULL; // always NULL for bm region.
+  } else {
+    if (DynamicDumpSharedSpaces) {
+      assert(!HeapShared::is_heap_region(region), "dynamic archive doesn't support heap regions");
+      target_base = DynamicArchive::buffer_to_target(base);
+    } else {
+      target_base = base;
+    }
   }
 
   si->set_file_offset(_file_offset);
-  log_info(cds)("Shared file region %d: " SIZE_FORMAT_HEX_W(08)
+  char* requested_base = (target_base == NULL) ? NULL : target_base + MetaspaceShared::final_delta();
+  log_info(cds)("Shared file region  %d: " SIZE_FORMAT_HEX_W(08)
                 " bytes, addr " INTPTR_FORMAT " file offset " SIZE_FORMAT_HEX_W(08),
-                region, size, p2i(target_base), _file_offset);
+                region, size, p2i(requested_base), _file_offset);
 
   int crc = ClassLoader::crc32(0, base, (jint)size);
-  si->init(HeapShared::is_heap_region(region), target_base, size, read_only, allow_exec, crc);
+  si->init(region, target_base, size, read_only, allow_exec, crc);
 
   if (base != NULL) {
     write_bytes_aligned(base, size);
   }
 }
 
+
+void FileMapInfo::write_bitmap_region(const CHeapBitMap* ptrmap) {
+  ResourceMark rm;
+  size_t size_in_bits = ptrmap->size();
+  size_t size_in_bytes = ptrmap->size_in_bytes();
+  uintptr_t* buffer = (uintptr_t*)NEW_RESOURCE_ARRAY(char, size_in_bytes);
+  ptrmap->write_to(buffer, size_in_bytes);
+  header()->set_ptrmap_size_in_bits(size_in_bits);
+
+  log_info(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);
+}
+
 // Write out the given archive heap memory regions.  GC code combines multiple
 // consecutive archive GC regions into one MemRegion whenever possible and
 // produces the 'heap_mem' array.
@@ -1229,11 +1252,13 @@
       total_size += size;
     }
 
-    log_info(cds)("Archive heap region %d " INTPTR_FORMAT " - " INTPTR_FORMAT " = " SIZE_FORMAT_W(8) " bytes",
+    log_info(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);
     if (size > 0) {
-      space_at(i)->init_oopmap(oopmaps->at(arr_idx)._oopmap,
+      address oopmap = oopmaps->at(arr_idx)._oopmap;
+      assert(oopmap >= (address)SharedBaseAddress, "must be");
+      space_at(i)->init_oopmap(oopmap - (address)SharedBaseAddress,
                                oopmaps->at(arr_idx)._oopmap_size_in_bits);
     }
   }
@@ -1285,6 +1310,9 @@
   align_file_position();
 }
 
+void FileMapInfo::set_final_requested_base(char* b) {
+  header()->set_final_requested_base(b);
+}
 
 // Close the shared archive file.  This does NOT unmap mapped regions.
 
@@ -1331,94 +1359,197 @@
   return true;
 }
 
-// Map the whole region at once, assumed to be allocated contiguously.
-ReservedSpace FileMapInfo::reserve_shared_memory() {
-  char* requested_addr = region_addr(0);
-  size_t size = FileMapInfo::core_spaces_size();
-
-  // Reserve the space first, then map otherwise map will go right over some
-  // other reserved memory (like the code cache).
-  ReservedSpace rs(size, os::vm_allocation_granularity(), false, requested_addr);
-  if (!rs.is_reserved()) {
-    fail_continue("Unable to reserve shared space at required address "
-                  INTPTR_FORMAT, p2i(requested_addr));
-    return rs;
-  }
-  // the reserved virtual memory is for mapping class data sharing archive
-  MemTracker::record_virtual_memory_type((address)rs.base(), mtClassShared);
-
-  return rs;
-}
-
 // Memory map a region in the address space.
-static const char* shared_region_name[] = { "MiscData", "ReadWrite", "ReadOnly", "MiscCode",
+static const char* shared_region_name[] = { "MiscData", "ReadWrite", "ReadOnly", "MiscCode", "Bitmap",
                                             "String1", "String2", "OpenArchive1", "OpenArchive2" };
 
-char* FileMapInfo::map_regions(int regions[], char* saved_base[], size_t len) {
-  char* prev_top = NULL;
-  char* curr_base;
-  char* curr_top;
-  int i = 0;
-  for (i = 0; i < (int)len; i++) {
-    curr_base = map_region(regions[i], &curr_top);
-    if (curr_base == NULL) {
-      return NULL;
+MapArchiveResult FileMapInfo::map_regions(int regions[], int num_regions, char* mapped_base_address, ReservedSpace rs) {
+  DEBUG_ONLY(FileMapRegion* last_region = NULL);
+  intx addr_delta = mapped_base_address - header()->requested_base_address();
+
+  // Make sure we don't attempt to use header()->mapped_base_address() unless
+  // it's been successfully mapped.
+  DEBUG_ONLY(header()->set_mapped_base_address((char*)(uintptr_t)0xdeadbeef);)
+
+  for (int r = 0; r < num_regions; r++) {
+    int idx = regions[r];
+    MapArchiveResult result = map_region(idx, addr_delta, mapped_base_address, rs);
+    if (result != MAP_ARCHIVE_SUCCESS) {
+      return result;
     }
-    if (i > 0) {
-      // We require that mc->rw->ro->md to be laid out consecutively, with no
-      // gaps between them. That way, we can ensure that the OS won't be able to
-      // allocate any new memory spaces inside _shared_metaspace_{base,top}, which
-      // would mess up the simple comparision in MetaspaceShared::is_in_shared_metaspace().
-      assert(curr_base == prev_top, "must be");
-    }
-    log_info(cds)("Mapped region #%d at base %p top %p", regions[i], curr_base, curr_top);
-    saved_base[i] = curr_base;
-    prev_top = curr_top;
+    FileMapRegion* si = space_at(idx);
+    DEBUG_ONLY(if (last_region != NULL) {
+        // Ensure that the OS won't be able to allocate new memory spaces between any mapped
+        // regions, or else it would mess up the simple comparision in MetaspaceObj::is_shared().
+        assert(si->mapped_base() == last_region->mapped_end(), "must have no gaps");
+      }
+      last_region = si;)
+    log_info(cds)("Mapped %s region #%d at base " INTPTR_FORMAT " top " INTPTR_FORMAT " (%s)", is_static() ? "static " : "dynamic",
+                  idx, p2i(si->mapped_base()), p2i(si->mapped_end()),
+                  shared_region_name[idx]);
+
   }
-  return curr_top;
+
+  DEBUG_ONLY(if (addr_delta == 0 && ArchiveRelocationMode == 1) {
+      // This is for simulating mmap failures at the requested address. We do it here (instead
+      // of MetaspaceShared::map_archives) so we can thoroughly test the code for failure handling
+      // (releasing all allocated resource, etc).
+      log_info(cds)("ArchiveRelocationMode == 1: always map archive(s) at an alternative address");
+      return MAP_ARCHIVE_MMAP_FAILURE;
+    });
+
+  header()->set_mapped_base_address(header()->requested_base_address() + addr_delta);
+  if (addr_delta != 0 && !relocate_pointers(addr_delta)) {
+    return MAP_ARCHIVE_OTHER_FAILURE;
+  }
+
+  return MAP_ARCHIVE_SUCCESS;
 }
 
-char* FileMapInfo::map_region(int i, char** top_ret) {
+bool FileMapInfo::read_region(int i, char* base, size_t size) {
+  assert(MetaspaceShared::use_windows_memory_mapping(), "used by windows only");
+  FileMapRegion* si = space_at(i);
+  log_info(cds)("Commit %s region #%d at base " INTPTR_FORMAT " top " INTPTR_FORMAT " (%s)%s",
+                is_static() ? "static " : "dynamic", i, p2i(base), p2i(base + size),
+                shared_region_name[i], si->allow_exec() ? " exec" : "");
+  if (!os::commit_memory(base, size, si->allow_exec())) {
+    log_error(cds)("Failed to commit %s region #%d (%s)", is_static() ? "static " : "dynamic",
+                   i, shared_region_name[i]);
+    return false;
+  }
+  if (lseek(_fd, (long)si->file_offset(), SEEK_SET) != (int)si->file_offset() ||
+      read_bytes(base, size) != size) {
+    return false;
+  }
+  return true;
+}
+
+MapArchiveResult FileMapInfo::map_region(int i, intx addr_delta, char* mapped_base_address, ReservedSpace rs) {
   assert(!HeapShared::is_heap_region(i), "sanity");
   FileMapRegion* si = space_at(i);
-  size_t used = si->used();
-  size_t alignment = os::vm_allocation_granularity();
-  size_t size = align_up(used, alignment);
-  char *requested_addr = region_addr(i);
+  size_t size = si->used_aligned();
+  char *requested_addr = mapped_base_address + si->mapping_offset();
+  assert(si->mapped_base() == NULL, "must be not mapped yet");
+  assert(requested_addr != NULL, "must be specified");
+
+  si->set_mapped_from_file(false);
 
-#ifdef _WINDOWS
-  // Windows cannot remap read-only shared memory to read-write when required for
-  // RedefineClasses, which is also used by JFR.  Always map windows regions as RW.
-  si->set_read_only(false);
-#else
-  // If a tool agent is in use (debugging enabled), or JFR, we must map the address space RW
-  if (JvmtiExport::can_modify_any_class() || JvmtiExport::can_walk_any_space() ||
-      Arguments::has_jfr_option()) {
+  if (MetaspaceShared::use_windows_memory_mapping()) {
+    // Windows cannot remap read-only shared memory to read-write when required for
+    // RedefineClasses, which is also used by JFR.  Always map windows regions as RW.
+    si->set_read_only(false);
+  } else if (JvmtiExport::can_modify_any_class() || JvmtiExport::can_walk_any_space() ||
+             Arguments::has_jfr_option()) {
+    // If a tool agent is in use (debugging enabled), or JFR, we must map the address space RW
     si->set_read_only(false);
+  } else if (addr_delta != 0) {
+    si->set_read_only(false); // Need to patch the pointers
+  }
+
+  if (rs.is_reserved()) {
+    assert(rs.contains(requested_addr) && rs.contains(requested_addr + size - 1), "must be");
+    MemTracker::record_virtual_memory_type((address)requested_addr, mtClassShared);
   }
-#endif // _WINDOWS
 
-  // map the contents of the CDS archive in this memory
-  char *base = os::map_memory(_fd, _full_path, si->file_offset(),
-                              requested_addr, size, si->read_only(),
-                              si->allow_exec());
-  if (base == NULL || base != requested_addr) {
-    fail_continue("Unable to map %s shared space at required address.", shared_region_name[i]);
-    _memory_mapping_failed = true;
-    return NULL;
+  if (MetaspaceShared::use_windows_memory_mapping() && addr_delta != 0) {
+    // This is the second time we try to map the archive(s). We have already created a ReservedSpace
+    // that covers all the FileMapRegions to ensure all regions can be mapped. However, Windows
+    // can't mmap into a ReservedSpace, so we just os::read() the data. We're going to patch all the
+    // regions anyway, so there's no benefit for mmap anyway.
+    if (!read_region(i, requested_addr, size)) {
+      return MAP_ARCHIVE_OTHER_FAILURE; // oom or I/O error.
+    }
+  } else {
+    char* base = os::map_memory(_fd, _full_path, si->file_offset(),
+                                requested_addr, size, si->read_only(),
+                                si->allow_exec());
+    if (base != requested_addr) {
+      log_info(cds)("Unable to map %s shared space at required address.", shared_region_name[i]);
+      _memory_mapping_failed = true;
+      return MAP_ARCHIVE_MMAP_FAILURE;
+    }
+    si->set_mapped_from_file(true);
   }
-#ifdef _WINDOWS
-  // This call is Windows-only because the memory_type gets recorded for the other platforms
-  // in method FileMapInfo::reserve_shared_memory(), which is not called on Windows.
-  MemTracker::record_virtual_memory_type((address)base, mtClassShared);
-#endif
+  si->set_mapped_base(requested_addr);
+
+  if (!rs.is_reserved()) {
+    // When mapping on Windows with (addr_delta == 0), we don't reserve the address space for the regions
+    // (Windows can't mmap into a ReservedSpace). In this case, NMT requires we call it after
+    // os::map_memory has succeeded.
+    assert(MetaspaceShared::use_windows_memory_mapping(), "Windows memory mapping only");
+    MemTracker::record_virtual_memory_type((address)requested_addr, mtClassShared);
+  }
 
   if (VerifySharedSpaces && !verify_region_checksum(i)) {
+    return MAP_ARCHIVE_OTHER_FAILURE;
+  }
+
+  return MAP_ARCHIVE_SUCCESS;
+}
+
+char* FileMapInfo::map_relocation_bitmap(size_t& bitmap_size) {
+  FileMapRegion* si = space_at(MetaspaceShared::bm);
+  bitmap_size = si->used_aligned();
+  bool read_only = true, allow_exec = false;
+  char* requested_addr = NULL; // allow OS to pick any location
+  char* bitmap_base = os::map_memory(_fd, _full_path, si->file_offset(),
+                                     requested_addr, bitmap_size, read_only, allow_exec);
+  if (bitmap_base == NULL) {
+    log_error(cds)("failed to map relocation bitmap");
     return NULL;
   }
 
-  *top_ret = base + size;
-  return base;
+  if (VerifySharedSpaces && !region_crc_check(bitmap_base, bitmap_size, si->crc())) {
+    log_error(cds)("relocation bitmap CRC error");
+    if (!os::unmap_memory(bitmap_base, bitmap_size)) {
+      fatal("os::unmap_memory of relocation bitmap failed");
+    }
+    return NULL;
+  }
+
+  return bitmap_base;
+}
+
+bool FileMapInfo::relocate_pointers(intx addr_delta) {
+  log_debug(cds, reloc)("runtime archive relocation start");
+  size_t bitmap_size;
+  char* bitmap_base = map_relocation_bitmap(bitmap_size);
+
+  if (bitmap_base == NULL) {
+    return false;
+  } else {
+    size_t ptrmap_size_in_bits = header()->ptrmap_size_in_bits();
+    log_debug(cds, reloc)("mapped relocation bitmap @ " INTPTR_FORMAT " (" SIZE_FORMAT
+                          " bytes = " SIZE_FORMAT " bits)",
+                          p2i(bitmap_base), bitmap_size, ptrmap_size_in_bits);
+
+    BitMapView ptrmap((BitMap::bm_word_t*)bitmap_base, ptrmap_size_in_bits);
+
+    // Patch all pointers in the the mapped region that are marked by ptrmap.
+    address patch_base = (address)mapped_base();
+    address patch_end  = (address)mapped_end();
+
+    // the current value of the pointers to be patched must be within this
+    // range (i.e., must be between the requesed base address, and the of the current archive).
+    // Note: top archive may point to objects in the base archive, but not the other way around.
+    address valid_old_base = (address)header()->requested_base_address();
+    address valid_old_end  = valid_old_base + mapping_end_offset();
+
+    // after patching, the pointers must point inside this range
+    // (the requested location of the archive, as mapped at runtime).
+    address valid_new_base = (address)header()->mapped_base_address();
+    address valid_new_end  = (address)mapped_end();
+
+    SharedDataRelocator<false> patcher((address*)patch_base, (address*)patch_end, valid_old_base, valid_old_end,
+                                       valid_new_base, valid_new_end, addr_delta);
+    ptrmap.iterate(&patcher);
+
+    if (!os::unmap_memory(bitmap_base, bitmap_size)) {
+      fatal("os::unmap_memory of relocation bitmap failed");
+    }
+    log_debug(cds, reloc)("runtime archive relocation done");
+    return true;
+  }
 }
 
 size_t FileMapInfo::read_bytes(void* buffer, size_t count) {
@@ -1434,10 +1565,13 @@
 }
 
 address FileMapInfo::decode_start_address(FileMapRegion* spc, bool with_current_oop_encoding_mode) {
+  size_t offset = spc->mapping_offset();
+  assert((offset >> 32) == 0, "must be 32-bit only");
+  uint n = (uint)offset;
   if (with_current_oop_encoding_mode) {
-    return (address)CompressedOops::decode_not_null(spc->offset());
+    return (address)CompressedOops::decode_not_null(n);
   } else {
-    return (address)HeapShared::decode_from_archive(spc->offset());
+    return (address)HeapShared::decode_from_archive(n);
   }
 }
 
@@ -1705,7 +1839,7 @@
                                                         int first_region_idx) {
   for (int i=0; i<num_ranges; i++) {
     FileMapRegion* si = space_at(i + first_region_idx);
-    HeapShared::patch_archived_heap_embedded_pointers(ranges[i], (address)si->oopmap(),
+    HeapShared::patch_archived_heap_embedded_pointers(ranges[i], (address)(SharedBaseAddress + si->oopmap_offset()),
                                                       si->oopmap_size_in_bits());
   }
 }
@@ -1759,11 +1893,10 @@
   }
 }
 
-void FileMapInfo::unmap_regions(int regions[], char* saved_base[], size_t len) {
-  for (int i = 0; i < (int)len; i++) {
-    if (saved_base[i] != NULL) {
-      unmap_region(regions[i]);
-    }
+void FileMapInfo::unmap_regions(int regions[], int num_regions) {
+  for (int r = 0; r < num_regions; r++) {
+    int idx = regions[r];
+    unmap_region(idx);
   }
 }
 
@@ -1772,16 +1905,17 @@
 void FileMapInfo::unmap_region(int i) {
   assert(!HeapShared::is_heap_region(i), "sanity");
   FileMapRegion* si = space_at(i);
+  char* mapped_base = si->mapped_base();
   size_t used = si->used();
   size_t size = align_up(used, os::vm_allocation_granularity());
 
-  if (used == 0) {
-    return;
-  }
-
-  char* addr = region_addr(i);
-  if (!os::unmap_memory(addr, size)) {
-    fail_stop("Unable to unmap shared space.");
+  if (mapped_base != NULL && size > 0 && si->mapped_from_file()) {
+    log_info(cds)("Unmapping region #%d at base " INTPTR_FORMAT " (%s)", i, p2i(mapped_base),
+                  shared_region_name[i]);
+    if (!os::unmap_memory(mapped_base, size)) {
+      fatal("os::unmap_memory failed");
+    }
+    si->set_mapped_base(NULL);
   }
 }
 
@@ -1813,7 +1947,7 @@
 // [1] validate_header() - done here.
 // [2] validate_shared_path_table - this is done later, because the table is in the RW
 //     region of the archive, which is not mapped yet.
-bool FileMapInfo::initialize(bool is_static) {
+bool FileMapInfo::initialize() {
   assert(UseSharedSpaces, "UseSharedSpaces expected.");
 
   if (JvmtiExport::should_post_class_file_load_hook() && JvmtiExport::has_early_class_hook_env()) {
@@ -1828,11 +1962,10 @@
   if (!open_for_read()) {
     return false;
   }
-
-  init_from_file(_fd, is_static);
-  // UseSharedSpaces could be disabled if the checking of some of the header fields in
-  // init_from_file has failed.
-  if (!UseSharedSpaces || !validate_header(is_static)) {
+  if (!init_from_file(_fd)) {
+    return false;
+  }
+  if (!validate_header()) {
     return false;
   }
   return true;
@@ -1845,10 +1978,18 @@
     return si->used() > 0 ?
           (char*)start_address_as_decoded_with_current_oop_encoding_mode(si) : NULL;
   } else {
-    return si->base();
+    return si->mapped_base();
   }
 }
 
+FileMapRegion* FileMapInfo::first_core_space() const {
+  return is_static() ? space_at(MetaspaceShared::mc) : space_at(MetaspaceShared::rw);
+}
+
+FileMapRegion* FileMapInfo::last_core_space() const {
+  return is_static() ? space_at(MetaspaceShared::md) : space_at(MetaspaceShared::mc);
+}
+
 int FileMapHeader::compute_crc() {
   char* start = (char*)this;
   // start computing from the field after _crc
@@ -1860,7 +2001,6 @@
 
 // This function should only be called during run time with UseSharedSpaces enabled.
 bool FileMapHeader::validate() {
-
   if (_obj_alignment != ObjectAlignmentInBytes) {
     FileMapInfo::fail_continue("The shared archive file's ObjectAlignmentInBytes of %d"
                   " does not equal the current ObjectAlignmentInBytes of " INTX_FORMAT ".",
@@ -1913,7 +2053,7 @@
   return true;
 }
 
-bool FileMapInfo::validate_header(bool is_static) {
+bool FileMapInfo::validate_header() {
   return header()->validate();
 }
 
@@ -1932,18 +2072,14 @@
 
 // Unmap mapped regions of shared space.
 void FileMapInfo::stop_sharing_and_unmap(const char* msg) {
-  MetaspaceShared::set_shared_metaspace_range(NULL, NULL);
+  MetaspaceShared::set_shared_metaspace_range(NULL, NULL, NULL);
 
   FileMapInfo *map_info = FileMapInfo::current_info();
   if (map_info) {
     map_info->fail_continue("%s", msg);
     for (int i = 0; i < MetaspaceShared::num_non_heap_spaces; i++) {
       if (!HeapShared::is_heap_region(i)) {
-        char *addr = map_info->region_addr(i);
-        if (addr != NULL) {
-          map_info->unmap_region(i);
-          map_info->space_at(i)->mark_invalid();
-        }
+        map_info->unmap_region(i);
       }
     }
     // Dealloc the archive heap regions only without unmapping. The regions are part
--- a/src/hotspot/share/memory/filemap.hpp	Wed Nov 13 17:21:31 2019 -0500
+++ b/src/hotspot/share/memory/filemap.hpp	Mon Nov 18 12:40:06 2019 -0500
@@ -43,6 +43,8 @@
 
 static const int JVM_IDENT_MAX = 256;
 
+class CHeapBitMap;
+
 class SharedClassPathEntry {
   enum {
     modules_image_entry,
@@ -104,6 +106,9 @@
   Array<u8>* _table;
   int _size;
 public:
+  SharedPathTable() : _table(NULL), _size(0) {}
+  SharedPathTable(Array<u8>* table, int size) : _table(table), _size(size) {}
+
   void dumptime_init(ClassLoaderData* loader_data, Thread* THREAD);
   void metaspace_pointers_do(MetaspaceClosure* it);
 
@@ -138,25 +143,29 @@
   }
 
   // Accessors
-  int crc()                      const { return _crc; }
-  size_t file_offset()           const { return _file_offset; }
-  char*  base()                  const { assert_is_not_heap_region(); return _addr._base;  }
-  narrowOop offset()             const { assert_is_heap_region();     return (narrowOop)(_addr._offset); }
-  size_t used()                  const { return _used; }
-  bool read_only()               const { return _read_only != 0; }
-  bool allow_exec()              const { return _allow_exec != 0; }
-  void* oopmap()                 const { return _oopmap; }
-  size_t oopmap_size_in_bits()   const { return _oopmap_size_in_bits; }
+  int crc()                         const { return _crc; }
+  size_t file_offset()              const { return _file_offset; }
+  size_t mapping_offset()           const { return _mapping_offset; }
+  size_t mapping_end_offset()       const { return _mapping_offset + used_aligned(); }
+  size_t used()                     const { return _used; }
+  size_t used_aligned()             const; // aligned up to os::vm_allocation_granularity()
+  char*  mapped_base()              const { assert_is_not_heap_region(); return _mapped_base; }
+  char*  mapped_end()               const { return mapped_base()        + used_aligned(); }
+  bool   read_only()                const { return _read_only != 0; }
+  bool   allow_exec()               const { return _allow_exec != 0; }
+  bool   mapped_from_file()         const { return _mapped_from_file != 0; }
+  size_t oopmap_offset()            const { assert_is_heap_region();     return _oopmap_offset; }
+  size_t oopmap_size_in_bits()      const { assert_is_heap_region();     return _oopmap_size_in_bits; }
 
-  void set_file_offset(size_t s) { _file_offset = s; }
-  void set_read_only(bool v)     { _read_only = v; }
-  void mark_invalid()            { _addr._base = NULL; }
-
-  void init(bool is_heap_region, char* base, size_t size, bool read_only,
+  void set_file_offset(size_t s)     { _file_offset = s; }
+  void set_read_only(bool v)         { _read_only = v; }
+  void set_mapped_base(char* p)      { _mapped_base = p; }
+  void set_mapped_from_file(bool v)  { _mapped_from_file = v; }
+  void init(int region_index, char* base, size_t size, bool read_only,
             bool allow_exec, int crc);
 
-  void init_oopmap(void* map, size_t size_in_bits) {
-    _oopmap = map;
+  void init_oopmap(size_t oopmap_offset, size_t size_in_bits) {
+    _oopmap_offset = oopmap_offset;
     _oopmap_size_in_bits = size_in_bits;
   }
 };
@@ -178,13 +187,10 @@
   uintx  _max_heap_size;            // java max heap size during dumping
   CompressedOops::Mode _narrow_oop_mode; // compressed oop encoding mode
   int     _narrow_klass_shift;      // save narrow klass base and shift
-  address _narrow_klass_base;
-  char*   _misc_data_patching_start;
-  char*   _serialized_data_start;  // Data accessed using {ReadClosure,WriteClosure}::serialize()
-  address _i2i_entry_code_buffers;
+  size_t  _misc_data_patching_offset;
+  size_t  _serialized_data_offset;  // Data accessed using {ReadClosure,WriteClosure}::serialize()
+  size_t  _i2i_entry_code_buffers_offset;
   size_t  _i2i_entry_code_buffers_size;
-  size_t  _core_spaces_size;        // number of bytes allocated by the core spaces
-                                    // (mc, md, ro, rw and od).
   address _heap_end;                // heap end at dump time.
   bool _base_archive_is_default;    // indicates if the base archive is the system default one
 
@@ -202,7 +208,8 @@
   //      check_nonempty_dir_in_shared_path_table()
   //      validate_shared_path_table()
   //      validate_non_existent_class_paths()
-  SharedPathTable _shared_path_table;
+  size_t _shared_path_table_offset;
+  int    _shared_path_table_size;
 
   jshort _app_class_paths_start_index;  // Index of first app classpath entry
   jshort _app_module_paths_start_index; // Index of first module path entry
@@ -211,9 +218,19 @@
   bool   _verify_local;                 // BytecodeVerificationLocal setting
   bool   _verify_remote;                // BytecodeVerificationRemote setting
   bool   _has_platform_or_app_classes;  // Archive contains app classes
-  size_t _shared_base_address;          // SharedBaseAddress used at dump time
+  char*  _requested_base_address;       // Archive relocation is not necessary if we map with this base address.
+  char*  _mapped_base_address;          // Actual base address where archive is mapped.
+
   bool   _allow_archiving_with_java_agent; // setting of the AllowArchivingWithJavaAgent option
+  size_t _ptrmap_size_in_bits;          // Size of pointer relocation bitmap
 
+  char* from_mapped_offset(size_t offset) const {
+    return mapped_base_address() + offset;
+  }
+  void set_mapped_offset(char* p, size_t *offset) {
+    assert(p >= mapped_base_address(), "sanity");
+    *offset = p - mapped_base_address();
+  }
 public:
   // Accessors -- fields declared in CDSFileMapHeaderBase
   unsigned int magic() const {return _magic;}
@@ -234,19 +251,19 @@
   uintx max_heap_size()                    const { return _max_heap_size; }
   CompressedOops::Mode narrow_oop_mode()   const { return _narrow_oop_mode; }
   int narrow_klass_shift()                 const { return _narrow_klass_shift; }
-  address narrow_klass_base()              const { return _narrow_klass_base; }
-  char* misc_data_patching_start()         const { return _misc_data_patching_start; }
-  char* serialized_data_start()            const { return _serialized_data_start; }
-  address i2i_entry_code_buffers()         const { return _i2i_entry_code_buffers; }
+  address narrow_klass_base()              const { return (address)mapped_base_address(); }
+  char* misc_data_patching_start()         const { return from_mapped_offset(_misc_data_patching_offset); }
+  char* serialized_data_start()            const { return from_mapped_offset(_serialized_data_offset); }
+  address i2i_entry_code_buffers()         const { return (address)from_mapped_offset(_i2i_entry_code_buffers_offset); }
   size_t i2i_entry_code_buffers_size()     const { return _i2i_entry_code_buffers_size; }
-  size_t core_spaces_size()                const { return _core_spaces_size; }
   address heap_end()                       const { return _heap_end; }
   bool base_archive_is_default()           const { return _base_archive_is_default; }
   const char* jvm_ident()                  const { return _jvm_ident; }
   size_t base_archive_name_size()          const { return _base_archive_name_size; }
-  size_t shared_base_address()             const { return _shared_base_address; }
+  char* requested_base_address()           const { return _requested_base_address; }
+  char* mapped_base_address()              const { return _mapped_base_address; }
   bool has_platform_or_app_classes()       const { return _has_platform_or_app_classes; }
-  SharedPathTable shared_path_table()      const { return _shared_path_table; }
+  size_t ptrmap_size_in_bits()             const { return _ptrmap_size_in_bits; }
 
   // FIXME: These should really return int
   jshort max_used_path_index()             const { return _max_used_path_index; }
@@ -254,27 +271,32 @@
   jshort app_class_paths_start_index()     const { return _app_class_paths_start_index; }
   jshort num_module_paths()                const { return _num_module_paths; }
 
-  void set_core_spaces_size(size_t s)            { _core_spaces_size = s; }
   void set_has_platform_or_app_classes(bool v)   { _has_platform_or_app_classes = v; }
-  void set_misc_data_patching_start(char* p)     { _misc_data_patching_start = p; }
-  void set_serialized_data_start(char* p)        { _serialized_data_start   = p; }
+  void set_misc_data_patching_start(char* p)     { set_mapped_offset(p, &_misc_data_patching_offset); }
+  void set_serialized_data_start(char* p)        { set_mapped_offset(p, &_serialized_data_offset); }
   void set_base_archive_name_size(size_t s)      { _base_archive_name_size = s; }
   void set_base_archive_is_default(bool b)       { _base_archive_is_default = b; }
   void set_header_size(size_t s)                 { _header_size = s; }
-
+  void set_ptrmap_size_in_bits(size_t s)         { _ptrmap_size_in_bits = s; }
+  void set_mapped_base_address(char* p)          { _mapped_base_address = p; }
   void set_i2i_entry_code_buffers(address p, size_t s) {
-    _i2i_entry_code_buffers = p;
+    set_mapped_offset((char*)p, &_i2i_entry_code_buffers_offset);
     _i2i_entry_code_buffers_size = s;
   }
 
-  void relocate_shared_path_table(Array<u8>* t) {
-    assert(DynamicDumpSharedSpaces, "only");
-    _shared_path_table.set_table(t);
+  void set_shared_path_table(SharedPathTable table) {
+    set_mapped_offset((char*)table.table(), &_shared_path_table_offset);
+    _shared_path_table_size = table.size();
   }
 
-  void shared_path_table_metaspace_pointers_do(MetaspaceClosure* it) {
-    assert(DynamicDumpSharedSpaces, "only");
-    _shared_path_table.metaspace_pointers_do(it);
+  void set_final_requested_base(char* b) {
+    _requested_base_address = b;
+    _mapped_base_address = 0;
+  }
+
+  SharedPathTable shared_path_table() const {
+    return SharedPathTable((Array<u8>*)from_mapped_offset(_shared_path_table_offset),
+                           _shared_path_table_size);
   }
 
   bool validate();
@@ -301,6 +323,7 @@
 
   bool           _is_static;
   bool           _file_open;
+  bool           _is_mapped;
   int            _fd;
   size_t         _file_offset;
   const char*    _full_path;
@@ -327,8 +350,11 @@
   static bool get_base_archive_name_from_header(const char* archive_name,
                                                 int* size, char** base_archive_name);
   static bool check_archive(const char* archive_name, bool is_static);
+  static SharedPathTable shared_path_table() {
+    return _shared_path_table;
+  }
   void restore_shared_path_table();
-  bool init_from_file(int fd, bool is_static);
+  bool init_from_file(int fd);
   static void metaspace_pointers_do(MetaspaceClosure* it);
 
   void log_paths(const char* msg, int start_idx, int end_idx);
@@ -341,7 +367,7 @@
   void   set_header_crc(int crc)     { header()->set_crc(crc); }
   int    space_crc(int i)      const { return space_at(i)->crc(); }
   void   populate_header(size_t alignment);
-  bool   validate_header(bool is_static);
+  bool   validate_header();
   void   invalidate();
   int    crc()                 const { return header()->crc(); }
   int    version()             const { return header()->version(); }
@@ -370,11 +396,17 @@
     header()->set_i2i_entry_code_buffers(addr, s);
   }
 
-  void set_core_spaces_size(size_t s)         const { header()->set_core_spaces_size(s); }
-  size_t core_spaces_size()                   const { return header()->core_spaces_size(); }
+  bool is_static()                            const { return _is_static; }
+  bool is_mapped()                            const { return _is_mapped; }
+  void set_is_mapped(bool v)                        { _is_mapped = v; }
+  const char* full_path()                     const { return _full_path; }
+  void set_final_requested_base(char* b);
+
+  char* requested_base_address()           const { return header()->requested_base_address(); }
+
 
   class DynamicArchiveHeader* dynamic_header() const {
-    assert(!_is_static, "must be");
+    assert(!is_static(), "must be");
     return (DynamicArchiveHeader*)header();
   }
 
@@ -402,21 +434,21 @@
   static void assert_mark(bool check);
 
   // File manipulation.
-  bool  initialize(bool is_static) NOT_CDS_RETURN_(false);
-  bool  open_for_read(const char* path = NULL);
+  bool  initialize() NOT_CDS_RETURN_(false);
+  bool  open_for_read();
   void  open_for_write(const char* path = NULL);
   void  write_header();
   void  write_region(int region, char* base, size_t size,
                      bool read_only, bool allow_exec);
+  void  write_bitmap_region(const CHeapBitMap* ptrmap);
   size_t write_archive_heap_regions(GrowableArray<MemRegion> *heap_mem,
                                     GrowableArray<ArchiveHeapOopmapInfo> *oopmaps,
                                     int first_region_id, int max_num_regions);
   void  write_bytes(const void* buffer, size_t count);
   void  write_bytes_aligned(const void* buffer, size_t count);
   size_t  read_bytes(void* buffer, size_t count);
-  char* map_regions(int regions[], char* saved_base[], size_t len);
-  char* map_region(int i, char** top_ret);
-  void  map_heap_regions_impl() NOT_CDS_JAVA_HEAP_RETURN;
+  MapArchiveResult map_regions(int regions[], int num_regions, char* mapped_base_address, ReservedSpace rs);
+  void  unmap_regions(int regions[], int num_regions);
   void  map_heap_regions() NOT_CDS_JAVA_HEAP_RETURN;
   void  fixup_mapped_heap_regions() NOT_CDS_JAVA_HEAP_RETURN;
   void  patch_archived_heap_embedded_pointers() NOT_CDS_JAVA_HEAP_RETURN;
@@ -424,7 +456,6 @@
                                               int first_region_idx) NOT_CDS_JAVA_HEAP_RETURN;
   bool  has_heap_regions()  NOT_CDS_JAVA_HEAP_RETURN_(false);
   MemRegion get_heap_regions_range_with_current_oop_encoding_mode() NOT_CDS_JAVA_HEAP_RETURN_(MemRegion());
-  void  unmap_regions(int regions[], char* saved_base[], size_t len);
   void  unmap_region(int i);
   bool  verify_region_checksum(int i);
   void  close();
@@ -452,6 +483,9 @@
   static void check_nonempty_dir_in_shared_path_table();
   bool validate_shared_path_table();
   void validate_non_existent_class_paths();
+  static void set_shared_path_table(FileMapInfo* info) {
+    _shared_path_table = info->header()->shared_path_table();
+  }
   static void update_jar_manifest(ClassPathEntry *cpe, SharedClassPathEntry* ent, TRAPS);
   static int num_non_existent_class_paths();
   static void record_non_existent_class_path_entry(const char* path);
@@ -475,12 +509,28 @@
 
   char* region_addr(int idx);
 
+  // The offset of the first core region in the archive, relative to SharedBaseAddress
+  size_t mapping_base_offset() const { return first_core_space()->mapping_offset(); }
+  // The offset of the (exclusive) end of the last core region in this archive, relative to SharedBaseAddress
+  size_t mapping_end_offset()  const { return last_core_space()->mapping_end_offset(); }
+
+  char* mapped_base()    const { return first_core_space()->mapped_base(); }
+  char* mapped_end()     const { return last_core_space()->mapped_end();   }
+
+  // Non-zero if the archive needs to be mapped a non-default location due to ASLR.
+  intx relocation_delta() const {
+    return header()->mapped_base_address() - header()->requested_base_address();
+  }
+
+  FileMapRegion* first_core_space() const;
+  FileMapRegion* last_core_space() const;
+
  private:
   void  seek_to_position(size_t pos);
   char* skip_first_path_entry(const char* path) NOT_CDS_RETURN_(NULL);
   int   num_paths(const char* path) NOT_CDS_RETURN_(0);
   GrowableArray<const char*>* create_path_array(const char* path) NOT_CDS_RETURN_(NULL);
-  bool  fail(const char* msg, const char* name) NOT_CDS_RETURN_(false);
+  bool  classpath_failure(const char* msg, const char* name) NOT_CDS_RETURN_(false);
   bool  check_paths(int shared_path_start_idx, int num_paths,
                     GrowableArray<const char*>* rp_array) NOT_CDS_RETURN_(false);
   bool  validate_boot_class_paths() NOT_CDS_RETURN_(false);
@@ -489,6 +539,11 @@
                       bool is_open = false) NOT_CDS_JAVA_HEAP_RETURN_(false);
   bool  region_crc_check(char* buf, size_t size, int expected_crc) NOT_CDS_RETURN_(false);
   void  dealloc_archive_heap_regions(MemRegion* regions, int num, bool is_open) NOT_CDS_JAVA_HEAP_RETURN;
+  void  map_heap_regions_impl() NOT_CDS_JAVA_HEAP_RETURN;
+  char* map_relocation_bitmap(size_t& bitmap_size);
+  MapArchiveResult map_region(int i, intx addr_delta, char* mapped_base_address, ReservedSpace rs);
+  bool  read_region(int i, char* base, size_t size);
+  bool  relocate_pointers(intx addr_delta);
 
   FileMapRegion* space_at(int i) const {
     return header()->space_at(i);
--- a/src/hotspot/share/memory/heapShared.cpp	Wed Nov 13 17:21:31 2019 -0500
+++ b/src/hotspot/share/memory/heapShared.cpp	Mon Nov 18 12:40:06 2019 -0500
@@ -26,15 +26,18 @@
 #include "classfile/javaClasses.inline.hpp"
 #include "classfile/stringTable.hpp"
 #include "classfile/symbolTable.hpp"
+#include "classfile/systemDictionaryShared.hpp"
 #include "classfile/vmSymbols.hpp"
 #include "logging/log.hpp"
 #include "logging/logMessage.hpp"
 #include "logging/logStream.hpp"
+#include "memory/archiveUtils.hpp"
 #include "memory/filemap.hpp"
 #include "memory/heapShared.inline.hpp"
 #include "memory/iterator.inline.hpp"
 #include "memory/metadataFactory.hpp"
 #include "memory/metaspaceClosure.hpp"
+#include "memory/metaspaceShared.hpp"
 #include "memory/resourceArea.hpp"
 #include "memory/universe.hpp"
 #include "oops/compressedOops.inline.hpp"
@@ -383,8 +386,13 @@
           _k->external_name(), i, subgraph_k->external_name());
       }
       _subgraph_object_klasses->at_put(i, subgraph_k);
+      ArchivePtrMarker::mark_pointer(_subgraph_object_klasses->adr_at(i));
     }
   }
+
+  ArchivePtrMarker::mark_pointer(&_k);
+  ArchivePtrMarker::mark_pointer(&_entry_field_records);
+  ArchivePtrMarker::mark_pointer(&_subgraph_object_klasses);
 }
 
 struct CopyKlassSubGraphInfoToArchive : StackObj {
@@ -397,7 +405,7 @@
         (ArchivedKlassSubGraphInfoRecord*)MetaspaceShared::read_only_space_alloc(sizeof(ArchivedKlassSubGraphInfoRecord));
       record->init(&info);
 
-      unsigned int hash = primitive_hash<Klass*>(klass);
+      unsigned int hash = SystemDictionaryShared::hash_for_shared_dictionary(klass);
       u4 delta = MetaspaceShared::object_delta_u4(record);
       _writer->add(hash, delta);
     }
@@ -436,7 +444,7 @@
   }
   assert(!DumpSharedSpaces, "Should not be called with DumpSharedSpaces");
 
-  unsigned int hash = primitive_hash<Klass*>(k);
+  unsigned int hash = SystemDictionaryShared::hash_for_shared_dictionary(k);
   const ArchivedKlassSubGraphInfoRecord* record = _run_time_subgraph_info_table.lookup(k, hash, 0);
 
   // Initialize from archived data. Currently this is done only
@@ -606,8 +614,20 @@
   assert(orig_obj != NULL, "must be");
   assert(!is_archived_object(orig_obj), "sanity");
 
-  // java.lang.Class instances cannot be included in an archived
-  // object sub-graph.
+  if (!JavaClasses::is_supported_for_archiving(orig_obj)) {
+    // This object has injected fields that cannot be supported easily, so we disallow them for now.
+    // If you get an error here, you probably made a change in the JDK library that has added
+    // these objects that are referenced (directly or indirectly) by static fields.
+    ResourceMark rm;
+    log_error(cds, heap)("Cannot archive object of class %s", orig_obj->klass()->external_name());
+    vm_exit(1);
+  }
+
+  // java.lang.Class instances cannot be included in an archived object sub-graph. We only support
+  // them as Klass::_archived_mirror because they need to be specially restored at run time.
+  //
+  // If you get an error here, you probably made a change in the JDK library that has added a Class
+  // object that is referenced (directly or indirectly) by static fields.
   if (java_lang_Class::is_instance(orig_obj)) {
     log_error(cds, heap)("(%d) Unknown java.lang.Class object is in the archived sub-graph", level);
     vm_exit(1);
--- a/src/hotspot/share/memory/metaspace.cpp	Wed Nov 13 17:21:31 2019 -0500
+++ b/src/hotspot/share/memory/metaspace.cpp	Mon Nov 18 12:40:06 2019 -0500
@@ -975,25 +975,18 @@
 #ifdef _LP64
 static const uint64_t UnscaledClassSpaceMax = (uint64_t(max_juint) + 1);
 
-void Metaspace::set_narrow_klass_base_and_shift(address metaspace_base, address cds_base) {
+void Metaspace::set_narrow_klass_base_and_shift(ReservedSpace metaspace_rs, address cds_base) {
   assert(!DumpSharedSpaces, "narrow_klass is set by MetaspaceShared class.");
   // Figure out the narrow_klass_base and the narrow_klass_shift.  The
   // narrow_klass_base is the lower of the metaspace base and the cds base
   // (if cds is enabled).  The narrow_klass_shift depends on the distance
   // between the lower base and higher address.
-  address lower_base;
-  address higher_address;
-#if INCLUDE_CDS
-  if (UseSharedSpaces) {
-    higher_address = MAX2((address)(cds_base + MetaspaceShared::core_spaces_size()),
-                          (address)(metaspace_base + compressed_class_space_size()));
-    lower_base = MIN2(metaspace_base, cds_base);
-  } else
-#endif
-  {
-    higher_address = metaspace_base + compressed_class_space_size();
-    lower_base = metaspace_base;
-
+  address lower_base = (address)metaspace_rs.base();
+  address higher_address = (address)metaspace_rs.end();
+  if (cds_base != NULL) {
+    assert(UseSharedSpaces, "must be");
+    lower_base = MIN2(lower_base, cds_base);
+  } else {
     uint64_t klass_encoding_max = UnscaledClassSpaceMax << LogKlassAlignmentInBytes;
     // If compressed class space fits in lower 32G, we don't need a base.
     if (higher_address <= (address)klass_encoding_max) {
@@ -1018,21 +1011,8 @@
   AOTLoader::set_narrow_klass_shift();
 }
 
-#if INCLUDE_CDS
-// Return TRUE if the specified metaspace_base and cds_base are close enough
-// to work with compressed klass pointers.
-bool Metaspace::can_use_cds_with_metaspace_addr(char* metaspace_base, address cds_base) {
-  assert(cds_base != 0 && UseSharedSpaces, "Only use with CDS");
-  assert(UseCompressedClassPointers, "Only use with CompressedKlassPtrs");
-  address lower_base = MIN2((address)metaspace_base, cds_base);
-  address higher_address = MAX2((address)(cds_base + MetaspaceShared::core_spaces_size()),
-                                (address)(metaspace_base + compressed_class_space_size()));
-  return ((uint64_t)(higher_address - lower_base) <= UnscaledClassSpaceMax);
-}
-#endif
-
 // Try to allocate the metaspace at the requested addr.
-void Metaspace::allocate_metaspace_compressed_klass_ptrs(char* requested_addr, address cds_base) {
+void Metaspace::allocate_metaspace_compressed_klass_ptrs(ReservedSpace metaspace_rs, char* requested_addr, address cds_base) {
   assert(!DumpSharedSpaces, "compress klass space is allocated by MetaspaceShared class.");
   assert(using_class_space(), "called improperly");
   assert(UseCompressedClassPointers, "Only use with CompressedKlassPtrs");
@@ -1045,14 +1025,16 @@
   // Don't use large pages for the class space.
   bool large_pages = false;
 
+ if (metaspace_rs.is_reserved()) {
+   // CDS should have already reserved the space.
+   assert(requested_addr == NULL, "not used");
+   assert(cds_base != NULL, "CDS should have already reserved the memory space");
+ } else {
+   assert(cds_base == NULL, "must be");
 #if !(defined(AARCH64) || defined(AIX))
-  ReservedSpace metaspace_rs = ReservedSpace(compressed_class_space_size(),
-                                             _reserve_alignment,
-                                             large_pages,
-                                             requested_addr);
+  metaspace_rs = ReservedSpace(compressed_class_space_size(), _reserve_alignment,
+                               large_pages, requested_addr);
 #else // AARCH64
-  ReservedSpace metaspace_rs;
-
   // Our compressed klass pointers may fit nicely into the lower 32
   // bits.
   if ((uint64_t)requested_addr + compressed_class_space_size() < 4*G) {
@@ -1077,19 +1059,6 @@
         increment = 4*G;
       }
 
-#if INCLUDE_CDS
-      if (UseSharedSpaces
-          && ! can_use_cds_with_metaspace_addr(a, cds_base)) {
-        // We failed to find an aligned base that will reach.  Fall
-        // back to using our requested addr.
-        metaspace_rs = ReservedSpace(compressed_class_space_size(),
-                                     _reserve_alignment,
-                                     large_pages,
-                                     requested_addr);
-        break;
-      }
-#endif
-
       metaspace_rs = ReservedSpace(compressed_class_space_size(),
                                    _reserve_alignment,
                                    large_pages,
@@ -1098,53 +1067,30 @@
         break;
     }
   }
-
 #endif // AARCH64
+ }
 
   if (!metaspace_rs.is_reserved()) {
-#if INCLUDE_CDS
-    if (UseSharedSpaces) {
-      size_t increment = align_up(1*G, _reserve_alignment);
-
-      // Keep trying to allocate the metaspace, increasing the requested_addr
-      // by 1GB each time, until we reach an address that will no longer allow
-      // use of CDS with compressed klass pointers.
-      char *addr = requested_addr;
-      while (!metaspace_rs.is_reserved() && (addr + increment > addr) &&
-             can_use_cds_with_metaspace_addr(addr + increment, cds_base)) {
-        addr = addr + increment;
-        metaspace_rs = ReservedSpace(compressed_class_space_size(),
-                                     _reserve_alignment, large_pages, addr);
-      }
-    }
-#endif
+    assert(cds_base == NULL, "CDS should have already reserved the memory space");
     // If no successful allocation then try to allocate the space anywhere.  If
     // that fails then OOM doom.  At this point we cannot try allocating the
     // metaspace as if UseCompressedClassPointers is off because too much
     // initialization has happened that depends on UseCompressedClassPointers.
     // So, UseCompressedClassPointers cannot be turned off at this point.
+    metaspace_rs = ReservedSpace(compressed_class_space_size(),
+                                 _reserve_alignment, large_pages);
     if (!metaspace_rs.is_reserved()) {
-      metaspace_rs = ReservedSpace(compressed_class_space_size(),
-                                   _reserve_alignment, large_pages);
-      if (!metaspace_rs.is_reserved()) {
-        vm_exit_during_initialization(err_msg("Could not allocate metaspace: " SIZE_FORMAT " bytes",
-                                              compressed_class_space_size()));
-      }
+      vm_exit_during_initialization(err_msg("Could not allocate metaspace: " SIZE_FORMAT " bytes",
+                                            compressed_class_space_size()));
     }
   }
 
-  // If we got here then the metaspace got allocated.
-  MemTracker::record_virtual_memory_type((address)metaspace_rs.base(), mtClass);
+  if (cds_base == NULL) {
+    // If we got here then the metaspace got allocated.
+    MemTracker::record_virtual_memory_type((address)metaspace_rs.base(), mtClass);
+  }
 
-#if INCLUDE_CDS
-  // Verify that we can use shared spaces.  Otherwise, turn off CDS.
-  if (UseSharedSpaces && !can_use_cds_with_metaspace_addr(metaspace_rs.base(), cds_base)) {
-    FileMapInfo::stop_sharing_and_unmap(
-        "Could not allocate metaspace at a compatible address");
-  }
-#endif
-  set_narrow_klass_base_and_shift((address)metaspace_rs.base(),
-                                  UseSharedSpaces ? (address)cds_base : 0);
+  set_narrow_klass_base_and_shift(metaspace_rs, cds_base);
 
   initialize_class_space(metaspace_rs);
 
@@ -1247,31 +1193,30 @@
 void Metaspace::global_initialize() {
   MetaspaceGC::initialize();
 
+  bool class_space_inited = false;
 #if INCLUDE_CDS
   if (DumpSharedSpaces) {
     MetaspaceShared::initialize_dumptime_shared_and_meta_spaces();
+    class_space_inited = true;
   } else if (UseSharedSpaces) {
     // If any of the archived space fails to map, UseSharedSpaces
-    // is reset to false. Fall through to the
-    // (!DumpSharedSpaces && !UseSharedSpaces) case to set up class
-    // metaspace.
+    // is reset to false.
     MetaspaceShared::initialize_runtime_shared_and_meta_spaces();
+    class_space_inited = UseSharedSpaces;
   }
 
   if (DynamicDumpSharedSpaces && !UseSharedSpaces) {
     vm_exit_during_initialization("DynamicDumpSharedSpaces is unsupported when base CDS archive is not loaded", NULL);
   }
+#endif // INCLUDE_CDS
 
-  if (!DumpSharedSpaces && !UseSharedSpaces)
-#endif // INCLUDE_CDS
-  {
 #ifdef _LP64
-    if (using_class_space()) {
-      char* base = (char*)align_up(CompressedOops::end(), _reserve_alignment);
-      allocate_metaspace_compressed_klass_ptrs(base, 0);
-    }
-#endif // _LP64
+  if (using_class_space() && !class_space_inited) {
+    char* base = (char*)align_up(CompressedOops::end(), _reserve_alignment);
+    ReservedSpace dummy;
+    allocate_metaspace_compressed_klass_ptrs(dummy, base, 0);
   }
+#endif
 
   // Initialize these before initializing the VirtualSpaceList
   _first_chunk_word_size = InitialBootClassLoaderMetaspaceSize / BytesPerWord;
--- a/src/hotspot/share/memory/metaspace.hpp	Wed Nov 13 17:21:31 2019 -0500
+++ b/src/hotspot/share/memory/metaspace.hpp	Mon Nov 18 12:40:06 2019 -0500
@@ -172,16 +172,13 @@
     assert(!_frozen, "sanity");
   }
 #ifdef _LP64
-  static void allocate_metaspace_compressed_klass_ptrs(char* requested_addr, address cds_base);
+  static void allocate_metaspace_compressed_klass_ptrs(ReservedSpace metaspace_rs, char* requested_addr, address cds_base);
 #endif
 
  private:
 
 #ifdef _LP64
-  static void set_narrow_klass_base_and_shift(address metaspace_base, address cds_base);
-
-  // Returns true if can use CDS with metaspace allocated as specified address.
-  static bool can_use_cds_with_metaspace_addr(char* metaspace_base, address cds_base);
+  static void set_narrow_klass_base_and_shift(ReservedSpace metaspace_rs, address cds_base);
 
   static void initialize_class_space(ReservedSpace rs);
 #endif
--- a/src/hotspot/share/memory/metaspaceClosure.hpp	Wed Nov 13 17:21:31 2019 -0500
+++ b/src/hotspot/share/memory/metaspaceClosure.hpp	Mon Nov 18 12:40:06 2019 -0500
@@ -75,6 +75,10 @@
     _default
   };
 
+  enum SpecialRef {
+    _method_entry_ref
+  };
+
   // class MetaspaceClosure::Ref --
   //
   // MetaspaceClosure can be viewed as a very simple type of copying garbage
@@ -278,6 +282,16 @@
   template <class T> void push(T** mpp, Writability w = _default) {
     push_impl(new ObjectRef<T>(mpp, w));
   }
+
+  template <class T> void push_method_entry(T** mpp, intptr_t* p) {
+    push_special(_method_entry_ref, new ObjectRef<T>(mpp, _default), (intptr_t*)p);
+  }
+
+  // This is for tagging special pointers that are not a reference to MetaspaceObj. It's currently
+  // used to mark the method entry points in Method/ConstMethod.
+  virtual void push_special(SpecialRef type, Ref* obj, intptr_t* p) {
+    assert(type == _method_entry_ref, "only special type allowed for now");
+  }
 };
 
 // This is a special MetaspaceClosure that visits each unique MetaspaceObj once.
--- a/src/hotspot/share/memory/metaspaceShared.cpp	Wed Nov 13 17:21:31 2019 -0500
+++ b/src/hotspot/share/memory/metaspaceShared.cpp	Mon Nov 18 12:40:06 2019 -0500
@@ -41,6 +41,8 @@
 #include "interpreter/bytecodes.hpp"
 #include "logging/log.hpp"
 #include "logging/logMessage.hpp"
+#include "memory/archiveUtils.inline.hpp"
+#include "memory/dynamicArchive.hpp"
 #include "memory/filemap.hpp"
 #include "memory/heapShared.inline.hpp"
 #include "memory/metaspace.hpp"
@@ -48,7 +50,6 @@
 #include "memory/metaspaceShared.hpp"
 #include "memory/resourceArea.hpp"
 #include "memory/universe.hpp"
-#include "memory/dynamicArchive.hpp"
 #include "oops/compressedOops.inline.hpp"
 #include "oops/instanceClassLoaderKlass.hpp"
 #include "oops/instanceMirrorKlass.hpp"
@@ -67,7 +68,7 @@
 #include "runtime/vmThread.hpp"
 #include "runtime/vmOperations.hpp"
 #include "utilities/align.hpp"
-#include "utilities/bitMap.hpp"
+#include "utilities/bitMap.inline.hpp"
 #include "utilities/defaultStream.hpp"
 #include "utilities/hashtable.inline.hpp"
 #if INCLUDE_G1GC
@@ -82,8 +83,8 @@
 bool MetaspaceShared::_remapped_readwrite = false;
 address MetaspaceShared::_i2i_entry_code_buffers = NULL;
 size_t MetaspaceShared::_i2i_entry_code_buffers_size = 0;
-size_t MetaspaceShared::_core_spaces_size = 0;
 void* MetaspaceShared::_shared_metaspace_static_top = NULL;
+intx MetaspaceShared::_relocation_delta;
 
 // The CDS archive is divided into the following regions:
 //     mc  - misc code (the method entry trampolines)
@@ -147,9 +148,21 @@
   return p;
 }
 
+void DumpRegion::append_intptr_t(intptr_t n, bool need_to_mark) {
+  assert(is_aligned(_top, sizeof(intptr_t)), "bad alignment");
+  intptr_t *p = (intptr_t*)_top;
+  char* newtop = _top + sizeof(intptr_t);
+  expand_top_to(newtop);
+  *p = n;
+  if (need_to_mark) {
+    ArchivePtrMarker::mark_pointer(p);
+  }
+}
+
 void DumpRegion::print(size_t total_bytes) const {
   tty->print_cr("%-3s space: " SIZE_FORMAT_W(9) " [ %4.1f%% of total] out of " SIZE_FORMAT_W(9) " bytes [%5.1f%% used] at " INTPTR_FORMAT,
-                _name, used(), percent_of(used(), total_bytes), reserved(), percent_of(used(), reserved()), p2i(_base));
+                _name, used(), percent_of(used(), total_bytes), reserved(), percent_of(used(), reserved()),
+                p2i(_base + MetaspaceShared::final_delta()));
 }
 
 void DumpRegion::print_out_of_space_msg(const char* failing_region, size_t needed_bytes) {
@@ -172,14 +185,14 @@
   }
 }
 
-DumpRegion _mc_region("mc"), _ro_region("ro"), _rw_region("rw"), _md_region("md");
-size_t _total_closed_archive_region_size = 0, _total_open_archive_region_size = 0;
+static DumpRegion _mc_region("mc"), _ro_region("ro"), _rw_region("rw"), _md_region("md");
+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)) {
-    vm_exit_during_initialization("Unable to allocate memory for shared space");
+    fatal("Unable to allocate memory for shared space");
   }
   first_space->init(&_shared_rs, (char*)first_space_bottom);
 }
@@ -209,73 +222,32 @@
   return _ro_region.allocate(num_bytes);
 }
 
-void MetaspaceShared::initialize_runtime_shared_and_meta_spaces() {
-  assert(UseSharedSpaces, "Must be called when UseSharedSpaces is enabled");
-
-  // If using shared space, open the file that contains the shared space
-  // and map in the memory before initializing the rest of metaspace (so
-  // the addresses don't conflict)
-  FileMapInfo* mapinfo = new FileMapInfo(true);
-
-  // Open the shared archive file, read and validate the header. If
-  // initialization fails, shared spaces [UseSharedSpaces] are
-  // disabled and the file is closed.
-  // Map in spaces now also
-  if (mapinfo->initialize(true) && map_shared_spaces(mapinfo)) {
-    size_t cds_total = core_spaces_size();
-    address cds_address = (address)mapinfo->region_addr(0);
-    char* cds_end = (char *)align_up(cds_address + cds_total,
-                                     Metaspace::reserve_alignment());
-
-    // Mapping the dynamic archive before allocating the class space
-    cds_end = initialize_dynamic_runtime_shared_spaces((char*)cds_address, cds_end);
-
-#ifdef _LP64
-    if (Metaspace::using_class_space()) {
-      // If UseCompressedClassPointers is set then allocate the metaspace area
-      // above the heap and above the CDS area (if it exists).
-      Metaspace::allocate_metaspace_compressed_klass_ptrs(cds_end, cds_address);
-      // map_heap_regions() compares the current narrow oop and klass encodings
-      // with the archived ones, so it must be done after all encodings are determined.
-      mapinfo->map_heap_regions();
-    }
-    CompressedKlassPointers::set_range(CompressedClassSpaceSize);
-#endif // _LP64
+// When reserving an address range using ReservedSpace, we need an alignment that satisfies both:
+// os::vm_allocation_granularity() -- so that we can sub-divide this range into multiple mmap regions,
+//                                    while keeping the first range at offset 0 of this range.
+// Metaspace::reserve_alignment()  -- so we can pass the region to
+//                                    Metaspace::allocate_metaspace_compressed_klass_ptrs.
+size_t MetaspaceShared::reserved_space_alignment() {
+  size_t os_align = os::vm_allocation_granularity();
+  size_t ms_align = Metaspace::reserve_alignment();
+  if (os_align >= ms_align) {
+    assert(os_align % ms_align == 0, "must be a multiple");
+    return os_align;
   } else {
-    assert(!mapinfo->is_open() && !UseSharedSpaces,
-           "archive file not closed or shared spaces not disabled.");
+    assert(ms_align % os_align == 0, "must be a multiple");
+    return ms_align;
   }
 }
 
-char* MetaspaceShared::initialize_dynamic_runtime_shared_spaces(
-        char* static_start, char* static_end) {
-  assert(UseSharedSpaces, "must be runtime");
-  char* cds_end = static_end;
-  if (!DynamicDumpSharedSpaces) {
-    address dynamic_top = DynamicArchive::map();
-    if (dynamic_top != NULL) {
-      assert(dynamic_top > (address)static_start, "Unexpected layout");
-      MetaspaceObj::expand_shared_metaspace_range(dynamic_top);
-      cds_end = (char *)align_up(dynamic_top, Metaspace::reserve_alignment());
-    }
-  }
-  return cds_end;
-}
-
-ReservedSpace* MetaspaceShared::reserve_shared_rs(size_t size, size_t alignment,
-                                                  bool large, char* requested_address) {
-  if (requested_address != NULL) {
-    _shared_rs = ReservedSpace(size, alignment, large, requested_address);
-  } else {
-    _shared_rs = ReservedSpace(size, alignment, large);
-  }
-  return &_shared_rs;
+ReservedSpace MetaspaceShared::reserve_shared_space(size_t size, char* requested_address) {
+  bool large_pages = false; // Don't use large pages for the CDS archive.
+  assert(is_aligned(requested_address, reserved_space_alignment()), "must be");
+  return ReservedSpace(size, reserved_space_alignment(), large_pages, requested_address);
 }
 
 void MetaspaceShared::initialize_dumptime_shared_and_meta_spaces() {
   assert(DumpSharedSpaces, "should be called for dump time only");
-  const size_t reserve_alignment = Metaspace::reserve_alignment();
-  bool large_pages = false; // No large pages when dumping the CDS archive.
+  const size_t reserve_alignment = reserved_space_alignment();
   char* shared_base = (char*)align_up((char*)SharedBaseAddress, reserve_alignment);
 
 #ifdef _LP64
@@ -296,15 +268,22 @@
   size_t cds_total = align_down(256*M, reserve_alignment);
 #endif
 
+  bool use_requested_base = true;
+  if (ArchiveRelocationMode == 1) {
+    log_info(cds)("ArchiveRelocationMode == 1: always allocate class space at an alternative address");
+    use_requested_base = false;
+  }
+
   // First try to reserve the space at the specified SharedBaseAddress.
-  //_shared_rs = ReservedSpace(cds_total, reserve_alignment, large_pages, shared_base);
-  reserve_shared_rs(cds_total, reserve_alignment, large_pages, shared_base);
+  assert(!_shared_rs.is_reserved(), "must be");
+  if (use_requested_base) {
+    _shared_rs = reserve_shared_space(cds_total, shared_base);
+  }
   if (_shared_rs.is_reserved()) {
     assert(shared_base == 0 || _shared_rs.base() == shared_base, "should match");
   } else {
     // Get a mmap region anywhere if the SharedBaseAddress fails.
-    //_shared_rs = ReservedSpace(cds_total, reserve_alignment, large_pages);
-    reserve_shared_rs(cds_total, reserve_alignment, large_pages, NULL);
+    _shared_rs = reserve_shared_space(cds_total);
   }
   if (!_shared_rs.is_reserved()) {
     vm_exit_during_initialization("Unable to reserve memory for shared space",
@@ -442,6 +421,8 @@
   assert(commit <= uncommitted, "sanity");
 
   bool result = _shared_vs.expand_by(commit, false);
+  ArchivePtrMarker::expand_ptr_end((address*)_shared_vs.high());
+
   if (!result) {
     vm_exit_during_initialization(err_msg("Failed to expand shared space to " SIZE_FORMAT " bytes",
                                           need_committed_size));
@@ -451,6 +432,10 @@
                 commit, _shared_vs.actual_committed_size(), _shared_vs.high());
 }
 
+void MetaspaceShared::initialize_ptr_marker(CHeapBitMap* ptrmap) {
+  ArchivePtrMarker::initialize(ptrmap, (address*)_shared_vs.low(), (address*)_shared_vs.high());
+}
+
 // Read/write a data stream for restoring/preserving metadata pointers and
 // miscellaneous data from/to the shared archive file.
 
@@ -469,6 +454,7 @@
   soc->do_tag(sizeof(Symbol));
 
   // Dump/restore miscellaneous metadata.
+  JavaClasses::serialize_offsets(soc);
   Universe::serialize(soc);
   soc->do_tag(--tag);
 
@@ -482,7 +468,6 @@
   HeapShared::serialize_subgraph_info_table_header(soc);
   SystemDictionaryShared::serialize_dictionary_headers(soc);
 
-  JavaClasses::serialize_offsets(soc);
   InstanceMirrorKlass::serialize_offsets(soc);
   soc->do_tag(--tag);
 
@@ -705,7 +690,9 @@
   // Switch the vtable pointer to point to the cloned vtable.
   static void patch(Metadata* obj) {
     assert(DumpSharedSpaces, "dump-time only");
+    assert(MetaspaceShared::is_in_output_space(obj), "must be");
     *(void**)obj = (void*)(_info->cloned_vtable());
+    ArchivePtrMarker::mark_pointer(obj);
   }
 
   static bool is_valid_shared_object(const T* obj) {
@@ -799,7 +786,8 @@
 }
 
 #define ALLOC_CPP_VTABLE_CLONE(c) \
-  _cloned_cpp_vtptrs[c##_Kind] = CppVtableCloner<c>::allocate(#c);
+  _cloned_cpp_vtptrs[c##_Kind] = CppVtableCloner<c>::allocate(#c); \
+  ArchivePtrMarker::mark_pointer(&_cloned_cpp_vtptrs[c##_Kind]);
 
 #define CLONE_CPP_VTABLE(c) \
   p = CppVtableCloner<c>::clone_vtable(#c, (CppVtableInfo*)p);
@@ -965,7 +953,7 @@
   assert(size % sizeof(intptr_t) == 0, "bad size");
   do_tag((int)size);
   while (size > 0) {
-    _dump_region->append_intptr_t(*(intptr_t*)start);
+    _dump_region->append_intptr_t(*(intptr_t*)start, true);
     start += sizeof(intptr_t);
     size -= sizeof(intptr_t);
   }
@@ -1129,9 +1117,13 @@
                                  GrowableArray<ArchiveHeapOopmapInfo>* oopmaps);
   void dump_symbols();
   char* dump_read_only_tables();
+  void print_class_stats();
   void print_region_stats();
+  void print_bitmap_region_stats(size_t size, size_t total_size);
   void print_heap_region_stats(GrowableArray<MemRegion> *heap_mem,
-                               const char *name, const size_t total_size);
+                               const char *name, size_t total_size);
+  void relocate_to_default_base_address(CHeapBitMap* ptrmap);
+
 public:
 
   VMOp_Type type() const { return VMOp_PopulateDumpSharedSpace; }
@@ -1276,6 +1268,15 @@
       ref->metaspace_pointers_do_at(&refer, new_loc);
       return true; // recurse into ref.obj()
     }
+    virtual void push_special(SpecialRef type, Ref* ref, intptr_t* p) {
+      assert(type == _method_entry_ref, "only special type allowed for now");
+      address obj = ref->obj();
+      address new_obj = get_new_loc(ref);
+      size_t offset = pointer_delta(p, obj,  sizeof(u1));
+      intptr_t* new_p = (intptr_t*)(new_obj + offset);
+      assert(*p == *new_p, "must be a copy");
+      ArchivePtrMarker::mark_pointer((address*)new_p);
+    }
   };
 
   // Relocate a reference to point to its shallow copy
@@ -1284,6 +1285,7 @@
     virtual bool do_ref(Ref* ref, bool read_only) {
       if (ref->not_null()) {
         ref->update(get_new_loc(ref));
+        ArchivePtrMarker::mark_pointer(ref->addr());
       }
       return false; // Do not recurse.
     }
@@ -1440,7 +1442,71 @@
   return start;
 }
 
+void VM_PopulateDumpSharedSpace::print_class_stats() {
+  tty->print_cr("Number of classes %d", _global_klass_objects->length());
+  {
+    int num_type_array = 0, num_obj_array = 0, num_inst = 0;
+    for (int i = 0; i < _global_klass_objects->length(); i++) {
+      Klass* k = _global_klass_objects->at(i);
+      if (k->is_instance_klass()) {
+        num_inst ++;
+      } else if (k->is_objArray_klass()) {
+        num_obj_array ++;
+      } else {
+        assert(k->is_typeArray_klass(), "sanity");
+        num_type_array ++;
+      }
+    }
+    tty->print_cr("    instance classes   = %5d", num_inst);
+    tty->print_cr("    obj array classes  = %5d", num_obj_array);
+    tty->print_cr("    type array classes = %5d", num_type_array);
+  }
+}
+
+void VM_PopulateDumpSharedSpace::relocate_to_default_base_address(CHeapBitMap* ptrmap) {
+  intx addr_delta = MetaspaceShared::final_delta();
+  if (addr_delta == 0) {
+    ArchivePtrMarker::compact((address)SharedBaseAddress, (address)_md_region.top());
+  } else {
+    // We are not able to reserve space at Arguments::default_SharedBaseAddress() (due to ASLR).
+    // This means that the current content of the archive is based on a random
+    // address. Let's relocate all the pointers, so that it can be mapped to
+    // Arguments::default_SharedBaseAddress() without runtime relocation.
+    //
+    // Note: both the base and dynamic archive are written with
+    // FileMapHeader::_shared_base_address == Arguments::default_SharedBaseAddress()
+
+    // Patch all pointers that are marked by ptrmap within this region,
+    // where we have just dumped all the metaspace data.
+    address patch_base = (address)SharedBaseAddress;
+    address patch_end  = (address)_md_region.top();
+    size_t size = patch_end - patch_base;
+
+    // the current value of the pointers to be patched must be within this
+    // range (i.e., must point to valid metaspace objects)
+    address valid_old_base = patch_base;
+    address valid_old_end  = patch_end;
+
+    // after patching, the pointers must point inside this range
+    // (the requested location of the archive, as mapped at runtime).
+    address valid_new_base = (address)Arguments::default_SharedBaseAddress();
+    address valid_new_end  = valid_new_base + size;
+
+    log_debug(cds)("Relocating archive from [" INTPTR_FORMAT " - " INTPTR_FORMAT " ] to "
+                   "[" INTPTR_FORMAT " - " INTPTR_FORMAT " ]", p2i(patch_base), p2i(patch_end),
+                   p2i(valid_new_base), p2i(valid_new_end));
+
+    SharedDataRelocator<true> patcher((address*)patch_base, (address*)patch_end, valid_old_base, valid_old_end,
+                                      valid_new_base, valid_new_end, addr_delta, ptrmap);
+    ptrmap->iterate(&patcher);
+    ArchivePtrMarker::compact(patcher.max_non_null_offset());
+  }
+}
+
 void VM_PopulateDumpSharedSpace::doit() {
+  CHeapBitMap ptrmap;
+  MetaspaceShared::initialize_ptr_marker(&ptrmap);
+
   // We should no longer allocate anything from the metaspace, so that:
   //
   // (1) Metaspace::allocate might trigger GC if we have run out of
@@ -1472,24 +1538,7 @@
   CollectClassesClosure collect_classes;
   ClassLoaderDataGraph::loaded_classes_do(&collect_classes);
 
-  tty->print_cr("Number of classes %d", _global_klass_objects->length());
-  {
-    int num_type_array = 0, num_obj_array = 0, num_inst = 0;
-    for (int i = 0; i < _global_klass_objects->length(); i++) {
-      Klass* k = _global_klass_objects->at(i);
-      if (k->is_instance_klass()) {
-        num_inst ++;
-      } else if (k->is_objArray_klass()) {
-        num_obj_array ++;
-      } else {
-        assert(k->is_typeArray_klass(), "sanity");
-        num_type_array ++;
-      }
-    }
-    tty->print_cr("    instance classes   = %5d", num_inst);
-    tty->print_cr("    obj array classes  = %5d", num_obj_array);
-    tty->print_cr("    type array classes = %5d", num_type_array);
-  }
+  print_class_stats();
 
   // Ensure the ConstMethods won't be modified at run-time
   tty->print("Updating ConstMethods ... ");
@@ -1520,12 +1569,6 @@
   MetaspaceShared::allocate_cpp_vtable_clones();
   _md_region.pack();
 
-  // The 4 core spaces are allocated consecutively mc->rw->ro->md, so there total size
-  // is just the spaces between the two ends.
-  size_t core_spaces_size = _md_region.end() - _mc_region.base();
-  assert(core_spaces_size == (size_t)align_up(core_spaces_size, Metaspace::reserve_alignment()),
-         "should already be aligned");
-
   // During patching, some virtual methods may be called, so at this point
   // the vtables must contain valid methods (as filled in by CppVtableCloner::allocate).
   MetaspaceShared::patch_cpp_vtable_pointers();
@@ -1534,6 +1577,10 @@
   // We don't want to write these addresses into the archive.
   MetaspaceShared::zero_cpp_vtable_clones_for_writing();
 
+  // relocate the data so that it can be mapped to Arguments::default_SharedBaseAddress()
+  // without runtime relocation.
+  relocate_to_default_base_address(&ptrmap);
+
   // Create and write the archive file that maps the shared spaces.
 
   FileMapInfo* mapinfo = new FileMapInfo(true);
@@ -1542,7 +1589,6 @@
   mapinfo->set_misc_data_patching_start(vtbl_list);
   mapinfo->set_i2i_entry_code_buffers(MetaspaceShared::i2i_entry_code_buffers(),
                                       MetaspaceShared::i2i_entry_code_buffers_size());
-  mapinfo->set_core_spaces_size(core_spaces_size);
   mapinfo->open_for_write();
 
   // NOTE: md contains the trampoline code for method entries, which are patched at run time,
@@ -1552,6 +1598,8 @@
   write_region(mapinfo, MetaspaceShared::ro, &_ro_region, /*read_only=*/true, /*allow_exec=*/false);
   write_region(mapinfo, MetaspaceShared::md, &_md_region, /*read_only=*/false,/*allow_exec=*/false);
 
+  mapinfo->write_bitmap_region(ArchivePtrMarker::ptrmap());
+
   _total_closed_archive_region_size = mapinfo->write_archive_heap_regions(
                                         _closed_archive_heap_regions,
                                         _closed_archive_heap_oopmaps,
@@ -1563,6 +1611,7 @@
                                         MetaspaceShared::first_open_archive_heap_region,
                                         MetaspaceShared::max_open_archive_heap_region);
 
+  mapinfo->set_final_requested_base((char*)Arguments::default_SharedBaseAddress());
   mapinfo->set_header_crc(mapinfo->compute_header_crc());
   mapinfo->write_header();
   mapinfo->close();
@@ -1594,12 +1643,16 @@
 
 void VM_PopulateDumpSharedSpace::print_region_stats() {
   // Print statistics of all the regions
+  const size_t bitmap_used = ArchivePtrMarker::ptrmap()->size_in_bytes();
+  const size_t bitmap_reserved = align_up(bitmap_used, Metaspace::reserve_alignment());
   const size_t total_reserved = _ro_region.reserved()  + _rw_region.reserved() +
                                 _mc_region.reserved()  + _md_region.reserved() +
+                                bitmap_reserved +
                                 _total_closed_archive_region_size +
                                 _total_open_archive_region_size;
   const size_t total_bytes = _ro_region.used()  + _rw_region.used() +
                              _mc_region.used()  + _md_region.used() +
+                             bitmap_used +
                              _total_closed_archive_region_size +
                              _total_open_archive_region_size;
   const double total_u_perc = percent_of(total_bytes, total_reserved);
@@ -1608,6 +1661,7 @@
   _rw_region.print(total_reserved);
   _ro_region.print(total_reserved);
   _md_region.print(total_reserved);
+  print_bitmap_region_stats(bitmap_reserved, total_reserved);
   print_heap_region_stats(_closed_archive_heap_regions, "ca", total_reserved);
   print_heap_region_stats(_open_archive_heap_regions, "oa", total_reserved);
 
@@ -1615,8 +1669,13 @@
                  total_bytes, total_reserved, total_u_perc);
 }
 
+void VM_PopulateDumpSharedSpace::print_bitmap_region_stats(size_t size, size_t total_size) {
+  tty->print_cr("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));
+}
+
 void VM_PopulateDumpSharedSpace::print_heap_region_stats(GrowableArray<MemRegion> *heap_mem,
-                                                         const char *name, const size_t total_size) {
+                                                         const char *name, size_t total_size) {
   int arr_len = heap_mem == NULL ? 0 : heap_mem->length();
   for (int i = 0; i < arr_len; i++) {
       char* start = (char*)heap_mem->at(i).start();
@@ -1636,9 +1695,13 @@
   o->set_klass(k);
 }
 
-Klass* MetaspaceShared::get_relocated_klass(Klass *k) {
+Klass* MetaspaceShared::get_relocated_klass(Klass *k, bool is_final) {
   assert(DumpSharedSpaces, "sanity");
-  return ArchiveCompactor::get_relocated_klass(k);
+  k = ArchiveCompactor::get_relocated_klass(k);
+  if (is_final) {
+    k = (Klass*)(address(k) + final_delta());
+  }
+  return k;
 }
 
 class LinkSharedClassesClosure : public KlassClosure {
@@ -1947,8 +2010,9 @@
   }
 }
 
-void MetaspaceShared::set_shared_metaspace_range(void* base, void* top) {
-  _shared_metaspace_static_top = top;
+void MetaspaceShared::set_shared_metaspace_range(void* base, void *static_top, void* top) {
+  assert(base <= static_top && static_top <= top, "must be");
+  _shared_metaspace_static_top = static_top;
   MetaspaceObj::set_shared_metaspace_range(base, top);
 }
 
@@ -1973,49 +2037,312 @@
   }
 }
 
-// Map shared spaces at requested addresses and return if succeeded.
-bool MetaspaceShared::map_shared_spaces(FileMapInfo* mapinfo) {
-  size_t image_alignment = mapinfo->alignment();
+void MetaspaceShared::initialize_runtime_shared_and_meta_spaces() {
+  assert(UseSharedSpaces, "Must be called when UseSharedSpaces is enabled");
+  MapArchiveResult result = MAP_ARCHIVE_OTHER_FAILURE;
+  FileMapInfo* static_mapinfo = open_static_archive();
+  FileMapInfo* dynamic_mapinfo = NULL;
+
+  if (static_mapinfo != NULL) {
+    dynamic_mapinfo = open_dynamic_archive();
+
+    // First try to map at the requested address
+    result = map_archives(static_mapinfo, dynamic_mapinfo, true);
+    if (result == MAP_ARCHIVE_MMAP_FAILURE) {
+      // Mapping has failed (probably due to ASLR). Let's map at an address chosen
+      // by the OS.
+      result = map_archives(static_mapinfo, dynamic_mapinfo, false);
+    }
+  }
+
+  if (result == MAP_ARCHIVE_SUCCESS) {
+    bool dynamic_mapped = (dynamic_mapinfo != NULL && dynamic_mapinfo->is_mapped());
+    char* cds_base = static_mapinfo->mapped_base();
+    char* cds_end =  dynamic_mapped ? dynamic_mapinfo->mapped_end() : static_mapinfo->mapped_end();
+    set_shared_metaspace_range(cds_base, static_mapinfo->mapped_end(), cds_end);
+    _relocation_delta = static_mapinfo->relocation_delta();
+    if (dynamic_mapped) {
+      FileMapInfo::set_shared_path_table(dynamic_mapinfo);
+    } else {
+      FileMapInfo::set_shared_path_table(static_mapinfo);
+    }
+  } else {
+    set_shared_metaspace_range(NULL, NULL, NULL);
+    UseSharedSpaces = false;
+    FileMapInfo::fail_continue("Unable to map shared spaces");
+    if (PrintSharedArchiveAndExit) {
+      vm_exit_during_initialization("Unable to use shared archive.");
+    }
+  }
+
+  if (static_mapinfo != NULL && !static_mapinfo->is_mapped()) {
+    delete static_mapinfo;
+  }
+  if (dynamic_mapinfo != NULL && !dynamic_mapinfo->is_mapped()) {
+    delete dynamic_mapinfo;
+  }
+}
+
+FileMapInfo* MetaspaceShared::open_static_archive() {
+  FileMapInfo* mapinfo = new FileMapInfo(true);
+  if (!mapinfo->initialize()) {
+    delete(mapinfo);
+    return NULL;
+  }
+  return mapinfo;
+}
+
+FileMapInfo* MetaspaceShared::open_dynamic_archive() {
+  if (DynamicDumpSharedSpaces) {
+    return NULL;
+  }
+  if (Arguments::GetSharedDynamicArchivePath() == NULL) {
+    return NULL;
+  }
 
-#ifndef _WINDOWS
-  // Map in the shared memory and then map the regions on top of it.
-  // On Windows, don't map the memory here because it will cause the
-  // mappings of the regions to fail.
-  ReservedSpace shared_rs = mapinfo->reserve_shared_memory();
-  if (!shared_rs.is_reserved()) return false;
-#endif
+  FileMapInfo* mapinfo = new FileMapInfo(false);
+  if (!mapinfo->initialize()) {
+    delete(mapinfo);
+    return NULL;
+  }
+  return mapinfo;
+}
+
+// use_requested_addr:
+//  true  = map at FileMapHeader::_requested_base_address
+//  false = map at an alternative address picked by OS.
+MapArchiveResult MetaspaceShared::map_archives(FileMapInfo* static_mapinfo, FileMapInfo* dynamic_mapinfo,
+                                               bool use_requested_addr) {
+  PRODUCT_ONLY(if (ArchiveRelocationMode == 1 && use_requested_addr) {
+      // For product build only -- this is for benchmarking the cost of doing relocation.
+      // For debug builds, the check is done in FileMapInfo::map_regions for better test coverage.
+      log_info(cds)("ArchiveRelocationMode == 1: always map archive(s) at an alternative address");
+      return MAP_ARCHIVE_MMAP_FAILURE;
+    });
+
+  if (ArchiveRelocationMode == 2 && !use_requested_addr) {
+    log_info(cds)("ArchiveRelocationMode == 2: never map archive(s) at an alternative address");
+    return MAP_ARCHIVE_MMAP_FAILURE;
+  };
+
+  if (dynamic_mapinfo != NULL) {
+    // Ensure that the OS won't be able to allocate new memory spaces between the two
+    // archives, or else it would mess up the simple comparision in MetaspaceObj::is_shared().
+    assert(static_mapinfo->mapping_end_offset() == dynamic_mapinfo->mapping_base_offset(), "no gap");
+  }
 
-  assert(!DumpSharedSpaces, "Should not be called with DumpSharedSpaces");
+  ReservedSpace main_rs, archive_space_rs, class_space_rs;
+  MapArchiveResult result = MAP_ARCHIVE_OTHER_FAILURE;
+  char* mapped_base_address = reserve_address_space_for_archives(static_mapinfo, dynamic_mapinfo,
+                                                                 use_requested_addr, main_rs, archive_space_rs,
+                                                                 class_space_rs);
+  if (mapped_base_address == NULL) {
+    result = MAP_ARCHIVE_MMAP_FAILURE;
+  } else {
+    log_debug(cds)("Reserved archive_space_rs     [" INTPTR_FORMAT " - " INTPTR_FORMAT "] (" SIZE_FORMAT ") bytes",
+                   p2i(archive_space_rs.base()), p2i(archive_space_rs.end()), archive_space_rs.size());
+    log_debug(cds)("Reserved class_space_rs [" INTPTR_FORMAT " - " INTPTR_FORMAT "] (" SIZE_FORMAT ") bytes",
+                   p2i(class_space_rs.base()), p2i(class_space_rs.end()), class_space_rs.size());
+    MapArchiveResult static_result = map_archive(static_mapinfo, mapped_base_address, archive_space_rs);
+    MapArchiveResult dynamic_result = (static_result == MAP_ARCHIVE_SUCCESS) ?
+                                     map_archive(dynamic_mapinfo, mapped_base_address, archive_space_rs) : MAP_ARCHIVE_OTHER_FAILURE;
 
-  // Map each shared region
-  int regions[] = {mc, rw, ro, md};
-  size_t len = sizeof(regions)/sizeof(int);
-  char* saved_base[] = {NULL, NULL, NULL, NULL};
-  char* top = mapinfo->map_regions(regions, saved_base, len );
+    if (static_result == MAP_ARCHIVE_SUCCESS) {
+      if (dynamic_result == MAP_ARCHIVE_SUCCESS) {
+        result = MAP_ARCHIVE_SUCCESS;
+      } else if (dynamic_result == MAP_ARCHIVE_OTHER_FAILURE) {
+        assert(dynamic_mapinfo != NULL && !dynamic_mapinfo->is_mapped(), "must have failed");
+        // No need to retry mapping the dynamic archive again, as it will never succeed
+        // (bad file, etc) -- just keep the base archive.
+        log_warning(cds, dynamic)("Unable to use shared archive. The top archive failed to load: %s",
+                                  dynamic_mapinfo->full_path());
+        result = MAP_ARCHIVE_SUCCESS;
+        // TODO, we can give the unused space for the dynamic archive to class_space_rs, but there's no
+        // easy API to do that right now.
+      } else {
+        result = MAP_ARCHIVE_MMAP_FAILURE;
+      }
+    } else if (static_result == MAP_ARCHIVE_OTHER_FAILURE) {
+      result = MAP_ARCHIVE_OTHER_FAILURE;
+    } else {
+      result = MAP_ARCHIVE_MMAP_FAILURE;
+    }
+  }
 
-  if (top != NULL &&
-      (image_alignment == (size_t)os::vm_allocation_granularity()) &&
-      mapinfo->validate_shared_path_table()) {
-    // Success -- set up MetaspaceObj::_shared_metaspace_{base,top} for
-    // fast checking in MetaspaceShared::is_in_shared_metaspace() and
-    // MetaspaceObj::is_shared().
-    _core_spaces_size = mapinfo->core_spaces_size();
-    set_shared_metaspace_range((void*)saved_base[0], (void*)top);
-    return true;
+  if (result == MAP_ARCHIVE_SUCCESS) {
+    if (!main_rs.is_reserved() && class_space_rs.is_reserved()) {
+      MemTracker::record_virtual_memory_type((address)class_space_rs.base(), mtClass);
+    }
+    SharedBaseAddress = (size_t)mapped_base_address;
+    LP64_ONLY({
+        if (Metaspace::using_class_space()) {
+          assert(class_space_rs.is_reserved(), "must be");
+          char* cds_base = static_mapinfo->mapped_base();
+          Metaspace::allocate_metaspace_compressed_klass_ptrs(class_space_rs, NULL, (address)cds_base);
+          // map_heap_regions() compares the current narrow oop and klass encodings
+          // with the archived ones, so it must be done after all encodings are determined.
+          static_mapinfo->map_heap_regions();
+        }
+        CompressedKlassPointers::set_range(CompressedClassSpaceSize);
+      });
+  } else {
+    unmap_archive(static_mapinfo);
+    unmap_archive(dynamic_mapinfo);
+    release_reserved_spaces(main_rs, archive_space_rs, class_space_rs);
+  }
+
+  return result;
+}
+
+char* MetaspaceShared::reserve_address_space_for_archives(FileMapInfo* static_mapinfo,
+                                                          FileMapInfo* dynamic_mapinfo,
+                                                          bool use_requested_addr,
+                                                          ReservedSpace& main_rs,
+                                                          ReservedSpace& archive_space_rs,
+                                                          ReservedSpace& class_space_rs) {
+  const bool use_klass_space = NOT_LP64(false) LP64_ONLY(Metaspace::using_class_space());
+  const size_t class_space_size = NOT_LP64(0) LP64_ONLY(Metaspace::compressed_class_space_size());
+
+  if (use_klass_space) {
+    assert(class_space_size > 0, "CompressedClassSpaceSize must have been validated");
+  }
+  if (use_requested_addr && !is_aligned(static_mapinfo->requested_base_address(), reserved_space_alignment())) {
+    return NULL;
+  }
+
+  // Size and requested location of the archive_space_rs (for both static and dynamic archives)
+  size_t base_offset = static_mapinfo->mapping_base_offset();
+  size_t end_offset  = (dynamic_mapinfo == NULL) ? static_mapinfo->mapping_end_offset() : dynamic_mapinfo->mapping_end_offset();
+  assert(base_offset == 0, "must be");
+  assert(is_aligned(end_offset,  os::vm_allocation_granularity()), "must be");
+  assert(is_aligned(base_offset, os::vm_allocation_granularity()), "must be");
+
+  // In case reserved_space_alignment() != os::vm_allocation_granularity()
+  assert((size_t)os::vm_allocation_granularity() <= reserved_space_alignment(), "must be");
+  end_offset = align_up(end_offset, reserved_space_alignment());
+
+  size_t archive_space_size = end_offset - base_offset;
+
+  // Special handling for Windows because it cannot mmap into a reserved space:
+  //    use_requested_addr: We just map each region individually, and give up if any one of them fails.
+  //   !use_requested_addr: We reserve the space first, and then os::read in all the regions (instead of mmap).
+  //                        We're going to patch all the pointers anyway so there's no benefit for mmap.
+
+  if (use_requested_addr) {
+    char* archive_space_base = static_mapinfo->requested_base_address() + base_offset;
+    char* archive_space_end  = archive_space_base + archive_space_size;
+    if (!MetaspaceShared::use_windows_memory_mapping()) {
+      archive_space_rs = reserve_shared_space(archive_space_size, archive_space_base);
+      if (!archive_space_rs.is_reserved()) {
+        return NULL;
+      }
+    }
+    if (use_klass_space) {
+      // Make sure we can map the klass space immediately following the archive_space space
+      char* class_space_base = archive_space_end;
+      class_space_rs = reserve_shared_space(class_space_size, class_space_base);
+      if (!class_space_rs.is_reserved()) {
+        return NULL;
+      }
+    }
+    return static_mapinfo->requested_base_address();
   } else {
-    mapinfo->unmap_regions(regions, saved_base, len);
-#ifndef _WINDOWS
-    // Release the entire mapped region
-    shared_rs.release();
-#endif
-    // If -Xshare:on is specified, print out the error message and exit VM,
-    // otherwise, set UseSharedSpaces to false and continue.
-    if (RequireSharedSpaces || PrintSharedArchiveAndExit) {
-      vm_exit_during_initialization("Unable to use shared archive.", "Failed map_region for using -Xshare:on.");
+    if (use_klass_space) {
+      main_rs = reserve_shared_space(archive_space_size + class_space_size);
+      if (main_rs.is_reserved()) {
+        archive_space_rs = main_rs.first_part(archive_space_size, reserved_space_alignment(), /*split=*/true);
+        class_space_rs = main_rs.last_part(archive_space_size);
+      }
+    } else {
+      main_rs = reserve_shared_space(archive_space_size);
+      archive_space_rs = main_rs;
+    }
+    if (archive_space_rs.is_reserved()) {
+      return archive_space_rs.base();
     } else {
-      FLAG_SET_DEFAULT(UseSharedSpaces, false);
+      return NULL;
+    }
+  }
+}
+
+void MetaspaceShared::release_reserved_spaces(ReservedSpace& main_rs,
+                                              ReservedSpace& archive_space_rs,
+                                              ReservedSpace& class_space_rs) {
+  if (main_rs.is_reserved()) {
+    assert(main_rs.contains(archive_space_rs.base()), "must be");
+    assert(main_rs.contains(class_space_rs.base()), "must be");
+    log_debug(cds)("Released shared space (archive+classes) " INTPTR_FORMAT, p2i(main_rs.base()));
+    main_rs.release();
+  } else {
+    if (archive_space_rs.is_reserved()) {
+      log_debug(cds)("Released shared space (archive) " INTPTR_FORMAT, p2i(archive_space_rs.base()));
+      archive_space_rs.release();
+    }
+    if (class_space_rs.is_reserved()) {
+      log_debug(cds)("Released shared space (classes) " INTPTR_FORMAT, p2i(class_space_rs.base()));
+      class_space_rs.release();
     }
-    return false;
+  }
+}
+
+static int static_regions[]  = {MetaspaceShared::mc,
+                                MetaspaceShared::rw,
+                                MetaspaceShared::ro,
+                                MetaspaceShared::md};
+static int dynamic_regions[] = {MetaspaceShared::rw,
+                                MetaspaceShared::ro,
+                                MetaspaceShared::mc};
+static int static_regions_count  = 4;
+static int dynamic_regions_count = 3;
+
+MapArchiveResult MetaspaceShared::map_archive(FileMapInfo* mapinfo, char* mapped_base_address, ReservedSpace rs) {
+  assert(UseSharedSpaces, "must be runtime");
+  if (mapinfo == NULL) {
+    return MAP_ARCHIVE_SUCCESS; // no error has happeed -- trivially succeeded.
+  }
+
+  mapinfo->set_is_mapped(false);
+
+  if (mapinfo->alignment() != (size_t)os::vm_allocation_granularity()) {
+    log_error(cds)("Unable to map CDS archive -- os::vm_allocation_granularity() expected: " SIZE_FORMAT
+                   " actual: %d", mapinfo->alignment(), os::vm_allocation_granularity());
+    return MAP_ARCHIVE_OTHER_FAILURE;
+  }
+
+  MapArchiveResult result = mapinfo->is_static() ?
+    mapinfo->map_regions(static_regions, static_regions_count, mapped_base_address, rs) :
+    mapinfo->map_regions(dynamic_regions, dynamic_regions_count, mapped_base_address, rs);
+
+  if (result != MAP_ARCHIVE_SUCCESS) {
+    unmap_archive(mapinfo);
+    return result;
+  }
+
+  if (mapinfo->is_static()) {
+    if (!mapinfo->validate_shared_path_table()) {
+      unmap_archive(mapinfo);
+      return MAP_ARCHIVE_OTHER_FAILURE;
+    }
+  } else {
+    if (!DynamicArchive::validate(mapinfo)) {
+      unmap_archive(mapinfo);
+      return MAP_ARCHIVE_OTHER_FAILURE;
+    }
+  }
+
+  mapinfo->set_is_mapped(true);
+  return MAP_ARCHIVE_SUCCESS;
+}
+
+void MetaspaceShared::unmap_archive(FileMapInfo* mapinfo) {
+  assert(UseSharedSpaces, "must be runtime");
+  if (mapinfo != NULL) {
+    if (mapinfo->is_static()) {
+      mapinfo->unmap_regions(static_regions, static_regions_count);
+    } else {
+      mapinfo->unmap_regions(dynamic_regions, dynamic_regions_count);
+    }
+    mapinfo->set_is_mapped(false);
   }
 }
 
@@ -2023,17 +2350,15 @@
 // serialize it out to its various destinations.
 
 void MetaspaceShared::initialize_shared_spaces() {
-  FileMapInfo *mapinfo = FileMapInfo::current_info();
-  _i2i_entry_code_buffers = mapinfo->i2i_entry_code_buffers();
-  _i2i_entry_code_buffers_size = mapinfo->i2i_entry_code_buffers_size();
-  // _core_spaces_size is loaded from the shared archive immediatelly after mapping
-  assert(_core_spaces_size == mapinfo->core_spaces_size(), "sanity");
-  char* buffer = mapinfo->misc_data_patching_start();
+  FileMapInfo *static_mapinfo = FileMapInfo::current_info();
+  _i2i_entry_code_buffers = static_mapinfo->i2i_entry_code_buffers();
+  _i2i_entry_code_buffers_size = static_mapinfo->i2i_entry_code_buffers_size();
+  char* buffer = static_mapinfo->misc_data_patching_start();
   clone_cpp_vtables((intptr_t*)buffer);
 
   // Verify various attributes of the archive, plus initialize the
   // shared string/symbol tables
-  buffer = mapinfo->serialized_data_start();
+  buffer = static_mapinfo->serialized_data_start();
   intptr_t* array = (intptr_t*)buffer;
   ReadClosure rc(&array);
   serialize(&rc);
@@ -2041,17 +2366,26 @@
   // Initialize the run-time symbol table.
   SymbolTable::create_table();
 
-  mapinfo->patch_archived_heap_embedded_pointers();
+  static_mapinfo->patch_archived_heap_embedded_pointers();
 
   // Close the mapinfo file
-  mapinfo->close();
+  static_mapinfo->close();
+
+  FileMapInfo *dynamic_mapinfo = FileMapInfo::dynamic_info();
+  if (dynamic_mapinfo != NULL) {
+    intptr_t* buffer = (intptr_t*)dynamic_mapinfo->serialized_data_start();
+    ReadClosure rc(&buffer);
+    SymbolTable::serialize_shared_table_header(&rc, false);
+    SystemDictionaryShared::serialize_dictionary_headers(&rc, false);
+    dynamic_mapinfo->close();
+  }
 
   if (PrintSharedArchiveAndExit) {
     if (PrintSharedDictionary) {
       tty->print_cr("\nShared classes:\n");
       SystemDictionaryShared::print_on(tty);
     }
-    if (_archive_loading_failed) {
+    if (FileMapInfo::current_info() == NULL || _archive_loading_failed) {
       tty->print_cr("archive is invalid");
       vm_exit(1);
     } else {
@@ -2094,3 +2428,10 @@
   vm_exit_during_initialization(err_msg("Unable to allocate from '%s' region", name),
                                 "Please reduce the number of shared classes.");
 }
+
+// This is used to relocate the pointers so that the archive can be mapped at
+// Arguments::default_SharedBaseAddress() without runtime relocation.
+intx MetaspaceShared::final_delta() {
+  return intx(Arguments::default_SharedBaseAddress())  // We want the archive to be mapped to here at runtime
+       - intx(SharedBaseAddress);                      // .. but the archive is mapped at here at dump time
+}
--- a/src/hotspot/share/memory/metaspaceShared.hpp	Wed Nov 13 17:21:31 2019 -0500
+++ b/src/hotspot/share/memory/metaspaceShared.hpp	Mon Nov 18 12:40:06 2019 -0500
@@ -37,6 +37,13 @@
 #define MAX_SHARED_DELTA                (0x7FFFFFFF)
 
 class FileMapInfo;
+class CHeapBitMap;
+
+enum MapArchiveResult {
+  MAP_ARCHIVE_SUCCESS,
+  MAP_ARCHIVE_MMAP_FAILURE,
+  MAP_ARCHIVE_OTHER_FAILURE
+};
 
 class MetaspaceSharedStats {
 public:
@@ -62,13 +69,7 @@
   char* expand_top_to(char* newtop);
   char* allocate(size_t num_bytes, size_t alignment=BytesPerWord);
 
-  void append_intptr_t(intptr_t n) {
-    assert(is_aligned(_top, sizeof(intptr_t)), "bad alignment");
-    intptr_t *p = (intptr_t*)_top;
-    char* newtop = _top + sizeof(intptr_t);
-    expand_top_to(newtop);
-    *p = n;
-  }
+  void append_intptr_t(intptr_t n, bool need_to_mark = false);
 
   char* base()      const { return _base;        }
   char* top()       const { return _top;         }
@@ -117,17 +118,15 @@
   }
 
   void do_ptr(void** p) {
-    _dump_region->append_intptr_t((intptr_t)*p);
+    _dump_region->append_intptr_t((intptr_t)*p, true);
   }
 
   void do_u4(u4* p) {
-    void* ptr = (void*)(uintx(*p));
-    do_ptr(&ptr);
+    _dump_region->append_intptr_t((intptr_t)(*p));
   }
 
   void do_bool(bool *p) {
-    void* ptr = (void*)(uintx(*p));
-    do_ptr(&ptr);
+    _dump_region->append_intptr_t((intptr_t)(*p));
   }
 
   void do_tag(int tag) {
@@ -170,7 +169,7 @@
   bool reading() const { return true; }
 };
 
-#endif
+#endif // INCLUDE_CDS
 
 // Class Data Sharing Support
 class MetaspaceShared : AllStatic {
@@ -187,6 +186,7 @@
   static size_t  _i2i_entry_code_buffers_size;
   static size_t  _core_spaces_size;
   static void* _shared_metaspace_static_top;
+  static intx _relocation_delta;
  public:
   enum {
     // core archive spaces
@@ -194,11 +194,12 @@
     rw = 1,  // read-write shared space in the heap
     ro = 2,  // read-only shared space in the heap
     md = 3,  // miscellaneous data for initializing tables, etc.
-    num_core_spaces = 4, // number of non-string regions
-    num_non_heap_spaces = 4,
+    bm = 4,  // relocation bitmaps (freed after file mapping is finished)
+    num_core_region = 4,
+    num_non_heap_spaces = 5,
 
     // mapped java heap regions
-    first_closed_archive_heap_region = md + 1,
+    first_closed_archive_heap_region = bm + 1,
     max_closed_archive_heap_region = 2,
     last_closed_archive_heap_region = first_closed_archive_heap_region + max_closed_archive_heap_region - 1,
     first_open_archive_heap_region = last_closed_archive_heap_region + 1,
@@ -220,16 +221,14 @@
     CDS_ONLY(return &_shared_rs);
     NOT_CDS(return NULL);
   }
+
+  static void set_shared_rs(ReservedSpace rs) {
+    CDS_ONLY(_shared_rs = rs);
+  }
+
   static void commit_shared_space_to(char* newtop) NOT_CDS_RETURN;
-  static size_t core_spaces_size() {
-    assert(DumpSharedSpaces || UseSharedSpaces, "sanity");
-    assert(_core_spaces_size != 0, "sanity");
-    return _core_spaces_size;
-  }
   static void initialize_dumptime_shared_and_meta_spaces() NOT_CDS_RETURN;
   static void initialize_runtime_shared_and_meta_spaces() NOT_CDS_RETURN;
-  static char* initialize_dynamic_runtime_shared_spaces(
-                     char* static_start, char* static_end) NOT_CDS_RETURN_(NULL);
   static void post_initialize(TRAPS) NOT_CDS_RETURN;
 
   // Delta of this object from SharedBaseAddress
@@ -245,22 +244,25 @@
   static void set_archive_loading_failed() {
     _archive_loading_failed = true;
   }
+  static bool is_in_output_space(void* ptr) {
+    assert(DumpSharedSpaces, "must be");
+    return shared_rs()->contains(ptr);
+  }
+
   static bool map_shared_spaces(FileMapInfo* mapinfo) NOT_CDS_RETURN_(false);
   static void initialize_shared_spaces() NOT_CDS_RETURN;
 
   // Return true if given address is in the shared metaspace regions (i.e., excluding any
   // mapped shared heap regions.)
   static bool is_in_shared_metaspace(const void* p) {
-    // If no shared metaspace regions are mapped, MetaspceObj::_shared_metaspace_{base,top} will
-    // both be NULL and all values of p will be rejected quickly.
-    return (p < MetaspaceObj::shared_metaspace_top() && p >= MetaspaceObj::shared_metaspace_base());
+    return MetaspaceObj::is_shared((const MetaspaceObj*)p);
   }
 
   static address shared_metaspace_top() {
     return (address)MetaspaceObj::shared_metaspace_top();
   }
 
-  static void set_shared_metaspace_range(void* base, void* top) NOT_CDS_RETURN;
+  static void set_shared_metaspace_range(void* base, void *static_top, void* top) NOT_CDS_RETURN;
 
   // Return true if given address is in the shared region corresponding to the idx
   static bool is_in_shared_region(const void* p, int idx) NOT_CDS_RETURN_(false);
@@ -298,8 +300,8 @@
   static void link_and_cleanup_shared_classes(TRAPS);
 
 #if INCLUDE_CDS
-  static ReservedSpace* reserve_shared_rs(size_t size, size_t alignment,
-                                          bool large, char* requested_address);
+  static 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 DumpRegion* misc_code_dump_space();
   static DumpRegion* read_write_dump_space();
@@ -342,11 +344,35 @@
   }
   static void relocate_klass_ptr(oop o);
 
-  static Klass* get_relocated_klass(Klass *k);
+  static Klass* get_relocated_klass(Klass *k, bool is_final=false);
 
   static intptr_t* fix_cpp_vtable_for_dynamic_archive(MetaspaceObj::Type msotype, address obj);
+  static void initialize_ptr_marker(CHeapBitMap* ptrmap);
 
+  // Non-zero if the archive(s) need to be mapped a non-default location due to ASLR.
+  static intx relocation_delta() { return _relocation_delta; }
+  static intx final_delta();
+  static bool use_windows_memory_mapping() {
+    const bool is_windows = (NOT_WINDOWS(false) WINDOWS_ONLY(true));
+    //const bool is_windows = true; // enable this to allow testing the windows mmap semantics on Linux, etc.
+    return is_windows;
+  }
 private:
   static void read_extra_data(const char* filename, TRAPS) NOT_CDS_RETURN;
+  static FileMapInfo* open_static_archive();
+  static FileMapInfo* open_dynamic_archive();
+  static MapArchiveResult map_archives(FileMapInfo* static_mapinfo, FileMapInfo* dynamic_mapinfo,
+                                       bool use_requested_addr);
+  static char* reserve_address_space_for_archives(FileMapInfo* static_mapinfo,
+                                                  FileMapInfo* dynamic_mapinfo,
+                                                  bool use_requested_addr,
+                                                  ReservedSpace& main_rs,
+                                                  ReservedSpace& archive_space_rs,
+                                                  ReservedSpace& class_space_rs);
+  static void release_reserved_spaces(ReservedSpace& main_rs,
+                                      ReservedSpace& archive_space_rs,
+                                      ReservedSpace& class_space_rs);
+  static MapArchiveResult map_archive(FileMapInfo* mapinfo, char* mapped_base_address, ReservedSpace rs);
+  static void unmap_archive(FileMapInfo* mapinfo);
 };
 #endif // SHARE_MEMORY_METASPACESHARED_HPP
--- a/src/hotspot/share/memory/universe.cpp	Wed Nov 13 17:21:31 2019 -0500
+++ b/src/hotspot/share/memory/universe.cpp	Mon Nov 18 12:40:06 2019 -0500
@@ -85,18 +85,24 @@
 #include "utilities/ostream.hpp"
 #include "utilities/preserveException.hpp"
 
+#define PRIMITIVE_MIRRORS_DO(func) \
+  func(_int_mirror)    \
+  func(_float_mirror)  \
+  func(_double_mirror) \
+  func(_byte_mirror)   \
+  func(_bool_mirror)   \
+  func(_char_mirror)   \
+  func(_long_mirror)   \
+  func(_short_mirror)  \
+  func(_void_mirror)
+
+#define DEFINE_PRIMITIVE_MIRROR(m) \
+    oop Universe::m  = NULL;
+
 // Known objects
+PRIMITIVE_MIRRORS_DO(DEFINE_PRIMITIVE_MIRROR)
 Klass* Universe::_typeArrayKlassObjs[T_LONG+1]        = { NULL /*, NULL...*/ };
 Klass* Universe::_objectArrayKlassObj                 = NULL;
-oop Universe::_int_mirror                             = NULL;
-oop Universe::_float_mirror                           = NULL;
-oop Universe::_double_mirror                          = NULL;
-oop Universe::_byte_mirror                            = NULL;
-oop Universe::_bool_mirror                            = NULL;
-oop Universe::_char_mirror                            = NULL;
-oop Universe::_long_mirror                            = NULL;
-oop Universe::_short_mirror                           = NULL;
-oop Universe::_void_mirror                            = NULL;
 oop Universe::_mirrors[T_VOID+1]                      = { NULL /*, NULL...*/ };
 oop Universe::_main_thread_group                      = NULL;
 oop Universe::_system_thread_group                    = NULL;
@@ -167,17 +173,11 @@
   }
 }
 
-void Universe::oops_do(OopClosure* f) {
+#define DO_PRIMITIVE_MIRROR(m) \
+  f->do_oop((oop*) &m);
 
-  f->do_oop((oop*) &_int_mirror);
-  f->do_oop((oop*) &_float_mirror);
-  f->do_oop((oop*) &_double_mirror);
-  f->do_oop((oop*) &_byte_mirror);
-  f->do_oop((oop*) &_bool_mirror);
-  f->do_oop((oop*) &_char_mirror);
-  f->do_oop((oop*) &_long_mirror);
-  f->do_oop((oop*) &_short_mirror);
-  f->do_oop((oop*) &_void_mirror);
+void Universe::oops_do(OopClosure* f) {
+  PRIMITIVE_MIRRORS_DO(DO_PRIMITIVE_MIRROR);
 
   for (int i = T_BOOLEAN; i < T_VOID+1; i++) {
     f->do_oop((oop*) &_mirrors[i]);
@@ -231,6 +231,13 @@
   _do_stack_walk_cache->metaspace_pointers_do(it);
 }
 
+#define ASSERT_MIRROR_NULL(m) \
+  assert(m == NULL, "archived mirrors should be NULL");
+
+#define SERIALIZE_MIRROR(m) \
+  f->do_oop(&m); \
+  if (m != NULL) { java_lang_Class::update_archived_primitive_mirror_native_pointers(m); }
+
 // Serialize metadata and pointers to primitive type mirrors in and out of CDS archive
 void Universe::serialize(SerializeClosure* f) {
 
@@ -239,25 +246,12 @@
   }
 
   f->do_ptr((void**)&_objectArrayKlassObj);
+
 #if INCLUDE_CDS_JAVA_HEAP
-#ifdef ASSERT
-  if (DumpSharedSpaces && !HeapShared::is_heap_object_archiving_allowed()) {
-    assert(_int_mirror == NULL    && _float_mirror == NULL &&
-           _double_mirror == NULL && _byte_mirror == NULL  &&
-           _bool_mirror == NULL   && _char_mirror == NULL  &&
-           _long_mirror == NULL   && _short_mirror == NULL &&
-           _void_mirror == NULL, "mirrors should be NULL");
-  }
-#endif
-  f->do_oop(&_int_mirror);
-  f->do_oop(&_float_mirror);
-  f->do_oop(&_double_mirror);
-  f->do_oop(&_byte_mirror);
-  f->do_oop(&_bool_mirror);
-  f->do_oop(&_char_mirror);
-  f->do_oop(&_long_mirror);
-  f->do_oop(&_short_mirror);
-  f->do_oop(&_void_mirror);
+  DEBUG_ONLY(if (DumpSharedSpaces && !HeapShared::is_heap_object_archiving_allowed()) {
+      PRIMITIVE_MIRRORS_DO(ASSERT_MIRROR_NULL);
+    });
+  PRIMITIVE_MIRRORS_DO(SERIALIZE_MIRROR);
 #endif
 
   f->do_ptr((void**)&_the_array_interfaces_array);
@@ -419,18 +413,18 @@
   #endif
 }
 
+#define ASSERT_MIRROR_NOT_NULL(m) \
+  assert(m != NULL, "archived mirrors should not be NULL");
+
 void Universe::initialize_basic_type_mirrors(TRAPS) {
 #if INCLUDE_CDS_JAVA_HEAP
     if (UseSharedSpaces &&
         HeapShared::open_archive_heap_region_mapped() &&
         _int_mirror != NULL) {
       assert(HeapShared::is_heap_object_archiving_allowed(), "Sanity");
-      assert(_float_mirror != NULL && _double_mirror != NULL &&
-             _byte_mirror  != NULL && _byte_mirror   != NULL &&
-             _bool_mirror  != NULL && _char_mirror   != NULL &&
-             _long_mirror  != NULL && _short_mirror  != NULL &&
-             _void_mirror  != NULL, "Sanity");
+      PRIMITIVE_MIRRORS_DO(ASSERT_MIRROR_NOT_NULL);
     } else
+      // _int_mirror could be NULL if archived heap is not mapped.
 #endif
     {
       _int_mirror     =
--- a/src/hotspot/share/oops/constMethod.cpp	Wed Nov 13 17:21:31 2019 -0500
+++ b/src/hotspot/share/oops/constMethod.cpp	Mon Nov 18 12:40:06 2019 -0500
@@ -420,6 +420,8 @@
   if (has_default_annotations()) {
       it->push(default_annotations_addr());
   }
+  ConstMethod* this_ptr = this;
+  it->push_method_entry(&this_ptr, (intptr_t*)&_adapter_trampoline);
 }
 
 // Printing
--- a/src/hotspot/share/oops/instanceKlass.cpp	Wed Nov 13 17:21:31 2019 -0500
+++ b/src/hotspot/share/oops/instanceKlass.cpp	Mon Nov 18 12:40:06 2019 -0500
@@ -1577,11 +1577,30 @@
 }
 #endif
 
-static int binary_search(const Array<Method*>* methods, const Symbol* name) {
+bool InstanceKlass::_disable_method_binary_search = false;
+
+int InstanceKlass::quick_search(const Array<Method*>* methods, const Symbol* name) {
   int len = methods->length();
-  // methods are sorted, so do binary search
   int l = 0;
   int h = len - 1;
+
+  if (_disable_method_binary_search) {
+    // At the final stage of dynamic dumping, the methods array may not be sorted
+    // by ascending addresses of their names, so we can't use binary search anymore.
+    // However, methods with the same name are still laid out consecutively inside the
+    // methods array, so let's look for the first one that matches.
+    assert(DynamicDumpSharedSpaces, "must be");
+    while (l <= h) {
+      Method* m = methods->at(l);
+      if (m->name() == name) {
+        return l;
+      }
+      l ++;
+    }
+    return -1;
+  }
+
+  // methods are sorted by ascending addresses of their names, so do binary search
   while (l <= h) {
     int mid = (l + h) >> 1;
     Method* m = methods->at(mid);
@@ -1733,7 +1752,7 @@
   const bool skipping_overpass = (overpass_mode == skip_overpass);
   const bool skipping_static = (static_mode == skip_static);
   const bool skipping_private = (private_mode == skip_private);
-  const int hit = binary_search(methods, name);
+  const int hit = quick_search(methods, name);
   if (hit != -1) {
     const Method* const m = methods->at(hit);
 
@@ -1784,7 +1803,7 @@
                                        const Symbol* name,
                                        int* end_ptr) {
   assert(end_ptr != NULL, "just checking");
-  int start = binary_search(methods, name);
+  int start = quick_search(methods, name);
   int end = start + 1;
   if (start != -1) {
     while (start - 1 >= 0 && (methods->at(start - 1))->name() == name) --start;
@@ -2365,6 +2384,7 @@
   _breakpoints = NULL;
   _previous_versions = NULL;
   _cached_class_file = NULL;
+  _jvmti_cached_class_field_map = NULL;
 #endif
 
   _init_thread = NULL;
@@ -2373,6 +2393,8 @@
   _oop_map_cache = NULL;
   // clear _nest_host to ensure re-load at runtime
   _nest_host = NULL;
+  _package_entry = NULL;
+  _dep_context_last_cleaned = 0;
 }
 
 void InstanceKlass::remove_java_mirror() {
--- a/src/hotspot/share/oops/instanceKlass.hpp	Wed Nov 13 17:21:31 2019 -0500
+++ b/src/hotspot/share/oops/instanceKlass.hpp	Mon Nov 18 12:40:06 2019 -0500
@@ -329,6 +329,8 @@
 
   friend class SystemDictionary;
 
+  static bool _disable_method_binary_search;
+
  public:
   u2 loader_type() {
     return _misc_flags & loader_type_bits();
@@ -564,6 +566,14 @@
   bool find_local_field_from_offset(int offset, bool is_static, fieldDescriptor* fd) const;
   bool find_field_from_offset(int offset, bool is_static, fieldDescriptor* fd) const;
 
+ private:
+  static int quick_search(const Array<Method*>* methods, const Symbol* name);
+
+ public:
+  static void disable_method_binary_search() {
+    _disable_method_binary_search = true;
+  }
+
   // find a local method (returns NULL if not found)
   Method* find_method(const Symbol* name, const Symbol* signature) const;
   static Method* find_method(const Array<Method*>* methods,
--- a/src/hotspot/share/oops/method.cpp	Wed Nov 13 17:21:31 2019 -0500
+++ b/src/hotspot/share/oops/method.cpp	Mon Nov 18 12:40:06 2019 -0500
@@ -332,18 +332,21 @@
   return align_metadata_size(header_size() + extra_words);
 }
 
-
 Symbol* Method::klass_name() const {
   return method_holder()->name();
 }
 
-
 void Method::metaspace_pointers_do(MetaspaceClosure* it) {
   log_trace(cds)("Iter(Method): %p", this);
 
   it->push(&_constMethod);
   it->push(&_method_data);
   it->push(&_method_counters);
+
+  Method* this_ptr = this;
+  it->push_method_entry(&this_ptr, (intptr_t*)&_i2i_entry);
+  it->push_method_entry(&this_ptr, (intptr_t*)&_from_compiled_entry);
+  it->push_method_entry(&this_ptr, (intptr_t*)&_from_interpreted_entry);
 }
 
 // Attempt to return method oop to original state.  Clear any pointers
@@ -1741,12 +1744,15 @@
 
 // This is only done during class loading, so it is OK to assume method_idnum matches the methods() array
 // default_methods also uses this without the ordering for fast find_method
-void Method::sort_methods(Array<Method*>* methods, bool set_idnums) {
+void Method::sort_methods(Array<Method*>* methods, bool set_idnums, method_comparator_func func) {
   int length = methods->length();
   if (length > 1) {
+    if (func == NULL) {
+      func = method_comparator;
+    }
     {
       NoSafepointVerifier nsv;
-      QuickSort::sort(methods->data(), length, method_comparator, /*idempotent=*/false);
+      QuickSort::sort(methods->data(), length, func, /*idempotent=*/false);
     }
     // Reset method ordering
     if (set_idnums) {
--- a/src/hotspot/share/oops/method.hpp	Wed Nov 13 17:21:31 2019 -0500
+++ b/src/hotspot/share/oops/method.hpp	Mon Nov 18 12:40:06 2019 -0500
@@ -1006,8 +1006,10 @@
   void print_name(outputStream* st = tty)        PRODUCT_RETURN; // prints as "virtual void foo(int)"
 #endif
 
+  typedef int (*method_comparator_func)(Method* a, Method* b);
+
   // Helper routine used for method sorting
-  static void sort_methods(Array<Method*>* methods, bool set_idnums = true);
+  static void sort_methods(Array<Method*>* methods, bool set_idnums = true, method_comparator_func func = NULL);
 
   // Deallocation function for redefine classes or if an error occurs
   void deallocate_contents(ClassLoaderData* loader_data);
--- a/src/hotspot/share/opto/chaitin.cpp	Wed Nov 13 17:21:31 2019 -0500
+++ b/src/hotspot/share/opto/chaitin.cpp	Mon Nov 18 12:40:06 2019 -0500
@@ -1169,7 +1169,7 @@
       lrgs(lo)._next = _simplified;
       _simplified = lo;
       // If this guy is "at risk" then mark his current neighbors
-      if( lrgs(lo)._at_risk ) {
+      if (lrgs(lo)._at_risk && !_ifg->neighbors(lo)->is_empty()) {
         IndexSetIterator elements(_ifg->neighbors(lo));
         uint datum;
         while ((datum = elements.next()) != 0) {
@@ -1178,7 +1178,10 @@
       }
 
       // Yank this guy from the IFG.
-      IndexSet *adj = _ifg->remove_node( lo );
+      IndexSet *adj = _ifg->remove_node(lo);
+      if (adj->is_empty()) {
+        continue;
+      }
 
       // If any neighbors' degrees fall below their number of
       // allowed registers, then put that neighbor on the low degree
@@ -1202,8 +1205,11 @@
           // Pull from hi-degree list
           uint prev = n->_prev;
           uint next = n->_next;
-          if (prev) lrgs(prev)._next = next;
-          else _hi_degree = next;
+          if (prev) {
+            lrgs(prev)._next = next;
+          } else {
+            _hi_degree = next;
+          }
           lrgs(next)._prev = prev;
           n->_next = _lo_degree;
           _lo_degree = neighbor;
@@ -1314,7 +1320,7 @@
 
   // Check for "at_risk" LRG's
   uint risk_lrg = _lrg_map.find(lrg._risk_bias);
-  if( risk_lrg != 0 ) {
+  if (risk_lrg != 0 && !_ifg->neighbors(risk_lrg)->is_empty()) {
     // Walk the colored neighbors of the "at_risk" candidate
     // Choose a color which is both legal and already taken by a neighbor
     // of the "at_risk" candidate in order to improve the chances of the
@@ -1330,7 +1336,7 @@
   }
 
   uint copy_lrg = _lrg_map.find(lrg._copy_bias);
-  if( copy_lrg != 0 ) {
+  if (copy_lrg != 0) {
     // If he has a color,
     if(!_ifg->_yanked->test(copy_lrg)) {
       OptoReg::Name reg = lrgs(copy_lrg).reg();
@@ -1432,41 +1438,43 @@
 
     // Remove neighbor colors
     IndexSet *s = _ifg->neighbors(lidx);
+    debug_only(RegMask orig_mask = lrg->mask();)
 
-    debug_only(RegMask orig_mask = lrg->mask();)
-    IndexSetIterator elements(s);
-    uint neighbor;
-    while ((neighbor = elements.next()) != 0) {
-      // Note that neighbor might be a spill_reg.  In this case, exclusion
-      // of its color will be a no-op, since the spill_reg chunk is in outer
-      // space.  Also, if neighbor is in a different chunk, this exclusion
-      // will be a no-op.  (Later on, if lrg runs out of possible colors in
-      // its chunk, a new chunk of color may be tried, in which case
-      // examination of neighbors is started again, at retry_next_chunk.)
-      LRG &nlrg = lrgs(neighbor);
-      OptoReg::Name nreg = nlrg.reg();
-      // Only subtract masks in the same chunk
-      if( nreg >= chunk && nreg < chunk + RegMask::CHUNK_SIZE ) {
+    if (!s->is_empty()) {
+      IndexSetIterator elements(s);
+      uint neighbor;
+      while ((neighbor = elements.next()) != 0) {
+        // Note that neighbor might be a spill_reg.  In this case, exclusion
+        // of its color will be a no-op, since the spill_reg chunk is in outer
+        // space.  Also, if neighbor is in a different chunk, this exclusion
+        // will be a no-op.  (Later on, if lrg runs out of possible colors in
+        // its chunk, a new chunk of color may be tried, in which case
+        // examination of neighbors is started again, at retry_next_chunk.)
+        LRG &nlrg = lrgs(neighbor);
+        OptoReg::Name nreg = nlrg.reg();
+        // Only subtract masks in the same chunk
+        if (nreg >= chunk && nreg < chunk + RegMask::CHUNK_SIZE) {
 #ifndef PRODUCT
-        uint size = lrg->mask().Size();
-        RegMask rm = lrg->mask();
+          uint size = lrg->mask().Size();
+          RegMask rm = lrg->mask();
 #endif
-        lrg->SUBTRACT(nlrg.mask());
+          lrg->SUBTRACT(nlrg.mask());
 #ifndef PRODUCT
-        if (trace_spilling() && lrg->mask().Size() != size) {
-          ttyLocker ttyl;
-          tty->print("L%d ", lidx);
-          rm.dump();
-          tty->print(" intersected L%d ", neighbor);
-          nlrg.mask().dump();
-          tty->print(" removed ");
-          rm.SUBTRACT(lrg->mask());
-          rm.dump();
-          tty->print(" leaving ");
-          lrg->mask().dump();
-          tty->cr();
+          if (trace_spilling() && lrg->mask().Size() != size) {
+            ttyLocker ttyl;
+            tty->print("L%d ", lidx);
+            rm.dump();
+            tty->print(" intersected L%d ", neighbor);
+            nlrg.mask().dump();
+            tty->print(" removed ");
+            rm.SUBTRACT(lrg->mask());
+            rm.dump();
+            tty->print(" leaving ");
+            lrg->mask().dump();
+            tty->cr();
+          }
+#endif
         }
-#endif
       }
     }
     //assert(is_allstack == lrg->mask().is_AllStack(), "nbrs must not change AllStackedness");
@@ -1827,7 +1835,7 @@
 
       // Found a safepoint?
       JVMState *jvms = n->jvms();
-      if( jvms ) {
+      if (jvms && !liveout.is_empty()) {
         // Now scan for a live derived pointer
         IndexSetIterator elements(&liveout);
         uint neighbor;
--- a/src/hotspot/share/opto/coalesce.cpp	Wed Nov 13 17:21:31 2019 -0500
+++ b/src/hotspot/share/opto/coalesce.cpp	Mon Nov 18 12:40:06 2019 -0500
@@ -602,29 +602,42 @@
   // Some original neighbors of lr1 might have gone away
   // because the constrained register mask prevented them.
   // Remove lr1 from such neighbors.
-  IndexSetIterator one(n_lr1);
-  uint neighbor;
+  uint neighbor = 0;
   LRG &lrg1 = lrgs(lr1);
-  while ((neighbor = one.next()) != 0)
-    if( !_ulr.member(neighbor) )
-      if( _phc._ifg->neighbors(neighbor)->remove(lr1) )
-        lrgs(neighbor).inc_degree( -lrg1.compute_degree(lrgs(neighbor)) );
+  if (!n_lr1->is_empty()) {
+    IndexSetIterator one(n_lr1);
+    while ((neighbor = one.next()) != 0) {
+      if (!_ulr.member(neighbor)) {
+        if (_phc._ifg->neighbors(neighbor)->remove(lr1)) {
+          lrgs(neighbor).inc_degree(-lrg1.compute_degree(lrgs(neighbor)));
+        }
+      }
+    }
+  }
 
 
   // lr2 is now called (coalesced into) lr1.
   // Remove lr2 from the IFG.
-  IndexSetIterator two(n_lr2);
   LRG &lrg2 = lrgs(lr2);
-  while ((neighbor = two.next()) != 0)
-    if( _phc._ifg->neighbors(neighbor)->remove(lr2) )
-      lrgs(neighbor).inc_degree( -lrg2.compute_degree(lrgs(neighbor)) );
+  if (!n_lr2->is_empty()) {
+    IndexSetIterator two(n_lr2);
+    while ((neighbor = two.next()) != 0) {
+      if (_phc._ifg->neighbors(neighbor)->remove(lr2)) {
+        lrgs(neighbor).inc_degree(-lrg2.compute_degree(lrgs(neighbor)));
+      }
+    }
+  }
 
   // Some neighbors of intermediate copies now interfere with the
   // combined live range.
-  IndexSetIterator three(&_ulr);
-  while ((neighbor = three.next()) != 0)
-    if( _phc._ifg->neighbors(neighbor)->insert(lr1) )
-      lrgs(neighbor).inc_degree( lrg1.compute_degree(lrgs(neighbor)) );
+  if (!_ulr.is_empty()) {
+    IndexSetIterator three(&_ulr);
+    while ((neighbor = three.next()) != 0) {
+      if (_phc._ifg->neighbors(neighbor)->insert(lr1)) {
+        lrgs(neighbor).inc_degree(lrg1.compute_degree(lrgs(neighbor)));
+      }
+    }
+  }
 }
 
 static void record_bias( const PhaseIFG *ifg, int lr1, int lr2 ) {
--- a/src/hotspot/share/opto/ifg.cpp	Wed Nov 13 17:21:31 2019 -0500
+++ b/src/hotspot/share/opto/ifg.cpp	Mon Nov 18 12:40:06 2019 -0500
@@ -80,11 +80,13 @@
   assert( !_is_square, "only on triangular" );
 
   // Simple transpose
-  for( uint i = 0; i < _maxlrg; i++ ) {
-    IndexSetIterator elements(&_adjs[i]);
-    uint datum;
-    while ((datum = elements.next()) != 0) {
-      _adjs[datum].insert( i );
+  for(uint i = 0; i < _maxlrg; i++ ) {
+    if (!_adjs[i].is_empty()) {
+      IndexSetIterator elements(&_adjs[i]);
+      uint datum;
+      while ((datum = elements.next()) != 0) {
+        _adjs[datum].insert(i);
+      }
     }
   }
   _is_square = true;
@@ -108,16 +110,18 @@
 }
 
 // Union edges of B into A
-void PhaseIFG::Union( uint a, uint b ) {
+void PhaseIFG::Union(uint a, uint b) {
   assert( _is_square, "only on square" );
   IndexSet *A = &_adjs[a];
-  IndexSetIterator b_elements(&_adjs[b]);
-  uint datum;
-  while ((datum = b_elements.next()) != 0) {
-    if(A->insert(datum)) {
-      _adjs[datum].insert(a);
-      lrgs(a).invalid_degree();
-      lrgs(datum).invalid_degree();
+  if (!_adjs[b].is_empty()) {
+    IndexSetIterator b_elements(&_adjs[b]);
+    uint datum;
+    while ((datum = b_elements.next()) != 0) {
+      if (A->insert(datum)) {
+        _adjs[datum].insert(a);
+        lrgs(a).invalid_degree();
+        lrgs(datum).invalid_degree();
+      }
     }
   }
 }
@@ -130,12 +134,15 @@
   _yanked->set(a);
 
   // I remove the LRG from all neighbors.
-  IndexSetIterator elements(&_adjs[a]);
   LRG &lrg_a = lrgs(a);
-  uint datum;
-  while ((datum = elements.next()) != 0) {
-    _adjs[datum].remove(a);
-    lrgs(datum).inc_degree( -lrg_a.compute_degree(lrgs(datum)) );
+
+  if (!_adjs[a].is_empty()) {
+    IndexSetIterator elements(&_adjs[a]);
+    uint datum;
+    while ((datum = elements.next()) != 0) {
+      _adjs[datum].remove(a);
+      lrgs(datum).inc_degree(-lrg_a.compute_degree(lrgs(datum)));
+    }
   }
   return neighbors(a);
 }
@@ -146,6 +153,8 @@
   assert( _yanked->test(a), "" );
   _yanked->remove(a);
 
+  if (_adjs[a].is_empty()) return;
+
   IndexSetIterator elements(&_adjs[a]);
   uint datum;
   while ((datum = elements.next()) != 0) {
@@ -159,7 +168,7 @@
 // mis-aligned (or for Fat-Projections, not-adjacent) then we have to
 // MULTIPLY the sizes.  Inspect Brigg's thesis on register pairs to see why
 // this is so.
-int LRG::compute_degree( LRG &l ) const {
+int LRG::compute_degree(LRG &l) const {
   int tmp;
   int num_regs = _num_regs;
   int nregs = l.num_regs();
@@ -174,14 +183,15 @@
 // mis-aligned (or for Fat-Projections, not-adjacent) then we have to
 // MULTIPLY the sizes.  Inspect Brigg's thesis on register pairs to see why
 // this is so.
-int PhaseIFG::effective_degree( uint lidx ) const {
+int PhaseIFG::effective_degree(uint lidx) const {
+  IndexSet *s = neighbors(lidx);
+  if (s->is_empty()) return 0;
   int eff = 0;
   int num_regs = lrgs(lidx).num_regs();
   int fat_proj = lrgs(lidx)._fat_proj;
-  IndexSet *s = neighbors(lidx);
   IndexSetIterator elements(s);
   uint nidx;
-  while((nidx = elements.next()) != 0) {
+  while ((nidx = elements.next()) != 0) {
     LRG &lrgn = lrgs(nidx);
     int nregs = lrgn.num_regs();
     eff += (fat_proj || lrgn._fat_proj) // either is a fat-proj?
@@ -196,14 +206,16 @@
 void PhaseIFG::dump() const {
   tty->print_cr("-- Interference Graph --%s--",
                 _is_square ? "square" : "triangular" );
-  if( _is_square ) {
-    for( uint i = 0; i < _maxlrg; i++ ) {
+  if (_is_square) {
+    for (uint i = 0; i < _maxlrg; i++) {
       tty->print(_yanked->test(i) ? "XX " : "  ");
       tty->print("L%d: { ",i);
-      IndexSetIterator elements(&_adjs[i]);
-      uint datum;
-      while ((datum = elements.next()) != 0) {
-        tty->print("L%d ", datum);
+      if (!_adjs[i].is_empty()) {
+        IndexSetIterator elements(&_adjs[i]);
+        uint datum;
+        while ((datum = elements.next()) != 0) {
+          tty->print("L%d ", datum);
+        }
       }
       tty->print_cr("}");
 
@@ -221,10 +233,12 @@
         tty->print("L%d ",j - 1);
       }
     tty->print("| ");
-    IndexSetIterator elements(&_adjs[i]);
-    uint datum;
-    while ((datum = elements.next()) != 0) {
-      tty->print("L%d ", datum);
+    if (!_adjs[i].is_empty()) {
+      IndexSetIterator elements(&_adjs[i]);
+      uint datum;
+      while ((datum = elements.next()) != 0) {
+        tty->print("L%d ", datum);
+      }
     }
     tty->print("}\n");
   }
@@ -251,16 +265,18 @@
   for( uint i = 0; i < _maxlrg; i++ ) {
     assert(!_yanked->test(i) || !neighbor_cnt(i), "Is removed completely" );
     IndexSet *set = &_adjs[i];
-    IndexSetIterator elements(set);
-    uint idx;
-    uint last = 0;
-    while ((idx = elements.next()) != 0) {
-      assert(idx != i, "Must have empty diagonal");
-      assert(pc->_lrg_map.find_const(idx) == idx, "Must not need Find");
-      assert(_adjs[idx].member(i), "IFG not square");
-      assert(!_yanked->test(idx), "No yanked neighbors");
-      assert(last < idx, "not sorted increasing");
-      last = idx;
+    if (!set->is_empty()) {
+      IndexSetIterator elements(set);
+      uint idx;
+      uint last = 0;
+      while ((idx = elements.next()) != 0) {
+        assert(idx != i, "Must have empty diagonal");
+        assert(pc->_lrg_map.find_const(idx) == idx, "Must not need Find");
+        assert(_adjs[idx].member(i), "IFG not square");
+        assert(!_yanked->test(idx), "No yanked neighbors");
+        assert(last < idx, "not sorted increasing");
+        last = idx;
+      }
     }
     assert(!lrgs(i)._degree_valid || effective_degree(i) == lrgs(i).degree(), "degree is valid but wrong");
   }
@@ -273,16 +289,18 @@
  * Only interfere if acceptable register masks overlap.
  */
 void PhaseChaitin::interfere_with_live(uint lid, IndexSet* liveout) {
-  LRG& lrg = lrgs(lid);
-  const RegMask& rm = lrg.mask();
-  IndexSetIterator elements(liveout);
-  uint interfering_lid = elements.next();
-  while (interfering_lid != 0) {
-    LRG& interfering_lrg = lrgs(interfering_lid);
-    if (rm.overlap(interfering_lrg.mask())) {
-      _ifg->add_edge(lid, interfering_lid);
+  if (!liveout->is_empty()) {
+    LRG& lrg = lrgs(lid);
+    const RegMask &rm = lrg.mask();
+    IndexSetIterator elements(liveout);
+    uint interfering_lid = elements.next();
+    while (interfering_lid != 0) {
+      LRG& interfering_lrg = lrgs(interfering_lid);
+      if (rm.overlap(interfering_lrg.mask())) {
+        _ifg->add_edge(lid, interfering_lid);
+      }
+      interfering_lid = elements.next();
     }
-    interfering_lid = elements.next();
   }
 }
 
@@ -381,6 +399,9 @@
 
 #ifdef ASSERT
 uint PhaseChaitin::count_int_pressure(IndexSet* liveout) {
+  if (liveout->is_empty()) {
+    return 0;
+  }
   IndexSetIterator elements(liveout);
   uint lidx = elements.next();
   uint cnt = 0;
@@ -397,6 +418,9 @@
 }
 
 uint PhaseChaitin::count_float_pressure(IndexSet* liveout) {
+  if (liveout->is_empty()) {
+    return 0;
+  }
   IndexSetIterator elements(liveout);
   uint lidx = elements.next();
   uint cnt = 0;
@@ -494,13 +518,15 @@
  * the block from the area.
  */
 void PhaseChaitin::compute_initial_block_pressure(Block* b, IndexSet* liveout, Pressure& int_pressure, Pressure& float_pressure, double cost) {
-  IndexSetIterator elements(liveout);
-  uint lid = elements.next();
-  while (lid != 0) {
-    LRG& lrg = lrgs(lid);
-    lrg._area += cost;
-    raise_pressure(b, lrg, int_pressure, float_pressure);
-    lid = elements.next();
+  if (!liveout->is_empty()) {
+    IndexSetIterator elements(liveout);
+    uint lid = elements.next();
+    while (lid != 0) {
+      LRG &lrg = lrgs(lid);
+      lrg._area += cost;
+      raise_pressure(b, lrg, int_pressure, float_pressure);
+      lid = elements.next();
+    }
   }
   assert(int_pressure.current_pressure() == count_int_pressure(liveout), "the int pressure is incorrect");
   assert(float_pressure.current_pressure() == count_float_pressure(liveout), "the float pressure is incorrect");
@@ -512,13 +538,15 @@
 * and int/pointer registers.
 */
 void PhaseChaitin::compute_entry_block_pressure(Block* b) {
-  IndexSet* livein = _live->livein(b);
-  IndexSetIterator elements(livein);
-  uint lid = elements.next();
-  while (lid != 0) {
-    LRG& lrg = lrgs(lid);
-    raise_pressure(b, lrg, _sched_int_pressure, _sched_float_pressure);
-    lid = elements.next();
+  IndexSet *livein = _live->livein(b);
+  if (!livein->is_empty()) {
+    IndexSetIterator elements(livein);
+    uint lid = elements.next();
+    while (lid != 0) {
+      LRG &lrg = lrgs(lid);
+      raise_pressure(b, lrg, _sched_int_pressure, _sched_float_pressure);
+      lid = elements.next();
+    }
   }
   // Now check phis for locally defined inputs
   for (uint j = 0; j < b->number_of_nodes(); j++) {
@@ -546,15 +574,18 @@
 * and int/pointer registers.
 */
 void PhaseChaitin::compute_exit_block_pressure(Block* b) {
+
   IndexSet* livein = _live->live(b);
-  IndexSetIterator elements(livein);
   _sched_int_pressure.set_current_pressure(0);
   _sched_float_pressure.set_current_pressure(0);
-  uint lid = elements.next();
-  while (lid != 0) {
-    LRG& lrg = lrgs(lid);
-    raise_pressure(b, lrg, _sched_int_pressure, _sched_float_pressure);
-    lid = elements.next();
+  if (!livein->is_empty()) {
+    IndexSetIterator elements(livein);
+    uint lid = elements.next();
+    while (lid != 0) {
+      LRG &lrg = lrgs(lid);
+      raise_pressure(b, lrg, _sched_int_pressure, _sched_float_pressure);
+      lid = elements.next();
+    }
   }
 }
 
@@ -654,6 +685,7 @@
  * all conflicting parties and avoid the interference.
  */
 void PhaseChaitin::remove_bound_register_from_interfering_live_ranges(LRG& lrg, IndexSet* liveout, uint& must_spill) {
+  if (liveout->is_empty()) return;
   // Check for common case
   const RegMask& rm = lrg.mask();
   int r_size = lrg.num_regs();
@@ -833,7 +865,7 @@
       Node* n = block->get_node(location);
       uint lid = _lrg_map.live_range_id(n);
 
-      if(lid) {
+      if (lid) {
         LRG& lrg = lrgs(lid);
 
         // A DEF normally costs block frequency; rematerialized values are
--- a/src/hotspot/share/opto/indexSet.cpp	Wed Nov 13 17:21:31 2019 -0500
+++ b/src/hotspot/share/opto/indexSet.cpp	Mon Nov 18 12:40:06 2019 -0500
@@ -111,6 +111,9 @@
 IndexSet::BitBlock *IndexSet::alloc_block_containing(uint element) {
   BitBlock *block = alloc_block();
   uint bi = get_block_index(element);
+  if (bi >= _current_block_limit) {
+    _current_block_limit = bi + 1;
+  }
   _blocks[bi] = block;
   return block;
 }
@@ -125,7 +128,7 @@
   assert(block != &_empty_block, "cannot free the empty block");
   block->set_next((IndexSet::BitBlock*)Compile::current()->indexSet_free_block_list());
   Compile::current()->set_indexSet_free_block_list(block);
-  set_block(i,&_empty_block);
+  set_block(i, &_empty_block);
 }
 
 //------------------------------lrg_union--------------------------------------
@@ -168,38 +171,43 @@
   // other color.  (A variant of the Briggs assertion)
   uint reg_degree = 0;
 
-  uint element;
+  uint element = 0;
   // Load up the combined interference set with the neighbors of one
-  IndexSetIterator elements(one);
-  while ((element = elements.next()) != 0) {
-    LRG &lrg = ifg->lrgs(element);
-    if (mask.overlap(lrg.mask())) {
-      insert(element);
-      if( !lrg.mask().is_AllStack() ) {
-        reg_degree += lrg1.compute_degree(lrg);
-        if( reg_degree >= fail_degree ) return reg_degree;
-      } else {
-        // !!!!! Danger!  No update to reg_degree despite having a neighbor.
-        // A variant of the Briggs assertion.
-        // Not needed if I simplify during coalesce, ala George/Appel.
-        assert( lrg.lo_degree(), "" );
+  if (!one->is_empty()) {
+    IndexSetIterator elements(one);
+    while ((element = elements.next()) != 0) {
+      LRG &lrg = ifg->lrgs(element);
+      if (mask.overlap(lrg.mask())) {
+        insert(element);
+        if (!lrg.mask().is_AllStack()) {
+          reg_degree += lrg1.compute_degree(lrg);
+          if (reg_degree >= fail_degree) return reg_degree;
+        } else {
+          // !!!!! Danger!  No update to reg_degree despite having a neighbor.
+          // A variant of the Briggs assertion.
+          // Not needed if I simplify during coalesce, ala George/Appel.
+          assert(lrg.lo_degree(), "");
+        }
       }
     }
   }
   // Add neighbors of two as well
-  IndexSetIterator elements2(two);
-  while ((element = elements2.next()) != 0) {
-    LRG &lrg = ifg->lrgs(element);
-    if (mask.overlap(lrg.mask())) {
-      if (insert(element)) {
-        if( !lrg.mask().is_AllStack() ) {
-          reg_degree += lrg2.compute_degree(lrg);
-          if( reg_degree >= fail_degree ) return reg_degree;
-        } else {
-          // !!!!! Danger!  No update to reg_degree despite having a neighbor.
-          // A variant of the Briggs assertion.
-          // Not needed if I simplify during coalesce, ala George/Appel.
-          assert( lrg.lo_degree(), "" );
+
+  if (!two->is_empty()) {
+    IndexSetIterator elements2(two);
+    while ((element = elements2.next()) != 0) {
+      LRG &lrg = ifg->lrgs(element);
+      if (mask.overlap(lrg.mask())) {
+        if (insert(element)) {
+          if (!lrg.mask().is_AllStack()) {
+            reg_degree += lrg2.compute_degree(lrg);
+            if (reg_degree >= fail_degree) return reg_degree;
+          } else {
+            // !!!!! Danger!  No update to reg_degree despite having a neighbor.
+            // A variant of the Briggs assertion.
+            // Not needed if I simplify during coalesce, ala George/Appel.
+            assert(lrg.lo_degree(), "");
+          }
         }
       }
     }
@@ -219,6 +227,7 @@
   _max_elements = set->_max_elements;
 #endif
   _count = set->_count;
+  _current_block_limit = set->_current_block_limit;
   _max_blocks = set->_max_blocks;
   if (_max_blocks <= preallocated_block_list_size) {
     _blocks = _preallocated_block_list;
@@ -248,6 +257,7 @@
   _max_elements = max_elements;
 #endif
   _count = 0;
+  _current_block_limit = 0;
   _max_blocks = (max_elements + bits_per_block - 1) / bits_per_block;
 
   if (_max_blocks <= preallocated_block_list_size) {
@@ -272,6 +282,7 @@
   _max_elements = max_elements;
 #endif // ASSERT
   _count = 0;
+  _current_block_limit = 0;
   _max_blocks = (max_elements + bits_per_block - 1) / bits_per_block;
 
   if (_max_blocks <= preallocated_block_list_size) {
@@ -294,7 +305,8 @@
   set->check_watch("swap", _serial_number);
 #endif
 
-  for (uint i = 0; i < _max_blocks; i++) {
+  uint max = MAX2(_current_block_limit, set->_current_block_limit);
+  for (uint i = 0; i < max; i++) {
     BitBlock *temp = _blocks[i];
     set_block(i, set->_blocks[i]);
     set->set_block(i, temp);
@@ -302,6 +314,11 @@
   uint temp = _count;
   _count = set->_count;
   set->_count = temp;
+
+  temp = _current_block_limit;
+  _current_block_limit = set->_current_block_limit;
+  set->_current_block_limit = temp;
+
 }
 
 //---------------------------- IndexSet::dump() -----------------------------
@@ -383,78 +400,6 @@
 // Create an iterator for a set.  If empty blocks are detected when iterating
 // over the set, these blocks are replaced.
 
-IndexSetIterator::IndexSetIterator(IndexSet *set) {
-#ifdef ASSERT
-  if (CollectIndexSetStatistics) {
-    set->tally_iteration_statistics();
-  }
-  set->check_watch("traversed", set->count());
-#endif
-  if (set->is_empty()) {
-    _current = 0;
-    _next_word = IndexSet::words_per_block;
-    _next_block = 1;
-    _max_blocks = 1;
-
-    // We don't need the following values when we iterate over an empty set.
-    // The commented out code is left here to document that the omission
-    // is intentional.
-    //
-    //_value = 0;
-    //_words = NULL;
-    //_blocks = NULL;
-    //_set = NULL;
-  } else {
-    _current = 0;
-    _value = 0;
-    _next_block = 0;
-    _next_word = IndexSet::words_per_block;
-
-    _max_blocks = set->_max_blocks;
-    _words = NULL;
-    _blocks = set->_blocks;
-    _set = set;
-  }
-}
-
-//---------------------------- IndexSetIterator(const) -----------------------------
-// Iterate over a constant IndexSet.
-
-IndexSetIterator::IndexSetIterator(const IndexSet *set) {
-#ifdef ASSERT
-  if (CollectIndexSetStatistics) {
-    set->tally_iteration_statistics();
-  }
-  // We don't call check_watch from here to avoid bad recursion.
-  //   set->check_watch("traversed const", set->count());
-#endif
-  if (set->is_empty()) {
-    _current = 0;
-    _next_word = IndexSet::words_per_block;
-    _next_block = 1;
-    _max_blocks = 1;
-
-    // We don't need the following values when we iterate over an empty set.
-    // The commented out code is left here to document that the omission
-    // is intentional.
-    //
-    //_value = 0;
-    //_words = NULL;
-    //_blocks = NULL;
-    //_set = NULL;
-  } else {
-    _current = 0;
-    _value = 0;
-    _next_block = 0;
-    _next_word = IndexSet::words_per_block;
-
-    _max_blocks = set->_max_blocks;
-    _words = NULL;
-    _blocks = set->_blocks;
-    _set = NULL;
-  }
-}
-
 //---------------------------- List16Iterator::advance_and_next() -----------------------------
 // Advance to the next non-empty word in the set being iterated over.  Return the next element
 // if there is one.  If we are done, return 0.  This method is called from the next() method
@@ -467,10 +412,8 @@
       // Found a non-empty word.
       _value = ((_next_block - 1) * IndexSet::bits_per_block) + (wi * IndexSet::bits_per_word);
       _current = _words[wi];
-
-      _next_word = wi+1;
-
-      return next();
+      _next_word = wi + 1;
+      return next_value();
     }
   }
 
@@ -488,8 +431,7 @@
 
           _next_block = bi+1;
           _next_word = wi+1;
-
-          return next();
+          return next_value();
         }
       }
 
@@ -501,11 +443,6 @@
     }
   }
 
-  // These assignments make redundant calls to next on a finished iterator
-  // faster.  Probably not necessary.
-  _next_block = _max_blocks;
-  _next_word = IndexSet::words_per_block;
-
   // No more words.
   return 0;
 }
--- a/src/hotspot/share/opto/indexSet.hpp	Wed Nov 13 17:21:31 2019 -0500
+++ b/src/hotspot/share/opto/indexSet.hpp	Mon Nov 18 12:40:06 2019 -0500
@@ -190,6 +190,9 @@
   // The number of elements in the set
   uint      _count;
 
+  // The current upper limit of blocks that has been allocated and might be in use
+  uint      _current_block_limit;
+
   // Our top level array of bitvector segments
   BitBlock **_blocks;
 
@@ -246,12 +249,13 @@
 
   void clear() {
     _count = 0;
-    for (uint i = 0; i < _max_blocks; i++) {
+    for (uint i = 0; i < _current_block_limit; i++) {
       BitBlock *block = _blocks[i];
       if (block != &_empty_block) {
         free_block(i);
       }
     }
+    _current_block_limit = 0;
   }
 
   uint count() const { return _count; }
@@ -380,18 +384,18 @@
   // The index of the next word we will inspect
   uint                  _next_word;
 
-  // A pointer to the contents of the current block
-  uint32_t             *_words;
-
   // The index of the next block we will inspect
   uint                  _next_block;
 
+  // The number of blocks in the set
+  uint                  _max_blocks;
+
+  // A pointer to the contents of the current block
+  uint32_t             *_words;
+
   // A pointer to the blocks in our set
   IndexSet::BitBlock **_blocks;
 
-  // The number of blocks in the set
-  uint                  _max_blocks;
-
   // If the iterator was created from a non-const set, we replace
   // non-canonical empty blocks with the _empty_block pointer.  If
   // _set is NULL, we do no replacement.
@@ -405,22 +409,64 @@
 
   // If an iterator is built from a constant set then empty blocks
   // are not canonicalized.
-  IndexSetIterator(IndexSet *set);
-  IndexSetIterator(const IndexSet *set);
+  IndexSetIterator(IndexSet *set) :
+    _current(0),
+    _value(0),
+    _next_word(IndexSet::words_per_block),
+    _next_block(0),
+    _max_blocks(set->is_empty() ? 0 : set->_current_block_limit),
+    _words(NULL),
+    _blocks(set->_blocks),
+    _set(set) {
+  #ifdef ASSERT
+    if (CollectIndexSetStatistics) {
+      set->tally_iteration_statistics();
+    }
+    set->check_watch("traversed", set->count());
+  #endif
+  }
+
+  IndexSetIterator(const IndexSet *set) :
+    _current(0),
+    _value(0),
+    _next_word(IndexSet::words_per_block),
+    _next_block(0),
+    _max_blocks(set->is_empty() ? 0 : set->_current_block_limit),
+    _words(NULL),
+    _blocks(set->_blocks),
+    _set(NULL)
+  {
+  #ifdef ASSERT
+    if (CollectIndexSetStatistics) {
+      set->tally_iteration_statistics();
+    }
+    // We don't call check_watch from here to avoid bad recursion.
+    //   set->check_watch("traversed const", set->count());
+  #endif
+  }
+
+  // Return the next element of the set.
+  uint next_value() {
+    uint current = _current;
+    assert(current != 0, "sanity");
+    uint advance = count_trailing_zeros(current);
+    assert(((current >> advance) & 0x1) == 1, "sanity");
+    _current = (current >> advance) - 1;
+    _value += advance;
+    return _value;
+  }
 
   // Return the next element of the set.  Return 0 when done.
   uint next() {
-    uint current = _current;
-    if (current != 0) {
-      uint advance = count_trailing_zeros(current);
-      assert(((current >> advance) & 0x1) == 1, "sanity");
-      _current = (current >> advance) - 1;
-      _value += advance;
-      return _value;
+    if (_current != 0) {
+      return next_value();
+    } else if (_next_word < IndexSet::words_per_block || _next_block < _max_blocks) {
+      return advance_and_next();
     } else {
-      return advance_and_next();
+      return 0;
     }
   }
+
 };
 
 #endif // SHARE_OPTO_INDEXSET_HPP
--- a/src/hotspot/share/opto/live.cpp	Wed Nov 13 17:21:31 2019 -0500
+++ b/src/hotspot/share/opto/live.cpp	Mon Nov 18 12:40:06 2019 -0500
@@ -84,7 +84,7 @@
 
   // Array of delta-set pointers, indexed by block pre_order-1.
   _deltas = NEW_RESOURCE_ARRAY(IndexSet*,_cfg.number_of_blocks());
-  memset( _deltas, 0, sizeof(IndexSet*)* _cfg.number_of_blocks());
+  memset(_deltas, 0, sizeof(IndexSet*)* _cfg.number_of_blocks());
 
   _free_IndexSet = NULL;
 
@@ -108,8 +108,8 @@
 
       uint r = _names.at(n->_idx);
       assert(!def_outside->member(r), "Use of external LRG overlaps the same LRG defined in this block");
-      def->insert( r );
-      use->remove( r );
+      def->insert(r);
+      use->remove(r);
       uint cnt = n->req();
       for (uint k = 1; k < cnt; k++) {
         Node *nk = n->in(k);
@@ -152,7 +152,7 @@
     while (_worklist->size()) {
       Block* block = _worklist->pop();
       IndexSet *delta = getset(block);
-      assert( delta->count(), "missing delta set" );
+      assert(delta->count(), "missing delta set");
 
       // Add new-live-in to predecessors live-out sets
       for (uint l = 1; l < block->num_preds(); l++) {
@@ -191,36 +191,34 @@
 
 // Get an IndexSet for a block.  Return existing one, if any.  Make a new
 // empty one if a prior one does not exist.
-IndexSet *PhaseLive::getset( Block *p ) {
+IndexSet *PhaseLive::getset(Block *p) {
   IndexSet *delta = _deltas[p->_pre_order-1];
-  if( !delta )                  // Not on worklist?
+  if (!delta) {                 // Not on worklist?
     // Get a free set; flag as being on worklist
     delta = _deltas[p->_pre_order-1] = getfreeset();
+  }
   return delta;                 // Return set of new live-out items
 }
 
 // Pull from free list, or allocate.  Internal allocation on the returned set
 // is always from thread local storage.
-IndexSet *PhaseLive::getfreeset( ) {
+IndexSet *PhaseLive::getfreeset() {
   IndexSet *f = _free_IndexSet;
-  if( !f ) {
+  if (!f) {
     f = new IndexSet;
-//    f->set_arena(Thread::current()->resource_area());
     f->initialize(_maxlrg, Thread::current()->resource_area());
   } else {
     // Pull from free list
     _free_IndexSet = f->next();
-  //f->_cnt = 0;                        // Reset to empty
-//    f->set_arena(Thread::current()->resource_area());
     f->initialize(_maxlrg, Thread::current()->resource_area());
   }
   return f;
 }
 
 // Free an IndexSet from a block.
-void PhaseLive::freeset( Block *p ) {
+void PhaseLive::freeset(Block *p) {
   IndexSet *f = _deltas[p->_pre_order-1];
-  if ( _keep_deltas ) {
+  if (_keep_deltas) {
     add_livein(p, f);
   }
   f->set_next(_free_IndexSet);
@@ -230,40 +228,45 @@
 
 // Add a live-out value to a given blocks live-out set.  If it is new, then
 // also add it to the delta set and stick the block on the worklist.
-void PhaseLive::add_liveout( Block *p, uint r, VectorSet &first_pass ) {
+void PhaseLive::add_liveout(Block *p, uint r, VectorSet &first_pass) {
   IndexSet *live = &_live[p->_pre_order-1];
-  if( live->insert(r) ) {       // If actually inserted...
+  if (live->insert(r)) {        // If actually inserted...
     // We extended the live-out set.  See if the value is generated locally.
     // If it is not, then we must extend the live-in set.
-    if( !_defs[p->_pre_order-1].member( r ) ) {
-      if( !_deltas[p->_pre_order-1] && // Not on worklist?
-          first_pass.test(p->_pre_order) )
+    if (!_defs[p->_pre_order-1].member(r)) {
+      if (!_deltas[p->_pre_order-1] && // Not on worklist?
+          first_pass.test(p->_pre_order)) {
         _worklist->push(p);     // Actually go on worklist if already 1st pass
+      }
       getset(p)->insert(r);
     }
   }
 }
 
 // Add a vector of live-out values to a given blocks live-out set.
-void PhaseLive::add_liveout( Block *p, IndexSet *lo, VectorSet &first_pass ) {
+void PhaseLive::add_liveout(Block *p, IndexSet *lo, VectorSet &first_pass) {
   IndexSet *live = &_live[p->_pre_order-1];
   IndexSet *defs = &_defs[p->_pre_order-1];
   IndexSet *on_worklist = _deltas[p->_pre_order-1];
   IndexSet *delta = on_worklist ? on_worklist : getfreeset();
 
-  IndexSetIterator elements(lo);
-  uint r;
-  while ((r = elements.next()) != 0) {
-    if( live->insert(r) &&      // If actually inserted...
-        !defs->member( r ) )    // and not defined locally
-      delta->insert(r);         // Then add to live-in set
+  if (!lo->is_empty()) {
+    IndexSetIterator elements(lo);
+    uint r;
+    while ((r = elements.next()) != 0) {
+      if (live->insert(r) &&      // If actually inserted...
+          !defs->member(r)) {     // and not defined locally
+        delta->insert(r);         // Then add to live-in set
+      }
+    }
   }
 
-  if( delta->count() ) {                // If actually added things
+  if (delta->count()) {                // If actually added things
     _deltas[p->_pre_order-1] = delta; // Flag as on worklist now
-    if( !on_worklist &&         // Not on worklist?
-        first_pass.test(p->_pre_order) )
+    if (!on_worklist &&         // Not on worklist?
+        first_pass.test(p->_pre_order)) {
       _worklist->push(p);       // Actually go on worklist if already 1st pass
+    }
   } else {                      // Nothing there; just free it
     delta->set_next(_free_IndexSet);
     _free_IndexSet = delta;     // Drop onto free list
@@ -273,23 +276,25 @@
 // Add a vector of live-in values to a given blocks live-in set.
 void PhaseLive::add_livein(Block *p, IndexSet *lo) {
   IndexSet *livein = &_livein[p->_pre_order-1];
-  IndexSetIterator elements(lo);
-  uint r;
-  while ((r = elements.next()) != 0) {
-    livein->insert(r);         // Then add to live-in set
+  if (!livein->is_empty()) {
+    IndexSetIterator elements(lo);
+    uint r;
+    while ((r = elements.next()) != 0) {
+      livein->insert(r);         // Then add to live-in set
+    }
   }
 }
 
 #ifndef PRODUCT
 // Dump the live-out set for a block
-void PhaseLive::dump( const Block *b ) const {
+void PhaseLive::dump(const Block *b) const {
   tty->print("Block %d: ",b->_pre_order);
-  if ( _keep_deltas ) {
+  if (_keep_deltas) {
     tty->print("LiveIn: ");  _livein[b->_pre_order-1].dump();
   }
   tty->print("LiveOut: ");  _live[b->_pre_order-1].dump();
   uint cnt = b->number_of_nodes();
-  for( uint i=0; i<cnt; i++ ) {
+  for (uint i = 0; i < cnt; i++) {
     tty->print("L%d/", _names.at(b->get_node(i)->_idx));
     b->get_node(i)->dump();
   }
@@ -297,7 +302,7 @@
 }
 
 // Verify that base pointers and derived pointers are still sane.
-void PhaseChaitin::verify_base_ptrs( ResourceArea *a ) const {
+void PhaseChaitin::verify_base_ptrs(ResourceArea *a) const {
 #ifdef ASSERT
   Unique_Node_List worklist(a);
   for (uint i = 0; i < _cfg.number_of_blocks(); i++) {
@@ -322,17 +327,17 @@
               worklist.clear();
               worklist.push(check);
               uint k = 0;
-              while( k < worklist.size() ) {
+              while (k < worklist.size()) {
                 check = worklist.at(k);
                 assert(check,"Bad base or derived pointer");
                 // See PhaseChaitin::find_base_for_derived() for all cases.
                 int isc = check->is_Copy();
-                if( isc ) {
+                if (isc) {
                   worklist.push(check->in(isc));
-                } else if( check->is_Phi() ) {
+                } else if (check->is_Phi()) {
                   for (uint m = 1; m < check->req(); m++)
                     worklist.push(check->in(m));
-                } else if( check->is_Con() ) {
+                } else if (check->is_Con()) {
                   if (is_derived) {
                     // Derived is NULL+offset
                     assert(!is_derived || check->bottom_type()->is_ptr()->ptr() == TypePtr::Null,"Bad derived pointer");
@@ -346,8 +351,8 @@
                              check->bottom_type()->is_ptr()->ptr() == TypePtr::Null,"Bad base pointer");
                     }
                   }
-                } else if( check->bottom_type()->is_ptr()->_offset == 0 ) {
-                  if(check->is_Proj() || (check->is_Mach() &&
+                } else if (check->bottom_type()->is_ptr()->_offset == 0) {
+                  if (check->is_Proj() || (check->is_Mach() &&
                      (check->as_Mach()->ideal_Opcode() == Op_CreateEx ||
                       check->as_Mach()->ideal_Opcode() == Op_ThreadLocal ||
                       check->as_Mach()->ideal_Opcode() == Op_CMoveP ||
@@ -381,7 +386,7 @@
 }
 
 // Verify that graphs and base pointers are still sane.
-void PhaseChaitin::verify( ResourceArea *a, bool verify_ifg ) const {
+void PhaseChaitin::verify(ResourceArea *a, bool verify_ifg) const {
 #ifdef ASSERT
   if (VerifyRegisterAllocator) {
     _cfg.verify();
--- a/src/hotspot/share/opto/reg_split.cpp	Wed Nov 13 17:21:31 2019 -0500
+++ b/src/hotspot/share/opto/reg_split.cpp	Mon Nov 18 12:40:06 2019 -0500
@@ -1271,10 +1271,12 @@
         // it contains no members which compress to defidx.  Finding such an
         // instance may be a case to add liveout adjustment in compress_uf_map().
         // See 5063219.
-        uint member;
-        IndexSetIterator isi(liveout);
-        while ((member = isi.next()) != 0) {
-          assert(defidx != _lrg_map.find_const(member), "Live out member has not been compressed");
+        if (!liveout->is_empty()) {
+          uint member;
+          IndexSetIterator isi(liveout);
+          while ((member = isi.next()) != 0) {
+            assert(defidx != _lrg_map.find_const(member), "Live out member has not been compressed");
+          }
         }
 #endif
         Reachblock[slidx] = NULL;
--- a/src/hotspot/share/prims/jvmtiEnv.cpp	Wed Nov 13 17:21:31 2019 -0500
+++ b/src/hotspot/share/prims/jvmtiEnv.cpp	Mon Nov 18 12:40:06 2019 -0500
@@ -3333,35 +3333,8 @@
 // rmonitor - pre-checked for validity
 jvmtiError
 JvmtiEnv::RawMonitorWait(JvmtiRawMonitor * rmonitor, jlong millis) {
-  int r = 0;
   Thread* thread = Thread::current();
-
-  if (thread->is_Java_thread()) {
-    JavaThread* current_thread = (JavaThread*)thread;
-
-    /* Transition to thread_blocked without entering vm state          */
-    /* This is really evil. Normally you can't undo _thread_blocked    */
-    /* transitions like this because it would cause us to miss a       */
-    /* safepoint but since the thread was already in _thread_in_native */
-    /* the thread is not leaving a safepoint safe state and it will    */
-    /* block when it tries to return from native. We can't safepoint   */
-    /* block in here because we could deadlock the vmthread. Blech.    */
-
-    JavaThreadState state = current_thread->thread_state();
-    assert(state == _thread_in_native, "Must be _thread_in_native");
-    // frame should already be walkable since we are in native
-    assert(!current_thread->has_last_Java_frame() ||
-           current_thread->frame_anchor()->walkable(), "Must be walkable");
-    current_thread->set_thread_state(_thread_blocked);
-
-    r = rmonitor->raw_wait(millis, true, current_thread);
-    // restore state, still at a safepoint safe state
-    current_thread->set_thread_state(state);
-
-  } else {
-      r = rmonitor->raw_wait(millis, false, thread);
-      assert(r != JvmtiRawMonitor::M_INTERRUPTED, "non-JavaThread can't be interrupted");
-  }
+  int r = rmonitor->raw_wait(millis, thread);
 
   switch (r) {
   case JvmtiRawMonitor::M_INTERRUPTED:
--- a/src/hotspot/share/prims/jvmtiRawMonitor.cpp	Wed Nov 13 17:21:31 2019 -0500
+++ b/src/hotspot/share/prims/jvmtiRawMonitor.cpp	Mon Nov 18 12:40:06 2019 -0500
@@ -174,29 +174,16 @@
   return;
 }
 
-int JvmtiRawMonitor::simple_wait(Thread* self, jlong millis) {
-  guarantee(_owner == self  , "invariant");
-  guarantee(_recursions == 0, "invariant");
-
-  QNode node(self);
+inline void JvmtiRawMonitor::enqueue_waiter(QNode& node) {
   node._notified = 0;
   node._t_state = QNode::TS_WAIT;
-
   RawMonitor_lock->lock_without_safepoint_check();
   node._next = _wait_set;
   _wait_set = &node;
   RawMonitor_lock->unlock();
-
-  simple_exit(self);
-  guarantee(_owner != self, "invariant");
+}
 
-  int ret = OS_OK;
-  if (millis <= 0) {
-    self->_ParkEvent->park();
-  } else {
-    ret = self->_ParkEvent->park(millis);
-  }
-
+inline void JvmtiRawMonitor::dequeue_waiter(QNode& node) {
   // If thread still resides on the waitset then unlink it.
   // Double-checked locking -- the usage is safe in this context
   // as _t_state is volatile and the lock-unlock operators are
@@ -225,10 +212,60 @@
   }
 
   guarantee(node._t_state == QNode::TS_RUN, "invariant");
+}
+
+// simple_wait is not quite so simple as we have to deal with the interaction
+// with the Thread interrupt state, which resides in the java.lang.Thread object.
+// That state must only be accessed while _thread_in_vm and requires proper thread-state
+// transitions. However, we cannot perform such transitions whilst we hold the RawMonitor,
+// else we can deadlock with the VMThread (which may also use RawMonitors as part of
+// executing various callbacks).
+// Returns M_OK usually, but M_INTERRUPTED if the thread is a JavaThread and was
+// interrupted.
+int JvmtiRawMonitor::simple_wait(Thread* self, jlong millis) {
+  guarantee(_owner == self  , "invariant");
+  guarantee(_recursions == 0, "invariant");
+
+  QNode node(self);
+  enqueue_waiter(node);
+
+  simple_exit(self);
+  guarantee(_owner != self, "invariant");
+
+  int ret = M_OK;
+  if (self->is_Java_thread()) {
+    JavaThread* jt = (JavaThread*) self;
+    // Transition to VM so we can check interrupt state
+    ThreadInVMfromNative tivm(jt);
+    if (jt->is_interrupted(true)) {
+        ret = M_INTERRUPTED;
+    } else {
+      ThreadBlockInVM tbivm(jt);
+      jt->set_suspend_equivalent();
+      if (millis <= 0) {
+        self->_ParkEvent->park();
+      } else {
+        self->_ParkEvent->park(millis);
+      }
+      // Return to VM before post-check of interrupt state
+    }
+    if (jt->is_interrupted(true)) {
+      ret = M_INTERRUPTED;
+    }
+  } else {
+    if (millis <= 0) {
+      self->_ParkEvent->park();
+    } else {
+      self->_ParkEvent->park(millis);
+    }
+  }
+
+  dequeue_waiter(node);
+
   simple_enter(self);
-
   guarantee(_owner == self, "invariant");
   guarantee(_recursions == 0, "invariant");
+
   return ret;
 }
 
@@ -351,60 +388,59 @@
   return M_OK;
 }
 
-// All JavaThreads will enter here with state _thread_blocked
-
-int JvmtiRawMonitor::raw_wait(jlong millis, bool interruptible, Thread* self) {
+int JvmtiRawMonitor::raw_wait(jlong millis, Thread* self) {
   if (self != _owner) {
     return M_ILLEGAL_MONITOR_STATE;
   }
 
+  int ret = M_OK;
+
   // To avoid spurious wakeups we reset the parkevent. This is strictly optional.
   // The caller must be able to tolerate spurious returns from raw_wait().
   self->_ParkEvent->reset();
   OrderAccess::fence();
 
-  JavaThread* jt = NULL;
-  // check interrupt event
-  if (interruptible) {
-    assert(self->is_Java_thread(), "Only JavaThreads can be interruptible");
-    jt = (JavaThread*)self;
-    if (jt->is_interrupted(true)) {
-      return M_INTERRUPTED;
-    }
-  } else {
-    assert(!self->is_Java_thread(), "JavaThreads must be interuptible");
-  }
-
   intptr_t save = _recursions;
   _recursions = 0;
   _waiters++;
-  if (self->is_Java_thread()) {
-    guarantee(jt->thread_state() == _thread_blocked, "invariant");
-    jt->set_suspend_equivalent();
-  }
-  int rv = simple_wait(self, millis);
+  ret = simple_wait(self, millis);
   _recursions = save;
   _waiters--;
 
   guarantee(self == _owner, "invariant");
+
   if (self->is_Java_thread()) {
+    JavaThread* jt = (JavaThread*)self;
     for (;;) {
+      jt->set_suspend_equivalent();
       if (!jt->handle_special_suspend_equivalent_condition()) {
         break;
+      } else {
+        // We've been suspended whilst waiting and so we have to
+        // relinquish the raw monitor until we are resumed. Of course
+        // after reacquiring we have to re-check for suspension again.
+        // Suspension requires we are _thread_blocked, and we also have to
+        // recheck for being interrupted.
+        simple_exit(jt);
+        {
+          ThreadInVMfromNative tivm(jt);
+          {
+            ThreadBlockInVM tbivm(jt);
+            jt->java_suspend_self();
+          }
+          if (jt->is_interrupted(true)) {
+            ret = M_INTERRUPTED;
+          }
+        }
+        simple_enter(jt);
       }
-      simple_exit(jt);
-      jt->java_suspend_self();
-      simple_enter(jt);
-      jt->set_suspend_equivalent();
     }
     guarantee(jt == _owner, "invariant");
+  } else {
+    assert(ret != M_INTERRUPTED, "Only JavaThreads can be interrupted");
   }
 
-  if (interruptible && jt->is_interrupted(true)) {
-    return M_INTERRUPTED;
-  }
-
-  return M_OK;
+  return ret;
 }
 
 int JvmtiRawMonitor::raw_notify(Thread* self) {
--- a/src/hotspot/share/prims/jvmtiRawMonitor.hpp	Wed Nov 13 17:21:31 2019 -0500
+++ b/src/hotspot/share/prims/jvmtiRawMonitor.hpp	Mon Nov 18 12:40:06 2019 -0500
@@ -65,6 +65,11 @@
   // JVMTI_RM_MAGIC is set in contructor and unset in destructor.
   enum { JVMTI_RM_MAGIC = (int)(('T' << 24) | ('I' << 16) | ('R' << 8) | 'M') };
 
+  // Helpers for queue management isolation
+  void enqueue_waiter(QNode& node);
+  void dequeue_waiter(QNode& node);
+
+  // Mostly low-level implementation routines
   void simple_enter(Thread* self);
   void simple_exit(Thread* self);
   int simple_wait(Thread* self, jlong millis);
@@ -92,7 +97,7 @@
   int recursions() const { return _recursions; }
   void raw_enter(Thread* self);
   int raw_exit(Thread* self);
-  int raw_wait(jlong millis, bool interruptible, Thread* self);
+  int raw_wait(jlong millis, Thread* self);
   int raw_notify(Thread* self);
   int raw_notifyAll(Thread* self);
   int magic() const { return _magic; }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/runtime/abstract_vm_version.cpp	Mon Nov 18 12:40:06 2019 -0500
@@ -0,0 +1,316 @@
+/*
+ * Copyright (c) 1998, 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#include "precompiled.hpp"
+#include "compiler/compilerDefinitions.hpp"
+#include "runtime/arguments.hpp"
+#include "runtime/vm_version.hpp"
+#include "utilities/globalDefinitions.hpp"
+
+const char* Abstract_VM_Version::_s_vm_release = Abstract_VM_Version::vm_release();
+const char* Abstract_VM_Version::_s_internal_vm_info_string = Abstract_VM_Version::internal_vm_info_string();
+
+uint64_t Abstract_VM_Version::_features = 0;
+const char* Abstract_VM_Version::_features_string = "";
+
+bool Abstract_VM_Version::_supports_cx8 = false;
+bool Abstract_VM_Version::_supports_atomic_getset4 = false;
+bool Abstract_VM_Version::_supports_atomic_getset8 = false;
+bool Abstract_VM_Version::_supports_atomic_getadd4 = false;
+bool Abstract_VM_Version::_supports_atomic_getadd8 = false;
+unsigned int Abstract_VM_Version::_logical_processors_per_package = 1U;
+unsigned int Abstract_VM_Version::_L1_data_cache_line_size = 0;
+unsigned int Abstract_VM_Version::_data_cache_line_flush_size = 0;
+
+VirtualizationType Abstract_VM_Version::_detected_virtualization = NoDetectedVirtualization;
+
+#ifndef HOTSPOT_VERSION_STRING
+  #error HOTSPOT_VERSION_STRING must be defined
+#endif
+
+#ifndef VERSION_FEATURE
+  #error VERSION_FEATURE must be defined
+#endif
+#ifndef VERSION_INTERIM
+  #error VERSION_INTERIM must be defined
+#endif
+#ifndef VERSION_UPDATE
+  #error VERSION_UPDATE must be defined
+#endif
+#ifndef VERSION_PATCH
+  #error VERSION_PATCH must be defined
+#endif
+#ifndef VERSION_BUILD
+  #error VERSION_BUILD must be defined
+#endif
+
+#ifndef VERSION_STRING
+  #error VERSION_STRING must be defined
+#endif
+
+#ifndef DEBUG_LEVEL
+  #error DEBUG_LEVEL must be defined
+#endif
+
+#define VM_RELEASE HOTSPOT_VERSION_STRING
+
+// HOTSPOT_VERSION_STRING equals the JDK VERSION_STRING (unless overridden
+// in a standalone build).
+int Abstract_VM_Version::_vm_major_version = VERSION_FEATURE;
+int Abstract_VM_Version::_vm_minor_version = VERSION_INTERIM;
+int Abstract_VM_Version::_vm_security_version = VERSION_UPDATE;
+int Abstract_VM_Version::_vm_patch_version = VERSION_PATCH;
+int Abstract_VM_Version::_vm_build_number = VERSION_BUILD;
+
+#if defined(_LP64)
+  #define VMLP "64-Bit "
+#else
+  #define VMLP ""
+#endif
+
+#ifndef VMTYPE
+  #ifdef TIERED
+    #define VMTYPE "Server"
+  #else // TIERED
+  #ifdef ZERO
+    #define VMTYPE "Zero"
+  #else // ZERO
+     #define VMTYPE COMPILER1_PRESENT("Client")   \
+                    COMPILER2_PRESENT("Server")
+  #endif // ZERO
+  #endif // TIERED
+#endif
+
+#ifndef HOTSPOT_VM_DISTRO
+  #error HOTSPOT_VM_DISTRO must be defined
+#endif
+#define VMNAME HOTSPOT_VM_DISTRO " " VMLP VMTYPE " VM"
+
+const char* Abstract_VM_Version::vm_name() {
+  return VMNAME;
+}
+
+
+const char* Abstract_VM_Version::vm_vendor() {
+#ifdef VENDOR
+  return VENDOR;
+#else
+  return "Oracle Corporation";
+#endif
+}
+
+
+const char* Abstract_VM_Version::vm_info_string() {
+  switch (Arguments::mode()) {
+    case Arguments::_int:
+      return UseSharedSpaces ? "interpreted mode, sharing" : "interpreted mode";
+    case Arguments::_mixed:
+      if (UseSharedSpaces) {
+        if (UseAOT) {
+          return "mixed mode, aot, sharing";
+#ifdef TIERED
+        } else if(is_client_compilation_mode_vm()) {
+          return "mixed mode, emulated-client, sharing";
+#endif
+        } else {
+          return "mixed mode, sharing";
+         }
+      } else {
+        if (UseAOT) {
+          return "mixed mode, aot";
+#ifdef TIERED
+        } else if(is_client_compilation_mode_vm()) {
+          return "mixed mode, emulated-client";
+#endif
+        } else {
+          return "mixed mode";
+        }
+      }
+    case Arguments::_comp:
+#ifdef TIERED
+      if (is_client_compilation_mode_vm()) {
+         return UseSharedSpaces ? "compiled mode, emulated-client, sharing" : "compiled mode, emulated-client";
+      }
+#endif
+      return UseSharedSpaces ? "compiled mode, sharing"    : "compiled mode";
+  };
+  ShouldNotReachHere();
+  return "";
+}
+
+// NOTE: do *not* use stringStream. this function is called by
+//       fatal error handler. if the crash is in native thread,
+//       stringStream cannot get resource allocated and will SEGV.
+const char* Abstract_VM_Version::vm_release() {
+  return VM_RELEASE;
+}
+
+// NOTE: do *not* use stringStream. this function is called by
+//       fatal error handlers. if the crash is in native thread,
+//       stringStream cannot get resource allocated and will SEGV.
+const char* Abstract_VM_Version::jre_release_version() {
+  return VERSION_STRING;
+}
+
+#define OS       LINUX_ONLY("linux")             \
+                 WINDOWS_ONLY("windows")         \
+                 SOLARIS_ONLY("solaris")         \
+                 AIX_ONLY("aix")                 \
+                 BSD_ONLY("bsd")
+
+#ifndef CPU
+#ifdef ZERO
+#define CPU      ZERO_LIBARCH
+#elif defined(PPC64)
+#if defined(VM_LITTLE_ENDIAN)
+#define CPU      "ppc64le"
+#else
+#define CPU      "ppc64"
+#endif // PPC64
+#else
+#define CPU      AARCH64_ONLY("aarch64")         \
+                 AMD64_ONLY("amd64")             \
+                 IA32_ONLY("x86")                \
+                 IA64_ONLY("ia64")               \
+                 S390_ONLY("s390")               \
+                 SPARC_ONLY("sparc")
+#endif // !ZERO
+#endif // !CPU
+
+const char *Abstract_VM_Version::vm_platform_string() {
+  return OS "-" CPU;
+}
+
+const char* Abstract_VM_Version::internal_vm_info_string() {
+  #ifndef HOTSPOT_BUILD_USER
+    #define HOTSPOT_BUILD_USER unknown
+  #endif
+
+  #ifndef HOTSPOT_BUILD_COMPILER
+    #ifdef _MSC_VER
+      #if _MSC_VER == 1600
+        #define HOTSPOT_BUILD_COMPILER "MS VC++ 10.0 (VS2010)"
+      #elif _MSC_VER == 1700
+        #define HOTSPOT_BUILD_COMPILER "MS VC++ 11.0 (VS2012)"
+      #elif _MSC_VER == 1800
+        #define HOTSPOT_BUILD_COMPILER "MS VC++ 12.0 (VS2013)"
+      #elif _MSC_VER == 1900
+        #define HOTSPOT_BUILD_COMPILER "MS VC++ 14.0 (VS2015)"
+      #elif _MSC_VER == 1911
+        #define HOTSPOT_BUILD_COMPILER "MS VC++ 15.3 (VS2017)"
+      #elif _MSC_VER == 1912
+        #define HOTSPOT_BUILD_COMPILER "MS VC++ 15.5 (VS2017)"
+      #elif _MSC_VER == 1913
+        #define HOTSPOT_BUILD_COMPILER "MS VC++ 15.6 (VS2017)"
+      #elif _MSC_VER == 1914
+        #define HOTSPOT_BUILD_COMPILER "MS VC++ 15.7 (VS2017)"
+      #elif _MSC_VER == 1915
+        #define HOTSPOT_BUILD_COMPILER "MS VC++ 15.8 (VS2017)"
+      #else
+        #define HOTSPOT_BUILD_COMPILER "unknown MS VC++:" XSTR(_MSC_VER)
+      #endif
+    #elif defined(__SUNPRO_CC)
+      #if __SUNPRO_CC == 0x580
+        #define HOTSPOT_BUILD_COMPILER "Workshop 5.8"
+      #elif __SUNPRO_CC == 0x590
+        #define HOTSPOT_BUILD_COMPILER "Workshop 5.9"
+      #elif __SUNPRO_CC == 0x5100
+        #define HOTSPOT_BUILD_COMPILER "Sun Studio 12u1"
+      #elif __SUNPRO_CC == 0x5120
+        #define HOTSPOT_BUILD_COMPILER "Sun Studio 12u3"
+      #elif __SUNPRO_CC == 0x5130
+        #define HOTSPOT_BUILD_COMPILER "Sun Studio 12u4"
+      #else
+        #define HOTSPOT_BUILD_COMPILER "unknown Workshop:" XSTR(__SUNPRO_CC)
+      #endif
+    #elif defined(__clang_version__)
+        #define HOTSPOT_BUILD_COMPILER "clang " __VERSION__
+    #elif defined(__GNUC__)
+        #define HOTSPOT_BUILD_COMPILER "gcc " __VERSION__
+    #else
+      #define HOTSPOT_BUILD_COMPILER "unknown compiler"
+    #endif
+  #endif
+
+  #ifndef FLOAT_ARCH
+    #if defined(__SOFTFP__)
+      #define FLOAT_ARCH_STR "-sflt"
+    #else
+      #define FLOAT_ARCH_STR ""
+    #endif
+  #else
+    #define FLOAT_ARCH_STR XSTR(FLOAT_ARCH)
+  #endif
+
+  #define INTERNAL_VERSION_SUFFIX VM_RELEASE ")" \
+         " for " OS "-" CPU FLOAT_ARCH_STR \
+         " JRE (" VERSION_STRING "), built on " __DATE__ " " __TIME__ \
+         " by " XSTR(HOTSPOT_BUILD_USER) " with " HOTSPOT_BUILD_COMPILER
+
+  return strcmp(DEBUG_LEVEL, "release") == 0
+      ? VMNAME " (" INTERNAL_VERSION_SUFFIX
+      : VMNAME " (" DEBUG_LEVEL " " INTERNAL_VERSION_SUFFIX;
+}
+
+const char *Abstract_VM_Version::vm_build_user() {
+  return HOTSPOT_BUILD_USER;
+}
+
+const char *Abstract_VM_Version::jdk_debug_level() {
+  return DEBUG_LEVEL;
+}
+
+const char *Abstract_VM_Version::printable_jdk_debug_level() {
+  // Debug level is not printed for "release" builds
+  return strcmp(DEBUG_LEVEL, "release") == 0 ? "" : DEBUG_LEVEL " ";
+}
+
+unsigned int Abstract_VM_Version::jvm_version() {
+  return ((Abstract_VM_Version::vm_major_version() & 0xFF) << 24) |
+         ((Abstract_VM_Version::vm_minor_version() & 0xFF) << 16) |
+         ((Abstract_VM_Version::vm_security_version() & 0xFF) << 8) |
+         (Abstract_VM_Version::vm_build_number() & 0xFF);
+}
+
+bool Abstract_VM_Version::print_matching_lines_from_file(const char* filename, outputStream* st, const char* keywords_to_match[]) {
+  char line[500];
+  FILE* fp = fopen(filename, "r");
+  if (fp == NULL) {
+    return false;
+  }
+
+  st->print_cr("Virtualization information:");
+  while (fgets(line, sizeof(line), fp) != NULL) {
+    int i = 0;
+    while (keywords_to_match[i] != NULL) {
+      if (strncmp(line, keywords_to_match[i], strlen(keywords_to_match[i])) == 0) {
+        st->print("%s", line);
+        break;
+      }
+      i++;
+    }
+  }
+  fclose(fp);
+  return true;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/runtime/abstract_vm_version.hpp	Mon Nov 18 12:40:06 2019 -0500
@@ -0,0 +1,194 @@
+/*
+ * Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#ifndef SHARE_RUNTIME_ABSTRACT_VM_VERSION_HPP
+#define SHARE_RUNTIME_ABSTRACT_VM_VERSION_HPP
+
+#include "memory/allocation.hpp"  // For declaration of class AllStatic
+#include "utilities/globalDefinitions.hpp"
+
+typedef enum {
+  NoDetectedVirtualization,
+  XenHVM,
+  KVM,
+  VMWare,
+  HyperV,
+  PowerVM, // on AIX or Linux ppc64(le)
+  PowerFullPartitionMode, // on Linux ppc64(le)
+  PowerKVM
+} VirtualizationType;
+
+class outputStream;
+
+// Abstract_VM_Version provides information about the VM.
+
+class Abstract_VM_Version: AllStatic {
+  friend class VMStructs;
+  friend class JVMCIVMStructs;
+
+ protected:
+  static const char*  _s_vm_release;
+  static const char*  _s_internal_vm_info_string;
+
+  // CPU feature flags.
+  static uint64_t _features;
+  static const char* _features_string;
+
+  // These are set by machine-dependent initializations
+  static bool         _supports_cx8;
+  static bool         _supports_atomic_getset4;
+  static bool         _supports_atomic_getset8;
+  static bool         _supports_atomic_getadd4;
+  static bool         _supports_atomic_getadd8;
+  static unsigned int _logical_processors_per_package;
+  static unsigned int _L1_data_cache_line_size;
+  static int          _vm_major_version;
+  static int          _vm_minor_version;
+  static int          _vm_security_version;
+  static int          _vm_patch_version;
+  static int          _vm_build_number;
+  static unsigned int _data_cache_line_flush_size;
+
+  static VirtualizationType _detected_virtualization;
+
+ public:
+  // Called as part of the runtime services initialization which is
+  // called from the management module initialization (via init_globals())
+  // after argument parsing and attaching of the main thread has
+  // occurred.  Examines a variety of the hardware capabilities of
+  // the platform to determine which features can be used to execute the
+  // program.
+  static void initialize() { }
+
+  // This allows for early initialization of VM_Version information
+  // that may be needed later in the initialization sequence but before
+  // full VM_Version initialization is possible. It can not depend on any
+  // other part of the VM being initialized when called. Platforms that
+  // need to specialize this define VM_Version::early_initialize().
+  static void early_initialize() { }
+
+  // Called to initialize VM variables needing initialization
+  // after command line parsing. Platforms that need to specialize
+  // this should define VM_Version::init_before_ergo().
+  static void init_before_ergo() {}
+
+  // Name
+  static const char* vm_name();
+  // Vendor
+  static const char* vm_vendor();
+  // VM version information string printed by launcher (java -version)
+  static const char* vm_info_string();
+  static const char* vm_release();
+  static const char* vm_platform_string();
+  static const char* vm_build_user();
+
+  static int vm_major_version()               { return _vm_major_version; }
+  static int vm_minor_version()               { return _vm_minor_version; }
+  static int vm_security_version()            { return _vm_security_version; }
+  static int vm_patch_version()               { return _vm_patch_version; }
+  static int vm_build_number()                { return _vm_build_number; }
+
+  // Gets the jvm_version_info.jvm_version defined in jvm.h
+  static unsigned int jvm_version();
+
+  // Internal version providing additional build information
+  static const char* internal_vm_info_string();
+  static const char* jre_release_version();
+  static const char* jdk_debug_level();
+  static const char* printable_jdk_debug_level();
+
+  static uint64_t features() {
+    return _features;
+  }
+
+  static const char* features_string() {
+    return _features_string;
+  }
+
+  static VirtualizationType get_detected_virtualization() {
+    return _detected_virtualization;
+  }
+
+  // platforms that need to specialize this
+  // define VM_Version::print_platform_virtualization_info()
+  static void print_platform_virtualization_info(outputStream*) { }
+
+  // does HW support an 8-byte compare-exchange operation?
+  static bool supports_cx8()  {
+#ifdef SUPPORTS_NATIVE_CX8
+    return true;
+#else
+    return _supports_cx8;
+#endif
+  }
+  // does HW support atomic get-and-set or atomic get-and-add?  Used
+  // to guide intrinsification decisions for Unsafe atomic ops
+  static bool supports_atomic_getset4()  {return _supports_atomic_getset4;}
+  static bool supports_atomic_getset8()  {return _supports_atomic_getset8;}
+  static bool supports_atomic_getadd4()  {return _supports_atomic_getadd4;}
+  static bool supports_atomic_getadd8()  {return _supports_atomic_getadd8;}
+
+  static unsigned int logical_processors_per_package() {
+    return _logical_processors_per_package;
+  }
+
+  static unsigned int L1_data_cache_line_size() {
+    return _L1_data_cache_line_size;
+  }
+
+  // the size in bytes of a data cache line flushed by a flush
+  // operation which should be a power of two or zero if cache line
+  // writeback is not supported by the current os_cpu combination
+  static unsigned int data_cache_line_flush_size() {
+    return _data_cache_line_flush_size;
+  }
+
+  // returns true if and only if cache line writeback is supported
+  static bool supports_data_cache_line_flush() {
+    return _data_cache_line_flush_size != 0;
+  }
+
+  // ARCH specific policy for the BiasedLocking
+  static bool use_biased_locking()  { return true; }
+
+  // Number of page sizes efficiently supported by the hardware.  Most chips now
+  // support two sizes, thus this default implementation.  Processor-specific
+  // subclasses should define new versions to hide this one as needed.  Note
+  // that the O/S may support more sizes, but at most this many are used.
+  static uint page_size_count() { return 2; }
+
+  // Denominator for computing default ParallelGCThreads for machines with
+  // a large number of cores.
+  static uint parallel_worker_threads_denominator() { return 8; }
+
+  // Does this CPU support spin wait instruction?
+  static bool supports_on_spin_wait() { return false; }
+
+  // Does platform support fast class initialization checks for static methods?
+  static bool supports_fast_class_init_checks() { return false; }
+
+  static bool print_matching_lines_from_file(const char* filename, outputStream* st, const char* keywords_to_match[]);
+};
+
+#endif // SHARE_RUNTIME_ABSTRACT_VM_VERSION_HPP
--- a/src/hotspot/share/runtime/arguments.cpp	Wed Nov 13 17:21:31 2019 -0500
+++ b/src/hotspot/share/runtime/arguments.cpp	Mon Nov 18 12:40:06 2019 -0500
@@ -85,6 +85,7 @@
 bool   Arguments::_ClipInlining                 = ClipInlining;
 intx   Arguments::_Tier3InvokeNotifyFreqLog     = Tier3InvokeNotifyFreqLog;
 intx   Arguments::_Tier4InvocationThreshold     = Tier4InvocationThreshold;
+size_t Arguments::_SharedBaseAddress            = SharedBaseAddress;
 
 bool   Arguments::_enable_preview               = false;
 
@@ -618,6 +619,7 @@
   { "ResizeOldPLAB",                           JDK_Version::undefined(), JDK_Version::jdk(14), JDK_Version::jdk(15) },
   { "UseCMSBestFit",                           JDK_Version::undefined(), JDK_Version::jdk(14), JDK_Version::jdk(15) },
   { "UseCMSInitiatingOccupancyOnly",           JDK_Version::undefined(), JDK_Version::jdk(14), JDK_Version::jdk(15) },
+  { "GCLockerInvokesConcurrent",     JDK_Version::undefined(), JDK_Version::jdk(14), JDK_Version::jdk(15) },
   { "BindGCTaskThreadsToCPUs",       JDK_Version::undefined(), JDK_Version::jdk(14), JDK_Version::jdk(16) },
   { "UseGCTaskAffinity",             JDK_Version::undefined(), JDK_Version::jdk(14), JDK_Version::jdk(16) },
 
@@ -2274,6 +2276,9 @@
     Arguments::_Tier4InvocationThreshold = Tier4InvocationThreshold;
   }
 
+  // CDS dumping always write the archive to the default value of SharedBaseAddress.
+  Arguments::_SharedBaseAddress = SharedBaseAddress;
+
   // Setup flags for mixed which is the default
   set_mode_flags(_mixed);
 
--- a/src/hotspot/share/runtime/arguments.hpp	Wed Nov 13 17:21:31 2019 -0500
+++ b/src/hotspot/share/runtime/arguments.hpp	Mon Nov 18 12:40:06 2019 -0500
@@ -481,6 +481,7 @@
 
   static char*  SharedArchivePath;
   static char*  SharedDynamicArchivePath;
+  static size_t _SharedBaseAddress; // The default value specified in globals.hpp
   static int num_archives(const char* archive_path) NOT_CDS_RETURN_(0);
   static void extract_shared_archive_paths(const char* archive_path,
                                          char** base_archive_path,
@@ -563,7 +564,7 @@
 
   static const char* GetSharedArchivePath() { return SharedArchivePath; }
   static const char* GetSharedDynamicArchivePath() { return SharedDynamicArchivePath; }
-
+  static size_t default_SharedBaseAddress() { return _SharedBaseAddress; }
   // Java launcher properties
   static void process_sun_java_launcher_properties(JavaVMInitArgs* args);
 
--- a/src/hotspot/share/runtime/globals.hpp	Wed Nov 13 17:21:31 2019 -0500
+++ b/src/hotspot/share/runtime/globals.hpp	Mon Nov 18 12:40:06 2019 -0500
@@ -2430,6 +2430,14 @@
   product(ccstr, ExtraSharedClassListFile, NULL,                            \
           "Extra classlist for building the CDS archive file")              \
                                                                             \
+  diagnostic(intx, ArchiveRelocationMode, 0,                                \
+           "(0) first map at preferred address, and if "                    \
+           "unsuccessful, map at alternative address (default); "           \
+           "(1) always map at alternative address; "                        \
+           "(2) always map at preferred address, and if unsuccessful, "     \
+           "do not map the archive")                                        \
+           range(0, 2)                                                      \
+                                                                            \
   experimental(size_t, ArrayAllocatorMallocLimit,                           \
           SOLARIS_ONLY(64*K) NOT_SOLARIS((size_t)-1),                       \
           "Allocation less than this value will be allocated "              \
--- a/src/hotspot/share/runtime/mutexLocker.cpp	Wed Nov 13 17:21:31 2019 -0500
+++ b/src/hotspot/share/runtime/mutexLocker.cpp	Mon Nov 18 12:40:06 2019 -0500
@@ -72,6 +72,7 @@
 Monitor* CGC_lock                     = NULL;
 Monitor* STS_lock                     = NULL;
 Monitor* FullGCCount_lock             = NULL;
+Monitor* G1OldGCCount_lock            = NULL;
 Monitor* DirtyCardQ_CBL_mon           = NULL;
 Mutex*   Shared_DirtyCardQ_lock       = NULL;
 Mutex*   MarkStackFreeList_lock       = NULL;
@@ -203,6 +204,8 @@
 
   def(FullGCCount_lock             , PaddedMonitor, leaf,        true,  _safepoint_check_never);      // in support of ExplicitGCInvokesConcurrent
   if (UseG1GC) {
+    def(G1OldGCCount_lock          , PaddedMonitor, leaf,        true,  _safepoint_check_always);
+
     def(DirtyCardQ_CBL_mon         , PaddedMonitor, access,      true,  _safepoint_check_never);
     def(Shared_DirtyCardQ_lock     , PaddedMutex  , access + 1,  true,  _safepoint_check_never);
 
--- a/src/hotspot/share/runtime/mutexLocker.hpp	Wed Nov 13 17:21:31 2019 -0500
+++ b/src/hotspot/share/runtime/mutexLocker.hpp	Mon Nov 18 12:40:06 2019 -0500
@@ -68,6 +68,7 @@
                                                  // fore- & background GC threads.
 extern Monitor* STS_lock;                        // used for joining/leaving SuspendibleThreadSet.
 extern Monitor* FullGCCount_lock;                // in support of "concurrent" full gc
+extern Monitor* G1OldGCCount_lock;               // in support of "concurrent" full gc
 extern Monitor* DirtyCardQ_CBL_mon;              // Protects dirty card Q
                                                  // completed buffer queue.
 extern Mutex*   Shared_DirtyCardQ_lock;          // Lock protecting dirty card
--- a/src/hotspot/share/runtime/objectMonitor.cpp	Wed Nov 13 17:21:31 2019 -0500
+++ b/src/hotspot/share/runtime/objectMonitor.cpp	Mon Nov 18 12:40:06 2019 -0500
@@ -1267,6 +1267,10 @@
 
   int ret = OS_OK;
   int WasNotified = 0;
+
+  // Need to check interrupt state whilst still _thread_in_vm
+  bool interrupted = interruptible && jt->is_interrupted(false);
+
   { // State transition wrappers
     OSThread* osthread = Self->osthread();
     OSThreadWaitState osts(osthread, true);
@@ -1275,7 +1279,7 @@
       // Thread is in thread_blocked state and oop access is unsafe.
       jt->set_suspend_equivalent();
 
-      if (interruptible && (jt->is_interrupted(false) || HAS_PENDING_EXCEPTION)) {
+      if (interrupted || HAS_PENDING_EXCEPTION) {
         // Intentionally empty
       } else if (node._notified == 0) {
         if (millis <= 0) {
--- a/src/hotspot/share/runtime/vmOperations.hpp	Wed Nov 13 17:21:31 2019 -0500
+++ b/src/hotspot/share/runtime/vmOperations.hpp	Mon Nov 18 12:40:06 2019 -0500
@@ -66,6 +66,7 @@
   template(G1CollectForAllocation)                \
   template(G1CollectFull)                         \
   template(G1Concurrent)                          \
+  template(G1TryInitiateConcMark)                 \
   template(ZMarkStart)                            \
   template(ZMarkEnd)                              \
   template(ZRelocateStart)                        \
--- a/src/hotspot/share/runtime/vmStructs.cpp	Wed Nov 13 17:21:31 2019 -0500
+++ b/src/hotspot/share/runtime/vmStructs.cpp	Mon Nov 18 12:40:06 2019 -0500
@@ -1103,7 +1103,7 @@
   CDS_ONLY(nonstatic_field(FileMapInfo,        _header,                   FileMapHeader*))                                           \
   CDS_ONLY(   static_field(FileMapInfo,        _current_info,             FileMapInfo*))                                             \
   CDS_ONLY(nonstatic_field(FileMapHeader,      _space[0],                 CDSFileMapRegion))                                         \
-  CDS_ONLY(nonstatic_field(CDSFileMapRegion,   _addr._base,               char*))                                                    \
+  CDS_ONLY(nonstatic_field(CDSFileMapRegion,   _mapped_base,              char*))                                                    \
   CDS_ONLY(nonstatic_field(CDSFileMapRegion,   _used,                     size_t))                                                   \
                                                                                                                                      \
   /******************/                                                                                                               \
--- a/src/hotspot/share/runtime/vm_version.cpp	Wed Nov 13 17:21:31 2019 -0500
+++ b/src/hotspot/share/runtime/vm_version.cpp	Mon Nov 18 12:40:06 2019 -0500
@@ -25,275 +25,8 @@
 #include "precompiled.hpp"
 #include "logging/log.hpp"
 #include "logging/logStream.hpp"
-#include "oops/oop.inline.hpp"
-#include "runtime/arguments.hpp"
 #include "runtime/vm_version.hpp"
 
-const char* Abstract_VM_Version::_s_vm_release = Abstract_VM_Version::vm_release();
-const char* Abstract_VM_Version::_s_internal_vm_info_string = Abstract_VM_Version::internal_vm_info_string();
-
-uint64_t Abstract_VM_Version::_features = 0;
-const char* Abstract_VM_Version::_features_string = "";
-
-bool Abstract_VM_Version::_supports_cx8 = false;
-bool Abstract_VM_Version::_supports_atomic_getset4 = false;
-bool Abstract_VM_Version::_supports_atomic_getset8 = false;
-bool Abstract_VM_Version::_supports_atomic_getadd4 = false;
-bool Abstract_VM_Version::_supports_atomic_getadd8 = false;
-unsigned int Abstract_VM_Version::_logical_processors_per_package = 1U;
-unsigned int Abstract_VM_Version::_L1_data_cache_line_size = 0;
-unsigned int Abstract_VM_Version::_data_cache_line_flush_size = 0;
-
-VirtualizationType Abstract_VM_Version::_detected_virtualization = NoDetectedVirtualization;
-
-#ifndef HOTSPOT_VERSION_STRING
-  #error HOTSPOT_VERSION_STRING must be defined
-#endif
-
-#ifndef VERSION_FEATURE
-  #error VERSION_FEATURE must be defined
-#endif
-#ifndef VERSION_INTERIM
-  #error VERSION_INTERIM must be defined
-#endif
-#ifndef VERSION_UPDATE
-  #error VERSION_UPDATE must be defined
-#endif
-#ifndef VERSION_PATCH
-  #error VERSION_PATCH must be defined
-#endif
-#ifndef VERSION_BUILD
-  #error VERSION_BUILD must be defined
-#endif
-
-#ifndef VERSION_STRING
-  #error VERSION_STRING must be defined
-#endif
-
-#ifndef DEBUG_LEVEL
-  #error DEBUG_LEVEL must be defined
-#endif
-
-#define VM_RELEASE HOTSPOT_VERSION_STRING
-
-// HOTSPOT_VERSION_STRING equals the JDK VERSION_STRING (unless overridden
-// in a standalone build).
-int Abstract_VM_Version::_vm_major_version = VERSION_FEATURE;
-int Abstract_VM_Version::_vm_minor_version = VERSION_INTERIM;
-int Abstract_VM_Version::_vm_security_version = VERSION_UPDATE;
-int Abstract_VM_Version::_vm_patch_version = VERSION_PATCH;
-int Abstract_VM_Version::_vm_build_number = VERSION_BUILD;
-
-#if defined(_LP64)
-  #define VMLP "64-Bit "
-#else
-  #define VMLP ""
-#endif
-
-#ifndef VMTYPE
-  #ifdef TIERED
-    #define VMTYPE "Server"
-  #else // TIERED
-  #ifdef ZERO
-    #define VMTYPE "Zero"
-  #else // ZERO
-     #define VMTYPE COMPILER1_PRESENT("Client")   \
-                    COMPILER2_PRESENT("Server")
-  #endif // ZERO
-  #endif // TIERED
-#endif
-
-#ifndef HOTSPOT_VM_DISTRO
-  #error HOTSPOT_VM_DISTRO must be defined
-#endif
-#define VMNAME HOTSPOT_VM_DISTRO " " VMLP VMTYPE " VM"
-
-const char* Abstract_VM_Version::vm_name() {
-  return VMNAME;
-}
-
-
-const char* Abstract_VM_Version::vm_vendor() {
-#ifdef VENDOR
-  return VENDOR;
-#else
-  return "Oracle Corporation";
-#endif
-}
-
-
-const char* Abstract_VM_Version::vm_info_string() {
-  switch (Arguments::mode()) {
-    case Arguments::_int:
-      return UseSharedSpaces ? "interpreted mode, sharing" : "interpreted mode";
-    case Arguments::_mixed:
-      if (UseSharedSpaces) {
-        if (UseAOT) {
-          return "mixed mode, aot, sharing";
-#ifdef TIERED
-        } else if(is_client_compilation_mode_vm()) {
-          return "mixed mode, emulated-client, sharing";
-#endif
-        } else {
-          return "mixed mode, sharing";
-         }
-      } else {
-        if (UseAOT) {
-          return "mixed mode, aot";
-#ifdef TIERED
-        } else if(is_client_compilation_mode_vm()) {
-          return "mixed mode, emulated-client";
-#endif
-        } else {
-          return "mixed mode";
-        }
-      }
-    case Arguments::_comp:
-#ifdef TIERED
-      if (is_client_compilation_mode_vm()) {
-         return UseSharedSpaces ? "compiled mode, emulated-client, sharing" : "compiled mode, emulated-client";
-      }
-#endif
-      return UseSharedSpaces ? "compiled mode, sharing"    : "compiled mode";
-  };
-  ShouldNotReachHere();
-  return "";
-}
-
-// NOTE: do *not* use stringStream. this function is called by
-//       fatal error handler. if the crash is in native thread,
-//       stringStream cannot get resource allocated and will SEGV.
-const char* Abstract_VM_Version::vm_release() {
-  return VM_RELEASE;
-}
-
-// NOTE: do *not* use stringStream. this function is called by
-//       fatal error handlers. if the crash is in native thread,
-//       stringStream cannot get resource allocated and will SEGV.
-const char* Abstract_VM_Version::jre_release_version() {
-  return VERSION_STRING;
-}
-
-#define OS       LINUX_ONLY("linux")             \
-                 WINDOWS_ONLY("windows")         \
-                 SOLARIS_ONLY("solaris")         \
-                 AIX_ONLY("aix")                 \
-                 BSD_ONLY("bsd")
-
-#ifndef CPU
-#ifdef ZERO
-#define CPU      ZERO_LIBARCH
-#elif defined(PPC64)
-#if defined(VM_LITTLE_ENDIAN)
-#define CPU      "ppc64le"
-#else
-#define CPU      "ppc64"
-#endif // PPC64
-#else
-#define CPU      AARCH64_ONLY("aarch64")         \
-                 AMD64_ONLY("amd64")             \
-                 IA32_ONLY("x86")                \
-                 IA64_ONLY("ia64")               \
-                 S390_ONLY("s390")               \
-                 SPARC_ONLY("sparc")
-#endif // !ZERO
-#endif // !CPU
-
-const char *Abstract_VM_Version::vm_platform_string() {
-  return OS "-" CPU;
-}
-
-const char* Abstract_VM_Version::internal_vm_info_string() {
-  #ifndef HOTSPOT_BUILD_USER
-    #define HOTSPOT_BUILD_USER unknown
-  #endif
-
-  #ifndef HOTSPOT_BUILD_COMPILER
-    #ifdef _MSC_VER
-      #if _MSC_VER == 1600
-        #define HOTSPOT_BUILD_COMPILER "MS VC++ 10.0 (VS2010)"
-      #elif _MSC_VER == 1700
-        #define HOTSPOT_BUILD_COMPILER "MS VC++ 11.0 (VS2012)"
-      #elif _MSC_VER == 1800
-        #define HOTSPOT_BUILD_COMPILER "MS VC++ 12.0 (VS2013)"
-      #elif _MSC_VER == 1900
-        #define HOTSPOT_BUILD_COMPILER "MS VC++ 14.0 (VS2015)"
-      #elif _MSC_VER == 1911
-        #define HOTSPOT_BUILD_COMPILER "MS VC++ 15.3 (VS2017)"
-      #elif _MSC_VER == 1912
-        #define HOTSPOT_BUILD_COMPILER "MS VC++ 15.5 (VS2017)"
-      #elif _MSC_VER == 1913
-        #define HOTSPOT_BUILD_COMPILER "MS VC++ 15.6 (VS2017)"
-      #elif _MSC_VER == 1914
-        #define HOTSPOT_BUILD_COMPILER "MS VC++ 15.7 (VS2017)"
-      #elif _MSC_VER == 1915
-        #define HOTSPOT_BUILD_COMPILER "MS VC++ 15.8 (VS2017)"
-      #else
-        #define HOTSPOT_BUILD_COMPILER "unknown MS VC++:" XSTR(_MSC_VER)
-      #endif
-    #elif defined(__SUNPRO_CC)
-      #if __SUNPRO_CC == 0x580
-        #define HOTSPOT_BUILD_COMPILER "Workshop 5.8"
-      #elif __SUNPRO_CC == 0x590
-        #define HOTSPOT_BUILD_COMPILER "Workshop 5.9"
-      #elif __SUNPRO_CC == 0x5100
-        #define HOTSPOT_BUILD_COMPILER "Sun Studio 12u1"
-      #elif __SUNPRO_CC == 0x5120
-        #define HOTSPOT_BUILD_COMPILER "Sun Studio 12u3"
-      #elif __SUNPRO_CC == 0x5130
-        #define HOTSPOT_BUILD_COMPILER "Sun Studio 12u4"
-      #else
-        #define HOTSPOT_BUILD_COMPILER "unknown Workshop:" XSTR(__SUNPRO_CC)
-      #endif
-    #elif defined(__clang_version__)
-        #define HOTSPOT_BUILD_COMPILER "clang " __VERSION__
-    #elif defined(__GNUC__)
-        #define HOTSPOT_BUILD_COMPILER "gcc " __VERSION__
-    #else
-      #define HOTSPOT_BUILD_COMPILER "unknown compiler"
-    #endif
-  #endif
-
-  #ifndef FLOAT_ARCH
-    #if defined(__SOFTFP__)
-      #define FLOAT_ARCH_STR "-sflt"
-    #else
-      #define FLOAT_ARCH_STR ""
-    #endif
-  #else
-    #define FLOAT_ARCH_STR XSTR(FLOAT_ARCH)
-  #endif
-
-  #define INTERNAL_VERSION_SUFFIX VM_RELEASE ")" \
-         " for " OS "-" CPU FLOAT_ARCH_STR \
-         " JRE (" VERSION_STRING "), built on " __DATE__ " " __TIME__ \
-         " by " XSTR(HOTSPOT_BUILD_USER) " with " HOTSPOT_BUILD_COMPILER
-
-  return strcmp(DEBUG_LEVEL, "release") == 0
-      ? VMNAME " (" INTERNAL_VERSION_SUFFIX
-      : VMNAME " (" DEBUG_LEVEL " " INTERNAL_VERSION_SUFFIX;
-}
-
-const char *Abstract_VM_Version::vm_build_user() {
-  return HOTSPOT_BUILD_USER;
-}
-
-const char *Abstract_VM_Version::jdk_debug_level() {
-  return DEBUG_LEVEL;
-}
-
-const char *Abstract_VM_Version::printable_jdk_debug_level() {
-  // Debug level is not printed for "release" builds
-  return strcmp(DEBUG_LEVEL, "release") == 0 ? "" : DEBUG_LEVEL " ";
-}
-
-unsigned int Abstract_VM_Version::jvm_version() {
-  return ((Abstract_VM_Version::vm_major_version() & 0xFF) << 24) |
-         ((Abstract_VM_Version::vm_minor_version() & 0xFF) << 16) |
-         ((Abstract_VM_Version::vm_security_version() & 0xFF) << 8) |
-         (Abstract_VM_Version::vm_build_number() & 0xFF);
-}
-
 void VM_Version_init() {
   VM_Version::initialize();
 
@@ -304,27 +37,3 @@
     os::print_cpu_info(&ls, buf, sizeof(buf));
   }
 }
-
-bool Abstract_VM_Version::print_matching_lines_from_file(const char* filename, outputStream* st, const char* keywords_to_match[]) {
-  char line[500];
-  FILE* fp = fopen(filename, "r");
-  if (fp == NULL) {
-    return false;
-  }
-
-  st->print_cr("Virtualization information:");
-  while (fgets(line, sizeof(line), fp) != NULL) {
-    int i = 0;
-    while (keywords_to_match[i] != NULL) {
-      if (strncmp(line, keywords_to_match[i], strlen(keywords_to_match[i])) == 0) {
-        st->print("%s", line);
-        break;
-      }
-      i++;
-    }
-  }
-  fclose(fp);
-  return true;
-}
-
-
--- a/src/hotspot/share/runtime/vm_version.hpp	Wed Nov 13 17:21:31 2019 -0500
+++ b/src/hotspot/share/runtime/vm_version.hpp	Mon Nov 18 12:40:06 2019 -0500
@@ -25,171 +25,7 @@
 #ifndef SHARE_RUNTIME_VM_VERSION_HPP
 #define SHARE_RUNTIME_VM_VERSION_HPP
 
-#include "memory/allocation.hpp"
-#include "utilities/ostream.hpp"
-#include "utilities/macros.hpp"
-
-typedef enum {
-  NoDetectedVirtualization,
-  XenHVM,
-  KVM,
-  VMWare,
-  HyperV,
-  PowerVM, // on AIX or Linux ppc64(le)
-  PowerFullPartitionMode, // on Linux ppc64(le)
-  PowerKVM
-} VirtualizationType;
-
-// VM_Version provides information about the VM.
-
-class Abstract_VM_Version: AllStatic {
-  friend class VMStructs;
-  friend class JVMCIVMStructs;
-
- protected:
-  static const char*  _s_vm_release;
-  static const char*  _s_internal_vm_info_string;
-
-  // CPU feature flags.
-  static uint64_t _features;
-  static const char* _features_string;
-
-  // These are set by machine-dependent initializations
-  static bool         _supports_cx8;
-  static bool         _supports_atomic_getset4;
-  static bool         _supports_atomic_getset8;
-  static bool         _supports_atomic_getadd4;
-  static bool         _supports_atomic_getadd8;
-  static unsigned int _logical_processors_per_package;
-  static unsigned int _L1_data_cache_line_size;
-  static int          _vm_major_version;
-  static int          _vm_minor_version;
-  static int          _vm_security_version;
-  static int          _vm_patch_version;
-  static int          _vm_build_number;
-  static unsigned int _data_cache_line_flush_size;
-
-  static VirtualizationType _detected_virtualization;
-
- public:
-  // Called as part of the runtime services initialization which is
-  // called from the management module initialization (via init_globals())
-  // after argument parsing and attaching of the main thread has
-  // occurred.  Examines a variety of the hardware capabilities of
-  // the platform to determine which features can be used to execute the
-  // program.
-  static void initialize() { }
-
-  // This allows for early initialization of VM_Version information
-  // that may be needed later in the initialization sequence but before
-  // full VM_Version initialization is possible. It can not depend on any
-  // other part of the VM being initialized when called. Platforms that
-  // need to specialize this define VM_Version::early_initialize().
-  static void early_initialize() { }
-
-  // Called to initialize VM variables needing initialization
-  // after command line parsing. Platforms that need to specialize
-  // this should define VM_Version::init_before_ergo().
-  static void init_before_ergo() {}
-
-  // Name
-  static const char* vm_name();
-  // Vendor
-  static const char* vm_vendor();
-  // VM version information string printed by launcher (java -version)
-  static const char* vm_info_string();
-  static const char* vm_release();
-  static const char* vm_platform_string();
-  static const char* vm_build_user();
-
-  static int vm_major_version()               { return _vm_major_version; }
-  static int vm_minor_version()               { return _vm_minor_version; }
-  static int vm_security_version()            { return _vm_security_version; }
-  static int vm_patch_version()               { return _vm_patch_version; }
-  static int vm_build_number()                { return _vm_build_number; }
-
-  // Gets the jvm_version_info.jvm_version defined in jvm.h
-  static unsigned int jvm_version();
-
-  // Internal version providing additional build information
-  static const char* internal_vm_info_string();
-  static const char* jre_release_version();
-  static const char* jdk_debug_level();
-  static const char* printable_jdk_debug_level();
-
-  static uint64_t features() {
-    return _features;
-  }
-
-  static const char* features_string() {
-    return _features_string;
-  }
-
-  static VirtualizationType get_detected_virtualization() {
-    return _detected_virtualization;
-  }
-
-  // platforms that need to specialize this
-  // define VM_Version::print_platform_virtualization_info()
-  static void print_platform_virtualization_info(outputStream*) { }
-
-  // does HW support an 8-byte compare-exchange operation?
-  static bool supports_cx8()  {
-#ifdef SUPPORTS_NATIVE_CX8
-    return true;
-#else
-    return _supports_cx8;
-#endif
-  }
-  // does HW support atomic get-and-set or atomic get-and-add?  Used
-  // to guide intrinsification decisions for Unsafe atomic ops
-  static bool supports_atomic_getset4()  {return _supports_atomic_getset4;}
-  static bool supports_atomic_getset8()  {return _supports_atomic_getset8;}
-  static bool supports_atomic_getadd4()  {return _supports_atomic_getadd4;}
-  static bool supports_atomic_getadd8()  {return _supports_atomic_getadd8;}
-
-  static unsigned int logical_processors_per_package() {
-    return _logical_processors_per_package;
-  }
-
-  static unsigned int L1_data_cache_line_size() {
-    return _L1_data_cache_line_size;
-  }
-
-  // the size in bytes of a data cache line flushed by a flush
-  // operation which should be a power of two or zero if cache line
-  // writeback is not supported by the current os_cpu combination
-  static unsigned int data_cache_line_flush_size() {
-    return _data_cache_line_flush_size;
-  }
-
-  // returns true if and only if cache line writeback is supported
-  static bool supports_data_cache_line_flush() {
-    return _data_cache_line_flush_size != 0;
-  }
-
-  // ARCH specific policy for the BiasedLocking
-  static bool use_biased_locking()  { return true; }
-
-  // Number of page sizes efficiently supported by the hardware.  Most chips now
-  // support two sizes, thus this default implementation.  Processor-specific
-  // subclasses should define new versions to hide this one as needed.  Note
-  // that the O/S may support more sizes, but at most this many are used.
-  static uint page_size_count() { return 2; }
-
-  // Denominator for computing default ParallelGCThreads for machines with
-  // a large number of cores.
-  static uint parallel_worker_threads_denominator() { return 8; }
-
-  // Does this CPU support spin wait instruction?
-  static bool supports_on_spin_wait() { return false; }
-
-  // Does platform support fast class initialization checks for static methods?
-  static bool supports_fast_class_init_checks() { return false; }
-
-  static bool print_matching_lines_from_file(const char* filename, outputStream* st, const char* keywords_to_match[]);
-};
-
+#include "utilities/macros.hpp"  // for CPU_HEADER() macro.
 #include CPU_HEADER(vm_version)
 
 #endif // SHARE_RUNTIME_VM_VERSION_HPP
--- a/src/hotspot/share/services/virtualMemoryTracker.cpp	Wed Nov 13 17:21:31 2019 -0500
+++ b/src/hotspot/share/services/virtualMemoryTracker.cpp	Mon Nov 18 12:40:06 2019 -0500
@@ -45,8 +45,8 @@
   if (ThreadStackTracker::track_as_vm()) {
     // Snapshot current thread stacks
     VirtualMemoryTracker::snapshot_thread_stacks();
-    as_snapshot()->copy_to(s);
   }
+  as_snapshot()->copy_to(s);
 }
 
 SortedLinkedList<ReservedMemoryRegion, compare_reserved_region_base>* VirtualMemoryTracker::_reserved_regions;
--- a/src/hotspot/share/utilities/hashtable.cpp	Wed Nov 13 17:21:31 2019 -0500
+++ b/src/hotspot/share/utilities/hashtable.cpp	Mon Nov 18 12:40:06 2019 -0500
@@ -61,7 +61,7 @@
 
   if (entry == NULL) {
     if (_first_free_entry + _entry_size >= _end_block) {
-      int block_size = MIN2(512, MAX2((int)_table_size / 2, (int)_number_of_entries));
+      int block_size = MIN2(512, MAX3(2, (int)_table_size / 2, (int)_number_of_entries));
       int len = _entry_size * block_size;
       len = 1 << log2_int(len); // round down to power of 2
       assert(len >= _entry_size, "");
--- a/src/java.base/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java	Wed Nov 13 17:21:31 2019 -0500
+++ b/src/java.base/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java	Mon Nov 18 12:40:06 2019 -0500
@@ -1168,7 +1168,7 @@
       *  } catch (Throwable e) {
       *      if (!a2.isInstance(e)) throw e;
       *      return a3.invokeBasic(ex, a6, a7);
-      *  }}
+      *  }}</pre></blockquote>
       */
     private Name emitGuardWithCatch(int pos) {
         Name args    = lambdaForm.names[pos];
@@ -1263,26 +1263,27 @@
      *                      load target                             (-- target)
      *                      load args                               (-- args... target)
      *                      INVOKEVIRTUAL MethodHandle.invokeBasic  (depends)
-     * FINALLY_NORMAL:      (-- r)
-     *                      load cleanup                            (-- cleanup r)
-     *                      SWAP                                    (-- r cleanup)
-     *                      ACONST_NULL                             (-- t r cleanup)
-     *                      SWAP                                    (-- r t cleanup)
-     *                      load args                               (-- args... r t cleanup)
-     *                      INVOKEVIRTUAL MethodHandle.invokeBasic  (-- r)
+     * FINALLY_NORMAL:      (-- r_2nd* r)
+     *                      store returned value                    (--)
+     *                      load cleanup                            (-- cleanup)
+     *                      ACONST_NULL                             (-- t cleanup)
+     *                      load returned value                     (-- r_2nd* r t cleanup)
+     *                      load args                               (-- args... r_2nd* r t cleanup)
+     *                      INVOKEVIRTUAL MethodHandle.invokeBasic  (-- r_2nd* r)
      *                      GOTO DONE
      * CATCH:               (-- t)
      *                      DUP                                     (-- t t)
      * FINALLY_EXCEPTIONAL: (-- t t)
      *                      load cleanup                            (-- cleanup t t)
      *                      SWAP                                    (-- t cleanup t)
-     *                      load default for r                      (-- r t cleanup t)
-     *                      load args                               (-- args... r t cleanup t)
-     *                      INVOKEVIRTUAL MethodHandle.invokeBasic  (-- r t)
-     *                      POP                                     (-- t)
+     *                      load default for r                      (-- r_2nd* r t cleanup t)
+     *                      load args                               (-- args... r_2nd* r t cleanup t)
+     *                      INVOKEVIRTUAL MethodHandle.invokeBasic  (-- r_2nd* r t)
+     *                      POP/POP2*                               (-- t)
      *                      ATHROW
      * DONE:                (-- r)
      * }</pre></blockquote>
+     * * = depends on whether the return type takes up 2 stack slots.
      */
     private Name emitTryFinally(int pos) {
         Name args    = lambdaForm.names[pos];
@@ -1295,7 +1296,9 @@
         Label lDone = new Label();
 
         Class<?> returnType = result.function.resolvedHandle().type().returnType();
+        BasicType basicReturnType = BasicType.basicType(returnType);
         boolean isNonVoid = returnType != void.class;
+
         MethodType type = args.function.resolvedHandle().type()
                 .dropParameterTypes(0,1)
                 .changeReturnType(returnType);
@@ -1316,13 +1319,14 @@
         mv.visitLabel(lTo);
 
         // FINALLY_NORMAL:
-        emitPushArgument(invoker, 1); // load cleanup
+        int index = extendLocalsMap(new Class<?>[]{ returnType });
         if (isNonVoid) {
-            mv.visitInsn(Opcodes.SWAP);
+            emitStoreInsn(basicReturnType, index);
         }
+        emitPushArgument(invoker, 1); // load cleanup
         mv.visitInsn(Opcodes.ACONST_NULL);
         if (isNonVoid) {
-            mv.visitInsn(Opcodes.SWAP);
+            emitLoadInsn(basicReturnType, index);
         }
         emitPushArguments(args, 1); // load args (skip 0: method handle)
         mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, MH, "invokeBasic", cleanupDesc, false);
@@ -1341,7 +1345,7 @@
         emitPushArguments(args, 1); // load args (skip 0: method handle)
         mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, MH, "invokeBasic", cleanupDesc, false);
         if (isNonVoid) {
-            mv.visitInsn(Opcodes.POP);
+            emitPopInsn(basicReturnType);
         }
         mv.visitInsn(Opcodes.ATHROW);
 
@@ -1351,6 +1355,24 @@
         return result;
     }
 
+    private void emitPopInsn(BasicType type) {
+        mv.visitInsn(popInsnOpcode(type));
+    }
+
+    private static int popInsnOpcode(BasicType type) {
+        switch (type) {
+            case I_TYPE:
+            case F_TYPE:
+            case L_TYPE:
+                return Opcodes.POP;
+            case J_TYPE:
+            case D_TYPE:
+                return Opcodes.POP2;
+            default:
+                throw new InternalError("unknown type: " + type);
+        }
+    }
+
     /**
      * Emit bytecode for the loop idiom.
      * <p>
--- a/src/java.base/share/classes/java/net/DatagramSocket.java	Wed Nov 13 17:21:31 2019 -0500
+++ b/src/java.base/share/classes/java/net/DatagramSocket.java	Mon Nov 18 12:40:06 2019 -0500
@@ -646,7 +646,9 @@
      *             if this socket has an associated channel,
      *             and the channel is in non-blocking mode.
      * @throws     IllegalArgumentException if the socket is connected,
-     *             and connected address and packet address differ.
+     *             and connected address and packet address differ, or
+     *             if the socket is not connected and the packet address
+     *             is not set.
      *
      * @see        java.net.DatagramPacket
      * @see        SecurityManager#checkMulticast(InetAddress)
@@ -655,12 +657,15 @@
      * @spec JSR-51
      */
     public void send(DatagramPacket p) throws IOException  {
-        InetAddress packetAddress = null;
         synchronized (p) {
             if (isClosed())
                 throw new SocketException("Socket is closed");
-            checkAddress (p.getAddress(), "send");
+            InetAddress packetAddress = p.getAddress();
+            checkAddress (packetAddress, "send");
             if (connectState == ST_NOT_CONNECTED) {
+                if (packetAddress == null) {
+                    throw new IllegalArgumentException("Address not set");
+                }
                 // check the address is ok with the security manager on every send.
                 SecurityManager security = System.getSecurityManager();
 
@@ -669,16 +674,15 @@
                 // while you are trying to send the packet for example
                 // after the security check but before the send.
                 if (security != null) {
-                    if (p.getAddress().isMulticastAddress()) {
-                        security.checkMulticast(p.getAddress());
+                    if (packetAddress.isMulticastAddress()) {
+                        security.checkMulticast(packetAddress);
                     } else {
-                        security.checkConnect(p.getAddress().getHostAddress(),
+                        security.checkConnect(packetAddress.getHostAddress(),
                                               p.getPort());
                     }
                 }
             } else {
                 // we're connected
-                packetAddress = p.getAddress();
                 if (packetAddress == null) {
                     p.setAddress(connectedAddress);
                     p.setPort(connectedPort);
--- a/src/java.base/share/classes/java/net/MulticastSocket.java	Wed Nov 13 17:21:31 2019 -0500
+++ b/src/java.base/share/classes/java/net/MulticastSocket.java	Mon Nov 18 12:40:06 2019 -0500
@@ -29,6 +29,7 @@
 import java.util.Collections;
 import java.util.Enumeration;
 import java.util.Set;
+import java.net.PortUnreachableException;
 
 /**
  * The multicast datagram socket class is useful for sending
@@ -643,11 +644,19 @@
      * @param ttl optional time to live for multicast packet.
      * default ttl is 1.
      *
-     * @throws    IOException is raised if an error occurs i.e
-     * error while setting ttl.
+     * @throws     IOException is raised if an error occurs i.e
+     *             error while setting ttl.
      * @throws     SecurityException  if a security manager exists and its
      *             {@code checkMulticast} or {@code checkConnect}
      *             method doesn't allow the send.
+     * @throws     PortUnreachableException may be thrown if the socket is connected
+     *             to a currently unreachable destination. Note, there is no
+     *             guarantee that the exception will be thrown.
+     * @throws     IllegalArgumentException if the socket is connected,
+     *             and connected address and packet address differ, or
+     *             if the socket is not connected and the packet address
+     *             is not set.
+     *
      *
      * @deprecated Use the following code or its equivalent instead:
      *  ......
@@ -667,32 +676,34 @@
         throws IOException {
             if (isClosed())
                 throw new SocketException("Socket is closed");
-            checkAddress(p.getAddress(), "send");
             synchronized(ttlLock) {
                 synchronized(p) {
+                    InetAddress packetAddress = p.getAddress();
+                    checkAddress(packetAddress, "send");
                     if (connectState == ST_NOT_CONNECTED) {
+                        if (packetAddress == null) {
+                            throw new IllegalArgumentException("Address not set");
+                        }
                         // Security manager makes sure that the multicast address
                         // is allowed one and that the ttl used is less
                         // than the allowed maxttl.
                         SecurityManager security = System.getSecurityManager();
                         if (security != null) {
-                            if (p.getAddress().isMulticastAddress()) {
-                                security.checkMulticast(p.getAddress(), ttl);
+                            if (packetAddress.isMulticastAddress()) {
+                                security.checkMulticast(packetAddress, ttl);
                             } else {
-                                security.checkConnect(p.getAddress().getHostAddress(),
+                                security.checkConnect(packetAddress.getHostAddress(),
                                                       p.getPort());
                             }
                         }
                     } else {
                         // we're connected
-                        InetAddress packetAddress = null;
-                        packetAddress = p.getAddress();
                         if (packetAddress == null) {
                             p.setAddress(connectedAddress);
                             p.setPort(connectedPort);
                         } else if ((!packetAddress.equals(connectedAddress)) ||
                                    p.getPort() != connectedPort) {
-                            throw new SecurityException("connected address and packet address" +
+                            throw new IllegalArgumentException("connected address and packet address" +
                                                         " differ");
                         }
                     }
--- a/src/java.base/share/classes/java/nio/channels/DatagramChannel.java	Wed Nov 13 17:21:31 2019 -0500
+++ b/src/java.base/share/classes/java/nio/channels/DatagramChannel.java	Mon Nov 18 12:40:06 2019 -0500
@@ -255,8 +255,11 @@
      * <p> The channel's socket is configured so that it only receives
      * datagrams from, and sends datagrams to, the given remote <i>peer</i>
      * address.  Once connected, datagrams may not be received from or sent to
-     * any other address.  A datagram socket remains connected until it is
-     * explicitly disconnected or until it is closed.
+     * any other address.  Datagrams in the channel's {@linkplain
+     * java.net.StandardSocketOptions#SO_RCVBUF socket receive buffer}, which
+     * have not been {@linkplain #receive(ByteBuffer) received} before invoking
+     * this method, may be discarded.  The channel's socket remains connected
+     * until it is explicitly disconnected or until it is closed.
      *
      * <p> This method performs exactly the same security checks as the {@link
      * java.net.DatagramSocket#connect connect} method of the {@link
@@ -270,12 +273,13 @@
      * should be taken to ensure that a connected datagram channel is not shared
      * with untrusted code.
      *
-     * <p> This method may be invoked at any time.  It will not have any effect
-     * on read or write operations that are already in progress at the moment
-     * that it is invoked. If this channel's socket is not bound then this method
-     * will first cause the socket to be bound to an address that is assigned
+     * <p> This method may be invoked at any time.  If another thread has
+     * already initiated a read or write operation upon this channel, then an
+     * invocation of this method will block until any such operation is
+     * complete.  If this channel's socket is not bound then this method will
+     * first cause the socket to be bound to an address that is assigned
      * automatically, as if invoking the {@link #bind bind} method with a
-     * parameter of {@code null}. </p>
+     * parameter of {@code null}.  </p>
      *
      * @param  remote
      *         The remote address to which this channel is to be connected
@@ -323,9 +327,10 @@
      * from, and sends datagrams to, any remote address so long as the security
      * manager, if installed, permits it.
      *
-     * <p> This method may be invoked at any time.  It will not have any effect
-     * on read or write operations that are already in progress at the moment
-     * that it is invoked.
+     * <p> This method may be invoked at any time.  If another thread has
+     * already initiated a read or write operation upon this channel, then an
+     * invocation of this method will block until any such operation is
+     * complete.
      *
      * <p> If this channel's socket is not connected, or if the channel is
      * closed, then invoking this method has no effect.  </p>
--- a/src/java.base/share/classes/sun/security/tools/keytool/Main.java	Wed Nov 13 17:21:31 2019 -0500
+++ b/src/java.base/share/classes/sun/security/tools/keytool/Main.java	Mon Nov 18 12:40:06 2019 -0500
@@ -1151,17 +1151,15 @@
             }
         } else if (command == GENKEYPAIR) {
             if (keyAlgName == null) {
-                keyAlgName = "DSA";
-                weakWarnings.add(String.format(rb.getString(
-                        "keyalg.option.1.missing.warning"), keyAlgName));
+                throw new Exception(rb.getString(
+                        "keyalg.option.missing.error"));
             }
             doGenKeyPair(alias, dname, keyAlgName, keysize, groupName, sigAlgName);
             kssave = true;
         } else if (command == GENSECKEY) {
             if (keyAlgName == null) {
-                keyAlgName = "DES";
-                weakWarnings.add(String.format(rb.getString(
-                        "keyalg.option.1.missing.warning"), keyAlgName));
+                throw new Exception(rb.getString(
+                        "keyalg.option.missing.error"));
             }
             doGenSecretKey(alias, keyAlgName, keysize);
             kssave = true;
--- a/src/java.base/share/classes/sun/security/tools/keytool/Resources.java	Wed Nov 13 17:21:31 2019 -0500
+++ b/src/java.base/share/classes/sun/security/tools/keytool/Resources.java	Mon Nov 18 12:40:06 2019 -0500
@@ -474,7 +474,7 @@
         {"migrate.keystore.warning", "Migrated \"%1$s\" to %4$s. The %2$s keystore is backed up as \"%3$s\"."},
         {"backup.keystore.warning", "The original keystore \"%1$s\" is backed up as \"%3$s\"..."},
         {"importing.keystore.status", "Importing keystore %1$s to %2$s..."},
-        {"keyalg.option.1.missing.warning", "No -keyalg option. The default key algorithm (%s) is a legacy algorithm and is no longer recommended. In a subsequent release of the JDK, the default will be removed and the -keyalg option must be specified."},
+        {"keyalg.option.missing.error", "The -keyalg option must be specified."},
 
         {"showinfo.no.option", "Missing option for -showinfo. Try \"keytool -showinfo -tls\"."},
     };
--- a/src/java.compiler/share/classes/javax/lang/model/SourceVersion.java	Wed Nov 13 17:21:31 2019 -0500
+++ b/src/java.compiler/share/classes/javax/lang/model/SourceVersion.java	Mon Nov 18 12:40:06 2019 -0500
@@ -58,9 +58,9 @@
      *   9: modules, small cleanups to 1.7 and 1.8 changes
      *  10: local-variable type inference (var)
      *  11: local-variable syntax for lambda parameters
-     *  12: no changes (switch expressions were in preview)
+     *  12: no changes (switch expressions in preview)
      *  13: no changes (switch expressions and text blocks in preview)
-     *  14: TBD
+     *  14: switch expressions
      */
 
     /**
@@ -199,6 +199,8 @@
      * The version recognized by the Java Platform, Standard Edition
      * 14.
      *
+     * Additions in this release include switch expressions.
+     *
      * @since 14
      */
      RELEASE_14;
--- a/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/trax/DOM2TO.java	Wed Nov 13 17:21:31 2019 -0500
+++ b/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/trax/DOM2TO.java	Mon Nov 18 12:40:06 2019 -0500
@@ -1,6 +1,5 @@
 /*
- * reserved comment block
- * DO NOT REMOVE OR ALTER!
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
  */
 /*
  * Licensed to the Apache Software Foundation (ASF) under one or more
@@ -42,6 +41,7 @@
 /**
  * @author Santiago Pericas-Geertsen
  * @author Sunitha Reddy
+ * @LastModified: Nov 2019
  */
 public class DOM2TO implements XMLReader, Locator2 {
 
@@ -171,7 +171,7 @@
             }
 
             // Process all non-namespace attributes next
-            NamespaceMappings nm = new NamespaceMappings();
+            NamespaceMappings nm = null;
             for (int i = 0; i < length; i++) {
                 final Node attr = map.item(i);
                 final String qnameAttr = attr.getNodeName();
@@ -187,6 +187,7 @@
                         // For attributes not given an prefix explictly
                         // but having a namespace uri we need
                         // to explicitly generate the prefix
+                        if (nm == null) nm = new NamespaceMappings();
                         String newPrefix = nm.lookupPrefix(uriAttr);
                         if (newPrefix == null)
                             newPrefix = nm.generateNextPrefix();
--- a/src/java.xml/share/legal/xalan.md	Wed Nov 13 17:21:31 2019 -0500
+++ b/src/java.xml/share/legal/xalan.md	Mon Nov 18 12:40:06 2019 -0500
@@ -231,4 +231,25 @@
 See the License for the specific language governing permissions and
 limitations under the License.
 
+
+JLEX COPYRIGHT NOTICE, LICENSE AND DISCLAIMER.
+Copyright 1996-2003 by Elliot Joel Berk and C. Scott Ananian
+Permission to use, copy, modify, and distribute this software and 
+its documentation for any purpose and without fee is hereby granted, 
+provided that the above copyright notice appear in all copies and that 
+both the copyright notice and this permission notice and warranty 
+disclaimer appear in supporting documentation, and that the name of 
+the authors or their employers not be used in advertising or publicity 
+pertaining to distribution of the software without specific, written 
+prior permission.
+The authors and their employers disclaim all warranties with regard to 
+this software, including all implied warranties of merchantability and 
+fitness. In no event shall the authors or their employers be liable for 
+any special, indirect or consequential damages or any damages whatsoever 
+resulting from loss of use, data or profits, whether in an action of 
+contract, negligence or other tortious action, arising out of or in 
+connection with the use or performance of this software.The portions of 
+JLex output which are hard-coded into the JLex source code are (naturally) 
+covered by this same license.
+
 </pre>
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Source.java	Wed Nov 13 17:21:31 2019 -0500
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Source.java	Mon Nov 18 12:40:06 2019 -0500
@@ -84,7 +84,7 @@
     /** 1.11 local-variable syntax for lambda parameters */
     JDK11("11"),
 
-    /** 12, no language features; switch expression were in preview */
+    /** 12, no language features; switch expression in preview */
     JDK12("12"),
 
     /**
@@ -94,8 +94,7 @@
     JDK13("13"),
 
     /**
-     * 14 covers the to be determined language features that will be
-     * added in JDK 14.
+     * 14, switch expressions
      */
     JDK14("14");
 
--- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/memory/FileMapInfo.java	Wed Nov 13 17:21:31 2019 -0500
+++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/memory/FileMapInfo.java	Mon Nov 18 12:40:06 2019 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -70,7 +70,7 @@
 
     // SpaceInfo
     type = db.lookupType("CDSFileMapRegion");
-    long mdRegionBaseAddressOffset = type.getField("_addr._base").getOffset();
+    long mdRegionBaseAddressOffset = type.getField("_mapped_base").getOffset();
     mdRegionBaseAddress = (mdSpaceValue.addOffsetTo(mdRegionBaseAddressOffset)).getAddressAt(0);
     long mdRegionSizeOffset = type.getField("_used").getOffset();
     long mdRegionSize = (mdSpaceValue.addOffsetTo(mdRegionSizeOffset)).getAddressAt(0).asLongValue();
--- a/src/jdk.hotspot.agent/share/native/libsaproc/ps_core_common.c	Wed Nov 13 17:21:31 2019 -0500
+++ b/src/jdk.hotspot.agent/share/native/libsaproc/ps_core_common.c	Mon Nov 18 12:40:06 2019 -0500
@@ -261,6 +261,7 @@
 // mangled name of Arguments::SharedArchivePath
 #define SHARED_ARCHIVE_PATH_SYM "_ZN9Arguments17SharedArchivePathE"
 #define USE_SHARED_SPACES_SYM "UseSharedSpaces"
+#define SHARED_BASE_ADDRESS_SYM "SharedBaseAddress"
 #define LIBJVM_NAME "/libjvm.so"
 #endif
 
@@ -268,6 +269,7 @@
 // mangled name of Arguments::SharedArchivePath
 #define SHARED_ARCHIVE_PATH_SYM "__ZN9Arguments17SharedArchivePathE"
 #define USE_SHARED_SPACES_SYM "_UseSharedSpaces"
+#define SHARED_BASE_ADDRESS_SYM "_SharedBaseAddress"
 #define LIBJVM_NAME "/libjvm.dylib"
 #endif
 
@@ -281,7 +283,8 @@
       char classes_jsa[PATH_MAX];
       CDSFileMapHeaderBase header;
       int fd = -1;
-      uintptr_t base = 0, useSharedSpacesAddr = 0;
+      uintptr_t useSharedSpacesAddr = 0;
+      uintptr_t sharedBaseAddressAddr = 0, sharedBaseAddress = 0;
       uintptr_t sharedArchivePathAddrAddr = 0, sharedArchivePathAddr = 0;
       jboolean useSharedSpaces = 0;
       int m;
@@ -308,6 +311,17 @@
         return true;
       }
 
+      sharedBaseAddressAddr = lookup_symbol(ph, jvm_name, SHARED_BASE_ADDRESS_SYM);
+      if (sharedBaseAddressAddr == 0) {
+        print_debug("can't lookup 'SharedBaseAddress' flag\n");
+        return false;
+      }
+
+      if (read_pointer(ph, sharedBaseAddressAddr, &sharedBaseAddress) != true) {
+        print_debug("can't read the value of 'SharedBaseAddress' flag\n");
+        return false;
+      }
+
       sharedArchivePathAddrAddr = lookup_symbol(ph, jvm_name, SHARED_ARCHIVE_PATH_SYM);
       if (sharedArchivePathAddrAddr == 0) {
         print_debug("can't lookup shared archive path symbol\n");
@@ -363,16 +377,19 @@
       ph->core->classes_jsa_fd = fd;
       // add read-only maps from classes.jsa to the list of maps
       for (m = 0; m < NUM_CDS_REGIONS; m++) {
-        if (header._space[m]._read_only) {
+        if (header._space[m]._read_only &&
+            !header._space[m]._is_heap_region &&
+            !header._space[m]._is_bitmap_region) {
           // With *some* linux versions, the core file doesn't include read-only mmap'ed
           // files regions, so let's add them here. This is harmless if the core file also
           // include these regions.
-          base = (uintptr_t) header._space[m]._addr._base;
+          uintptr_t base = sharedBaseAddress + (uintptr_t) header._space[m]._mapping_offset;
+          size_t size = header._space[m]._used;
           // no need to worry about the fractional pages at-the-end.
           // possible fractional pages are handled by core_read_data.
           add_class_share_map_info(ph, (off_t) header._space[m]._file_offset,
-                                   base, (size_t) header._space[m]._used);
-          print_debug("added a share archive map at 0x%lx\n", base);
+                                   base, size);
+          print_debug("added a share archive map [%d] at 0x%lx (size 0x%lx bytes)\n", m, base, size);
         }
       }
       return true;
--- a/src/jdk.hotspot.agent/solaris/native/libsaproc/saproc.cpp	Wed Nov 13 17:21:31 2019 -0500
+++ b/src/jdk.hotspot.agent/solaris/native/libsaproc/saproc.cpp	Mon Nov 18 12:40:06 2019 -0500
@@ -538,9 +538,11 @@
 }
 
 #define USE_SHARED_SPACES_SYM   "UseSharedSpaces"
+#define SHARED_BASE_ADDRESS_SYM "SharedBaseAddress"
 // mangled symbol name for Arguments::SharedArchivePath
 #define SHARED_ARCHIVE_PATH_SYM "__1cJArgumentsRSharedArchivePath_"
 
+static uintptr_t sharedBaseAddress = 0;
 static int
 init_classsharing_workaround(void *cd, const prmap_t* pmap, const char* obj_name) {
   Debugger* dbg = (Debugger*) cd;
@@ -577,6 +579,19 @@
     return 1;
   }
 
+  psaddr_t sharedBaseAddressAddr = 0;
+  ps_pglobal_lookup(ph, jvm_name, SHARED_ARCHIVE_PATH_SYM, &sharedBaseAddressAddr);
+  if (sharedBaseAddressAddr == 0) {
+    print_debug("can't find symbol 'SharedBaseAddress'\n");
+    THROW_NEW_DEBUGGER_EXCEPTION_("can't find 'SharedBaseAddress' flag\n", 1);
+  }
+
+  sharedBaseAddress = 0;
+  if (read_pointer(ph, sharedBaseAddressAddr, &sharedBaseAddress) != true) {
+    print_debug("can't read the value of 'SharedBaseAddress' flag\n");
+    THROW_NEW_DEBUGGER_EXCEPTION_("can't get SharedBaseAddress from debuggee", 1);
+  }
+
   char classes_jsa[PATH_MAX];
   psaddr_t sharedArchivePathAddrAddr = 0;
   ps_pglobal_lookup(ph, jvm_name, SHARED_ARCHIVE_PATH_SYM, &sharedArchivePathAddrAddr);
@@ -648,9 +663,14 @@
 
   if (_libsaproc_debug) {
     for (int m = 0; m < NUM_CDS_REGIONS; m++) {
-       print_debug("shared file offset %d mapped at 0x%lx, size = %ld, read only? = %d\n",
-          pheader->_space[m]._file_offset, pheader->_space[m]._addr._base,
-          pheader->_space[m]._used, pheader->_space[m]._read_only);
+      if (!pheader->_space[m]._is_heap_region &&
+          !pheader->_space[m]._is_bitmap_region) {
+        jlong mapping_offset = pheader->_space[m]._mapping_offset;
+        jlong baseAddress = mapping_offset + (jlong)sharedBaseAddress;
+        print_debug("shared file offset %d mapped at 0x%lx, size = %ld, read only? = %d\n",
+                    pheader->_space[m]._file_offset, baseAddress,
+                    pheader->_space[m]._used, pheader->_space[m]._read_only);
+      }
     }
   }
 
@@ -1052,11 +1072,14 @@
         // We can skip the non-read-only maps. These are mapped as MAP_PRIVATE
         // and hence will be read by libproc. Besides, the file copy may be
         // stale because the process might have modified those pages.
-        if (pheader->_space[m]._read_only) {
-          jlong baseAddress = (jlong) (uintptr_t) pheader->_space[m]._addr._base;
-          size_t usedSize = pheader->_space[m]._used;
-          if (address >= baseAddress && address < (baseAddress + usedSize)) {
-            // the given address falls in this shared heap area
+        if (pheader->_space[m]._read_only &&
+            !pheader->_space[m]._is_heap_region &&
+            !pheader->_space[m]._is_bitmap_region) {
+         jlong mapping_offset = (jlong) (uintptr_t) pheader->_space[m]._mapping_offset;
+         jlong baseAddress = mapping_offset + (jlong)sharedBaseAddress;
+         size_t usedSize = pheader->_space[m]._used;
+         if (address >= baseAddress && address < (baseAddress + usedSize)) {
+            // the given address falls in this shared metadata area
             print_debug("found shared map at 0x%lx\n", (long) baseAddress);
 
 
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.asm.amd64/src/org/graalvm/compiler/asm/amd64/AMD64BaseAssembler.java	Wed Nov 13 17:21:31 2019 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.asm.amd64/src/org/graalvm/compiler/asm/amd64/AMD64BaseAssembler.java	Mon Nov 18 12:40:06 2019 -0500
@@ -944,7 +944,7 @@
     }
 
     public final boolean vexPrefix(Register dst, Register nds, Register src, AVXSize size, int pp, int mmmmm, int w, int wEvex, boolean checkAVX) {
-        if (isAVX512Register(dst) || isAVX512Register(nds) || isAVX512Register(src)) {
+        if (isAVX512Register(dst) || isAVX512Register(nds) || isAVX512Register(src) || size == AVXSize.ZMM) {
             evexPrefix(dst, Register.None, nds, src, size, pp, mmmmm, wEvex, Z0, B0);
             return true;
         }
@@ -953,7 +953,7 @@
     }
 
     public final boolean vexPrefix(Register dst, Register nds, AMD64Address src, AVXSize size, int pp, int mmmmm, int w, int wEvex, boolean checkAVX) {
-        if (isAVX512Register(dst) || isAVX512Register(nds)) {
+        if (isAVX512Register(dst) || isAVX512Register(nds) || size == AVXSize.ZMM) {
             evexPrefix(dst, Register.None, nds, src, size, pp, mmmmm, wEvex, Z0, B0);
             return true;
         }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.aarch64.test/src/org/graalvm/compiler/core/aarch64/test/AArch64ElideL2ITest.java	Mon Nov 18 12:40:06 2019 -0500
@@ -0,0 +1,142 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2019, Arm Limited. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+
+
+package org.graalvm.compiler.core.aarch64.test;
+
+import org.graalvm.compiler.lir.LIRInstruction;
+import org.graalvm.compiler.lir.aarch64.AArch64ArithmeticOp.BinaryConstOp;
+import org.junit.Test;
+
+import java.util.function.Predicate;
+
+public class AArch64ElideL2ITest extends AArch64MatchRuleTest {
+    private static final Predicate<LIRInstruction> predicate = op -> {
+        if (op instanceof BinaryConstOp && op.name().toUpperCase().equals("AND")) {
+            return true;
+        }
+        return false;
+    };
+
+    public int addWithSingleL2I(long m) {
+        return (int) m + 100;
+    }
+
+    @Test
+    public void testAddWithSingleL2I() {
+        test("addWithSingleL2I", 5L);
+        checkLIR("addWithSingleL2I", predicate, 0);
+    }
+
+    public int addWithTwoL2I(long m, long n) {
+        return (int) m + (int) n;
+    }
+
+    @Test
+    public void testAddWithTwoL2I() {
+        test("addWithTwoL2I", 5L, 0x1FFFFFFFFL);
+        checkLIR("addWithTwoL2I", predicate, 0);
+    }
+
+    public int addWithTwoNarrow(long m, long n) {
+        return (int) m + (short) n;
+    }
+
+    @Test
+    public void testAddWithTwoNarrow() {
+        test("addWithTwoNarrow", 0x80000000L, 6L);
+        checkLIR("addWithTwoNarrow", predicate, 1);
+    }
+
+    public int subSingleL2I(int m, long n) {
+        return m - (int) n;
+    }
+
+    @Test
+    public void testSubSingleL2I() {
+        test("subSingleL2I", 13, 40L);
+        checkLIR("subSingleL2I", predicate, 0);
+    }
+
+    public int shiftWithSingleL2I(long m) {
+        return ((int) m) >> 5;
+    }
+
+    @Test
+    public void testShiftWithSingleL2I() {
+        test("shiftWithSingleL2I", 234L);
+        checkLIR("shiftWithSingleL2I", predicate, 0);
+    }
+
+    public int shiftWithTwoL2I(long m, long n) {
+        return (int) m << (int) n;
+    }
+
+    @Test
+    public void testShiftWithTwoL2I() {
+        test("shiftWithTwoL2I", 234L, 3L);
+        checkLIR("shiftWithTwoL2I", predicate, 0);
+    }
+
+    public long shiftLongWithL2I(long a, int m) {
+        return a + ((m & 0xFFFFFFFFL) << (int) a);
+    }
+
+    @Test
+    public void testShiftLongWithL2I() {
+        test("shiftLongWithL2I", 0xFFFFFFFFL, 123);
+        checkLIR("shiftLongWithL2I", predicate, 1);
+    }
+
+    public int logicWithTwoL2I(long m, long n) {
+        return (int) m | (int) n;
+    }
+
+    @Test
+    public void testLogicWithTwoL2I() {
+        test("logicWithTwoL2I", 234L, 3L);
+        checkLIR("logicWithTwoL2I", predicate, 0);
+    }
+
+    public int negateL2I(long m) {
+        return -((int) m);
+    }
+
+    @Test
+    public void testNegateL2I() {
+        test("negateL2I", 0xFFFFFFFFL);
+        checkLIR("negateL2I", predicate, 0);
+    }
+
+    public int notL2I(long m) {
+        return ~((int) m);
+    }
+
+    @Test
+    public void testNotL2I() {
+        test("notL2I", 0xFFFFFFFFL);
+        checkLIR("notL2I", predicate, 0);
+    }
+}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.aarch64/src/org/graalvm/compiler/core/aarch64/AArch64NodeMatchRules.java	Wed Nov 13 17:21:31 2019 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.aarch64/src/org/graalvm/compiler/core/aarch64/AArch64NodeMatchRules.java	Mon Nov 18 12:40:06 2019 -0500
@@ -38,7 +38,6 @@
 import org.graalvm.compiler.core.gen.NodeMatchRules;
 import org.graalvm.compiler.core.match.ComplexMatchResult;
 import org.graalvm.compiler.core.match.MatchRule;
-import org.graalvm.compiler.graph.Node;
 import org.graalvm.compiler.lir.LIRFrameState;
 import org.graalvm.compiler.lir.LabelRef;
 import org.graalvm.compiler.lir.Variable;
@@ -58,26 +57,33 @@
 import org.graalvm.compiler.nodes.calc.IntegerLessThanNode;
 import org.graalvm.compiler.nodes.calc.LeftShiftNode;
 import org.graalvm.compiler.nodes.calc.MulNode;
+import org.graalvm.compiler.nodes.calc.NarrowNode;
+import org.graalvm.compiler.nodes.calc.NegateNode;
 import org.graalvm.compiler.nodes.calc.NotNode;
 import org.graalvm.compiler.nodes.calc.OrNode;
 import org.graalvm.compiler.nodes.calc.RightShiftNode;
 import org.graalvm.compiler.nodes.calc.SubNode;
+import org.graalvm.compiler.nodes.calc.UnaryNode;
 import org.graalvm.compiler.nodes.calc.UnsignedRightShiftNode;
 import org.graalvm.compiler.nodes.calc.XorNode;
 import org.graalvm.compiler.nodes.memory.Access;
 
 public class AArch64NodeMatchRules extends NodeMatchRules {
-    private static final EconomicMap<Class<? extends Node>, AArch64ArithmeticOp> nodeOpMap;
+    private static final EconomicMap<Class<? extends BinaryNode>, AArch64ArithmeticOp> binaryOpMap;
     private static final EconomicMap<Class<? extends BinaryNode>, AArch64BitFieldOp.BitFieldOpCode> bitFieldOpMap;
     private static final EconomicMap<Class<? extends BinaryNode>, AArch64MacroAssembler.ShiftType> shiftTypeMap;
 
     static {
-        nodeOpMap = EconomicMap.create(Equivalence.IDENTITY, 5);
-        nodeOpMap.put(AddNode.class, AArch64ArithmeticOp.ADD);
-        nodeOpMap.put(SubNode.class, AArch64ArithmeticOp.SUB);
-        nodeOpMap.put(AndNode.class, AArch64ArithmeticOp.AND);
-        nodeOpMap.put(OrNode.class, AArch64ArithmeticOp.OR);
-        nodeOpMap.put(XorNode.class, AArch64ArithmeticOp.XOR);
+        binaryOpMap = EconomicMap.create(Equivalence.IDENTITY, 9);
+        binaryOpMap.put(AddNode.class, AArch64ArithmeticOp.ADD);
+        binaryOpMap.put(SubNode.class, AArch64ArithmeticOp.SUB);
+        binaryOpMap.put(MulNode.class, AArch64ArithmeticOp.MUL);
+        binaryOpMap.put(AndNode.class, AArch64ArithmeticOp.AND);
+        binaryOpMap.put(OrNode.class, AArch64ArithmeticOp.OR);
+        binaryOpMap.put(XorNode.class, AArch64ArithmeticOp.XOR);
+        binaryOpMap.put(LeftShiftNode.class, AArch64ArithmeticOp.SHL);
+        binaryOpMap.put(RightShiftNode.class, AArch64ArithmeticOp.ASHR);
+        binaryOpMap.put(UnsignedRightShiftNode.class, AArch64ArithmeticOp.LSHR);
 
         bitFieldOpMap = EconomicMap.create(Equivalence.IDENTITY, 2);
         bitFieldOpMap.put(UnsignedRightShiftNode.class, AArch64BitFieldOp.BitFieldOpCode.UBFX);
@@ -153,6 +159,10 @@
         };
     }
 
+    private static boolean isNarrowingLongToInt(NarrowNode narrow) {
+        return narrow.getInputBits() == 64 && narrow.getResultBits() == 32;
+    }
+
     @MatchRule("(And (UnsignedRightShift=shift a Constant=b) Constant=c)")
     @MatchRule("(LeftShift=shift (And a Constant=c) Constant=b)")
     public ComplexMatchResult unsignedBitField(BinaryNode shift, ValueNode a, ConstantNode b, ConstantNode c) {
@@ -194,7 +204,7 @@
     @MatchRule("(Sub=binary a (RightShift=shift b Constant))")
     @MatchRule("(Sub=binary a (UnsignedRightShift=shift b Constant))")
     public ComplexMatchResult addSubShift(BinaryNode binary, ValueNode a, BinaryNode shift) {
-        AArch64ArithmeticOp op = nodeOpMap.get(binary.getClass());
+        AArch64ArithmeticOp op = binaryOpMap.get(binary.getClass());
         assert op != null;
         return emitBinaryShift(op, a, shift, false);
     }
@@ -218,7 +228,7 @@
     @MatchRule("(Xor=binary a (Not (RightShift=shift b Constant)))")
     @MatchRule("(Xor=binary a (Not (UnsignedRightShift=shift b Constant)))")
     public ComplexMatchResult logicShift(BinaryNode binary, ValueNode a, BinaryNode shift) {
-        AArch64ArithmeticOp op = nodeOpMap.get(binary.getClass());
+        AArch64ArithmeticOp op = binaryOpMap.get(binary.getClass());
         assert op != null;
         ValueNode operand = binary.getX() == a ? binary.getY() : binary.getX();
         boolean isShiftNot = operand instanceof NotNode;
@@ -252,6 +262,75 @@
                         resultKind, AArch64ArithmeticOp.SMULL, true, operand(a), operand(b));
     }
 
+    @MatchRule("(Add=binary (Narrow=narrow a) (Narrow b))")
+    @MatchRule("(Sub=binary (Narrow=narrow a) (Narrow b))")
+    @MatchRule("(Mul=binary (Narrow=narrow a) (Narrow b))")
+    @MatchRule("(And=binary (Narrow=narrow a) (Narrow b))")
+    @MatchRule("(Or=binary (Narrow=narrow a) (Narrow b))")
+    @MatchRule("(Xor=binary (Narrow=narrow a) (Narrow b))")
+    @MatchRule("(LeftShift=binary (Narrow=narrow a) (Narrow b))")
+    @MatchRule("(RightShift=binary (Narrow=narrow a) (Narrow b))")
+    @MatchRule("(UnsignedRightShift=binary (Narrow=narrow a) (Narrow b))")
+    @MatchRule("(Add=binary a (Narrow=narrow b))")
+    @MatchRule("(Sub=binary a (Narrow=narrow b))")
+    @MatchRule("(Mul=binary a (Narrow=narrow b))")
+    @MatchRule("(And=binary a (Narrow=narrow b))")
+    @MatchRule("(Or=binary a (Narrow=narrow b))")
+    @MatchRule("(Xor=binary a (Narrow=narrow b))")
+    @MatchRule("(LeftShift=binary a (Narrow=narrow b))")
+    @MatchRule("(RightShift=binary a (Narrow=narrow b))")
+    @MatchRule("(UnsignedRightShift=binary a (Narrow=narrow b))")
+    @MatchRule("(Sub=binary (Narrow=narrow a) b)")
+    @MatchRule("(LeftShift=binary (Narrow=narrow a) b)")
+    @MatchRule("(RightShift=binary (Narrow=narrow a) b)")
+    @MatchRule("(UnsignedRightShift=binary (Narrow=narrow a) b)")
+    public ComplexMatchResult elideL2IForBinary(BinaryNode binary, NarrowNode narrow) {
+        assert binary.getStackKind().isNumericInteger();
+
+        ValueNode a = narrow;
+        ValueNode b = binary.getX() == narrow ? binary.getY() : binary.getX();
+        boolean isL2Ia = isNarrowingLongToInt((NarrowNode) a);
+        boolean isL2Ib = (b instanceof NarrowNode) && isNarrowingLongToInt((NarrowNode) b);
+        if (!isL2Ia && !isL2Ib) {
+            return null;
+        }
+        // Get the value of L2I NarrowNode as the src value.
+        ValueNode src1 = isL2Ia ? ((NarrowNode) a).getValue() : a;
+        ValueNode src2 = isL2Ib ? ((NarrowNode) b).getValue() : b;
+
+        AArch64ArithmeticOp op = binaryOpMap.get(binary.getClass());
+        assert op != null;
+        boolean commutative = binary.getNodeClass().isCommutative();
+        LIRKind resultKind = LIRKind.fromJavaKind(gen.target().arch, binary.getStackKind());
+
+        // Must keep the right operator order for un-commutative binary operations.
+        if (a == binary.getX()) {
+            return builder -> getArithmeticLIRGenerator().emitBinary(
+                            resultKind, op, commutative, operand(src1), operand(src2));
+        }
+        return builder -> getArithmeticLIRGenerator().emitBinary(
+                        resultKind, op, commutative, operand(src2), operand(src1));
+    }
+
+    @MatchRule("(Negate=unary (Narrow=narrow value))")
+    @MatchRule("(Not=unary (Narrow=narrow value))")
+    public ComplexMatchResult elideL2IForUnary(UnaryNode unary, NarrowNode narrow) {
+        assert unary.getStackKind().isNumericInteger();
+        if (!isNarrowingLongToInt(narrow)) {
+            return null;
+        }
+
+        AArch64ArithmeticOp op = unary instanceof NegateNode ? AArch64ArithmeticOp.NEG
+                        : AArch64ArithmeticOp.NOT;
+        return builder -> {
+            AllocatableValue input = gen.asAllocatable(operand(narrow.getValue()));
+            LIRKind resultKind = LIRKind.fromJavaKind(gen.target().arch, unary.getStackKind());
+            Variable result = gen.newVariable(resultKind);
+            gen.append(new AArch64ArithmeticOp.UnaryOp(op, result, moveSp(input)));
+            return result;
+        };
+    }
+
     @MatchRule("(Mul (Negate a) b)")
     @MatchRule("(Negate (Mul a b))")
     public ComplexMatchResult multiplyNegate(ValueNode a, ValueNode b) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/spi/ForeignCallLinkage.java	Wed Nov 13 17:21:31 2019 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/spi/ForeignCallLinkage.java	Mon Nov 18 12:40:06 2019 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -73,4 +73,13 @@
      * the VM to be able to inspect the thread's execution state.
      */
     boolean needsDebugInfo();
+
+    /**
+     * Returns true if further cleanup on the float registers is needed after performing the foreign
+     * call. This is critical on AMD64 as there is a performance penalty switching between legacy
+     * SSE and AVX instruction while the upper halves of the xmm registers are not zero.
+     */
+    default boolean needsClearUpperVectorRegisters() {
+        return false;
+    }
 }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/HashMapGetTest.java	Wed Nov 13 17:21:31 2019 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/HashMapGetTest.java	Mon Nov 18 12:40:06 2019 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -52,7 +52,7 @@
         for (IfNode ifNode : lastCompiledGraph.getNodes(IfNode.TYPE)) {
             LogicNode condition = ifNode.condition();
             if (ifNode.getTrueSuccessorProbability() < 0.4 && condition instanceof ObjectEqualsNode) {
-                assertTrue(ifNode.trueSuccessor().next() instanceof ReturnNode, "Expected return.", ifNode.trueSuccessor(), ifNode.trueSuccessor().next());
+                assertTrue(ifNode.trueSuccessor().next() instanceof ReturnNode, "Expected return but got %s (trueSuccessor: %s)", ifNode.trueSuccessor().next(), ifNode.trueSuccessor());
             }
         }
     }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/UnsafeVirtualizationTest.java	Wed Nov 13 17:21:31 2019 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/UnsafeVirtualizationTest.java	Mon Nov 18 12:40:06 2019 -0500
@@ -24,8 +24,7 @@
 
 package org.graalvm.compiler.core.test;
 
-import java.lang.reflect.Field;
-
+import org.graalvm.compiler.core.test.ea.EATestBase.TestClassInt;
 import org.graalvm.compiler.nodes.StructuredGraph;
 import org.graalvm.compiler.nodes.StructuredGraph.AllowAssumptions;
 import org.graalvm.compiler.nodes.spi.CoreProviders;
@@ -39,75 +38,45 @@
 
 public class UnsafeVirtualizationTest extends GraalCompilerTest {
 
-    public static class Base {
-        /*
-         * This padding ensure that the size of the Base class ends up as a multiple of 8, which
-         * makes the first field of the subclass 8-byte aligned.
-         */
-        double padding;
-    }
-
-    public static class A extends Base {
-        int f1;
-        int f2;
-    }
-
-    private static final long AF1Offset;
-    private static final long AF2Offset;
-    static {
-        long o1 = -1;
-        long o2 = -1;
-        try {
-            Field f1 = A.class.getDeclaredField("f1");
-            Field f2 = A.class.getDeclaredField("f2");
-            o1 = UNSAFE.objectFieldOffset(f1);
-            o2 = UNSAFE.objectFieldOffset(f2);
-        } catch (NoSuchFieldException | SecurityException e) {
-            throw new AssertionError(e);
-        }
-        AF1Offset = o1;
-        AF2Offset = o2;
-    }
-
     public static int unsafeSnippet1(double i1) {
-        A a = new A();
-        UNSAFE.putDouble(a, AF1Offset, i1);
-        return UNSAFE.getInt(a, AF1Offset) + UNSAFE.getInt(a, AF2Offset);
+        TestClassInt a = new TestClassInt();
+        UNSAFE.putDouble(a, TestClassInt.fieldOffset1, i1);
+        return UNSAFE.getInt(a, TestClassInt.fieldOffset1) + UNSAFE.getInt(a, TestClassInt.fieldOffset2);
     }
 
     public static long unsafeSnippet2a(int i1) {
-        A a = new A();
-        UNSAFE.putDouble(a, AF1Offset, i1);
-        a.f1 = i1;
-        return UNSAFE.getLong(a, AF1Offset);
+        TestClassInt a = new TestClassInt();
+        UNSAFE.putDouble(a, TestClassInt.fieldOffset1, i1);
+        a.setFirstField(i1);
+        return UNSAFE.getLong(a, TestClassInt.fieldOffset1);
     }
 
     public static long unsafeSnippet2b(int i1) {
-        A a = new A();
-        UNSAFE.putDouble(a, AF1Offset, i1);
-        a.f2 = i1;
-        return UNSAFE.getLong(a, AF1Offset);
+        TestClassInt a = new TestClassInt();
+        UNSAFE.putDouble(a, TestClassInt.fieldOffset1, i1);
+        a.setSecondField(i1);
+        return UNSAFE.getLong(a, TestClassInt.fieldOffset1);
     }
 
     public static long unsafeSnippet3a(int i1) {
-        A a = new A();
-        UNSAFE.putDouble(a, AF1Offset, i1);
-        UNSAFE.putInt(a, AF1Offset, i1);
-        return UNSAFE.getLong(a, AF1Offset);
+        TestClassInt a = new TestClassInt();
+        UNSAFE.putDouble(a, TestClassInt.fieldOffset1, i1);
+        UNSAFE.putInt(a, TestClassInt.fieldOffset1, i1);
+        return UNSAFE.getLong(a, TestClassInt.fieldOffset1);
     }
 
     public static long unsafeSnippet3b(int i1) {
-        A a = new A();
-        UNSAFE.putDouble(a, AF1Offset, i1);
-        UNSAFE.putInt(a, AF2Offset, i1);
-        return UNSAFE.getLong(a, AF1Offset);
+        TestClassInt a = new TestClassInt();
+        UNSAFE.putDouble(a, TestClassInt.fieldOffset1, i1);
+        UNSAFE.putInt(a, TestClassInt.fieldOffset2, i1);
+        return UNSAFE.getLong(a, TestClassInt.fieldOffset1);
     }
 
     public static int unsafeSnippet4(double i1) {
-        A a = new A();
-        UNSAFE.putDouble(a, AF1Offset, i1);
-        UNSAFE.putDouble(a, AF1Offset, i1);
-        return UNSAFE.getInt(a, AF1Offset) + UNSAFE.getInt(a, AF2Offset);
+        TestClassInt a = new TestClassInt();
+        UNSAFE.putDouble(a, TestClassInt.fieldOffset1, i1);
+        UNSAFE.putDouble(a, TestClassInt.fieldOffset1, i1);
+        return UNSAFE.getInt(a, TestClassInt.fieldOffset1) + UNSAFE.getInt(a, TestClassInt.fieldOffset2);
     }
 
     @Test
@@ -141,7 +110,7 @@
     }
 
     public void testPartialEscapeReadElimination(String snippet, boolean canonicalizeBefore, Object... args) {
-        assert AF1Offset % 8 == 0 : "First of the two int-fields must be 8-byte aligned";
+        assert TestClassInt.fieldOffset1 % 8 == 0 : "First of the two int-fields must be 8-byte aligned";
 
         ResolvedJavaMethod method = getResolvedJavaMethod(snippet);
         StructuredGraph graph = parseEager(snippet, AllowAssumptions.NO);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/ea/EATestBase.java	Wed Nov 13 17:21:31 2019 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/ea/EATestBase.java	Mon Nov 18 12:40:06 2019 -0500
@@ -87,6 +87,46 @@
         public int hashCode() {
             return x + 13 * y;
         }
+
+        public static final long fieldOffset1;
+        public static final long fieldOffset2;
+        public static final boolean firstFieldIsX;
+
+        static {
+            try {
+                long localFieldOffset1 = UNSAFE.objectFieldOffset(EATestBase.TestClassInt.class.getField("x"));
+                // Make the fields 8 byte aligned (Required for testing setLong on Architectures
+                // which does not support unaligned memory access
+                if (localFieldOffset1 % 8 == 0) {
+                    fieldOffset1 = localFieldOffset1;
+                    fieldOffset2 = UNSAFE.objectFieldOffset(EATestBase.TestClassInt.class.getField("y"));
+                    firstFieldIsX = true;
+                } else {
+                    fieldOffset1 = UNSAFE.objectFieldOffset(EATestBase.TestClassInt.class.getField("y"));
+                    fieldOffset2 = UNSAFE.objectFieldOffset(EATestBase.TestClassInt.class.getField("z"));
+                    firstFieldIsX = false;
+                }
+                assert fieldOffset2 == fieldOffset1 + 4;
+            } catch (Exception e) {
+                throw new RuntimeException(e);
+            }
+        }
+
+        public void setFirstField(int v) {
+            if (firstFieldIsX) {
+                x = v;
+            } else {
+                y = v;
+            }
+        }
+
+        public void setSecondField(int v) {
+            if (firstFieldIsX) {
+                y = v;
+            } else {
+                z = v;
+            }
+        }
     }
 
     public static class TestClassObject {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/ea/UnsafeEATest.java	Wed Nov 13 17:21:31 2019 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/ea/UnsafeEATest.java	Mon Nov 18 12:40:06 2019 -0500
@@ -48,27 +48,6 @@
 
     public static int zero = 0;
 
-    private static final long fieldOffset1;
-    private static final long fieldOffset2;
-
-    static {
-        try {
-            long localFieldOffset1 = UNSAFE.objectFieldOffset(TestClassInt.class.getField("x"));
-            // Make the fields 8 byte aligned (Required for testing setLong on Architectures which
-            // does not support unaligned memory access
-            if (localFieldOffset1 % 8 == 0) {
-                fieldOffset1 = localFieldOffset1;
-                fieldOffset2 = UNSAFE.objectFieldOffset(TestClassInt.class.getField("y"));
-            } else {
-                fieldOffset1 = UNSAFE.objectFieldOffset(TestClassInt.class.getField("y"));
-                fieldOffset2 = UNSAFE.objectFieldOffset(TestClassInt.class.getField("z"));
-            }
-            assert fieldOffset2 == fieldOffset1 + 4;
-        } catch (Exception e) {
-            throw new RuntimeException(e);
-        }
-    }
-
     @Override
     protected void testEscapeAnalysis(String snippet, JavaConstant expectedConstantResult, boolean iterativeEscapeAnalysis) {
         // Exercise both a graph containing UnsafeAccessNodes and one which has been possibly been
@@ -134,8 +113,8 @@
 
     public static int testSimpleIntSnippet() {
         TestClassInt x = new TestClassInt();
-        UNSAFE.putInt(x, fieldOffset1, 101);
-        return UNSAFE.getInt(x, fieldOffset1);
+        UNSAFE.putInt(x, TestClassInt.fieldOffset1, 101);
+        return UNSAFE.getInt(x, TestClassInt.fieldOffset1);
     }
 
     @Test
@@ -145,7 +124,7 @@
 
     public static TestClassInt testMaterializedIntSnippet() {
         TestClassInt x = new TestClassInt();
-        UNSAFE.putInt(x, fieldOffset1, 101);
+        UNSAFE.putInt(x, TestClassInt.fieldOffset1, 101);
         return x;
     }
 
@@ -156,8 +135,8 @@
 
     public static double testSimpleDoubleSnippet() {
         TestClassInt x = new TestClassInt();
-        UNSAFE.putDouble(x, fieldOffset1, 10.1);
-        return UNSAFE.getDouble(x, fieldOffset1);
+        UNSAFE.putDouble(x, TestClassInt.fieldOffset1, 10.1);
+        return UNSAFE.getDouble(x, TestClassInt.fieldOffset1);
     }
 
     @Test
@@ -167,9 +146,9 @@
 
     public static int testSimpleDoubleOverwriteWithIntSnippet() {
         TestClassInt x = new TestClassInt();
-        UNSAFE.putDouble(x, fieldOffset1, 10.1);
-        UNSAFE.putInt(x, fieldOffset1, 10);
-        return UNSAFE.getInt(x, fieldOffset1);
+        UNSAFE.putDouble(x, TestClassInt.fieldOffset1, 10.1);
+        UNSAFE.putInt(x, TestClassInt.fieldOffset1, 10);
+        return UNSAFE.getInt(x, TestClassInt.fieldOffset1);
     }
 
     @Test
@@ -183,9 +162,9 @@
 
     public static int testSimpleDoubleOverwriteWithSecondIntSnippet() {
         TestClassInt x = new TestClassInt();
-        UNSAFE.putDouble(x, fieldOffset1, 10.1);
-        UNSAFE.putInt(x, fieldOffset1, 10);
-        return UNSAFE.getInt(x, fieldOffset2);
+        UNSAFE.putDouble(x, TestClassInt.fieldOffset1, 10.1);
+        UNSAFE.putInt(x, TestClassInt.fieldOffset1, 10);
+        return UNSAFE.getInt(x, TestClassInt.fieldOffset2);
     }
 
     @Test
@@ -199,9 +178,9 @@
 
     public static int testSimpleDoubleOverwriteWithFirstIntSnippet() {
         TestClassInt x = new TestClassInt();
-        UNSAFE.putDouble(x, fieldOffset1, 10.1);
-        UNSAFE.putInt(x, fieldOffset2, 10);
-        return UNSAFE.getInt(x, fieldOffset1);
+        UNSAFE.putDouble(x, TestClassInt.fieldOffset1, 10.1);
+        UNSAFE.putInt(x, TestClassInt.fieldOffset2, 10);
+        return UNSAFE.getInt(x, TestClassInt.fieldOffset1);
     }
 
     @Test
@@ -215,9 +194,9 @@
 
     public static int testSimpleLongOverwriteWithSecondIntSnippet() {
         TestClassInt x = new TestClassInt();
-        UNSAFE.putLong(x, fieldOffset1, 0x1122334455667788L);
-        UNSAFE.putInt(x, fieldOffset1, 10);
-        return UNSAFE.getInt(x, fieldOffset2);
+        UNSAFE.putLong(x, TestClassInt.fieldOffset1, 0x1122334455667788L);
+        UNSAFE.putInt(x, TestClassInt.fieldOffset1, 10);
+        return UNSAFE.getInt(x, TestClassInt.fieldOffset2);
     }
 
     @Test
@@ -231,9 +210,9 @@
 
     public static int testSimpleLongOverwriteWithFirstIntSnippet() {
         TestClassInt x = new TestClassInt();
-        UNSAFE.putLong(x, fieldOffset1, 0x1122334455667788L);
-        UNSAFE.putInt(x, fieldOffset2, 10);
-        return UNSAFE.getInt(x, fieldOffset1);
+        UNSAFE.putLong(x, TestClassInt.fieldOffset1, 0x1122334455667788L);
+        UNSAFE.putInt(x, TestClassInt.fieldOffset2, 10);
+        return UNSAFE.getInt(x, TestClassInt.fieldOffset1);
     }
 
     @Test
@@ -250,12 +229,12 @@
         TestClassInt x;
         if (a) {
             x = new TestClassInt(0, 0);
-            UNSAFE.putDouble(x, fieldOffset1, doubleField);
+            UNSAFE.putDouble(x, TestClassInt.fieldOffset1, doubleField);
         } else {
             x = new TestClassInt();
-            UNSAFE.putDouble(x, fieldOffset1, doubleField2);
+            UNSAFE.putDouble(x, TestClassInt.fieldOffset1, doubleField2);
         }
-        return UNSAFE.getDouble(x, fieldOffset1);
+        return UNSAFE.getDouble(x, TestClassInt.fieldOffset1);
     }
 
     static class ExtendedTestClassInt extends TestClassInt {
@@ -271,14 +250,14 @@
         TestClassInt x;
         if (value == 1) {
             x = new TestClassInt();
-            UNSAFE.putDouble(x, fieldOffset1, 10);
+            UNSAFE.putDouble(x, TestClassInt.fieldOffset1, 10);
         } else {
             x = new TestClassInt();
-            UNSAFE.putInt(x, fieldOffset1, 0);
+            UNSAFE.putInt(x, TestClassInt.fieldOffset1, 0);
         }
-        UNSAFE.putInt(x, fieldOffset1, 0);
+        UNSAFE.putInt(x, TestClassInt.fieldOffset1, 0);
         if (value == 2) {
-            UNSAFE.putInt(x, fieldOffset2, 0);
+            UNSAFE.putInt(x, TestClassInt.fieldOffset2, 0);
         }
         GraalDirectives.deoptimizeAndInvalidate();
         return x;
@@ -291,7 +270,7 @@
 
     public static TestClassInt testMaterializedDoubleSnippet() {
         TestClassInt x = new TestClassInt();
-        UNSAFE.putDouble(x, fieldOffset1, 10.1);
+        UNSAFE.putDouble(x, TestClassInt.fieldOffset1, 10.1);
         return x;
     }
 
@@ -305,10 +284,10 @@
 
     public static TestClassInt testDeoptDoubleVarSnippet() {
         TestClassInt x = new TestClassInt();
-        UNSAFE.putDouble(x, fieldOffset1, doubleField);
+        UNSAFE.putDouble(x, TestClassInt.fieldOffset1, doubleField);
         doubleField2 = 123;
         try {
-            doubleField = ((int) UNSAFE.getDouble(x, fieldOffset1)) / zero;
+            doubleField = ((int) UNSAFE.getDouble(x, TestClassInt.fieldOffset1)) / zero;
         } catch (RuntimeException e) {
             return x;
         }
@@ -322,10 +301,10 @@
 
     public static TestClassInt testDeoptDoubleConstantSnippet() {
         TestClassInt x = new TestClassInt();
-        UNSAFE.putDouble(x, fieldOffset1, 10.123);
+        UNSAFE.putDouble(x, TestClassInt.fieldOffset1, 10.123);
         doubleField2 = 123;
         try {
-            doubleField = ((int) UNSAFE.getDouble(x, fieldOffset1)) / zero;
+            doubleField = ((int) UNSAFE.getDouble(x, TestClassInt.fieldOffset1)) / zero;
         } catch (RuntimeException e) {
             return x;
         }
@@ -342,10 +321,10 @@
 
     public static TestClassInt testDeoptLongVarSnippet() {
         TestClassInt x = new TestClassInt();
-        UNSAFE.putLong(x, fieldOffset1, longField);
+        UNSAFE.putLong(x, TestClassInt.fieldOffset1, longField);
         longField2 = 123;
         try {
-            longField = UNSAFE.getLong(x, fieldOffset1) / zero;
+            longField = UNSAFE.getLong(x, TestClassInt.fieldOffset1) / zero;
         } catch (RuntimeException e) {
             return x;
         }
@@ -359,10 +338,10 @@
 
     public static TestClassInt testDeoptLongConstantSnippet() {
         TestClassInt x = new TestClassInt();
-        UNSAFE.putLong(x, fieldOffset1, 0x2222222210123L);
+        UNSAFE.putLong(x, TestClassInt.fieldOffset1, 0x2222222210123L);
         longField2 = 123;
         try {
-            longField = UNSAFE.getLong(x, fieldOffset1) / zero;
+            longField = UNSAFE.getLong(x, TestClassInt.fieldOffset1) / zero;
         } catch (RuntimeException e) {
             return x;
         }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/CompilationWrapper.java	Wed Nov 13 17:21:31 2019 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/CompilationWrapper.java	Mon Nov 18 12:40:06 2019 -0500
@@ -243,6 +243,9 @@
                 String message;
                 ByteArrayOutputStream baos = new ByteArrayOutputStream();
                 try (PrintStream ps = new PrintStream(baos)) {
+                    // This output is used by external tools to detect compilation failures.
+                    ps.println("[[[Graal compilation failure]]]");
+
                     ps.printf("%s: Compilation of %s failed:%n", Thread.currentThread(), this);
                     cause.printStackTrace(ps);
                     ps.printf("To disable compilation failure notifications, set %s to %s (e.g., -Dgraal.%s=%s).%n",
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.debug/src/org/graalvm/compiler/debug/GraalError.java	Wed Nov 13 17:21:31 2019 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.debug/src/org/graalvm/compiler/debug/GraalError.java	Mon Nov 18 12:40:06 2019 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -169,6 +169,14 @@
     }
 
     /**
+     * This constructor creates a {@link GraalError} for a given causing Throwable instance with
+     * detailed error message.
+     */
+    public GraalError(Throwable cause, String msg, Object... args) {
+        super(format(msg, args), cause);
+    }
+
+    /**
      * This constructor creates a {@link GraalError} and adds all the
      * {@linkplain #addContext(String) context} of another {@link GraalError}.
      *
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotBackend.java	Wed Nov 13 17:21:31 2019 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotBackend.java	Mon Nov 18 12:40:06 2019 -0500
@@ -26,6 +26,7 @@
 
 import static jdk.vm.ci.amd64.AMD64.r10;
 import static jdk.vm.ci.amd64.AMD64.rax;
+import static jdk.vm.ci.amd64.AMD64.rbp;
 import static jdk.vm.ci.amd64.AMD64.rsp;
 import static jdk.vm.ci.code.ValueUtil.asRegister;
 import static org.graalvm.compiler.core.common.GraalOptions.CanOmitFrame;
@@ -93,7 +94,7 @@
     @Override
     protected FrameMapBuilder newFrameMapBuilder(RegisterConfig registerConfig) {
         RegisterConfig registerConfigNonNull = registerConfig == null ? getCodeCache().getRegisterConfig() : registerConfig;
-        FrameMap frameMap = new AMD64FrameMap(getCodeCache(), registerConfigNonNull, this);
+        FrameMap frameMap = new AMD64FrameMap(getCodeCache(), registerConfigNonNull, this, config.preserveFramePointer);
         return new AMD64FrameMapBuilder(frameMap, getCodeCache(), registerConfigNonNull);
     }
 
@@ -130,10 +131,12 @@
 
         final boolean isStub;
         final boolean omitFrame;
+        final boolean useStandardFrameProlog;
 
-        HotSpotFrameContext(boolean isStub, boolean omitFrame) {
+        HotSpotFrameContext(boolean isStub, boolean omitFrame, boolean useStandardFrameProlog) {
             this.isStub = isStub;
             this.omitFrame = omitFrame;
+            this.useStandardFrameProlog = useStandardFrameProlog;
         }
 
         @Override
@@ -157,6 +160,11 @@
                     // assert asm.position() - verifiedEntryPointOffset >=
                     // PATCHED_VERIFIED_ENTRY_POINT_INSTRUCTION_SIZE;
                 }
+                if (useStandardFrameProlog) {
+                    // Stack-walking friendly instructions
+                    asm.push(rbp);
+                    asm.movq(rbp, rsp);
+                }
                 if (!isStub && asm.position() == verifiedEntryPointOffset) {
                     asm.subqWide(rsp, frameSize);
                     assert asm.position() - verifiedEntryPointOffset >= PATCHED_VERIFIED_ENTRY_POINT_INSTRUCTION_SIZE;
@@ -180,7 +188,12 @@
                 assert crb.frameMap.getRegisterConfig().getCalleeSaveRegisters() == null;
 
                 int frameSize = crb.frameMap.frameSize();
-                asm.incrementq(rsp, frameSize);
+                if (useStandardFrameProlog) {
+                    asm.movq(rsp, rbp);
+                    asm.pop(rbp);
+                } else {
+                    asm.incrementq(rsp, frameSize);
+                }
             }
         }
     }
@@ -202,7 +215,7 @@
 
         Stub stub = gen.getStub();
         Assembler masm = new AMD64MacroAssembler(getTarget());
-        HotSpotFrameContext frameContext = new HotSpotFrameContext(stub != null, omitFrame);
+        HotSpotFrameContext frameContext = new HotSpotFrameContext(stub != null, omitFrame, config.preserveFramePointer);
         DataBuilder dataBuilder = new HotSpotDataBuilder(getCodeCache().getTarget());
         CompilationResultBuilder crb = factory.createBuilder(getCodeCache(), getForeignCalls(), frameMap, masm, dataBuilder, frameContext, options, debug, compilationResult, Register.None);
         crb.setTotalFrameSize(frameMap.totalFrameSize());
@@ -330,7 +343,7 @@
     @Override
     public RegisterAllocationConfig newRegisterAllocationConfig(RegisterConfig registerConfig, String[] allocationRestrictedTo) {
         RegisterConfig registerConfigNonNull = registerConfig == null ? getCodeCache().getRegisterConfig() : registerConfig;
-        return new AMD64HotSpotRegisterAllocationConfig(registerConfigNonNull, allocationRestrictedTo);
+        return new AMD64HotSpotRegisterAllocationConfig(registerConfigNonNull, allocationRestrictedTo, config.preserveFramePointer);
     }
 
     @Override
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotEpilogueBlockEndOp.java	Wed Nov 13 17:21:31 2019 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotEpilogueBlockEndOp.java	Mon Nov 18 12:40:06 2019 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -24,6 +24,7 @@
 
 package org.graalvm.compiler.hotspot.amd64;
 
+import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.ILLEGAL;
 import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.REG;
 import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.STACK;
 
@@ -33,6 +34,7 @@
 import org.graalvm.compiler.lir.asm.CompilationResultBuilder;
 
 import jdk.vm.ci.meta.AllocatableValue;
+import jdk.vm.ci.meta.Value;
 
 /**
  * @see AMD64HotSpotEpilogueOp
@@ -43,7 +45,7 @@
         super(c);
     }
 
-    @Use({REG, STACK}) protected AllocatableValue savedRbp = PLACEHOLDER;
+    @Use({REG, STACK, ILLEGAL}) protected AllocatableValue savedRbp = Value.ILLEGAL;
 
     protected void leaveFrameAndRestoreRbp(CompilationResultBuilder crb, AMD64MacroAssembler masm) {
         AMD64HotSpotEpilogueOp.leaveFrameAndRestoreRbp(savedRbp, crb, masm);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotEpilogueOp.java	Wed Nov 13 17:21:31 2019 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotEpilogueOp.java	Mon Nov 18 12:40:06 2019 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -24,20 +24,23 @@
 
 package org.graalvm.compiler.hotspot.amd64;
 
-import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.REG;
-import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.STACK;
 import static jdk.vm.ci.amd64.AMD64.rbp;
 import static jdk.vm.ci.code.ValueUtil.asRegister;
 import static jdk.vm.ci.code.ValueUtil.isStackSlot;
+import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.ILLEGAL;
+import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.REG;
+import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.STACK;
 
 import org.graalvm.compiler.asm.amd64.AMD64Address;
 import org.graalvm.compiler.asm.amd64.AMD64MacroAssembler;
 import org.graalvm.compiler.lir.LIRInstructionClass;
+import org.graalvm.compiler.lir.amd64.AMD64FrameMap;
 import org.graalvm.compiler.lir.amd64.AMD64LIRInstruction;
 import org.graalvm.compiler.lir.asm.CompilationResultBuilder;
 
 import jdk.vm.ci.code.Register;
 import jdk.vm.ci.meta.AllocatableValue;
+import jdk.vm.ci.meta.Value;
 
 /**
  * Superclass for operations that use the value of RBP saved in a method's prologue.
@@ -48,14 +51,17 @@
         super(c);
     }
 
-    @Use({REG, STACK}) private AllocatableValue savedRbp = PLACEHOLDER;
+    @Use({REG, STACK, ILLEGAL}) private AllocatableValue savedRbp = Value.ILLEGAL;
 
     protected void leaveFrameAndRestoreRbp(CompilationResultBuilder crb, AMD64MacroAssembler masm) {
         leaveFrameAndRestoreRbp(savedRbp, crb, masm);
     }
 
     static void leaveFrameAndRestoreRbp(AllocatableValue savedRbp, CompilationResultBuilder crb, AMD64MacroAssembler masm) {
-        if (isStackSlot(savedRbp)) {
+        if (Value.ILLEGAL.equals(savedRbp)) {
+            // RBP will be restored in FrameContext.leave(..). Nothing to do here.
+            assert ((AMD64FrameMap) crb.frameMap).useStandardFrameProlog() : "savedRbp is not initialized.";
+        } else if (isStackSlot(savedRbp)) {
             // Restoring RBP from the stack must be done before the frame is removed
             masm.movq(rbp, (AMD64Address) crb.asAddress(savedRbp));
         } else {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotLIRGenerator.java	Wed Nov 13 17:21:31 2019 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotLIRGenerator.java	Mon Nov 18 12:40:06 2019 -0500
@@ -153,7 +153,7 @@
         SaveRbp(NoOp placeholder) {
             this.placeholder = placeholder;
             AMD64FrameMapBuilder frameMapBuilder = (AMD64FrameMapBuilder) getResult().getFrameMapBuilder();
-            this.reservedSlot = frameMapBuilder.allocateRBPSpillSlot();
+            this.reservedSlot = config.preserveFramePointer ? null : frameMapBuilder.allocateRBPSpillSlot();
         }
 
         /**
@@ -162,6 +162,7 @@
          * @param useStack specifies if rbp must be saved to the stack
          */
         public AllocatableValue finalize(boolean useStack) {
+            assert !config.preserveFramePointer : "rbp has been pushed onto the stack";
             AllocatableValue dst;
             if (useStack) {
                 dst = reservedSlot;
@@ -173,6 +174,10 @@
             placeholder.replace(getResult().getLIR(), new MoveFromRegOp(AMD64Kind.QWORD, dst, rbp.asValue(LIRKind.value(AMD64Kind.QWORD))));
             return dst;
         }
+
+        public void remove() {
+            placeholder.remove(getResult().getLIR());
+        }
     }
 
     private SaveRbp saveRbp;
@@ -183,10 +188,6 @@
         saveRbp = new SaveRbp(placeholder);
     }
 
-    protected SaveRbp getSaveRbp() {
-        return saveRbp;
-    }
-
     /**
      * Helper instruction to reserve a stack slot for the whole method. Note that the actual users
      * of the stack slot might be inserted after stack slot allocation. This dummy instruction
@@ -547,16 +548,21 @@
     public void beforeRegisterAllocation() {
         super.beforeRegisterAllocation();
         boolean hasDebugInfo = getResult().getLIR().hasDebugInfo();
-        AllocatableValue savedRbp = saveRbp.finalize(hasDebugInfo);
+
+        if (config.preserveFramePointer) {
+            saveRbp.remove();
+        } else {
+            AllocatableValue savedRbp = saveRbp.finalize(hasDebugInfo);
+            for (AMD64HotSpotRestoreRbpOp op : epilogueOps) {
+                op.setSavedRbp(savedRbp);
+            }
+        }
+
         if (hasDebugInfo) {
             getResult().setDeoptimizationRescueSlot(((AMD64FrameMapBuilder) getResult().getFrameMapBuilder()).allocateDeoptimizationRescueSlot());
         }
-
         getResult().setMaxInterpreterFrameSize(debugInfoBuilder.maxInterpreterFrameSize());
 
-        for (AMD64HotSpotRestoreRbpOp op : epilogueOps) {
-            op.setSavedRbp(savedRbp);
-        }
         if (BenchmarkCounters.enabled) {
             // ensure that the rescue slot is available
             LIRInstruction op = getOrInitRescueSlotOp();
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotRegisterAllocationConfig.java	Wed Nov 13 17:21:31 2019 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotRegisterAllocationConfig.java	Mon Nov 18 12:40:06 2019 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -83,8 +83,11 @@
     };
     // @formatter:on
 
-    AMD64HotSpotRegisterAllocationConfig(RegisterConfig registerConfig, String[] allocationRestrictedTo) {
+    private final boolean useStandardFrameProlog;
+
+    AMD64HotSpotRegisterAllocationConfig(RegisterConfig registerConfig, String[] allocationRestrictedTo, boolean useStandardFrameProlog) {
         super(registerConfig, allocationRestrictedTo);
+        this.useStandardFrameProlog = useStandardFrameProlog;
     }
 
     @Override
@@ -93,6 +96,9 @@
         for (Register reg : registers) {
             regMap.set(reg.number);
         }
+        if (useStandardFrameProlog) {
+            regMap.clear(rbp.number);
+        }
 
         ArrayList<Register> allocatableRegisters = new ArrayList<>(registers.size());
         for (Register reg : registerAllocationOrder) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotRestoreRbpOp.java	Wed Nov 13 17:21:31 2019 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotRestoreRbpOp.java	Mon Nov 18 12:40:06 2019 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -24,20 +24,9 @@
 
 package org.graalvm.compiler.hotspot.amd64;
 
-import org.graalvm.compiler.core.common.LIRKind;
-import org.graalvm.compiler.lir.Variable;
-
-import jdk.vm.ci.amd64.AMD64Kind;
 import jdk.vm.ci.meta.AllocatableValue;
 
 public interface AMD64HotSpotRestoreRbpOp {
 
-    /**
-     * The type of location (i.e., stack or register) in which RBP is saved is not known until
-     * initial LIR generation is finished. Until then, we use a placeholder variable so that LIR
-     * verification is successful.
-     */
-    Variable PLACEHOLDER = new Variable(LIRKind.value(AMD64Kind.QWORD), Integer.MAX_VALUE);
-
     void setSavedRbp(AllocatableValue value);
 }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotReturnOp.java	Wed Nov 13 17:21:31 2019 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotReturnOp.java	Mon Nov 18 12:40:06 2019 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -111,10 +111,14 @@
              * live value at this point should be the return value in either rax, or in xmm0 with
              * the upper half of the register unused, so we don't destroy any value here.
              */
-            if (masm.supports(CPUFeature.AVX)) {
+            if (masm.supports(CPUFeature.AVX) && crb.needsClearUpperVectorRegisters()) {
+                // If we decide to perform vzeroupper also for stubs (like what JDK9+ C2 does for
+                // intrinsics that employ AVX2 instruction), we need to be careful that it kills all
+                // the xmm registers (at least the upper halves).
                 masm.vzeroupper();
             }
         }
         masm.ret(0);
     }
+
 }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/CheckGraalIntrinsics.java	Wed Nov 13 17:21:31 2019 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/CheckGraalIntrinsics.java	Mon Nov 18 12:40:06 2019 -0500
@@ -158,11 +158,15 @@
     private static Collection<String> add(Collection<String> c, String... elements) {
         String[] sorted = elements.clone();
         Arrays.sort(sorted);
-        for (int i = 0; i < elements.length; i++) {
-            if (!elements[i].equals(sorted[i])) {
-                // Let's keep the list sorted for easier visual inspection
-                fail("Element %d is out of order, \"%s\"", i, elements[i]);
+        if (!Arrays.equals(elements, sorted)) {
+            int width = 2 + Arrays.asList(elements).stream().map(String::length).reduce(0, Integer::max);
+            Formatter fmt = new Formatter();
+            fmt.format("%-" + width + "s | sorted%n", "original");
+            fmt.format("%s%n", new String(new char[width * 2 + 2]).replace('\0', '='));
+            for (int i = 0; i < elements.length; i++) {
+                fmt.format("%-" + width + "s | %s%n", elements[i], sorted[i]);
             }
+            fail("Elements not sorted alphabetically:%n%s", fmt);
         }
         c.addAll(Arrays.asList(elements));
         return c;
@@ -517,8 +521,8 @@
         // AES intrinsics
         if (!config.useAESIntrinsics) {
             add(ignore,
+                            "com/sun/crypto/provider/AESCrypt." + aesDecryptName + "([BI[BI)V",
                             "com/sun/crypto/provider/AESCrypt." + aesEncryptName + "([BI[BI)V",
-                            "com/sun/crypto/provider/AESCrypt." + aesDecryptName + "([BI[BI)V",
                             "com/sun/crypto/provider/CipherBlockChaining." + cbcDecryptName + "([BII[BI)I",
                             "com/sun/crypto/provider/CipherBlockChaining." + cbcEncryptName + "([BII[BI)I");
         }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/CompilationWrapperTest.java	Wed Nov 13 17:21:31 2019 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/CompilationWrapperTest.java	Mon Nov 18 12:40:06 2019 -0500
@@ -122,6 +122,12 @@
     public void testVMCompilation3() throws IOException, InterruptedException {
         assumeManagementLibraryIsLoadable();
         final int maxProblems = 2;
+        Probe failurePatternProbe = new Probe("[[[Graal compilation failure]]]", maxProblems) {
+            @Override
+            String test() {
+                return actualOccurrences > 0 && actualOccurrences <= maxProblems ? null : String.format("expected occurrences to be in [1 .. %d]", maxProblems);
+            }
+        };
         Probe retryingProbe = new Probe("Retrying compilation of", maxProblems) {
             @Override
             String test() {
@@ -140,6 +146,7 @@
             }
         };
         Probe[] probes = {
+                        failurePatternProbe,
                         retryingProbe,
                         adjustmentProbe
         };
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/CompileTheWorldTest.java	Wed Nov 13 17:21:31 2019 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/CompileTheWorldTest.java	Mon Nov 18 12:40:06 2019 -0500
@@ -66,7 +66,7 @@
                         excludeMethodFilters,
                         verbose,
                         harnessOptions,
-                        new OptionValues(initialOptions, HighTier.Options.Inline, false));
+                        new OptionValues(initialOptions, HighTier.Options.Inline, false, CompilationFailureAction, ExceptionAction.Silent));
         ctw.compile();
         assert CompilationBailoutAsFailure.getValue(initialOptions) == originalBailoutAction;
         assert CompilationFailureAction.getValue(initialOptions) == originalFailureAction;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/GraalHotSpotVMConfig.java	Wed Nov 13 17:21:31 2019 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/GraalHotSpotVMConfig.java	Mon Nov 18 12:40:06 2019 -0500
@@ -111,6 +111,8 @@
     public final boolean useVectorizedMismatchIntrinsic = getFlag("UseVectorizedMismatchIntrinsic", Boolean.class, false);
     public final boolean useFMAIntrinsics = getFlag("UseFMA", Boolean.class, false);
 
+    public final boolean preserveFramePointer = getFlag("PreserveFramePointer", Boolean.class, false);
+
     /*
      * These are methods because in some JDKs the flags are visible but the stubs themselves haven't
      * been exported so we have to check both if the flag is on and if we have the stub.
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotForeignCallLinkageImpl.java	Wed Nov 13 17:21:31 2019 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotForeignCallLinkageImpl.java	Mon Nov 18 12:40:06 2019 -0500
@@ -304,4 +304,9 @@
     public String getSymbol() {
         return stub == null ? null : stub.toString();
     }
+
+    @Override
+    public boolean needsClearUpperVectorRegisters() {
+        return isCompiledStub() && mayContainFP();
+    }
 }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/JVMCIVersionCheck.java	Wed Nov 13 17:21:31 2019 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/JVMCIVersionCheck.java	Mon Nov 18 12:40:06 2019 -0500
@@ -43,7 +43,7 @@
  */
 public final class JVMCIVersionCheck {
 
-    private static final Version JVMCI8_MIN_VERSION = new Version3(19, 3, 2);
+    private static final Version JVMCI_MIN_VERSION = new Version3(19, 3, 4);
 
     public interface Version {
         boolean isLessThan(Version other);
@@ -145,7 +145,7 @@
         }
     }
 
-    private static void failVersionCheck(Map<String, String> props, boolean exit, String reason, Object... args) {
+    private void failVersionCheck(boolean exit, String reason, Object... args) {
         Formatter errorMessage = new Formatter().format(reason, args);
         String javaHome = props.get("java.home");
         String vmName = props.get("java.vm.name");
@@ -153,10 +153,14 @@
         errorMessage.format("this error or to \"warn\" to emit a warning and continue execution.%n");
         errorMessage.format("Currently used Java home directory is %s.%n", javaHome);
         errorMessage.format("Currently used VM configuration is: %s%n", vmName);
-        if (props.get("java.specification.version").compareTo("1.9") < 0) {
+        if (javaSpecVersion.compareTo("1.9") < 0) {
             errorMessage.format("Download the latest JVMCI JDK 8 from https://github.com/graalvm/openjdk8-jvmci-builder/releases");
         } else {
-            errorMessage.format("Download JDK 11 or later.");
+            if (javaSpecVersion.compareTo("11") == 0 && vmVersion.contains("-jvmci-")) {
+                errorMessage.format("Download the latest Labs OpenJDK 11 from https://github.com/graalvm/labs-openjdk-11/releases");
+            } else {
+                errorMessage.format("Download JDK 11 or later.");
+            }
         }
         String value = System.getenv("JVMCI_VERSION_CHECK");
         if ("warn".equals(value)) {
@@ -183,7 +187,7 @@
 
     static void check(Map<String, String> props, boolean exitOnFailure) {
         JVMCIVersionCheck checker = new JVMCIVersionCheck(props, props.get("java.specification.version"), props.get("java.vm.version"));
-        checker.run(exitOnFailure, JVMCI8_MIN_VERSION);
+        checker.run(exitOnFailure, JVMCI_MIN_VERSION);
     }
 
     /**
@@ -202,14 +206,14 @@
             Version v = Version.parse(vmVersion);
             if (v != null) {
                 if (v.isLessThan(minVersion)) {
-                    failVersionCheck(props, exitOnFailure, "The VM does not support the minimum JVMCI API version required by Graal: %s < %s.%n", v, minVersion);
+                    failVersionCheck(exitOnFailure, "The VM does not support the minimum JVMCI API version required by Graal: %s < %s.%n", v, minVersion);
                 }
                 return;
             }
-            failVersionCheck(props, exitOnFailure, "The VM does not support the minimum JVMCI API version required by Graal.%n" +
+            failVersionCheck(exitOnFailure, "The VM does not support the minimum JVMCI API version required by Graal.%n" +
                             "Cannot read JVMCI version from java.vm.version property: %s.%n", vmVersion);
         } else if (javaSpecVersion.compareTo("11") < 0) {
-            failVersionCheck(props, exitOnFailure, "Graal is not compatible with the JVMCI API in JDK 9 and 10.%n");
+            failVersionCheck(exitOnFailure, "Graal is not compatible with the JVMCI API in JDK 9 and 10.%n");
         } else {
             if (vmVersion.contains("SNAPSHOT")) {
                 return;
@@ -218,28 +222,16 @@
                 // Allow local builds
                 return;
             }
-            if (vmVersion.startsWith("11-ea+")) {
-                String buildString = vmVersion.substring("11-ea+".length());
-                try {
-                    int build = Integer.parseInt(buildString);
-                    if (build < 20) {
-                        failVersionCheck(props, exitOnFailure, "Graal requires build 20 or later of JDK 11 early access binary, got build %d.%n", build);
-                        return;
-                    }
-                } catch (NumberFormatException e) {
-                    failVersionCheck(props, exitOnFailure, "Could not parse the JDK 11 early access build number from java.vm.version property: %s.%n", vmVersion);
-                    return;
-                }
-            } else if (vmVersion.contains("-jvmci-")) {
+            if (vmVersion.contains("-jvmci-")) {
                 // A "labsjdk"
                 Version v = Version.parse(vmVersion);
                 if (v != null) {
                     if (v.isLessThan(minVersion)) {
-                        failVersionCheck(props, exitOnFailure, "The VM does not support the minimum JVMCI API version required by Graal: %s < %s.%n", v, minVersion);
+                        failVersionCheck(exitOnFailure, "The VM does not support the minimum JVMCI API version required by Graal: %s < %s.%n", v, minVersion);
                     }
                     return;
                 }
-                failVersionCheck(props, exitOnFailure, "The VM does not support the minimum JVMCI API version required by Graal.%n" +
+                failVersionCheck(exitOnFailure, "The VM does not support the minimum JVMCI API version required by Graal.%n" +
                                 "Cannot read JVMCI version from java.vm.version property: %s.%n", vmVersion);
             } else {
                 // Graal is compatible with all JDK versions as of 11 GA.
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotGraphBuilderPlugins.java	Wed Nov 13 17:21:31 2019 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotGraphBuilderPlugins.java	Mon Nov 18 12:40:06 2019 -0500
@@ -35,9 +35,11 @@
 import java.lang.invoke.MutableCallSite;
 import java.lang.invoke.VolatileCallSite;
 import java.lang.reflect.Array;
+import java.lang.reflect.Type;
 import java.math.BigInteger;
 import java.util.zip.CRC32;
 
+import jdk.internal.vm.compiler.collections.Pair;
 import org.graalvm.compiler.api.replacements.SnippetReflectionProvider;
 import org.graalvm.compiler.core.common.spi.ForeignCallsProvider;
 import org.graalvm.compiler.core.common.type.ObjectStamp;
@@ -115,6 +117,7 @@
 import jdk.vm.ci.meta.JavaKind;
 import jdk.vm.ci.meta.MetaAccessProvider;
 import jdk.vm.ci.meta.ResolvedJavaMethod;
+import jdk.vm.ci.services.Services;
 import sun.misc.Unsafe;
 
 /**
@@ -461,21 +464,29 @@
     }
 
     public static String lookupIntrinsicName(GraalHotSpotVMConfig config, String className, String name1, String name2) {
+        return selectIntrinsicName(config, className, name1, name2).getLeft();
+    }
+
+    /**
+     * Returns a pair of Strings where the left one represents the matched intrinsic name and the
+     * right one represents the mismatched intrinsic name.
+     */
+    public static Pair<String, String> selectIntrinsicName(GraalHotSpotVMConfig config, String className, String name1, String name2) {
         boolean foundName1 = false;
         boolean foundName2 = false;
-        String name = name1;
         for (VMIntrinsicMethod intrinsic : config.getStore().getIntrinsics()) {
             if (className.equals(intrinsic.declaringClass)) {
                 if (name1.equals(intrinsic.name)) {
                     foundName1 = true;
                 } else if (name2.equals(intrinsic.name)) {
                     foundName2 = true;
-                    name = name2;
                 }
             }
         }
-        if (foundName1 != foundName2) {
-            return name;
+        if (foundName1 && !foundName2) {
+            return Pair.create(name1, name2);
+        } else if (foundName2 && !foundName1) {
+            return Pair.create(name2, name1);
         }
         throw GraalError.shouldNotReachHere();
     }
@@ -500,19 +511,41 @@
             String arch = config.osArch;
             String decryptSuffix = arch.equals("sparc") ? "WithOriginalKey" : "";
 
-            String cbcEncryptName = lookupIntrinsicName(config, "com/sun/crypto/provider/CipherBlockChaining", "implEncrypt", "encrypt");
-            String cbcDecryptName = lookupIntrinsicName(config, "com/sun/crypto/provider/CipherBlockChaining", "implDecrypt", "decrypt");
             Registration r = new Registration(plugins, "com.sun.crypto.provider.CipherBlockChaining", replacements);
-            r.registerMethodSubstitution(CipherBlockChainingSubstitutions.class, cbcEncryptName, Receiver.class, byte[].class, int.class, int.class, byte[].class, int.class);
-            r.registerMethodSubstitution(CipherBlockChainingSubstitutions.class, cbcDecryptName, cbcDecryptName + decryptSuffix, Receiver.class, byte[].class, int.class, int.class, byte[].class,
-                            int.class);
 
-            String aesEncryptName = lookupIntrinsicName(config, "com/sun/crypto/provider/AESCrypt", "implEncryptBlock", "encryptBlock");
-            String aesDecryptName = lookupIntrinsicName(config, "com/sun/crypto/provider/AESCrypt", "implDecryptBlock", "decryptBlock");
+            Pair<String, String> cbcEncryptName = selectIntrinsicName(config, "com/sun/crypto/provider/CipherBlockChaining", "implEncrypt", "encrypt");
+            registerAndCheckMismatch(r, CipherBlockChainingSubstitutions.class, cbcEncryptName, Receiver.class, byte[].class, int.class, int.class,
+                            byte[].class, int.class);
+
+            Pair<String, String> cbcDecryptName = selectIntrinsicName(config, "com/sun/crypto/provider/CipherBlockChaining", "implDecrypt", "decrypt");
+            registerAndCheckMismatch(r, CipherBlockChainingSubstitutions.class, cbcDecryptName, cbcDecryptName.getLeft() + decryptSuffix, Receiver.class, byte[].class, int.class, int.class,
+                            byte[].class, int.class);
 
             r = new Registration(plugins, "com.sun.crypto.provider.AESCrypt", replacements);
-            r.registerMethodSubstitution(AESCryptSubstitutions.class, aesEncryptName, Receiver.class, byte[].class, int.class, byte[].class, int.class);
-            r.registerMethodSubstitution(AESCryptSubstitutions.class, aesDecryptName, aesDecryptName + decryptSuffix, Receiver.class, byte[].class, int.class, byte[].class, int.class);
+
+            Pair<String, String> aesEncryptName = selectIntrinsicName(config, "com/sun/crypto/provider/AESCrypt", "implEncryptBlock", "encryptBlock");
+            registerAndCheckMismatch(r, AESCryptSubstitutions.class, aesEncryptName, Receiver.class, byte[].class, int.class, byte[].class, int.class);
+
+            Pair<String, String> aesDecryptName = selectIntrinsicName(config, "com/sun/crypto/provider/AESCrypt", "implDecryptBlock", "decryptBlock");
+            registerAndCheckMismatch(r, AESCryptSubstitutions.class, aesDecryptName, aesDecryptName.getLeft() + decryptSuffix, Receiver.class, byte[].class, int.class, byte[].class, int.class);
+        }
+    }
+
+    private static void registerAndCheckMismatch(Registration r, Class<?> substitutionClass, Pair<String, String> intrinsicNames, Type... argumentTypes) {
+        try {
+            r.registerMethodSubstitution(substitutionClass, intrinsicNames.getLeft(), argumentTypes);
+        } catch (NoSuchMethodError e) {
+            throw new GraalError(e, "Found method named '%s' instead of '%s' in class '%s'. This is most likely because the JVMCI JDK in %s was built on an incompatible base JDK.",
+                            intrinsicNames.getRight(), intrinsicNames.getLeft(), r.getDeclaringType().getTypeName(), Services.getSavedProperties().get("java.home"));
+        }
+    }
+
+    private static void registerAndCheckMismatch(Registration r, Class<?> substitutionClass, Pair<String, String> intrinsicNames, String substituteName, Type... argumentTypes) {
+        try {
+            r.registerMethodSubstitution(substitutionClass, intrinsicNames.getLeft(), substituteName, argumentTypes);
+        } catch (NoSuchMethodError e) {
+            throw new GraalError(e, "Found method named '%s' instead of '%s' in class '%s'. This is most likely because the JVMCI JDK in %s was built on an incompatible base JDK.",
+                            intrinsicNames.getRight(), intrinsicNames.getLeft(), r.getDeclaringType().getTypeName(), Services.getSavedProperties().get("java.home"));
         }
     }
 
@@ -544,21 +577,21 @@
             r.registerMethodSubstitution(DigestBaseSubstitutions.class, "implCompressMultiBlock0", Receiver.class, byte[].class, int.class, int.class);
         }
 
-        String implCompressName = lookupIntrinsicName(config, "sun/security/provider/SHA", "implCompress", "implCompress0");
+        Pair<String, String> implCompressName = selectIntrinsicName(config, "sun/security/provider/SHA", "implCompress", "implCompress0");
         if (useSha1) {
             assert config.sha1ImplCompress != 0L;
             Registration r = new Registration(plugins, "sun.security.provider.SHA", replacements);
-            r.registerMethodSubstitution(SHASubstitutions.class, implCompressName, "implCompress0", Receiver.class, byte[].class, int.class);
+            registerAndCheckMismatch(r, SHASubstitutions.class, implCompressName, "implCompress0", Receiver.class, byte[].class, int.class);
         }
         if (useSha256) {
             assert config.sha256ImplCompress != 0L;
             Registration r = new Registration(plugins, "sun.security.provider.SHA2", replacements);
-            r.registerMethodSubstitution(SHA2Substitutions.class, implCompressName, "implCompress0", Receiver.class, byte[].class, int.class);
+            registerAndCheckMismatch(r, SHA2Substitutions.class, implCompressName, "implCompress0", Receiver.class, byte[].class, int.class);
         }
         if (useSha512) {
             assert config.sha512ImplCompress != 0L;
             Registration r = new Registration(plugins, "sun.security.provider.SHA5", replacements);
-            r.registerMethodSubstitution(SHA5Substitutions.class, implCompressName, "implCompress0", Receiver.class, byte[].class, int.class);
+            registerAndCheckMismatch(r, SHA5Substitutions.class, implCompressName, "implCompress0", Receiver.class, byte[].class, int.class);
         }
     }
 
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/stubs/Stub.java	Wed Nov 13 17:21:31 2019 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/stubs/Stub.java	Mon Nov 18 12:40:06 2019 -0500
@@ -27,6 +27,7 @@
 import static java.util.Collections.singletonList;
 import static org.graalvm.compiler.core.GraalCompiler.emitFrontEnd;
 import static org.graalvm.compiler.core.common.GraalOptions.GeneratePIC;
+import static org.graalvm.compiler.core.common.GraalOptions.RegisterPressure;
 import static org.graalvm.compiler.debug.DebugContext.DEFAULT_LOG_STREAM;
 import static org.graalvm.compiler.debug.DebugOptions.DebugStubsAndSnippets;
 import static org.graalvm.compiler.hotspot.HotSpotHostBackend.UNCOMMON_TRAP_HANDLER;
@@ -76,7 +77,7 @@
 
 /**
  * Base class for implementing some low level code providing the out-of-line slow path for a snippet
- * and/or a callee saved call to a HotSpot C/C++ runtime function or even a another compiled Java
+ * and/or a callee saved call to a HotSpot C/C++ runtime function or even another compiled Java
  * method.
  */
 public abstract class Stub {
@@ -135,7 +136,9 @@
      */
     public Stub(OptionValues options, HotSpotProviders providers, HotSpotForeignCallLinkage linkage) {
         this.linkage = linkage;
-        this.options = new OptionValues(options, GraalOptions.TraceInlining, GraalOptions.TraceInliningForStubsAndSnippets.getValue(options));
+        // The RegisterPressure flag can be ignored by a compilation that runs out of registers, so
+        // the stub compilation must ignore the flag so that all allocatable registers are saved.
+        this.options = new OptionValues(options, GraalOptions.TraceInlining, GraalOptions.TraceInliningForStubsAndSnippets.getValue(options), RegisterPressure, null);
         this.providers = providers;
     }
 
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.amd64/src/org/graalvm/compiler/lir/amd64/AMD64ArrayCompareToOp.java	Wed Nov 13 17:21:31 2019 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.amd64/src/org/graalvm/compiler/lir/amd64/AMD64ArrayCompareToOp.java	Mon Nov 18 12:40:06 2019 -0500
@@ -579,4 +579,9 @@
             masm.movzwl(elem2, new AMD64Address(str2, index, scale2, 0));
         }
     }
+
+    @Override
+    public boolean needsClearUpperVectorRegisters() {
+        return true;
+    }
 }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.amd64/src/org/graalvm/compiler/lir/amd64/AMD64ArrayEqualsOp.java	Wed Nov 13 17:21:31 2019 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.amd64/src/org/graalvm/compiler/lir/amd64/AMD64ArrayEqualsOp.java	Mon Nov 18 12:40:06 2019 -0500
@@ -864,4 +864,9 @@
                 throw new IllegalStateException();
         }
     }
+
+    @Override
+    public boolean needsClearUpperVectorRegisters() {
+        return true;
+    }
 }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.amd64/src/org/graalvm/compiler/lir/amd64/AMD64ArrayIndexOfOp.java	Wed Nov 13 17:21:31 2019 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.amd64/src/org/graalvm/compiler/lir/amd64/AMD64ArrayIndexOfOp.java	Mon Nov 18 12:40:06 2019 -0500
@@ -644,4 +644,9 @@
     private static boolean supports(LIRGeneratorTool tool, CPUFeature cpuFeature) {
         return ((AMD64) tool.target().arch).getFeatures().contains(cpuFeature);
     }
+
+    @Override
+    public boolean needsClearUpperVectorRegisters() {
+        return true;
+    }
 }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.amd64/src/org/graalvm/compiler/lir/amd64/AMD64Call.java	Wed Nov 13 17:21:31 2019 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.amd64/src/org/graalvm/compiler/lir/amd64/AMD64Call.java	Mon Nov 18 12:40:06 2019 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -152,6 +152,11 @@
         public boolean destroysCallerSavedRegisters() {
             return callTarget.destroysRegisters();
         }
+
+        @Override
+        public boolean needsClearUpperVectorRegisters() {
+            return callTarget.needsClearUpperVectorRegisters();
+        }
     }
 
     @Opcode("NEAR_FOREIGN_CALL")
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.amd64/src/org/graalvm/compiler/lir/amd64/AMD64FrameMap.java	Wed Nov 13 17:21:31 2019 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.amd64/src/org/graalvm/compiler/lir/amd64/AMD64FrameMap.java	Mon Nov 18 12:40:06 2019 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -78,17 +78,15 @@
  */
 public class AMD64FrameMap extends FrameMap {
 
+    private final boolean useStandardFrameProlog;
     private StackSlot rbpSpillSlot;
 
-    public AMD64FrameMap(CodeCacheProvider codeCache, RegisterConfig registerConfig, ReferenceMapBuilderFactory referenceMapFactory) {
-        this(codeCache, registerConfig, referenceMapFactory, false);
-    }
-
-    public AMD64FrameMap(CodeCacheProvider codeCache, RegisterConfig registerConfig, ReferenceMapBuilderFactory referenceMapFactory, boolean useBasePointer) {
+    public AMD64FrameMap(CodeCacheProvider codeCache, RegisterConfig registerConfig, ReferenceMapBuilderFactory referenceMapFactory, boolean useStandardFrameProlog) {
         super(codeCache, registerConfig, referenceMapFactory);
         // (negative) offset relative to sp + total frame size
-        initialSpillSize = returnAddressSize() + (useBasePointer ? getTarget().arch.getWordSize() : 0);
-        spillSize = initialSpillSize;
+        this.useStandardFrameProlog = useStandardFrameProlog;
+        this.initialSpillSize = returnAddressSize() + (useStandardFrameProlog ? getTarget().arch.getWordSize() : 0);
+        this.spillSize = initialSpillSize;
     }
 
     @Override
@@ -141,4 +139,8 @@
                         spillSlotSize(LIRKind.value(AMD64Kind.QWORD)) : "Deoptimization rescue slot must be the first or second (if there is an RBP spill slot) stack slot";
         return allocateSpillSlot(LIRKind.value(AMD64Kind.QWORD));
     }
+
+    public boolean useStandardFrameProlog() {
+        return useStandardFrameProlog;
+    }
 }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.amd64/src/org/graalvm/compiler/lir/amd64/AMD64StringLatin1InflateOp.java	Wed Nov 13 17:21:31 2019 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.amd64/src/org/graalvm/compiler/lir/amd64/AMD64StringLatin1InflateOp.java	Mon Nov 18 12:40:06 2019 -0500
@@ -275,4 +275,8 @@
         masm.bind(labelDone);
     }
 
+    @Override
+    public boolean needsClearUpperVectorRegisters() {
+        return true;
+    }
 }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.amd64/src/org/graalvm/compiler/lir/amd64/AMD64StringUTF16CompressOp.java	Wed Nov 13 17:21:31 2019 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.amd64/src/org/graalvm/compiler/lir/amd64/AMD64StringUTF16CompressOp.java	Mon Nov 18 12:40:06 2019 -0500
@@ -340,4 +340,8 @@
         masm.bind(labelDone);
     }
 
+    @Override
+    public boolean needsClearUpperVectorRegisters() {
+        return true;
+    }
 }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.amd64/src/org/graalvm/compiler/lir/amd64/AMD64Ternary.java	Wed Nov 13 17:21:31 2019 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.amd64/src/org/graalvm/compiler/lir/amd64/AMD64Ternary.java	Mon Nov 18 12:40:06 2019 -0500
@@ -37,6 +37,7 @@
 import org.graalvm.compiler.asm.amd64.AVXKind.AVXSize;
 import org.graalvm.compiler.lir.LIRInstructionClass;
 import org.graalvm.compiler.lir.Opcode;
+import org.graalvm.compiler.lir.amd64.vector.AMD64VectorInstruction;
 import org.graalvm.compiler.lir.asm.CompilationResultBuilder;
 
 import jdk.vm.ci.meta.AllocatableValue;
@@ -49,11 +50,10 @@
     /**
      * Instruction that has two {@link AllocatableValue} operands.
      */
-    public static class ThreeOp extends AMD64LIRInstruction {
+    public static class ThreeOp extends AMD64VectorInstruction {
         public static final LIRInstructionClass<ThreeOp> TYPE = LIRInstructionClass.create(ThreeOp.class);
 
         @Opcode private final VexRVMOp opcode;
-        private final AVXSize size;
 
         @Def({REG, HINT}) protected AllocatableValue result;
         @Use({REG}) protected AllocatableValue x;
@@ -65,10 +65,8 @@
         @Alive({REG, STACK}) protected AllocatableValue z;
 
         public ThreeOp(VexRVMOp opcode, AVXSize size, AllocatableValue result, AllocatableValue x, AllocatableValue y, AllocatableValue z) {
-            super(TYPE);
+            super(TYPE, size);
             this.opcode = opcode;
-            this.size = size;
-
             this.result = result;
             this.x = x;
             this.y = y;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.amd64/src/org/graalvm/compiler/lir/amd64/AMD64VZeroUpper.java	Wed Nov 13 17:21:31 2019 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.amd64/src/org/graalvm/compiler/lir/amd64/AMD64VZeroUpper.java	Mon Nov 18 12:40:06 2019 -0500
@@ -32,6 +32,8 @@
 
 import org.graalvm.compiler.asm.amd64.AMD64MacroAssembler;
 import org.graalvm.compiler.lir.LIRInstructionClass;
+import org.graalvm.compiler.lir.amd64.AMD64Call.ForeignCallOp;
+import org.graalvm.compiler.lir.amd64.vector.AMD64VectorInstruction;
 import org.graalvm.compiler.lir.asm.CompilationResultBuilder;
 
 import jdk.vm.ci.amd64.AMD64;
@@ -40,6 +42,48 @@
 import jdk.vm.ci.code.RegisterValue;
 import jdk.vm.ci.meta.Value;
 
+/**
+ * vzeroupper is essential to avoid performance penalty during SSE-AVX transition. Specifically,
+ * once we have executed instructions that modify the upper bits (i.e., 128+) of the YMM registers,
+ * we need to perform vzeroupper to transit the state to 128bits before executing any SSE
+ * instructions. We don't need to place vzeroupper between VEX-encoded SSE instructions and legacy
+ * SSE instructions, nor between AVX instructions and VEX-encoded SSE instructions.
+ *
+ * When running Graal on HotSpot, we emit a vzeroupper LIR operation (i.e. an instance of this
+ * class) before a foreign call to the runtime function where Graal has no knowledge. The underlying
+ * reason is that HotSpot is SSE-compiled so as to support older CPUs. We also emit a vzeroupper
+ * instruction (see {@code AMD64HotSpotReturnOp.emitCode}) upon returning, if the current LIR graph
+ * contains LIR operations that touch the upper bits of the YMM registers, including but not limited
+ * to {@link AMD64VectorInstruction}, {@link AMD64ArrayCompareToOp}, {@link AMD64ArrayEqualsOp},
+ * {@link AMD64ArrayIndexOfOp}, and {@link ForeignCallOp} that invokes to Graal-compiled stubs. For
+ * the last case, since Graal-compiled stubs is under our control, we don't emit vzeroupper upon
+ * returning of the stub, but rather do that upon returning of the current method.
+ *
+ * On JDK8, C2 does not emit many vzeroupper instructions, potentially because that YMM registers
+ * are not heavily employed (C2 vectorization starts using YMM registers in 9, source
+ * https://cr.openjdk.java.net/~vlivanov/talks/2017_Vectorization_in_HotSpot_JVM.pdf) and thus less
+ * care has been taken to place these instructions. One example is that many intrinsics employ YMM
+ * registers starting from https://bugs.openjdk.java.net/browse/JDK-8005419, but does not properly
+ * place vzeroupper upon returning of the intrinsic stub or the caller of the stub.
+ *
+ * Most vzeroupper were added in JDK 10 (https://bugs.openjdk.java.net/browse/JDK-8178811), and was
+ * later restricted on Haswell Xeon due to performance regression
+ * (https://bugs.openjdk.java.net/browse/JDK-8190934). The actual condition for placing vzeroupper
+ * is at http://hg.openjdk.java.net/jdk/jdk/file/c7d9df2e470c/src/hotspot/cpu/x86/x86_64.ad#l428. To
+ * summarize, if nmethod employs YMM registers (or intrinsics which use them, search for
+ * clear_upper_avx() in opto/library_call.cpp) vzeroupper will be generated on nmethod's exit and
+ * before any calls in nmethod, because even compiled nmethods can still use only SSE instructions.
+ *
+ * This means, if a Java method performs a call to an intrinsic that employs YMM registers,
+ * C2-compiled code will place a vzeroupper before the call, upon exit of the stub and upon exit of
+ * this method. Graal will only place the last, because it ensures that Graal-compiled Java method
+ * and stubs will be consistent on using VEX-encoding.
+ *
+ * In SubstrateVM, since the whole image is compiled consistently with or without VEX encoding (the
+ * later is the default behavior, see {@code NativeImageGenerator.createTarget}), there is no need
+ * for vzeroupper. For dynamic compilation on a SubstrateVM image, if the image is SSE-compiled, we
+ * then need vzeroupper when returning from the dynamic compiled code to the pre-built image code.
+ */
 public class AMD64VZeroUpper extends AMD64LIRInstruction {
 
     public static final LIRInstructionClass<AMD64VZeroUpper> TYPE = LIRInstructionClass.create(AMD64VZeroUpper.class);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.amd64/src/org/graalvm/compiler/lir/amd64/vector/AMD64VectorBinary.java	Wed Nov 13 17:21:31 2019 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.amd64/src/org/graalvm/compiler/lir/amd64/vector/AMD64VectorBinary.java	Mon Nov 18 12:40:06 2019 -0500
@@ -40,7 +40,6 @@
 import org.graalvm.compiler.lir.LIRInstructionClass;
 import org.graalvm.compiler.lir.Opcode;
 import org.graalvm.compiler.lir.amd64.AMD64AddressValue;
-import org.graalvm.compiler.lir.amd64.AMD64LIRInstruction;
 import org.graalvm.compiler.lir.asm.CompilationResultBuilder;
 
 import jdk.vm.ci.amd64.AMD64Kind;
@@ -48,20 +47,18 @@
 
 public class AMD64VectorBinary {
 
-    public static final class AVXBinaryOp extends AMD64LIRInstruction {
+    public static final class AVXBinaryOp extends AMD64VectorInstruction {
         public static final LIRInstructionClass<AVXBinaryOp> TYPE = LIRInstructionClass.create(AVXBinaryOp.class);
 
         @Opcode private final VexRVMOp opcode;
-        private final AVXKind.AVXSize size;
 
         @Def({REG}) protected AllocatableValue result;
         @Use({REG}) protected AllocatableValue x;
         @Use({REG, STACK}) protected AllocatableValue y;
 
         public AVXBinaryOp(VexRVMOp opcode, AVXKind.AVXSize size, AllocatableValue result, AllocatableValue x, AllocatableValue y) {
-            super(TYPE);
+            super(TYPE, size);
             this.opcode = opcode;
-            this.size = size;
             this.result = result;
             this.x = x;
             this.y = y;
@@ -77,22 +74,20 @@
         }
     }
 
-    public static final class AVXBinaryConstOp extends AMD64LIRInstruction {
+    public static final class AVXBinaryConstOp extends AMD64VectorInstruction {
 
         public static final LIRInstructionClass<AVXBinaryConstOp> TYPE = LIRInstructionClass.create(AVXBinaryConstOp.class);
 
         @Opcode private final VexRRIOp opcode;
-        private final AVXKind.AVXSize size;
 
         @Def({REG}) protected AllocatableValue result;
         @Use({REG}) protected AllocatableValue x;
         protected int y;
 
         public AVXBinaryConstOp(VexRRIOp opcode, AVXKind.AVXSize size, AllocatableValue result, AllocatableValue x, int y) {
-            super(TYPE);
+            super(TYPE, size);
             assert (y & 0xFF) == y;
             this.opcode = opcode;
-            this.size = size;
             this.result = result;
             this.x = x;
             this.y = y;
@@ -104,22 +99,20 @@
         }
     }
 
-    public static final class AVXBinaryConstFloatOp extends AMD64LIRInstruction {
+    public static final class AVXBinaryConstFloatOp extends AMD64VectorInstruction {
 
         public static final LIRInstructionClass<AVXBinaryConstFloatOp> TYPE = LIRInstructionClass.create(AVXBinaryConstFloatOp.class);
 
         @Opcode private final VexRVMOp opcode;
-        private final AVXKind.AVXSize size;
 
         @Def({REG}) protected AllocatableValue result;
         @Use({REG}) protected AllocatableValue x;
         protected ConstantValue y;
 
         public AVXBinaryConstFloatOp(VexRVMOp opcode, AVXKind.AVXSize size, AllocatableValue result, AllocatableValue x, ConstantValue y) {
-            super(TYPE);
+            super(TYPE, size);
             assert y.getPlatformKind() == AMD64Kind.SINGLE || y.getPlatformKind() == AMD64Kind.DOUBLE;
             this.opcode = opcode;
-            this.size = size;
             this.result = result;
             this.x = x;
             this.y = y;
@@ -136,11 +129,10 @@
         }
     }
 
-    public static final class AVXBinaryMemoryOp extends AMD64LIRInstruction {
+    public static final class AVXBinaryMemoryOp extends AMD64VectorInstruction {
         public static final LIRInstructionClass<AVXBinaryMemoryOp> TYPE = LIRInstructionClass.create(AVXBinaryMemoryOp.class);
 
         @Opcode private final VexRVMOp opcode;
-        private final AVXKind.AVXSize size;
 
         @Def({REG}) protected AllocatableValue result;
         @Use({REG}) protected AllocatableValue x;
@@ -148,9 +140,8 @@
         @State protected LIRFrameState state;
 
         public AVXBinaryMemoryOp(VexRVMOp opcode, AVXKind.AVXSize size, AllocatableValue result, AllocatableValue x, AMD64AddressValue y, LIRFrameState state) {
-            super(TYPE);
+            super(TYPE, size);
             this.opcode = opcode;
-            this.size = size;
             this.result = result;
             this.x = x;
             this.y = y;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.amd64/src/org/graalvm/compiler/lir/amd64/vector/AMD64VectorCompareOp.java	Wed Nov 13 17:21:31 2019 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.amd64/src/org/graalvm/compiler/lir/amd64/vector/AMD64VectorCompareOp.java	Mon Nov 18 12:40:06 2019 -0500
@@ -35,16 +35,14 @@
 import org.graalvm.compiler.asm.amd64.AVXKind.AVXSize;
 import org.graalvm.compiler.lir.LIRInstructionClass;
 import org.graalvm.compiler.lir.Opcode;
-import org.graalvm.compiler.lir.amd64.AMD64LIRInstruction;
 import org.graalvm.compiler.lir.asm.CompilationResultBuilder;
 
 import jdk.vm.ci.meta.AllocatableValue;
 
-public final class AMD64VectorCompareOp extends AMD64LIRInstruction {
+public final class AMD64VectorCompareOp extends AMD64VectorInstruction {
     public static final LIRInstructionClass<AMD64VectorCompareOp> TYPE = LIRInstructionClass.create(AMD64VectorCompareOp.class);
 
     @Opcode private final VexRMOp opcode;
-    private final AVXSize size;
     @Use({REG}) protected AllocatableValue x;
     @Use({REG, STACK}) protected AllocatableValue y;
 
@@ -53,9 +51,8 @@
     }
 
     public AMD64VectorCompareOp(VexRMOp opcode, AVXSize size, AllocatableValue x, AllocatableValue y) {
-        super(TYPE);
+        super(TYPE, size);
         this.opcode = opcode;
-        this.size = size;
         this.x = x;
         this.y = y;
     }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.amd64/src/org/graalvm/compiler/lir/amd64/vector/AMD64VectorFloatCompareOp.java	Mon Nov 18 12:40:06 2019 -0500
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+
+package org.graalvm.compiler.lir.amd64.vector;
+
+import static jdk.vm.ci.code.ValueUtil.asRegister;
+import static jdk.vm.ci.code.ValueUtil.isRegister;
+import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.REG;
+import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.STACK;
+
+import org.graalvm.compiler.asm.amd64.AMD64Address;
+import org.graalvm.compiler.asm.amd64.AMD64MacroAssembler;
+import org.graalvm.compiler.asm.amd64.AMD64Assembler.VexFloatCompareOp;
+import org.graalvm.compiler.asm.amd64.AVXKind.AVXSize;
+import org.graalvm.compiler.lir.LIRInstructionClass;
+import org.graalvm.compiler.lir.Opcode;
+import org.graalvm.compiler.lir.amd64.AMD64LIRInstruction;
+import org.graalvm.compiler.lir.asm.CompilationResultBuilder;
+
+import jdk.vm.ci.meta.AllocatableValue;
+
+public class AMD64VectorFloatCompareOp extends AMD64LIRInstruction {
+    public static final LIRInstructionClass<AMD64VectorFloatCompareOp> TYPE = LIRInstructionClass.create(AMD64VectorFloatCompareOp.class);
+
+    @Opcode private final VexFloatCompareOp opcode;
+    private final AVXSize size;
+    @Def({REG}) protected AllocatableValue result;
+    @Use({REG}) protected AllocatableValue x;
+    @Use({REG, STACK}) protected AllocatableValue y;
+    private final VexFloatCompareOp.Predicate predicate;
+
+    public AMD64VectorFloatCompareOp(VexFloatCompareOp opcode, AVXSize size, AllocatableValue result, AllocatableValue x, AllocatableValue y, VexFloatCompareOp.Predicate predicate) {
+        super(TYPE);
+        this.opcode = opcode;
+        this.size = size;
+        this.result = result;
+        this.x = x;
+        this.y = y;
+        this.predicate = predicate;
+    }
+
+    @Override
+    public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) {
+        if (isRegister(y)) {
+            opcode.emit(masm, size, asRegister(result), asRegister(x), asRegister(y), predicate);
+        } else {
+            opcode.emit(masm, size, asRegister(result), asRegister(x), (AMD64Address) crb.asAddress(y), predicate);
+        }
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.amd64/src/org/graalvm/compiler/lir/amd64/vector/AMD64VectorInstruction.java	Mon Nov 18 12:40:06 2019 -0500
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+
+package org.graalvm.compiler.lir.amd64.vector;
+
+import org.graalvm.compiler.asm.amd64.AVXKind.AVXSize;
+import org.graalvm.compiler.lir.LIRInstructionClass;
+import org.graalvm.compiler.lir.amd64.AMD64LIRInstruction;
+
+public abstract class AMD64VectorInstruction extends AMD64LIRInstruction {
+
+    public static final LIRInstructionClass<AMD64VectorInstruction> TYPE = LIRInstructionClass.create(AMD64VectorInstruction.class);
+    protected final AVXSize size;
+
+    public AMD64VectorInstruction(LIRInstructionClass<? extends AMD64VectorInstruction> c, AVXSize size) {
+        super(c);
+        this.size = size;
+    }
+
+    @Override
+    public boolean needsClearUpperVectorRegisters() {
+        return size == AVXSize.YMM || size == AVXSize.ZMM;
+    }
+
+}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.amd64/src/org/graalvm/compiler/lir/amd64/vector/AMD64VectorMove.java	Wed Nov 13 17:21:31 2019 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.amd64/src/org/graalvm/compiler/lir/amd64/vector/AMD64VectorMove.java	Mon Nov 18 12:40:06 2019 -0500
@@ -203,17 +203,15 @@
         }
     }
 
-    public abstract static class VectorMemOp extends AMD64LIRInstruction {
+    public abstract static class VectorMemOp extends AMD64VectorInstruction {
 
-        protected final AVXSize size;
         protected final VexMoveOp op;
 
         @Use({COMPOSITE}) protected AMD64AddressValue address;
         @State protected LIRFrameState state;
 
         protected VectorMemOp(LIRInstructionClass<? extends VectorMemOp> c, AVXSize size, VexMoveOp op, AMD64AddressValue address, LIRFrameState state) {
-            super(c);
-            this.size = size;
+            super(c, size);
             this.op = op;
             this.address = address;
             this.state = state;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.amd64/src/org/graalvm/compiler/lir/amd64/vector/AMD64VectorUnary.java	Wed Nov 13 17:21:31 2019 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.amd64/src/org/graalvm/compiler/lir/amd64/vector/AMD64VectorUnary.java	Mon Nov 18 12:40:06 2019 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -50,19 +50,17 @@
 
 public class AMD64VectorUnary {
 
-    public static final class AVXUnaryOp extends AMD64LIRInstruction {
+    public static final class AVXUnaryOp extends AMD64VectorInstruction {
         public static final LIRInstructionClass<AVXUnaryOp> TYPE = LIRInstructionClass.create(AVXUnaryOp.class);
 
         @Opcode private final VexRMOp opcode;
-        private final AVXKind.AVXSize size;
 
         @Def({REG}) protected AllocatableValue result;
         @Use({REG, STACK}) protected AllocatableValue input;
 
         public AVXUnaryOp(VexRMOp opcode, AVXKind.AVXSize size, AllocatableValue result, AllocatableValue input) {
-            super(TYPE);
+            super(TYPE, size);
             this.opcode = opcode;
-            this.size = size;
             this.result = result;
             this.input = input;
         }
@@ -77,20 +75,18 @@
         }
     }
 
-    public static final class AVXUnaryMemoryOp extends AMD64LIRInstruction {
+    public static final class AVXUnaryMemoryOp extends AMD64VectorInstruction {
         public static final LIRInstructionClass<AVXUnaryMemoryOp> TYPE = LIRInstructionClass.create(AVXUnaryMemoryOp.class);
 
         @Opcode private final VexRMOp opcode;
-        private final AVXKind.AVXSize size;
 
         @Def({REG}) protected AllocatableValue result;
         @Use({COMPOSITE}) protected AMD64AddressValue input;
         @State protected LIRFrameState state;
 
         public AVXUnaryMemoryOp(VexRMOp opcode, AVXKind.AVXSize size, AllocatableValue result, AMD64AddressValue input, LIRFrameState state) {
-            super(TYPE);
+            super(TYPE, size);
             this.opcode = opcode;
-            this.size = size;
             this.result = result;
             this.input = input;
             this.state = state;
@@ -105,19 +101,17 @@
         }
     }
 
-    public static final class AVXBroadcastOp extends AMD64LIRInstruction {
+    public static final class AVXBroadcastOp extends AMD64VectorInstruction {
         public static final LIRInstructionClass<AVXBroadcastOp> TYPE = LIRInstructionClass.create(AVXBroadcastOp.class);
 
         @Opcode private final VexRMOp opcode;
-        private final AVXKind.AVXSize size;
 
         @Def({REG}) protected AllocatableValue result;
         @Use({REG, STACK, CONST}) protected Value input;
 
         public AVXBroadcastOp(VexRMOp opcode, AVXKind.AVXSize size, AllocatableValue result, Value input) {
-            super(TYPE);
+            super(TYPE, size);
             this.opcode = opcode;
-            this.size = size;
             this.result = result;
             this.input = input;
         }
@@ -136,20 +130,18 @@
         }
     }
 
-    public static final class AVXConvertMemoryOp extends AMD64LIRInstruction {
+    public static final class AVXConvertMemoryOp extends AMD64VectorInstruction {
         public static final LIRInstructionClass<AVXConvertMemoryOp> TYPE = LIRInstructionClass.create(AVXConvertMemoryOp.class);
 
         @Opcode private final VexRVMOp opcode;
-        private final AVXKind.AVXSize size;
 
         @Def({REG}) protected AllocatableValue result;
         @Use({COMPOSITE}) protected AMD64AddressValue input;
         @State protected LIRFrameState state;
 
         public AVXConvertMemoryOp(VexRVMOp opcode, AVXKind.AVXSize size, AllocatableValue result, AMD64AddressValue input, LIRFrameState state) {
-            super(TYPE);
+            super(TYPE, size);
             this.opcode = opcode;
-            this.size = size;
             this.result = result;
             this.input = input;
             this.state = state;
@@ -180,6 +172,8 @@
 
         @Override
         public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) {
+            // Note that we assume only XMM-size instructions are emitted here. Loosening this
+            // restriction would require informing AMD64HotSpotReturnOp when emitting vzeroupper.
             if (isRegister(input)) {
                 if (!asRegister(input).equals(asRegister(result))) {
                     // clear result register to avoid unnecessary dependency
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/LIRInstruction.java	Wed Nov 13 17:21:31 2019 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/LIRInstruction.java	Mon Nov 18 12:40:06 2019 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -458,4 +458,8 @@
     public int hashCode() {
         return id;
     }
+
+    public boolean needsClearUpperVectorRegisters() {
+        return false;
+    }
 }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/asm/CompilationResultBuilder.java	Wed Nov 13 17:21:31 2019 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/asm/CompilationResultBuilder.java	Mon Nov 18 12:40:06 2019 -0500
@@ -692,4 +692,18 @@
     public void setConservativeLabelRanges() {
         this.conservativeLabelOffsets = true;
     }
+
+    public final boolean needsClearUpperVectorRegisters() {
+        for (AbstractBlockBase<?> block : lir.codeEmittingOrder()) {
+            if (block == null) {
+                continue;
+            }
+            for (LIRInstruction op : lir.getLIRforBlock(block)) {
+                if (op.needsClearUpperVectorRegisters()) {
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
 }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/CompareNode.java	Wed Nov 13 17:21:31 2019 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/CompareNode.java	Mon Nov 18 12:40:06 2019 -0500
@@ -354,4 +354,24 @@
 
         return comparison;
     }
+
+    public static LogicNode createFloatCompareNode(StructuredGraph graph, CanonicalCondition condition, ValueNode x, ValueNode y, boolean unorderedIsTrue, NodeView view) {
+        LogicNode result = createFloatCompareNode(condition, x, y, unorderedIsTrue, view);
+        return (result.graph() == null ? graph.addOrUniqueWithInputs(result) : result);
+    }
+
+    public static LogicNode createFloatCompareNode(CanonicalCondition condition, ValueNode x, ValueNode y, boolean unorderedIsTrue, NodeView view) {
+        assert x.getStackKind() == y.getStackKind();
+        assert x.getStackKind().isNumericFloat();
+
+        LogicNode comparison;
+        if (condition == CanonicalCondition.EQ) {
+            comparison = FloatEqualsNode.create(x, y, view);
+        } else {
+            assert condition == CanonicalCondition.LT;
+            comparison = FloatLessThanNode.create(x, y, unorderedIsTrue, view);
+        }
+
+        return comparison;
+    }
 }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/graphbuilderconf/InvocationPlugins.java	Wed Nov 13 17:21:31 2019 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/graphbuilderconf/InvocationPlugins.java	Mon Nov 18 12:40:06 2019 -0500
@@ -1401,7 +1401,7 @@
             if (declaringType instanceof ResolvedJavaSymbol) {
                 return checkResolvable(isOptional, ((ResolvedJavaSymbol) declaringType).getResolved(), binding);
             }
-            Class<?> declaringClass = InvocationPlugins.resolveType(declaringType, isOptional);
+            Class<?> declaringClass = resolveType(declaringType, isOptional);
             if (declaringClass == null) {
                 return true;
             }
@@ -1411,7 +1411,7 @@
                 }
             } else {
                 if (resolveMethod(declaringClass, binding) == null && !isOptional) {
-                    throw new AssertionError(String.format("Method not found: %s.%s%s", declaringClass.getName(), binding.name, binding.argumentsDescriptor));
+                    throw new NoSuchMethodError(String.format("%s.%s%s", declaringClass.getName(), binding.name, binding.argumentsDescriptor));
                 }
             }
             return true;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.options/src/org/graalvm/compiler/options/OptionsParser.java	Wed Nov 13 17:21:31 2019 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.options/src/org/graalvm/compiler/options/OptionsParser.java	Mon Nov 18 12:40:06 2019 -0500
@@ -132,12 +132,19 @@
             throw new IllegalArgumentException(msg.toString());
         }
 
+        Object value = parseOptionValue(desc, uncheckedValue);
+
+        desc.getOptionKey().update(values, value);
+    }
+
+    /** Parses a given option value with a known descriptor. */
+    public static Object parseOptionValue(OptionDescriptor desc, Object uncheckedValue) {
         Class<?> optionType = desc.getOptionValueType();
         Object value;
         if (!(uncheckedValue instanceof String)) {
             if (optionType != uncheckedValue.getClass()) {
                 String type = optionType.getSimpleName();
-                throw new IllegalArgumentException(type + " option '" + name + "' must have " + type + " value, not " + uncheckedValue.getClass() + " [toString: " + uncheckedValue + "]");
+                throw new IllegalArgumentException(type + " option '" + desc.getName() + "' must have " + type + " value, not " + uncheckedValue.getClass() + " [toString: " + uncheckedValue + "]");
             }
             value = uncheckedValue;
         } else {
@@ -148,7 +155,7 @@
                 } else if ("false".equals(valueString)) {
                     value = Boolean.FALSE;
                 } else {
-                    throw new IllegalArgumentException("Boolean option '" + name + "' must have value \"true\" or \"false\", not \"" + uncheckedValue + "\"");
+                    throw new IllegalArgumentException("Boolean option '" + desc.getName() + "' must have value \"true\" or \"false\", not \"" + uncheckedValue + "\"");
                 }
             } else if (optionType == String.class) {
                 value = valueString;
@@ -156,7 +163,7 @@
                 value = ((EnumOptionKey<?>) desc.getOptionKey()).valueOf(valueString);
             } else {
                 if (valueString.isEmpty()) {
-                    throw new IllegalArgumentException("Non empty value required for option '" + name + "'");
+                    throw new IllegalArgumentException("Non empty value required for option '" + desc.getName() + "'");
                 }
                 try {
                     if (optionType == Float.class) {
@@ -168,15 +175,14 @@
                     } else if (optionType == Long.class) {
                         value = Long.valueOf(parseLong(valueString));
                     } else {
-                        throw new IllegalArgumentException("Wrong value for option '" + name + "'");
+                        throw new IllegalArgumentException("Wrong value for option '" + desc.getName() + "'");
                     }
                 } catch (NumberFormatException nfe) {
-                    throw new IllegalArgumentException("Value for option '" + name + "' has invalid number format: " + valueString);
+                    throw new IllegalArgumentException("Value for option '" + desc.getName() + "' has invalid number format: " + valueString);
                 }
             }
         }
-
-        desc.getOptionKey().update(values, value);
+        return value;
     }
 
     private static long parseLong(String v) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/StandardGraphBuilderPlugins.java	Wed Nov 13 17:21:31 2019 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/StandardGraphBuilderPlugins.java	Mon Nov 18 12:40:06 2019 -0500
@@ -1107,11 +1107,20 @@
 
         @Override
         public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver unsafe, ValueNode object, ValueNode offset) {
+            // Opaque mode does not directly impose any ordering constraints with respect to other
+            // variables beyond Plain mode.
+            if (accessKind == AccessKind.OPAQUE && StampTool.isPointerAlwaysNull(object)) {
+                // OFF_HEAP_LOCATION accesses are not floatable => no membars needed for opaque.
+                return apply(b, targetMethod, unsafe, offset);
+            }
             // Emits a null-check for the otherwise unused receiver
             unsafe.get();
             if (accessKind.emitBarriers) {
                 b.add(new MembarNode(accessKind.preReadBarriers));
             }
+            // Raw accesses can be turned into floatable field accesses, the membars preserve the
+            // access mode. In the case of opaque access, and only for opaque, the location of the
+            // wrapping membars can be refined to the field location.
             createUnsafeAccess(object, b, (obj, loc) -> new RawLoadNode(obj, offset, unsafeAccessKind, loc));
             if (accessKind.emitBarriers) {
                 b.add(new MembarNode(accessKind.postReadBarriers));
@@ -1144,12 +1153,21 @@
 
         @Override
         public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver unsafe, ValueNode object, ValueNode offset, ValueNode value) {
+            // Opaque mode does not directly impose any ordering constraints with respect to other
+            // variables beyond Plain mode.
+            if (accessKind == AccessKind.OPAQUE && StampTool.isPointerAlwaysNull(object)) {
+                // OFF_HEAP_LOCATION accesses are not floatable => no membars needed for opaque.
+                return apply(b, targetMethod, unsafe, offset, value);
+            }
             // Emits a null-check for the otherwise unused receiver
             unsafe.get();
             if (accessKind.emitBarriers) {
                 b.add(new MembarNode(accessKind.preWriteBarriers));
             }
             ValueNode maskedValue = b.maskSubWordValue(value, unsafeAccessKind);
+            // Raw accesses can be turned into floatable field accesses, the membars preserve the
+            // access mode. In the case of opaque access, and only for opaque, the location of the
+            // wrapping membars can be refined to the field location.
             createUnsafeAccess(object, b, (obj, loc) -> new RawStoreNode(obj, offset, maskedValue, unsafeAccessKind, loc));
             if (accessKind.emitBarriers) {
                 b.add(new MembarNode(accessKind.postWriteBarriers));
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/MethodHandleNode.java	Wed Nov 13 17:21:31 2019 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/MethodHandleNode.java	Mon Nov 18 12:40:06 2019 -0500
@@ -259,7 +259,7 @@
 
         Assumptions assumptions = adder.getAssumptions();
         ResolvedJavaMethod realTarget = null;
-        if (target.canBeStaticallyBound()) {
+        if (target.canBeStaticallyBound() || intrinsicMethod == IntrinsicMethod.LINK_TO_SPECIAL) {
             realTarget = target;
         } else {
             ResolvedJavaType targetType = target.getDeclaringClass();
--- a/src/jdk.zipfs/share/classes/jdk/nio/zipfs/ZipFileSystem.java	Wed Nov 13 17:21:31 2019 -0500
+++ b/src/jdk.zipfs/share/classes/jdk/nio/zipfs/ZipFileSystem.java	Mon Nov 18 12:40:06 2019 -0500
@@ -2089,7 +2089,7 @@
     // Releases the specified inflater to the list of available inflaters.
     private void releaseDeflater(Deflater def) {
         synchronized (deflaters) {
-            if (inflaters.size() < MAX_FLATER) {
+            if (deflaters.size() < MAX_FLATER) {
                def.reset();
                deflaters.add(def);
             } else {
--- a/test/hotspot/jtreg/ProblemList.txt	Wed Nov 13 17:21:31 2019 -0500
+++ b/test/hotspot/jtreg/ProblemList.txt	Mon Nov 18 12:40:06 2019 -0500
@@ -54,7 +54,6 @@
 compiler/types/correctness/OffTest.java         8225620 solaris-sparcv9
 
 compiler/c2/Test6852078.java 8194310 generic-all
-compiler/c2/Test8004741.java 8214904 generic-all
 
 compiler/cpuflags/TestAESIntrinsicsOnSupportedConfig.java 8190680 generic-all
 
@@ -206,16 +205,4 @@
 
 vmTestbase/nsk/jdwp/ThreadReference/ForceEarlyReturn/forceEarlyReturn001/forceEarlyReturn001.java 7199837 generic-all
 
-vmTestbase/nsk/jvmti/scenarios/allocation/AP01/ap01t001/TestDescription.java 8233549 generic-all
-vmTestbase/nsk/jvmti/scenarios/allocation/AP04/ap04t001/TestDescription.java 8233549 generic-all
-vmTestbase/nsk/jvmti/scenarios/allocation/AP04/ap04t002/TestDescription.java 8233549 generic-all
-vmTestbase/nsk/jvmti/scenarios/allocation/AP04/ap04t003/TestDescription.java 8233549 generic-all
-vmTestbase/nsk/jvmti/scenarios/allocation/AP10/ap10t001/TestDescription.java 8233549 generic-all
-vmTestbase/nsk/jvmti/scenarios/allocation/AP12/ap12t001/TestDescription.java 8233549 generic-all
-vmTestbase/nsk/jvmti/scenarios/capability/CM02/cm02t001/TestDescription.java 8233549 generic-all
-vmTestbase/nsk/jvmti/scenarios/events/EM02/em02t002/TestDescription.java 8233549 generic-all
-vmTestbase/nsk/jvmti/scenarios/events/EM02/em02t003/TestDescription.java 8233549 generic-all
-vmTestbase/nsk/jvmti/scenarios/events/EM02/em02t005/TestDescription.java 8233549 generic-all
-vmTestbase/nsk/jvmti/scenarios/events/EM02/em02t006/TestDescription.java 8233549 generic-all
-vmTestbase/nsk/jvmti/scenarios/events/EM07/em07t002/TestDescription.java 8233549 generic-all
 #############################################################################
--- a/test/hotspot/jtreg/TEST.groups	Wed Nov 13 17:21:31 2019 -0500
+++ b/test/hotspot/jtreg/TEST.groups	Mon Nov 18 12:40:06 2019 -0500
@@ -322,6 +322,7 @@
  -runtime/cds/appcds/javaldr/GCSharedStringsDuringDump.java \
  -runtime/cds/appcds/javaldr/HumongousDuringDump.java \
  -runtime/cds/appcds/sharedStrings \
+ -runtime/cds/appcds/ArchiveRelocationTest.java \
  -runtime/cds/appcds/DumpClassList.java \
  -runtime/cds/appcds/ExtraSymbols.java \
  -runtime/cds/appcds/LongClassListPath.java \
@@ -332,6 +333,15 @@
  -runtime/cds/appcds/UnusedCPDuringDump.java \
  -runtime/cds/appcds/VerifierTest_1B.java
 
+hotspot_cds_relocation = \
+  gc/g1/TestSharedArchiveWithPreTouch.java \
+  runtime/cds \
+  runtime/modules/ModulesSymLink.java \
+  runtime/modules/PatchModule/PatchModuleCDS.java \
+  runtime/modules/PatchModule/PatchModuleClassList.java \
+  runtime/NMT \
+  serviceability/sa
+
 # A subset of AppCDS tests to be run in tier1
 tier1_runtime_appcds = \
   runtime/cds/appcds/HelloTest.java \
--- a/test/hotspot/jtreg/compiler/c2/Test8004741.java	Wed Nov 13 17:21:31 2019 -0500
+++ b/test/hotspot/jtreg/compiler/c2/Test8004741.java	Mon Nov 18 12:40:06 2019 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -22,22 +22,33 @@
  */
 
 /*
- * @test Test8004741.java
+ * @test
  * @bug 8004741
  * @summary Missing compiled exception handle table entry for multidimensional array allocation
  *
  * @requires !vm.graal.enabled
+ * @library /test/lib
+ *
+ * @build sun.hotspot.WhiteBox
+ * @run driver ClassFileInstaller sun.hotspot.WhiteBox
+ *                                sun.hotspot.WhiteBox$WhiteBoxPermission
+ *
  * @run main/othervm -Xmx128m -Xbatch -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockDiagnosticVMOptions
  *    -XX:-TieredCompilation -XX:+StressCompiledExceptionHandlers
  *    -XX:+SafepointALot -XX:GuaranteedSafepointInterval=100
+ *    -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI
  *    compiler.c2.Test8004741
+ *
  * @run main/othervm -Xmx128m -Xbatch -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockDiagnosticVMOptions
  *    -XX:-TieredCompilation -XX:+StressCompiledExceptionHandlers
+ *    -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI
  *    compiler.c2.Test8004741
  */
 
 package compiler.c2;
 
+import sun.hotspot.WhiteBox;
+
 public class Test8004741 extends Thread {
 
   static int passed = 0;
@@ -58,7 +69,7 @@
     } catch (ThreadDeath e) {
       System.out.println("test got ThreadDeath");
       passed++;
-      throw(e);
+      throw e;
     }
     return ar;
   }
@@ -84,15 +95,11 @@
         try {
           progressLock.wait();
         } catch (InterruptedException e) {
-          e.printStackTrace();
-          System.out.println("unexpected InterruptedException");
-          fail();
+          throw new Error("unexpected InterruptedException", e);
         }
       }
       if (progressState > state) {
-        System.out.println("unexpected test state change, expected " +
-                            state + " but saw " + progressState);
-        fail();
+        throw new Error("unexpected test state change, state = " + state + ", progressState = " + progressState);
       }
     }
   }
@@ -114,9 +121,7 @@
     } catch (ThreadDeath e) {
       // nothing to say, passing was incremented by the test.
     } catch (Throwable e) {
-      e.printStackTrace();
-      System.out.println("unexpected Throwable " + e);
-      fail();
+      throw new Error("unexpected Throwable " + e, e);
     }
     toState(STOPPING);
   }
@@ -144,24 +149,22 @@
       test(2, 100);
     }
 
-    // Will this sleep help ensure that the compiler is run?
-    Thread.sleep(500);
-    passed = 0;
+    var method = Test8004741.class.getDeclaredMethod("test", int.class, int.class);
+    if (!WhiteBox.getWhiteBox().isMethodCompiled(method)) {
+        throw new Error("test method didn't get compiled");
+    }
 
     try {
       test(-1, 100);
-      System.out.println("Missing NegativeArraySizeException #1");
-      fail();
-    } catch ( java.lang.NegativeArraySizeException e ) {
+      throw new AssertionError("Missing NegativeArraySizeException");
+    } catch (NegativeArraySizeException e) {
       System.out.println("Saw expected NegativeArraySizeException #1");
     }
 
     try {
       test(100, -1);
-      fail();
-      System.out.println("Missing NegativeArraySizeException #2");
-      fail();
-    } catch ( java.lang.NegativeArraySizeException e ) {
+      throw new AssertionError("Missing NegativeArraySizeException");
+    } catch (NegativeArraySizeException e) {
       System.out.println("Saw expected NegativeArraySizeException #2");
     }
 
@@ -169,23 +172,10 @@
      * as long as it does not crash (the outcome if the exception range
      * table entry for the array allocation is missing).
      */
-    int N = 12;
-    for (int n = 0; n < N; n++) {
+    passed = 0;
+    int limit = 6;
+    while (passed != limit) {
       threadTest();
     }
-
-    if (passed > N/2) {
-      System.out.println("Saw " + passed + " out of " + N + " possible ThreadDeath hits");
-      System.out.println("PASSED");
-    } else {
-      System.out.println("Too few ThreadDeath hits; expected at least " + N/2 +
-                         " but saw only " + passed);
-      fail();
-    }
   }
-
-  static void fail() {
-    System.out.println("FAILED");
-    System.exit(97);
-  }
-};
+}
--- a/test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/VirtualObjectTestBase.java	Wed Nov 13 17:21:31 2019 -0500
+++ b/test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/VirtualObjectTestBase.java	Mon Nov 18 12:40:06 2019 -0500
@@ -97,9 +97,9 @@
         JavaValue[] values = getJavaValues(kinds);
         test(simple, values, kinds, false);
 
-        // Spread a long value across two int fields
+        // Spread a long value across two int fields starting at an aligned field
         kinds = Arrays.copyOf(fieldKinds, fieldKinds.length - 1);
-        kinds[1] = JavaKind.Long;
+        kinds[fields[0].getOffset() % 8 == 0 ? 0 : 1] = JavaKind.Long;
         test(simple, getJavaValues(kinds), kinds, false);
 
         // Produce a long value for the final int field so there is no matching int field for the
--- a/test/hotspot/jtreg/gc/shenandoah/jvmti/TestHeapDump.java	Wed Nov 13 17:21:31 2019 -0500
+++ b/test/hotspot/jtreg/gc/shenandoah/jvmti/TestHeapDump.java	Mon Nov 18 12:40:06 2019 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, 2018, Red Hat, Inc. All rights reserved.
+ * Copyright (c) 2017, 2019, Red Hat, Inc. All rights reserved.
  *
  * This code is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License version 2 only, as
@@ -40,6 +40,8 @@
  * @run main/othervm/native/timeout=300 -agentlib:TestHeapDump -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx128m -XX:ShenandoahGCHeuristics=aggressive -XX:-UseCompressedOops TestHeapDump
  */
 
+import java.lang.ref.Reference;
+
 public class TestHeapDump {
 
     private static final int NUM_ITER = 10000;
@@ -86,6 +88,8 @@
                 throw new RuntimeException("Expected " + EXPECTED_OBJECTS + " objects, but got " + numObjs);
             }
         }
+        Reference.reachabilityFence(array);
+        Reference.reachabilityFence(localRoot);
     }
 
     // We look for the instances of this class during the heap scan
--- a/test/hotspot/jtreg/runtime/cds/SpaceUtilizationCheck.java	Wed Nov 13 17:21:31 2019 -0500
+++ b/test/hotspot/jtreg/runtime/cds/SpaceUtilizationCheck.java	Mon Nov 18 12:40:06 2019 -0500
@@ -73,8 +73,8 @@
                 Matcher matcher = pattern.matcher(line);
                 if (matcher.find()) {
                     String name = matcher.group(1);
-                    if (name.equals("s0") || name.equals("s1")) {
-                      // String regions are listed at the end and they may not be fully occupied.
+                    if (name.equals("bm")) {
+                      // Bitmap space does not have a requested address.
                       break;
                     } else {
                       System.out.println("Checking " + name + " in : " + line);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/cds/appcds/ArchiveRelocationTest.java	Mon Nov 18 12:40:06 2019 -0500
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @comment the test uses -XX:ArchiveRelocationMode=1 to force relocation.
+ * @requires vm.cds
+ * @summary Testing relocation of CDS archive (during both dump time and run time)
+ * @comment JDK-8231610 Relocate the CDS archive if it cannot be mapped to the requested address
+ * @bug 8231610
+ * @library /test/lib /test/hotspot/jtreg/runtime/cds/appcds/test-classes
+ * @build Hello
+ * @run driver ClassFileInstaller -jar hello.jar Hello
+ * @run driver ArchiveRelocationTest
+ */
+
+import jdk.test.lib.process.OutputAnalyzer;
+import jtreg.SkippedException;
+
+public class ArchiveRelocationTest {
+    public static void main(String... args) throws Exception {
+        try {
+            test(true,  false);
+            test(false, true);
+            test(true,  true);
+        } catch (SkippedException s) {
+            s.printStackTrace();
+            throw new RuntimeException("Archive mapping should always succeed after JDK-8231610 (did the machine run out of memory?)");
+        }
+    }
+
+    static int caseCount = 0;
+
+    // dump_reloc - force relocation of archive during dump time?
+    // run_reloc  - force relocation of archive during run time?
+    static void test(boolean dump_reloc, boolean run_reloc) throws Exception {
+        caseCount += 1;
+        System.out.println("============================================================");
+        System.out.println("case = " + caseCount + ", dump = " + dump_reloc
+                           + ", run = " + run_reloc);
+        System.out.println("============================================================");
+
+
+        String appJar = ClassFileInstaller.getJarPath("hello.jar");
+        String mainClass = "Hello";
+        String forceRelocation = "-XX:ArchiveRelocationMode=1";
+        String dumpRelocArg = dump_reloc ? forceRelocation : "-showversion";
+        String runRelocArg  = run_reloc  ? forceRelocation : "-showversion";
+        String logArg = "-Xlog:cds=debug,cds+reloc=debug";
+        String unlockArg = "-XX:+UnlockDiagnosticVMOptions";
+
+        OutputAnalyzer out = TestCommon.dump(appJar,
+                                             TestCommon.list(mainClass),
+                                             unlockArg, dumpRelocArg, logArg);
+        if (dump_reloc) {
+            out.shouldContain("ArchiveRelocationMode == 1: always allocate class space at an alternative address");
+            out.shouldContain("Relocating archive from");
+        }
+
+        TestCommon.run("-cp", appJar, unlockArg, runRelocArg, logArg,  mainClass)
+            .assertNormalExit(output -> {
+                    if (run_reloc) {
+                        output.shouldContain("runtime archive relocation start");
+                        output.shouldContain("runtime archive relocation done");
+                    }
+                });
+    }
+}
--- a/test/hotspot/jtreg/runtime/cds/appcds/JarBuilder.java	Wed Nov 13 17:21:31 2019 -0500
+++ b/test/hotspot/jtreg/runtime/cds/appcds/JarBuilder.java	Mon Nov 18 12:40:06 2019 -0500
@@ -232,7 +232,7 @@
 
         executeProcess(keyTool,
             "-genkey", "-keystore", "./keystore", "-alias", "mykey",
-            "-storepass", "abc123", "-keypass", "abc123",
+            "-storepass", "abc123", "-keypass", "abc123", "-keyalg", "dsa",
             "-dname", "CN=jvmtest")
             .shouldHaveExitValue(0);
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/DynamicArchiveRelocationTest.java	Mon Nov 18 12:40:06 2019 -0500
@@ -0,0 +1,129 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+/**
+ * @test
+ * @comment the test uses -XX:ArchiveRelocationMode=1 to force relocation.
+ * @requires vm.cds
+ * @summary Testing relocation of dynamic CDS archive (during both dump time and run time)
+ * @comment JDK-8231610 Relocate the CDS archive if it cannot be mapped to the requested address
+ * @bug 8231610
+ * @library /test/lib /test/hotspot/jtreg/runtime/cds/appcds /test/hotspot/jtreg/runtime/cds/appcds/test-classes
+ * @build Hello
+ * @run driver ClassFileInstaller -jar hello.jar Hello
+ * @run driver DynamicArchiveRelocationTest
+ */
+
+import jdk.test.lib.process.OutputAnalyzer;
+import jtreg.SkippedException;
+
+public class DynamicArchiveRelocationTest extends DynamicArchiveTestBase {
+    public static void main(String... args) throws Exception {
+        try {
+            testOuter(false);
+            testOuter(true);
+        } catch (SkippedException s) {
+            s.printStackTrace();
+            throw new RuntimeException("Archive mapping should always succeed after JDK-8231610 (did the machine run out of memory?)");
+        }
+    }
+
+    static void testOuter(boolean dump_base_reloc) throws Exception {
+        testInner(dump_base_reloc, true,  false);
+        testInner(dump_base_reloc, false, true);
+        testInner(dump_base_reloc, true,  true);
+    }
+
+    static boolean dump_base_reloc, dump_top_reloc, run_reloc;
+
+    // dump_base_reloc - force relocation of archive when dumping base archive
+    // dump_top_reloc  - force relocation of archive when dumping top  archive
+    // run_reloc       - force relocation of archive when running
+    static void testInner(boolean dump_base_reloc, boolean dump_top_reloc, boolean run_reloc) throws Exception {
+        DynamicArchiveRelocationTest.dump_base_reloc = dump_base_reloc;
+        DynamicArchiveRelocationTest.dump_top_reloc  = dump_top_reloc;
+        DynamicArchiveRelocationTest.run_reloc       = run_reloc;
+
+        runTest(DynamicArchiveRelocationTest::doTest);
+    }
+
+    static int caseCount = 0;
+    static void doTest() throws Exception {
+        caseCount += 1;
+        System.out.println("============================================================");
+        System.out.println("case = " + caseCount + ", base = " + dump_base_reloc
+                           + ", top = " + dump_top_reloc
+                           + ", run = " + run_reloc);
+        System.out.println("============================================================");
+
+        String appJar = ClassFileInstaller.getJarPath("hello.jar");
+        String mainClass = "Hello";
+        String forceRelocation = "-XX:ArchiveRelocationMode=1";
+        String dumpBaseRelocArg = dump_base_reloc ? forceRelocation : "-showversion";
+        String dumpTopRelocArg  = dump_top_reloc  ? forceRelocation : "-showversion";
+        String runRelocArg      = run_reloc       ? forceRelocation : "-showversion";
+        String logArg = "-Xlog:cds=debug,cds+reloc=debug";
+
+        String baseArchiveName = getNewArchiveName("base");
+        String topArchiveName  = getNewArchiveName("top");
+
+        String runtimeMsg1 = "runtime archive relocation start";
+        String runtimeMsg2 = "runtime archive relocation done";
+        String unlockArg = "-XX:+UnlockDiagnosticVMOptions";
+
+        // (1) Dump base archive (static)
+
+        OutputAnalyzer out = dumpBaseArchive(baseArchiveName, unlockArg, dumpBaseRelocArg, logArg);
+        if (dump_base_reloc) {
+            out.shouldContain("ArchiveRelocationMode == 1: always allocate class space at an alternative address");
+            out.shouldContain("Relocating archive from");
+        }
+
+        // (2) Dump top archive (dynamic)
+
+        dump2(baseArchiveName, topArchiveName,
+              unlockArg,
+              dumpTopRelocArg,
+              logArg,
+              "-cp", appJar, mainClass)
+            .assertNormalExit(output -> {
+                    if (dump_top_reloc) {
+                        output.shouldContain(runtimeMsg1);
+                        output.shouldContain(runtimeMsg2);
+                    }
+                });
+
+        run2(baseArchiveName, topArchiveName,
+             unlockArg,
+             runRelocArg,
+             logArg,
+            "-cp", appJar, mainClass)
+            .assertNormalExit(output -> {
+                    if (run_reloc) {
+                        output.shouldContain(runtimeMsg1);
+                        output.shouldContain(runtimeMsg2);
+                    }
+                });
+    }
+}
--- a/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/DynamicArchiveTestBase.java	Wed Nov 13 17:21:31 2019 -0500
+++ b/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/DynamicArchiveTestBase.java	Mon Nov 18 12:40:06 2019 -0500
@@ -134,7 +134,7 @@
      * Dump the base archive. The JDK's default class list is used (unless otherwise specified
      * in cmdLineSuffix).
      */
-    public static void dumpBaseArchive(String baseArchiveName, String ... cmdLineSuffix)
+    public static OutputAnalyzer dumpBaseArchive(String baseArchiveName, String ... cmdLineSuffix)
         throws Exception
     {
         CDSOptions opts = new CDSOptions();
@@ -143,6 +143,7 @@
         opts.addSuffix("-Djava.class.path=");
         OutputAnalyzer out = CDSTestUtils.createArchive(opts);
         CDSTestUtils.checkDump(out);
+        return out;
     }
 
     /**
--- a/test/jdk/com/sun/jdi/JdwpListenTest.java	Wed Nov 13 17:21:31 2019 -0500
+++ b/test/jdk/com/sun/jdi/JdwpListenTest.java	Mon Nov 18 12:40:06 2019 -0500
@@ -54,6 +54,10 @@
 
     private static final boolean IsWindows = System.getProperty("os.name").toLowerCase().contains("windows");
 
+    // Set to true to allow testing of attach from wrong address (expected to fail).
+    // It's off by default as it causes test time increase and test interference (see JDK-8231915).
+    private static boolean allowNegativeTesting = false;
+
     public static void main(String[] args) throws Exception {
         List<InetAddress> addresses = getAddresses();
 
@@ -87,6 +91,11 @@
             throws IOException {
         log("\nTest: listen at " + listenAddress + ", attaching from " + connectAddress
                 + ", expected: " + (expectedResult ? "SUCCESS" : "FAILURE"));
+        if (!expectedResult && !allowNegativeTesting) {
+            log("SKIPPED: negative testing is disabled");
+            return;
+        }
+
         log("Starting listening debuggee at " + listenAddress);
         try (Debuggee debuggee = Debuggee.launcher("HelloWorld").setAddress(listenAddress + ":0").launch()) {
             log("Debuggee is listening on " + listenAddress + ":" + debuggee.getAddress());
@@ -103,6 +112,7 @@
                 }
             }
         }
+        log("PASSED");
     }
 
     private static void addAddr(List<InetAddress> list, InetAddress addr) {
--- a/test/jdk/java/lang/invoke/TryFinallyTest.java	Wed Nov 13 17:21:31 2019 -0500
+++ b/test/jdk/java/lang/invoke/TryFinallyTest.java	Mon Nov 18 12:40:06 2019 -0500
@@ -24,8 +24,8 @@
  */
 
 /* @test
- * @bug 8139885 8150824 8150825 8194238
- * @run testng/othervm -ea -esa test.java.lang.invoke.TryFinallyTest
+ * @bug 8139885 8150824 8150825 8194238 8233920
+ * @run testng/othervm -ea -esa -Xverify:all test.java.lang.invoke.TryFinallyTest
  */
 
 package test.java.lang.invoke;
@@ -55,6 +55,41 @@
         assertEquals("Hello, world!", hello.invoke("world"));
     }
 
+    @DataProvider
+    static Object[][] tryFinallyArgs() {
+        return new Object[][] {
+                { boolean.class, true },
+                { byte.class, (byte) 2 },
+                { short.class, (short) 2 },
+                { char.class, (char) 2 },
+                { int.class, 2 },
+                { long.class, 2L },
+                { float.class, 2f },
+                { double.class, 2D },
+                { Object.class, new Object() }
+        };
+    }
+
+    @Test(dataProvider = "tryFinallyArgs")
+    public static void testTryFinally(Class<?> argType, Object arg) throws Throwable {
+        MethodHandle identity = MethodHandles.identity(argType);
+        MethodHandle tryFinally = MethodHandles.tryFinally(
+                identity,
+                MethodHandles.dropArguments(identity, 0, Throwable.class));
+        assertEquals(methodType(argType, argType), tryFinally.type());
+        assertEquals(arg, tryFinally.invoke(arg));
+    }
+
+    @Test(dataProvider = "tryFinallyArgs", expectedExceptions = TryFinally.T1.class)
+    public static void testTryFinallyException(Class<?> argType, Object arg) throws Throwable {
+        MethodHandle identity = TryFinally.MH_throwingTargetIdentity.asType(methodType(argType, argType));
+        MethodHandle tryFinally = MethodHandles.tryFinally(
+                identity,
+                MethodHandles.dropArguments(identity, 0, TryFinally.T1.class));
+        assertEquals(methodType(argType, argType), tryFinally.type());
+        tryFinally.invoke(arg); // should throw
+    }
+
     @Test
     public static void testTryFinallyVoid() throws Throwable {
         MethodHandle tfVoid = MethodHandles.tryFinally(TryFinally.MH_print, TryFinally.MH_printMore);
@@ -175,6 +210,10 @@
             throw new T1();
         }
 
+        static Object throwingTargetIdentity(Object o) throws Throwable {
+            throw new T1();
+        }
+
         static void catchingCleanup(T2 t) throws Throwable {
         }
 
@@ -189,6 +228,7 @@
         static final MethodType MT_voidTarget = methodType(void.class);
         static final MethodType MT_voidCleanup = methodType(void.class, Throwable.class);
         static final MethodType MT_throwingTarget = methodType(void.class);
+        static final MethodType MT_throwingTargetIdentity = methodType(Object.class, Object.class);
         static final MethodType MT_catchingCleanup = methodType(void.class, T2.class);
 
         static final MethodHandle MH_greet;
@@ -200,6 +240,7 @@
         static final MethodHandle MH_voidTarget;
         static final MethodHandle MH_voidCleanup;
         static final MethodHandle MH_throwingTarget;
+        static final MethodHandle MH_throwingTargetIdentity;
         static final MethodHandle MH_catchingCleanup;
 
         static final MethodHandle MH_dummyTarget;
@@ -219,6 +260,7 @@
                 MH_voidTarget = LOOKUP.findStatic(TRY_FINALLY, "voidTarget", MT_voidTarget);
                 MH_voidCleanup = LOOKUP.findStatic(TRY_FINALLY, "voidCleanup", MT_voidCleanup);
                 MH_throwingTarget = LOOKUP.findStatic(TRY_FINALLY, "throwingTarget", MT_throwingTarget);
+                MH_throwingTargetIdentity = LOOKUP.findStatic(TRY_FINALLY, "throwingTargetIdentity", MT_throwingTargetIdentity);
                 MH_catchingCleanup = LOOKUP.findStatic(TRY_FINALLY, "catchingCleanup", MT_catchingCleanup);
                 MH_dummyTarget = MethodHandles.dropArguments(MH_voidTarget, 0, int.class, long.class, Object.class,
                         int.class, long.class, Object.class);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/net/DatagramSocket/AddressNotSet.java	Mon Nov 18 12:40:06 2019 -0500
@@ -0,0 +1,150 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8233141
+ * @summary DatagramSocket.send should throw IllegalArgumentException
+ *          when the packet address is not correctly set.
+ * @run main AddressNotSet
+ */
+
+import java.net.DatagramPacket;
+import java.net.DatagramSocket;
+import java.net.InetAddress;
+import java.net.MulticastSocket;
+import java.net.SocketAddress;
+import java.nio.channels.DatagramChannel;
+
+import static java.lang.System.out;
+
+public class AddressNotSet {
+
+    final InetAddress loopbackAddress = InetAddress.getLoopbackAddress();
+    final DatagramSocket serversock;
+    int i;
+    AddressNotSet() throws Exception {
+        serversock = new DatagramSocket(0, loopbackAddress);
+    }
+
+    public static void main (String args[]) throws Exception {
+        new AddressNotSet().run();
+    }
+
+    public void run() throws Exception {
+        try (var ss = serversock) {
+            try (DatagramSocket sock = new DatagramSocket()) {
+                test(sock);
+            }
+            try (DatagramSocket sock = new MulticastSocket()) {
+                test(sock);
+            }
+            try (DatagramSocket sock = DatagramChannel.open().socket()) {
+                test(sock);
+            }
+        }
+    }
+
+    private void test(DatagramSocket sock) throws Exception {
+        out.println("Testing with " + sock.getClass());
+        InetAddress addr = loopbackAddress;
+        byte[] buf;
+        DatagramPacket p;
+        int port = serversock.getLocalPort();
+        SocketAddress connectedAddress = serversock.getLocalSocketAddress();
+
+        out.println("Checking send to non-connected address ...");
+        try {
+            out.println("Checking send with no packet address");
+            buf = ("Hello, server"+(++i)).getBytes();
+            p = new DatagramPacket(buf, buf.length);
+            sock.send(p);
+            throw new AssertionError("Expected IllegalArgumentException not received");
+        } catch (IllegalArgumentException x) {
+            out.println("Got expected exception: " + x);
+        }
+
+        out.println("Checking send to valid address");
+        buf = ("Hello, server"+(++i)).getBytes();
+        p = new DatagramPacket(buf, buf.length, addr, port);
+        sock.send(p);
+        serversock.receive(p);
+
+        out.println("Connecting to server address: " + connectedAddress);
+        sock.connect(connectedAddress);
+
+        try {
+            out.println("Checking send with different address than connected");
+            buf = ("Hello, server"+(++i)).getBytes();
+            p = new DatagramPacket(buf, buf.length, addr, port+1);
+            sock.send(p);
+            throw new AssertionError("Expected IllegalArgumentException not received");
+        } catch (IllegalArgumentException x) {
+            out.println("Got expected exception: " + x);
+        }
+
+        out.println("Checking send to valid address");
+        buf = ("Hello, server"+(++i)).getBytes();
+        p = new DatagramPacket(buf, buf.length, addr, port);
+        sock.send(p);
+        serversock.receive(p);
+
+        if (sock instanceof MulticastSocket) {
+            sock.disconnect();
+            testTTL((MulticastSocket)sock);
+        }
+    }
+
+    private void testTTL(MulticastSocket sock) throws Exception {
+        out.println("Testing deprecated send TTL with " + sock.getClass());
+        final byte ttl = 100;
+        InetAddress addr = loopbackAddress;
+        byte[] buf;
+        DatagramPacket p;
+        int port = serversock.getLocalPort();
+
+        out.println("Checking send to non-connected address ...");
+        try {
+            out.println("Checking send with no packet address");
+            buf = ("Hello, server"+(++i)).getBytes();
+            p = new DatagramPacket(buf, buf.length);
+            sock.send(p,ttl);
+            throw new AssertionError("Expected IllegalArgumentException not received");
+        } catch (IllegalArgumentException x) {
+            out.println("Got expected exception: " + x);
+        }
+
+        out.println("Connecting to connected address: " + sock);
+        sock.connect(addr, port);
+
+        try {
+            out.println("Checking send with different address than connected");
+            buf = ("Hello, server"+(++i)).getBytes();
+            p = new DatagramPacket(buf, buf.length, addr, port+1);
+            sock.send(p, ttl);
+            throw new AssertionError("Expected IllegalArgumentException not received");
+        } catch (IllegalArgumentException x) {
+            out.println("Got expected exception: " + x);
+        }
+    }
+}
--- a/test/jdk/java/net/DatagramSocket/SendDatagramToBadAddress.java	Wed Nov 13 17:21:31 2019 -0500
+++ b/test/jdk/java/net/DatagramSocket/SendDatagramToBadAddress.java	Mon Nov 18 12:40:06 2019 -0500
@@ -110,12 +110,17 @@
     }
 
     public void run() throws Exception {
-
         if (OSsupportsFeature()) {
             print ("running on OS that supports ICMP port unreachable");
         }
+        try (DatagramSocket sock = new DatagramSocket()) {
+            test(sock);
+        }
+    }
+
+    private void test(DatagramSocket sock) throws Exception {
+        print("Testing with " + sock.getClass());
         InetAddress addr = InetAddress.getLoopbackAddress();
-        DatagramSocket sock = new DatagramSocket();
         DatagramSocket serversock = new DatagramSocket(0);
         DatagramPacket p;
         byte[] buf;
--- a/test/jdk/java/net/MulticastSocket/SetLoopbackMode.java	Wed Nov 13 17:21:31 2019 -0500
+++ b/test/jdk/java/net/MulticastSocket/SetLoopbackMode.java	Mon Nov 18 12:40:06 2019 -0500
@@ -33,7 +33,6 @@
 
 import java.net.*;
 import java.io.IOException;
-import java.util.Enumeration;
 import jdk.test.lib.NetworkConfiguration;
 
 public class SetLoopbackMode {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/net/MulticastSocket/SetLoopbackModeIPv4.java	Mon Nov 18 12:40:06 2019 -0500
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2001, 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 4686717
+ * @summary Test MulticastSocket.setLoopbackMode with IPv4 addresses
+ * @library /test/lib
+ * @build jdk.test.lib.NetworkConfiguration
+ *        jdk.test.lib.Platform
+ *        SetLoopbackMode
+ *        SetLoopbackModeIPv4
+ * @run main/othervm -Djava.net.preferIPv4Stack=true SetLoopbackModeIPv4
+ */
+
+import jdk.test.lib.net.IPSupport;
+
+public class SetLoopbackModeIPv4 {
+    public static void main(String[] args) throws Exception {
+        IPSupport.throwSkippedExceptionIfNonOperational();
+        SetLoopbackMode.main(args);
+    }
+}
+
+
--- a/test/jdk/java/net/SocketOption/AfterClose.java	Wed Nov 13 17:21:31 2019 -0500
+++ b/test/jdk/java/net/SocketOption/AfterClose.java	Mon Nov 18 12:40:06 2019 -0500
@@ -34,8 +34,10 @@
 import java.lang.reflect.Method;
 import java.net.DatagramSocket;
 import java.net.MulticastSocket;
+import java.net.NetworkInterface;
 import java.net.ServerSocket;
 import java.net.Socket;
+import java.net.SocketException;
 import java.net.SocketOption;
 import java.nio.channels.DatagramChannel;
 import java.nio.channels.ServerSocketChannel;
@@ -45,6 +47,7 @@
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.stream.Collectors;
 import org.testng.annotations.DataProvider;
 import org.testng.annotations.Test;
 import static java.lang.Boolean.*;
@@ -57,9 +60,26 @@
 
     static Map<SocketOption<?>,List<Object>> OPTION_VALUES_MAP = optionValueMap();
 
+    static boolean supportsMulticast(NetworkInterface ni) {
+        try {
+            return ni.supportsMulticast();
+        } catch (SocketException e) {
+            return false;
+        }
+    }
+
+    static List<Object> listNetworkInterfaces() {
+        try {
+            return NetworkInterface.networkInterfaces()
+                    .filter(AfterClose::supportsMulticast)
+                    .collect(Collectors.toList());
+        } catch (Exception e) { }
+        return List.of();
+    }
+
     static Map<SocketOption<?>,List<Object>> optionValueMap() {
         Map<SocketOption<?>,List<Object>> map = new HashMap<>();
-        map.put(IP_MULTICAST_IF,   listOf(TRUE, FALSE) );
+        map.put(IP_MULTICAST_IF,   listNetworkInterfaces() );
         map.put(IP_MULTICAST_LOOP, listOf(TRUE, FALSE) );
         map.put(IP_MULTICAST_TTL,  listOf(0, 100, 255) );
         map.put(IP_TOS,            listOf(0, 101, 255) );
--- a/test/jdk/java/security/Policy/ExtensiblePolicy/ExtensiblePolicyWithJarTest.java	Wed Nov 13 17:21:31 2019 -0500
+++ b/test/jdk/java/security/Policy/ExtensiblePolicy/ExtensiblePolicyWithJarTest.java	Mon Nov 18 12:40:06 2019 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -69,6 +69,7 @@
         // create key pair for jar signing
         ProcessTools.executeCommand(KEYTOOL,
                 "-genkey",
+                "-keyalg", "DSA",
                 "-alias", ALIAS,
                 "-keystore", KEYSTORE,
                 "-storetype", "JKS",
--- a/test/jdk/java/security/Policy/SignedJar/SignedJarTest.java	Wed Nov 13 17:21:31 2019 -0500
+++ b/test/jdk/java/security/Policy/SignedJar/SignedJarTest.java	Mon Nov 18 12:40:06 2019 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -66,6 +66,7 @@
         //Creating first key , keystore both.jks
         ProcessTools.executeCommand(KEYTOOL,
                 "-genkey",
+                "-keyalg", "DSA",
                 "-alias", "first",
                 "-keystore", KEYSTORE1,
                 "-keypass", PASSWORD,
@@ -76,6 +77,7 @@
         //Creating Second key, keystore both.jks
         ProcessTools.executeCommand(KEYTOOL,
                 "-genkey",
+                "-keyalg", "DSA",
                 // "-storetype","JKS",
                 "-alias", "second",
                 "-keystore", KEYSTORE1,
--- a/test/jdk/jdk/jfr/event/runtime/TestClassUnloadEvent.java	Wed Nov 13 17:21:31 2019 -0500
+++ b/test/jdk/jdk/jfr/event/runtime/TestClassUnloadEvent.java	Mon Nov 18 12:40:06 2019 -0500
@@ -47,12 +47,6 @@
  * @run main/othervm -Xlog:class+unload -Xlog:gc -Xmx16m jdk.jfr.event.runtime.TestClassUnloadEvent
  */
 
-/**
- * System.gc() will trigger class unloading if -XX:+ExplicitGCInvokesConcurrent is NOT set.
- * If this flag is set G1 will never unload classes on System.gc().
- * As far as the "jfr" key guarantees no VM flags are set from the outside
- * it should be enough with System.gc().
- */
 public final class TestClassUnloadEvent {
     private final static String TEST_CLASS_NAME = "jdk.jfr.event.runtime.TestClasses";
     private final static String EVENT_PATH = EventNames.ClassUnload;
--- a/test/jdk/jdk/nio/zipfs/CRCWriteTest.java	Wed Nov 13 17:21:31 2019 -0500
+++ b/test/jdk/jdk/nio/zipfs/CRCWriteTest.java	Mon Nov 18 12:40:06 2019 -0500
@@ -57,10 +57,10 @@
      * can be used successfully with the OutputStream write methods
      */
     @Test
-    private void zipFsOsDeflatedWriteTest() throws Exception {
+    public void zipFsOsDeflatedWriteTest() throws Exception {
         Files.deleteIfExists(JAR_FILE);
         String[] msg = {"Hello ", "Tennis Anyone", "!!!!"};
-        Entry e0 = Entry.of("Entry-0", ZipEntry.DEFLATED, Arrays.toString(msg));
+        Entry e0 = Entry.of("Entry-0", ZipEntry.DEFLATED, String.join("",msg));
 
         try (FileSystem zipfs = FileSystems.newFileSystem(JAR_FILE,
                 Map.of("create", "true"))) {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/jdk/nio/zipfs/ReleaseDeflater.java	Mon Nov 18 12:40:06 2019 -0500
@@ -0,0 +1,96 @@
+/*
+ * Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+/*
+ * @test
+ * @bug 8234011
+ * @summary Check that jdk.nio.zipfs.ZipFileSystem doesn't cache more than ZipFileSystem.MAX_FLATER Inflater/Deflater objects
+ * @run main ReleaseDeflater
+ * @modules jdk.zipfs/jdk.nio.zipfs:+open
+ * @author Volker Simonis
+ */
+
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.lang.reflect.Field;
+import java.nio.file.FileSystem;
+import java.nio.file.FileSystems;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.nio.file.spi.FileSystemProvider;
+import java.util.List;
+import java.util.Map;
+import java.util.ArrayList;
+
+public class ReleaseDeflater {
+    public static void main(String[] args) throws Throwable {
+        Path zipFile = Paths.get("ReleaseDeflaterTest.zip");
+        try (FileSystem fs = FileSystems.newFileSystem(zipFile, Map.of("create", true))) {
+            FileSystemProvider zprov = fs.provider();
+            Path test = fs.getPath("test.txt");
+            int STREAMS = 100;
+            List<OutputStream> ostreams = new ArrayList<>(STREAMS);
+            List<InputStream> istreams = new ArrayList<>(STREAMS);
+            for (int i = 0; i < STREAMS; i++) {
+                OutputStream zos = zprov.newOutputStream(test);
+                ostreams.add(zos);
+                zos.write("Hello".getBytes());
+            }
+            for (OutputStream os : ostreams) {
+                os.close();
+            }
+            for (int i = 0; i < STREAMS; i++) {
+                InputStream zis = zprov.newInputStream(test);
+                istreams.add(zis);
+            }
+            for (InputStream is : istreams) {
+                is.close();
+            }
+            try {
+                Field max_flaters = fs.getClass().getDeclaredField("MAX_FLATER");
+                max_flaters.setAccessible(true);
+                int MAX_FLATERS = max_flaters.getInt(fs);
+                Field inflaters = fs.getClass().getDeclaredField("inflaters");
+                inflaters.setAccessible(true);
+                int inflater_count = ((List<?>) inflaters.get(fs)).size();
+                if (inflater_count > MAX_FLATERS) {
+                    throw new Exception("Too many inflaters " + inflater_count);
+                }
+                Field deflaters = fs.getClass().getDeclaredField("deflaters");
+                deflaters.setAccessible(true);
+                int deflater_count = ((List<?>) deflaters.get(fs)).size();
+                if (deflater_count > MAX_FLATERS) {
+                    throw new Exception("Too many deflaters " + deflater_count);
+                }
+            } catch (NoSuchFieldException nsfe) {
+                // Probably the implementation has changed, so there's not much we can do...
+                throw new RuntimeException("Implementation of jdk.nio.zipfs.ZipFileSystem changed - disable or fix the test");
+            }
+        } finally {
+            Files.deleteIfExists(zipFile);
+        }
+
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/security/infra/java/security/cert/CertPathValidator/certification/LuxTrustCA.java	Mon Nov 18 12:40:06 2019 -0500
@@ -0,0 +1,194 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8232019
+ * @summary Interoperability tests with LuxTrust Global Root 2 CA
+ * @build ValidatePathWithParams
+ * @run main/othervm -Djava.security.debug=certpath LuxTrustCA OCSP
+ * @run main/othervm -Djava.security.debug=certpath LuxTrustCA CRL
+ */
+
+/*
+ * Obtain TLS test artifacts for LuxTrust CAs from:
+ *
+ * LuxTrust Global Root 2 CA sent test certificates as attachment
+ */
+public class LuxTrustCA {
+
+    // Owner: CN=LuxTrust Global Qualified CA 3, O=LuxTrust S.A., C=LU
+    // Issuer: CN=LuxTrust Global Root 2, O=LuxTrust S.A., C=LU
+    // Serial number: 413dea1a28c2253845558e047f3e2a8b5b9baeae
+    // Valid from: Fri Mar 06 06:12:15 PST 2015 until: Mon Mar 05 05:21:57 PST 2035
+    private static final String INT = "-----BEGIN CERTIFICATE-----\n" +
+            "MIIGcjCCBFqgAwIBAgIUQT3qGijCJThFVY4Efz4qi1ubrq4wDQYJKoZIhvcNAQEL\n" +
+            "BQAwRjELMAkGA1UEBhMCTFUxFjAUBgNVBAoMDUx1eFRydXN0IFMuQS4xHzAdBgNV\n" +
+            "BAMMFkx1eFRydXN0IEdsb2JhbCBSb290IDIwHhcNMTUwMzA2MTQxMjE1WhcNMzUw\n" +
+            "MzA1MTMyMTU3WjBOMQswCQYDVQQGEwJMVTEWMBQGA1UECgwNTHV4VHJ1c3QgUy5B\n" +
+            "LjEnMCUGA1UEAwweTHV4VHJ1c3QgR2xvYmFsIFF1YWxpZmllZCBDQSAzMIICIjAN\n" +
+            "BgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAuZ5iXSmFbP80gWb0kieYsImcyIo3\n" +
+            "QYg+XA3NlwH6QtI0PgZEG9dSo8pM7VMIzE5zq8tgJ50HnPdYflvfhkEKvAW2NuNX\n" +
+            "6hi/6HK4Nye+kB+INjpfAHmLft3GT95e+frk/t7hJNorK44xzqfWZKLNGysEHIri\n" +
+            "ddcePWOk3J/VMc9CsSemeZbmeZW1/xXeqolMS7JIDZ3+0DgVCYsKIK+b3sAQ8iqX\n" +
+            "bQlQyvymG6QyoQoJbuEP23iawRMWKNWk+sjzOkPAAQDtgEEVdggzzudLSM04C5Cj\n" +
+            "eLlLYuXgljler9bKRk9wW8nkareLZsn9uCDihGXGyC5m9jseGY1KAnlV8usLjBFA\n" +
+            "iW5OCnzcOg+CPsVucoRhS6uvXcu7VtHRGo5yLysJVv7sj6cx5lMvQKAMLviVi3kp\n" +
+            "hZKYfqVLAVFJpXTpunY2GayVGf/uOpzNoiSRpcxxYjmAlPKNeTgXVl5Mc0zojgT/\n" +
+            "MZTGFN7ov7n01yodN6OhfTADacvaKfj2C2CwdCJvMqvlUuCKrvuXbdZrtRm3BZXr\n" +
+            "ghGhuQmG0Tir7VVCI0WZjVjyHs2rpUcCQ6+D1WymKhzp0mrXdaFzYRce7FrEk69J\n" +
+            "WzWVp/9/GKnnb0//camavEaI4V64MVxYAir5AL/j7d4JIOqhPPU14ajxmC6dEH84\n" +
+            "guVs0Lo/dwVTUzsCAwEAAaOCAU4wggFKMBIGA1UdEwEB/wQIMAYBAf8CAQAwQwYD\n" +
+            "VR0gBDwwOjA4BggrgSsBAQEKAzAsMCoGCCsGAQUFBwIBFh5odHRwczovL3JlcG9z\n" +
+            "aXRvcnkubHV4dHJ1c3QubHUwagYIKwYBBQUHAQEEXjBcMCsGCCsGAQUFBzABhh9o\n" +
+            "dHRwOi8vbHRncm9vdC5vY3NwLmx1eHRydXN0Lmx1MC0GCCsGAQUFBzAChiFodHRw\n" +
+            "Oi8vY2EubHV4dHJ1c3QubHUvTFRHUkNBMi5jcnQwDgYDVR0PAQH/BAQDAgEGMB8G\n" +
+            "A1UdIwQYMBaAFP8YKHb5SAUsoa7xKxsrslP4S3yzMDMGA1UdHwQsMCowKKAmoCSG\n" +
+            "Imh0dHA6Ly9jcmwubHV4dHJ1c3QubHUvTFRHUkNBMi5jcmwwHQYDVR0OBBYEFGOP\n" +
+            "wosDsauO2FNHlh2ZqH32rKh1MA0GCSqGSIb3DQEBCwUAA4ICAQADB6M/edbOO9iJ\n" +
+            "COnVxayJ1NBk08/BVKlHwe7HBYAzT6Kmo3TbMUwOpcGI2e/NBCR3F4wTzXOVvFmv\n" +
+            "dBl7sdS6uMSLBTrav+5LChcFDBQj26X5VQDcXkA8b/u6J4Ve7CwoSesYg9H0fsJ3\n" +
+            "v12QrmGUUao9gbamKP1TFriO+XiIaDLYectruusRktIke9qy8MCpNSarZqr3oD3c\n" +
+            "/+N5D3lDlGpaz1IL8TpbubFEQHPCr6JiwR+qSqGRfxv8vIvOOAVxe7np5QhtwmCk\n" +
+            "XdMOPQ/XOOuEA06bez+zHkASX64at7dXru+4JUEbpijjMA+1jbFZr20OeBIQZL7o\n" +
+            "Est+FF8lFuvmucC9TS9QnlF28WJExvpIknjS7LhFMGXB9w380q38ZOuKjPZpoztY\n" +
+            "eyUpf8gxzV7fE5Q1okhnsDZ+12vBzBruzJcwtNuXyLyIh3fVN0LunVd+NP2kGjB2\n" +
+            "t9WD2Y0CaKxWx8snDdrSbAi46TpNoe04eroWgZOvdN0hEmf2d8tYBSJ/XZekU9sC\n" +
+            "Aww5vxHnXJi6CZHhjt8f1mMhyE2gBvmpk4CFetViO2sG0n/nsxCQNpnclsax/eJu\n" +
+            "XmGiZ3OPCIRijI5gy3pLRgnbgLyktWoOkmT/gxtWDLfVZwEt52JL8d550KIgttyR\n" +
+            "qX81LJWGSDdpnzeRVQEnzAt6+RebAQ==\n" +
+            "-----END CERTIFICATE-----";
+
+    // Owner: T=Private Person, SERIALNUMBER=00100978855105608536,
+    // GIVENNAME=TokenPRIActive, SURNAME=Test, CN=TokenPRIActive Test, C=DE
+    // Issuer: CN=LuxTrust Global Qualified CA 3, O=LuxTrust S.A., C=LU
+    // Serial number: 3814b6
+    // Valid from: Wed Jul 10 04:36:12 PDT 2019 until: Sun Jul 10 04:36:12 PDT 2022
+    private static final String VALID = "-----BEGIN CERTIFICATE-----\n" +
+            "MIIG/jCCBOagAwIBAgIDOBS2MA0GCSqGSIb3DQEBCwUAME4xCzAJBgNVBAYTAkxV\n" +
+            "MRYwFAYDVQQKDA1MdXhUcnVzdCBTLkEuMScwJQYDVQQDDB5MdXhUcnVzdCBHbG9i\n" +
+            "YWwgUXVhbGlmaWVkIENBIDMwHhcNMTkwNzEwMTEzNjEyWhcNMjIwNzEwMTEzNjEy\n" +
+            "WjCBizELMAkGA1UEBhMCREUxHDAaBgNVBAMTE1Rva2VuUFJJQWN0aXZlIFRlc3Qx\n" +
+            "DTALBgNVBAQTBFRlc3QxFzAVBgNVBCoTDlRva2VuUFJJQWN0aXZlMR0wGwYDVQQF\n" +
+            "ExQwMDEwMDk3ODg1NTEwNTYwODUzNjEXMBUGA1UEDBMOUHJpdmF0ZSBQZXJzb24w\n" +
+            "ggGiMA0GCSqGSIb3DQEBAQUAA4IBjwAwggGKAoIBgQDb8l2RJNS7iA9hJFj8aR25\n" +
+            "kpU/ZQTHl8Z9yrTLhr4VcMWMxqeOQUcUU27SgIuFvU9s/68OuaIhxyu6eohaGCLC\n" +
+            "wzFFRg8OlsUYuI1QtUEliIjmHOMDqSNIt093+SDV64osnHw5fpfy8V0zehEkd7QR\n" +
+            "t7Aq38ixCQyxCmNIDJeDCKJT+wwdLaKuw/4SEpR9sygSxZ3kG6kF4icsgYuiOCRx\n" +
+            "+DrS1wP9kcrQVWQ0bJbGzwxLZXCHaJsWE1Y17mQAO4Iv/9icqDkP3bZBU5GCgbNT\n" +
+            "JEP2GiUUPU3nL41Tlq03+iDmkS2bpWCtFZmTgUg+1nJEb7PSCJ9VcoflOOFgX/ku\n" +
+            "TQCJWwhsgyOneEZAg7PpzOj2msxA9RWI88FzRnX/zyjWEpdUCVJ85hFw8u+UZ7k1\n" +
+            "eF37oOpgNxQMJ+/ey7huneTzyhpFz/TqJpfMmwaGbPL6zmPLAMQalIPQj+68zlcX\n" +
+            "qyeKVbZU74Vm051kXb/3qs6CeUpT4HrY3UmHWLvOdNkCAwEAAaOCAiUwggIhMB8G\n" +
+            "A1UdIwQYMBaAFGOPwosDsauO2FNHlh2ZqH32rKh1MGYGCCsGAQUFBwEBBFowWDAn\n" +
+            "BggrBgEFBQcwAYYbaHR0cDovL3FjYS5vY3NwLmx1eHRydXN0Lmx1MC0GCCsGAQUF\n" +
+            "BzAChiFodHRwOi8vY2EubHV4dHJ1c3QubHUvTFRHUUNBMy5jcnQwggEuBgNVHSAE\n" +
+            "ggElMIIBITCCARMGC4g3AQOBKwEBCgMFMIIBAjAqBggrBgEFBQcCARYeaHR0cHM6\n" +
+            "Ly9yZXBvc2l0b3J5Lmx1eHRydXN0Lmx1MIHTBggrBgEFBQcCAjCBxgyBw0x1eFRy\n" +
+            "dXN0IENlcnRpZmljYXRlIG5vdCBvbiBTU0NEIGNvbXBsaWFudCB3aXRoIEVUU0kg\n" +
+            "VFMgMTAyIDA0MiBOQ1AgY2VydGlmaWNhdGUgcG9saWN5LiBLZXkgR2VuZXJhdGlv\n" +
+            "biBieSBDU1AuIFNvbGUgQXV0aG9yaXNlZCBVc2FnZTogU2lnbmF0dXJlLCBEYXRh\n" +
+            "IG9yIEVudGl0eSBBdXRoZW50aWNhdGlvbiBhbmQgRGF0YSBFbmNyeXB0aW9uLjAI\n" +
+            "BgYEAI96AQEwMwYDVR0fBCwwKjAooCagJIYiaHR0cDovL2NybC5sdXh0cnVzdC5s\n" +
+            "dS9MVEdRQ0EzLmNybDARBgNVHQ4ECgQISND+8GZyXrcwDgYDVR0PAQH/BAQDAgTw\n" +
+            "MAwGA1UdEwEB/wQCMAAwDQYJKoZIhvcNAQELBQADggIBAA54w2kGy+hJsYSyrQ5C\n" +
+            "ft0rasUHQviEiy31H2Z1lh4yEPLiuUsaepdzG4bov/J1RewX1fL7fvErraKK7nNr\n" +
+            "ioAXNElHtC0wfxGx0xGaCz7xsZIDFgpzyPqS+vd8VKbRCOY66AI+3aPiatCsk+BM\n" +
+            "Hp9GwW3B1e5EOgXiWVNxzYFtav5QSAj28IEV7ZuN2BIiU+phawRaoFy+4glMB7zE\n" +
+            "J5AM/Zfi50Q85ljy1kWUueFE3VNDafAUGOF5gTHvkKqj6LznUkqcT8m96Wd0IbF2\n" +
+            "BLYjnKPF6lGJsivErGqMwQIhlUUMkRQ13/hftL12rIiSjC1C/6cnbxOjWEOGnler\n" +
+            "Qn2zu2OTGnnrYxp/hojdZggb5Yt9mkM3EmyuqP1W4g0xtMv9q97swm/fHz/rDh8T\n" +
+            "MqrEOJzz284IM0DXjXq1wkmsZ/6/ueCyf0oBN0csvYspZKmLAydZ+jZmjdKKxX+N\n" +
+            "dreauHgOq1knLHkMb/YIyA+Oh6SBlNXL4Iae8APQcRGnylHQ1lc/YHTqWh8N1tmn\n" +
+            "no5r1kVJBYYtkI3oufaLtP7JIazteZlqTN+tubMJhO4xGgt6bqEpQiid9r3UnIjR\n" +
+            "esLYxXS5qRwSoOSleXT98H75+Ok1WR3ciD4exBR8/KcUtDITvDJhkBHnRHm40jFs\n" +
+            "5UbHFf98S6G9dqzsqW8+2Bpn\n" +
+            "-----END CERTIFICATE-----";
+
+    // Owner: T=Private Person, SERIALNUMBER=00100918135105608625,
+    // GIVENNAME=TokenPRIREV, SURNAME=Test, CN=TokenPRIREV Test, C=LU
+    // Issuer: CN=LuxTrust Global Qualified CA 3, O=LuxTrust S.A., C=LU
+    // Serial number: 3814b8
+    // Valid from: Wed Jul 10 04:36:48 PDT 2019 until: Sun Jul 10 04:36:48 PDT 2022
+    private static final String REVOKED = "-----BEGIN CERTIFICATE-----\n" +
+            "MIIG+DCCBOCgAwIBAgIDOBS4MA0GCSqGSIb3DQEBCwUAME4xCzAJBgNVBAYTAkxV\n" +
+            "MRYwFAYDVQQKDA1MdXhUcnVzdCBTLkEuMScwJQYDVQQDDB5MdXhUcnVzdCBHbG9i\n" +
+            "YWwgUXVhbGlmaWVkIENBIDMwHhcNMTkwNzEwMTEzNjQ4WhcNMjIwNzEwMTEzNjQ4\n" +
+            "WjCBhTELMAkGA1UEBhMCTFUxGTAXBgNVBAMTEFRva2VuUFJJUkVWIFRlc3QxDTAL\n" +
+            "BgNVBAQTBFRlc3QxFDASBgNVBCoTC1Rva2VuUFJJUkVWMR0wGwYDVQQFExQwMDEw\n" +
+            "MDkxODEzNTEwNTYwODYyNTEXMBUGA1UEDBMOUHJpdmF0ZSBQZXJzb24wggGiMA0G\n" +
+            "CSqGSIb3DQEBAQUAA4IBjwAwggGKAoIBgQCcm7y4c/D58u6g3m6HGdfiqDXa2yEl\n" +
+            "H2cAeSb85fsAX08iXfa/U/kmFqqycwp2nsJdfor6HEEqHsmozyjjIWHDEsq+cUre\n" +
+            "SO6d2Ag29MrxsAWZ1XAol40FcxNN+yEL9Xs5doqqcbz3OoKdxkoWVdYq3D7peizF\n" +
+            "OER4M2XA0KSLiKXDapDCfTVLE6qRG6Cn5mqnlqbUtkI6vSsda5mWLSNe4Qw/PIMw\n" +
+            "v7ZDn5dHeHoV6UpZC95Ole5vMQfjAOsy4nRc1zofQz7iPw4ClNzDQSuonaAKSk3Y\n" +
+            "1KjWPmHshb6BoANL+ce1KuWESKV3D5lBkVVLTeoBkWQu7ViJviF2HE5UoPRSGijO\n" +
+            "nmGOTZRsjOJXPe7/pEq9SQ477EufnSsoCj1cPCtaowbsO7oswzV/axKMhhZf6nU7\n" +
+            "0wd9xUuMgMRKBfi026mYK7pdxJ85qE8qKlqeNprje+g1sjxMDbMHARA427Px0IUJ\n" +
+            "mzIJk0ysAQvbqQVe8QQM/f+PH3mUkXR02H8CAwEAAaOCAiUwggIhMB8GA1UdIwQY\n" +
+            "MBaAFGOPwosDsauO2FNHlh2ZqH32rKh1MGYGCCsGAQUFBwEBBFowWDAnBggrBgEF\n" +
+            "BQcwAYYbaHR0cDovL3FjYS5vY3NwLmx1eHRydXN0Lmx1MC0GCCsGAQUFBzAChiFo\n" +
+            "dHRwOi8vY2EubHV4dHJ1c3QubHUvTFRHUUNBMy5jcnQwggEuBgNVHSAEggElMIIB\n" +
+            "ITCCARMGC4g3AQOBKwEBCgMFMIIBAjAqBggrBgEFBQcCARYeaHR0cHM6Ly9yZXBv\n" +
+            "c2l0b3J5Lmx1eHRydXN0Lmx1MIHTBggrBgEFBQcCAjCBxgyBw0x1eFRydXN0IENl\n" +
+            "cnRpZmljYXRlIG5vdCBvbiBTU0NEIGNvbXBsaWFudCB3aXRoIEVUU0kgVFMgMTAy\n" +
+            "IDA0MiBOQ1AgY2VydGlmaWNhdGUgcG9saWN5LiBLZXkgR2VuZXJhdGlvbiBieSBD\n" +
+            "U1AuIFNvbGUgQXV0aG9yaXNlZCBVc2FnZTogU2lnbmF0dXJlLCBEYXRhIG9yIEVu\n" +
+            "dGl0eSBBdXRoZW50aWNhdGlvbiBhbmQgRGF0YSBFbmNyeXB0aW9uLjAIBgYEAI96\n" +
+            "AQEwMwYDVR0fBCwwKjAooCagJIYiaHR0cDovL2NybC5sdXh0cnVzdC5sdS9MVEdR\n" +
+            "Q0EzLmNybDARBgNVHQ4ECgQIS0KUXpWyku0wDgYDVR0PAQH/BAQDAgTwMAwGA1Ud\n" +
+            "EwEB/wQCMAAwDQYJKoZIhvcNAQELBQADggIBAFSnezuyeRO0sh9e8/1N+2RE6Uhb\n" +
+            "RIdLKmaS8hMOyUNBapnHfJAdOn7j767qWQjRop5VNCcv0zDOxAqApxFiz4gJdzBY\n" +
+            "FVrEVwYos8a3BHLXNxfwIWEJ6EjlqI2qI3NjqK8m4M8LTq4G94V2/MOFVpXeCLju\n" +
+            "r0s+XZep2Sk9J4ofUOc8Gp7IZNhPzIlfKQ+KhnWovde4bpL3zRpp4u7Y580XsBuN\n" +
+            "kow2Eg84tRzSVizmgLPuRbySHuMo1jGIP7F9FdtOC8VVSjntfCXSEQqOvpH4YZ8S\n" +
+            "V4qP17CQHPWW1kOHAyXpkAjU+6SOlmF76Adv9nQFTZ6DAnKqiuxmi8EVCv96aFD7\n" +
+            "Ih+zBF7kj7fghPjUzsVdB6gI4VwuFCXEaAfWlxJS67s1hKnsCyqX3cu+Gnq9aRt+\n" +
+            "08iaTVEdrKL95AYYobVbnGJ7bH87SpenjLL+CDctXNNDlpJZ8eRYcQe+Q4dg+8L8\n" +
+            "X8tkXBeRbiZD1U7XwVBnKF6sJmhA4F/h/EJzwX0lp7EU6EO91bSiwD2NFVs+64UR\n" +
+            "9lftfFFm5In2N3vjDR/3nrCf3Jq9f0g7bTrNJmo+hc0+fD+zlAhZAx+ii2xE1cY1\n" +
+            "KLH2zXNzPUgIqYGdVQwn1TUFJN8JgGKsXwc+P51nEpgf6JVyK1m7EtVGtr9gF7DI\n" +
+            "P+4VSqTbTp4/l5n0\n" +
+            "-----END CERTIFICATE-----";
+
+    public static void main(String[] args) throws Exception {
+
+        ValidatePathWithParams pathValidator = new ValidatePathWithParams(null);
+
+        if (args.length >= 1 && "CRL".equalsIgnoreCase(args[0])) {
+            pathValidator.enableCRLCheck();
+        } else {
+            // OCSP check by default
+            pathValidator.enableOCSPCheck();
+        }
+
+        // Validate valid
+        pathValidator.validate(new String[]{VALID, INT},
+                ValidatePathWithParams.Status.GOOD, null, System.out);
+
+        // Validate Revoked
+        pathValidator.validate(new String[]{REVOKED, INT},
+                ValidatePathWithParams.Status.REVOKED,
+                "Wed Jul 10 04:48:49 PDT 2019", System.out);
+    }
+}
--- a/test/jdk/sun/security/lib/cacerts/VerifyCACerts.java	Wed Nov 13 17:21:31 2019 -0500
+++ b/test/jdk/sun/security/lib/cacerts/VerifyCACerts.java	Mon Nov 18 12:40:06 2019 -0500
@@ -26,7 +26,7 @@
  * @test
  * @bug 8189131 8198240 8191844 8189949 8191031 8196141 8204923 8195774 8199779
  *      8209452 8209506 8210432 8195793 8216577 8222089 8222133 8222137 8222136
- *      8223499 8225392
+ *      8223499 8225392 8232019 8234245
  * @summary Check root CA entries in cacerts file
  */
 import java.io.ByteArrayInputStream;
@@ -52,12 +52,12 @@
             + File.separator + "security" + File.separator + "cacerts";
 
     // The numbers of certs now.
-    private static final int COUNT = 88;
+    private static final int COUNT = 89;
 
     // SHA-256 of cacerts, can be generated with
     // shasum -a 256 cacerts | sed -e 's/../&:/g' | tr '[:lower:]' '[:upper:]' | cut -c1-95
     private static final String CHECKSUM
-            = "4E:21:94:7C:1D:49:28:BB:34:B0:40:DF:AE:19:B4:41:C6:B5:8A:EE:EB:D5:DE:B4:EF:07:AF:63:18:73:A6:FE";
+            = "DE:71:94:6D:6C:5B:2A:AE:5C:AC:D1:3E:07:23:B6:43:CB:F7:32:69:32:04:36:9C:B4:11:78:6A:49:9D:C5:AB";
 
     // map of cert alias to SHA-256 fingerprint
     @SuppressWarnings("serial")
@@ -239,6 +239,8 @@
                     "DD:69:36:FE:21:F8:F0:77:C1:23:A1:A5:21:C1:22:24:F7:22:55:B7:3E:03:A7:26:06:93:E8:A2:4B:0F:A3:89");
             put("globalsignrootcar6 [jdk]",
                     "2C:AB:EA:FE:37:D0:6C:A2:2A:BA:73:91:C0:03:3D:25:98:29:52:C4:53:64:73:49:76:3A:3A:B5:AD:6C:CF:69");
+            put("luxtrustglobalroot2ca [jdk]",
+                    "54:45:5F:71:29:C2:0B:14:47:C4:18:F9:97:16:8F:24:C5:8F:C5:02:3B:F5:DA:5B:E2:EB:6E:1D:D8:90:2E:D5");
         }
     };
 
@@ -268,6 +270,7 @@
         if (!checksum.equals(CHECKSUM)) {
             atLeastOneFailed = true;
             System.err.println("ERROR: wrong checksum\n" + checksum);
+            System.err.println("Expected checksum\n" + CHECKSUM);
         }
 
         KeyStore ks = KeyStore.getInstance("JKS");
--- a/test/jdk/sun/security/pkcs12/PBES2Encoding.java	Wed Nov 13 17:21:31 2019 -0500
+++ b/test/jdk/sun/security/pkcs12/PBES2Encoding.java	Mon Nov 18 12:40:06 2019 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -35,7 +35,7 @@
     // This is a PKCS 12 file using PBES2 to encrypt the cert and key. It is
     // generated with these commands:
     //
-    // keytool -keystore ks -genkeypair -storepass changeit -alias a -dname CN=A
+    // keytool -keystore ks -genkeypair -keyalg DSA -storepass changeit -alias a -dname CN=A
     // openssl pkcs12 -in ks -nodes -out kandc -passin pass:changeit
     // openssl pkcs12 -export -in kandc -out p12 -name a -passout pass:changeit
     //         -certpbe AES-128-CBC -keypbe AES-128-CBC
--- a/test/jdk/sun/security/pkcs12/ParamsTest.java	Wed Nov 13 17:21:31 2019 -0500
+++ b/test/jdk/sun/security/pkcs12/ParamsTest.java	Mon Nov 18 12:40:06 2019 -0500
@@ -114,7 +114,8 @@
         check("ksnormal", "a", "wrongpass", "-", IOException.class, "-", "-");
 
         // Add a new entry with password-less settings, still has a storepass
-        keytool("-keystore ksnormal -genkeypair -storepass changeit -alias b -dname CN=b "
+        keytool("-keystore ksnormal -genkeypair -keyalg DSA "
+                + "-storepass changeit -alias b -dname CN=b "
                 + "-J-Dkeystore.pkcs12.certProtectionAlgorithm=NONE "
                 + "-J-Dkeystore.pkcs12.macAlgorithm=NONE");
         data = Files.readAllBytes(Path.of("ksnormal"));
@@ -146,7 +147,8 @@
         check("ksnopass", "a", "wrongpass", "changeit", true, true, true);
 
         // Add a new entry with normal settings, still password-less
-        keytool("-keystore ksnopass -genkeypair -storepass changeit -alias b -dname CN=B");
+        keytool("-keystore ksnopass -genkeypair -keyalg DSA "
+                + "-storepass changeit -alias b -dname CN=B");
         data = Files.readAllBytes(Path.of("ksnopass"));
         shouldNotExist(data, "2"); // no Mac
         checkAlg(data, "110c010c01000", pbeWithSHA1AndRC4_128_oid);
@@ -171,13 +173,15 @@
         checkInt(data, "110c1101111", 6666); // cert ic
 
         // keypbe alg cannot be NONE
-        keytool("-keystore ksnewic -genkeypair -storepass changeit -alias b -dname CN=B "
+        keytool("-keystore ksnewic -genkeypair -keyalg DSA "
+                + "-storepass changeit -alias b -dname CN=B "
                 + "-J-Dkeystore.pkcs12.keyProtectionAlgorithm=NONE")
                 .shouldContain("NONE AlgorithmParameters not available")
                 .shouldHaveExitValue(1);
 
         // new entry new keypbe alg (and default ic), else unchanged
-        keytool("-keystore ksnewic -genkeypair -storepass changeit -alias b -dname CN=B "
+        keytool("-keystore ksnewic -genkeypair -keyalg DSA "
+                + "-storepass changeit -alias b -dname CN=B "
                 + "-J-Dkeystore.pkcs12.keyProtectionAlgorithm=PBEWithSHA1AndRC4_128");
         data = Files.readAllBytes(Path.of("ksnewic"));
         checkInt(data, "22", 5555); // Mac ic
@@ -336,7 +340,8 @@
 
         // still prompt for keypass for genkeypair and certreq
         SecurityTools.setResponse("changeit", "changeit");
-        keytool("-keystore ksnopassnew -genkeypair -alias a -dname CN=A "
+        keytool("-keystore ksnopassnew -genkeypair -keyalg DSA "
+                + "-alias a -dname CN=A "
                 + "-J-Dkeystore.pkcs12.certProtectionAlgorithm=NONE "
                 + "-J-Dkeystore.pkcs12.macAlgorithm=NONE")
                 .shouldNotContain("Enter keystore password:")
@@ -351,7 +356,8 @@
         // params only read on demand
 
         // keyPbeIterationCount is used by -genkeypair
-        keytool("-keystore ksgenbadkeyic -genkeypair -alias a -dname CN=A "
+        keytool("-keystore ksgenbadkeyic -genkeypair -keyalg DSA "
+                + "-alias a -dname CN=A "
                 + "-storepass changeit "
                 + "-J-Dkeystore.pkcs12.keyPbeIterationCount=abc")
                 .shouldContain("keyPbeIterationCount is not a number: abc")
--- a/test/jdk/sun/security/pkcs12/SameDN.java	Wed Nov 13 17:21:31 2019 -0500
+++ b/test/jdk/sun/security/pkcs12/SameDN.java	Mon Nov 18 12:40:06 2019 -0500
@@ -55,7 +55,7 @@
     }
 
     static void genkeypair(String alias, String dn) throws Exception {
-        keytool(COMMON + "-genkeypair -alias " + alias + " -dname " + dn)
+        keytool(COMMON + "-genkeypair -keyalg DSA -alias " + alias + " -dname " + dn)
                 .shouldHaveExitValue(0);
     }
 
--- a/test/jdk/sun/security/tools/jarsigner/AltProvider.java	Wed Nov 13 17:21:31 2019 -0500
+++ b/test/jdk/sun/security/tools/jarsigner/AltProvider.java	Mon Nov 18 12:40:06 2019 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -69,7 +69,7 @@
                 MOD_SRC_DIR.toString());
 
         // Create a keystore
-        tool("keytool", "-keystore x.jks -storetype jks -genkeypair" +
+        tool("keytool", "-keystore x.jks -storetype jks -genkeypair -keyalg dsa" +
                 " -storepass changeit -keypass changeit -alias x -dname CN=X")
                 .shouldHaveExitValue(0);
 
--- a/test/jdk/sun/security/tools/jarsigner/JavaKeyStoreAliasCaseInsensitive.java	Wed Nov 13 17:21:31 2019 -0500
+++ b/test/jdk/sun/security/tools/jarsigner/JavaKeyStoreAliasCaseInsensitive.java	Mon Nov 18 12:40:06 2019 -0500
@@ -50,7 +50,7 @@
     public void testAliasCase() throws Exception {
         final String KEYSTORE_OPTIONS = "-storetype JKS -keystore "
                 + "test-alias-case.jks -storepass changeit";
-        SecurityTools.keytool(KEYSTORE_OPTIONS + " -genkeypair"
+        SecurityTools.keytool(KEYSTORE_OPTIONS + " -genkeypair -keyalg DSA"
                 + " -keypass changeit -alias " + ALIAS + " -dname CN=" + ALIAS)
                 .shouldHaveExitValue(0);
         String jarFilename = "test-alias-case.jar";
@@ -88,10 +88,10 @@
         // signed by another certificate associated with ALIAS + "1".
         final String KEYSTORE_OPTIONS = "-storetype JKS -keystore"
                 + " test-alias-storeHash-case.jks -storepass changeit";
-        SecurityTools.keytool(KEYSTORE_OPTIONS + " -genkeypair"
+        SecurityTools.keytool(KEYSTORE_OPTIONS + " -genkeypair -keyalg DSA"
                 + " -keypass changeit -alias " + ALIAS + "1 -dname CN=" +
                 ALIAS + "1").shouldHaveExitValue(0);
-        SecurityTools.keytool(KEYSTORE_OPTIONS + " -genkeypair"
+        SecurityTools.keytool(KEYSTORE_OPTIONS + " -genkeypair -keyalg DSA"
                 + " -keypass changeit -alias " + ALIAS + "2 -dname CN="
                 + ALIAS + "2").shouldHaveExitValue(0);
         String certReq = SecurityTools.keytool(KEYSTORE_OPTIONS +
--- a/test/jdk/sun/security/tools/jarsigner/LineBrokenMultiByteCharacter.java	Wed Nov 13 17:21:31 2019 -0500
+++ b/test/jdk/sun/security/tools/jarsigner/LineBrokenMultiByteCharacter.java	Mon Nov 18 12:40:06 2019 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -77,6 +77,7 @@
 
     static void prepare() throws Exception {
         SecurityTools.keytool("-keystore", keystoreFileName, "-genkeypair",
+                "-keyalg", "dsa",
                 "-storepass", "changeit", "-keypass", "changeit", "-storetype",
                 "JKS", "-alias", alias, "-dname", "CN=X", "-validity", "366")
             .shouldHaveExitValue(0);
--- a/test/jdk/sun/security/tools/jarsigner/multiRelease/MVJarSigningTest.java	Wed Nov 13 17:21:31 2019 -0500
+++ b/test/jdk/sun/security/tools/jarsigner/multiRelease/MVJarSigningTest.java	Mon Nov 18 12:40:06 2019 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -152,6 +152,7 @@
                 "-J-Duser.language=en",
                 "-J-Duser.country=US",
                 "-genkey",
+                "-keyalg", "dsa",
                 "-alias", ALIAS,
                 "-keystore", KEYSTORE,
                 "-keypass", KEYPASS,
--- a/test/jdk/sun/security/tools/keytool/DeprecateKeyalg.java	Wed Nov 13 17:21:31 2019 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,73 +0,0 @@
-/*
- * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-import jdk.test.lib.SecurityTools;
-import jdk.test.lib.process.OutputAnalyzer;
-
-/**
- * @test
- * @bug 8212003 8214179
- * @summary Deprecating the default keytool -keyalg option
- * @library /test/lib
- */
-
-public class DeprecateKeyalg {
-
-    private static final String COMMON = "-keystore ks -storetype jceks "
-            + "-storepass changeit -keypass changeit";
-
-    public static void main(String[] args) throws Throwable {
-
-        kt("-genkeypair -keyalg DSA -alias a -dname CN=A")
-                .shouldContain("Generating")
-                .shouldNotContain("-keyalg option must be specified");
-
-        kt("-genkeypair -alias b -dname CN=B")
-                .shouldContain("Generating")
-                .shouldContain("default key algorithm (DSA)")
-                .shouldContain("-keyalg option must be specified");
-
-        kt("-genseckey -keyalg DES -alias c")
-                .shouldContain("Generated")
-                .shouldNotContain("-keyalg option must be specified");
-
-        kt("-genseckey -alias d")
-                .shouldContain("Generated")
-                .shouldContain("default key algorithm (DES)")
-                .shouldContain("-keyalg option must be specified");
-
-        kt("-genkeypair -alias e -dname CN=e -keyalg EC -groupname brainpoolP256r1")
-                .shouldContain("Generating 256 bit EC (brainpoolP256r1) key pair");
-
-        kt("-genkeypair -alias f -dname CN=f -keyalg EC")
-                .shouldContain("Generating 256 bit EC (secp256r1) key pair");
-
-        kt("-genkeypair -alias g -dname CN=g -keyalg EC -keysize 384")
-                .shouldContain("Generating 384 bit EC (secp384r1) key pair");
-    }
-
-    private static OutputAnalyzer kt(String cmd) throws Throwable {
-        return SecurityTools.keytool(COMMON + " " + cmd)
-                .shouldHaveExitValue(0);
-    }
-}
--- a/test/jdk/sun/security/tools/keytool/DupImport.java	Wed Nov 13 17:21:31 2019 -0500
+++ b/test/jdk/sun/security/tools/keytool/DupImport.java	Mon Nov 18 12:40:06 2019 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -51,9 +51,9 @@
         Files.deleteIfExists(Paths.get("dup.ks"));
 
         // Create chain: root -> int -> me
-        run("-genkeypair -alias me -dname CN=Me");
-        run("-genkeypair -alias int -dname CN=Int");
-        run("-genkeypair -alias root -dname CN=Root");
+        run("-genkeypair -keyalg DSA -alias me -dname CN=Me");
+        run("-genkeypair -keyalg DSA -alias int -dname CN=Int");
+        run("-genkeypair -keyalg DSA -alias root -dname CN=Root");
 
         run("-certreq -alias int -file int.req");
         run("-gencert -infile int.req -alias root -rfc -outfile int.resp");
--- a/test/jdk/sun/security/tools/keytool/HasSrcStoretypeOption.java	Wed Nov 13 17:21:31 2019 -0500
+++ b/test/jdk/sun/security/tools/keytool/HasSrcStoretypeOption.java	Mon Nov 18 12:40:06 2019 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -33,7 +33,7 @@
 public class HasSrcStoretypeOption {
 
     public static void main(String[] args) throws Exception {
-        run("-genkeypair -alias a -dname CN=A -storetype jceks -keystore jce");
+        run("-genkeypair -keyalg DSA -alias a -dname CN=A -storetype jceks -keystore jce");
         // When there is no -srcstoretype, it should be probed from the file
         run("-importkeystore -srckeystore jce -destkeystore jks -deststoretype jks");
     }
--- a/test/jdk/sun/security/tools/keytool/ImportPrompt.java	Wed Nov 13 17:21:31 2019 -0500
+++ b/test/jdk/sun/security/tools/keytool/ImportPrompt.java	Mon Nov 18 12:40:06 2019 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -50,11 +50,11 @@
 
     public static void main(String[] args) throws Throwable {
 
-        kt("-keystore ks1 -genkeypair -alias a -dname CN=A");
+        kt("-keystore ks1 -genkeypair -keyalg DSA -alias a -dname CN=A");
         kt("-keystore ks1 -exportcert -alias a -file a.cert");
 
         // Just create a keystore
-        kt("-keystore ks2 -genkeypair -alias b -dname CN=B");
+        kt("-keystore ks2 -genkeypair -keyalg DSA -alias b -dname CN=B");
 
         // no response text, assume no
         kt("-keystore ks2 -importcert -alias a -file a.cert");
--- a/test/jdk/sun/security/tools/keytool/KeyAlg.java	Wed Nov 13 17:21:31 2019 -0500
+++ b/test/jdk/sun/security/tools/keytool/KeyAlg.java	Mon Nov 18 12:40:06 2019 -0500
@@ -23,7 +23,7 @@
 
 /*
  * @test
- * @bug 8029659
+ * @bug 8029659 8214179
  * @summary Keytool, print key algorithm of certificate or key entry
  * @library /test/lib
  */
@@ -33,22 +33,25 @@
 
 public class KeyAlg {
     public static void main(String[] args) throws Exception {
-        keytool("-genkeypair -alias ca -dname CN=CA -keyalg EC")
-                .shouldHaveExitValue(0);
-        keytool("-genkeypair -alias user -dname CN=User -keyalg RSA -keysize 1024")
-                .shouldHaveExitValue(0);
-        keytool("-certreq -alias user -file user.req").shouldHaveExitValue(0);
+        keytool("-genkeypair -alias ca -dname CN=CA -keyalg EC");
+        keytool("-genkeypair -alias user -dname CN=User -keyalg RSA -keysize 1024");
+        keytool("-certreq -alias user -file user.req");
         keytool("-gencert -alias ca -rfc -sigalg SHA1withECDSA"
-                + " -infile user.req -outfile user.crt")
-                .shouldHaveExitValue(0);
+                + " -infile user.req -outfile user.crt");
         keytool("-printcert -file user.crt")
-                .shouldHaveExitValue(0)
                 .shouldMatch("Signature algorithm name:.*SHA1withECDSA")
                 .shouldMatch("Subject Public Key Algorithm:.*1024.*RSA");
+        keytool("-genkeypair -alias e -dname CN=e -keyalg EC -groupname brainpoolP256r1")
+                .shouldContain("Generating 256 bit EC (brainpoolP256r1) key pair");
+        keytool("-genkeypair -alias f -dname CN=f -keyalg EC")
+                .shouldContain("Generating 256 bit EC (secp256r1) key pair");
+        keytool("-genkeypair -alias g -dname CN=g -keyalg EC -keysize 384")
+                .shouldContain("Generating 384 bit EC (secp384r1) key pair");
     }
 
     static OutputAnalyzer keytool(String s) throws Exception {
         return SecurityTools.keytool(
-                "-keystore ks -storepass changeit -keypass changeit " + s);
+                "-keystore ks -storepass changeit -keypass changeit " + s)
+                .shouldHaveExitValue(0);
     }
 }
--- a/test/jdk/sun/security/tools/keytool/KeyToolTest.java	Wed Nov 13 17:21:31 2019 -0500
+++ b/test/jdk/sun/security/tools/keytool/KeyToolTest.java	Mon Nov 18 12:40:06 2019 -0500
@@ -197,7 +197,7 @@
             // jarsigner and keytool algorithm for DSA keys". Unfortunately
             // SunPKCS11-NSS does not support SHA256withDSA yet.
             if (cmd.contains("p11-nss.txt") && cmd.contains("-genkey")
-                    && !cmd.contains("-keyalg")) {
+                    && cmd.contains("DSA")) {
                 cmd += " -sigalg SHA1withDSA -keysize 1024";
             }
             test(input, cmd);
@@ -352,7 +352,7 @@
         remove("x.jks");
         remove("x.jks.p1.cert");
         testOK("", "-keystore x.jks -storetype JKS -storepass changeit " +
-                "-keypass changeit -genkeypair -alias p1 -dname CN=olala");
+                "-keypass changeit -genkeypair -keyalg DSA -alias p1 -dname CN=olala");
         testOK("", "-keystore x.jks -storetype JKS -storepass changeit " +
                 "-exportcert -alias p1 -file x.jks.p1.cert");
         ks = loadStore("x.jks", "changeit", "JKS");
@@ -377,7 +377,7 @@
 
         // changealias and keyclone
         testOK("", "-keystore x.jks -storetype JKS -storepass changeit " +
-                "-keypass changeit -genkeypair -alias p1 -dname CN=olala");
+                "-keypass changeit -genkeypair -keyalg DSA -alias p1 -dname CN=olala");
         testOK("changeit\n", "-keystore x.jks -storetype JKS " +
                 "-changealias -alias p1 -destalias p11");
         testOK("changeit\n", "-keystore x.jks -storetype JKS " +
@@ -396,10 +396,10 @@
         remove("x.jceks");
         // DES, no need keysize
         testOK("changeit\nchangeit\n\n", "-keystore x.jceks -storetype JCEKS " +
-                "-genseckey -alias s1");
+                "-genseckey -keyalg DES -alias s1");
         // DES, keysize cannot be 128
         testFail("changeit\n\n", "-keystore x.jceks -storetype JCEKS " +
-                "-genseckey -alias s11 -keysize 128");
+                "-genseckey -keyalg DES -alias s11 -keysize 128");
         // DESede. no need keysize
         testOK("changeit\n\n", "-keystore x.jceks -storetype JCEKS " +
                 "-genseckey -keyalg DESede -alias s2");
@@ -411,19 +411,20 @@
         // about keypass
         // can accept storepass
         testOK("\n", "-keystore x.jceks -storetype JCEKS -storepass changeit " +
-                "-genseckey -alias s4");
+                "-genseckey -keyalg DES -alias s4");
         // or a new one
         testOK("keypass\nkeypass\n", "-keystore x.jceks -storetype JCEKS " +
-                "-storepass changeit -genseckey -alias s5");
+                "-storepass changeit -genseckey -keyalg DES -alias s5");
         // keypass must be valid (prompt 3 times)
         testOK("bad\n\bad\nkeypass\nkeypass\n", "-keystore x.jceks " +
-                "-storetype JCEKS -storepass changeit -genseckey -alias s6");
+                "-storetype JCEKS -storepass changeit -genseckey " +
+                "-keyalg DES -alias s6");
         // keypass must be valid (prompt 3 times)
         testFail("bad\n\bad\nbad\n", "-keystore x.jceks -storetype JCEKS " +
-                "-storepass changeit -genseckey -alias s7");
+                "-storepass changeit -genseckey -keyalg DES -alias s7");
         // keypass must be valid (prompt 3 times)
         testFail("bad\n\bad\nbad\nkeypass\n", "-keystore x.jceks " +
-                "-storetype JCEKS -storepass changeit -genseckey -alias s7");
+                "-storetype JCEKS -storepass changeit -genseckey -keyalg DES -alias s7");
         ks = loadStore("x.jceks", "changeit", "JCEKS");
         assertTrue(ks.getKey("s1", "changeit".toCharArray())
                 .getAlgorithm().equalsIgnoreCase("DES"), "s1 is DES");
@@ -452,7 +453,7 @@
         remove("x.jceks");
         // create 2 entries...
         testOK("changeit\nchangeit\n\n", "-keystore x.jceks -storetype JCEKS " +
-                "-genkeypair -alias p1 -dname CN=Olala");
+                "-genkeypair -keyalg DSA -alias p1 -dname CN=Olala");
         testOK("", "-keystore x.jceks -storetype JCEKS -storepass changeit " +
                 "-importcert -alias c1 -file x.jks.p1.cert -noprompt");
         ks = loadStore("x.jceks", "changeit", "JCEKS");
@@ -532,7 +533,7 @@
         remove("x.jks");
         // generate entry with different keypass
         testOK("changeit\nkeypass\nkeypass\n", "-keystore x.jceks " +
-                "-storetype JCEKS -genkeypair -alias p2 -dname CN=Olala");
+                "-storetype JCEKS -genkeypair -keyalg DSA -alias p2 -dname CN=Olala");
         // prompt
         testOK("changeit\nchangeit\nchangeit\nkeypass\n", "-importkeystore " +
                 "-srckeystore x.jceks -srcstoretype JCEKS " +
@@ -581,10 +582,10 @@
         remove("x.jks");
         // create SecretKeyEntry
         testOK("changeit\n\n", "-keystore x.jceks -storetype JCEKS " +
-                "-genseckey -alias s1");
+                "-genseckey -keyalg DES -alias s1");
         // create SecretKeyEntry
         testOK("changeit\n\n", "-keystore x.jceks -storetype JCEKS " +
-                "-genseckey -alias s2");
+                "-genseckey -keyalg DES -alias s2");
         // remove the keypass!=storepass one
         testOK("changeit\n", "-keystore x.jceks -storetype JCEKS " +
                 "-delete -alias p2");
@@ -629,13 +630,13 @@
         remove("x.jks");
         // just type ENTER means keypass=storepass
         testOK("changeit\nchangeit\n\n", "-keystore x.jks -storetype JKS " +
-                "-genkeypair -alias p1 -dname CN=olala");
+                "-genkeypair -keyalg DSA -alias p1 -dname CN=olala");
         remove("x.p12");
         // PKCS12 only need storepass
         testOK("", "-keystore x.p12 -storetype PKCS12 -storepass changeit " +
-                "-genkeypair -alias p0 -dname CN=olala");
+                "-genkeypair -keyalg DSA -alias p0 -dname CN=olala");
         testOK("changeit\n", "-keystore x.p12 -storetype PKCS12 " +
-                "-genkeypair -alias p1 -dname CN=olala");
+                "-genkeypair -keyalg DSA -alias p1 -dname CN=olala");
         // when specify keypass, make sure keypass==storepass...
         testOK("changeit\n", "-keystore x.p12 -keypass changeit " +
                 "-storetype PKCS12 -genkeypair -keyalg DSA -alias p3 -dname CN=olala");
@@ -658,9 +659,9 @@
         remove("x.p12");
         // PKCS12 only need storepass
         testOK("", "-keystore x.p12 -storetype PKCS12 -storepass changeit " +
-                "-genkeypair -alias p0 -dname CN=olala");
+                "-genkeypair -keyalg DSA -alias p0 -dname CN=olala");
         testOK("", "-storepass changeit -keystore x.p12 -storetype PKCS12 " +
-                "-genkeypair -alias p1 -dname CN=olala");
+                "-genkeypair -keyalg DSA -alias p1 -dname CN=olala");
         // when specify keypass, make sure keypass==storepass...
         testOK("", "-storepass changeit -keystore x.p12 -keypass changeit " +
                 "-storetype PKCS12 -genkeypair -keyalg DSA -alias p3 -dname CN=olala");
@@ -696,14 +697,14 @@
                         "BEFORE THIS TEST ***");
 
         testOK("", p11Arg +
-                "-storepass test12 -genkeypair -alias p1 -dname CN=olala");
-        testOK("test12\n", p11Arg + "-genkeypair -alias p2 -dname CN=olala2");
+                "-storepass test12 -genkeypair -keyalg DSA -alias p1 -dname CN=olala");
+        testOK("test12\n", p11Arg + "-genkeypair -keyalg DSA -alias p2 -dname CN=olala2");
         // cannot provide keypass for PKCS11
         testFail("test12\n", p11Arg +
-                "-keypass test12 -genkeypair -alias p3 -dname CN=olala3");
+                "-keypass test12 -genkeypair -keyalg DSA -alias p3 -dname CN=olala3");
         // cannot provide keypass for PKCS11
         testFail("test12\n", p11Arg +
-                "-keypass nonsense -genkeypair -alias p3 -dname CN=olala3");
+                "-keypass nonsense -genkeypair -keyalg DSA -alias p3 -dname CN=olala3");
 
         testOK("", p11Arg + "-storepass test12 -list");
         assertTrue(out.indexOf("Your keystore contains 2 entries") != -1,
@@ -738,8 +739,8 @@
 
         KeyStore ks;
         testOK("", p11Arg +
-                "-storepass test12 -genkeypair -alias p1 -dname CN=olala");
-        testOK("test12\n", p11Arg + "-genkeypair -alias p2 -dname CN=olala2");
+                "-storepass test12 -genkeypair -keyalg DSA -alias p1 -dname CN=olala");
+        testOK("test12\n", p11Arg + "-genkeypair -keyalg DSA -alias p2 -dname CN=olala2");
         // test importkeystore for pkcs11
 
         remove("x.jks");
@@ -809,7 +810,7 @@
         KeyStore ks;
         remove("x.jks");
         testOK("", "-keystore x.jks -storetype JKS -storepass changeit " +
-                "-keypass changeit -genkeypair -dname CN=olala");
+                "-keypass changeit -genkeypair -keyalg DSA -dname CN=olala");
         testOK("", "-keystore x.jks -storetype JKS -storepass changeit " +
                 "-exportcert -file x.jks.p1.cert");
         /* deleted */ testOK("", "-keystore x.jks -storetype JKS " +
@@ -842,7 +843,7 @@
     void sqeKeyclonetest() throws Exception {
         remove("x.jks");
         testOK("", "-keystore x.jks -storetype JKS -storepass changeit " +
-                "-keypass changeit -genkeypair -dname CN=olala");
+                "-keypass changeit -genkeypair -keyalg DSA -dname CN=olala");
         // new pass
         testOK("", "-keystore x.jks -storetype JKS -storepass changeit " +
                 "-keypass changeit -new newpass -keyclone -dest p0");
@@ -871,7 +872,7 @@
     void sqeKeypasswdTest() throws Exception {
         remove("x.jks");
         testOK("", "-keystore x.jks -storetype JKS -storepass changeit " +
-                "-keypass changeit -genkeypair -dname CN=olala");
+                "-keypass changeit -genkeypair -keyalg DSA -dname CN=olala");
         testOK("", "-keystore x.jks -storetype JKS -storepass changeit " +
                 "-keypass changeit -keypasswd -new newpass");
         /*change back*/ testOK("", "-keystore x.jks -storetype JKS " +
@@ -909,7 +910,7 @@
         testOK("", "-keystore x.jks -storetype JKS -storepass changeit " +
                 "-delete -alias mykey");
         testOK("", "-keystore x.jks -storetype JKS -storepass changeit " +
-                "-keypass keypass -genkeypair -dname CN=olala");
+                "-keypass keypass -genkeypair -keyalg DSA -dname CN=olala");
         testFail("", "-keystore x.jks -storetype JKS -storepass changeit " +
                 "-keypasswd -new newpass");
         testOK("keypass\n", "-keystore x.jks -storetype JKS " +
@@ -922,7 +923,7 @@
     void sqeListTest() throws Exception {
         remove("x.jks");
         testOK("", "-keystore x.jks -storetype JKS -storepass changeit " +
-                "-keypass changeit -genkeypair -dname CN=olala");
+                "-keypass changeit -genkeypair -keyalg DSA -dname CN=olala");
         testOK("", "-keystore x.jks -storetype JKS -storepass changeit -list");
         testOK("", "-keystore x.jks -storetype JKS -storepass changeit " +
                 "-list -alias mykey");
@@ -948,7 +949,7 @@
     void sqeSelfCertTest() throws Exception {
         remove("x.jks");
         testOK("", "-keystore x.jks -storetype JKS -storepass changeit " +
-                "-keypass changeit -genkeypair -dname CN=olala");
+                "-keypass changeit -genkeypair -keyalg DSA -dname CN=olala");
         testOK("", "-keystore x.jks -storetype JKS -storepass changeit -selfcert");
         testOK("", "-keystore x.jks -storetype JKS -storepass changeit " +
                 "-keypass changeit -selfcert");
@@ -974,7 +975,7 @@
         // diff pass
         remove("x.jks");
         testOK("", "-keystore x.jks -storetype JKS -storepass changeit " +
-                "-keypass keypass -genkeypair -dname CN=olala");
+                "-keypass keypass -genkeypair -keyalg DSA -dname CN=olala");
         testFail("", "-keystore x.jks -storetype JKS " +
                 "-storepass changeit -selfcert");
         testOK("keypass\n", "-keystore x.jks -storetype JKS " +
@@ -995,7 +996,7 @@
     void sqeStorepassTest() throws Exception {
         remove("x.jks");
         testOK("", "-keystore x.jks -storetype JKS -storepass changeit " +
-                "-keypass changeit -genkeypair -dname CN=olala");
+                "-keypass changeit -genkeypair -keyalg DSA -dname CN=olala");
         // all in arg
         testOK("", "-storepasswd -keystore x.jks -storetype JKS " +
                 "-storepass changeit -new newstore");
@@ -1044,13 +1045,13 @@
 
         remove("x.jks");
         testOK("", "-keystore x.jks -storetype JKS -storepass changeit " +
-                "-keypass changeit -genkeypair -dname CN=olala");
+                "-keypass changeit -genkeypair -keyalg DSA -dname CN=olala");
         testFail("", "-keystore x.jks -storetype JKS -storepass changeit " +
-                "-keypass changeit -genkeypair -dname CN=olala");
+                "-keypass changeit -genkeypair -keyalg DSA -dname CN=olala");
         testOK("", "-keystore x.jks -storetype JKS -storepass changeit " +
-                "-keypass changeit -genkeypair -dname CN=olala -alias newentry");
+                "-keypass changeit -genkeypair -keyalg DSA -dname CN=olala -alias newentry");
         testFail("", "-keystore x.jks -storetype JKS -storepass changeit " +
-                "-keypass changeit -genkeypair -dname CN=olala -alias newentry");
+                "-keypass changeit -genkeypair -keyalg DSA -dname CN=olala -alias newentry");
         testOK("", "-keystore x.jks -storetype JKS -storepass changeit " +
                 "-keypass changeit -genkeypair -dname CN=olala -keyalg DSA " +
                 "-alias n1");
@@ -1061,19 +1062,19 @@
                 "-keypass changeit -genkeypair -dname CN=olala " +
                 "-keyalg NoSuchAlg -alias n3");
         testFail("", "-keystore x.jks -storetype JKS -storepass changeit " +
-                "-keypass changeit -genkeypair -dname CN=olala -keysize 56 " +
+                "-keypass changeit -genkeypair -keyalg DSA -dname CN=olala -keysize 56 " +
                 "-alias n4");
         testFail("", "-keystore x.jks -storetype JKS -storepass changeit " +
-                "-keypass changeit -genkeypair -dname CN=olala -keysize 999 " +
+                "-keypass changeit -genkeypair -keyalg DSA -dname CN=olala -keysize 999 " +
                 "-alias n5");
         testOK("", "-keystore x.jks -storetype JKS -storepass changeit " +
-                "-keypass changeit -genkeypair -dname CN=olala -keysize 512 " +
+                "-keypass changeit -genkeypair -keyalg DSA -dname CN=olala -keysize 512 " +
                 "-alias n6");
         testOK("", "-keystore x.jks -storetype JKS -storepass changeit " +
-                "-keypass changeit -genkeypair -dname CN=olala -keysize 1024 " +
+                "-keypass changeit -genkeypair -keyalg DSA -dname CN=olala -keysize 1024 " +
                 "-alias n7");
         testFail("", "-keystore x.jks -storetype JKS -storepass changeit " +
-                "-keypass changeit -genkeypair -dname CN=olala " +
+                "-keypass changeit -genkeypair -keyalg DSA -dname CN=olala " +
                 "-sigalg NoSuchAlg -alias n8");
         testOK("", "-keystore x.jks -storetype JKS -storepass changeit " +
                 "-keypass changeit -genkeypair -dname CN=olala -keyalg RSA " +
@@ -1088,12 +1089,12 @@
                 "-keypass changeit -genkeypair -dname CN=olala -keyalg RSA " +
                 "-sigalg NoSuchAlg -alias n12");
         testFail("", "-keystore badkeystore -storepass changeit " +
-                "-keypass changeit -genkeypair -dname CN=olala " +
+                "-keypass changeit -genkeypair -keyalg DSA -dname CN=olala " +
                 "-alias n14");
         testFail("", "-keystore x.jks -storetype JKS -storepass badpass " +
-                "-keypass changeit -genkeypair -dname CN=olala -alias n16");
+                "-keypass changeit -genkeypair -keyalg DSA -dname CN=olala -alias n16");
         testFail("", "-keystore x.jks -storetype JKS -storepass changeit " +
-                "-keypass changeit -genkeypair -dname CNN=olala -alias n17");
+                "-keypass changeit -genkeypair -keyalg DSA -dname CNN=olala -alias n17");
         remove("x.jks");
     }
 
@@ -1103,7 +1104,7 @@
         testFail("", "-keystore x.jks -storetype JKS -storepass changeit " +
                 "-export -file mykey.cert -alias mykey");
         testOK("", "-keystore x.jks -storetype JKS -storepass changeit " +
-                "-keypass changeit -genkeypair -dname CN=olala");
+                "-keypass changeit -genkeypair -keyalg DSA -dname CN=olala");
         testOK("", "-keystore x.jks -storetype JKS -storepass changeit " +
                 "-export -file mykey.cert -alias mykey");
         testOK("", "-keystore x.jks -storetype JKS -storepass changeit " +
@@ -1131,11 +1132,11 @@
         testFail("", "-keystore x.jks -storetype JKS -storepass changeit " +
                 "-delete -alias mykey");
         testOK("", "-keystore x.jks -storetype JKS -storepass changeit " +
-                "-keypass changeit -genkeypair -dname CN=olala");
+                "-keypass changeit -genkeypair -keyalg DSA -dname CN=olala");
         testOK("", "-keystore x.jks -storetype JKS -storepass changeit " +
                 "-delete -alias mykey");
         testOK("", "-keystore x.jks -storetype JKS -storepass changeit " +
-                "-keypass changeit -genkeypair -dname CN=olala");
+                "-keypass changeit -genkeypair -keyalg DSA -dname CN=olala");
         // keystore name illegal
         testFail("", "-keystore aa\\bb//cc\\dd -storepass changeit " +
                 "-delete -alias mykey");
@@ -1157,7 +1158,7 @@
         remove("csr1");
         // PrivateKeyEntry can do certreq
         testOK("", "-keystore x.jks -storetype JKS -storepass changeit " +
-                "-keypass changeit -genkeypair -dname CN=olala -keysize 1024");
+                "-keypass changeit -genkeypair -keyalg DSA -dname CN=olala -keysize 1024");
         testOK("", "-keystore x.jks -storetype JKS -storepass changeit " +
                 "-certreq -file csr1 -alias mykey");
         testOK("", "-keystore x.jks -storetype JKS -storepass changeit " +
@@ -1221,7 +1222,7 @@
         remove("mykey.cert");
         remove("myweakkey.cert");
         testOK("", "-keystore x.jks -storetype JKS -storepass changeit " +
-                "-keypass changeit -genkeypair -dname CN=olala");
+                "-keypass changeit -genkeypair -keyalg DSA -dname CN=olala");
         testOK("", "-keystore x.jks -storetype JKS -storepass changeit " +
                 "-export -file mykey.cert -alias mykey");
         testOK("", "-keystore x.jks -storetype JKS -storepass changeit " +
@@ -1264,7 +1265,7 @@
         remove("x.jks");
         String simple = "-keystore x.jks -storetype JKS -storepass changeit " +
                 "-keypass changeit -noprompt -keyalg " + keyAlg + " ";
-        String pre = simple + "-genkeypair -dname CN=Olala -alias ";
+        String pre = simple + "-genkeypair -keyalg DSA -dname CN=Olala -alias ";
 
         // Version and SKID
         testOK("", pre + "o1");
@@ -1678,30 +1679,30 @@
         remove("x.jks");
         testOK("", "-help");
 
-        //   2. keytool -genkey -v -keysize 512 Enter "a" for the keystore
+        //   2. keytool -genkey -keyalg DSA -v -keysize 512 Enter "a" for the keystore
         // password. Check error (password too short). Enter "password" for
         // the keystore password. Hit 'return' for "first and last name",
         // "organizational unit", "City", "State", and "Country Code".
         // Type "yes" when they ask you if everything is correct.
         // Type 'return' for new key password.
         testOK("a\npassword\npassword\nMe\nHere\nNow\nPlace\nPlace\nUS\nyes\n\n",
-                "-genkey -v -keysize 512 -keystore x.jks -storetype JKS");
+                "-genkey -keyalg DSA -v -keysize 512 -keystore x.jks -storetype JKS");
         //   3. keytool -list -v -storepass password
         testOK("", "-list -v -storepass password -keystore x.jks -storetype JKS");
         //   4. keytool -list -v Type "a" for the keystore password.
         // Check error (wrong keystore password).
         testFail("a\n", "-list -v -keystore x.jks -storetype JKS");
         assertTrue(ex.indexOf("password was incorrect") != -1);
-        //   5. keytool -genkey -v -keysize 512 Enter "password" as the password.
+        //   5. keytool - -keyalg DSA -v -keysize 512 Enter "password" as the password.
         // Check error (alias 'mykey' already exists).
-        testFail("password\n", "-genkey -v -keysize 512" +
+        testFail("password\n", "-genkey -keyalg DSA -v -keysize 512" +
                 " -keystore x.jks -storetype JKS");
         assertTrue(ex.indexOf("alias <mykey> already exists") != -1);
-        //   6. keytool -genkey -v -keysize 512 -alias mykey2 -storepass password
+        //   6. keytool -genkey -keyalg DSA -v -keysize 512 -alias mykey2 -storepass password
         // Hit 'return' for "first and last name", "organizational unit", "City",
         // "State", and "Country Code". Type "yes" when they ask you if
         // everything is correct. Type 'return' for new key password.
-        testOK("\n\n\n\n\n\nyes\n\n", "-genkey -v -keysize 512 -alias mykey2" +
+        testOK("\n\n\n\n\n\nyes\n\n", "-genkey -keyalg DSA -v -keysize 512 -alias mykey2" +
                 " -storepass password -keystore x.jks -storetype JKS");
         //   7. keytool -list -v Type 'password' for the store password.
         testOK("password\n", "-list -v -keystore x.jks -storetype JKS");
@@ -1810,7 +1811,7 @@
     void sszzTest() throws Exception {
         testAnyway("", NSS_P11_ARG+"-delete -alias nss -storepass test12");
         testAnyway("", NZZ_P11_ARG+"-delete -alias nss -storepass test12");
-        testOK("", NSS_P11_ARG+"-genkeypair -dname CN=NSS " +
+        testOK("", NSS_P11_ARG+"-genkeypair -keyalg DSA -dname CN=NSS " +
                 "-alias nss -storepass test12");
         testOK("", NSS_SRC_P11_ARG + NZZ_P11_ARG +
                 "-importkeystore -srcstorepass test12 -deststorepass test12");
--- a/test/jdk/sun/security/tools/keytool/PKCS12Passwd.java	Wed Nov 13 17:21:31 2019 -0500
+++ b/test/jdk/sun/security/tools/keytool/PKCS12Passwd.java	Mon Nov 18 12:40:06 2019 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -49,11 +49,11 @@
     public static void main(String[] args) throws Exception {
 
         // A PrivateKeyEntry
-        kt("-genkeypair -alias a -dname CN=A")
+        kt("-genkeypair -alias a -dname CN=A -keyalg DSA")
                 .shouldHaveExitValue(0);
 
         // A TrustedCertificateEntry (genkeypair, export, delete, import)
-        kt("-genkeypair -alias b -dname CN=B")
+        kt("-genkeypair -alias b -dname CN=B -keyalg DSA")
                 .shouldHaveExitValue(0);
         kt("-exportcert -alias b -file b.cert")
                 .shouldHaveExitValue(0);
@@ -90,7 +90,7 @@
         // A PKCS12 keystore can be loaded as a JKS, and it follows JKS rules
         // which means the storepass and keypass can be changed separately!
 
-        ktFull("-genkeypair -alias a -dname CN=A -storetype pkcs12 "
+        ktFull("-genkeypair -alias a -dname CN=A -storetype pkcs12 -keyalg DSA "
                     + "-storepass changeit -keypass changeit -keystore p12")
                 .shouldHaveExitValue(0);
 
@@ -112,7 +112,7 @@
         // PKCS12 rules that both passwords are changed at the same time and
         // some commands are rejected.
 
-        ktFull("-genkeypair -alias a -dname CN=A -storetype jks "
+        ktFull("-genkeypair -alias a -dname CN=A -storetype jks -keyalg DSA "
                     + "-storepass changeit -keypass changeit -keystore jks")
                 .shouldHaveExitValue(0);
 
--- a/test/jdk/sun/security/tools/keytool/ProbingFailure.java	Wed Nov 13 17:21:31 2019 -0500
+++ b/test/jdk/sun/security/tools/keytool/ProbingFailure.java	Mon Nov 18 12:40:06 2019 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -53,7 +53,7 @@
     public static void main(String[] args) throws Exception {
 
         // genkeypair
-        kt("-genkeypair -keystore mks -alias a -dname CN=A -storetype MYKS")
+        kt("-genkeypair -keystore mks -alias a -dname CN=A -keyalg DSA -storetype MYKS")
                 .shouldHaveExitValue(0);
 
         // list
--- a/test/jdk/sun/security/tools/keytool/RealType.java	Wed Nov 13 17:21:31 2019 -0500
+++ b/test/jdk/sun/security/tools/keytool/RealType.java	Mon Nov 18 12:40:06 2019 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -45,7 +45,7 @@
 
     public static void main(String[] args) throws Throwable {
 
-        kt("-genkeypair -alias a -dname CN=A -keypass changeit -storetype jks")
+        kt("-genkeypair -keyalg DSA -alias a -dname CN=A -keypass changeit -storetype jks")
                 .shouldHaveExitValue(0);
 
         // -keypasswd command should be allowed on JKS
@@ -54,7 +54,7 @@
 
         Files.delete(Paths.get("ks"));
 
-        kt("-genkeypair -alias a -dname CN=A -keypass changeit -storetype pkcs12")
+        kt("-genkeypair -keyalg DSA -alias a -dname CN=A -keypass changeit -storetype pkcs12")
                 .shouldHaveExitValue(0);
 
         // A pkcs12 keystore cannot be loaded as a JCEKS keystore
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/sun/security/tools/keytool/RemoveKeyAlgDefault.java	Mon Nov 18 12:40:06 2019 -0500
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import jdk.test.lib.SecurityTools;
+import jdk.test.lib.process.OutputAnalyzer;
+
+/**
+ * @test
+ * @bug 8212003 8214024
+ * @summary Deprecating the default keytool -keyalg option
+ * @library /test/lib
+ */
+
+public class RemoveKeyAlgDefault {
+
+    private static final String COMMON = "-keystore ks -storetype jceks "
+            + "-storepass changeit -keypass changeit";
+
+    public static void main(String[] args) throws Throwable {
+
+        kt("-genkeypair -keyalg DSA -alias a -dname CN=A")
+                .shouldHaveExitValue(0)
+                .shouldContain("Generating")
+                .shouldNotContain("-keyalg option must be specified");
+
+        kt("-genkeypair -alias b -dname CN=B")
+                .shouldHaveExitValue(1)
+                .shouldContain("-keyalg option must be specified");
+
+        kt("-genseckey -keyalg DES -alias c")
+                .shouldHaveExitValue(0)
+                .shouldContain("Generated")
+                .shouldNotContain("-keyalg option must be specified");
+
+        kt("-genseckey -alias d")
+                .shouldHaveExitValue(1)
+                .shouldContain("-keyalg option must be specified");
+    }
+
+    private static OutputAnalyzer kt(String cmd) throws Throwable {
+        return SecurityTools.keytool(COMMON + " " + cmd);
+    }
+}
--- a/test/jdk/sun/security/tools/keytool/WeakAlg.java	Wed Nov 13 17:21:31 2019 -0500
+++ b/test/jdk/sun/security/tools/keytool/WeakAlg.java	Mon Nov 18 12:40:06 2019 -0500
@@ -178,7 +178,7 @@
         // no warning if all certs
         kt("-importcert -alias b -file a.crt -storetype jks -noprompt")
                 .shouldNotContain("Warning:");
-        kt("-genkeypair -alias a -dname CN=A")
+        kt("-genkeypair -keyalg DSA -alias a -dname CN=A")
                 .shouldContain("JKS keystore uses a proprietary format");
         kt("-list")
                 .shouldContain("JKS keystore uses a proprietary format");
@@ -202,7 +202,7 @@
 
         rm("ks");
 
-        kt("-genkeypair -alias a -dname CN=A -storetype jceks")
+        kt("-genkeypair -keyalg DSA -alias a -dname CN=A -storetype jceks")
                 .shouldContain("JCEKS keystore uses a proprietary format");
         kt("-list")
                 .shouldContain("JCEKS keystore uses a proprietary format");
@@ -239,7 +239,7 @@
     static void checkInplaceImportKeyStore() throws Exception {
 
         rm("ks");
-        genkeypair("a", "");
+        genkeypair("a", "-keyalg DSA");
 
         // Same type backup
         importkeystore("ks", "ks", "")
--- a/test/jdk/sun/security/tools/keytool/console.sh	Wed Nov 13 17:21:31 2019 -0500
+++ b/test/jdk/sun/security/tools/keytool/console.sh	Mon Nov 18 12:40:06 2019 -0500
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2006, 2014, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2006, 2019, Oracle and/or its affiliates. All rights reserved.
 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 #
 # This code is free software; you can redistribute it and/or modify it
@@ -75,7 +75,7 @@
 echo "=========================================="
 echo
 rm $KS 2> /dev/null
-$J5/bin/keytool -keystore $KS -genkey -dname CN=olala -storepass $PASSW || exit 1
+$J5/bin/keytool -keystore $KS -genkey -keyalg DSA -dname CN=olala -storepass $PASSW || exit 1
 $JM/bin/keytool -keystore $KS -list -storepass $PASSW || exit 2
 
 echo "=========================================="
@@ -84,7 +84,7 @@
 echo
 
 rm $KS 2> /dev/null
-$JM/bin/keytool -keystore $KS -genkey -dname CN=olala -storepass $PASSW || exit 3
+$JM/bin/keytool -keystore $KS -genkey -keyalg DSA -dname CN=olala -storepass $PASSW || exit 3
 $J5/bin/keytool -keystore $KS -list -storepass $PASSW || exit 4
 
 echo "============================================================"
@@ -93,7 +93,7 @@
 echo
 
 rm $KS 2> /dev/null
-$J5/bin/keytool -keystore $KS -genkey -dname CN=olala || exit 5
+$J5/bin/keytool -keystore $KS -genkey -keyalg DSA -dname CN=olala || exit 5
 $JM/bin/keytool -keystore $KS -list || exit 6
 echo $PASSW| $J5/bin/keytool -keystore $KS -list || exit 7
 echo $PASSW| $JM/bin/keytool -keystore $KS -list || exit 8
@@ -104,7 +104,7 @@
 echo
 
 rm $KS 2> /dev/null
-$JM/bin/keytool -keystore $KS -genkey -dname CN=olala || exit 9
+$JM/bin/keytool -keystore $KS -genkey -keyalg DSA -dname CN=olala || exit 9
 $J5/bin/keytool -keystore $KS -list || exit 10
 echo $PASSW| $JM/bin/keytool -keystore $KS -list || exit 11
 echo $PASSW| $J5/bin/keytool -keystore $KS -list || exit 12
@@ -115,7 +115,7 @@
 echo
 
 rm $KS 2> /dev/null
-echo $PASSW| $J5/bin/keytool -keystore $KS -genkey -dname CN=olala || exit 13
+echo $PASSW| $J5/bin/keytool -keystore $KS -genkey -keyalg DSA -dname CN=olala || exit 13
 $JM/bin/keytool -keystore $KS -list || exit 14
 echo $PASSW| $J5/bin/keytool -keystore $KS -list || exit 15
 echo $PASSW| $JM/bin/keytool -keystore $KS -list || exit 16
--- a/test/jdk/sun/security/tools/keytool/i18n.html	Wed Nov 13 17:21:31 2019 -0500
+++ b/test/jdk/sun/security/tools/keytool/i18n.html	Mon Nov 18 12:40:06 2019 -0500
@@ -9,7 +9,7 @@
         If you are on a Windows platform, delete the .keystore file in
         your home directory.
 <li>	keytool -help
-<li>	keytool -genkey -v -keysize 512
+<li>	keytool -genkey -keyalg DSA -v -keysize 512
 	Enter "a" for the keystore password.  Check error (password too short).
 	Enter "password" for the keystore password.
         Re-enter "password" to confirm.
@@ -21,10 +21,10 @@
 <li>	keytool -list -v
 	Type "a" for the keystore password.
 	Check error (wrong keystore password).
-<li>	keytool -genkey -v -keysize 512
+<li>	keytool -genkey -keyalg DSA -v -keysize 512
 	Enter "password" as the password.
 	Check error (alias 'mykey' already exists).
-<li>	keytool -genkey -v -keysize 512 -alias mykey2 -storepass password
+<li>	keytool -genkey -keyalg DSA -v -keysize 512 -alias mykey2 -storepass password
 	Hit 'return' for "first and last name", "organizational unit",
 	"organization", "City", "State", and "Country Code".
 	Type "yes" when they ask you if everything is correct.
--- a/test/langtools/tools/javac/api/TestModuleUnnamedPackage.java	Wed Nov 13 17:21:31 2019 -0500
+++ b/test/langtools/tools/javac/api/TestModuleUnnamedPackage.java	Mon Nov 18 12:40:06 2019 -0500
@@ -25,7 +25,8 @@
  * @test
  * @bug     8234025
  * @summary Elements.getPackageElement(ModuleElement,CharSequence) returns null for unnamed package
- * @modules jdk.compiler
+ * @modules jdk.compiler/com.sun.tools.javac.api
+ *          jdk.compiler/com.sun.tools.javac.main
  * @library /tools/lib /tools/javac/lib
  * @build toolbox.ModuleBuilder toolbox.ToolBox
  * @run main TestModuleUnnamedPackage
--- a/test/langtools/tools/javac/processing/model/TestSourceVersion.java	Wed Nov 13 17:21:31 2019 -0500
+++ b/test/langtools/tools/javac/processing/model/TestSourceVersion.java	Mon Nov 18 12:40:06 2019 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -23,7 +23,7 @@
 
 /*
  * @test
- * @bug 7025809 8028543 6415644 8028544 8029942 8187951 8193291 8196551
+ * @bug 7025809 8028543 6415644 8028544 8029942 8187951 8193291 8196551 8233096
  * @summary Test latest, latestSupported, underscore as keyword, etc.
  * @author  Joseph D. Darcy
  * @modules java.compiler
@@ -31,11 +31,12 @@
  */
 
 import java.util.*;
+import java.util.function.Predicate;
 import javax.lang.model.SourceVersion;
 import static javax.lang.model.SourceVersion.*;
 
 /**
- * Verify latest[Supported] behavior.
+ * Verify behavior of latest[Supported] and other methods.
  */
 public class TestSourceVersion {
     public static void main(String... args) {
@@ -43,6 +44,7 @@
         testVersionVaryingKeywords();
         testRestrictedKeywords();
         testVar();
+        testYield();
     }
 
     private static void testLatestSupported() {
@@ -52,8 +54,10 @@
         SourceVersion latestSupported = SourceVersion.latestSupported();
 
         if (latest == last &&
-            latestSupported == SourceVersion.valueOf("RELEASE_" + Runtime.version().feature()) &&
-            (latest == latestSupported || (latest.ordinal() - latestSupported.ordinal() == 1)) )
+            latestSupported == SourceVersion.valueOf("RELEASE_" +
+                                                     Runtime.version().feature()) &&
+            (latest == latestSupported ||
+             (latest.ordinal() - latestSupported.ordinal() == 1)) )
             return;
         else {
             throw new RuntimeException("Unexpected release value(s) found:\n" +
@@ -73,14 +77,14 @@
             String key = entry.getKey();
             SourceVersion value = entry.getValue();
 
-            check(true, isKeyword(key), "keyword", latest());
-            check(false, isName(key),   "name",    latest());
+            check(true,  key, (String s) -> isKeyword(s), "keyword", latest());
+            check(false, key, (String s) -> isName(s),    "name",    latest());
 
             for(SourceVersion version : SourceVersion.values()) {
                 boolean isKeyword = version.compareTo(value) >= 0;
 
-                check(isKeyword,  isKeyword(key, version), "keyword", version);
-                check(!isKeyword, isName(key, version),    "name",    version);
+                check(isKeyword,  key, (String s) -> isKeyword(s, version), "keyword", version);
+                check(!isKeyword, key, (String s) -> isName(s, version),    "name",    version);
             }
         }
     }
@@ -98,31 +102,47 @@
             Set.of("open", "module", "requires", "transitive", "exports",
                    "opens", "to", "uses", "provides", "with");
 
-        for(String key : restrictedKeywords) {
-            for(SourceVersion version : SourceVersion.values()) {
-                check(false, isKeyword(key, version), "keyword", version);
-                check(true,  isName(key, version),    "name",    version);
+        for (String key : restrictedKeywords) {
+            for (SourceVersion version : SourceVersion.values()) {
+                check(false, key, (String s) -> isKeyword(s, version), "keyword", version);
+                check(true,  key, (String s) -> isName(s, version),    "name",    version);
             }
         }
     }
 
     private static void testVar() {
+        for (SourceVersion version : SourceVersion.values()) {
+            Predicate<String> isKeywordVersion = (String s) -> isKeyword(s, version);
+            Predicate<String> isNameVersion = (String s) -> isName(s, version);
 
-        for(SourceVersion version : SourceVersion.values()) {
-            check(false, isKeyword("var",     version), "keyword", version);
-            check(false, isKeyword("foo.var", version), "keyword", version);
-            check(false, isKeyword("var.foo", version), "keyword", version);
-
-            check(true, isName("var", version),     "name", version);
-            check(true, isName("foo.var", version), "name", version);
-            check(true, isName("var.foo", version), "name", version);
+            for (String name : List.of("var", "foo.var", "var.foo")) {
+                check(false, name, isKeywordVersion, "keyword", version);
+                check(true, name,  isNameVersion, "name", version);
+            }
         }
     }
 
-    private static void check(boolean result, boolean expected,
-                              String message, SourceVersion version) {
+    private static void testYield() {
+        for (SourceVersion version : SourceVersion.values()) {
+            Predicate<String> isKeywordVersion = (String s) -> isKeyword(s, version);
+            Predicate<String> isNameVersion = (String s) -> isName(s, version);
+
+            for  (String name : List.of("yield", "foo.yield", "yield.foo")) {
+                check(false, name, isKeywordVersion, "keyword", version);
+                check(true, name,  isNameVersion, "name", version);
+            }
+        }
+    }
+
+    private static void check(boolean expected,
+                              String input,
+                              Predicate<String> predicate,
+                              String message,
+                              SourceVersion version) {
+        boolean result  = predicate.test(input);
         if (result != expected) {
-            throw new RuntimeException("Unexpected " + message +  "-ness of _ on " + version);
+            throw new RuntimeException("Unexpected " + message +  "-ness of " + input +
+                                       " on " + version);
         }
     }
 }